TextHandler: Simplify logic for tracking the rendering state

function InitTextHandlers() {
    // QUESTION: We could also take an argument and throw all text handlers from
    // extensions into the same dictionary

    textHandlers = CreateDictionary(
        'StyleId', CreateDictionary(),
        'StyleAsText', CreateDictionary()
    );

    RegisterHandlers(textHandlers, CreateDictionary(
        'StyleId', CreateDictionary(
            'text.staff.expression', 'ExpressionTextHandler',
            'text.system.page_aligned.title', 'PageTitleHandler',
            'text.system.page_aligned.subtitle', 'PageTitleHandler',
            'text.system.page_aligned.composer', 'PageComposerTextHandler',
            'text.system.tempo', 'TempoTextHandler',
            'text.staff.space.figuredbass', 'FiguredBassTextHandler',
            'text.staff.plain', 'CreateAnchoredText'
        )
    ), Self);

    return textHandlers;
}  //$end

function InitTextSubstituteMap() {
    return CreateDictionary(
        'Title', CreateSparseArray('Title'),
        'Subtitle', CreateSparseArray('Title', CreateDictionary('type', 'subordinate')),
        // <dedication> is only allowed on <titlePage> and <creation>, so use
        // generic element
        'Dedication', CreateSparseArray('Seg', CreateDictionary('type', 'Dedication')),
        // <composer>, <arranger>, <lyricist>, <userRestrict> and <publisher>
        // are only allowed in a few places, e.g. metadata or title pages.
        // We therfore use more generic elements
        'Composer', CreateSparseArray('PersName', CreateDictionary('role', 'Composer')),
        'Arranger', CreateSparseArray('PersName', CreateDictionary('role', 'Arranger')),
        'Lyricist', CreateSparseArray('PersName', CreateDictionary('role', 'Lyricist')),
        'Artist', CreateSparseArray('PersName', CreateDictionary('role', 'Artist')),
        // <useRestrict> is only allowed on <titlePage>, so use generic element
        'Copyright', CreateSparseArray('Seg', CreateDictionary('type', 'Copyright')),
        // <publisher> is only allowed in a few places, so use generic element
        // We don't even know if it's a person or an institution
        'Publisher', CreateSparseArray('Seg', CreateDictionary('type', 'Publisher')),
        'MoreInfo', CreateSparseArray('Seg', CreateDictionary('type', 'MoreInfo')),
        'PartName', CreateSparseArray('Seg', CreateDictionary('type', 'PartName'))
    );
}  //$end

function HandleText (textObject) {
    // Step through the different ID types ('StyleId' and 'StyleAsText') and
    // check for text handlers for this type
    textHandlers = Self._property:TextHandlers;
    for each Name idType in textHandlers
    {
        handlersForIdType = textHandlers.@idType;
        idValue = textObject.@idType;
        if(handlersForIdType.MethodExists(idValue))
        {
            return handlersForIdType.@idValue(textObject);
        }
    }
}  //$end

function ExpressionTextHandler (this, textObject) {
    dynam = GenerateControlEvent(textObject, 'Dynam');
    AddFormattedText(dynam, textObject);
    return dynam;
}  //$end

function PageTitleHandler (this, textObject) {
    anchoredText = libmei.AnchoredText();
    title = libmei.Title();
    if (textObject.StyleId = 'text.system.page_aligned.subtitle')
    {
        libmei.AddAttribute(title, 'type', 'subordinate');
    }

    libmei.AddChild(anchoredText, title);
    AddFormattedText(title, textObject);

    return anchoredText;
}  //$end

function PageComposerTextHandler (this, textObject) {
    // 'text.system.page_aligned.composer'
    anchoredText = libmei.AnchoredText();
    AddFormattedText(anchoredText, textObject);
    return anchoredText;
}  //$end

function TempoTextHandler (this, textObject) {
    // 'text.system.tempo'
    tempo = GenerateControlEvent(textObject, 'Tempo');
    AddFormattedText(tempo, textObject);
    return tempo;
}  //$end

function FiguredBassTextHandler (this, textObject) {
    // 'text.staff.space.figuredbass'
    harm = GenerateControlEvent(textObject, 'Harm');
    fb = libmei.Fb();
    libmei.AddChild(harm, fb);
    ConvertFbFigures(fb, textObject);
    return harm;
}  //$end

function CreateAnchoredText (this, textObj) {
    anchoredText = libmei.AnchoredText();
    AddFormattedText(anchoredText, textObj);
    return anchoredText;
}  //$end

function AddFormattedText (parentElement, textObj) {
    textWithFormatting = textObj.TextWithFormatting;
    if (textWithFormatting.NumChildren < 2 and CharAt(textWithFormatting[0], 0) != '\\')
    {
        // We have a simple text element without special style properties
        if (parentElement.name = 'div')
        {
            p = libmei.P();
            libmei.SetText(p, textObj.Text);
            libmei.AddChild(parentElement, p);
        }
        else
        {
            libmei.SetText(parentElement, textObj.Text);
        }
        return parentElement;
    }

    // At this point we know that we have text with style changes and/or text
    // substitutions
    nodes = CreateSparseArray();

    state = CreateDictionary(
        'currentText', null,
        'style', CreateDictionary(),
        // TODO: Also track the active character style (mainly
        // `\ctext.character.musictext\`, and custom styles)
        'meiNodes', nodes
    );

    for each component in textObj.TextWithFormatting
    {
        switch (Substring(component, 0, 2))
        {
            case ('\\n')
            {
                PushStyledText(state);
                nodes.Push(libmei.Lb());
            }
            case ('\\N')
            {
                PushStyledText(state);
                // TODO: Add <p> if it is allowed within parentElement (use libmei.GetName())
                nodes.Push(libmei.Lb());
            }
            case ('\\B')
            {
                SwitchTextStyle(state, 'fontweight', 'bold');
            }
            case ('\\b')
            {
                SwitchTextStyle(state, 'fontweight', 'normal');
            }
            case ('\\I')
            {
                SwitchTextStyle(state, 'fontstyle', 'italic');
            }
            case ('\\i')
            {
                SwitchTextStyle(state, 'fontstyle', 'normal');
            }
            case ('\\U')
            {
                SwitchTextStyle(state, 'underline', 'underline_on');
            }
            case ('\\u')
            {
                SwitchTextStyle(state, 'underline', 'underline_off');
            }
            case ('\\f')
            {
                font = GetTextCommandArg(component);
                if (font = '_')
                {
                    ResetTextStyles(state);
                }
                else
                {
                    SwitchTextStyle(state, 'fontfam', font);
                }
            }
            case ('\\c')
            {
                // TODO: Can we sensibly handle a character style change? The
                // only built-in one seem to be `text.character.musictext`. We
                // might want to allow Extensions to handle custom character
                // styles.
                ;
            }
            case ('\\s')
            {
                fontsize = ConvertOffsetsToMEI(GetTextCommandArg(component));
                SwitchTextStyle(state, 'fontsize', fontsize);
            }
            case ('\\v')
            {
                // Vertical scale change (vertical stretching). Probably not
                // possible to handle
                ;
            }
            case ('\\h')
            {
                // Horizontal scale change (horizontal stretching). Probably not
                // possible to handle
                ;
            }
            case ('\\t')
            {
                // Tracking. Probably not possible to handle.
                ;
            }
            case ('\\p')
            {
                SwitchTextStyle(state, 'baseline', GetTextCommandArg(component));
            }
            case ('\\$')
            {
                AppendTextSubstitute(state, GetTextCommandArg(component));
            }
            case ('\\\\')
            {
                // According to the documentation, 'backslashes themselves are
                // represented by \\ , to avoid conflicting with the above
                // commands'. Though Sibelius does not seem to allow inputting
                // this, let's still cover it in case Avid fixes this.

                // We strip one leading backspace.
                state.currentText = state.currentText & Substring(component, 1);
            }
            default
            {
                // This is regular text
                state.currentText = state.currentText & component;
            }
        }
    }

    PushStyledText(state);

    nodeCount = nodes.Length;
    precedingElement = null;

    nodeIndex = 0;
    while (nodeIndex < nodeCount)
    {
        node = nodes[nodeIndex];
        if (IsObject(node))
        {
            // We have an element
            libmei.AddChild(parentElement, node);
            precedingElement = node;
        }
        else
        {
            // We have a text node
            text = node;
            // If there are multiple adjacent text nodes, we need to join them
            while (nodeIndex < nodeCount and not IsObject(nodes[nodeIndex + 1]))
            {
                nodeIndex = nodeIndex + 1;
                text = text & nodes[nodeIndex];
            }

            if (precedingElement = null)
            {
                libmei.SetText(parentElement, text);
            }
            else
            {
                libmei.SetTail(precedingElement, text);
            }
        }
        nodeIndex = nodeIndex + 1;
    }
}  //$end

function GetTextCommandArg (command) {
    // Remove leading part, e.g. the '\$' or '\s' and trailing '\'
    return Substring(command, 2, Length(command) - 3);
}  //$end

function ResetTextStyles (state) {
    textNotYetPushed = true;
    style = state.style;

    for each Name property in style
    {
        if (textNotYetPushed and null != style[property])
        {
            // Style changes because we reset this property from non-null value
            // to null. Therefore push the existing text with the old style
            // before resetting it.
            textNotYetPushed = false;
            PushStyledText(state);
        }
        style[property] = null;
    }
}  //$end

function SwitchTextStyle (state, property, value) {
    if (state.style[property] != value)
    {
        // Style changes, so append current text before modifying style state
        PushStyledText(state);
    }
    state.style[property] = value;
}  //$end

function PushStyledText (state) {
    if (state.currentText = '')
    {
        return null;
    }

    styleAttributes = GetStyleAttributes(state);
    if (null = styleAttributes)
    {
        // We attach unstyled text without wrapping it in <rend>
        state.meiNodes.Push(state.currentText);
    }
    else
    {
        rend = libmei.Rend();
        for each Name attName in styleAttributes
        {
            libmei.AddAttribute(rend, attName, styleAttributes[attName]);
        }
        libmei.SetText(rend, state.currentText);
        state.meiNodes.Push(rend);
    }

    state.currentText = '';
}  //$end

function GetStyleAttributes (state) {
    // Returns a dictionary with attribute names and values.
    // Returns null if there are no style attributes.

    style = state.style;
    styleAttributes = CreateDictionary();
    rendValues = CreateSparseArray();

    noStyles = true;

    for each Name property in state.style
    {
        value = style[property];
        switch (value)
        {
            case (null)
            {
                ; // Nothing to add
            }
            case ('underline_on')
            {
                rendValues.Push('underline');
            }
            case ('underline_off')
            {
                ; // Nothing to add
            }
            case ('normal') // baseline
            {
                ; // Nothing to add
            }
            case ('subscript')
            {
                rendValues.Push('sub');
            }
            case ('superscript')
            {
                rendValues.Push('sup');
            }
            default
            {
                noStyles = false;
                styleAttributes[property] = value;
            }
        }
    }

    if (rendValues.Length > 0)
    {
        noStyles = false;
        styleAttributes['rend'] = rendValues.Join(' ');
    }

    if (noStyles)
    {
        return null;
    }
    return styleAttributes;
}  //$end

function AppendTextSubstitute (state, substituteName) {
    score = Self._property:ActiveScore;

    textSubstituteTemplate = TextSubstituteMap[substituteName];
    if (null = textSubstituteTemplate)
    {
        // No known substitution. Sibelius renders those literally.
        state.currentText = state.currentText & '\\$' & substituteName & '\\';
        return null;
    }

    substitutedText = score.@substituteName;
    if (substitutedText = '')
    {
        return null;
    }

    PushStyledText(state);

    element = MeiFactory(textSubstituteTemplate);
    state.meiNodes.Push(element);

    styleAttributes = GetStyleAttributes(state);
    rendElement = null;
    if (null = styleAttributes)
    {
        libmei.SetText(element, substitutedText);
    }
    else
    {
        rendElement = libmei.Rend();
        libmei.AddChild(element, rendElement);
        for each Name attName in styleAttributes
        {
            libmei.AddAttribute(rendElement, attName, styleAttributes[attName]);
        }
        libmei.SetText(rendElement, substitutedText);
    }
}  //$end

