Turn champion role color to orange on hover.

/*****************************************************************************/
/* SetsList: Style */
/*****************************************************************************/
.sets_list {
}

.loadingText {
  font-size: 2.5em;
  font-weight: bold;
}

.itemSet {
  padding: 0;
  overflow: hidden;
}

.itemSetLink {
  background-color: rgba(195, 176, 164, 0.6);
  color: white;
}

.itemSetLink:hover {
  background-color: rgba(214, 86, 5, 0.6);
  color: rgb(227, 172, 137);
}

.itemSetRole {
  position: absolute;
  background-color: inherit;
  color: white;
  font-size: 14px;
  font-weight: bold;
  line-height: 20px;
  text-align: center;
  z-index: 10;
  width: 100%;
  height: 20px;
  bottom: 0;
  left: 0;
  margin: 0;
}

.champImage {
  width: 100%;
}

.spriteContainer {
  width: 100%;
}
.spriteContainer:before {
  content: "";
  display: block;
  padding-top: 100%;
}

.champSprite {
  /* from : http://stackoverflow.com/a/28985475/4022804 */
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  text-align: center;
}

.champSprite .champName {
  position: absolute;
  left: 0;
  top: 0;
  color: inherit;
  font-size: 14px;
  font-weight: bold;
  line-height: 20px;
  text-align: center;
  background-color: rgba(56, 56, 56, 0.6);
  -webkit-box-shadow: 0px 0px 8px 5px rgba(56, 56, 56, 0.6);
  -moz-box-shadow: 0px 0px 8px 5px rgba(56, 56, 56, 0.6);
  box-shadow: 0px 0px 8px 5px rgba(56, 56, 56, 0.6);
  padding: 3px 8px;
}

/*****************************************************************************/
/* SetsList: Style */
/*****************************************************************************/
.sets_list {
}

.loadingText {
  font-size: 2.5em;
  font-weight: bold;
}

.itemSet {
  padding: 0;
  overflow: hidden;
}

.itemSetLink {
  background-color: rgba(195, 176, 164, 0.6);
}

.itemSetLink:hover {
  background-color: rgba(214, 86, 5, 0.6);
}

.itemSetRole {
  position: absolute;
  background-color: inherit;
  color: white;
  font-size: 14px;
  font-weight: bold;
  line-height: 20px;
  text-align: center;
  z-index: 10;
  width: 100%;
  height: 20px;
  bottom: 0;
  left: 0;
  margin: 0;
}

.champImage {
  width: 100%;
}

.spriteContainer {
  width: 100%;
}
.spriteContainer:before {
  content: "";
  display: block;
  padding-top: 100%;
}

.champSprite {
  /* from : http://stackoverflow.com/a/28985475/4022804 */
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  text-align: center;
}

.champSprite .champName {
  position: absolute;
  left: 0;
  top: 0;
  color: white;
  font-size: 14px;
  font-weight: bold;
  line-height: 20px;
  text-align: center;
  background-color: rgba(56, 56, 56, 0.6);
  -webkit-box-shadow: 0px 0px 8px 5px rgba(56, 56, 56, 0.6);
  -moz-box-shadow: 0px 0px 8px 5px rgba(56, 56, 56, 0.6);
  box-shadow: 0px 0px 8px 5px rgba(56, 56, 56, 0.6);
  padding: 3px 8px;
}


Fix raster rendering test.

Fix raster rendering test.

#data {
    raster-opacity: 1;
    raster-mode: multiply2;
}


tweak country labels

tweak country labels

@text_font_transport: 'PT Sans Narrow Regular', 'Unifont Medium';
@text_font_shield: 'PT Sans Bold', 'Unifont Medium';
@text_font_administrative: 'PT Sans Bold', 'Unifont Medium';
@text_font_city: 'PT Sans Narrow Regular', 'Unifont Medium';
@text_font_parks: 'PT Sans Narrow Regular', 'Unifont Medium';
@text_font_water: 'PT Sans Italic', 'Unifont Medium';
@text_font_water_bold: 'PT Sans Bold Italic', 'Unifont Medium';

@label_color_transport: #524c4c;
@label_color_shield: #fff;
@label_color_shield_fed: #333;
@label_color_administrative: #2e2115;
@label_color_city: #2e2115;

@text_font_size_xxsm: 12;
@text_font_size_xsm: 14;
@text_font_size_sm: 15;
@text_font_size_medium: 17;
@text_font_size_medium_plus: 18;
@text_font_size_large: 20;
@text_font_size_xlg: 24;
@text_font_size_xxlg: 34;

@text_character_spacing_sm: 0.7;
@text_character_spacing_md: 1.2;
@text_character_spacing_lg: 1.7;
@text_character_spacing_xlg: 2.2;

@text_font_halo_radius_sm: 1.5;
@text_font_halo_radius_md: 1.75;
@text_font_halo_radius_large: 2;

@label_color_halo_low: fadeout(rgba(255,255,255,0.7), 30%);
@label_color_halo_high: fadeout(rgba(255,255,255,1), 30%);
@label_color_administrative_halo: fadeout(#fff, 30%);
@label_color_physical: #000;
@label_color_physical_halo: #fff;
@label_color_transport_halo: #F7F7E6;
@label_color_airport_halo: #f7f7e6;
@label_color_places_halo_low: fadeout(rgba(255,255,255, 1), 30%);
@label_color_places_halo_high: fadeout(rgba(255,255,255, 1), 30%);

@label_color_green_area: #374c30;
@label_color_green_area_halo: #c0d3b5;
@label_color_water: darken(@color_water,20);
@label_color_water_halo: @color_water;

Map {
  font-directory: url("fonts/");
  buffer-size: 128;
}

#minor_road_labels,
#major_road_labels,
{
  text-name: [name];
  text-face-name: @text_font_transport;
  text-placement: line;
  text-label-position-tolerance: 2;
  text-max-char-angle-delta: 20;
  text-min-path-length: 30;
  text-fill: #444;
  text-spacing: 256;
  text-min-distance: 5;
  text-character-spacing: @text_character_spacing_sm;
  text-avoid-edges: true;
  text-halo-fill: @label_color_transport_halo;
  text-halo-radius: @text_font_halo_radius_md;

  [kind='major_road'] {
    text-size: @text_font_size_xxsm;
  }

  [zoom>=13] {
    text-size: @text_font_size_xxsm;

    [kind='major_road'] {
      text-size: @text_font_size_xxsm * 1.2;
    }
  }

  [zoom>=14] {
    text-min-distance: 10;
    text-size: @text_font_size_sm;
    text-character-spacing: @text_character_spacing_md;
    text-halo-radius: @text_font_halo_radius_large;

    [kind='major_road'] {
      text-size: @text_font_size_sm * 1.2;
    }
  }

  [zoom>=16]{
    text-min-distance: 100;
    text-character-spacing: @text_character_spacing_lg;
  }
}

#highway_shields {
  [zoom>=11],
  [highway='motorway'],
  [highway='trunk'],
  [highway='primary'] {
    // default rectangle shield
    shield-file: url(shields/default.svg);
    shield-fill: @label_color_shield_fed;
    shield-transform: scale(0.2,0.2);
    shield-face-name: @text_font_shield;
    shield-name: [ref];
    shield-size: 10;
    shield-min-distance: 44;
    shield-spacing: 20;
    // half the width of the shield to prevent from wrapping
    shield-min-padding: 10;

    [ref=~'I \d+'] {
      shield-file: url(shields/interstate_2.svg);
      shield-transform: scale(0.033, 0.033);
      shield-fill: @label_color_shield;
      shield-size: 9;
      shield-name: "[ref].replace('I ', '')";

      [zoom>=13] {
        shield-size: 11;
        shield-transform: scale(0.038, 0.038);
        shield-min-distance: 65;
      }

      [zoom>=15] {
        shield-size: 13;
        shield-transform: scale(0.045, 0.045);
      }

      [zoom>=17] {
        shield-size: 15;
        shield-transform: scale(0.05, 0.05);
      }
    }

    [ref=~'I \d{3,}'] {
      shield-file: url(shields/interstate_3.svg);
      shield-transform: scale(0.033, 0.033);
      shield-fill: @label_color_shield;
      shield-size: 9;
      shield-name: "[ref].replace('I ', '')";

      [zoom>=13] {
        shield-size: 11;
        shield-transform: scale(0.038, 0.038);
        shield-min-distance: 40;
      }

      [zoom>=15] {
        shield-size: 13;
        shield-transform: scale(0.045, 0.045);
      }

      [zoom>=17] {
        shield-size: 13;
        shield-transform: scale(0.05, 0.05);
      }
    }

    [ref=~'US \d+'] {
      shield-file: url(shields/us.svg);
      shield-transform: scale(0.062, 0.062);
      shield-size: 10;
      shield-name: "[ref].replace('US ', '')";
      shield-fill: @label_color_shield_fed;
      shield-text-dy: 1;
      shield-character-spacing: -1;

      [zoom>=13] {
        shield-size: 12;
        shield-transform: scale(0.075, 0.075);
      }

      [zoom>=15] {
        shield-size: 14;
        shield-transform: scale(0.088, 0.088);
      }

      [zoom>=17] {
        shield-size: 16;
        shield-transform: scale(0.091, 0.091);
      }
    }

    [ref=~'CA \d+'] {
      shield-file: url(shields/ca.svg);
      shield-fill: @label_color_shield;
      shield-transform: scale(0.052, 0.052);
      shield-size: 10;
      shield-name: "[ref].replace('CA ', '')";
      shield-dy: -2.5;
      shield-character-spacing: -1;

      [zoom>=13] {
        shield-size: 12;
        shield-transform: scale(0.060, 0.060);
        shield-min-distance: 50;
      }

      [zoom>=14] {
        shield-min-distance: 80;
      }

      [zoom>=15] {
        shield-size: 14;
        shield-transform: scale(0.080, 0.080);
        shield-dy: -3.5;
      }

      [zoom>=17] {
        shield-size: 16;
        shield-transform: scale(0.090, 0.090);
      }
    }
  }
}

#ne_110m_geography_marine_polys[zoom=2][scalerank=0][changed!=''],
#ne_110m_geography_marine_polys[zoom=3][changed!=''],
#ne_50m_geography_marine_polys[zoom=4][scalerank<4][changed!=''] {
    text-name: [name];

    [namealt!=''] {
      text-name: [name] + '\n(' + [namealt] + ')';
    }

    text-face-name: @text_font_water_bold;
    text-wrap-width: 40;
    text-wrap-character: ' ';
    text-size: @text_font_size_sm;
    text-character-spacing: @text_character_spacing_xlg;
    text-align: center;

    text-fill: @label_color_water;
    text-halo-radius: @text_font_halo_radius_sm;
    text-halo-fill: @label_color_water_halo;
}

#ne_50m_geography_marine_polys[zoom=5][scalerank<4][changed!=''],
#ne_10m_geography_marine_polys[zoom>=6][zoom<=8][scalerank<7][changed!='']
{
    text-name: [name];

    [namealt!=''] {
      text-name: [name] + '\n(' + [namealt] + ')';
    }

    [name = 'Hecate Straight'] {
      text-name: 'Hecate Strait' + [namealt]; // Becase we know namealt is empty
    }

    [name = 'Queen Charlotte Straight'] {
      text-name: 'Queen Charlotte Strait' + [namealt]; // Becase we know namealt is empty
    }

    text-face-name: @text_font_water_bold;
    text-wrap-width: 50;
    text-size: @text_font_size_medium;
    text-character-spacing: @text_character_spacing_lg;
    text-fill: @label_color_water;
    text-halo-radius: @text_font_halo_radius_sm;
    text-halo-fill: @label_color_water_halo;
}

#water-bodies-labels-low,
#water-bodies-labels-med,
#water-bodies-labels-high {
  [zoom=9][area>100000000],
  [zoom=10][area>100000000],
  [zoom=11][area>25000000],
  [zoom=12][area>5000000],
  [zoom=13][area>2000000],
  [zoom=14][area>200000],
  [zoom=15][area>50000],
  [zoom=16][area>10000],
  [zoom>=17] {
    text-name: "[name]";
    text-face-name: @text_font_water;
    text-placement: interior;
    text-max-char-angle-delta: 30;
    text-wrap-width: 40;
    text-halo-radius: @text_font_halo_radius_large;
    text-fill: @label_color_water;
    text-halo-fill: @label_color_water_halo;
    text-size: @text_font_size_xsm;

    [zoom>9][zoom<12] {
      text-spacing: 200;
      text-wrap-width: 50;
    }
    [zoom=12] {
      text-size: @text_font_size_xsm;
      text-spacing: 200;
      text-wrap-width: 70;
    }
    [zoom=13] {
      text-size: @text_font_size_xsm;
      text-spacing: 100;
      text-wrap-width: 70;
    }
    [zoom=14] {
      text-size: @text_font_size_xsm;
      text-spacing: 100;
      text-wrap-width: 70;
    }
    [zoom>=15] {
      text-size: @text_font_size_sm;
      text-spacing: 100;
      text-wrap-width: 40;
    }
  }
}

