min/max builtin function implementation

This includes the behavior described in issue #1369 including the "future improvement."

Examples of functionality:

    max(3%, 1cm, 8%, 2mm)  // max(8%, 1cm) [tree.Anonymous]
    min("junk", 3, 5cm, 1) // min("junk", 1, 5cm) [tree.Anonymous]
    max(1, 5, 3)           // 5 [tree.Dimension]
    max("junk")            // "junk" [tree.Quoted]
    max(blah(1, 2, 3))     // blah(1, 2, 3) [tree.Anonymous]

    max((31mm/1em), (32mm/1em), 48mm) // max(32mm, 48mm) [tree.Anonymous]

Specifically, a single argument will always be returned as itself, and when all arguments are compatible parsed numerics, a single tree.Dimension value will be returned. Otherwise, groups of compatible tree.Dimension arguments will independently reduce with the result of each occupying the position of the first element in that group.

Compatibility is determined based on `x.unify().unit.toString()`, thus the last example doesn't produce just 48mm since the unit groups are "mm/em" and "mm", respectively; if the arithmetic system is ever changed to preserve units on output while still using the same tree.Dimension object structure, min and max will continue do the right thing.

All non-Dimension arguments will appear in the output, and all output terms identically match input arguments, so min/max will never visibly convert units beyond what the toCSS method will already do to Dimensions with mixed units.