function InitTextHandlers() {
    // QUESTION: We could also take an argument and throw all text handlers from
    // extensions into the same dictionary

    textHandlers = CreateDictionary(
        'StyleId', CreateDictionary(),
        'StyleAsText', CreateDictionary()
    );

    RegisterHandlers(textHandlers, CreateDictionary(
        'StyleId', CreateDictionary(
            'text.staff.expression', 'ExpressionTextHandler',
            'text.system.page_aligned.title', 'PageTitleHandler',
            'text.system.page_aligned.subtitle', 'PageTitleHandler',
            'text.system.page_aligned.composer', 'PageComposerTextHandler',
            'text.system.tempo', 'TempoTextHandler',
            'text.staff.space.figuredbass', 'FiguredBassTextHandler',
            'text.staff.plain', 'CreateAnchoredText'
        )
    ), Self);

    return textHandlers;
}  //$end

function InitTextSubstituteMap() {
    return CreateDictionary(
        'Title', CreateSparseArray('Title'),
        'Subtitle', CreateSparseArray('Title', CreateDictionary('type', 'subordinate')),
        // <dedication> is only allowed on <titlePage> and <creation>, so use
        // generic element
        'Dedication', CreateSparseArray('Seg', CreateDictionary('type', 'Dedication')),
        // <composer>, <arranger>, <lyricist>, <userRestrict> and <publisher>
        // are only allowed in a few places, e.g. metadata or title pages.
        // We therfore use more generic elements
        'Composer', CreateSparseArray('PersName', CreateDictionary('role', 'Composer')),
        'Arranger', CreateSparseArray('PersName', CreateDictionary('role', 'Arranger')),
        'Lyricist', CreateSparseArray('PersName', CreateDictionary('role', 'Lyricist')),
        'Artist', CreateSparseArray('PersName', CreateDictionary('role', 'Artist')),
        // <useRestrict> is only allowed on <titlePage>, so use generic element
        'Copyright', CreateSparseArray('Seg', CreateDictionary('type', 'Copyright')),
        // <publisher> is only allowed in a few places, so use generic element
        // We don't even know if it's a person or an institution
        'Publisher', CreateSparseArray('Seg', CreateDictionary('type', 'Publisher')),
        'MoreInfo', CreateSparseArray('Seg', CreateDictionary('type', 'MoreInfo')),
        'PartName', CreateSparseArray('Seg', CreateDictionary('type', 'PartName'))
    );
}  //$end

function HandleText (textObject) {
    // Step through the different ID types ('StyleId' and 'StyleAsText') and
    // check for text handlers for this type
    textHandlers = Self._property:TextHandlers;
    for each Name idType in textHandlers {
        handlersForIdType = textHandlers.@idType;
        idValue = textObject.@idType;
        if(handlersForIdType.MethodExists(idValue))
        {
            return handlersForIdType.@idValue(textObject);
        }
    }
}  //$end

function ExpressionTextHandler (this, textObject) {
    dynam = GenerateControlEvent(textObject, 'Dynam');
    AddFormattedText(dynam, textObject);
    return dynam;
}  //$end

function PageTitleHandler (this, textObject) {
    anchoredText = libmei.AnchoredText();
    title = libmei.Title();
    if (textObject.StyleId = 'text.system.page_aligned.subtitle')
    {
        libmei.AddAttribute(title, 'type', 'subordinate');
    }

    libmei.AddChild(anchoredText, title);
    AddFormattedText(title, textObject);

    return anchoredText;
}  //$end

function PageComposerTextHandler (this, textObject) {
    // 'text.system.page_aligned.composer'
    anchoredText = libmei.AnchoredText();
    AddFormattedText(anchoredText, textObject);
    return anchoredText;
}  //$end

function TempoTextHandler (this, textObject) {
    // 'text.system.tempo'
    tempo = GenerateControlEvent(textObject, 'Tempo');
    AddFormattedText(tempo, textObject);
    return tempo;
}  //$end

function FiguredBassTextHandler (this, textObject) {
    // 'text.staff.space.figuredbass'
    harm = GenerateControlEvent(textObject, 'Harm');
    fb = libmei.Fb();
    libmei.AddChild(harm, fb);
    ConvertFbFigures(fb, textObject);
    return harm;
}  //$end

function CreateAnchoredText (this, textObj) {
    anchoredText = libmei.AnchoredText();
    AddFormattedText(anchoredText, textObj);
    return anchoredText;
}  //$end

function AddFormattedText (parentElement, textObj) {
    textWithFormatting = textObj.TextWithFormatting;
    if (textWithFormatting.NumChildren < 2 and CharAt(textWithFormatting[0], 0) != '\\')
    {
        if (parentElement.name = 'div')
        {
            p = libmei.P();
            libmei.SetText(p, textObj.Text);
            libmei.AddChild(parentElement, p);
        }
        else
        {
            libmei.SetText(parentElement, textObj.Text);
        }
        return parentElement;
    }

    nodes = CreateSparseArray();

    state = CreateDictionary(
        'currentText', null,
        'rendAttributes', CreateDictionary(),
        'rendFlags', CreateDictionary(),
        // TODO: Also track the active character style (mainly
        // `\ctext.character.musictext\`, and custom styles)
        'nodes', nodes,
        'paragraphs', null
    );

    for each component in textObj.TextWithFormatting
    {
        switch (Substring(component, 0, 2))
        {
            case ('\\n')
            {
                PushStyledText(state);
                nodes.Push(libmei.Lb());
            }
            case ('\\N')
            {
                PushStyledText(state);
                // TODO: Add <p> if it is allowed within parentElement (use libmei.GetName())
                nodes.Push(libmei.Lb());
            }
            case ('\\B')
            {
                SwitchTextStyle(state, 'fontweight', 'bold');
            }
            case ('\\b')
            {
                SwitchTextStyle(state, 'fontweight', 'normal');
            }
            case ('\\I')
            {
                SwitchTextStyle(state, 'fontstyle', 'italic');
            }
            case ('\\i')
            {
                SwitchTextStyle(state, 'fontstyle', 'normal');
            }
            case ('\\U')
            {
                SwitchTextStyle(state, 'rend', 'underline', true);
            }
            case ('\\u')
            {
                SwitchTextStyle(state, 'rend', 'underline', false);
            }
            case ('\\f')
            {
                SwitchFont(state, GetTextCommandArg(component));
            }
            case ('\\c')
            {
                // TODO: Can we sensibly handle a character style change? The
                // only built-in one seem to be `text.character.musictext`. We
                // might want to allow Extensions to handle custom character
                // styles.
                ;
            }
            case ('\\s')
            {
                fontsize = ConvertOffsetsToMEI(GetTextCommandArg(component));
                SwitchTextStyle(state, 'fontsize', fontsize);
            }
            case ('\\v')
            {
                // Vertical scale change (vertical stretching). Probably not
                // possible to handle
                ;
            }
            case ('\\h')
            {
                // Horizontal scale change (horizontal stretching). Probably not
                // possible to handle
                ;
            }
            case ('\\t')
            {
                // Tracking. Probably not possible to handle.
                ;
            }
            case ('\\p')
            {
                SwitchBaselineAdjust(state, GetTextCommandArg(component));
            }
            case ('\\$') {
                AppendTextSubstitute(state, GetTextCommandArg(component));
            }
            case ('\\\\')
            {
                // According to the documentation, 'backslashes themselves are
                // represented by \\ , to avoid conflicting with the above
                // commands'. Though that does not seem to work, let's just
                // assume it does in case Avid fixes this.

                // We strip one leading backspace.
                state.currentText = state.currentText & Substring(component, 1);
            }
            default
            {
                // This is regular text
                state.currentText = state.currentText & component;
            }
        }
    }

    PushStyledText(state);

    nodeCount = nodes.Length;
    precedingElement = null;

    nodeIndex = 0;
    while (nodeIndex < nodeCount)
    {
        node = nodes[nodeIndex];
        if (IsObject(node))
        {
            // We have an element
            libmei.AddChild(parentElement, node);
            precedingElement = node;
        }
        else
        {
            // We have a text node
            text = node;
            // If there are multiple adjacent text nodes, we need to join them
            while (nodeIndex < nodeCount and not IsObject(nodes[nodeIndex + 1])) {
                nodeIndex = nodeIndex + 1;
                text = text & nodes[nodeIndex];
            }

            if (precedingElement = null)
            {
                libmei.SetText(parentElement, text);
            }
            else
            {
                libmei.SetTail(precedingElement, text);
            }
        }
        nodeIndex = nodeIndex + 1;
    }
}  //$end

function NewTextParagraph (state) {
    // TODO!
    ;
}  //$end

function GetTextCommandArg (command) {
    // Remove leading part, e.g. the '\$' or '\s' and trailing '\'
    return Substring(command, 2, Length(command) - 3);
}  //$end

function SwitchBaselineAdjust (state, param) {
    sup = (param = 'superscript');
    sub = (param = 'subscript');
    if (sup != state.rendFlags['sup'] or sub != state.rendFlags['sub']) {
        // Style changed, push the previous text before changing the style
        PushStyledText(state);
    }
    state.rendFlags['sup'] = sup;
    state.rendFlags['sub'] = sub;
}  //$end

function ResetTextStyles (state, infoOnly) {
    // If `infoOnly` is `true`, does not make any changes, only tells us if
    // there are re-settable styles
    if (null != state.rendAttributes)
    {
        for each Name attName in state.rendAttributes
        {
            if (infoOnly and state.rendAttributes[attName] != null)
            {
                return true;
            }
            state.rendAttributes[attName] = null;
        }
    }

    if (null != state.rendFlags)
    {
        for each Name flagName in state.rendFlags
        {
            if (infoOnly and state.rendFlags[flagName])
            {
                return true;
            }
            state.rendFlags[flagName] = false;
        }
    }
    return false;
}  //$end

function SwitchFont (state, fontName) {
    if (fontName = '_')
    {
        // Before resetting the style, we have to add text preceding the '\f_\'
        // style reset – but only if the style reset actually changes something.
        if (ResetTextStyles(state, true))
        {
            PushStyledText(state);
            ResetTextStyles(state, false);
        }
    }
    else
    {
        SwitchTextStyle(state, 'fontfam', fontName);
    }
}  //$end

function SwitchTextStyle (state, attName, value) {
    if (state.rendAttributes[attName] != value)
    {
        // Style changes, so append current text before modifying style state
        PushStyledText(state);
    }
    state.rendAttributes[attName] = value;
}  //$end

function SwitchRendFlags (state, flagName, value) {
    if (state.rendFlags[flagName] != value)
    {
        PushStyledText(state);
    }
    state.rendFlags[flagName] = value;
}  //$end

function PushStyledText (state) {
    if (state.currentText = '')
    {
        return null;
    }

    styleAttributes = GetStyleAttributes(state);
    if (null = styleAttributes)
    {
        // We attach unstyled text without wrapping it in <rend>
        state.nodes.Push(state.currentText);
    }
    else
    {
        rend = libmei.Rend();
        for each Name attName in styleAttributes {
            libmei.AddAttribute(rend, attName, styleAttributes[attName]);
        }
        libmei.SetText(rend, state.currentText);
        state.nodes.Push(rend);
    }

    state.currentText = '';
}  //$end