#green-areas-labels-low,
#green-areas-labels-med,
#green-areas-labels-high {
  [zoom=8][area>100000000],
  [zoom=9][area>100000000],
  [zoom=10][area>100000000],
  [zoom=11][area>5000000],
  [zoom=12][area>1000000],
  [zoom=13][area>400000],
  [zoom=14][area>200000],
  [zoom=15][area>50000],
  [zoom=16][area>10000],
  [zoom>=17] {
    text-name: [name];
    text-face-name: @text_font_parks;
    text-placement: interior;
    text-wrap-width: 96;
    text-wrap-before: true;
    text-line-spacing: -3;
    text-fill: @label_color_green_area;
    text-size: 15;

    [zoom>=8] {
      text-halo-fill: @label_color_green_area_halo;
      text-halo-radius: @text_font_halo_radius_sm;
    }

    [zoom>=11] {
      text-fill: #586e50;
      text-halo-radius: @text_font_halo_radius_large;
    }

    [zoom>=15] {
      text-size: 20;
      text-line-spacing: -7;
    }
  }
}

#continents
{
  text-name: [name];
  text-face-name: @text_font_administrative;
  text-wrap-width: 32;
  text-size: 24;
  text-line-spacing: -12;
  text-fill: #2e2115;
  text-halo-radius: @text_font_halo_radius_sm;
  text-halo-fill: @label_color_halo_low;
}

#admin1-labels {
  // [zoom>=4][scalerank<3],
  [zoom>=5][scalerank<3][admin!='United States of America'][admin!='Canada'],
  [zoom>=6][scalerank<5],
  [zoom>=7][scalerank>=5] {
    text-name: [name];
    text-transform: uppercase;
    text-face-name: @text_font_administrative;
    text-face-name: @text_font_administrative;
    text-fill: @label_color_administrative;
    text-halo-fill: @label_color_halo_low;
    text-halo-radius: @text_font_halo_radius_sm;
    text-size: @text_font_size_sm;
    text-character-spacing: 1;
    text-wrap-width: 40;
    text-placement-type: simple;
    text-placements: 'E,N,W,S';

    [zoom>=5] {
     text-size: @text_font_size_sm;
    }

    [zoom>=6] {
      text-size: @text_font_size_medium;
      text-character-spacing: 2;
    }

    [zoom>=7] {
      text-size: @text_font_size_large;
      text-character-spacing: 3;
    }
  }
}

#admin1-labels-50m-z4 {
    text-face-name: @text_font_administrative;
    text-wrap-width: 80;
    text-fill: @label_color_administrative;
    text-halo-radius: @text_font_halo_radius_sm;
    text-halo-fill: @label_color_halo_low;
    text-name: "[label_z4]";
    text-size:  @text_font_size_xsm;
    text-character-spacing: 1;
}

#admin1-labels-50m-z5 {
    text-face-name: @text_font_administrative;
    text-wrap-width: 80;
    text-fill: @label_color_administrative;
    text-halo-radius: @text_font_halo_radius_sm;
    text-halo-fill: @label_color_halo_low;
    // text-halo-comp-op: overlay;
    text-halo-rasterizer: fast;
    text-name: "[label_z5]";
    text-size:  @text_font_size_sm;
    text-character-spacing: 1;
}

#admin1-labels-50m-z6 {
    text-face-name: @text_font_administrative;
    text-wrap-width: 80;
    text-fill: @label_color_administrative;
    text-halo-radius: @text_font_halo_radius_sm;
    text-halo-fill: @label_color_halo_low;
    text-name: "[label_z6]";
    text-size:  @text_font_size_medium;
    text-character-spacing: 2;
}

#admin1-labels-50m-z7 {
    text-face-name: @text_font_administrative;
    text-wrap-width: 80;
    text-fill: @label_color_administrative;
    text-halo-radius: @text_font_halo_radius_sm;
    text-halo-fill: @label_color_halo_low;
    text-name: "[label_z7]";
    text-size:  @text_font_size_large;
    text-character-spacing: 3;
}

/* Admin 0 labels */

#admin0-labels-z3[longfrom>3] {
    text-name: "[shortname]";
    text-face-name: @text_font_administrative;
    text-transform: uppercase;
    text-wrap-width: 80;
    text-character-spacing: @text_character_spacing_sm;
    text-size: @text_font_size_medium_plus;
    text-halo-radius: @text_font_halo_radius_sm;
    text-halo-fill: @label_color_halo_low;
    text-fill: @label_color_administrative;
    text-min-distance: 5;
}

#admin0-labels-z3[longfrom<=3] {
    text-name: "[name]";
    text-face-name: @text_font_administrative;
    text-transform: uppercase;
    text-size: @text_font_size_large;
    text-line-spacing: -8;
    text-wrap-width: 100;
    text-character-spacing: @text_character_spacing_sm;
    text-halo-radius: @text_font_halo_radius_sm;
    text-halo-fill: @label_color_halo_low;
    text-fill: @label_color_administrative;
}

#admin0-labels-z4 {
    text-name: [name];
    text-face-name: @text_font_administrative;
    text-transform: uppercase;
    text-wrap-width: 80;
    text-character-spacing: @text_character_spacing_lg;
    text-size: @text_font_size_large;
    [population<100] { text-size: @text_font_size_medium_plus; }
    text-min-distance: 15;
    text-halo-radius: @text_font_halo_radius_sm;
    text-halo-fill: @label_color_halo_low;
    text-fill: @label_color_administrative;
}

#admin0-labels-z5 {
  text-name: [name];
  text-face-name: @text_font_administrative;
  text-transform: uppercase;
  text-wrap-width: 80;
  text-character-spacing: @text_character_spacing_xlg;
  text-size: @text_font_size_xlg;
  [population<100] { text-size: @text_font_size_large; }
  text-halo-radius: @text_font_halo_radius_sm;
  text-halo-fill: @label_color_halo_low;
  text-fill: @label_color_administrative;
}

#admin0-labels-z6 {
  text-name: [name];
  text-face-name: @text_font_administrative;
  text-transform: uppercase;
  text-wrap-width: 80;
  text-character-spacing: @text_character_spacing_xlg;
  text-size: @text_font_size_xxlg;
  [population<100] { text-size: @text_font_size_xlg; }
  text-halo-radius: @text_font_halo_radius_sm;
  text-halo-fill: @label_color_halo_low;
  text-fill: @label_color_administrative;
}

/* city labels */

#aries-places-labels {
  [zoom=4][scalerank<5],
  [zoom=5][scalerank<6],
  [zoom=6][scalerank<7],
  [zoom=7][scalerank<8],
  [zoom=8][scalerank<9],
  [zoom=9][scalerank<10],
  [zoom=10][scalerank<11],
  [zoom=11][scalerank<12],
  [zoom=12][scalerank<13],
  [zoom=13][scalerank<14],
  [zoom=14][scalerank<15]
  [zoom>=15][scalerank<15]{

    shield-file: url(shields/circle-12.svg);
    shield-fill: @label_color_city;
    shield-halo-fill: @label_color_halo_low;
    shield-halo-radius: @text_font_halo_radius_sm;
    shield-unlock-image: true;
    shield-transform: scale(0.5, 0.5);
    shield-face-name: @text_font_city;
    shield-name: [name];
    shield-min-distance: 2;
    shield-placement-type: simple;
    shield-placements: 'NE, N, NW, SE, S, SW';
    shield-justify-alignment: auto;
    shield-horizontal-alignment: auto;

    [zoom>=4] {
      shield-size: @text_font_size_xsm;
      shield-text-dy: -7;

      [population>700000] {
        shield-size: @text_font_size_xsm * 1.2;
        shield-transform: scale(0.7, 0.7);
        shield-text-dy: -9;
      }

      [population>7000000] {
        shield-size: @text_font_size_xsm * 1.3;
        shield-transform: scale(0.8, 0.8);
        shield-text-dy: -10;
      }
    }

    [zoom>=5]{
      shield-size: @text_font_size_sm;
      shield-text-dy: -7;

      [population>700000] {
        shield-size: @text_font_size_sm * 1.2;
        shield-text-dy: -9;
      }

      [population>7000000] {
        shield-size: @text_font_size_sm * 1.3;
      }
    }

    [zoom>=6]{
      shield-size: @text_font_size_medium;
      shield-text-dy: -8;

      [population>700000] {
        shield-size: @text_font_size_medium * 1.2;
      }

      [population>7000000] {
        shield-size: @text_font_size_medium * 1.5;
      }
    }

    [zoom>=8] {
      shield-halo-radius: @text_font_halo_radius_md;
    }

    [zoom>=10]{
      shield-size: @text_font_size_medium_plus;
      shield-halo-radius: @text_font_halo_radius_large;
      shield-halo-fill: @label_color_halo_high;

      [population>700000] {
        shield-size: @text_font_size_medium_plus * 1.2;
      }

      [population>7000000] {
        shield-size: @text_font_size_medium_plus * 1.3;
      }
    }

    [zoom>=11] {
      shield-opacity: 0;
    }

    [zoom>=12] {
      shield-size: @text_font_size_xlg;

      [population>700000] {
        shield-size: @text_font_size_xlg * 1.2;
      }

      [population>7000000] {
        shield-size: @text_font_size_xlg * 1.3;
      }
    }
  }
}

#airports {
  [zoom>=10] {
    text-name: [abbrev];
    text-face-name: @text_font_transport;
    text-fill: #444;
    text-size: @text_font_size_medium_plus;

    text-halo-fill: @label_color_airport_halo;
    text-halo-radius: @text_font_halo_radius_large;

    text-wrap-width: 128;
    text-dy: 14;
  }

  [zoom>=13] {
    text-name: [name];
  }

  [zoom=14][natlscale>.04],
  [zoom=15][natlscale>.02],
  [zoom>=16][natlscale>.01]
  {
      text-dy: 20;
  }

  [zoom=8][natlscale>2.3][type='major'],
  [zoom=9][natlscale>1.2][type='major'],
  [zoom=10][natlscale>0.57][type='major'],
  [zoom=11][natlscale>0.29][type='major'],
  [zoom=12][natlscale>0.29][type='major'],
  [zoom=13][natlscale>0.29][type='major']
  {
    point-file: url('icons/airport_major_l.png');
  }

  [zoom=14][natlscale>.29][type='major'],
  [zoom=15][natlscale>.29][type='major'],
  [zoom>=16][natlscale>.29][type='major']
  {
      point-file: url('icons/airport_major_xl.png');
  }

  [zoom=8][natlscale>2.3][type='small'],
  [zoom=9][natlscale>1.2][type='small'],
  [zoom=10][natlscale>.57][type='small'],
  [zoom=11][natlscale>.29][type='small'],
  [zoom=12][natlscale>.29][type='small'],
  [zoom=13][natlscale>.29][type='small']
  {
      point-file: url('icons/airport_small_l.png');
  }

  [zoom=14][natlscale>.29][type='small'],
  [zoom=15][natlscale>.29][type='small'],
  [zoom>=16][natlscale>.29][type='small']
  {
      point-file: url('icons/airport_small_xl.png');
  }

  [zoom=8][natlscale>2.3][type='military'],
  [zoom=9][natlscale>1.2][type='military'],
  [zoom=10][natlscale>.57][type='military'],
  [zoom=11][natlscale>.29][type='military'],
  [zoom=12][natlscale>.29][type='military'],
  [zoom=13][natlscale>.29][type='military']
  {
      point-file: url('icons/airport_military_l.png');
  }

  [zoom=14][natlscale>.29][type='military'],
  [zoom=15][natlscale>.29][type='military'],
  [zoom>=16][natlscale>.29][type='military']
  {
      point-file: url('icons/airport_military_xl.png');
  }

  [zoom=8][natlscale>2.3][type='spaceport'],
  [zoom=9][natlscale>1.2][type='spaceport'],
  [zoom=10][natlscale>.57][type='spaceport'],
  [zoom=11][natlscale>.29][type='spaceport'],
  [zoom=12][natlscale>.29][type='spaceport'],
  [zoom=13][natlscale>.29][type='spaceport']
  {
      point-file: url('icons/intergalactic_l.png');
  }

  [zoom=14][natlscale>.29][type='spaceport'],
  [zoom=15][natlscale>.29][type='spaceport'],
  [zoom>=16][natlscale>.29][type='spaceport']
  {
      point-file: url('icons/intergalactic_xl.png');
  }
}