function GetStyleAttributes (state) {
    rendAttributes = null;

    if (null != state.rendAttributes)
    {
        for each Name attName in state.rendAttributes
        {
            value = state.rendAttributes[attName];
            if (null != value)
            {
                if (null = rendAttributes) {
                    rendAttributes = CreateDictionary();
                }
                rendAttributes[attName] = value;
            }
        }
    }

    if (null != state.rendFlags)
    {
        rendAttValue = '';
        firstRendFlag = true;
        for each Name flagName in state.rendFlags
        {
            flagActive = state.rendFlags[flagName];
            if (flagActive)
            {
                if (firstRendFlag = true)
                {
                    rendAttValue = rendAttValue & flagName;
                    firstRendFlag = false;
                }
                else
                {
                    rendAttValue = rendAttValue & ' ' & flagName;
                }
            }
        }
        if (rendAttValue != '')
        {
            if (null = rendAttributes) {
                rendAttributes = CreateDictionary();
            }
            rendAttributes['rend'] = rendAttValue;
        }
    }

    return rendAttributes;
}  //$end

function AppendTextSubstitute (state, substituteName) {
    score = Self._property:ActiveScore;

    textSubstituteInfo = TextSubstituteMap[substituteName];
    if (null = textSubstituteInfo)
    {
        // No known substitution. Sibelius renders those literally.
        state.currentText = state.currentText & '\\$' & substituteName & '\\';
        return null;
    }

    substitutedText = score.@substituteName;
    if (substitutedText = '') {
        return null;
    }

    element = MeiFactory(textSubstituteInfo);
    state.nodes.Push(element);

    styleAttributes = GetStyleAttributes(state);
    rendElement = null;
    if (null = styleAttributes)
    {
        libmei.SetText(element, substitutedText);
    }
    else
    {
        rendElement = libmei.Rend();
        libmei.AddChild(element, rendElement);
        for each Name attName in styleAttributes
        {
            libmei.AddAttribute(rendElement, attName, styleAttributes[attName]);
        }
        libmei.SetText(rendElement, substitutedText);
    }
}  //$end


Lighten green footpaths slightly

Lighten green footpaths slightly

// https://github.com/gregrs-uk/gb-leisure-carto/

Map {
  background-color: white;
}

#landuse {
  [natural='woodland'],
  [natural='wood'],
  [landuse='forest'] {
    polygon-fill:#cfc;
  }
  [landuse='residential'], [landuse='industrial'],
  [landuse='retail'], [landuse='commercial'],
  [landuse='farmyard'] {
    polygon-fill:#f0f0f0;
  }
}

#water {
  // natural=water and waterway=riverbank
  polygon-fill:#eff;
  line-width:1;
  line-color:#bcf;
}

#waterways {
  [waterway='stream'],[waterway='drain'],[waterway='ditch'] {
    line-width:1;
    line-color:#bcf;
  }
  [waterway='river'],[waterway='canal'] {
    ::outer {
      line-width:4;
      line-color:#bcf;
      line-cap:round;
      line-join:bevel;
    }
    ::inner {
      line-width:2;
      line-color:#eff;
      line-cap:round;
      line-join:bevel;
    }
  }
}

@motorway_width: 4;
@primary_width: 3;
@secondary_width: 3;
@minor_width: 2;
@outer_width: 1;

#roads {
  ::outer {
    line-cap:round;
    line-join:bevel;
    [highway='motorway'],[highway='motorway_link'] {
      line-width:@motorway_width+@outer_width;
    }
    [highway='trunk'],[highway='trunk_link'],
    [highway='primary'],[highway='primary_link'] {
      line-width:@primary_width+@outer_width;
      line-color:#700;
    }
    [highway='secondary'],[highway='secondary_link'] {
      line-width:@secondary_width+@outer_width;
      line-color:#910;
    }
    [highway='tertiary'],[highway='tertiary_link'] {
      line-width:@secondary_width+@outer_width;
      line-color:#aa0;
    }
    [highway='unclassified'],[highway='residential'] {
      line-width:@minor_width+@outer_width;
      line-color:#333;
    }
    [highway='service'],
    [highway='track'][tracktype='grade1'],
    [highway='track'][tracktype='grade2'] {
      line-width:@minor_width+@outer_width;
      line-color:#aaa;
    }
    [highway='track'][tracktype!='grade1'][tracktype!='grade2'] {
      line-width:@minor_width+@outer_width;
      line-color:#aaa;
      line-dasharray:6,2;
      line-cap:butt;
    }
  }

  ::inner {
    line-cap:round;
    line-join:bevel;
    line-color:white;
    [highway='motorway'],[highway='motorway_link'] {
      line-width:@motorway_width;
      line-color:blue;
    }
    [highway='trunk'],[highway='trunk_link'],
    [highway='primary'],[highway='primary_link'] {
      line-width:@primary_width;
      line-color:#f99;
    }
    [highway='secondary'],[highway='secondary_link'] {
      line-width:@secondary_width;
      line-color:#fb4;
    }
    [highway='tertiary'],[highway='tertiary_link'] {
      line-width:@secondary_width;
      line-color:#ff5;
    }
    [highway='unclassified'],[highway='residential'],
    [highway='service'],[highway='track'] {
      line-width:@minor_width;
    }
  }
}

#railway {
  line-width:1;
  line-color:black;
  line-cap:butt;
  line-join:bevel;
}

#buildings {
  polygon-fill:#eb6;
}

#paths {
  // from db: highway=footway/bridleway/cycleway
  // or anything with designation tag set
  line-width: 1.5;
  line-color:#999;
  line-dasharray:4,2;
  line-cap:butt;
  line-join:bevel;
  // probably public rights of way but no designation set
  [foot='designated'],[access='designated'],
  [foot='permissive'],[access='permissive'],
  [foot='yes'],[access='yes'] {
    line-color: #0a0;
  }
  // override colour if designation is explicitly set
  [designation='public_footpath'] {
    line-color: #f70;
  }
  [designation='public_bridleway'] {
    line-color: #66f;
  }
  [designation='restricted_byway'] {
    line-color: purple;
  }
  [designation='byway_open_to_all_traffic'] {
    line-color: red;
  }
}

#boundaries {
  line-width:0.5;
  [barrier='fence'] { line-color:#b83; }
  [barrier='hedge'] { line-color:#7b7; }
  [barrier='wall'] { line-color:#999; }
}

#contours {
  line-width:0.5;
  line-color:#f0f;
  line-opacity:0.8;
  line-cap:butt;
  line-dasharray:1,1;
}

#labels {
  text-name:[name];
  text-face-name:'Arial Regular';
  text-halo-fill: white; //fadeout(white,40%);
  text-size:8pt;
  text-halo-radius:1.5;
  text-fill: black; //#777;
  text-opacity:0.3;
  [place='city'] {
    text-size:35pt;
  }
  [place='town'] {
    text-size:28pt;
  }
  [place='suburb'],[place='neighbourhood']
  {
    text-size:21pt;
  }
  [place='village'],[place='hamlet'],
  [place='island'] {
    text-size:14pt;
  }
}

#grid {
  line-color:cyan;
  line-width:0.5;
  line-opacity:0.25;
}

// https://github.com/gregrs-uk/gb-leisure-carto/

Map {
  background-color: white;
}

#landuse {
  [natural='woodland'],
  [natural='wood'],
  [landuse='forest'] {
    polygon-fill:#cfc;
  }
  [landuse='residential'], [landuse='industrial'],
  [landuse='retail'], [landuse='commercial'],
  [landuse='farmyard'] {
    polygon-fill:#f0f0f0;
  }
}

#water {
  // natural=water and waterway=riverbank
  polygon-fill:#eff;
  line-width:1;
  line-color:#bcf;
}

#waterways {
  [waterway='stream'],[waterway='drain'],[waterway='ditch'] {
    line-width:1;
    line-color:#bcf;
  }
  [waterway='river'],[waterway='canal'] {
    ::outer {
      line-width:4;
      line-color:#bcf;
      line-cap:round;
      line-join:bevel;
    }
    ::inner {
      line-width:2;
      line-color:#eff;
      line-cap:round;
      line-join:bevel;
    }
  }
}

@motorway_width: 4;
@primary_width: 3;
@secondary_width: 3;
@minor_width: 2;
@outer_width: 1;

#roads {
  ::outer {
    line-cap:round;
    line-join:bevel;
    [highway='motorway'],[highway='motorway_link'] {
      line-width:@motorway_width+@outer_width;
    }
    [highway='trunk'],[highway='trunk_link'],
    [highway='primary'],[highway='primary_link'] {
      line-width:@primary_width+@outer_width;
      line-color:#700;
    }
    [highway='secondary'],[highway='secondary_link'] {
      line-width:@secondary_width+@outer_width;
      line-color:#910;
    }
    [highway='tertiary'],[highway='tertiary_link'] {
      line-width:@secondary_width+@outer_width;
      line-color:#aa0;
    }
    [highway='unclassified'],[highway='residential'] {
      line-width:@minor_width+@outer_width;
      line-color:#333;
    }
    [highway='service'],
    [highway='track'][tracktype='grade1'],
    [highway='track'][tracktype='grade2'] {
      line-width:@minor_width+@outer_width;
      line-color:#aaa;
    }
    [highway='track'][tracktype!='grade1'][tracktype!='grade2'] {
      line-width:@minor_width+@outer_width;
      line-color:#aaa;
      line-dasharray:6,2;
      line-cap:butt;
    }
  }

  ::inner {
    line-cap:round;
    line-join:bevel;
    line-color:white;
    [highway='motorway'],[highway='motorway_link'] {
      line-width:@motorway_width;
      line-color:blue;
    }
    [highway='trunk'],[highway='trunk_link'],
    [highway='primary'],[highway='primary_link'] {
      line-width:@primary_width;
      line-color:#f99;
    }
    [highway='secondary'],[highway='secondary_link'] {
      line-width:@secondary_width;
      line-color:#fb4;
    }
    [highway='tertiary'],[highway='tertiary_link'] {
      line-width:@secondary_width;
      line-color:#ff5;
    }
    [highway='unclassified'],[highway='residential'],
    [highway='service'],[highway='track'] {
      line-width:@minor_width;
    }
  }
}

#railway {
  line-width:1;
  line-color:black;
  line-cap:butt;
  line-join:bevel;
}

#buildings {
  polygon-fill:#eb6;
}

#paths {
  // from db: highway=footway/bridleway/cycleway
  // or anything with designation tag set
  line-width: 1.5;
  line-color:#999;
  line-dasharray:4,2;
  line-cap:butt;
  line-join:bevel;
  // probably public rights of way but no designation set
  [foot='designated'],[access='designated'],
  [foot='permissive'],[access='permissive'],
  [foot='yes'],[access='yes'] {
    line-color: green;
  }
  // override colour if designation is explicitly set
  [designation='public_footpath'] {
    line-color: #f70;
  }
  [designation='public_bridleway'] {
    line-color: #66f;
  }
  [designation='restricted_byway'] {
    line-color: purple;
  }
  [designation='byway_open_to_all_traffic'] {
    line-color: red;
  }
}

#boundaries {
  line-width:0.5;
  [barrier='fence'] { line-color:#b83; }
  [barrier='hedge'] { line-color:#7b7; }
  [barrier='wall'] { line-color:#999; }
}

#contours {
  line-width:0.5;
  line-color:#f0f;
  line-opacity:0.8;
  line-cap:butt;
  line-dasharray:1,1;
}

#labels {
  text-name:[name];
  text-face-name:'Arial Regular';
  text-halo-fill: white; //fadeout(white,40%);
  text-size:8pt;
  text-halo-radius:1.5;
  text-fill: black; //#777;
  text-opacity:0.3;
  [place='city'] {
    text-size:35pt;
  }
  [place='town'] {
    text-size:28pt;
  }
  [place='suburb'],[place='neighbourhood']
  {
    text-size:21pt;
  }
  [place='village'],[place='hamlet'],
  [place='island'] {
    text-size:14pt;
  }
}

#grid {
  line-color:cyan;
  line-width:0.5;
  line-opacity:0.25;
}


Remove unused 'campus' style.

Remove unused 'campus' style.

This functionality is handled by the landuse layer instead. Fixes #5.

/* BASE.MSS CONTENTS
 * - Landuse & landcover
 * - Water areas
 * - Water ways
 * - Administrative Boundaries
 *
 */

/* ================================================================== */
/* LANDUSE & LANDCOVER
/* ================================================================== */

#land[zoom>=0][zoom<6],
#shoreline_300[zoom>=6][zoom<10],
#processed_p[zoom>=10] {
  polygon-fill: @land;
  polygon-gamma: 0.75;
}

#landuse_gen0[zoom>3][zoom<=9],
#landuse_gen1[zoom>9][zoom<=12],
#landuse[zoom>12] {
  [type='cemetery']      { polygon-fill: @cemetery; }
  [type='college']       { polygon-fill: @school; }
  [type='commercial']    { polygon-fill: @industrial; }
  [type='forest']        { polygon-fill: @forest; }
  [type='golf_course']   { polygon-fill: @park; }
  [type='grass']         { polygon-fill: @park; }
  [type='hospital']      { polygon-fill: @hospital; }
  [type='industrial']    { polygon-fill: @industrial; }
  [type='park']          { polygon-fill: @park; }
  [type='parking']       { polygon-fill: @parking; }
  [type='pedestrian']    { polygon-fill: @pedestrian_fill; }
  [type='pitch']         { polygon-fill: @sports; }
  [type='residential']   { polygon-fill: @residential; }
  [type='school']        { polygon-fill: @school; }
  [type='sports_center'] { polygon-fill: @sports; }
  [type='stadium']       { polygon-fill: @sports; }
  [type='university']    { polygon-fill: @school; }
  [type='wood']          { polygon-fill: @forest; }
}

#landuse_overlays[type='nature_reserve'][zoom>6] {
  line-color: darken(@forest,25%);
  line-opacity:  0.3;
  line-dasharray: 1,1;
  polygon-fill: darken(@forest,25%);
  polygon-opacity: 0.1;
  [zoom=7] { line-width: 0.4; }
  [zoom=8] { line-width: 0.6; }
  [zoom=9] { line-width: 0.8; }
  [zoom=10] { line-width: 1.0; }
  [zoom=11] { line-width: 1.5; }
  [zoom>=12] { line-width: 2.0; }
}

/* ---- BUILDINGS ---- */
#buildings[zoom>10][zoom<=16] {
  polygon-fill:@building;
  [zoom>13] {
    line-color:darken(@building,5);
    line-width:0.2;
  }
  [zoom>15] {
    line-color:darken(@building,10);
    line-width:0.4;
  }
}
/* At the highest zoom levels, render buildings in fancy pseudo-3D */
#buildings[zoom>=17] {
  building-fill:@building;
  building-height:1.25;
}

/* ================================================================== */
/* WATER AREAS
/* ================================================================== */

Map { background-color: @water; }

#water_gen0[zoom>3][zoom<=9],
#water_gen1[zoom>9][zoom<=12],
#water[zoom>12] {
  polygon-fill: @water;
}

/* ================================================================== */
/* WATER WAYS
/* ================================================================== */

#waterway[type='river'][zoom>5] {
  line-color: @water;
  [zoom=6] { line-width: 0.15; }
  [zoom=7] { line-width: 0.25; }
  [zoom=8] { line-width: 0.5; }
  [zoom=9] { line-width: 1; }
  [zoom=10]{ line-width: 1; }
  [zoom>10]{
    line-cap: round;
    line-join: round;
  }
  [zoom=11]{ line-width: 2; }
  [zoom=12]{ line-width: 2; }
  [zoom=13]{ line-width: 3; }
  [zoom=14]{ line-width: 3; }
  [zoom=15]{ line-width: 4; }
  [zoom=16]{ line-width: 5; }
  [zoom=17]{ line-width: 6; }
  [zoom>17]{ line-width: 7; }
}

#waterway[type='stream'][zoom>9] {
  line-color: @water;
  [zoom=10]{ line-width: 0.5; }
  [zoom=11]{ line-width: 0.5; }
  [zoom=12]{ line-width: 1; }
  [zoom=13]{ line-width: 1; }
  [zoom>13]{
    line-width: 2;
    line-join: round;
    line-cap: round;
  }
}

#waterway[type='canal'][zoom>9] {
  line-color: @water;
  [zoom=10]{ line-width: 0.5; }
  [zoom=11]{ line-width: 0.5; }
  [zoom=12]{ line-width: 1; }
  [zoom=13]{ line-width: 1; }
  [zoom>13]{
    line-cap: round;
    line-join: round;
  }
  [zoom=14]{ line-width: 2; }
  [zoom=15]{ line-width: 4; }
  [zoom=16]{ line-width: 8; }
  [zoom=17]{ line-width: 16; }
  [zoom>17]{ line-width: 30; }
}

/* == 7. ADMINISTRATIVE BOUNDARIES ================================== */

#admin[admin_level=2][zoom>1] {
  line-color:@admin_2;
  line-width:0.5;
  [zoom=2] { line-opacity: 0.25; }
  [zoom=3] { line-opacity: 0.3; }
  [zoom=4] { line-opacity: 0.4; }
}

/* ****************************************************************** */

/* BASE.MSS CONTENTS
 * - Landuse & landcover
 * - Water areas
 * - Water ways
 * - Administrative Boundaries
 *
 */

/* ================================================================== */
/* LANDUSE & LANDCOVER
/* ================================================================== */

#land[zoom>=0][zoom<6],
#shoreline_300[zoom>=6][zoom<10],
#processed_p[zoom>=10] {
  polygon-fill: @land;
  polygon-gamma: 0.75;
}

#landuse_gen0[zoom>3][zoom<=9],
#landuse_gen1[zoom>9][zoom<=12],
#landuse[zoom>12] {
  [type='cemetery']      { polygon-fill: @cemetery; }
  [type='college']       { polygon-fill: @school; }
  [type='commercial']    { polygon-fill: @industrial; }
  [type='forest']        { polygon-fill: @forest; }
  [type='golf_course']   { polygon-fill: @park; }
  [type='grass']         { polygon-fill: @park; }
  [type='hospital']      { polygon-fill: @hospital; }
  [type='industrial']    { polygon-fill: @industrial; }
  [type='park']          { polygon-fill: @park; }
  [type='parking']       { polygon-fill: @parking; }
  [type='pedestrian']    { polygon-fill: @pedestrian_fill; }
  [type='pitch']         { polygon-fill: @sports; }
  [type='residential']   { polygon-fill: @residential; }
  [type='school']        { polygon-fill: @school; }
  [type='sports_center'] { polygon-fill: @sports; }
  [type='stadium']       { polygon-fill: @sports; }
  [type='university']    { polygon-fill: @school; }
  [type='wood']          { polygon-fill: @forest; }
}

#landuse_overlays[type='nature_reserve'][zoom>6] {
  line-color: darken(@forest,25%);
  line-opacity:  0.3;
  line-dasharray: 1,1;
  polygon-fill: darken(@forest,25%);
  polygon-opacity: 0.1;
  [zoom=7] { line-width: 0.4; }
  [zoom=8] { line-width: 0.6; }
  [zoom=9] { line-width: 0.8; }
  [zoom=10] { line-width: 1.0; }
  [zoom=11] { line-width: 1.5; }
  [zoom>=12] { line-width: 2.0; }
}

/* Note that amenity=school, amenity=hospital, etc are ideally polygons of the
   *campus*, but are occasionally applied to the physical building instead. */
@campus: #ECF;
#campus[zoom>10] {
  polygon-opacity:0.2;
  polygon-fill:@campus;
  [zoom>12] {
    line-opacity:0.4;
    line-color:spin(darken(@campus,20),20);
  }
  [zoom=13] { line-width:0.3; }
  [zoom=14] { line-width:0.5; }
  [zoom=15] { line-width:0.7; }
  [zoom=16] { line-width:0.8; }
  [zoom=17] { line-width:0.9; }
  [zoom=18] { line-width:1.0; }
}

/* ---- BUILDINGS ---- */
#buildings[zoom>10][zoom<=16] {
  polygon-fill:@building;
  [zoom>13] {
    line-color:darken(@building,5);
    line-width:0.2;
  }
  [zoom>15] {
    line-color:darken(@building,10);
    line-width:0.4;
  }
}
/* At the highest zoom levels, render buildings in fancy pseudo-3D */
#buildings[zoom>=17] {
  building-fill:@building;
  building-height:1.25;
}

/* ================================================================== */
/* WATER AREAS
/* ================================================================== */

Map { background-color: @water; }

#water_gen0[zoom>3][zoom<=9],
#water_gen1[zoom>9][zoom<=12],
#water[zoom>12] {
  polygon-fill: @water;
}

/* ================================================================== */
/* WATER WAYS
/* ================================================================== */

#waterway[type='river'][zoom>5] {
  line-color: @water;
  [zoom=6] { line-width: 0.15; }
  [zoom=7] { line-width: 0.25; }
  [zoom=8] { line-width: 0.5; }
  [zoom=9] { line-width: 1; }
  [zoom=10]{ line-width: 1; }
  [zoom>10]{
    line-cap: round;
    line-join: round;
  }
  [zoom=11]{ line-width: 2; }
  [zoom=12]{ line-width: 2; }
  [zoom=13]{ line-width: 3; }
  [zoom=14]{ line-width: 3; }
  [zoom=15]{ line-width: 4; }
  [zoom=16]{ line-width: 5; }
  [zoom=17]{ line-width: 6; }
  [zoom>17]{ line-width: 7; }
}

#waterway[type='stream'][zoom>9] {
  line-color: @water;
  [zoom=10]{ line-width: 0.5; }
  [zoom=11]{ line-width: 0.5; }
  [zoom=12]{ line-width: 1; }
  [zoom=13]{ line-width: 1; }
  [zoom>13]{
    line-width: 2;
    line-join: round;
    line-cap: round;
  }
}

#waterway[type='canal'][zoom>9] {
  line-color: @water;
  [zoom=10]{ line-width: 0.5; }
  [zoom=11]{ line-width: 0.5; }
  [zoom=12]{ line-width: 1; }
  [zoom=13]{ line-width: 1; }
  [zoom>13]{
    line-cap: round;
    line-join: round;
  }
  [zoom=14]{ line-width: 2; }
  [zoom=15]{ line-width: 4; }
  [zoom=16]{ line-width: 8; }
  [zoom=17]{ line-width: 16; }
  [zoom>17]{ line-width: 30; }
}

/* == 7. ADMINISTRATIVE BOUNDARIES ================================== */

#admin[admin_level=2][zoom>1] {
  line-color:@admin_2;
  line-width:0.5;
  [zoom=2] { line-opacity: 0.25; }
  [zoom=3] { line-opacity: 0.3; }
  [zoom=4] { line-opacity: 0.4; }
}

/* ****************************************************************** */


landcover and color weaks

landcover and color weaks