@text_font_transport: 'PT Sans Narrow Regular', 'Unifont Medium';
@text_font_shield: 'PT Sans Bold', 'Unifont Medium';
@text_font_administrative: 'PT Sans Bold', 'Unifont Medium';
@text_font_city: 'PT Sans Narrow Regular', 'Unifont Medium';
@text_font_parks: 'PT Sans Narrow Regular', 'Unifont Medium';
@text_font_water: 'PT Sans Italic', 'Unifont Medium';
@text_font_water_bold: 'PT Sans Bold Italic', 'Unifont Medium';

@label_color_transport: #524c4c;
@label_color_shield: #fff;
@label_color_shield_fed: #333;
@label_color_administrative: #2e2115;
@label_color_city: #2e2115;

@text_font_size_xxsm: 12;
@text_font_size_xsm: 14;
@text_font_size_sm: 15;
@text_font_size_medium: 17;
@text_font_size_medium_plus: 18;
@text_font_size_large: 20;
@text_font_size_xlg: 24;
@text_font_size_xxlg: 34;

@text_character_spacing_sm: 0.7;
@text_character_spacing_md: 1.2;
@text_character_spacing_lg: 1.7;
@text_character_spacing_xlg: 2.2;

@text_font_halo_radius_sm: 1.5;
@text_font_halo_radius_md: 1.75;
@text_font_halo_radius_large: 2;

@label_color_halo_low: fadeout(rgba(255,255,255,0.7), 30%);
@label_color_halo_high: fadeout(rgba(255,255,255,1), 30%);
@label_color_administrative_halo: fadeout(#fff, 30%);
@label_color_physical: #000;
@label_color_physical_halo: #fff;
@label_color_transport_halo: #F7F7E6;
@label_color_airport_halo: #f7f7e6;
@label_color_places_halo_low: fadeout(rgba(255,255,255, 1), 30%);
@label_color_places_halo_high: fadeout(rgba(255,255,255, 1), 30%);

@label_color_green_area: #374c30;
@label_color_green_area_halo: #c0d3b5;
@label_color_water: darken(@color_water,20);
@label_color_water_halo: @color_water;

Map {
  font-directory: url("fonts/");
  buffer-size: 128;
}

#minor_road_labels,
#major_road_labels,
{
  text-name: [name];
  text-face-name: @text_font_transport;
  text-placement: line;
  text-label-position-tolerance: 2;
  text-max-char-angle-delta: 20;
  text-min-path-length: 30;
  text-fill: #444;
  text-spacing: 256;
  text-min-distance: 5;
  text-character-spacing: @text_character_spacing_sm;
  text-avoid-edges: true;
  text-halo-fill: @label_color_transport_halo;
  text-halo-radius: @text_font_halo_radius_md;

  [kind='major_road'] {
    text-size: @text_font_size_xxsm;
  }

  [zoom>=13] {
    text-size: @text_font_size_xxsm;

    [kind='major_road'] {
      text-size: @text_font_size_xxsm * 1.2;
    }
  }

  [zoom>=14] {
    text-min-distance: 10;
    text-size: @text_font_size_sm;
    text-character-spacing: @text_character_spacing_md;
    text-halo-radius: @text_font_halo_radius_large;

    [kind='major_road'] {
      text-size: @text_font_size_sm * 1.2;
    }
  }

  [zoom>=16]{
    text-min-distance: 100;
    text-character-spacing: @text_character_spacing_lg;
  }
}

#highway_shields {
  [zoom>=11],
  [highway='motorway'],
  [highway='trunk'],
  [highway='primary'] {
    // default rectangle shield
    shield-file: url(shields/default.svg);
    shield-fill: @label_color_shield_fed;
    shield-transform: scale(0.2,0.2);
    shield-face-name: @text_font_shield;
    shield-name: [ref];
    shield-size: 10;
    shield-min-distance: 44;
    shield-spacing: 20;
    // half the width of the shield to prevent from wrapping
    shield-min-padding: 10;

    [ref=~'I \d+'] {
      shield-file: url(shields/interstate_2.svg);
      shield-transform: scale(0.033, 0.033);
      shield-fill: @label_color_shield;
      shield-size: 9;
      shield-name: "[ref].replace('I ', '')";

      [zoom>=13] {
        shield-size: 11;
        shield-transform: scale(0.038, 0.038);
        shield-min-distance: 65;
      }

      [zoom>=15] {
        shield-size: 13;
        shield-transform: scale(0.045, 0.045);
      }

      [zoom>=17] {
        shield-size: 15;
        shield-transform: scale(0.05, 0.05);
      }
    }

    [ref=~'I \d{3,}'] {
      shield-file: url(shields/interstate_3.svg);
      shield-transform: scale(0.033, 0.033);
      shield-fill: @label_color_shield;
      shield-size: 9;
      shield-name: "[ref].replace('I ', '')";

      [zoom>=13] {
        shield-size: 11;
        shield-transform: scale(0.038, 0.038);
        shield-min-distance: 40;
      }

      [zoom>=15] {
        shield-size: 13;
        shield-transform: scale(0.045, 0.045);
      }

      [zoom>=17] {
        shield-size: 13;
        shield-transform: scale(0.05, 0.05);
      }
    }

    [ref=~'US \d+'] {
      shield-file: url(shields/us.svg);
      shield-transform: scale(0.062, 0.062);
      shield-size: 10;
      shield-name: "[ref].replace('US ', '')";
      shield-fill: @label_color_shield_fed;
      shield-text-dy: 1;
      shield-character-spacing: -1;

      [zoom>=13] {
        shield-size: 12;
        shield-transform: scale(0.075, 0.075);
      }

      [zoom>=15] {
        shield-size: 14;
        shield-transform: scale(0.088, 0.088);
      }

      [zoom>=17] {
        shield-size: 16;
        shield-transform: scale(0.091, 0.091);
      }
    }

    [ref=~'CA \d+'] {
      shield-file: url(shields/ca.svg);
      shield-fill: @label_color_shield;
      shield-transform: scale(0.052, 0.052);
      shield-size: 10;
      shield-name: "[ref].replace('CA ', '')";
      shield-dy: -2.5;
      shield-character-spacing: -1;

      [zoom>=13] {
        shield-size: 12;
        shield-transform: scale(0.060, 0.060);
        shield-min-distance: 50;
      }

      [zoom>=14] {
        shield-min-distance: 80;
      }

      [zoom>=15] {
        shield-size: 14;
        shield-transform: scale(0.080, 0.080);
        shield-dy: -3.5;
      }

      [zoom>=17] {
        shield-size: 16;
        shield-transform: scale(0.090, 0.090);
      }
    }
  }
}

#ne_110m_geography_marine_polys[zoom=2][scalerank=0][changed!=''],
#ne_110m_geography_marine_polys[zoom=3][changed!=''],
#ne_50m_geography_marine_polys[zoom=4][scalerank<4][changed!=''] {
    text-name: [name];

    [namealt!=''] {
      text-name: [name] + '\n(' + [namealt] + ')';
    }

    text-face-name: @text_font_water_bold;
    text-wrap-width: 40;
    text-wrap-character: ' ';
    text-size: @text_font_size_sm;
    text-character-spacing: @text_character_spacing_xlg;
    text-align: center;

    text-fill: @label_color_water;
    text-halo-radius: @text_font_halo_radius_sm;
    text-halo-fill: @label_color_water_halo;
}

#ne_50m_geography_marine_polys[zoom=5][scalerank<4][changed!=''],
#ne_10m_geography_marine_polys[zoom>=6][zoom<=8][scalerank<7][changed!='']
{
    text-name: [name];

    [namealt!=''] {
      text-name: [name] + '\n(' + [namealt] + ')';
    }

    [name = 'Hecate Straight'] {
      text-name: 'Hecate Strait' + [namealt]; // Becase we know namealt is empty
    }

    [name = 'Queen Charlotte Straight'] {
      text-name: 'Queen Charlotte Strait' + [namealt]; // Becase we know namealt is empty
    }

    text-face-name: @text_font_water_bold;
    text-wrap-width: 50;
    text-size: @text_font_size_medium;
    text-character-spacing: @text_character_spacing_lg;
    text-fill: @label_color_water;
    text-halo-radius: @text_font_halo_radius_sm;
    text-halo-fill: @label_color_water_halo;
}

#water-bodies-labels-low,
#water-bodies-labels-med,
#water-bodies-labels-high {
  [zoom=9][area>100000000],
  [zoom=10][area>100000000],
  [zoom=11][area>25000000],
  [zoom=12][area>5000000],
  [zoom=13][area>2000000],
  [zoom=14][area>200000],
  [zoom=15][area>50000],
  [zoom=16][area>10000],
  [zoom>=17] {
    text-name: "[name]";
    text-face-name: @text_font_water;
    text-placement: interior;
    text-max-char-angle-delta: 30;
    text-wrap-width: 40;
    text-halo-radius: @text_font_halo_radius_large;
    text-fill: @label_color_water;
    text-halo-fill: @label_color_water_halo;
    text-size: @text_font_size_xsm;

    [zoom>9][zoom<12] {
      text-spacing: 200;
      text-wrap-width: 50;
    }
    [zoom=12] {
      text-size: @text_font_size_xsm;
      text-spacing: 200;
      text-wrap-width: 70;
    }
    [zoom=13] {
      text-size: @text_font_size_xsm;
      text-spacing: 100;
      text-wrap-width: 70;
    }
    [zoom=14] {
      text-size: @text_font_size_xsm;
      text-spacing: 100;
      text-wrap-width: 70;
    }
    [zoom>=15] {
      text-size: @text_font_size_sm;
      text-spacing: 100;
      text-wrap-width: 40;
    }
  }
}

#green-areas-labels-low,
#green-areas-labels-med,
#green-areas-labels-high {
  [zoom=8][area>100000000],
  [zoom=9][area>100000000],
  [zoom=10][area>100000000],
  [zoom=11][area>5000000],
  [zoom=12][area>1000000],
  [zoom=13][area>400000],
  [zoom=14][area>200000],
  [zoom=15][area>50000],
  [zoom=16][area>10000],
  [zoom>=17] {
    text-name: [name];
    text-face-name: @text_font_parks;
    text-placement: interior;
    text-wrap-width: 96;
    text-wrap-before: true;
    text-line-spacing: -3;
    text-fill: @label_color_green_area;
    text-size: 15;

    [zoom>=8] {
      text-halo-fill: @label_color_green_area_halo;
      text-halo-radius: @text_font_halo_radius_sm;
    }

    [zoom>=11] {
      text-fill: #586e50;
      text-halo-radius: @text_font_halo_radius_large;
    }

    [zoom>=15] {
      text-size: 20;
      text-line-spacing: -7;
    }
  }
}

#continents
{
  text-name: [name];
  text-face-name: @text_font_administrative;
  text-wrap-width: 32;
  text-size: 24;
  text-line-spacing: -12;
  text-fill: #2e2115;
  text-halo-radius: @text_font_halo_radius_sm;
  text-halo-fill: @label_color_halo_low;
}

#admin1-labels {
  // [zoom>=4][scalerank<3],
  [zoom>=5][scalerank<3][admin!='United States of America'][admin!='Canada'],
  [zoom>=6][scalerank<5],
  [zoom>=7][scalerank>=5] {
    text-name: [name];
    text-transform: uppercase;
    text-face-name: @text_font_administrative;
    text-face-name: @text_font_administrative;
    text-fill: @label_color_administrative;
    text-halo-fill: @label_color_halo_low;
    text-halo-radius: @text_font_halo_radius_sm;
    text-size: @text_font_size_sm;
    text-character-spacing: 1;
    text-wrap-width: 40;
    text-placement-type: simple;
    text-placements: 'E,N,W,S';

    [zoom>=5] {
     text-size: @text_font_size_sm;
    }

    [zoom>=6] {
      text-size: @text_font_size_medium;
      text-character-spacing: 2;
    }

    [zoom>=7] {
      text-size: @text_font_size_large;
      text-character-spacing: 3;
    }
  }
}

#admin1-labels-50m-z4 {
    text-face-name: @text_font_administrative;
    text-wrap-width: 80;
    text-fill: @label_color_administrative;
    text-halo-radius: @text_font_halo_radius_sm;
    text-halo-fill: @label_color_halo_low;
    text-name: "[label_z4]";
    text-size:  @text_font_size_xsm;
    text-character-spacing: 1;
}