@color_physical: #dee0be;
@color_physical_bright: #fff;
@color_water: #99b3cc;
@color_administrative_lowzoom: #000;
@color_administrative_dark: #000;
@color_administrative_bright: #fff;
@color_administrative_medium_low: #000;
@color_administrative_medium_high: #000;
@color_administrative_medium_high2: #000;
@color_transport: #999;
@color_transport_casing: #ddd;
@color_transport_inline: #fff;
@color_transport_tunnel: #ccc;
@color_transport_minor: #ccc;
@color_transport_rail: #444;
@color_transport_path: #ededed;
@color_building: #cdd;
@color_building_outline: darken(@color_building,20);
@color_building_outline_special: #00aeef;
@color_airport_runways: @color_transport;
@color_airport_runways_detail: darken(@color_airport_runways,20);
@color_green_areas: darken(#c0d3b5,20);

Map {
  background-color: @color_physical;
  font-directory: url("fonts/");
}

/**
 * "shore" is a general class for layers with continents, coastlines, lakes,
 * and other kinds of meeting points between water and land.
 */
.shore {
  line-color: @color_physical;
  /* lighten background color, as we decrease landcover opacity */
  [zoom>=12] {
    polygon-fill: lighten(@color_physical,20);
  }
  [zoom>=14] {
    polygon-fill: lighten(@color_physical,40);
  }

  line-cap: round;
  line-join: round;
  line-width: 0;
}

#ne_10m_rivers_lake_centerlines_scale_rank
{
  [zoom=4][scalerank<4] {
    line-color: @color_water;
    line-width: 0.5;
    [strokeweig>1] { line-width: 1; }
    [strokeweig>2] { line-width: 2; }
  }
  [zoom=5][scalerank<5] {
    line-color: @color_water;
    line-width: 0.5;
    [strokeweig>1] { line-width: 1; }
    [strokeweig>2] { line-width: 2; }
  }
  [zoom=6][scalerank<6] {
    line-color: @color_water;
    line-width: 0.5;
    [strokeweig>1] { line-width: 1; }
    [strokeweig>2] { line-width: 2; }
  }
  [zoom=7][scalerank<7] {
    line-color: @color_water;
    line-width: 1;
    [strokeweig>1] { line-width: 1.5; }
    [strokeweig>2] { line-width: 2.5; }
  }
  [zoom>=8] {
    line-width: 1;
    line-color: @color_water;
    [strokeweig>1] { line-width: 2; }
    [strokeweig>2] { line-width: 3; }
  }
}

#water,
#ne_10m_ocean,
#ne_10m_lakes,
#ne_50m_lakes
{
  //line-width: 0.5;
  line-color: @color_water;
  polygon-fill: @color_water;
}

.country-boundary[scalerank<6],
.country-boundary-10m[scalerank<6] {
  line-color: @color_administrative_dark;
  line-opacity: 0.2;
  line-width: 2;
  line-dasharray: 7,3;
  ::glow {
    line-color: @color_administrative_dark;
    line-opacity: 0.08;
    line-width: 4;
    line-dasharray: 7,3;
  }
}

#admin1-lines-10m,
#admin0-map-units-10m {
  [zoom>=4][adm0_a3='CAN'],
  [zoom>=4][adm0_a3='USA'],
  [zoom>=4][adm0_a3='AUS'],
  [zoom>=5][scalerank<=2],
  [zoom>=5][featurecla='Map unit boundary'][adm0_a3='GBR'],
  [zoom>=6][scalerank<=4],
  [zoom>=6][featurecla='Map unit boundary'][adm0_a3='GBR'] {
    line-color: @color_administrative_dark;
    line-opacity: 0.15;
    line-width: 1.5;
    line-dasharray: 7,3;
    ::glow {
      line-color: @color_administrative_dark;
      line-opacity: 0.05;
      line-width: 3;
      line-dasharray: 7,3;
    }
  }

  [zoom>=7][scalerank<=5] {
    line-width: 1;
    line-color: @color_administrative_medium_low;
    line-dasharray: 1,5;
    line-cap: round;
  }

  [zoom>=8][scalerank<=6] {
    line-width: 1.2;
    line-color: @color_administrative_medium_high;
    line-dasharray: 1,5;
    line-cap: round;
  }

  [zoom>=9][scalerank<=8] {
    line-width: 1.2;
    line-color: @color_administrative_medium_high2;
    line-dasharray: 1,5;
    line-cap: round;
  }
}

#lakes-50m[zoom<3][scalerank<1],
#lakes-50m[zoom=3][scalerank<2],
#lakes-50m[zoom=4][scalerank<3],
#lakes-50m[zoom=5][scalerank<5],
#lakes-50m[zoom=6],
#lakes-10m,
{
  line-width: 1;
  polygon-fill: @color_physical;
}

#ne-roads[zoom=7][scalerank<=4],
#ne-roads[zoom>=8][scalerank<=8] {
  ::casing {
    line-color: @color_transport_casing;
    line-opacity: 0.5;
    line-width: 1.5;

    [zoom=8][scalerank<=6] {
      line-width: 3;
    }
  }

  line-color: @color_transport;
  line-width: 0;

  [zoom=8][scalerank<=6] {
    line-width: 1;
  }
}

/**
 * Ocean, lake, and river polygons
 */
#water-bodies-low[zoom=8][area>50000000],
#water-bodies-low[zoom=9][area>10000000],
#water-bodies-low[zoom=10][area>2500000],
#water-bodies-med[zoom=11][area> 800000],
#water-bodies-med[zoom=12][area> 500000],
#water-bodies-med[zoom=13][area>  25000],
#water-bodies-high[zoom=14][area> 10000],
#water-bodies-high[zoom>=15]
{
  polygon-fill: @color_water;
}

/**
 * Water bodies that are parts of rivers
 * should never be filtered
 */
#water-bodies-low[type='riverbank'],
#water-bodies-med[type='riverbank'],
#water-bodies-high[type='riverbank']
{
  polygon-fill: @color_water;
}

#nullisland {
  polygon-fill: @color_physical;
}

#admin1-lines-osm,
{
  line-width: 2.0;
  line-color: @color_administrative_medium_high2;
  line-dasharray: 1,5;
  line-cap: round;
}

/**
 * Zoom 13 buildings.
 * Already filtered by size upon import.
 */
#buildings-med[type!='no'] {
  polygon-fill: @color_building;
  line-width: 0.5;
  line-color: @color_building_outline;
}

/**
 * Zoom 14+ buildings.
 * Includes all buildings.
 */
#buildings-high[type!='no'] {
  [zoom=14] {
    [area>=5000] {
      polygon-fill: @color_building;
      line-width: 0.5;
      line-color: @color_building_outline;
    }
  }

  /**
   * This is for outlines and no stripe. Catches small buildings.
   * Larger buildings will be overridden with stripes below.
   */
  [zoom>=15][area>=2000],
  [zoom>=16] {
    polygon-fill: @color_building;
    line-width: 0.5;
    line-color: @color_building_outline;
  }

  [zoom=15][area>=3000],
  [zoom=16][area>=2000],
  [zoom=17][area>=1000],
  [zoom>=18],
  {
    polygon-fill: @color_building;
    line-width: 0.5;
    line-color: @color_building_outline;
  }

  // Stamen HQ fancy candycane striping
  [zoom>=18] {
    [osm_id=260351411],
    [osm_id=224030635], // Seth's house
    [osm_id=248153467], // Sean's house
    [osm_id=291796473], // Stamen South
    {
      polygon-fill: @color_building;
      line-width: 1.5;
      line-color: @color_building_outline_special;
    }
  }
}

#green-areas-low[zoom=10][area>5000000],
#green-areas-med[zoom=11][area>1000000],
#green-areas-med[zoom=12][area> 500000],
#green-areas-med[zoom=12][area> 200000],
#green-areas-med[zoom=13][area>  75000],
#green-areas-high[zoom=14][area> 10000],
#green-areas-high[zoom>14],
{
  polygon-fill: @color_green_areas;
  polygon-opacity: 0.5;

  [type='nature_reserve'] {
    polygon-fill: @color_green_areas;
    polygon-opacity: 0.3;
  }
}

#aeroways {
  line-color: @color_airport_runways;
  line-cap: square;
  line-join: miter;

  [zoom>=15] {
    line-color: @color_airport_runways_detail;
  }

  [type='runway'] {
    [zoom=12] {
      line-width: 2;
    }

    [zoom=13] {
      line-width: 4;
    }

    [zoom=14] {
      line-width: 8;
    }

    [zoom=15] {
      line-width: 16;
    }

    [zoom=16] {
      line-width: 32;
    }

    [zoom=17] {
      line-width: 64;
    }

    [zoom>=18] {
      line-width: 128;
    }
  }

  [type='taxiway'] {
    [zoom=13] {
      line-width: 1;
    }

    [zoom=14] {
      line-width: 2;
    }

    [zoom=15] {
      line-width: 4;
    }

    [zoom=16] {
      line-width: 8;
    }

    [zoom=17] {
      line-width: 16;
    }

    [zoom>=18] {
      line-width: 32;
    }
  }
}

#tunnels,
#roads,
#roads_med,
#highways_med,
#bridges {
  ::casing,
  ::outline,
  {
    line-cap: butt;
    line-width: 0;
    line-color: @color_transport_casing;
  }

  line-join: round;
  line-cap: round;
  line-width: 1;
  line-color: @color_transport;
}

#tunnels {
  [zoom>=14] {
    ::outline
    {
      line-opacity: 0.7;
      line-color: @color_transport_tunnel;
    }

    line-opacity: 0.5;
    line-width: 4;
  }
}

#tunnels[kind='highway'] {
  [zoom>=15] {
    ::outline {
      line-width: 5.5;
    }

    line-width: 4;
  }

  [zoom>=16] {
    ::outline {
      line-width: 7;
      line-opacity: 0.4;
    }

    line-opacity: 0.7;
    line-color: @color_transport_tunnel;

    [is_link='yes'] {
      ::outline {
        line-color: @color_transport_casing;
      }
    }
  }

  [zoom>=17] {
    ::outline {
      line-width: 18;
    }

    line-width: 12;

    [is_link='yes'] {
      ::outline {
        line-width: 9;
      }
    }
  }

  [zoom>=18] {
    ::outline {
      line-width: 22;
      line-color: @color_transport;
    }

    line-width: 18;
    line-color: @color_transport_inline;
  }

  [zoom>=19] {
    ::outline {
      line-width: 30;
    }

    line-width: 26;

    [is_link='yes'] {
      ::outline {
        line-width: 13;
      }
    }
  }
}

#tunnels[kind='major_road'] {
  [zoom>=15] {
    ::outline {
      line-width: 5;
      line-opacity: 0.7;
      line-color: @color_transport_tunnel;
    }

    line-width: 3;
    line-opacity: 0.5;
  }

  [zoom>=16] {
    ::outline {
      line-width: 7;
      line-opacity: 0.4;
    }

    line-opacity: 0.7;
    line-color: @color_transport_tunnel;

    [is_link='yes'] {
      ::outline {
        line-color: @color_transport_casing;
      }
    }
  }

  [zoom>=17] {
    ::outline {
      line-width: 18;
    }

    line-width: 12;

    [is_link='yes'] {
      ::outline {
        line-width: 9;
      }
    }
  }

  [zoom>=18] {
    ::outline {
      line-width: 22;
    }

    line-width: 18;
  }

  [zoom>=19] {
    ::outline {
      line-width: 30;
    }

    line-width: 26;

    [is_link='yes'] {
      ::outline {
        line-width: 13;
      }
    }
  }
}

#tunnels[kind='minor_road'] {
  [zoom>=15] {
    ::outline {
      line-opacity: 0.7;
      line-color: @color_transport_tunnel;
    }

    line-color: @color_transport_minor;
    line-width: 1.5;
    line-opacity: 0.5;
  }

  [zoom>=16] {
    ::outline {
      line-width: 7;
    }

    line-width: 4;
    line-color: @color_transport;
  }

  [zoom>=17] {
    ::outline {
      line-width: 9;
    }

    line-width: 7;
  }

  [zoom>=18] {
    ::outline {
      line-width: 17;
      line-color: @color_transport;
    }

    line-width: 13;
    line-color: @color_transport_casing;
  }

  [zoom>=19] {
    ::outline {
      line-width: 20;
    }

    line-width: 16;
  }
}

#bridges[kind='highway'] {
  [zoom>=13] {
    ::outline {
      line-width: 8;
    }

    line-width: 4;

    [is_link='yes'] {
      ::outline {
        line-width: 0;
      }

      line-width: 1;
    }
  }

  [zoom>=14] {
    ::outline {
      line-width: 8;
    }

    line-width: 4;

    [is_link='yes'] {
      ::outline {
        line-width: 4;
      }

      line-width: 2.5;
    }
  }

  [zoom>=15] {
    ::outline {
      line-width: 11;
    }

    line-width: 6;

    [is_link='yes'] {
      ::outline {
        line-width: 5.5;
      }

      line-width: 2.5;
    }
  }

  [zoom>=16] {
    ::outline {
      line-width: 14;
    }

    line-width: 9;

    [is_link='yes'] {
      ::outline {
        line-width: 7;
      }

      line-width: 2.5;
    }
  }

  [zoom>=17] {
    ::outline {
      line-width: 20;
    }

    line-width: 15;

    [is_link='yes'] {
      ::outline {
        line-width: 9;
      }

      line-width: 5;
    }
  }

  [zoom>=18] {
    ::outline {
      line-width: 44;
      line-color: @color_transport;
    }

    line-width: 28;
    line-color: @color_transport_inline;

    [is_link='yes'] {
      ::outline {
        line-width: 22;
      }

      line-width: 18;
    }
  }

  [zoom>=19] {
    ::outline {
      line-width: 51;
    }

    line-width: 35;

    [is_link='yes'] {
      ::outline {
        line-width: 21;
      }

      line-width: 16;
    }
  }
}

#bridges[kind='major_road'] {
  line-color: @color_transport;

  [zoom>=14] {
    ::outline {
      line-width: 5;
    }

    line-width: 1.9;
  }

  [zoom>=15] {
    ::outline {
      line-width: 8.5;
    }

    line-width: 5.5;

    [is_link='yes'] {
      ::outline {
        line-width: 5.5;
      }

      line-width: 2.5;
    }
  }

  [zoom>=16] {
    ::outline {
      line-width: 11;
    }

    line-width: 7;

    [is_link='yes'] {
      ::outline {
        line-width: 7;
      }

      line-width: 2.5;
    }
  }

  [zoom>=17] {
    ::outline {
      line-width: 18;
    }

    line-width: 12;

    [is_link='yes'] {
      ::outline {
        line-width: 8;
      }

      line-width: 4;
    }
  }

  [zoom>=18] {
    ::outline {
      line-width: 24;
      line-color: @color_transport;
    }

    line-width: 18;
    line-color: @color_transport_inline;

    [is_link='yes'] {
      ::outline {
        line-width: 14;
      }

      line-width: 9;
    }
  }

  [zoom>=19] {
    ::outline {
      line-width: 32;
    }

    line-width: 26;

    [is_link='yes'] {
      ::outline {
        line-width: 18;
      }

      line-width: 13;
    }
  }
}

#roads,
#roads_med,
#highways_med {
  ::casing,
  ::outline,
  {
    line-cap: butt;
    line-width: 0;
    line-color: @color_transport_casing;
  }

  line-join: round;
  line-cap: round;
  line-width: 0;
  line-color: @color_transport;

  [is_link='yes']
  {
    [zoom>=16]
    {
      ::casing {
        line-width: 8;
      }

      line-width: 4;
    }
  }
}

#roads[kind='highway'],
#highways_med[kind='highway']
{
  [zoom>=9] {
    ::outline {
      line-width: 4.25;
    }

    line-width: 1.5;
  }

  [zoom>=10] {
    ::outline {
      line-width: 5;
    }

    line-width: 2;
  }

  [zoom>=11] {
    ::outline {
      line-width: 6;
    }

    line-width: 2.5;
  }

  [zoom>=12] {
    ::outline {
      line-width: 7;
    }

    line-width: 3;

    [is_link='yes'] {
      ::outline {
        line-width: 0;
      }

      line-width: 0.5;
    }
  }

  [zoom>=13] {
    ::outline {
      line-width: 8;
    }

    [is_link='yes'] {
      ::outline {
        line-width: 0;
      }

      line-width: 1;
    }
  }

  [zoom>=14] {
    ::outline {
      line-width: 9;
    }

    line-width: 4;

    [is_link='yes'] {
      ::outline {
        line-width: 4;
      }

      line-width: 2.5;
    }
  }

  [zoom>=15] {
    ::casing {
      line-width: 11;
    }

    line-width: 6;

    [is_link='yes'] {
      ::casing {
        line-width: 6.5;
      }

      line-width: 2.25;
    }
  }

  [zoom>=16] {
    ::casing {
      line-width: 14;
    }

    line-width: 9;

    [is_link='yes'] {
      ::casing {
        line-width: 7;
      }

      line-width: 2.5;
    }
  }

  [zoom>=17] {
    ::casing {
      line-width: 24;
    }

    line-width: 15;

    [is_link='yes'] {
      ::casing {
        line-width: 9;
      }

      line-width: 5;
    }
  }

  [zoom>=18] {
    ::casing {
      line-width: 42;
      line-color: @color_transport;
    }

    line-width: 28;
    line-color: @color_transport_inline;

    [is_link='yes'] {
      ::casing {
        line-width: 14;
      }

      line-width: 10;
    }
  }

  [zoom>=19] {
    ::casing {
      line-width: 49;
    }

    line-width: 35;

    [is_link='yes'] {
      ::casing {
        line-width: 20;
      }

      line-width: 16;
    }
  }
}

#roads[kind='major_road'],
#roads_med[kind='major_road']
{
  [zoom<=12] {
    line-color: @color_transport;
  }

  [zoom>=9] {
    line-width: 0.15;
  }

  [zoom>=10] {
    line-width: 0.5;
  }

  [zoom>=11] {
    ::outline {
      line-width: 1.25;
    }

    line-width: 0.7;
  }

  [zoom>=12] {
    ::outline {
      line-width: 5;
    }

    line-width: 1;

    [is_link='yes'] {
      ::outline {
        line-width: 0;
      }

      line-width: 0.5;
    }
  }

  [zoom>=13] {
    line-width: 1.5;
  }

  [zoom>=14] {
    ::outline {
      line-width: 5;
    }

    line-width: 1.9;

    [is_link='yes'] {
      ::outline {
        line-width: 5;
      }

      line-width: 1.9;
    }
  }

  [zoom>=15] {
    ::casing {
      line-width: 8;
    }

    line-width: 5;

    [is_link='yes'] {
      ::casing {
        line-width: 5.5;
      }

      line-width: 2.25;
    }
  }

  [zoom>=16] {
    ::casing {
      line-width: 11;
    }

    line-width: 7;

    [is_link='yes'] {
      ::casing {
        line-width: 7;
      }

      line-width: 2.5;
    }
  }

  [zoom>=17] {
    ::casing {
      line-width: 18;
    }

    line-width: 12;

    [is_link='yes'] {
      ::casing {
        line-width: 8;
      }

      line-width: 4;
    }
  }

  [zoom>=18] {
    ::casing {
      line-width: 22;
      line-color: @color_transport;
    }

    line-width: 18;
    line-color: @color_transport_inline;

    [is_link='yes'] {
      ::casing {
        line-width: 13;
      }

      line-width: 9;
    }
  }

  [zoom>=19] {
    ::casing {
      line-width: 30;
    }

    line-width: 26;

    [is_link='yes'] {
      ::casing {
        line-width: 17;
      }

      line-width: 13;
    }
  }
}

#roads[kind='minor_road'],
#roads_med[kind='minor_road']
{
  line-color: @color_transport_minor;

  [zoom>=10] {
    line-width: 0.2;
  }

  [zoom>=13] {
    line-width: 0.4;
  }

  [zoom>=14] {
    line-width: 0.8;
  }

  [zoom>=15] {
    line-width: 1.5;
  }

  [zoom>=16] {
    ::casing {
      line-width: 7;
    }

    line-width: 4;
    line-color: @color_transport;
  }

  [zoom>=17] {
    ::casing {
      line-width: 9;
    }

    line-width: 7;
  }

  [zoom>=18] {
    ::casing {
      line-width: 17;
      line-color: @color_transport;
    }

    line-width: 13;
    line-color: @color_transport_casing;
  }

  [zoom>=19] {
    ::casing {
      line-width: 20;
    }

    line-width: 16;
  }
}

#tunnels[kind='rail'],
#roads[kind='rail'],
#bridges[kind='rail']
{
  ::casing,
  ::outline,
  {
    line-color: @color_transport_rail;
  }

  line-color: @color_transport_rail;

  [zoom>=14] {
    ::casing {
      line-width: 3;
      line-dasharray: 1,3;
    }

    line-width: 1;
  }

  [zoom>=16] {
    ::casing {
      line-width: 5;
      line-dasharray: 1,4;
    }
  }

  [zoom>=18] {
    ::casing {
      line-width: 6;
      line-dasharray: 2,6;
    }

    line-width: 2;
  }

  [zoom>=19] {
    ::casing {
      line-width: 9;
      line-dasharray: 4,7;
    }

    line-width: 4;
  }
}

#tunnels[highway='service'],
#roads[highway='service'],
#bridges[highway='service'],
{
  [zoom>=15]
  {
    line-width: 1.5;
  }

  [zoom>=16] {
    ::casing {
      line-width: 4;
    }

    line-width: 2;
  }

  [zoom>=17] {
    ::casing {
      line-width: 6;
    }

    line-width: 4;
  }
}

#tunnels[kind='path'],
#roads[kind='path'],
#bridges[kind='path'],
{
  ::casing {
    line-color: @color_transport_path;
  }

  line-color: @color_transport_casing;

  [zoom>=15] {
    ::casing {
      line-width: 4;
    }

    line-width: 1.5;
    line-cap: butt;
  }

  [zoom>=16] {
    ::casing {
      line-width: 5;
    }

    line-width: 2;
  }

  [zoom>=17] {
    line-width: 3;
  }

  [zoom>=19] {
    line-width: 4;
  }
}

.landcoverraster {
  raster-opacity:1;
  raster-scaling:gaussian;

  /* blur landcover as it becomes too pixelated */
/*
  [zoom>=10] {
    image-filters: agg-stack-blur(5,5);
  }
  [zoom>=12] {
    image-filters: agg-stack-blur(10,10);
    opacity: 0.8;
  }
  [zoom>=14] {
    image-filters: agg-stack-blur(20,20);
    opacity: 0.6;
  }
*/
}

@color_physical: #dee0be;
@color_physical_bright: #fff;
@color_water: #99b3cc;
@color_administrative_lowzoom: #000;
@color_administrative_dark: #000;
@color_administrative_bright: #fff;
@color_administrative_medium_low: #000;
@color_administrative_medium_high: #000;
@color_administrative_medium_high2: #000;
@color_transport: #999;
@color_transport_casing: #ddd;
@color_transport_inline: #fff;
@color_transport_tunnel: #ccc;
@color_transport_minor: #ccc;
@color_transport_rail: #444;
@color_transport_path: #ededed;
@color_building: #cdd;
@color_building_outline: darken(@color_building,20);
@color_building_outline_special: #00aeef;
@color_airport_runways: @color_transport;
@color_airport_runways_detail: darken(@color_airport_runways,20);
@color_green_areas: darken(#c0d3b5,20);

Map {
  background-color: @color_physical;
  font-directory: url("fonts/");
}

/**
 * "shore" is a general class for layers with continents, coastlines, lakes,
 * and other kinds of meeting points between water and land.
 */
.shore {
  line-color: @color_physical;
  line-cap: round;
  line-join: round;
  line-width: 0;
}

#ne_10m_rivers_lake_centerlines_scale_rank
{
  [zoom=4][scalerank<4] {
    line-color: @color_water;
    line-width: 0.5;
    [strokeweig>1] { line-width: 1; }
    [strokeweig>2] { line-width: 2; }
  }
  [zoom=5][scalerank<5] {
    line-color: @color_water;
    line-width: 0.5;
    [strokeweig>1] { line-width: 1; }
    [strokeweig>2] { line-width: 2; }
  }
  [zoom=6][scalerank<6] {
    line-color: @color_water;
    line-width: 0.5;
    [strokeweig>1] { line-width: 1; }
    [strokeweig>2] { line-width: 2; }
  }
  [zoom=7][scalerank<7] {
    line-color: @color_water;
    line-width: 1;
    [strokeweig>1] { line-width: 1.5; }
    [strokeweig>2] { line-width: 2.5; }
  }
  [zoom>=8] {
    line-width: 1;
    line-color: @color_water;
    [strokeweig>1] { line-width: 2; }
    [strokeweig>2] { line-width: 3; }
  }
}

#water,
#ne_10m_ocean,
#ne_10m_lakes,
#ne_50m_lakes
{
  //line-width: 0.5;
  line-color: @color_water;
  polygon-fill: @color_water;
}

.country-boundary[scalerank<6],
.country-boundary-10m[scalerank<6] {
  line-color: @color_administrative_dark;
  line-opacity: 0.2;
  line-width: 2;
  line-dasharray: 7,3;
  ::glow {
    line-color: @color_administrative_dark;
    line-opacity: 0.08;
    line-width: 4;
    line-dasharray: 7,3;
  }
}

#admin1-lines-10m,
#admin0-map-units-10m {
  [zoom>=4][adm0_a3='CAN'],
  [zoom>=4][adm0_a3='USA'],
  [zoom>=4][adm0_a3='AUS'],
  [zoom>=5][scalerank<=2],
  [zoom>=5][featurecla='Map unit boundary'][adm0_a3='GBR'],
  [zoom>=6][scalerank<=4],
  [zoom>=6][featurecla='Map unit boundary'][adm0_a3='GBR'] {
    line-color: @color_administrative_dark;
    line-opacity: 0.15;
    line-width: 1.5;
    line-dasharray: 7,3;
    ::glow {
      line-color: @color_administrative_dark;
      line-opacity: 0.05;
      line-width: 3;
      line-dasharray: 7,3;
    }
  }

  [zoom>=7][scalerank<=5] {
    line-width: 1;
    line-color: @color_administrative_medium_low;
    line-dasharray: 1,5;
    line-cap: round;
  }

  [zoom>=8][scalerank<=6] {
    line-width: 1.2;
    line-color: @color_administrative_medium_high;
    line-dasharray: 1,5;
    line-cap: round;
  }

  [zoom>=9][scalerank<=8] {
    line-width: 1.2;
    line-color: @color_administrative_medium_high2;
    line-dasharray: 1,5;
    line-cap: round;
  }
}