#admin1-labels-50m-z5 {
    text-face-name: @text_font_administrative;
    text-wrap-width: 80;
    text-fill: @label_color_administrative;
    text-halo-radius: @text_font_halo_radius_sm;
    text-halo-fill: @label_color_halo_low;
    // text-halo-comp-op: overlay;
    text-halo-rasterizer: fast;
    text-name: "[label_z5]";
    text-size:  @text_font_size_sm;
    text-character-spacing: 1;
}

#admin1-labels-50m-z6 {
    text-face-name: @text_font_administrative;
    text-wrap-width: 80;
    text-fill: @label_color_administrative;
    text-halo-radius: @text_font_halo_radius_sm;
    text-halo-fill: @label_color_halo_low;
    text-name: "[label_z6]";
    text-size:  @text_font_size_medium;
    text-character-spacing: 2;
}

#admin1-labels-50m-z7 {
    text-face-name: @text_font_administrative;
    text-wrap-width: 80;
    text-fill: @label_color_administrative;
    text-halo-radius: @text_font_halo_radius_sm;
    text-halo-fill: @label_color_halo_low;
    text-name: "[label_z7]";
    text-size:  @text_font_size_large;
    text-character-spacing: 3;
}

/* Admin 0 labels */

#admin0-labels-z3[longfrom>3] {
    text-name: "[shortname]";
    text-face-name: @text_font_administrative;
    text-transform: uppercase;
    text-wrap-width: 80;
    text-character-spacing: @text_character_spacing_sm;
    text-size: @text_font_size_medium_plus;
    text-halo-radius: @text_font_halo_radius_sm;
    text-halo-fill: @label_color_halo_low;
    text-fill: @label_color_administrative;
    text-min-distance: 5;
}

#admin0-labels-z3[longfrom<=3] {
    text-name: "[name]";
    text-face-name: @text_font_administrative;
    text-transform: uppercase;
    text-size: @text_font_size_large;
    text-line-spacing: -8;
    text-wrap-width: 100;
    text-character-spacing: @text_character_spacing_sm;
    text-halo-radius: @text_font_halo_radius_sm;
    text-halo-fill: @label_color_halo_low;
    text-fill: @label_color_administrative;
}

#admin0-labels-z4 {
    text-name: [name];
    text-face-name: @text_font_administrative;
    text-transform: uppercase;
    text-wrap-width: 80;
    text-character-spacing: @text_character_spacing_lg;
    text-size: @text_font_size_large;
    text-min-distance: 15;
    text-halo-radius: @text_font_halo_radius_sm;
    text-halo-fill: @label_color_halo_low;
    text-fill: @label_color_administrative;
}

#admin0-labels-z5 {
  text-name: [name];
  text-face-name: @text_font_administrative;
  text-transform: uppercase;
  text-wrap-width: 80;
  text-character-spacing: @text_character_spacing_xlg;
  text-size: @text_font_size_xlg;
  text-halo-radius: @text_font_halo_radius_sm;
  text-halo-fill: @label_color_halo_low;
  text-fill: @label_color_administrative;
}

#admin0-labels-z6 {
  text-name: [name];
  text-face-name: @text_font_administrative;
  text-transform: uppercase;
  text-wrap-width: 80;
  text-character-spacing: @text_character_spacing_xlg;
  text-size: @text_font_size_xxlg;
  text-halo-radius: @text_font_halo_radius_sm;
  text-halo-fill: @label_color_halo_low;
  text-fill: @label_color_administrative;
}

/* city labels */

#aries-places-labels {
  [zoom=4][scalerank<5],
  [zoom=5][scalerank<6],
  [zoom=6][scalerank<7],
  [zoom=7][scalerank<8],
  [zoom=8][scalerank<9],
  [zoom=9][scalerank<10],
  [zoom=10][scalerank<11],
  [zoom=11][scalerank<12],
  [zoom=12][scalerank<13],
  [zoom=13][scalerank<14],
  [zoom=14][scalerank<15]
  [zoom>=15][scalerank<15]{

    shield-file: url(shields/circle-12.svg);
    shield-fill: @label_color_city;
    shield-halo-fill: @label_color_halo_low;
    shield-halo-radius: @text_font_halo_radius_sm;
    shield-unlock-image: true;
    shield-transform: scale(0.5, 0.5);
    shield-face-name: @text_font_city;
    shield-name: [name];
    shield-min-distance: 2;
    shield-placement-type: simple;
    shield-placements: 'NE, N, NW, SE, S, SW';
    shield-justify-alignment: auto;
    shield-horizontal-alignment: auto;

    [zoom>=4] {
      shield-size: @text_font_size_xsm;
      shield-text-dy: -7;

      [population>700000] {
        shield-size: @text_font_size_xsm * 1.2;
        shield-transform: scale(0.7, 0.7);
        shield-text-dy: -9;
      }

      [population>7000000] {
        shield-size: @text_font_size_xsm * 1.3;
        shield-transform: scale(0.8, 0.8);
        shield-text-dy: -10;
      }
    }

    [zoom>=5]{
      shield-size: @text_font_size_sm;
      shield-text-dy: -7;

      [population>700000] {
        shield-size: @text_font_size_sm * 1.2;
        shield-text-dy: -9;
      }

      [population>7000000] {
        shield-size: @text_font_size_sm * 1.3;
      }
    }

    [zoom>=6]{
      shield-size: @text_font_size_medium;
      shield-text-dy: -8;

      [population>700000] {
        shield-size: @text_font_size_medium * 1.2;
      }

      [population>7000000] {
        shield-size: @text_font_size_medium * 1.5;
      }
    }

    [zoom>=8] {
      shield-halo-radius: @text_font_halo_radius_md;
    }

    [zoom>=10]{
      shield-size: @text_font_size_medium_plus;
      shield-halo-radius: @text_font_halo_radius_large;
      shield-halo-fill: @label_color_halo_high;

      [population>700000] {
        shield-size: @text_font_size_medium_plus * 1.2;
      }

      [population>7000000] {
        shield-size: @text_font_size_medium_plus * 1.3;
      }
    }

    [zoom>=11] {
      shield-opacity: 0;
    }

    [zoom>=12] {
      shield-size: @text_font_size_xlg;

      [population>700000] {
        shield-size: @text_font_size_xlg * 1.2;
      }

      [population>7000000] {
        shield-size: @text_font_size_xlg * 1.3;
      }
    }
  }
}

#airports {
  [zoom>=10] {
    text-name: [abbrev];
    text-face-name: @text_font_transport;
    text-fill: #444;
    text-size: @text_font_size_medium_plus;

    text-halo-fill: @label_color_airport_halo;
    text-halo-radius: @text_font_halo_radius_large;

    text-wrap-width: 128;
    text-dy: 14;
  }

  [zoom>=13] {
    text-name: [name];
  }

  [zoom=14][natlscale>.04],
  [zoom=15][natlscale>.02],
  [zoom>=16][natlscale>.01]
  {
      text-dy: 20;
  }

  [zoom=8][natlscale>2.3][type='major'],
  [zoom=9][natlscale>1.2][type='major'],
  [zoom=10][natlscale>0.57][type='major'],
  [zoom=11][natlscale>0.29][type='major'],
  [zoom=12][natlscale>0.29][type='major'],
  [zoom=13][natlscale>0.29][type='major']
  {
    point-file: url('icons/airport_major_l.png');
  }

  [zoom=14][natlscale>.29][type='major'],
  [zoom=15][natlscale>.29][type='major'],
  [zoom>=16][natlscale>.29][type='major']
  {
      point-file: url('icons/airport_major_xl.png');
  }

  [zoom=8][natlscale>2.3][type='small'],
  [zoom=9][natlscale>1.2][type='small'],
  [zoom=10][natlscale>.57][type='small'],
  [zoom=11][natlscale>.29][type='small'],
  [zoom=12][natlscale>.29][type='small'],
  [zoom=13][natlscale>.29][type='small']
  {
      point-file: url('icons/airport_small_l.png');
  }

  [zoom=14][natlscale>.29][type='small'],
  [zoom=15][natlscale>.29][type='small'],
  [zoom>=16][natlscale>.29][type='small']
  {
      point-file: url('icons/airport_small_xl.png');
  }

  [zoom=8][natlscale>2.3][type='military'],
  [zoom=9][natlscale>1.2][type='military'],
  [zoom=10][natlscale>.57][type='military'],
  [zoom=11][natlscale>.29][type='military'],
  [zoom=12][natlscale>.29][type='military'],
  [zoom=13][natlscale>.29][type='military']
  {
      point-file: url('icons/airport_military_l.png');
  }

  [zoom=14][natlscale>.29][type='military'],
  [zoom=15][natlscale>.29][type='military'],
  [zoom>=16][natlscale>.29][type='military']
  {
      point-file: url('icons/airport_military_xl.png');
  }

  [zoom=8][natlscale>2.3][type='spaceport'],
  [zoom=9][natlscale>1.2][type='spaceport'],
  [zoom=10][natlscale>.57][type='spaceport'],
  [zoom=11][natlscale>.29][type='spaceport'],
  [zoom=12][natlscale>.29][type='spaceport'],
  [zoom=13][natlscale>.29][type='spaceport']
  {
      point-file: url('icons/intergalactic_l.png');
  }

  [zoom=14][natlscale>.29][type='spaceport'],
  [zoom=15][natlscale>.29][type='spaceport'],
  [zoom>=16][natlscale>.29][type='spaceport']
  {
      point-file: url('icons/intergalactic_xl.png');
  }
}


Move filename dialog to DoExport() and return filename

Like this, project specific export plugins can more easily use the standard
sibmei behavior for determining file names. The returned file name can also
be used to trigger postprocessing for the exported file.

function Run() {
    //$module(Run.mss)

    // do some preliminary checks
    if (Sibelius.ProgramVersion < 7000)
    {
        Sibelius.MessageBox(_VersionNotSupported);
        return False;
    }

    if (Sibelius.ScoreCount = 0)
    {
        Sibelius.MessageBox(_ScoreError);
        return False;
    }

    DoExport(null);

}  //$end

function GetExportFileName () {
    // get the active score object
    activeScore = Sibelius.ActiveScore;

    if (Sibelius.FileExists(activeScore.FileName)) {
        scoreFile = Sibelius.GetFile(activeScore.FileName);
        activeFileName = scoreFile.NameNoPath & '.mei';
        activePath = scoreFile.Path;
    } else {
        activeFileName = 'untitled.mei';
        activePath = Sibelius.GetDocumentsFolder();
    }

    if (not InitGlobals(null))
    {
        return null;
    }

    // Ask to the file to be saved somewhere
    filename = Sibelius.SelectFileToSave('Save as...', activeFileName, activePath, 'mei', 'TEXT', 'Music Encoding Initiative');

    return filename;
} //$end

function DoExport (filename) {
    //$module(Run.mss)

    // Argument filename is optional and will be determined automatically if
    // `null` is passed in instead.  The filename is also returned so the
    // caller can then work with.
    if (null = filename)
    {
        filename = GetExportFileName();
        if (null = filename)
        {
            Sibelius.MessageBox(_ExportFileIsNull);
            return null;
        }
    }

    if (not Self._property:_Initialized)
    {
        Trace('InitGlobals() must be called before running DoExport()');
        return null;
    }

    // first, ensure we're running with a clean slate.
    // (initialization of libmei has moved to InitGlobals())
    libmei.destroy();

    // set the active score here so we can refer to it throughout the plugin
    Self._property:ActiveScore = Sibelius.ActiveScore;
    if (Self._property:ActiveScore = null)
    {
        Sibelius.MessageBox('Could not find an active score. Cannot export to ' & filename);
        return false;
    }

    // Set up the warnings tracker
    Self._property:warnings = CreateSparseArray();

    // Deal with the Progress GUI
    progCount = Sibelius.ActiveScore.SystemStaff.BarCount;
    fn = utils.ExtractFileName(filename);
    progressTitle = utils.Format(_InitialProgressTitle, fn);
    Sibelius.CreateProgressDialog(progressTitle, 0, progCount - 1);

    // finally, process the score.
    ProcessScore();

    doc = libmei.getDocument();
    // save the file
    export_status = libmei.meiDocumentToFile(doc, filename);

    // start cleaning up.
    Sibelius.DestroyProgressDialog();

    // display the warnings that were registered during the export process
    for each warning in Self._property:warnings
    {
        trace('Warning: ' & warning);
    }

    if (export_status = False)
    {
        Sibelius.MessageBox(_ExportFailure);
    }

    // clean up after ourself
    libmei.destroy();

    return filename;
}  //$end