#lakes-50m[zoom<3][scalerank<1],
#lakes-50m[zoom=3][scalerank<2],
#lakes-50m[zoom=4][scalerank<3],
#lakes-50m[zoom=5][scalerank<5],
#lakes-50m[zoom=6],
#lakes-10m,
{
  line-width: 1;
  polygon-fill: @color_physical;
}

#ne-roads[zoom=7][scalerank<=4],
#ne-roads[zoom>=8][scalerank<=8] {
  ::casing {
    line-color: @color_transport_casing;
    line-opacity: 0.5;
    line-width: 1.5;

    [zoom=8][scalerank<=6] {
      line-width: 3;
    }
  }

  line-color: @color_transport;
  line-width: 0;

  [zoom=8][scalerank<=6] {
    line-width: 1;
  }
}

/**
 * Ocean, lake, and river polygons
 */
#water-bodies-low[zoom=8][area>50000000],
#water-bodies-low[zoom=9][area>10000000],
#water-bodies-low[zoom=10][area>2500000],
#water-bodies-med[zoom=11][area> 800000],
#water-bodies-med[zoom=12][area> 500000],
#water-bodies-med[zoom=13][area>  25000],
#water-bodies-high[zoom=14][area> 10000],
#water-bodies-high[zoom>=15]
{
  polygon-fill: @color_water;
}

/**
 * Water bodies that are parts of rivers
 * should never be filtered
 */
#water-bodies-low[type='riverbank'],
#water-bodies-med[type='riverbank'],
#water-bodies-high[type='riverbank']
{
  polygon-fill: @color_water;
}

#nullisland {
  polygon-fill: @color_physical;
}

#admin1-lines-osm,
{
  line-width: 2.0;
  line-color: @color_administrative_medium_high2;
  line-dasharray: 1,5;
  line-cap: round;
}

/**
 * Zoom 13 buildings.
 * Already filtered by size upon import.
 */
#buildings-med[type!='no'] {
  polygon-fill: @color_building;
  line-width: 0.5;
  line-color: @color_building_outline;
}

/**
 * Zoom 14+ buildings.
 * Includes all buildings.
 */
#buildings-high[type!='no'] {
  [zoom=14] {
    [area>=5000] {
      polygon-fill: @color_building;
      line-width: 0.5;
      line-color: @color_building_outline;
    }
  }

  /**
   * This is for outlines and no stripe. Catches small buildings.
   * Larger buildings will be overridden with stripes below.
   */
  [zoom>=15][area>=2000],
  [zoom>=16] {
    polygon-fill: @color_building;
    line-width: 0.5;
    line-color: @color_building_outline;
  }

  [zoom=15][area>=3000],
  [zoom=16][area>=2000],
  [zoom=17][area>=1000],
  [zoom>=18],
  {
    polygon-fill: @color_building;
    line-width: 0.5;
    line-color: @color_building_outline;
  }

  // Stamen HQ fancy candycane striping
  [zoom>=18] {
    [osm_id=260351411],
    [osm_id=224030635], // Seth's house
    [osm_id=248153467], // Sean's house
    [osm_id=291796473], // Stamen South
    {
      polygon-fill: @color_building;
      line-width: 1.5;
      line-color: @color_building_outline_special;
    }
  }
}

#green-areas-low[zoom=10][area>5000000],
#green-areas-med[zoom=11][area>1000000],
#green-areas-med[zoom=12][area> 500000],
#green-areas-med[zoom=12][area> 200000],
#green-areas-med[zoom=13][area>  75000],
#green-areas-high[zoom=14][area> 10000],
#green-areas-high[zoom>14],
{
  polygon-fill: @color_green_areas;

  [type='nature_reserve'] {
    polygon-fill: @color_green_areas;
    polygon-opacity: 0.5;
  }
}

#aeroways {
  line-color: @color_airport_runways;
  line-cap: square;
  line-join: miter;

  [zoom>=15] {
    line-color: @color_airport_runways_detail;
  }

  [type='runway'] {
    [zoom=12] {
      line-width: 2;
    }

    [zoom=13] {
      line-width: 4;
    }

    [zoom=14] {
      line-width: 8;
    }

    [zoom=15] {
      line-width: 16;
    }

    [zoom=16] {
      line-width: 32;
    }

    [zoom=17] {
      line-width: 64;
    }

    [zoom>=18] {
      line-width: 128;
    }
  }

  [type='taxiway'] {
    [zoom=13] {
      line-width: 1;
    }

    [zoom=14] {
      line-width: 2;
    }

    [zoom=15] {
      line-width: 4;
    }

    [zoom=16] {
      line-width: 8;
    }

    [zoom=17] {
      line-width: 16;
    }

    [zoom>=18] {
      line-width: 32;
    }
  }
}

#tunnels,
#roads,
#roads_med,
#highways_med,
#bridges {
  ::casing,
  ::outline,
  {
    line-cap: butt;
    line-width: 0;
    line-color: @color_transport_casing;
  }

  line-join: round;
  line-cap: round;
  line-width: 1;
  line-color: @color_transport;
}

#tunnels {
  [zoom>=14] {
    ::outline
    {
      line-opacity: 0.7;
      line-color: @color_transport_tunnel;
    }

    line-opacity: 0.5;
    line-width: 4;
  }
}

#tunnels[kind='highway'] {
  [zoom>=15] {
    ::outline {
      line-width: 5.5;
    }

    line-width: 4;
  }

  [zoom>=16] {
    ::outline {
      line-width: 7;
      line-opacity: 0.4;
    }

    line-opacity: 0.7;
    line-color: @color_transport_tunnel;

    [is_link='yes'] {
      ::outline {
        line-color: @color_transport_casing;
      }
    }
  }

  [zoom>=17] {
    ::outline {
      line-width: 18;
    }

    line-width: 12;

    [is_link='yes'] {
      ::outline {
        line-width: 9;
      }
    }
  }

  [zoom>=18] {
    ::outline {
      line-width: 22;
      line-color: @color_transport;
    }

    line-width: 18;
    line-color: @color_transport_inline;
  }

  [zoom>=19] {
    ::outline {
      line-width: 30;
    }

    line-width: 26;

    [is_link='yes'] {
      ::outline {
        line-width: 13;
      }
    }
  }
}

#tunnels[kind='major_road'] {
  [zoom>=15] {
    ::outline {
      line-width: 5;
      line-opacity: 0.7;
      line-color: @color_transport_tunnel;
    }

    line-width: 3;
    line-opacity: 0.5;
  }

  [zoom>=16] {
    ::outline {
      line-width: 7;
      line-opacity: 0.4;
    }

    line-opacity: 0.7;
    line-color: @color_transport_tunnel;

    [is_link='yes'] {
      ::outline {
        line-color: @color_transport_casing;
      }
    }
  }

  [zoom>=17] {
    ::outline {
      line-width: 18;
    }

    line-width: 12;

    [is_link='yes'] {
      ::outline {
        line-width: 9;
      }
    }
  }

  [zoom>=18] {
    ::outline {
      line-width: 22;
    }

    line-width: 18;
  }

  [zoom>=19] {
    ::outline {
      line-width: 30;
    }

    line-width: 26;

    [is_link='yes'] {
      ::outline {
        line-width: 13;
      }
    }
  }
}

#tunnels[kind='minor_road'] {
  [zoom>=15] {
    ::outline {
      line-opacity: 0.7;
      line-color: @color_transport_tunnel;
    }

    line-color: @color_transport_minor;
    line-width: 1.5;
    line-opacity: 0.5;
  }

  [zoom>=16] {
    ::outline {
      line-width: 7;
    }

    line-width: 4;
    line-color: @color_transport;
  }

  [zoom>=17] {
    ::outline {
      line-width: 9;
    }

    line-width: 7;
  }

  [zoom>=18] {
    ::outline {
      line-width: 17;
      line-color: @color_transport;
    }

    line-width: 13;
    line-color: @color_transport_casing;
  }

  [zoom>=19] {
    ::outline {
      line-width: 20;
    }

    line-width: 16;
  }
}

#bridges[kind='highway'] {
  [zoom>=13] {
    ::outline {
      line-width: 8;
    }

    line-width: 4;

    [is_link='yes'] {
      ::outline {
        line-width: 0;
      }

      line-width: 1;
    }
  }

  [zoom>=14] {
    ::outline {
      line-width: 8;
    }

    line-width: 4;

    [is_link='yes'] {
      ::outline {
        line-width: 4;
      }

      line-width: 2.5;
    }
  }

  [zoom>=15] {
    ::outline {
      line-width: 11;
    }

    line-width: 6;

    [is_link='yes'] {
      ::outline {
        line-width: 5.5;
      }

      line-width: 2.5;
    }
  }

  [zoom>=16] {
    ::outline {
      line-width: 14;
    }

    line-width: 9;

    [is_link='yes'] {
      ::outline {
        line-width: 7;
      }

      line-width: 2.5;
    }
  }

  [zoom>=17] {
    ::outline {
      line-width: 20;
    }

    line-width: 15;

    [is_link='yes'] {
      ::outline {
        line-width: 9;
      }

      line-width: 5;
    }
  }

  [zoom>=18] {
    ::outline {
      line-width: 44;
      line-color: @color_transport;
    }

    line-width: 28;
    line-color: @color_transport_inline;

    [is_link='yes'] {
      ::outline {
        line-width: 22;
      }

      line-width: 18;
    }
  }

  [zoom>=19] {
    ::outline {
      line-width: 51;
    }

    line-width: 35;

    [is_link='yes'] {
      ::outline {
        line-width: 21;
      }

      line-width: 16;
    }
  }
}

#bridges[kind='major_road'] {
  line-color: @color_transport;

  [zoom>=14] {
    ::outline {
      line-width: 5;
    }

    line-width: 1.9;
  }

  [zoom>=15] {
    ::outline {
      line-width: 8.5;
    }

    line-width: 5.5;

    [is_link='yes'] {
      ::outline {
        line-width: 5.5;
      }

      line-width: 2.5;
    }
  }

  [zoom>=16] {
    ::outline {
      line-width: 11;
    }

    line-width: 7;

    [is_link='yes'] {
      ::outline {
        line-width: 7;
      }

      line-width: 2.5;
    }
  }

  [zoom>=17] {
    ::outline {
      line-width: 18;
    }

    line-width: 12;

    [is_link='yes'] {
      ::outline {
        line-width: 8;
      }

      line-width: 4;
    }
  }

  [zoom>=18] {
    ::outline {
      line-width: 24;
      line-color: @color_transport;
    }

    line-width: 18;
    line-color: @color_transport_inline;

    [is_link='yes'] {
      ::outline {
        line-width: 14;
      }

      line-width: 9;
    }
  }

  [zoom>=19] {
    ::outline {
      line-width: 32;
    }

    line-width: 26;

    [is_link='yes'] {
      ::outline {
        line-width: 18;
      }

      line-width: 13;
    }
  }
}

#roads,
#roads_med,
#highways_med {
  ::casing,
  ::outline,
  {
    line-cap: butt;
    line-width: 0;
    line-color: @color_transport_casing;
  }

  line-join: round;
  line-cap: round;
  line-width: 0;
  line-color: @color_transport;

  [is_link='yes']
  {
    [zoom>=16]
    {
      ::casing {
        line-width: 8;
      }

      line-width: 4;
    }
  }
}

#roads[kind='highway'],
#highways_med[kind='highway']
{
  [zoom>=9] {
    ::outline {
      line-width: 4.25;
    }

    line-width: 1.5;
  }

  [zoom>=10] {
    ::outline {
      line-width: 5;
    }

    line-width: 2;
  }

  [zoom>=11] {
    ::outline {
      line-width: 6;
    }

    line-width: 2.5;
  }

  [zoom>=12] {
    ::outline {
      line-width: 7;
    }

    line-width: 3;

    [is_link='yes'] {
      ::outline {
        line-width: 0;
      }

      line-width: 0.5;
    }
  }

  [zoom>=13] {
    ::outline {
      line-width: 8;
    }

    [is_link='yes'] {
      ::outline {
        line-width: 0;
      }

      line-width: 1;
    }
  }

  [zoom>=14] {
    ::outline {
      line-width: 9;
    }

    line-width: 4;

    [is_link='yes'] {
      ::outline {
        line-width: 4;
      }

      line-width: 2.5;
    }
  }

  [zoom>=15] {
    ::casing {
      line-width: 11;
    }

    line-width: 6;

    [is_link='yes'] {
      ::casing {
        line-width: 6.5;
      }

      line-width: 2.25;
    }
  }

  [zoom>=16] {
    ::casing {
      line-width: 14;
    }

    line-width: 9;

    [is_link='yes'] {
      ::casing {
        line-width: 7;
      }

      line-width: 2.5;
    }
  }

  [zoom>=17] {
    ::casing {
      line-width: 24;
    }

    line-width: 15;

    [is_link='yes'] {
      ::casing {
        line-width: 9;
      }

      line-width: 5;
    }
  }

  [zoom>=18] {
    ::casing {
      line-width: 42;
      line-color: @color_transport;
    }

    line-width: 28;
    line-color: @color_transport_inline;

    [is_link='yes'] {
      ::casing {
        line-width: 14;
      }

      line-width: 10;
    }
  }

  [zoom>=19] {
    ::casing {
      line-width: 49;
    }

    line-width: 35;

    [is_link='yes'] {
      ::casing {
        line-width: 20;
      }

      line-width: 16;
    }
  }
}

#roads[kind='major_road'],
#roads_med[kind='major_road']
{
  [zoom<=12] {
    line-color: @color_transport;
  }

  [zoom>=9] {
    line-width: 0.15;
  }

  [zoom>=10] {
    line-width: 0.5;
  }

  [zoom>=11] {
    ::outline {
      line-width: 1.25;
    }

    line-width: 0.7;
  }

  [zoom>=12] {
    ::outline {
      line-width: 5;
    }

    line-width: 1;

    [is_link='yes'] {
      ::outline {
        line-width: 0;
      }

      line-width: 0.5;
    }
  }

  [zoom>=13] {
    line-width: 1.5;
  }

  [zoom>=14] {
    ::outline {
      line-width: 5;
    }

    line-width: 1.9;

    [is_link='yes'] {
      ::outline {
        line-width: 5;
      }

      line-width: 1.9;
    }
  }

  [zoom>=15] {
    ::casing {
      line-width: 8;
    }

    line-width: 5;

    [is_link='yes'] {
      ::casing {
        line-width: 5.5;
      }

      line-width: 2.25;
    }
  }

  [zoom>=16] {
    ::casing {
      line-width: 11;
    }

    line-width: 7;

    [is_link='yes'] {
      ::casing {
        line-width: 7;
      }

      line-width: 2.5;
    }
  }

  [zoom>=17] {
    ::casing {
      line-width: 18;
    }

    line-width: 12;

    [is_link='yes'] {
      ::casing {
        line-width: 8;
      }

      line-width: 4;
    }
  }

  [zoom>=18] {
    ::casing {
      line-width: 22;
      line-color: @color_transport;
    }

    line-width: 18;
    line-color: @color_transport_inline;

    [is_link='yes'] {
      ::casing {
        line-width: 13;
      }

      line-width: 9;
    }
  }

  [zoom>=19] {
    ::casing {
      line-width: 30;
    }

    line-width: 26;

    [is_link='yes'] {
      ::casing {
        line-width: 17;
      }

      line-width: 13;
    }
  }
}

#roads[kind='minor_road'],
#roads_med[kind='minor_road']
{
  line-color: @color_transport_minor;

  [zoom>=10] {
    line-width: 0.2;
  }

  [zoom>=13] {
    line-width: 0.4;
  }

  [zoom>=14] {
    line-width: 0.8;
  }

  [zoom>=15] {
    line-width: 1.5;
  }

  [zoom>=16] {
    ::casing {
      line-width: 7;
    }

    line-width: 4;
    line-color: @color_transport;
  }

  [zoom>=17] {
    ::casing {
      line-width: 9;
    }

    line-width: 7;
  }

  [zoom>=18] {
    ::casing {
      line-width: 17;
      line-color: @color_transport;
    }

    line-width: 13;
    line-color: @color_transport_casing;
  }

  [zoom>=19] {
    ::casing {
      line-width: 20;
    }

    line-width: 16;
  }
}

#tunnels[kind='rail'],
#roads[kind='rail'],
#bridges[kind='rail']
{
  ::casing,
  ::outline,
  {
    line-color: @color_transport_rail;
  }

  line-color: @color_transport_rail;

  [zoom>=14] {
    ::casing {
      line-width: 3;
      line-dasharray: 1,3;
    }

    line-width: 1;
  }

  [zoom>=16] {
    ::casing {
      line-width: 5;
      line-dasharray: 1,4;
    }
  }

  [zoom>=18] {
    ::casing {
      line-width: 6;
      line-dasharray: 2,6;
    }

    line-width: 2;
  }

  [zoom>=19] {
    ::casing {
      line-width: 9;
      line-dasharray: 4,7;
    }

    line-width: 4;
  }
}

#tunnels[highway='service'],
#roads[highway='service'],
#bridges[highway='service'],
{
  [zoom>=15]
  {
    line-width: 1.5;
  }

  [zoom>=16] {
    ::casing {
      line-width: 4;
    }

    line-width: 2;
  }

  [zoom>=17] {
    ::casing {
      line-width: 6;
    }

    line-width: 4;
  }
}

#tunnels[kind='path'],
#roads[kind='path'],
#bridges[kind='path'],
{
  ::casing {
    line-color: @color_transport_path;
  }

  line-color: @color_transport_casing;

  [zoom>=15] {
    ::casing {
      line-width: 4;
    }

    line-width: 1.5;
    line-cap: butt;
  }

  [zoom>=16] {
    ::casing {
      line-width: 5;
    }

    line-width: 2;
  }

  [zoom>=17] {
    line-width: 3;
  }

  [zoom>=19] {
    line-width: 4;
  }
}

.landcoverraster {
  raster-opacity:1;
  raster-scaling:gaussian;
}


pinker city & town colors, town halos

pinker city & town colors, town halos

@sans: 'Source Sans Pro Regular';
@sans_md: 'Source Sans Pro Semibold';
@Sand_bd: 'Source Sans Pro Bold';

#place_label {
  [type='city'][zoom<=15] {
    text-name: @name;
    text-face-name: @sans_md;
    text-fill: #846;
    text-size: 16;
    text-wrap-width: 100;
    text-wrap-before: true;
    text-halo-fill: @land;
    text-halo-radius: 1;
    text-halo-rasterizer: fast;
    [zoom>=10] { text-size: 18; }
    [zoom>=12] { text-size: 24; }
  }
  [type='town'][zoom<=17] {
    text-name: @name;
    text-face-name: 'Source Sans Pro Regular';
    text-fill: #867;
    text-size: 14;
    text-wrap-width: 100;
    text-halo-fill: @land;
    text-halo-radius: 1;
    text-halo-rasterizer: fast;
    text-wrap-before: true;
    [zoom>=12] { text-size: 16; }
    [zoom>=14] { text-size: 18; }
  }
  [type='village'] {
    text-name: @name;
    text-face-name: 'Source Sans Pro Regular';
    text-fill: #444;
    text-size: 12;
    text-wrap-width: 100;
    text-wrap-before: true;
    [zoom>=12] { text-size: 14; }
    [zoom>=14] { text-size: 18; }
  }
  [type='hamlet'],
  [type='suburb'],
  [type='neighbourhood'] {
    text-name: @name;
    text-face-name: 'Source Sans Pro Semibold';
    text-fill: #a98;
    text-transform: uppercase;
    text-character-spacing: 1;
    text-size: 10;
    text-wrap-width: 100;
    text-wrap-before: true;
    text-halo-fill: @land;
    text-halo-radius: 1;
    text-halo-rasterizer: fast;
    [zoom>=14] { text-size: 11; }
    [zoom>=15] { text-size: 12; text-character-spacing: 2; }
    [zoom>=16] { text-size: 14; text-character-spacing: 3; }
  }
}

@sans: 'Source Sans Pro Regular';
@sans_md: 'Source Sans Pro Semibold';
@Sand_bd: 'Source Sans Pro Bold';

#place_label {
  [type='city'][zoom<=15] {
    text-name: @name;
    text-face-name: @sans_md;
    text-fill: #543;
    text-size: 16;
    text-wrap-width: 100;
    text-wrap-before: true;
    text-halo-fill: @land;
    text-halo-radius: 1;
    text-halo-rasterizer: fast;
    [zoom>=10] { text-size: 18; }
    [zoom>=12] { text-size: 24; }
  }
  [type='town'][zoom<=17] {
    text-name: @name;
    text-face-name: 'Source Sans Pro Regular';
    text-fill: #333;
    text-size: 14;
    text-wrap-width: 100;
    text-wrap-before: true;
    [zoom>=12] { text-size: 16; }
    [zoom>=14] { text-size: 18; }
  }
  [type='village'] {
    text-name: @name;
    text-face-name: 'Source Sans Pro Regular';
    text-fill: #444;
    text-size: 12;
    text-wrap-width: 100;
    text-wrap-before: true;
    [zoom>=12] { text-size: 14; }
    [zoom>=14] { text-size: 18; }
  }
  [type='hamlet'],
  [type='suburb'],
  [type='neighbourhood'] {
    text-name: @name;
    text-face-name: 'Source Sans Pro Semibold';
    text-fill: #a98;
    text-transform: uppercase;
    text-character-spacing: 1;
    text-size: 10;
    text-wrap-width: 100;
    text-wrap-before: true;
    text-halo-fill: @land;
    text-halo-radius: 1;
    text-halo-rasterizer: fast;
    [zoom>=14] { text-size: 11; }
    [zoom>=15] { text-size: 12; text-character-spacing: 2; }
    [zoom>=16] { text-size: 14; text-character-spacing: 3; }
  }
}