function Run() {
    //$module(Run.mss)

    // do some preliminary checks
    if (Sibelius.ProgramVersion < 7000)
    {
        Sibelius.MessageBox(_VersionNotSupported);
        return False;
    }

    if (Sibelius.ScoreCount = 0)
    {
        Sibelius.MessageBox(_ScoreError);
        return False;
    }

    // get the active score object
    activeScore = Sibelius.ActiveScore;

    if (Sibelius.FileExists(activeScore.FileName)) {
        scoreFile = Sibelius.GetFile(activeScore.FileName);
        activeFileName = scoreFile.NameNoPath & '.mei';
        activePath = scoreFile.Path;
    } else {
        activeFileName = 'untitled.mei';
        activePath = Sibelius.GetDocumentsFolder();
    }

    if (not InitGlobals(null))
    {
        return false;
    }

    // Ask to the file to be saved somewhere
    filename = Sibelius.SelectFileToSave('Save as...', activeFileName, activePath, 'mei', 'TEXT', 'Music Encoding Initiative');

    if (filename = null)
    {
        Sibelius.MessageBox(_ExportFileIsNull);
        return False;
    }

    DoExport(filename);

}  //$end

function DoExport (filename) {
    //$module(Run.mss)

    if (not Self._property:_Initialized)
    {
        Trace('InitGlobals() must be called before running DoExport()');
        return null;
    }

    // first, ensure we're running with a clean slate.
    // (initialization of libmei has moved to InitGlobals())
    libmei.destroy();

    // set the active score here so we can refer to it throughout the plugin
    Self._property:ActiveScore = Sibelius.ActiveScore;
    if (Self._property:ActiveScore = null)
    {
        Sibelius.MessageBox('Could not find an active score. Cannot export to ' & filename);
        return false;
    }

    // Set up the warnings tracker
    Self._property:warnings = CreateSparseArray();

    // Deal with the Progress GUI
    progCount = Sibelius.ActiveScore.SystemStaff.BarCount;
    fn = utils.ExtractFileName(filename);
    progressTitle = utils.Format(_InitialProgressTitle, fn);
    Sibelius.CreateProgressDialog(progressTitle, 0, progCount - 1);

    // finally, process the score.
    ProcessScore();

    doc = libmei.getDocument();
    // save the file
    export_status = libmei.meiDocumentToFile(doc, filename);

    // start cleaning up.
    Sibelius.DestroyProgressDialog();

    // display the warnings that were registered during the export process
    for each warning in Self._property:warnings
    {
        trace('Warning: ' & warning);
    }

    if (export_status = False)
    {
        Sibelius.MessageBox(_ExportFailure);
    }

    // clean up after ourself
    libmei.destroy();
}  //$end


Fix label positions on the progress map for concave polygons.

Some of the neighborhood polygons on the progress map have centroids that
lie outside the polygon, which leads to their percentage label being
placed inside a different neighborhood (which will then have two labels).

By adding `text-placement: interior` to the CartoCSS, we tell Mapnik to
prefer placing labels on the interior of polygons if the centroid is not
inside the poygon.

/* If you change these colors, also change src/nyc_trees/sass/partials/_legend.scss */
@mapped: #8BC34A;
@not-mapped: #85664B;
@not-mapped-zoomed-out: #85664B;

#survey_blockface {
  line-join: round;
  line-cap: round;

  line-opacity: 1;

  // Note: this must be kept in sync with src/nyc_trees/js/src/BlockfaceLayer.js
  line-width: 1;
  [zoom = 16]{ line-width: 2; }
  [zoom = 17]{ line-width: 4; }
  [zoom = 18]{ line-width: 8; }
  [zoom = 19]{ line-width: 16; }

  [is_mapped = 'T'] {
    line-color: @mapped;
    [zoom <= 17]{ line-width: 6; }
  }
  [is_mapped = 'F'] {
    line-color: @not-mapped;
    [zoom <= 15]{
      line-color: @not-mapped-zoomed-out;
    }
  }
}

/* If you change these colors, also change src/nyc_trees/sass/partials/_legend.scss */
#survey_borough,#survey_neighborhoodtabulationarea {
  line-color: #555;
  line-width: 1;
  polygon-opacity: 0.50;
  polygon-fill: #fff;
  [percent >= 10] { polygon-fill: #F6F9F4 }
  [percent >= 20] { polygon-fill: #D7EBC7 }
  [percent >= 30] { polygon-fill: #B8DD9B }
  [percent >= 40] { polygon-fill: #99CF6F }
  [percent >= 50] { polygon-fill: #7AC143 }
  [percent >= 60] { polygon-fill: #5BA63B }
  [percent >= 70] { polygon-fill: #3D8C33 }
  [percent >= 80] { polygon-fill: #1E722B }
  [percent >= 90] { polygon-fill: #005824 }
}

/*

Running this command in the windshaft module directory will list available fonts
node -e "var m=require('mapnik');m.register_system_fonts();console.log(m.fontFiles())"

*/

#survey_borough::labels,
#survey_neighborhoodtabulationarea::labels {
  text-name: '[label]';
  text-face-name: 'DejaVu Sans Bold';
  text-fill: #000;
  text-size: 12;
  text-halo-fill:  fadeout(#fff, 30%);
  text-halo-radius: 2;
  text-placement: interior;
}

/* If you change these colors, also change src/nyc_trees/sass/partials/_legend.scss */
@mapped: #8BC34A;
@not-mapped: #85664B;
@not-mapped-zoomed-out: #85664B;

#survey_blockface {
  line-join: round;
  line-cap: round;

  line-opacity: 1;

  // Note: this must be kept in sync with src/nyc_trees/js/src/BlockfaceLayer.js
  line-width: 1;
  [zoom = 16]{ line-width: 2; }
  [zoom = 17]{ line-width: 4; }
  [zoom = 18]{ line-width: 8; }
  [zoom = 19]{ line-width: 16; }

  [is_mapped = 'T'] {
    line-color: @mapped;
    [zoom <= 17]{ line-width: 6; }
  }
  [is_mapped = 'F'] {
    line-color: @not-mapped;
    [zoom <= 15]{
      line-color: @not-mapped-zoomed-out;
    }
  }
}

/* If you change these colors, also change src/nyc_trees/sass/partials/_legend.scss */
#survey_borough,#survey_neighborhoodtabulationarea {
  line-color: #555;
  line-width: 1;
  polygon-opacity: 0.50;
  polygon-fill: #fff;
  [percent >= 10] { polygon-fill: #F6F9F4 }
  [percent >= 20] { polygon-fill: #D7EBC7 }
  [percent >= 30] { polygon-fill: #B8DD9B }
  [percent >= 40] { polygon-fill: #99CF6F }
  [percent >= 50] { polygon-fill: #7AC143 }
  [percent >= 60] { polygon-fill: #5BA63B }
  [percent >= 70] { polygon-fill: #3D8C33 }
  [percent >= 80] { polygon-fill: #1E722B }
  [percent >= 90] { polygon-fill: #005824 }
}

/*

Running this command in the windshaft module directory will list available fonts
node -e "var m=require('mapnik');m.register_system_fonts();console.log(m.fontFiles())"

*/

#survey_borough::labels,
#survey_neighborhoodtabulationarea::labels {
  text-name: '[label]';
  text-face-name: 'DejaVu Sans Bold';
  text-fill: #000;
  text-size: 12;
  text-halo-fill:  fadeout(#fff, 30%);
  text-halo-radius: 2;
}


New: Method to convert Units to typographic points

function ConvertClef (clefid) {
    //$module(ExportConverters.mss)
    clefparts = MSplitString(clefid, '.');
    shape = ' ';
    line = ' ';
    dis = ' ';
    dir = ' ';

    switch(clefparts[2])
    {
        case ('down')
        {
            dir = 'below';
        }
        case ('up')
        {
            dir = 'above';
        }
    }

    switch(clefparts[3])
    {
        case ('8')
        {
            dis = '8';
        }
        case ('15')
        {
            dis = '15';
        }
    }
    switch (clefparts[1]) {
        case ('bass')
        {
            shape = 'F';
            line = '4';
        }
        case ('treble')
        {
            if (clefparts[4] = 'old')
            {
                shape = 'GG';
            }
            else
            {
                shape = 'G';
            }
            line = '2';
        }
        case ('tenor')
        {
            shape = 'C';
            line = '4';
        }
        case ('alto')
        {
            shape = 'C';
            line = '3';
        }
        case ('soprano')
        {
            shape = 'C';
            if (clefparts[2] = 'mezzo')
            {
                line = '2';
            }
            else
            {
                line = '1';
            }
        }
        case ('baritone')
        {
            if (clefparts[2] = 'c')
            {
                shape = 'C';
                line = '5';
            }
            else
            {
                shape = 'F';
                line = '3';
            }
        }
        case ('violin')
        {
            shape = 'G';
            line = '1';
        }
        case ('sub-bass')
        {
            shape = 'F';
            line = '5';
        }
        case ('tab')
        {
            shape = 'TAB';
        }
        case (('percussion') or ('percussion_2'))
        {
            shape = 'perc';
        }
    }
    ret = CreateSparseArray(shape, line, dis, dir);
    return ret;
}  //$end

function ConvertOctava (octava_id) {
    //$module(ExportConverters.mss)
    octparts = MSplitString(octava_id, '.');
    switch(octparts[3])
    {
        case ('minus15')
        {
            dis = '15';
            place = 'below';
        }
        case ('minus8')
        {
            dis = '8';
            place = 'below';
        }
        case ('plus15')
        {
            dis = '15';
            place = 'above';
        }
        case ('plus8')
        {
            dis = '8';
            place = 'above';
        }
        default
        {
            dis = ' ';
            place = ' ';
        }
    }
    return CreateSparseArray(dis, place);
}  //$end

function ConvertSlur (slur_value) {
    //$module(ExportConverters.mss)
    slurparts = MSplitString(slur_value, '.');
    direction = ' ';
    style = ' ';
    switch(slurparts[3])
    {
        case ('up')
        {
            direction = 'above';
        }
        case ('down')
        {
            direction = 'below';
        }
        default
        {
            direction = ' ';
        }
    }
    switch(slurparts[4])
    {
        case ('dashed')
        {
            style = 'dashed';
        }
        case ('dotted')
        {
            style = 'dotted';
        }
        default
        {
            style = ' ';
        }
    }
    return CreateSparseArray(direction, style);
}  //$end

function ConvertDiatonicPitch (diatonic_pitch) {
    //$module(ExportConverters)
    octv = (diatonic_pitch / 7) - 1;
    pnames = CreateSparseArray('c', 'd', 'e', 'f', 'g', 'a', 'b');
    idx = (diatonic_pitch % 7);
    pname = pnames[idx];

    return CreateSparseArray(pname, octv);
}  //$end

function ConvertOffsetsToMillimeters (offset) {
    //$module(ExportConverters.mss)

    /*
     This function will convert the 1/32 unit
     Sibelius offsets into a millimeter measurement as required by the
     data.MEASUREMENT datatype used by MEI.

    The `StaffHeight` property always returns the staff height in millimeters.

    Most offsets are given in Sibelius Units, which
    are defined as 1/32 of a space. A space is 1/4 of the staff height, so
    the staff height is always 128. A unit is therefore:
    ((staffheight / 128) = units in mm.

    So a staff height of 7mm (default) gives us (7 / 128) = 0.05mm per Sibelius
    Unit.
    */
    scr = Sibelius.ActiveScore;
    staffheight = scr.StaffHeight;
    factor = (staffheight / 128.0);
    oset = factor * offset;
    retval = oset & 'mm';
    return retval;
}  //$end

function ConvertUnitsToPoints (units) {
    //$module(ExportConverters.mss)
    scr = Sibelius.ActiveScore;
    staffheight = scr.StaffHeight;

    /*
        Points are 0.352778mm (a point is 1/72 of an inch * 25.4mm/in).
    */
    retval = (((staffheight / 128.0) * units) / 0.352778;
    return retval & 'pt';
}  //$end

function ConvertDuration (dur) {
    //$module(ExportConverters.mss)
    // there doesn't really seem to be a smarter way to do this...
    // 1024 = 1 whole note

    ret = CreateSparseArray();

    pow = PrevPow2(dur);
    counter = pow;
    dots = 0;
    powcount = pow;
    durset = false;

    durrem = 1024 % dur;
    if (durrem != 0)
    {
        while (counter < dur)
        {
            powcount = (powcount / 2);
            counter = counter + powcount;
            dots = dots + 1;

            if (dots > 5)
            {
                // prevent a runaway loop.
                counter = 1000000000;
            }
        }
    }

    switch (powcount)
    {
        case (pow >= 4096)
        {
            ret[0] = 'long';
            durset = true;
        }
        case (pow >= 2048)
        {
            ret[0] = 'breve';
            durset = true;
        }
        default
        {
            if (durset = false)
            {
                ret[0] = 1024 / pow;
            }
        }
    }

    if (dots = 0)
    {
        ret[1] = ' ';
    }
    else
    {
        ret[1] = dots;
    }

    return ret;
}  //$end

function ConvertKeySignature (numsharps) {
    //$module(ExportConverters.mss)
    switch (numsharps)
    {
        case (0)
        {
            // key of c
            return '0';
        }
        case (-8)
        {
            // atonal in Sibelius
            return '0';
        }
        case (numsharps > 0)
        {
            // sharps
            return numsharps & 's';
        }
        case (numsharps < 0)
        {
            //flats
            return utils.AbsoluteValue(numsharps) & 'f';
        }
    }
}  //$end

function PitchesInKeySignature (keysig) {
    //$module(ExportConverters.mss)

    // keysig is 7 >= 0 >= -7, for the number of sharps (negative is flats)
    ac = CreateSparseArray('F', 'C', 'G', 'D', 'A', 'E', 'B');
    if (keysig = 0)
    {
        return CreateSparseArray();
    }

    if (keysig > 0)
    {
        return ac.Slice(0, keysig);
    }
    else
    {
        v = ac.Slice(keysig);
        v.Reverse();
        return v;
    }
}  //$end

function ConvertAccidental (noteobj) {
    //$module(ExportConverters.mss)
    // If accidentals are audible, but not visible, you get @accid.ges
    // If accidentals are both audible and visible, you get @accid
    // is_visible is not to be confused with hidden accidentals! is_visible
    // just determines whether an accidental is shown or not based on
    // the rules of CMN.

    // Returns a tuple [0 => accid (string), 1 => is_visible (bool)]
    // If the accidental is a natural and is visible, returns ('n', true); otherwise,
    // it returns ('', false);

    // first, determine if the accidental is visible.
    is_visible = HasVisibleAccidental(noteobj);
    ac = ' ';

    pname = Substring(noteobj.Name, 0, 1);  // captures first letter
    accid = Substring(noteobj.Name, 1);     // captures all other characters

    switch(accid)
    {
        case('bb')
        {
            ac = 'ff';
        }
        case('b-')
        {
            ac = 'fd';
        }
        case('b')
        {
            ac = 'f';
        }
        case('-')
        {
            ac = 'fu';
        }
        case('')
        {
            if (is_visible = True)
            {
                ac = 'n';
            }
        }
        case('+')
        {
            ac = 'sd';
        }
        case('#')
        {
            ac = 's';
        }
        case('#+')
        {
            ac = 'su';
        }
        case('x')
        {
            ac = 'x';
        }
        case('##')
        {
            ac = 'ss';
        }
    }

    ret = CreateSparseArray(ac, is_visible);
    return ret;
}  //$end

function HasVisibleAccidental (noteobj) {
    //$module(ExportConverters.mss)
    // determines whether a note is *likely* to have a visible accidental.
    // Caution: This is probably not 100% accurate.

    // Returns a boolean if the note is visible.

    // If it has a cautionary accidental, it's most likely to be visible.
    if (noteobj.AccidentalStyle = CautionaryAcc)
    {
        return True;
    }

    if (noteobj.AccidentalStyle = HiddenAcc)
    {
        return False;
    }

    keysig = noteobj.ParentNoteRest.ParentBar.GetKeySignatureAt(noteobj.ParentNoteRest.Position);
    sf = sibmei2.PitchesInKeySignature(keysig.Sharps);
    pname = Substring(noteobj.Name, 0, 1);  // captures first letter
    accid = Substring(noteobj.Name, 1);  // captures all other characters

    // if the note is not in the key signature, then it should have an accidental
    note_is_in_keysig = utils.IsInArray(sf, pname);
    has_prev_pitch_with_accidental = False;

    parent_nr = noteobj.ParentNoteRest;
    parent_bar = parent_nr.ParentBar;

    for each NoteRest nr in parent_bar
    {
        if (nr.Position < parent_nr.Position)
        {
            for each n in nr
            {
                pname2 = Substring(n.Name, 0, 1);  // captures first letter
                accid2 = Substring(n.Name, 1);  // captures all other characters

                if (n.Name = noteobj.Name and note_is_in_keysig = False and n.Accidental != 0)
                {
                    has_prev_pitch_with_accidental = True;
                }

                if (n.Name = noteobj.Name and n.AccidentalStyle = CautionaryAcc)
                {
                    has_prev_pitch_with_accidental = True;
                }

                if (n.Name = noteobj.Name and note_is_in_keysig = True)
                {
                    has_prev_pitch_with_accidental = False;
                }

                // this is a special case for dealing with naturals. If the pitch names
                // match, and the note is not in the key signature, and the previous pitch
                // was not empty, then we probably have a natural on the query note.
                if (pname = pname2 and note_is_in_keysig = False and accid2 != '')
                {
                    has_prev_pitch_with_accidental = True;
                }

            }
        }
        else
        {
            for each n in nr
            {
                if (n.Name = noteobj.Name and n.Accidental != 0 and note_is_in_keysig = True)
                {
                    has_prev_pitch_with_accidental = False;
                }
            }
        }
    }

    // deal with the 'weird' accidental values that don't have a value in noteobj.Accidental
    switch (accid)
    {
        case ('bb')
        {
            ret = (has_prev_pitch_with_accidental != True);
            return ret;
        }
        case ('b-')
        {
            ret = (has_prev_pitch_with_accidental != True);
            return ret;
        }
        case ('-')
        {
            ret = (has_prev_pitch_with_accidental != True);
            return ret;
        }
        case ('+')
        {
            ret = (has_prev_pitch_with_accidental != True);
            return ret;
        }
        case ('#+')
        {
            ret = (has_prev_pitch_with_accidental != True);
            return ret;
        }
    }

    if (noteobj.Accidental = 0 and note_is_in_keysig = True and has_prev_pitch_with_accidental = False)
    {
        // it's a natural?
        return True;
    }

    if (note_is_in_keysig = True and has_prev_pitch_with_accidental = False)
    {
        return False;
    }

    if (has_prev_pitch_with_accidental = False and noteobj.Accidental != 0)
    {
        return True;
    }

    if (has_prev_pitch_with_accidental = True and accid = '')
    {
        // this is the corresponding return value for special cased naturals.
        return True;
    }

    // Finally, by default, assume this has no accidental.
    return False;
}  //$end

function ConvertNamedTimeSignature (timesig) {
    //$module(ExportConverters.mss)
    switch(timesig)
    {
        case(CommonTimeString)
        {
            return 'common';
        }
        case(AllaBreveTimeString)
        {
            return 'cut';
        }
        default
        {
            return ' ';
        }
    }
}  //$end

function ConvertBracket (bracket) {
    //$module(ExportConverters.mss)
    switch(bracket)
    {
        case(BracketFull)
        {
            return 'bracket';
        }
        case(BracketBrace)
        {
            return 'brace';
        }
        case(BracketSub)
        {
            return 'line';
        }
        default
        {
            return 'none';
        }
    }
}  //$end

function ConvertSibeliusStructure (score) {
    //$module(ExportConverters.mss)
    // Takes in the Staff/Bar Sibelius Structure and returns a Bar/Staff
    // mapping for our MEI writers.
    bar_to_staff = CreateDictionary();

    // Invert the Sibelius structure
    for each Staff s in score
    {
        for each Bar b in s
        {
            if (bar_to_staff.PropertyExists(b.BarNumber))
            {
                bar_to_staff[b.BarNumber].Push(s.StaffNum);
            }
            else
            {
                bar_to_staff[b.BarNumber] = CreateSparseArray();
                bar_to_staff[b.BarNumber].Push(s.StaffNum);
            }
        }
    }
    return bar_to_staff;
}  //$end

function ConvertColor (nrest) {
    //$module(ExportConverters.mss)
    r = nrest.ColorRed;
    g = nrest.ColorGreen;
    b = nrest.ColorBlue;
    a_dec = nrest.ColorAlpha & '.0';
    a = a_dec / 255.0;

    return 'rgba(' & r & ',' & g & ',' & b & ',' & a & ')';
}  //$end

function ConvertNoteStyle (style) {
    //$module(ExportConverters.mss)
    noteStyle = ' ';

    if (style = NormalNoteStyle)
    {
        return ' ';
    }

    switch (style)
    {
        case (CrossNoteStyle)
        {
            noteStyle = 'cross';
        }
        case (DiamondNoteStyle)
        {
            noteStyle = 'diamond';
        }
        case (CrossOrDiamondNoteStyle)
        {
            // Sibelius uses this for percussion
            // and does not differentiate in the
            // head style, so we have to choose one
            // or the other.
            noteStyle = 'cross';
        }
        case (BlackAndWhiteDiamondNoteStyle)
        {
            noteStyle = 'filldiamond';
        }
        case (SlashedNoteStyle)
        {
            noteStyle = 'addslash';
        }
        case (BackSlashedNoteStyle)
        {
            noteStyle = 'addbackslash';
        }
        case (ArrowDownNoteStyle)
        {
            // this is not completely correct, since
            // we use the same value for up and down
            // iso triangles. But it's all we have for now.
            noteStyle = 'isotriangle';
        }
        case (ArrowUpNoteStyle)
        {
            noteStyle = 'isotriangle';
        }
        case (InvertedTriangleNoteStyle)
        {
            noteStyle = 'isotriangle';
        }
        case (ShapedNote1NoteStyle)
        {
            noteStyle = 'isotriangle';
        }
        case (ShapedNote2NoteStyle)
        {
            noteStyle = 'semicircle';
        }
        case (ShapedNote3NoteStyle)
        {
            noteStyle = 'diamond';
        }
        case (ShapedNote4StemUpNoteStyle)
        {
            noteStyle = 'rtriangle';
        }
        case (ShapedNote4StemDownNoteStyle)
        {
            noteStyle = 'rtriangle';
        }
        case (ShapedNote5NoteStyle)
        {
            // this looks normal...
            noteStyle = ' ';
        }
        case (ShapedNote6NoteStyle)
        {
            // there is no square in MEI...
            noteStyle = ' ';
        }
        case (ShapedNote7NoteStyle)
        {
            noteStyle = 'piewedge';
        }
    }

    return noteStyle;
}  //$end

function ConvertSlurStyle (style) {
    //$module(ExportConverters.mss)
    slurparts = MSplitString(style, '.');
    direction = ' ';
    style = ' ';

    switch(slurparts[3])
    {
        case ('up')
        {
            direction = 'above';
        }
        case ('down')
        {
            direction = 'below';
        }
        default
        {
            direction = ' ';
        }
    }
    switch(slurparts[4])
    {
        case ('dashed')
        {
            style = 'dashed';
        }
        case ('dotted')
        {
            style = 'dotted';
        }
        default
        {
            style = ' ';
        }
    }
    return CreateSparseArray(direction, style);
}  //$end

function ConvertPositionToTimestamp (position, bar) {
    //$module(ExportConverters.mss)
    /*
        To convert Sibelius ticks to musical timestamps
        we use the formula:

        tstamp = (notePosition / (barLength / beatsInBar))
    */

    // make sure we're working with floating point numbers
    // and yes, this makes me feel very, very dirty in case
    // you were wondering, but this is the only way ManuScript
    // can cast to floating point...
    barlength = bar.Length;
    timesignature = Sibelius.ActiveScore.SystemStaff.CurrentTimeSignature(bar.BarNumber);

    if (position = 0)
    {
        return 1;
    }

    barlen = barlength & '.0';
    pos = position & '.0';
    beats = timesignature.Numerator & '.0';
    unit = (barlen / beats);
    ret = (pos / unit) + 1;

    return ret;
}  //$end

function ConvertTupletStyle (tupletStyle) {
    //$module(ExportConverters.mss)
    switch (tupletStyle)
    {
        case(TupletNoNumber)
        {
            libmei.addAttribute(activeTuplet, 'dur.visible', 'false');
        }
        case(TupletLeft)
        {
            libmei.addAttribute(activeTuplet, 'num.format', 'count');
        }
        case(TupletLeftRight)
        {
            libmei.addAttribute(activeTuplet, 'num.format', 'ratio');
        }
    }

}  //$end

function ConvertBarline (linetype) {
    //$module(ExportConverters.mss)
    switch(linetype)
    {
        case (SpecialBarlineStartRepeat)
        {
            // start repeat
            return 'rptstart';
        }
        case (SpecialBarlineEndRepeat)
        {
            // end repeat
            return 'rptend';
        }
        case (SpecialBarlineDashed)
        {
            // dashed
            return 'dashed';
        }
        case (SpecialBarlineDouble)
        {
            // double
            return 'dbl';
        }
        case (SpecialBarlineFinal)
        {
            // final
            return 'end';
        }
        case (SpecialBarlineInvisible)
        {
            // invisible
            return 'invis';
        }
        case (SpecialBarlineBetweenStaves)
        {
            // between staves
            // no MEI equiv.
            return ' ';
        }
        case (SpecialBarlineNormal)
        {
            // normal
            // this should usually be needed.
            return 'single';
        }
        case (SpecialBarlineTick)
        {
            // tick
            // unknown
            return ' ';
        }
        case (SpecialBarlineShort)
        {
            // short
            // unknown
            return ' ';
        }
        default
        {
            return ' ';
        }
    }
}  //$end

function ConvertText (textobj) {
    //$module(ExportConverters.mss)
    styleid = textobj.StyleId;
    switch (styleid)
    {
        case ('text.staff.expression')
        {
            dynam = libmei.Dynam();
            libmei.SetText(dynam, lstrip(textobj.Text));
            libmei.AddAttribute(dynam, 'staff', textobj.ParentBar.ParentStaff.StaffNum);
            libmei.AddAttribute(dynam, 'tstamp', ConvertPositionToTimestamp(textobj));

            if (textobj.Dx != 0)
            {
                libmei.AddAttribute(dynam, 'ho', ConvertOffsetsToMillimeters(textobj.Dx));
            }

            if (textobj.Dy != 0)
            {
                libmei.AddAttribute(dynam, 'vo', ConvertOffsetsToMillimeters(textobj.Dy));
            }
            return dynam;
        }
        case ('text.system.page_aligned.title')
        {
            return ConvertTextElement(textobj);
        }
        case ('text.system.page_aligned.composer')
        {
            return ConvertTextElement(textobj);
        }
        default
        {
            return null;
        }
    }
}  //$end

function ConvertTextElement (textobj) {
    //$module(ExportConverters.mss)
    obj = libmei.AnchoredText();
    libmei.SetText(obj, lstrip(textobj.Text));

    if (textobj.Dx != 0)
    {
        libmei.AddAttribute(obj, 'ho', ConvertOffsetsToMillimeters(textobj.Dx));
    }

    if (textobj.Dy != 0)
    {
        libmei.AddAttribute(obj, 'vo', ConvertOffsetsToMillimeters(textobj.Dy));
    }

    return obj;
}  //$end

function ConvertEndingValues (styleid) {
    //$module(ExportConverters)
    ending_style = MSplitString(styleid, '.');
    num = ' ';
    label = ' ';
    type = ' ';

    switch(ending_style[3])
    {
        case ('1st')
        {
            num = 1;
            label = '1.';
            type = 'closed';
        }
        case ('1st_n_2nd')
        {
            num = 1;
            label = '1. 2.';
            type = 'closed';
        }
        case ('2nd')
        {
            num = 2;
            label = '2.';
            if (ending_style[-1] = 'closed')
            {
                type = 'closed';
            }
            else
            {
                type = 'open';
            }
        }
        case ('3rd')
        {
            num = 3;
            label = '3.';
            type = 'closed';
        }
        case ('open')
        {
            type = 'open';
        }
        case ('closed')
        {
            type = 'closed';
        }
    }

    return CreateSparseArray(num, label, type);

}  //$end

function ConvertDate (datetime) {
    //$module(ExportConverters.mss)
    d = datetime.DayOfMonth;
    m = datetime.Month;
    y = datetime.Year;

    time = datetime.TimeWithSeconds;

    isodate = utils.Format('%s-%s-%sT%sZ', y, m, d, time);

    return isodate;
}  //$end

function ConvertClef (clefid) {
    //$module(ExportConverters.mss)
    clefparts = MSplitString(clefid, '.');
    shape = ' ';
    line = ' ';
    dis = ' ';
    dir = ' ';

    switch(clefparts[2])
    {
        case ('down')
        {
            dir = 'below';
        }
        case ('up')
        {
            dir = 'above';
        }
    }

    switch(clefparts[3])
    {
        case ('8')
        {
            dis = '8';
        }
        case ('15')
        {
            dis = '15';
        }
    }
    switch (clefparts[1]) {
        case ('bass')
        {
            shape = 'F';
            line = '4';
        }
        case ('treble')
        {
            if (clefparts[4] = 'old')
            {
                shape = 'GG';
            }
            else
            {
                shape = 'G';
            }
            line = '2';
        }
        case ('tenor')
        {
            shape = 'C';
            line = '4';
        }
        case ('alto')
        {
            shape = 'C';
            line = '3';
        }
        case ('soprano')
        {
            shape = 'C';
            if (clefparts[2] = 'mezzo')
            {
                line = '2';
            }
            else
            {
                line = '1';
            }
        }
        case ('baritone')
        {
            if (clefparts[2] = 'c')
            {
                shape = 'C';
                line = '5';
            }
            else
            {
                shape = 'F';
                line = '3';
            }
        }
        case ('violin')
        {
            shape = 'G';
            line = '1';
        }
        case ('sub-bass')
        {
            shape = 'F';
            line = '5';
        }
        case ('tab')
        {
            shape = 'TAB';
        }
        case (('percussion') or ('percussion_2'))
        {
            shape = 'perc';
        }
    }
    ret = CreateSparseArray(shape, line, dis, dir);
    return ret;
}  //$end

function ConvertOctava (octava_id) {
    //$module(ExportConverters.mss)
    octparts = MSplitString(octava_id, '.');
    switch(octparts[3])
    {
        case ('minus15')
        {
            dis = '15';
            place = 'below';
        }
        case ('minus8')
        {
            dis = '8';
            place = 'below';
        }
        case ('plus15')
        {
            dis = '15';
            place = 'above';
        }
        case ('plus8')
        {
            dis = '8';
            place = 'above';
        }
        default
        {
            dis = ' ';
            place = ' ';
        }
    }
    return CreateSparseArray(dis, place);
}  //$end

function ConvertSlur (slur_value) {
    //$module(ExportConverters.mss)
    slurparts = MSplitString(slur_value, '.');
    direction = ' ';
    style = ' ';
    switch(slurparts[3])
    {
        case ('up')
        {
            direction = 'above';
        }
        case ('down')
        {
            direction = 'below';
        }
        default
        {
            direction = ' ';
        }
    }
    switch(slurparts[4])
    {
        case ('dashed')
        {
            style = 'dashed';
        }
        case ('dotted')
        {
            style = 'dotted';
        }
        default
        {
            style = ' ';
        }
    }
    return CreateSparseArray(direction, style);
}  //$end

function ConvertDiatonicPitch (diatonic_pitch) {
    //$module(ExportConverters)
    octv = (diatonic_pitch / 7) - 1;
    pnames = CreateSparseArray('c', 'd', 'e', 'f', 'g', 'a', 'b');
    idx = (diatonic_pitch % 7);
    pname = pnames[idx];

    return CreateSparseArray(pname, octv);
}  //$end

function ConvertOffsetsToMillimeters (offset) {
    //$module(ExportConverters.mss)

    /*
     This function will convert the 1/32 unit
     Sibelius offsets into a millimeter measurement as required by the
     data.MEASUREMENT datatype used by MEI.

    The `StaffHeight` property always returns the staff height in millimeters.

    Most offsets are given in Sibelius Units, which
    are defined as 1/32 of a space. A space is 1/4 of the staff height, so
    the staff height is always 128. A unit is therefore:
    ((staffheight / 128) = units in mm.

    So a staff height of 7mm (default) gives us (7 / 128) = 0.05mm per Sibelius
    Unit.
    */
    scr = Sibelius.ActiveScore;
    staffheight = scr.StaffHeight;
    factor = (staffheight / 128.0);
    oset = factor * offset;
    retval = oset & 'mm';
    return retval;
}  //$end

function ConvertDuration (dur) {
    //$module(ExportConverters.mss)
    // there doesn't really seem to be a smarter way to do this...
    // 1024 = 1 whole note

    ret = CreateSparseArray();

    pow = PrevPow2(dur);
    counter = pow;
    dots = 0;
    powcount = pow;
    durset = false;

    durrem = 1024 % dur;
    if (durrem != 0)
    {
        while (counter < dur)
        {
            powcount = (powcount / 2);
            counter = counter + powcount;
            dots = dots + 1;

            if (dots > 5)
            {
                // prevent a runaway loop.
                counter = 1000000000;
            }
        }
    }

    switch (powcount)
    {
        case (pow >= 4096)
        {
            ret[0] = 'long';
            durset = true;
        }
        case (pow >= 2048)
        {
            ret[0] = 'breve';
            durset = true;
        }
        default
        {
            if (durset = false)
            {
                ret[0] = 1024 / pow;
            }
        }
    }

    if (dots = 0)
    {
        ret[1] = ' ';
    }
    else
    {
        ret[1] = dots;
    }

    return ret;
}  //$end

function ConvertKeySignature (numsharps) {
    //$module(ExportConverters.mss)
    switch (numsharps)
    {
        case (0)
        {
            // key of c
            return '0';
        }
        case (-8)
        {
            // atonal in Sibelius
            return '0';
        }
        case (numsharps > 0)
        {
            // sharps
            return numsharps & 's';
        }
        case (numsharps < 0)
        {
            //flats
            return utils.AbsoluteValue(numsharps) & 'f';
        }
    }
}  //$end

function PitchesInKeySignature (keysig) {
    //$module(ExportConverters.mss)

    // keysig is 7 >= 0 >= -7, for the number of sharps (negative is flats)
    ac = CreateSparseArray('F', 'C', 'G', 'D', 'A', 'E', 'B');
    if (keysig = 0)
    {
        return CreateSparseArray();
    }

    if (keysig > 0)
    {
        return ac.Slice(0, keysig);
    }
    else
    {
        v = ac.Slice(keysig);
        v.Reverse();
        return v;
    }
}  //$end

function ConvertAccidental (noteobj) {
    //$module(ExportConverters.mss)
    // If accidentals are audible, but not visible, you get @accid.ges
    // If accidentals are both audible and visible, you get @accid
    // is_visible is not to be confused with hidden accidentals! is_visible
    // just determines whether an accidental is shown or not based on
    // the rules of CMN.

    // Returns a tuple [0 => accid (string), 1 => is_visible (bool)]
    // If the accidental is a natural and is visible, returns ('n', true); otherwise,
    // it returns ('', false);

    // first, determine if the accidental is visible.
    is_visible = HasVisibleAccidental(noteobj);
    ac = ' ';

    pname = Substring(noteobj.Name, 0, 1);  // captures first letter
    accid = Substring(noteobj.Name, 1);     // captures all other characters

    switch(accid)
    {
        case('bb')
        {
            ac = 'ff';
        }
        case('b-')
        {
            ac = 'fd';
        }
        case('b')
        {
            ac = 'f';
        }
        case('-')
        {
            ac = 'fu';
        }
        case('')
        {
            if (is_visible = True)
            {
                ac = 'n';
            }
        }
        case('+')
        {
            ac = 'sd';
        }
        case('#')
        {
            ac = 's';
        }
        case('#+')
        {
            ac = 'su';
        }
        case('x')
        {
            ac = 'x';
        }
        case('##')
        {
            ac = 'ss';
        }
    }

    ret = CreateSparseArray(ac, is_visible);
    return ret;
}  //$end

function HasVisibleAccidental (noteobj) {
    //$module(ExportConverters.mss)
    // determines whether a note is *likely* to have a visible accidental.
    // Caution: This is probably not 100% accurate.

    // Returns a boolean if the note is visible.

    // If it has a cautionary accidental, it's most likely to be visible.
    if (noteobj.AccidentalStyle = CautionaryAcc)
    {
        return True;
    }

    if (noteobj.AccidentalStyle = HiddenAcc)
    {
        return False;
    }

    keysig = noteobj.ParentNoteRest.ParentBar.GetKeySignatureAt(noteobj.ParentNoteRest.Position);
    sf = sibmei2.PitchesInKeySignature(keysig.Sharps);
    pname = Substring(noteobj.Name, 0, 1);  // captures first letter
    accid = Substring(noteobj.Name, 1);  // captures all other characters

    // if the note is not in the key signature, then it should have an accidental
    note_is_in_keysig = utils.IsInArray(sf, pname);
    has_prev_pitch_with_accidental = False;

    parent_nr = noteobj.ParentNoteRest;
    parent_bar = parent_nr.ParentBar;

    for each NoteRest nr in parent_bar
    {
        if (nr.Position < parent_nr.Position)
        {
            for each n in nr
            {
                pname2 = Substring(n.Name, 0, 1);  // captures first letter
                accid2 = Substring(n.Name, 1);  // captures all other characters

                if (n.Name = noteobj.Name and note_is_in_keysig = False and n.Accidental != 0)
                {
                    has_prev_pitch_with_accidental = True;
                }

                if (n.Name = noteobj.Name and n.AccidentalStyle = CautionaryAcc)
                {
                    has_prev_pitch_with_accidental = True;
                }

                if (n.Name = noteobj.Name and note_is_in_keysig = True)
                {
                    has_prev_pitch_with_accidental = False;
                }

                // this is a special case for dealing with naturals. If the pitch names
                // match, and the note is not in the key signature, and the previous pitch
                // was not empty, then we probably have a natural on the query note.
                if (pname = pname2 and note_is_in_keysig = False and accid2 != '')
                {
                    has_prev_pitch_with_accidental = True;
                }

            }
        }
        else
        {
            for each n in nr
            {
                if (n.Name = noteobj.Name and n.Accidental != 0 and note_is_in_keysig = True)
                {
                    has_prev_pitch_with_accidental = False;
                }
            }
        }
    }

    // deal with the 'weird' accidental values that don't have a value in noteobj.Accidental
    switch (accid)
    {
        case ('bb')
        {
            ret = (has_prev_pitch_with_accidental != True);
            return ret;
        }
        case ('b-')
        {
            ret = (has_prev_pitch_with_accidental != True);
            return ret;
        }
        case ('-')
        {
            ret = (has_prev_pitch_with_accidental != True);
            return ret;
        }
        case ('+')
        {
            ret = (has_prev_pitch_with_accidental != True);
            return ret;
        }
        case ('#+')
        {
            ret = (has_prev_pitch_with_accidental != True);
            return ret;
        }
    }

    if (noteobj.Accidental = 0 and note_is_in_keysig = True and has_prev_pitch_with_accidental = False)
    {
        // it's a natural?
        return True;
    }

    if (note_is_in_keysig = True and has_prev_pitch_with_accidental = False)
    {
        return False;
    }

    if (has_prev_pitch_with_accidental = False and noteobj.Accidental != 0)
    {
        return True;
    }

    if (has_prev_pitch_with_accidental = True and accid = '')
    {
        // this is the corresponding return value for special cased naturals.
        return True;
    }

    // Finally, by default, assume this has no accidental.
    return False;
}  //$end

function ConvertNamedTimeSignature (timesig) {
    //$module(ExportConverters.mss)
    switch(timesig)
    {
        case(CommonTimeString)
        {
            return 'common';
        }
        case(AllaBreveTimeString)
        {
            return 'cut';
        }
        default
        {
            return ' ';
        }
    }
}  //$end

function ConvertBracket (bracket) {
    //$module(ExportConverters.mss)
    switch(bracket)
    {
        case(BracketFull)
        {
            return 'bracket';
        }
        case(BracketBrace)
        {
            return 'brace';
        }
        case(BracketSub)
        {
            return 'line';
        }
        default
        {
            return 'none';
        }
    }
}  //$end

function ConvertSibeliusStructure (score) {
    //$module(ExportConverters.mss)
    // Takes in the Staff/Bar Sibelius Structure and returns a Bar/Staff
    // mapping for our MEI writers.
    bar_to_staff = CreateDictionary();

    // Invert the Sibelius structure
    for each Staff s in score
    {
        for each Bar b in s
        {
            if (bar_to_staff.PropertyExists(b.BarNumber))
            {
                bar_to_staff[b.BarNumber].Push(s.StaffNum);
            }
            else
            {
                bar_to_staff[b.BarNumber] = CreateSparseArray();
                bar_to_staff[b.BarNumber].Push(s.StaffNum);
            }
        }
    }
    return bar_to_staff;
}  //$end

function ConvertColor (nrest) {
    //$module(ExportConverters.mss)
    r = nrest.ColorRed;
    g = nrest.ColorGreen;
    b = nrest.ColorBlue;
    a_dec = nrest.ColorAlpha & '.0';
    a = a_dec / 255.0;

    return 'rgba(' & r & ',' & g & ',' & b & ',' & a & ')';
}  //$end

function ConvertNoteStyle (style) {
    //$module(ExportConverters.mss)
    noteStyle = ' ';

    if (style = NormalNoteStyle)
    {
        return ' ';
    }

    switch (style)
    {
        case (CrossNoteStyle)
        {
            noteStyle = 'cross';
        }
        case (DiamondNoteStyle)
        {
            noteStyle = 'diamond';
        }
        case (CrossOrDiamondNoteStyle)
        {
            // Sibelius uses this for percussion
            // and does not differentiate in the
            // head style, so we have to choose one
            // or the other.
            noteStyle = 'cross';
        }
        case (BlackAndWhiteDiamondNoteStyle)
        {
            noteStyle = 'filldiamond';
        }
        case (SlashedNoteStyle)
        {
            noteStyle = 'addslash';
        }
        case (BackSlashedNoteStyle)
        {
            noteStyle = 'addbackslash';
        }
        case (ArrowDownNoteStyle)
        {
            // this is not completely correct, since
            // we use the same value for up and down
            // iso triangles. But it's all we have for now.
            noteStyle = 'isotriangle';
        }
        case (ArrowUpNoteStyle)
        {
            noteStyle = 'isotriangle';
        }
        case (InvertedTriangleNoteStyle)
        {
            noteStyle = 'isotriangle';
        }
        case (ShapedNote1NoteStyle)
        {
            noteStyle = 'isotriangle';
        }
        case (ShapedNote2NoteStyle)
        {
            noteStyle = 'semicircle';
        }
        case (ShapedNote3NoteStyle)
        {
            noteStyle = 'diamond';
        }
        case (ShapedNote4StemUpNoteStyle)
        {
            noteStyle = 'rtriangle';
        }
        case (ShapedNote4StemDownNoteStyle)
        {
            noteStyle = 'rtriangle';
        }
        case (ShapedNote5NoteStyle)
        {
            // this looks normal...
            noteStyle = ' ';
        }
        case (ShapedNote6NoteStyle)
        {
            // there is no square in MEI...
            noteStyle = ' ';
        }
        case (ShapedNote7NoteStyle)
        {
            noteStyle = 'piewedge';
        }
    }

    return noteStyle;
}  //$end

function ConvertSlurStyle (style) {
    //$module(ExportConverters.mss)
    slurparts = MSplitString(style, '.');
    direction = ' ';
    style = ' ';

    switch(slurparts[3])
    {
        case ('up')
        {
            direction = 'above';
        }
        case ('down')
        {
            direction = 'below';
        }
        default
        {
            direction = ' ';
        }
    }
    switch(slurparts[4])
    {
        case ('dashed')
        {
            style = 'dashed';
        }
        case ('dotted')
        {
            style = 'dotted';
        }
        default
        {
            style = ' ';
        }
    }
    return CreateSparseArray(direction, style);
}  //$end

function ConvertPositionToTimestamp (position, bar) {
    //$module(ExportConverters.mss)
    /*
        To convert Sibelius ticks to musical timestamps
        we use the formula:

        tstamp = (notePosition / (barLength / beatsInBar))
    */

    // make sure we're working with floating point numbers
    // and yes, this makes me feel very, very dirty in case
    // you were wondering, but this is the only way ManuScript
    // can cast to floating point...
    barlength = bar.Length;
    timesignature = Sibelius.ActiveScore.SystemStaff.CurrentTimeSignature(bar.BarNumber);

    if (position = 0)
    {
        return 1;
    }

    barlen = barlength & '.0';
    pos = position & '.0';
    beats = timesignature.Numerator & '.0';
    unit = (barlen / beats);
    ret = (pos / unit) + 1;

    return ret;
}  //$end

function ConvertTupletStyle (tupletStyle) {
    //$module(ExportConverters.mss)
    switch (tupletStyle)
    {
        case(TupletNoNumber)
        {
            libmei.addAttribute(activeTuplet, 'dur.visible', 'false');
        }
        case(TupletLeft)
        {
            libmei.addAttribute(activeTuplet, 'num.format', 'count');
        }
        case(TupletLeftRight)
        {
            libmei.addAttribute(activeTuplet, 'num.format', 'ratio');
        }
    }

}  //$end

function ConvertBarline (linetype) {
    //$module(ExportConverters.mss)
    switch(linetype)
    {
        case (SpecialBarlineStartRepeat)
        {
            // start repeat
            return 'rptstart';
        }
        case (SpecialBarlineEndRepeat)
        {
            // end repeat
            return 'rptend';
        }
        case (SpecialBarlineDashed)
        {
            // dashed
            return 'dashed';
        }
        case (SpecialBarlineDouble)
        {
            // double
            return 'dbl';
        }
        case (SpecialBarlineFinal)
        {
            // final
            return 'end';
        }
        case (SpecialBarlineInvisible)
        {
            // invisible
            return 'invis';
        }
        case (SpecialBarlineBetweenStaves)
        {
            // between staves
            // no MEI equiv.
            return ' ';
        }
        case (SpecialBarlineNormal)
        {
            // normal
            // this should usually be needed.
            return 'single';
        }
        case (SpecialBarlineTick)
        {
            // tick
            // unknown
            return ' ';
        }
        case (SpecialBarlineShort)
        {
            // short
            // unknown
            return ' ';
        }
        default
        {
            return ' ';
        }
    }
}  //$end

function ConvertText (textobj) {
    //$module(ExportConverters.mss)
    styleid = textobj.StyleId;
    switch (styleid)
    {
        case ('text.staff.expression')
        {
            dynam = libmei.Dynam();
            libmei.SetText(dynam, lstrip(textobj.Text));
            libmei.AddAttribute(dynam, 'staff', textobj.ParentBar.ParentStaff.StaffNum);
            libmei.AddAttribute(dynam, 'tstamp', ConvertPositionToTimestamp(textobj));

            if (textobj.Dx != 0)
            {
                libmei.AddAttribute(dynam, 'ho', ConvertOffsetsToMillimeters(textobj.Dx));
            }

            if (textobj.Dy != 0)
            {
                libmei.AddAttribute(dynam, 'vo', ConvertOffsetsToMillimeters(textobj.Dy));
            }
            return dynam;
        }
        case ('text.system.page_aligned.title')
        {
            return ConvertTextElement(textobj);
        }
        case ('text.system.page_aligned.composer')
        {
            return ConvertTextElement(textobj);
        }
        default
        {
            return null;
        }
    }
}  //$end

function ConvertTextElement (textobj) {
    //$module(ExportConverters.mss)
    obj = libmei.AnchoredText();
    libmei.SetText(obj, lstrip(textobj.Text));

    if (textobj.Dx != 0)
    {
        libmei.AddAttribute(obj, 'ho', ConvertOffsetsToMillimeters(textobj.Dx));
    }

    if (textobj.Dy != 0)
    {
        libmei.AddAttribute(obj, 'vo', ConvertOffsetsToMillimeters(textobj.Dy));
    }

    return obj;
}  //$end

function ConvertEndingValues (styleid) {
    //$module(ExportConverters)
    ending_style = MSplitString(styleid, '.');
    num = ' ';
    label = ' ';
    type = ' ';

    switch(ending_style[3])
    {
        case ('1st')
        {
            num = 1;
            label = '1.';
            type = 'closed';
        }
        case ('1st_n_2nd')
        {
            num = 1;
            label = '1. 2.';
            type = 'closed';
        }
        case ('2nd')
        {
            num = 2;
            label = '2.';
            if (ending_style[-1] = 'closed')
            {
                type = 'closed';
            }
            else
            {
                type = 'open';
            }
        }
        case ('3rd')
        {
            num = 3;
            label = '3.';
            type = 'closed';
        }
        case ('open')
        {
            type = 'open';
        }
        case ('closed')
        {
            type = 'closed';
        }
    }

    return CreateSparseArray(num, label, type);

}  //$end

function ConvertDate (datetime) {
    //$module(ExportConverters.mss)
    d = datetime.DayOfMonth;
    m = datetime.Month;
    y = datetime.Year;

    time = datetime.TimeWithSeconds;

    isodate = utils.Format('%s-%s-%sT%sZ', y, m, d, time);

    return isodate;
}  //$end