geojs 1.8.8 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/geo.lean.js CHANGED
@@ -138,6 +138,12 @@ var editHandleFeatureLevel = 3;
138
138
  * @property {boolean|string[]} [showLabel=true] `true` to show the annotation
139
139
  * label on annotations in done or edit states. Alternately, a list of
140
140
  * states in which to show the label. Falsy to not show the label.
141
+ * @property {boolean} [allowBooleanOperations] This defaults to `true` for
142
+ * annotations that have area and `false` for those without area (e.g.,
143
+ * false for lines and points). If it is truthy, then, when the annotation
144
+ * is being created, it checks the metakeys on the first click that defines
145
+ * a coordinate to determine what boolean polygon operation should be
146
+ * performaned on the completion of the annotation.
141
147
  */
142
148
 
143
149
  /**
@@ -160,9 +166,7 @@ var annotation = function annotation(type, args) {
160
166
  }
161
167
 
162
168
  var m_this = this,
163
- m_options = $.extend({}, {
164
- showLabel: true
165
- }, args || {}),
169
+ m_options = $.extend(true, {}, this.constructor.defaults, args || {}),
166
170
  m_id = m_options.annotationId;
167
171
  delete m_options.annotationId;
168
172
 
@@ -968,11 +972,16 @@ var annotation = function annotation(type, args) {
968
972
  value = util.ensureFunction(objStyle[key])();
969
973
 
970
974
  if (value !== undefined) {
975
+ var defvalue = ((m_this.constructor.defaults || {}).style || {})[key];
976
+
971
977
  if (key.toLowerCase().match(/color$/)) {
972
978
  value = util.convertColorToHex(value, 'needed');
979
+ defvalue = defvalue !== undefined ? util.convertColorToHex(defvalue, 'needed') : defvalue;
973
980
  }
974
981
 
975
- obj.properties[key] = value;
982
+ if (value !== defvalue) {
983
+ obj.properties[key] = value;
984
+ }
976
985
  }
977
986
  }
978
987
 
@@ -1699,7 +1708,14 @@ function constrainAspectRatio(ratio) {
1699
1708
 
1700
1709
  return constraintFunction;
1701
1710
  }
1711
+ /**
1712
+ * This object contains the default options to initialize the class.
1713
+ */
1702
1714
 
1715
+
1716
+ annotation.defaults = {
1717
+ showLabel: true
1718
+ };
1703
1719
  module.exports = {
1704
1720
  state: annotationState,
1705
1721
  actionOwner: annotationActionOwner,
@@ -1744,18 +1760,22 @@ var ellipseAnnotation = __webpack_require__(7505);
1744
1760
  var circleAnnotation = function circleAnnotation(args, annotationName) {
1745
1761
  'use strict';
1746
1762
 
1747
- args = $.extend({}, args, {
1748
- constraint: 1
1749
- });
1750
-
1751
1763
  if (!(this instanceof circleAnnotation)) {
1752
1764
  return new circleAnnotation(args, annotationName);
1753
1765
  }
1754
1766
 
1767
+ args = $.extend(true, {}, this.constructor.defaults, args, {
1768
+ constraint: 1
1769
+ });
1755
1770
  ellipseAnnotation.call(this, args, annotationName || 'circle');
1756
1771
  };
1757
1772
 
1758
1773
  inherit(circleAnnotation, ellipseAnnotation);
1774
+ /**
1775
+ * This object contains the default options to initialize the class.
1776
+ */
1777
+
1778
+ circleAnnotation.defaults = $.extend({}, ellipseAnnotation.defaults, {});
1759
1779
  var circleRequiredFeatures = {};
1760
1780
  circleRequiredFeatures[markerFeature.capabilities.feature] = true;
1761
1781
  registerAnnotation('circle', circleAnnotation, circleRequiredFeatures);
@@ -1798,6 +1818,7 @@ var ellipseAnnotation = function ellipseAnnotation(args, annotationName) {
1798
1818
  return new ellipseAnnotation(args, annotationName);
1799
1819
  }
1800
1820
 
1821
+ args = $.extend(true, {}, this.constructor.defaults, args);
1801
1822
  rectangleAnnotation.call(this, args, annotationName || 'ellipse');
1802
1823
  var m_this = this;
1803
1824
  /**
@@ -1844,9 +1865,68 @@ var ellipseAnnotation = function ellipseAnnotation(args, annotationName) {
1844
1865
 
1845
1866
  return features;
1846
1867
  };
1868
+ /**
1869
+ * Return this annotation as a polygon list.
1870
+ *
1871
+ * @param {geo.util.polyop.spec} [opts] The ``tolerance`` and
1872
+ * ``pixelTolerance`` parameters are used if set. Otherwise, a polygon is
1873
+ * approximated to 1/10th of a pixel at the map's current maximum zoom
1874
+ * level.
1875
+ * @returns {geo.polygonList} A list of polygons.
1876
+ */
1877
+
1878
+
1879
+ this.toPolygonList = function (opts) {
1880
+ var coord = m_this._coordinates();
1881
+
1882
+ if (coord.length < 3) {
1883
+ return [];
1884
+ }
1885
+
1886
+ var tolerance = opts && opts.tolerance || 0;
1887
+
1888
+ if (!tolerance) {
1889
+ var map = m_this.layer().map();
1890
+
1891
+ if (opts && opts.pixelTolerance) {
1892
+ tolerance = map.unitsPerPixel(map.zoom()) * opts.pixelTolerance;
1893
+ } else {
1894
+ tolerance = map.unitsPerPixel(map.zoomRange().max) * 0.1;
1895
+ }
1896
+ }
1897
+
1898
+ var w = Math.pow(Math.pow(coord[0].x - coord[1].x, 2) + Math.pow(coord[0].y - coord[1].y, 2), 0.5);
1899
+ var h = Math.pow(Math.pow(coord[0].x - coord[3].x, 2) + Math.pow(coord[0].y - coord[3].y, 2), 0.5);
1900
+ var cx = (coord[0].x + coord[2].x) / 2;
1901
+ var cy = (coord[0].y + coord[2].y) / 2;
1902
+ var radius = Math.max(w, h) / 2;
1903
+ var rotation = -Math.atan2(coord[1].y - coord[0].y, coord[1].x - coord[0].x);
1904
+ var sides = Math.max(12, Math.ceil(Math.PI / Math.acos((radius - tolerance) / (radius + tolerance))));
1905
+ var a = w / 2 * (1 + (1 - Math.cos(Math.PI / sides)) / 2);
1906
+ var b = h / 2 * (1 + (1 - Math.cos(Math.PI / sides)) / 2);
1907
+ var poly = [];
1908
+ var cosr = Math.cos(rotation),
1909
+ sinr = Math.sin(rotation);
1910
+
1911
+ for (var s = 0; s < sides; s += 1) {
1912
+ var sa = Math.PI * 2 * s / sides;
1913
+ var cosa = Math.cos(sa),
1914
+ sina = Math.sin(sa);
1915
+ var x = cx + a * cosr * cosa - b * sinr * sina;
1916
+ var y = cy + a * sinr * cosa + b * cosr * sina;
1917
+ poly.push([x, y]);
1918
+ }
1919
+
1920
+ return [[poly]];
1921
+ };
1847
1922
  };
1848
1923
 
1849
1924
  inherit(ellipseAnnotation, rectangleAnnotation);
1925
+ /**
1926
+ * This object contains the default options to initialize the class.
1927
+ */
1928
+
1929
+ ellipseAnnotation.defaults = $.extend({}, rectangleAnnotation.defaults, {});
1850
1930
  var ellipseRequiredFeatures = {};
1851
1931
  ellipseRequiredFeatures[markerFeature.capabilities.feature] = true;
1852
1932
  registerAnnotation('ellipse', ellipseAnnotation, ellipseRequiredFeatures);
@@ -1933,7 +2013,7 @@ var lineAnnotation = function lineAnnotation(args) {
1933
2013
  return new lineAnnotation(args);
1934
2014
  }
1935
2015
 
1936
- args = $.extend(true, {}, {
2016
+ args = $.extend(true, {}, this.constructor.defaults, {
1937
2017
  style: {
1938
2018
  line: function line(d) {
1939
2019
  /* Return an array that has the same number of items as we have
@@ -1944,20 +2024,7 @@ var lineAnnotation = function lineAnnotation(args) {
1944
2024
  },
1945
2025
  position: function position(d, i) {
1946
2026
  return m_this.options('vertices')[i];
1947
- },
1948
- strokeColor: {
1949
- r: 0,
1950
- g: 0,
1951
- b: 0
1952
- },
1953
- strokeOpacity: 1,
1954
- strokeWidth: 3,
1955
- closed: false,
1956
- lineCap: 'butt',
1957
- lineJoin: 'miter'
1958
- },
1959
- highlightStyle: {
1960
- strokeWidth: 5
2027
+ }
1961
2028
  },
1962
2029
  createStyle: {
1963
2030
  line: function line(d) {
@@ -1969,19 +2036,9 @@ var lineAnnotation = function lineAnnotation(args) {
1969
2036
  },
1970
2037
  position: function position(d, i) {
1971
2038
  return m_this.options('vertices')[i];
1972
- },
1973
- strokeColor: {
1974
- r: 0,
1975
- g: 0,
1976
- b: 1
1977
- },
1978
- strokeOpacity: 1,
1979
- strokeWidth: 3,
1980
- closed: false,
1981
- lineCap: 'butt',
1982
- lineJoin: 'miter'
2039
+ }
1983
2040
  }
1984
- }, args || {});
2041
+ }, args);
1985
2042
  args.vertices = args.vertices || args.coordinates || [];
1986
2043
  delete args.coordinates;
1987
2044
  annotation.call(this, 'line', args);
@@ -2277,6 +2334,39 @@ var lineAnnotation = function lineAnnotation(args) {
2277
2334
  };
2278
2335
 
2279
2336
  inherit(lineAnnotation, annotation);
2337
+ /**
2338
+ * This object contains the default options to initialize the class.
2339
+ */
2340
+
2341
+ lineAnnotation.defaults = $.extend({}, annotation.defaults, {
2342
+ style: {
2343
+ strokeColor: {
2344
+ r: 0,
2345
+ g: 0,
2346
+ b: 0
2347
+ },
2348
+ strokeOpacity: 1,
2349
+ strokeWidth: 3,
2350
+ closed: false,
2351
+ lineCap: 'butt',
2352
+ lineJoin: 'miter'
2353
+ },
2354
+ highlightStyle: {
2355
+ strokeWidth: 5
2356
+ },
2357
+ createStyle: {
2358
+ strokeColor: {
2359
+ r: 0,
2360
+ g: 0,
2361
+ b: 1
2362
+ },
2363
+ strokeOpacity: 1,
2364
+ strokeWidth: 3,
2365
+ closed: false,
2366
+ lineCap: 'butt',
2367
+ lineJoin: 'miter'
2368
+ }
2369
+ });
2280
2370
  var lineRequiredFeatures = {};
2281
2371
  lineRequiredFeatures[lineFeature.capabilities.basic] = [annotationState.create];
2282
2372
  registerAnnotation('line', lineAnnotation, lineRequiredFeatures);
@@ -2336,49 +2426,7 @@ var pointAnnotation = function pointAnnotation(args) {
2336
2426
  return new pointAnnotation(args);
2337
2427
  }
2338
2428
 
2339
- args = $.extend(true, {}, {
2340
- style: {
2341
- fill: true,
2342
- fillColor: {
2343
- r: 0,
2344
- g: 1,
2345
- b: 0
2346
- },
2347
- fillOpacity: 0.25,
2348
- radius: 10,
2349
- scaled: false,
2350
- stroke: true,
2351
- strokeColor: {
2352
- r: 0,
2353
- g: 0,
2354
- b: 0
2355
- },
2356
- strokeOpacity: 1,
2357
- strokeWidth: 3
2358
- },
2359
- createStyle: {
2360
- fillColor: {
2361
- r: 0.3,
2362
- g: 0.3,
2363
- b: 0.3
2364
- },
2365
- fillOpacity: 0.25,
2366
- strokeColor: {
2367
- r: 0,
2368
- g: 0,
2369
- b: 1
2370
- }
2371
- },
2372
- highlightStyle: {
2373
- fillColor: {
2374
- r: 0,
2375
- g: 1,
2376
- b: 1
2377
- },
2378
- fillOpacity: 0.5,
2379
- strokeWidth: 5
2380
- }
2381
- }, args || {});
2429
+ args = $.extend(true, {}, this.constructor.defaults, args);
2382
2430
  args.position = args.position || (args.coordinates ? args.coordinates[0] : undefined);
2383
2431
  delete args.coordinates;
2384
2432
  annotation.call(this, 'point', args);
@@ -2539,6 +2587,53 @@ var pointAnnotation = function pointAnnotation(args) {
2539
2587
  };
2540
2588
 
2541
2589
  inherit(pointAnnotation, annotation);
2590
+ /**
2591
+ * This object contains the default options to initialize the class.
2592
+ */
2593
+
2594
+ pointAnnotation.defaults = $.extend({}, annotation.defaults, {
2595
+ style: {
2596
+ fill: true,
2597
+ fillColor: {
2598
+ r: 0,
2599
+ g: 1,
2600
+ b: 0
2601
+ },
2602
+ fillOpacity: 0.25,
2603
+ radius: 10,
2604
+ scaled: false,
2605
+ stroke: true,
2606
+ strokeColor: {
2607
+ r: 0,
2608
+ g: 0,
2609
+ b: 0
2610
+ },
2611
+ strokeOpacity: 1,
2612
+ strokeWidth: 3
2613
+ },
2614
+ createStyle: {
2615
+ fillColor: {
2616
+ r: 0.3,
2617
+ g: 0.3,
2618
+ b: 0.3
2619
+ },
2620
+ fillOpacity: 0.25,
2621
+ strokeColor: {
2622
+ r: 0,
2623
+ g: 0,
2624
+ b: 1
2625
+ }
2626
+ },
2627
+ highlightStyle: {
2628
+ fillColor: {
2629
+ r: 0,
2630
+ g: 1,
2631
+ b: 1
2632
+ },
2633
+ fillOpacity: 0.5,
2634
+ strokeWidth: 5
2635
+ }
2636
+ });
2542
2637
  var pointRequiredFeatures = {};
2543
2638
  pointRequiredFeatures[pointFeature.capabilities.feature] = true;
2544
2639
  registerAnnotation('point', pointAnnotation, pointRequiredFeatures);
@@ -2603,45 +2698,13 @@ var polygonAnnotation = function polygonAnnotation(args) {
2603
2698
  return new polygonAnnotation(args);
2604
2699
  }
2605
2700
 
2606
- args = $.extend(true, {}, {
2701
+ args = $.extend(true, {}, this.constructor.defaults, {
2607
2702
  style: {
2608
- fill: true,
2609
- fillColor: {
2610
- r: 0,
2611
- g: 1,
2612
- b: 0
2613
- },
2614
- fillOpacity: 0.25,
2615
2703
  polygon: function polygon(d) {
2616
2704
  return d.polygon;
2617
- },
2618
- stroke: true,
2619
- strokeColor: {
2620
- r: 0,
2621
- g: 0,
2622
- b: 0
2623
- },
2624
- strokeOpacity: 1,
2625
- strokeWidth: 3,
2626
- uniformPolygon: true
2627
- },
2628
- highlightStyle: {
2629
- fillColor: {
2630
- r: 0,
2631
- g: 1,
2632
- b: 1
2633
- },
2634
- fillOpacity: 0.5,
2635
- strokeWidth: 5
2705
+ }
2636
2706
  },
2637
2707
  createStyle: {
2638
- closed: false,
2639
- fillColor: {
2640
- r: 0.3,
2641
- g: 0.3,
2642
- b: 0.3
2643
- },
2644
- fillOpacity: 0.25,
2645
2708
  line: function line(d) {
2646
2709
  var coord = m_this._coordinates();
2647
2710
  /* Return an array that has the same number of items as we have
@@ -2658,15 +2721,9 @@ var polygonAnnotation = function polygonAnnotation(args) {
2658
2721
  }
2659
2722
 
2660
2723
  return m_this.options('vertices')[i];
2661
- },
2662
- stroke: false,
2663
- strokeColor: {
2664
- r: 0,
2665
- g: 0,
2666
- b: 1
2667
2724
  }
2668
2725
  }
2669
- }, args || {});
2726
+ }, args);
2670
2727
  args.vertices = args.vertices || args.coordinates || [];
2671
2728
  delete args.coordinates;
2672
2729
  annotation.call(this, 'polygon', args);
@@ -2727,6 +2784,37 @@ var polygonAnnotation = function polygonAnnotation(args) {
2727
2784
 
2728
2785
  return features;
2729
2786
  };
2787
+ /**
2788
+ * Return this annotation as a polygon list.
2789
+ *
2790
+ * @param {geo.util.polyop.spec} [opts] Ignored.
2791
+ * @returns {geo.polygonList} A list of polygons.
2792
+ */
2793
+
2794
+
2795
+ this.toPolygonList = function (opts) {
2796
+ var coord = m_this._coordinates();
2797
+
2798
+ if (coord.outer) {
2799
+ var result = [[coord.outer.map(function (pt) {
2800
+ return [pt.x, pt.y];
2801
+ })]];
2802
+ (coord.inner || []).forEach(function (h) {
2803
+ return result[0].push(h.map(function (pt) {
2804
+ return [pt.x, pt.y];
2805
+ }));
2806
+ });
2807
+ return result;
2808
+ }
2809
+
2810
+ if (coord.length < 3) {
2811
+ return [];
2812
+ }
2813
+
2814
+ return [[coord.map(function (pt) {
2815
+ return [pt.x, pt.y];
2816
+ })]];
2817
+ };
2730
2818
  /**
2731
2819
  * Get and optionally set coordinates associated with this annotation in the
2732
2820
  * map gcs coordinate system.
@@ -2926,6 +3014,55 @@ var polygonAnnotation = function polygonAnnotation(args) {
2926
3014
  };
2927
3015
 
2928
3016
  inherit(polygonAnnotation, annotation);
3017
+ /**
3018
+ * This object contains the default options to initialize the class.
3019
+ */
3020
+
3021
+ polygonAnnotation.defaults = $.extend({}, annotation.defaults, {
3022
+ style: {
3023
+ fill: true,
3024
+ fillColor: {
3025
+ r: 0,
3026
+ g: 1,
3027
+ b: 0
3028
+ },
3029
+ fillOpacity: 0.25,
3030
+ stroke: true,
3031
+ strokeColor: {
3032
+ r: 0,
3033
+ g: 0,
3034
+ b: 0
3035
+ },
3036
+ strokeOpacity: 1,
3037
+ strokeWidth: 3,
3038
+ uniformPolygon: true
3039
+ },
3040
+ highlightStyle: {
3041
+ fillColor: {
3042
+ r: 0,
3043
+ g: 1,
3044
+ b: 1
3045
+ },
3046
+ fillOpacity: 0.5,
3047
+ strokeWidth: 5
3048
+ },
3049
+ createStyle: {
3050
+ closed: false,
3051
+ fillColor: {
3052
+ r: 0.3,
3053
+ g: 0.3,
3054
+ b: 0.3
3055
+ },
3056
+ fillOpacity: 0.25,
3057
+ stroke: false,
3058
+ strokeColor: {
3059
+ r: 0,
3060
+ g: 0,
3061
+ b: 1
3062
+ }
3063
+ },
3064
+ allowBooleanOperations: true
3065
+ });
2929
3066
  var polygonRequiredFeatures = {};
2930
3067
  polygonRequiredFeatures[polygonFeature.capabilities.feature] = true;
2931
3068
  polygonRequiredFeatures[lineFeature.capabilities.basic] = [annotationState.create];
@@ -2996,51 +3133,7 @@ var rectangleAnnotation = function rectangleAnnotation(args, annotationName) {
2996
3133
  return new rectangleAnnotation(args, annotationName);
2997
3134
  }
2998
3135
 
2999
- args = $.extend(true, {}, {
3000
- style: {
3001
- fill: true,
3002
- fillColor: {
3003
- r: 0,
3004
- g: 1,
3005
- b: 0
3006
- },
3007
- fillOpacity: 0.25,
3008
- polygon: function polygon(d) {
3009
- return d.polygon;
3010
- },
3011
- stroke: true,
3012
- strokeColor: {
3013
- r: 0,
3014
- g: 0,
3015
- b: 0
3016
- },
3017
- strokeOpacity: 1,
3018
- strokeWidth: 3,
3019
- uniformPolygon: true
3020
- },
3021
- highlightStyle: {
3022
- fillColor: {
3023
- r: 0,
3024
- g: 1,
3025
- b: 1
3026
- },
3027
- fillOpacity: 0.5,
3028
- strokeWidth: 5
3029
- },
3030
- createStyle: {
3031
- fillColor: {
3032
- r: 0.3,
3033
- g: 0.3,
3034
- b: 0.3
3035
- },
3036
- fillOpacity: 0.25,
3037
- strokeColor: {
3038
- r: 0,
3039
- g: 0,
3040
- b: 1
3041
- }
3042
- }
3043
- }, args || {});
3136
+ args = $.extend(true, {}, this.constructor.defaults, args);
3044
3137
  args.corners = args.corners || args.coordinates || [];
3045
3138
  delete args.coordinates;
3046
3139
  annotation.call(this, annotationName || 'rectangle', args);
@@ -3156,6 +3249,23 @@ var rectangleAnnotation = function rectangleAnnotation(args, annotationName) {
3156
3249
 
3157
3250
  return features;
3158
3251
  };
3252
+ /**
3253
+ * Return this annotation as a polygon list.
3254
+ *
3255
+ * @param {geo.util.polyop.spec} [opts] Ignored.
3256
+ * @returns {geo.polygonList} A list of polygons.
3257
+ */
3258
+
3259
+
3260
+ this.toPolygonList = function (opts) {
3261
+ if (m_this._coordinates().length < 3) {
3262
+ return [];
3263
+ }
3264
+
3265
+ return [[m_this._coordinates().map(function (pt) {
3266
+ return [pt.x, pt.y];
3267
+ })]];
3268
+ };
3159
3269
  /**
3160
3270
  * Get and optionally set coordinates associated with this annotation in the
3161
3271
  * map gcs coordinate system.
@@ -3431,6 +3541,56 @@ var rectangleAnnotation = function rectangleAnnotation(args, annotationName) {
3431
3541
  };
3432
3542
 
3433
3543
  inherit(rectangleAnnotation, annotation);
3544
+ /**
3545
+ * This object contains the default options to initialize the class.
3546
+ */
3547
+
3548
+ rectangleAnnotation.defaults = $.extend({}, annotation.defaults, {
3549
+ style: {
3550
+ fill: true,
3551
+ fillColor: {
3552
+ r: 0,
3553
+ g: 1,
3554
+ b: 0
3555
+ },
3556
+ fillOpacity: 0.25,
3557
+ polygon: function polygon(d) {
3558
+ return d.polygon;
3559
+ },
3560
+ stroke: true,
3561
+ strokeColor: {
3562
+ r: 0,
3563
+ g: 0,
3564
+ b: 0
3565
+ },
3566
+ strokeOpacity: 1,
3567
+ strokeWidth: 3,
3568
+ uniformPolygon: true
3569
+ },
3570
+ highlightStyle: {
3571
+ fillColor: {
3572
+ r: 0,
3573
+ g: 1,
3574
+ b: 1
3575
+ },
3576
+ fillOpacity: 0.5,
3577
+ strokeWidth: 5
3578
+ },
3579
+ createStyle: {
3580
+ fillColor: {
3581
+ r: 0.3,
3582
+ g: 0.3,
3583
+ b: 0.3
3584
+ },
3585
+ fillOpacity: 0.25,
3586
+ strokeColor: {
3587
+ r: 0,
3588
+ g: 0,
3589
+ b: 1
3590
+ }
3591
+ },
3592
+ allowBooleanOperations: true
3593
+ });
3434
3594
  var rectangleRequiredFeatures = {};
3435
3595
  rectangleRequiredFeatures[polygonFeature.capabilities.feature] = true;
3436
3596
  registerAnnotation('rectangle', rectangleAnnotation, rectangleRequiredFeatures);
@@ -3467,18 +3627,22 @@ var rectangleAnnotation = __webpack_require__(3442);
3467
3627
  var squareAnnotation = function squareAnnotation(args, annotationName) {
3468
3628
  'use strict';
3469
3629
 
3470
- args = $.extend({}, args, {
3471
- constraint: 1
3472
- });
3473
-
3474
3630
  if (!(this instanceof squareAnnotation)) {
3475
3631
  return new squareAnnotation(args, annotationName);
3476
3632
  }
3477
3633
 
3634
+ args = $.extend(true, {}, this.constructor.defaults, args, {
3635
+ constraint: 1
3636
+ });
3478
3637
  rectangleAnnotation.call(this, args, annotationName || 'square');
3479
3638
  };
3480
3639
 
3481
3640
  inherit(squareAnnotation, rectangleAnnotation);
3641
+ /**
3642
+ * This object contains the default options to initialize the class.
3643
+ */
3644
+
3645
+ squareAnnotation.defaults = $.extend({}, rectangleAnnotation.defaults, {});
3482
3646
  var squareRequiredFeatures = {};
3483
3647
  squareRequiredFeatures[polygonFeature.capabilities.feature] = true;
3484
3648
  registerAnnotation('square', squareAnnotation, squareRequiredFeatures);
@@ -3489,6 +3653,20 @@ module.exports = squareAnnotation;
3489
3653
  /***/ 836:
3490
3654
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
3491
3655
 
3656
+ function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
3657
+
3658
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
3659
+
3660
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
3661
+
3662
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
3663
+
3664
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
3665
+
3666
+ function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
3667
+
3668
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
3669
+
3492
3670
  var inherit = __webpack_require__(5699);
3493
3671
 
3494
3672
  var featureLayer = __webpack_require__(3715);
@@ -3722,6 +3900,56 @@ var annotationLayer = function annotationLayer(arg) {
3722
3900
 
3723
3901
  m_this._updateFromEvent(update);
3724
3902
  };
3903
+ /**
3904
+ * Check if there is a current boolean operation.
3905
+ *
3906
+ * @returns {string?} Either undefined for no current boolean operation or
3907
+ * the name of the operation.
3908
+ */
3909
+
3910
+
3911
+ this.currentBooleanOperation = function () {
3912
+ var op;
3913
+
3914
+ if (m_this._currentBooleanClass) {
3915
+ op = m_this._currentBooleanClass.split('-')[1];
3916
+ }
3917
+
3918
+ return op;
3919
+ };
3920
+ /**
3921
+ * Check if the map is currently in a mode where we are adding an annotation
3922
+ * with a boolean operation. If so, remove the current annotation from the
3923
+ * layer, then apply it via the boolean operation.
3924
+ */
3925
+
3926
+
3927
+ this._handleBooleanOperation = function () {
3928
+ var op = m_this.currentBooleanOperation();
3929
+
3930
+ if (!op || !m_this.currentAnnotation || !m_this.currentAnnotation.toPolygonList) {
3931
+ return;
3932
+ }
3933
+
3934
+ var newAnnot = m_this.currentAnnotation;
3935
+ m_this.removeAnnotation(m_this.currentAnnotation, false);
3936
+
3937
+ if (m_this.annotations().length || op !== 'difference' && op !== 'intersect') {
3938
+ var evt = {
3939
+ annotation: newAnnot,
3940
+ operation: op
3941
+ };
3942
+ m_this.geoTrigger(geo_event.annotation.boolean, evt);
3943
+
3944
+ if (evt.cancel !== false) {
3945
+ util.polyops[op](m_this, newAnnot.toPolygonList(), {
3946
+ correspond: {},
3947
+ keepAnnotations: 'exact',
3948
+ style: m_this
3949
+ });
3950
+ }
3951
+ }
3952
+ };
3725
3953
  /**
3726
3954
  * Handle updating the current annotation based on an update state.
3727
3955
  *
@@ -3740,6 +3968,8 @@ var annotationLayer = function annotationLayer(arg) {
3740
3968
  break;
3741
3969
 
3742
3970
  case 'done':
3971
+ m_this._handleBooleanOperation();
3972
+
3743
3973
  m_this.mode(null);
3744
3974
  break;
3745
3975
  }
@@ -3749,6 +3979,30 @@ var annotationLayer = function annotationLayer(arg) {
3749
3979
  m_this.draw();
3750
3980
  }
3751
3981
  };
3982
+ /**
3983
+ * Check the state of the modifier keys and apply them if appropriate.
3984
+ *
3985
+ * @param {geo.event} evt The mouse move or click event.
3986
+ */
3987
+
3988
+
3989
+ this._handleMouseMoveModifiers = function (evt) {
3990
+ if (m_this.mode() !== m_this.modes.edit && m_this.currentAnnotation.options('allowBooleanOperations') && m_this.currentAnnotation._coordinates().length < 2) {
3991
+ if (evt.modifiers) {
3992
+ var mod = (evt.modifiers.shift ? 's' : '') + (evt.modifiers.ctrl ? 'c' : '') + (evt.modifiers.meta || evt.modifiers.alt ? 'a' : '');
3993
+
3994
+ if (m_this._currentBooleanClass === m_this._booleanClasses[mod]) {
3995
+ return;
3996
+ }
3997
+
3998
+ m_this._currentBooleanClass = m_this._booleanClasses[mod];
3999
+ var mapNode = m_this.map().node();
4000
+ Object.values(m_this._booleanClasses).forEach(function (c) {
4001
+ mapNode.toggleClass(c, m_this._booleanClasses[mod] === c);
4002
+ });
4003
+ }
4004
+ }
4005
+ };
3752
4006
  /**
3753
4007
  * Handle mouse movement. If there is a current annotation, the movement
3754
4008
  * event is sent to it.
@@ -3759,6 +4013,8 @@ var annotationLayer = function annotationLayer(arg) {
3759
4013
 
3760
4014
  this._handleMouseMove = function (evt) {
3761
4015
  if (m_this.mode() && m_this.currentAnnotation) {
4016
+ m_this._handleMouseMoveModifiers(evt);
4017
+
3762
4018
  var update = m_this.currentAnnotation.mouseMove(evt);
3763
4019
 
3764
4020
  if (update) {
@@ -3881,6 +4137,8 @@ var annotationLayer = function annotationLayer(arg) {
3881
4137
  });
3882
4138
  retrigger = true;
3883
4139
  } else if (m_this.mode() && m_this.currentAnnotation) {
4140
+ m_this._handleMouseMoveModifiers(evt);
4141
+
3884
4142
  update = m_this.currentAnnotation.mouseClick(evt);
3885
4143
 
3886
4144
  m_this._updateFromEvent(update);
@@ -4118,6 +4376,15 @@ var annotationLayer = function annotationLayer(arg) {
4118
4376
  this.modes = {
4119
4377
  edit: 'edit'
4120
4378
  };
4379
+ /* Keys are short-hand for preferred event modifiers. Values are classes to
4380
+ * apply to the map node. */
4381
+
4382
+ this._booleanClasses = {
4383
+ s: 'annotation-union',
4384
+ sc: 'annotation-intersect',
4385
+ c: 'annotation-difference',
4386
+ sa: 'annotation-xor'
4387
+ };
4121
4388
  /**
4122
4389
  * Get or set the current mode.
4123
4390
  *
@@ -4139,7 +4406,7 @@ var annotationLayer = function annotationLayer(arg) {
4139
4406
  return m_mode;
4140
4407
  }
4141
4408
 
4142
- if (arg !== m_mode || arg === m_this.modes.edit && editAnnotation !== m_this.editAnnotation) {
4409
+ if (arg !== m_mode || arg === m_this.modes.edit && editAnnotation !== m_this.editAnnotation || arg !== m_this.modes.edit && arg && !m_this.currentAnnotation) {
4143
4410
  var createAnnotation,
4144
4411
  actions,
4145
4412
  mapNode = m_this.map().node(),
@@ -4147,6 +4414,13 @@ var annotationLayer = function annotationLayer(arg) {
4147
4414
  m_mode = arg;
4148
4415
  mapNode.toggleClass('annotation-input', !!(m_mode && m_mode !== m_this.modes.edit));
4149
4416
 
4417
+ if (!m_mode || m_mode === m_this.modes.edit) {
4418
+ Object.values(m_this._booleanClasses).forEach(function (c) {
4419
+ return mapNode.toggleClass(c, false);
4420
+ });
4421
+ m_this._currentBooleanClass = undefined;
4422
+ }
4423
+
4150
4424
  if (!m_keyHandler) {
4151
4425
  m_keyHandler = Mousetrap(mapNode[0]);
4152
4426
  }
@@ -4238,7 +4512,10 @@ var annotationLayer = function annotationLayer(arg) {
4238
4512
  this.geojson = function (geojson, clear, gcs, includeCrs) {
4239
4513
  if (geojson !== undefined) {
4240
4514
  var reader = registry.createFileReader('geojsonReader', {
4241
- layer: m_this
4515
+ layer: m_this,
4516
+ lineStyle: (__webpack_require__(3984).defaults.style),
4517
+ pointStyle: (__webpack_require__(8296).defaults.style),
4518
+ polygonStyle: (__webpack_require__(56).defaults.style)
4242
4519
  });
4243
4520
 
4244
4521
  if (!reader.canRead(geojson)) {
@@ -4887,6 +5164,150 @@ var annotationLayer = function annotationLayer(arg) {
4887
5164
  s_draw.call(m_this);
4888
5165
  return m_this;
4889
5166
  };
5167
+ /**
5168
+ * Return any annotation that has area as a polygon list: an array of
5169
+ * polygons, each of which is an array of polylines, each of which is an
5170
+ * array of points, each of which is a 2-tuple of numbers.
5171
+ *
5172
+ * @param {geo.util.polyop.spec} [opts] Ignored.
5173
+ * @returns {geo.polygonList} A list of polygons.
5174
+ */
5175
+
5176
+
5177
+ this.toPolygonList = function (opts) {
5178
+ var poly = [];
5179
+ opts = opts || {};
5180
+ opts.annotationIndices = [];
5181
+ m_annotations.forEach(function (annotation, idx) {
5182
+ if (annotation.toPolygonList) {
5183
+ annotation.toPolygonList(opts).forEach(function (p) {
5184
+ return poly.push(p);
5185
+ });
5186
+ opts.annotationIndices.push(idx);
5187
+ }
5188
+ });
5189
+ return poly;
5190
+ };
5191
+ /**
5192
+ * Replace appropriate annotations with a list of polygons.
5193
+ *
5194
+ * @param {geo.polygonList} poly A list of polygons.
5195
+ * @param {geo.util.polyop.spec} [opts] This contains annotationIndices and
5196
+ * correspondence used to track annotations.
5197
+ * @returns {this}
5198
+ */
5199
+
5200
+
5201
+ this.fromPolygonList = function (poly, opts) {
5202
+ if (!poly || !poly.length) {
5203
+ return m_this;
5204
+ }
5205
+ /* One of 'all', 'exact', 'none'; default is 'exact' */
5206
+
5207
+
5208
+ var keep = opts.keepAnnotations;
5209
+ var keepIds = {};
5210
+ var reusedIds = {};
5211
+ var correspond, exact, annot;
5212
+
5213
+ if (opts.annotationIndices && opts.correspond && opts.correspond.poly1 && opts.annotationIndices.length === opts.correspond.poly1.length) {
5214
+ correspond = opts.correspond.poly1;
5215
+ exact = opts.correspond.exact1;
5216
+ annot = m_this.annotations();
5217
+ }
5218
+
5219
+ if (keep !== 'all' && keep !== 'none') {
5220
+ annot.forEach(function (oldAnnot, idx) {
5221
+ if (opts.annotationIndices.indexOf(idx) < 0) {
5222
+ keepIds[oldAnnot.id()] = true;
5223
+ }
5224
+ });
5225
+ }
5226
+
5227
+ var polyAnnot = [];
5228
+ poly.forEach(function (p, idx) {
5229
+ p = p.map(function (h) {
5230
+ return h.map(function (pt) {
5231
+ return {
5232
+ x: pt[0],
5233
+ y: pt[1]
5234
+ };
5235
+ });
5236
+ });
5237
+ var result = {
5238
+ vertices: p.length === 1 ? p[0] : {
5239
+ outer: p[0],
5240
+ inner: p.slice(1)
5241
+ }
5242
+ };
5243
+
5244
+ if (correspond) {
5245
+ for (var i = 0; i < correspond.length; i += 1) {
5246
+ if (correspond[i] && correspond[i].indexOf(idx) >= 0) {
5247
+ var _ret = function () {
5248
+ var orig = annot[opts.annotationIndices[i]];
5249
+
5250
+ if (keep !== 'all' && keep !== 'none' && exact && exact[i] && exact[i].indexOf(idx) >= 0) {
5251
+ keepIds[orig.id()] = true;
5252
+ return {
5253
+ v: void 0
5254
+ };
5255
+ }
5256
+
5257
+ if (keep !== 'all' && reusedIds[orig.id()] === undefined) {
5258
+ result.annotationId = orig.id();
5259
+ reusedIds[orig.id()] = true;
5260
+ }
5261
+
5262
+ ['name', 'description', 'label'].forEach(function (k) {
5263
+ if (orig[k](undefined, true)) {
5264
+ result[k] = orig[k](undefined, true);
5265
+ }
5266
+ });
5267
+ Object.entries(orig.options()).forEach(function (_ref) {
5268
+ var _ref2 = _slicedToArray(_ref, 2),
5269
+ key = _ref2[0],
5270
+ value = _ref2[1];
5271
+
5272
+ if (['showLabel', 'style'].indexOf(key) >= 0 || key.endsWith('Style')) {
5273
+ result[key] = value;
5274
+ }
5275
+ });
5276
+ return "break";
5277
+ }();
5278
+
5279
+ if (_ret === "break") break;
5280
+ if (_typeof(_ret) === "object") return _ret.v;
5281
+ }
5282
+ }
5283
+ }
5284
+
5285
+ polyAnnot.push(result);
5286
+ });
5287
+ var update = false; // delete extant annotations
5288
+
5289
+ if (keep !== 'all' && annot) {
5290
+ annot.filter(function (oldAnnot) {
5291
+ return keepIds[oldAnnot.id()] === undefined;
5292
+ }).forEach(function (oldAnnot) {
5293
+ m_this.removeAnnotation(oldAnnot, false);
5294
+ update = true;
5295
+ });
5296
+ } // add new annotations
5297
+
5298
+
5299
+ polyAnnot.forEach(function (p) {
5300
+ m_this.addAnnotation(registry.createAnnotation('polygon', p), m_this.gcs(), false);
5301
+ update = true;
5302
+ });
5303
+
5304
+ if (update) {
5305
+ m_this.modified();
5306
+ m_this.draw();
5307
+ }
5308
+
5309
+ return m_this;
5310
+ };
4890
5311
  /**
4891
5312
  * Initialize.
4892
5313
  *
@@ -9418,6 +9839,20 @@ geo_event.annotation.state = 'geo_annotation_state';
9418
9839
  */
9419
9840
 
9420
9841
  geo_event.annotation.mode = 'geo_annotation_mode';
9842
+ /**
9843
+ * Triggered when an annotation can be combined via a boolean operation (union,
9844
+ * intersect, difference, xor).
9845
+ *
9846
+ * @event geo.event.annotation.boolean
9847
+ * @type {geo.event.base}
9848
+ * @property {geo.annotation} annotation The annotation that is being operated
9849
+ * on.
9850
+ * @property {string} operation The operation being performed.
9851
+ * @property {boolean} [cancel] If the handle sets this to false, don't apply
9852
+ * the operation to the annotation layer.
9853
+ */
9854
+
9855
+ geo_event.annotation.boolean = 'geo_annotation_boolean';
9421
9856
  module.exports = geo_event;
9422
9857
 
9423
9858
  /***/ }),
@@ -11490,6 +11925,7 @@ var geojsonReader = function geojsonReader(arg) {
11490
11925
  strokeOffset: 0,
11491
11926
  lineCap: 'butt',
11492
11927
  lineJoin: 'miter',
11928
+ uniformLine: true,
11493
11929
  closed: false
11494
11930
  }, arg.lineStyle),
11495
11931
  polygonStyle: _objectSpread({
@@ -11499,7 +11935,8 @@ var geojsonReader = function geojsonReader(arg) {
11499
11935
  stroke: true,
11500
11936
  strokeColor: '#999999',
11501
11937
  strokeWidth: 2,
11502
- strokeOpacity: 1
11938
+ strokeOpacity: 1,
11939
+ uniformPolygon: true
11503
11940
  }, arg.polygonStyle)
11504
11941
  });
11505
11942
 
@@ -15141,6 +15578,9 @@ var util = __webpack_require__(4634);
15141
15578
  * divided by the sine of half the angle between segments, then a bevel join
15142
15579
  * is used instead. This is a single value that applies to all lines. If a
15143
15580
  * function, it is called with `(data)`.
15581
+ * @property {boolean|function} [uniformLine=false] Boolean indicating if each
15582
+ * line has a uniform style (uniform stroke color, opacity, and width). Can
15583
+ * vary by line.
15144
15584
  * @property {number|function} [antialiasing] Antialiasing distance in pixels.
15145
15585
  * Values must be non-negative. A value greater than 1 will produce a
15146
15586
  * visible gradient. This is a single value that applies to all lines.
@@ -15258,24 +15698,38 @@ var lineFeature = function lineFeature(arg) {
15258
15698
  var data = m_this.data(),
15259
15699
  line = m_this.line(),
15260
15700
  widthFunc = m_this.style.get('strokeWidth'),
15701
+ widthVal = util.isFunction(m_this.style('strokeWidth')) ? undefined : widthFunc(),
15261
15702
  posFunc = m_this.position(),
15262
15703
  closedFunc = m_this.style.get('closed'),
15704
+ closedVal = util.isFunction(m_this.style('closed')) ? undefined : closedFunc(),
15705
+ uniformFunc = m_this.style.get('uniformLine'),
15706
+ uniformVal = util.isFunction(m_this.style('uniformLine')) ? undefined : uniformFunc(),
15263
15707
  gcs = m_this.gcs(),
15264
- mapgcs = m_this.layer().map().gcs();
15265
- data.forEach(function (d, index) {
15266
- var closed = closedFunc(d, index),
15267
- last,
15268
- lasti,
15269
- lastr,
15270
- lastr2,
15271
- first,
15272
- record = [],
15273
- min,
15274
- max;
15275
- line(d, index).forEach(function (current, j) {
15708
+ mapgcs = m_this.layer().map().gcs(),
15709
+ onlyInvertedY = transform.onlyInvertedY(gcs, mapgcs);
15710
+
15711
+ for (var index = 0; index < data.length; index += 1) {
15712
+ var d = data[index];
15713
+ var closed = closedVal === undefined ? closedFunc(d, index) : closedVal;
15714
+ var last = void 0,
15715
+ lasti = void 0,
15716
+ lastr = void 0,
15717
+ lastr2 = void 0,
15718
+ first = void 0,
15719
+ min = void 0,
15720
+ max = void 0,
15721
+ width = void 0;
15722
+ var record = [];
15723
+ var uniform = uniformVal === undefined ? uniformFunc(d, index) : uniformVal;
15724
+ var lineRecord = line(d, index);
15725
+
15726
+ for (var j = 0; j < lineRecord.length; j += 1) {
15727
+ var current = lineRecord[j];
15276
15728
  var p = posFunc(current, j, d, index);
15277
15729
 
15278
- if (gcs !== mapgcs) {
15730
+ if (onlyInvertedY) {
15731
+ p.y = -p.y;
15732
+ } else if (gcs !== mapgcs) {
15279
15733
  p = transform.transformCoordinates(gcs, mapgcs, p);
15280
15734
  }
15281
15735
 
@@ -15309,7 +15763,11 @@ var lineFeature = function lineFeature(arg) {
15309
15763
  max.y = p.y;
15310
15764
  }
15311
15765
 
15312
- var r = Math.ceil(widthFunc(current, j, d, index) / 2) + 2;
15766
+ if (!uniform || !j) {
15767
+ width = widthVal === undefined ? widthFunc(current, j, d, index) : widthVal;
15768
+ }
15769
+
15770
+ var r = Math.ceil(width / 2) + 2;
15313
15771
 
15314
15772
  if (max.r === undefined || r > max.r) {
15315
15773
  max.r = r;
@@ -15341,7 +15799,7 @@ var lineFeature = function lineFeature(arg) {
15341
15799
  i: j
15342
15800
  };
15343
15801
  }
15344
- });
15802
+ }
15345
15803
 
15346
15804
  if (closed && first && (last.x !== first.p.x || last.y !== first.p.y)) {
15347
15805
  record.push({
@@ -15357,7 +15815,8 @@ var lineFeature = function lineFeature(arg) {
15357
15815
  record.min = min;
15358
15816
  record.max = max;
15359
15817
  m_pointSearchInfo.push(record);
15360
- });
15818
+ }
15819
+
15361
15820
  return m_pointSearchInfo;
15362
15821
  };
15363
15822
  /**
@@ -24850,7 +25309,8 @@ var polygonFeature = function polygonFeature(arg) {
24850
25309
  strokeStyle: linePolyStyle(polyStyle.strokeStyle),
24851
25310
  strokeColor: linePolyStyle(polyStyle.strokeColor),
24852
25311
  strokeOffset: linePolyStyle(polyStyle.strokeOffset),
24853
- strokeOpacity: strokeOpacity
25312
+ strokeOpacity: strokeOpacity,
25313
+ uniformLine: linePolyStyle(polyStyle.uniformPolygon)
24854
25314
  });
24855
25315
  var data = m_this.data(),
24856
25316
  posVal = m_this.style('position');
@@ -25065,6 +25525,72 @@ var polygonFeature = function polygonFeature(arg) {
25065
25525
  evt.over.found[idx] = data[di];
25066
25526
  });
25067
25527
  };
25528
+ /**
25529
+ * Return the polygons as a polygon list: an array of polygons, each of which
25530
+ * is an array of polylines, each of which is an array of points, each of
25531
+ * which is a 2-tuple of numbers.
25532
+ *
25533
+ * @param {geo.util.polyop.spec} [opts] Ignored.
25534
+ * @returns {geo.polygonList} A list of polygons.
25535
+ */
25536
+
25537
+
25538
+ this.toPolygonList = function (opts) {
25539
+ var polyFunc = m_this.style.get('polygon');
25540
+ var posFunc = m_this.style.get('position');
25541
+ return m_this.data().map(function (d, i) {
25542
+ var polygon = polyFunc(d, i);
25543
+ var outer = polygon.outer || (Array.isArray(polygon) ? polygon : []);
25544
+
25545
+ if (outer.length < 3) {
25546
+ return [];
25547
+ }
25548
+
25549
+ var resp = [outer.map(function (p, j) {
25550
+ var pos = posFunc(p, j, d, i);
25551
+ return [pos.x, pos.y];
25552
+ })];
25553
+
25554
+ if (polygon.inner) {
25555
+ polygon.inner.forEach(function (h) {
25556
+ resp.push(h.map(function (p, j) {
25557
+ var pos = posFunc(p, j, d, i);
25558
+ return [pos.x, pos.y];
25559
+ }));
25560
+ });
25561
+ }
25562
+
25563
+ return resp;
25564
+ });
25565
+ };
25566
+ /**
25567
+ * Set the data, position accessor, and polygon accessor to use a list of
25568
+ * polygons.
25569
+ *
25570
+ * @param {geo.polygonList} poly A list of polygons.
25571
+ * @param {geo.util.polyop.spec} [opts] Ignored.
25572
+ * @returns {this}
25573
+ */
25574
+
25575
+
25576
+ this.fromPolygonList = function (poly, opts) {
25577
+ m_this.style({
25578
+ position: function position(p) {
25579
+ return {
25580
+ x: p[0],
25581
+ y: p[1]
25582
+ };
25583
+ },
25584
+ polygon: function polygon(p) {
25585
+ return {
25586
+ outer: p[0],
25587
+ inner: p.slice(1)
25588
+ };
25589
+ }
25590
+ });
25591
+ m_this.data(poly);
25592
+ return m_this;
25593
+ };
25068
25594
  /**
25069
25595
  * Destroy.
25070
25596
  */
@@ -27034,7 +27560,7 @@ module.exports = sceneObject;
27034
27560
  * @constant
27035
27561
  * @type {string}
27036
27562
  */
27037
- module.exports = "e4988e06092d4bee858b11f2d0109a6bfe77dfbb";
27563
+ module.exports = "ffc7f4252531033b8d82d126218e1d0553a90974";
27038
27564
 
27039
27565
  /***/ }),
27040
27566
 
@@ -33981,6 +34507,17 @@ module.exports = transform;
33981
34507
  * @property {number} [z=0] Altitude coordinate.
33982
34508
  */
33983
34509
 
34510
+ /**
34511
+ * General represention of a point on the earth. The coordinates are most
34512
+ * commonly in longitude and latitude, but the coordinate system is changed
34513
+ * by the interface gcs. This is a list of numbers consisting of either [x, y]
34514
+ * or [x, y, z], where therse are the horizontal, vertical, and altitude
34515
+ * coordinates.
34516
+ *
34517
+ * @typedef geo.geoPositionFlat
34518
+ * @type {number[]}
34519
+ */
34520
+
33984
34521
  /**
33985
34522
  * General represention of a two-dimensional point in any coordinate system.
33986
34523
  *
@@ -38803,7 +39340,8 @@ __webpack_require__(7566), __webpack_require__(9215), __webpack_require__(895),
38803
39340
  {
38804
39341
  DistanceGrid: __webpack_require__(5844),
38805
39342
  ClusterGroup: __webpack_require__(9808),
38806
- mesh: __webpack_require__(9244)
39343
+ mesh: __webpack_require__(9244),
39344
+ polyops: __webpack_require__(6771)
38807
39345
  });
38808
39346
 
38809
39347
  /***/ }),
@@ -39180,6 +39718,592 @@ module.exports.restoreWebglRenderer = function () {
39180
39718
 
39181
39719
  /***/ }),
39182
39720
 
39721
+ /***/ 6771:
39722
+ /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
39723
+
39724
+ function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
39725
+
39726
+ function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
39727
+
39728
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
39729
+
39730
+ function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
39731
+
39732
+ function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
39733
+
39734
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
39735
+
39736
+ var PolyBool = __webpack_require__(3291);
39737
+
39738
+ var geo_map = __webpack_require__(2804);
39739
+ /**
39740
+ * A list of flat polygon lists.
39741
+ *
39742
+ * @typedef {Array.<Array.<Array.<geo.geoPositionFlat>>>} geo.polygonList
39743
+ */
39744
+
39745
+ /**
39746
+ * A polygon in any of a variety of formats.
39747
+ *
39748
+ * This can be any object with a ``toPolygonList`` and ``fromPolygonList``
39749
+ * method.
39750
+ *
39751
+ * @typedef {geo.polygonFlat|Array.<geo.polygonFlat>|Array.<Array.<geo.polygonFlat>>|geo.polygonObject|Array.<geo.polygonObject>|Array.<geo.geoPositionFlat>|Array.<Array.<geo.geoPositionFlat>>|geo.polygonList|object} geo.polygonAny
39752
+ */
39753
+
39754
+ /**
39755
+ * Object specification for polygon operation options.
39756
+ *
39757
+ * @typedef {object} geo.util.polyop.spec
39758
+ * @property {geo.polygonAny} [poly1] The first polygon set to operate on.
39759
+ * @property {geo.polygonAny} [poly2] The second polygon set to operate on.
39760
+ * @property {number} [epsilon1] A precision value to use when computing the
39761
+ * operation. If not specified, this is computed from the range of values in
39762
+ * ``poly1``. It is used for processing ``poly1`` and the general operation.
39763
+ * @property {number} [epsilon1] A precision value to use when processing
39764
+ * ``poly2``. If not specified, this is computed from the range of values in
39765
+ * ``poly2``.
39766
+ * @property {string|object} [style] If specified, the preferred output style.
39767
+ * This can be (flat|object)[-list[list[-outer[-list]]]]. If an object,
39768
+ * the object must have a method ``fromPolygonList``.
39769
+ * @property {string|geo.transform} [ingcs] The default coordinate
39770
+ * system of the source polygon coordinates. If not specified , this is
39771
+ * taken from the feature first or the map second if either is available.
39772
+ * @property {string|geo.transform} [gcs] The default coordinate system to use
39773
+ * for the actual operations. This is where the epsilon and rdp values are
39774
+ * applied. If not specified , this is taken from the map second if
39775
+ * available.
39776
+ * @property {geo.map} [map] Used for ``ingcs`` and ``gcs`` if needed.
39777
+ * @property {string} [innerOperation="union"] one of union, intersect, xor.
39778
+ * Used to combine individual polygons in each of ``poly1`` and ``poly2``
39779
+ * before the main operation is carried out.
39780
+ * @property {object} [correspond] If present, information about the
39781
+ * correspondence of the input and output polygons is added to this object.
39782
+ * This is of the form {poly1: [idx...], poly2: [idx...], exact1: [idx...],
39783
+ * exact2: [idx...]}, where the [idx...] array is the length of the input
39784
+ * polygon array and each entry is either undefined or contains a list of
39785
+ * indices of corresponding output polygons. Exact means that all of the
39786
+ * points in the input polygon are in the output polygon. Multiple inputs
39787
+ * can refer to the same output.
39788
+ * @property {number} [tolerance] A tolerance value to pass to features,
39789
+ * annotations, or other object-based polygon generators to specify how
39790
+ * closely non-polygons are converted to polygons. This is in the feature's
39791
+ * gcs coordinate system.
39792
+ * @property {number} [pixelTolerance] A tolerance value to pass to features,
39793
+ * annotations, or other object-based polygon generators to specify how
39794
+ * closely non-polygons are converted to polygons. This is interpreted in
39795
+ * the feature's map's display coordinates.
39796
+ */
39797
+
39798
+
39799
+ var AlternateOpNames = {
39800
+ '+': 'union',
39801
+ '|': 'union',
39802
+ add: 'union',
39803
+ '-': 'difference',
39804
+ sub: 'difference',
39805
+ subtract: 'difference',
39806
+ minus: 'difference',
39807
+ '*': 'intersect',
39808
+ '&': 'intersect',
39809
+ mul: 'intersect',
39810
+ multiply: 'intersect',
39811
+ x: 'xor',
39812
+ '^': 'xor'
39813
+ };
39814
+ /**
39815
+ * Convert a segment list to a polygon list.
39816
+ *
39817
+ * @param {object[]} seglist A PolyBool segment list.
39818
+ * @returns {geo.polygonList} A polygon list.
39819
+ */
39820
+
39821
+ function seglistToPolygonList(seglist) {
39822
+ // This single line doesn't arrange holes correctly
39823
+ // return seglist.map((s) => PolyBool.polygon(s).regions);
39824
+ var polys = [];
39825
+ seglist.forEach(function (s) {
39826
+ var geojson = PolyBool.polygonToGeoJSON(PolyBool.polygon(s));
39827
+
39828
+ if (geojson.type === 'MultiPolygon') {
39829
+ geojson.coordinates.forEach(function (p) {
39830
+ polys.push(p.map(function (h) {
39831
+ return h.slice(0, h.length - 1);
39832
+ }));
39833
+ });
39834
+ } else if (geojson.type === 'Polygon') {
39835
+ polys.push(geojson.coordinates.map(function (h) {
39836
+ return h.slice(0, h.length - 1);
39837
+ }));
39838
+ }
39839
+ });
39840
+ return polys;
39841
+ }
39842
+ /**
39843
+ * Perform an boolean operation on a seglist from polygons.
39844
+ *
39845
+ * @param {string} op One of 'union', 'intersect', or other value PolyBool
39846
+ * supports.
39847
+ * @param {number} epsilon Precision for calculations. In degrees, 1e-9 is
39848
+ * around 0.11 mm in ground distance.
39849
+ * @param {object} seglist A seglist array as used by the polybool library.
39850
+ * @returns {object} A seglist array.
39851
+ */
39852
+
39853
+
39854
+ function polygonOperationSeglist(op, epsilon, seglist) {
39855
+ op = 'select' + op.charAt(0).toUpperCase() + op.slice(1);
39856
+ PolyBool.epsilon(epsilon);
39857
+
39858
+ while (seglist.length > 1) {
39859
+ var newlist = [];
39860
+ var half = Math.ceil(seglist.length / 2);
39861
+
39862
+ for (var i = 0; i < half; i += 1) {
39863
+ var segments = seglist[i];
39864
+
39865
+ if (i + half < seglist.length) {
39866
+ var nextseg = seglist[i + half];
39867
+
39868
+ try {
39869
+ segments = PolyBool.combine(segments, nextseg);
39870
+ } catch (err) {
39871
+ segments = PolyBool.segments(PolyBool.polygon(segments));
39872
+ nextseg = PolyBool.segments(PolyBool.polygon(nextseg));
39873
+
39874
+ for (var j = 20; j >= 6; j -= 1) {
39875
+ PolyBool.epsilon(Math.pow(0.1, j));
39876
+
39877
+ try {
39878
+ segments = PolyBool.combine(segments, nextseg);
39879
+ break;
39880
+ } catch (err) {}
39881
+ }
39882
+
39883
+ PolyBool.epsilon(epsilon);
39884
+ }
39885
+
39886
+ if (segments.combined) {
39887
+ segments.combined = segments.combined.filter(function (s) {
39888
+ return Math.abs(s.start[0] - s.end[0]) > epsilon || Math.abs(s.start[1] - s.end[1]) > epsilon;
39889
+ });
39890
+ segments = PolyBool[op](segments);
39891
+ } else {
39892
+ console.warn('Failed in polygon functions.');
39893
+ }
39894
+
39895
+ segments.segments = segments.segments.filter(function (s) {
39896
+ return Math.abs(s.start[0] - s.end[0]) > epsilon || Math.abs(s.start[1] - s.end[1]) > epsilon;
39897
+ });
39898
+ }
39899
+
39900
+ newlist.push(segments);
39901
+ }
39902
+
39903
+ seglist = newlist;
39904
+ }
39905
+
39906
+ return seglist;
39907
+ }
39908
+ /**
39909
+ * Convert a polygon in any of several formats to a polygon list. Each polygon
39910
+ * in the list is a list of polylines. Each polyline is a list of points.
39911
+ * Each point is a list of two coordinates. The input can be a variety of
39912
+ * formats:
39913
+ * - object, flat: a list of {x, y} or [x, y]
39914
+ * - object-list, flat-list: a list of lists of {x, y} or [x, y]
39915
+ * - object-listlist, flat-listlist: a list if lists of lists of {x, y} or
39916
+ * [x, y]
39917
+ * - object-listlist-outer, flat-listlist-outer: {outer: {x, y}, inner:
39918
+ * [{x, y}]} or {outer: [x, y], inner: [[x, y]]}
39919
+ * - object-listlist-outer-list, flat-listlist-outer-list: a list of objects
39920
+ * in outer/inner object or outer/inner list form
39921
+ * The actual format is stored in the mode object.
39922
+ *
39923
+ * @param {geo.polygonAny} poly A polygon in one of the above formats to
39924
+ * convert.
39925
+ * @param {object} mode An object that is modified with information about
39926
+ * the conversion. This includes style: the input polygon format; min: a
39927
+ * 2-item list with minimum values in x, y; max: a 2-item list with
39928
+ * maximum values in x, y; epsilon: a recommended value for epsilon in other
39929
+ * functions.
39930
+ * @param {geo.util.polyop.spec} [opts] Options for the operation. Only used
39931
+ * if poly is an object with a toPolygonList method.
39932
+ * @returns {geo.polygonList} A list of polygons.
39933
+ */
39934
+
39935
+
39936
+ function toPolygonList(poly, mode, opts) {
39937
+ mode = mode || {};
39938
+
39939
+ if (poly.toPolygonList) {
39940
+ mode.style = poly;
39941
+ poly = poly.toPolygonList(opts);
39942
+
39943
+ if (!poly.length) {
39944
+ mode.min = mode.max = [0, 0];
39945
+ mode.epsilon = 1e-10;
39946
+ return poly;
39947
+ }
39948
+ } else {
39949
+ mode.style = '';
39950
+
39951
+ if (poly.outer) {
39952
+ mode.style = '-outer';
39953
+ poly = [[poly.outer].concat(_toConsumableArray(poly.inner || []))];
39954
+ } else if (poly.length && poly[0].outer) {
39955
+ mode.style = '-outer-list';
39956
+ poly = poly.map(function (p) {
39957
+ return [p.outer].concat(_toConsumableArray(p.inner || []));
39958
+ });
39959
+ }
39960
+
39961
+ if (!poly.length) {
39962
+ mode.style = 'flat-listlist' + mode.style;
39963
+ mode.min = mode.max = [0, 0];
39964
+ mode.epsilon = 1e-10;
39965
+ return poly;
39966
+ }
39967
+
39968
+ if (poly[0].x !== undefined) {
39969
+ mode.style = 'object';
39970
+ poly = [[poly.map(function (pt) {
39971
+ return [pt.x, pt.y];
39972
+ })]];
39973
+ } else if (poly[0][0].x !== undefined) {
39974
+ mode.style = 'object-list' + mode.style;
39975
+ poly = [poly.map(function (p) {
39976
+ return p.map(function (pt) {
39977
+ return [pt.x, pt.y];
39978
+ });
39979
+ })];
39980
+ } else if (poly[0][0][0] === undefined) {
39981
+ mode.style = 'flat';
39982
+ poly = [[poly]];
39983
+ } else if (poly[0][0][0].x !== undefined) {
39984
+ mode.style = 'object-listlist' + mode.style;
39985
+ poly = poly.map(function (p) {
39986
+ return p.map(function (l) {
39987
+ return l.map(function (pt) {
39988
+ return [pt.x, pt.y];
39989
+ });
39990
+ });
39991
+ });
39992
+ } else if (poly[0][0][0][0] === undefined) {
39993
+ mode.style = 'flat-list';
39994
+ poly = [poly];
39995
+ } else {
39996
+ mode.style = 'flat-listlist' + mode.style;
39997
+ }
39998
+ }
39999
+
40000
+ mode.min = [poly[0][0][0][0], poly[0][0][0][1]];
40001
+ mode.max = [poly[0][0][0][0], poly[0][0][0][1]];
40002
+ poly.forEach(function (p) {
40003
+ return p.forEach(function (l) {
40004
+ return l.forEach(function (pt) {
40005
+ if (pt[0] < mode.min[0]) {
40006
+ mode.min[0] = pt[0];
40007
+ }
40008
+
40009
+ if (pt[0] > mode.max[0]) {
40010
+ mode.max[0] = pt[0];
40011
+ }
40012
+
40013
+ if (pt[1] < mode.min[1]) {
40014
+ mode.min[1] = pt[1];
40015
+ }
40016
+
40017
+ if (pt[1] > mode.max[1]) {
40018
+ mode.max[1] = pt[1];
40019
+ }
40020
+ });
40021
+ });
40022
+ });
40023
+ mode.epsilon = Math.max(Math.max(mode.max[0], mode.max[1]), Math.max(Math.abs(mode.min[0]), Math.abs(mode.min[1]))) * 1e-10;
40024
+ return poly;
40025
+ }
40026
+ /**
40027
+ * Convert a polygon list to another format.
40028
+ *
40029
+ * @param {geo.polygonList} poly A list of polygons.
40030
+ * @param {object} mode An object that is modified with information about the
40031
+ * conversion. This includes style: the input polygon format; min: a 2-item
40032
+ * list with minimum values in x, y; max: a 2-item list with maximum values
40033
+ * in x, y; epsilon: a recommended value for epsilon in other functions.
40034
+ * @param {geo.util.polyop.spec} [opts] Options for the operation. Only used
40035
+ * if ``mode.style`` is an object with a fromPolygonList method.
40036
+ * @returns {geo.polygonAny} A polygon in one of several formats.
40037
+ */
40038
+
40039
+
40040
+ function fromPolygonList(poly, mode, opts) {
40041
+ if (mode.style.fromPolygonList) {
40042
+ return mode.style.fromPolygonList(poly, opts);
40043
+ }
40044
+
40045
+ if (mode.style.includes('object')) {
40046
+ poly = poly.map(function (p) {
40047
+ return p.map(function (h) {
40048
+ return h.map(function (pt) {
40049
+ return {
40050
+ x: pt[0],
40051
+ y: pt[1]
40052
+ };
40053
+ });
40054
+ });
40055
+ });
40056
+ }
40057
+
40058
+ if (mode.style.includes('outer')) {
40059
+ poly = [poly.map(function (p) {
40060
+ return {
40061
+ outer: p[0],
40062
+ inner: p.slice(1)
40063
+ };
40064
+ })];
40065
+ }
40066
+
40067
+ if (!mode.style.endsWith('listlist')) {
40068
+ if (mode.style.endsWith('list')) {
40069
+ poly = poly[0];
40070
+ } else {
40071
+ poly = poly[0][0];
40072
+ }
40073
+ }
40074
+
40075
+ return poly;
40076
+ }
40077
+ /**
40078
+ * Use a minimum style for output to include all of the results.
40079
+ *
40080
+ * @param {geo.polygonList} polylist A list of polygons.
40081
+ * @param {string} style the proposed style.
40082
+ * @returns {string} The preferred style.
40083
+ */
40084
+
40085
+
40086
+ function minimumPolygonStyle(polylist, style) {
40087
+ if (style.fromPolygonList) {
40088
+ return style;
40089
+ }
40090
+
40091
+ if (polylist.length > 1) {
40092
+ if (style.includes('outer')) {
40093
+ return style + (style.endsWith('list') ? '' : '-list');
40094
+ }
40095
+
40096
+ if (style.endsWith('listlist')) {
40097
+ return style;
40098
+ }
40099
+
40100
+ return style + (style.endsWith('list') ? 'list' : '-listlist');
40101
+ }
40102
+
40103
+ if (polylist.length === 1 && polylist[0].length > 1) {
40104
+ if (style.includes('outer') || style.endsWith('list')) {
40105
+ return style;
40106
+ }
40107
+
40108
+ return style + '-list';
40109
+ }
40110
+
40111
+ return style;
40112
+ }
40113
+ /**
40114
+ * Generate the correspondence between the source polygons and the output
40115
+ * polygons. A polygon corresponds if it has at least two points in common.
40116
+ *
40117
+ * @param {geo.polygonList} poly1 First set of source polygons.
40118
+ * @param {geo.polygonList} poly2 Second set of source polygons.
40119
+ * @param {geo.polygonList} newpoly Output polygons.
40120
+ * @param {object} results An object to add results to.
40121
+ */
40122
+
40123
+
40124
+ function generateCorrespondence(poly1, poly2, newpoly, results) {
40125
+ var pts = {};
40126
+ var counts = [];
40127
+ newpoly.forEach(function (p, idx) {
40128
+ return p.forEach(function (h) {
40129
+ return h.forEach(function (pt) {
40130
+ var key = '_' + pt[0] + '_' + pt[1];
40131
+
40132
+ if (pts[key]) {
40133
+ if (pts[key].indexOf(idx) === -1) {
40134
+ pts[key].push(idx);
40135
+ }
40136
+ } else {
40137
+ pts[key] = [idx];
40138
+ }
40139
+
40140
+ if (counts.length <= idx) {
40141
+ counts.push(0);
40142
+ }
40143
+
40144
+ counts[idx] += 1;
40145
+ });
40146
+ });
40147
+ });
40148
+ ['poly1', 'poly2'].forEach(function (pkey) {
40149
+ var poly = pkey === 'poly1' ? poly1 : poly2;
40150
+ var ekey = pkey === 'poly1' ? 'exact1' : 'exact2';
40151
+ results[pkey] = Array(poly.length);
40152
+ results[ekey] = Array(poly.length);
40153
+ poly.forEach(function (p, idx) {
40154
+ var found = {};
40155
+ p.forEach(function (h) {
40156
+ return h.forEach(function (pt) {
40157
+ var key = '_' + pt[0] + '_' + pt[1];
40158
+
40159
+ if (pts[key]) {
40160
+ pts[key].forEach(function (val) {
40161
+ found[val] = (found[val] || 0) + 1;
40162
+ });
40163
+ }
40164
+ });
40165
+ });
40166
+ Object.keys(found).forEach(function (nidx) {
40167
+ if (found[nidx] === counts[+nidx]) {
40168
+ if (!results[ekey][idx]) {
40169
+ results[ekey][idx] = [];
40170
+ }
40171
+
40172
+ results[ekey][idx].push(+nidx);
40173
+ }
40174
+
40175
+ if (found[nidx] >= 2) {
40176
+ if (!results[pkey][idx]) {
40177
+ results[pkey][idx] = [];
40178
+ }
40179
+
40180
+ results[pkey][idx].push(+nidx);
40181
+ }
40182
+ });
40183
+ });
40184
+ });
40185
+ }
40186
+ /**
40187
+ * Perform a general operation of a set of polygons.
40188
+ *
40189
+ * @param {string} op The operation to handle. One of union, intersect,
40190
+ * difference, or xor.
40191
+ * @param {geo.polygonAny|geo.util.polyop.spec} poly1 Either the first polygon
40192
+ * set or an object containing all parameters for the function.
40193
+ * @param {geo.polygonAny} [poly2] If the poly1 parameter is not a complete
40194
+ * options object, the second polygon set for the operation.
40195
+ * @param {geo.util.polyop.spec} [opts] If the poly1 parameter is not a
40196
+ * complete options object, the options for the operation.
40197
+ * @returns {geo.polygonAny} A polygon set in the same style as poly1.
40198
+ */
40199
+
40200
+
40201
+ function generalOperationProcess(op, poly1, poly2, opts) {
40202
+ var transform = __webpack_require__(6853);
40203
+
40204
+ op = AlternateOpNames[op] || op;
40205
+
40206
+ if (poly1.poly1) {
40207
+ opts = poly1;
40208
+ poly1 = opts.poly1;
40209
+ poly2 = opts.poly2;
40210
+ }
40211
+
40212
+ opts = opts || {};
40213
+ var ingcs1 = opts.ingcs || (opts.map ? opts.map.ingcs() : poly1.gcs ? poly1.gcs() : poly1.layer && poly1.layer().gcs ? poly1.layer().gcs() : poly1.layer ? poly1.layer().map().ingcs() : poly1.map instanceof geo_map ? poly1.map().ingcs() : undefined);
40214
+ var ingcs2 = opts.ingcs || (opts.map ? opts.map.ingcs() : poly2.gcs ? poly2.gcs() : poly2.layer && poly2.layer().gcs ? poly2.layer().gcs() : poly2.layer ? poly2.layer().map().ingcs() : poly2.map instanceof geo_map ? poly2.map().ingcs() : ingcs1);
40215
+ var gcs = opts.gcs || (opts.map ? opts.map.gcs() : poly1.layer ? poly1.layer().map().gcs() : poly1.map instanceof geo_map ? poly1.map().gcs() : undefined);
40216
+ var mode1 = {};
40217
+ var mode2 = {};
40218
+ poly1 = toPolygonList(poly1, mode1, opts);
40219
+ poly2 = toPolygonList(poly2, mode2, opts);
40220
+ mode1.epsilon = opts.epsilon1 || mode1.epsilon;
40221
+ mode2.epsilon = opts.epsilon2 || mode1.epsilon;
40222
+
40223
+ if (ingcs1 && gcs && ingcs1 !== gcs) {
40224
+ poly1 = poly1.map(function (p) {
40225
+ return p.map(function (h) {
40226
+ return transform.transformCoordinates(ingcs1, gcs, h);
40227
+ });
40228
+ });
40229
+ }
40230
+
40231
+ if (ingcs2 && gcs && ingcs2 !== gcs) {
40232
+ poly2 = poly2.map(function (p) {
40233
+ return p.map(function (h) {
40234
+ return transform.transformCoordinates(ingcs2, gcs, h);
40235
+ });
40236
+ });
40237
+ }
40238
+
40239
+ var seglist1 = poly1.map(function (p) {
40240
+ return PolyBool.segments({
40241
+ regions: p
40242
+ });
40243
+ });
40244
+ var seglist2 = poly2.map(function (p) {
40245
+ return PolyBool.segments({
40246
+ regions: p
40247
+ });
40248
+ });
40249
+ seglist1 = polygonOperationSeglist(opts.innerOperation || 'union', mode1.epsilon, seglist1);
40250
+ seglist2 = polygonOperationSeglist(opts.innerOperation || 'union', mode2.epsilon, seglist2);
40251
+ var seglist = seglist1;
40252
+
40253
+ if (seglist1[0] && seglist2[0]) {
40254
+ /* We need to do the main operation with the same inversion flags */
40255
+ seglist1[0].inverted = false;
40256
+ seglist2[0].inverted = false;
40257
+ seglist = polygonOperationSeglist(op, Math.max(mode1.epsilon, mode2.epsilon), [seglist1[0], seglist2[0]]);
40258
+ } else if (seglist2[0]) {
40259
+ seglist = seglist2;
40260
+ }
40261
+
40262
+ var newpoly = seglistToPolygonList(seglist);
40263
+
40264
+ if (opts.correspond) {
40265
+ generateCorrespondence(poly1, poly2, newpoly, opts.correspond);
40266
+ }
40267
+
40268
+ if (ingcs1 && gcs && ingcs1 !== gcs) {
40269
+ newpoly = newpoly.map(function (p) {
40270
+ return p.map(function (h) {
40271
+ return transform.transformCoordinates(gcs, ingcs1, h);
40272
+ });
40273
+ });
40274
+ }
40275
+
40276
+ var mode = {
40277
+ style: opts.style || minimumPolygonStyle(newpoly, mode1.style)
40278
+ };
40279
+ return fromPolygonList(newpoly, mode, opts);
40280
+ }
40281
+ /**
40282
+ * Generate a polygon function for a specific operation.
40283
+ *
40284
+ * @param {string} op The operation to handle. One of union, intersect,
40285
+ * difference, or xor.
40286
+ * @returns {function} a function for the polygons.
40287
+ */
40288
+
40289
+
40290
+ function generalOperation(op) {
40291
+ return function (poly1, poly2, opts) {
40292
+ return generalOperationProcess(op, poly1, poly2, opts);
40293
+ };
40294
+ }
40295
+
40296
+ module.exports = {
40297
+ union: generalOperation('union'),
40298
+ intersect: generalOperation('intersect'),
40299
+ difference: generalOperation('difference'),
40300
+ xor: generalOperation('xor'),
40301
+ toPolygonList: toPolygonList,
40302
+ fromPolygonList: fromPolygonList
40303
+ };
40304
+
40305
+ /***/ }),
40306
+
39183
40307
  /***/ 9215:
39184
40308
  /***/ (function(module) {
39185
40309
 
@@ -39556,7 +40680,7 @@ module.exports = vectorFeature;
39556
40680
  * @constant
39557
40681
  * @type {string}
39558
40682
  */
39559
- module.exports = "1.8.8";
40683
+ module.exports = "1.9.0";
39560
40684
 
39561
40685
  /***/ }),
39562
40686
 
@@ -40789,7 +41913,6 @@ var webgl_lineFeature = function webgl_lineFeature(arg) {
40789
41913
  v = vert[1],
40790
41914
  target_gcs = m_this.gcs(),
40791
41915
  map_gcs = m_this.layer().map().gcs(),
40792
- simpleInverse = transform.onlyInvertedY(target_gcs, map_gcs),
40793
41916
  pos,
40794
41917
  posIdx3,
40795
41918
  firstpos,
@@ -40809,6 +41932,9 @@ var webgl_lineFeature = function webgl_lineFeature(arg) {
40809
41932
  strokeOffsetVal,
40810
41933
  miterLimit = m_this.style.get('miterLimit')(data),
40811
41934
  antialiasing = m_this.style.get('antialiasing')(data) || 0,
41935
+ uniformFunc = m_this.style.get('uniformLine'),
41936
+ uniformVal,
41937
+ uniform,
40812
41938
  order = m_this.featureVertices(),
40813
41939
  orderk0,
40814
41940
  prevkey,
@@ -40839,6 +41965,7 @@ var webgl_lineFeature = function webgl_lineFeature(arg) {
40839
41965
  strokeOffsetVal = util.isFunction(m_this.style('strokeOffset')) ? undefined : strokeOffsetFunc() || 0;
40840
41966
  strokeOpacityVal = util.isFunction(m_this.style('strokeOpacity')) ? undefined : strokeOpacityFunc();
40841
41967
  strokeWidthVal = util.isFunction(m_this.style('strokeWidth')) ? undefined : strokeWidthFunc();
41968
+ uniformVal = util.isFunction(m_this.style('uniformLine')) ? undefined : uniformFunc();
40842
41969
 
40843
41970
  if (miterLimit !== undefined) {
40844
41971
  /* We impose a limit no matter what, since otherwise the growth is
@@ -40871,7 +41998,7 @@ var webgl_lineFeature = function webgl_lineFeature(arg) {
40871
41998
  for (j = 0; j < lineItem.length; j += 1) {
40872
41999
  pos = posFunc ? posFunc(lineItem[j], j, d, i) : lineItem[j];
40873
42000
  position.push(pos.x);
40874
- position.push(simpleInverse ? -pos.y : pos.y);
42001
+ position.push(pos.y);
40875
42002
  position.push(pos.z || 0.0);
40876
42003
 
40877
42004
  if (!j) {
@@ -40894,10 +42021,7 @@ var webgl_lineFeature = function webgl_lineFeature(arg) {
40894
42021
  }
40895
42022
  }
40896
42023
 
40897
- if (!simpleInverse) {
40898
- position = transform.transformCoordinates(target_gcs, map_gcs, position, 3);
40899
- }
40900
-
42024
+ position = transform.transformCoordinates(target_gcs, map_gcs, position, 3);
40901
42025
  m_origin = new Float32Array(m_this.style.get('origin')(position));
40902
42026
 
40903
42027
  if (m_origin[0] || m_origin[1] || m_origin[2]) {
@@ -40950,6 +42074,7 @@ var webgl_lineFeature = function webgl_lineFeature(arg) {
40950
42074
  continue;
40951
42075
  }
40952
42076
 
42077
+ uniform = uniformVal === undefined ? uniformFunc(lineItem, i) : uniformVal;
40953
42078
  d = data[i];
40954
42079
  closedVal = closed[i];
40955
42080
  firstPosIdx3 = posIdx3;
@@ -40979,13 +42104,27 @@ var webgl_lineFeature = function webgl_lineFeature(arg) {
40979
42104
  v.next = j + 1 < lineItem.length ? posIdx3 + 3 : closedVal ? j !== lidx ? firstPosIdx3 + 3 : firstPosIdx3 + 6 - closedVal * 3 : posIdx3;
40980
42105
  }
40981
42106
 
40982
- v.strokeWidth = strokeWidthVal === undefined ? strokeWidthFunc(lineItemData, lidx, d, i) : strokeWidthVal;
40983
- v.strokeColor = strokeColorVal === undefined ? strokeColorFunc(lineItemData, lidx, d, i) : strokeColorVal;
40984
- v.strokeOpacity = strokeOpacityVal === undefined ? strokeOpacityFunc(lineItemData, lidx, d, i) : strokeOpacityVal;
42107
+ if (uniform && j > 0) {
42108
+ if (j === 1) {
42109
+ v.strokeWidth = vert[0].strokeWidth;
42110
+ v.strokeColor = vert[0].strokeColor;
42111
+ v.strokeOpacity = vert[0].strokeOpacity;
42112
+ }
42113
+ } else {
42114
+ v.strokeWidth = strokeWidthVal === undefined ? strokeWidthFunc(lineItemData, lidx, d, i) : strokeWidthVal;
42115
+ v.strokeColor = strokeColorVal === undefined ? strokeColorFunc(lineItemData, lidx, d, i) : strokeColorVal;
42116
+ v.strokeOpacity = strokeOpacityVal === undefined ? strokeOpacityFunc(lineItemData, lidx, d, i) : strokeOpacityVal;
42117
+ }
40985
42118
 
40986
42119
  if (updateFlags) {
40987
42120
  if (strokeOffsetVal !== 0) {
40988
- v.strokeOffset = (strokeOffsetVal === undefined ? strokeOffsetFunc(lineItemData, lidx, d, i) : strokeOffsetVal) || 0;
42121
+ if (uniform && j > 0) {
42122
+ if (j === 1) {
42123
+ v.strokeOffset = vert[0].strokeOffset;
42124
+ }
42125
+ } else {
42126
+ v.strokeOffset = (strokeOffsetVal === undefined ? strokeOffsetFunc(lineItemData, lidx, d, i) : strokeOffsetVal) || 0;
42127
+ }
40989
42128
 
40990
42129
  if (v.strokeOffset) {
40991
42130
  /* we use 11 bits to store the offset, and we want to store values
@@ -43415,13 +44554,13 @@ var webgl_polygonFeature = function webgl_polygonFeature(arg) {
43415
44554
  fillOpacityVal,
43416
44555
  fillFunc,
43417
44556
  fillVal,
43418
- uniformPolyFunc,
44557
+ uniformFunc,
44558
+ uniformVal,
43419
44559
  uniform,
43420
44560
  indices,
43421
44561
  items = [],
43422
44562
  target_gcs = m_this.gcs(),
43423
44563
  map_gcs = m_this.layer().map().gcs(),
43424
- simpleInverse = transform.onlyInvertedY(target_gcs, map_gcs),
43425
44564
  numPts = 0,
43426
44565
  geom = m_mapper.geometryData(),
43427
44566
  color,
@@ -43444,7 +44583,8 @@ var webgl_polygonFeature = function webgl_polygonFeature(arg) {
43444
44583
  fillOpacityVal = util.isFunction(m_this.style('fillOpacity')) ? undefined : fillOpacityFunc();
43445
44584
  fillFunc = m_this.style.get('fill');
43446
44585
  fillVal = util.isFunction(m_this.style('fill')) ? undefined : fillFunc();
43447
- uniformPolyFunc = m_this.style.get('uniformPolygon');
44586
+ uniformFunc = m_this.style.get('uniformPolygon');
44587
+ uniformVal = util.isFunction(m_this.style('uniformPolygon')) ? undefined : uniformFunc();
43448
44588
 
43449
44589
  if (!onlyStyle) {
43450
44590
  posFunc = m_this.style.get('position');
@@ -43474,7 +44614,7 @@ var webgl_polygonFeature = function webgl_polygonFeature(arg) {
43474
44614
  for (i = d3 = 0; i < outer.length; i += 1, d3 += 3) {
43475
44615
  c = posFunc ? posFunc(outer[i], i, item, itemIndex) : outer[i];
43476
44616
  geometry[d3] = c.x;
43477
- geometry[d3 + 1] = simpleInverse ? -c.y : c.y; // ignore the z values until we support them
44617
+ geometry[d3 + 1] = c.y; // ignore the z values until we support them
43478
44618
 
43479
44619
  geometry[d3 + 2] = 0; // c.z || 0;
43480
44620
  }
@@ -43498,7 +44638,7 @@ var webgl_polygonFeature = function webgl_polygonFeature(arg) {
43498
44638
  for (i = 0; i < hole.length; i += 1, d3 += 3) {
43499
44639
  c = posFunc ? posFunc(hole[i], i, item, itemIndex) : hole[i];
43500
44640
  geometry.vertices[d3] = c.x;
43501
- geometry.vertices[d3 + 1] = simpleInverse ? -c.y : c.y; // ignore the z values until we support them
44641
+ geometry.vertices[d3 + 1] = c.y; // ignore the z values until we support them
43502
44642
 
43503
44643
  geometry.vertices[d3 + 2] = 0; // c.z || 0;
43504
44644
  }
@@ -43506,10 +44646,7 @@ var webgl_polygonFeature = function webgl_polygonFeature(arg) {
43506
44646
  } // transform to map gcs
43507
44647
 
43508
44648
 
43509
- if (!simpleInverse) {
43510
- geometry.vertices = transform.transformCoordinates(target_gcs, map_gcs, geometry.vertices, geometry.dimensions);
43511
- }
43512
-
44649
+ geometry.vertices = transform.transformCoordinates(target_gcs, map_gcs, geometry.vertices, geometry.dimensions);
43513
44650
  record = {
43514
44651
  // triangulate
43515
44652
  triangles: earcut(geometry.vertices, geometry.holes, geometry.dimensions),
@@ -43555,7 +44692,7 @@ var webgl_polygonFeature = function webgl_polygonFeature(arg) {
43555
44692
  item = items[k].item;
43556
44693
  itemIndex = items[k].itemIndex;
43557
44694
  original = items[k].original;
43558
- uniform = uniformPolyFunc(item, itemIndex);
44695
+ uniform = uniformVal === undefined ? uniformFunc(item, itemIndex) : uniformVal;
43559
44696
  opacity = fillOpacityVal;
43560
44697
 
43561
44698
  if (uniform) {
@@ -45276,12 +46413,23 @@ module.exports = {
45276
46413
  /* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);
45277
46414
  /* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3476);
45278
46415
  /* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);
46416
+ /* harmony import */ var _node_modules_css_loader_dist_runtime_getUrl_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(1678);
46417
+ /* harmony import */ var _node_modules_css_loader_dist_runtime_getUrl_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_getUrl_js__WEBPACK_IMPORTED_MODULE_2__);
45279
46418
  // Imports
45280
46419
 
45281
46420
 
46421
+
46422
+ var ___CSS_LOADER_URL_IMPORT_0___ = new URL(/* asset import */ __webpack_require__(3554), __webpack_require__.b);
46423
+ var ___CSS_LOADER_URL_IMPORT_1___ = new URL(/* asset import */ __webpack_require__(4144), __webpack_require__.b);
46424
+ var ___CSS_LOADER_URL_IMPORT_2___ = new URL(/* asset import */ __webpack_require__(237), __webpack_require__.b);
46425
+ var ___CSS_LOADER_URL_IMPORT_3___ = new URL(/* asset import */ __webpack_require__(9490), __webpack_require__.b);
45282
46426
  var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));
46427
+ var ___CSS_LOADER_URL_REPLACEMENT_0___ = _node_modules_css_loader_dist_runtime_getUrl_js__WEBPACK_IMPORTED_MODULE_2___default()(___CSS_LOADER_URL_IMPORT_0___);
46428
+ var ___CSS_LOADER_URL_REPLACEMENT_1___ = _node_modules_css_loader_dist_runtime_getUrl_js__WEBPACK_IMPORTED_MODULE_2___default()(___CSS_LOADER_URL_IMPORT_1___);
46429
+ var ___CSS_LOADER_URL_REPLACEMENT_2___ = _node_modules_css_loader_dist_runtime_getUrl_js__WEBPACK_IMPORTED_MODULE_2___default()(___CSS_LOADER_URL_IMPORT_2___);
46430
+ var ___CSS_LOADER_URL_REPLACEMENT_3___ = _node_modules_css_loader_dist_runtime_getUrl_js__WEBPACK_IMPORTED_MODULE_2___default()(___CSS_LOADER_URL_IMPORT_3___);
45283
46431
  // Module
45284
- ___CSS_LOADER_EXPORT___.push([module.id, ".geojs-map{position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;overflow:hidden}.geojs-map .geo-attribution{position:absolute;right:0;bottom:0;padding-right:5px;cursor:auto;font:11px/1.5 \"Helvetica Neue\",Arial,Helvetica,sans-serif;z-index:1001;background:rgba(255,255,255,0.7);clear:both;display:block;pointer-events:auto}.geojs-map .geo-attribution .geo-attribution-layer{padding-left:5px}.geojs-map .canvas-canvas{display:block;-webkit-transform-origin:0 0;-moz-transform-origin:0 0;-o-transform-origin:0 0;-ms-transform-origin:0 0;transform-origin:0 0}.geojs-map .webgl-canvas{display:block}.geojs-map .geojs-layer{position:absolute;width:100%;height:100%;left:0;top:0;pointer-events:none}.geojs-map .geojs-layer.active:not(.hidden) > *{pointer-events:auto}.geojs-map .geojs-layer.hidden{display:none}.geojs-map .geojs-layer.hidden[renderer=\"webgl\"]{display:inherit}.geojs-map .geo-tile-layer{-webkit-transform-origin:0 0;-moz-transform-origin:0 0;-o-transform-origin:0 0;-ms-transform-origin:0 0;transform-origin:0 0;line-height:0;font-size:0}.geojs-map.annotation-input{cursor:crosshair}.geojs-map.highlight-focus:after{content:\"\";display:block;position:absolute;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;left:0;top:0;right:0;bottom:0;border:3px solid Highlight;opacity:1;-ms-filter:none;filter:none;-webkit-transition:opacity 0s;-moz-transition:opacity 0s;-o-transition:opacity 0s;-ms-transition:opacity 0s;transition:opacity 0s;visibility:hidden}.geojs-map.highlight-focus:focus:after{visibility:visible;-webkit-transition:opacity 2.5s ease-in;-moz-transition:opacity 2.5s ease-in;-o-transition:opacity 2.5s ease-in;-ms-transition:opacity 2.5s ease-in;transition:opacity 2.5s ease-in;opacity:0;-ms-filter:\"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)\";filter:alpha(opacity=0)}.geo-tile-container{position:absolute}.geo-tile-container.crop{overflow:hidden}", "",{"version":3,"sources":["webpack://./main.styl","webpack://./../node_modules/nib/lib/nib/vendor.styl","webpack://./../node_modules/nib/lib/nib/overflow.styl","webpack://./../node_modules/nib/lib/nib/flex.styl","webpack://./../node_modules/nib/lib/nib/border.styl"],"names":[],"mappings":"AAEA,WACE,iBAAS,CCwCO,wBAAG,CAAH,qBAAG,CAAH,oBAAG,CARN,gBAAG,CChBd,eAAU,CFZZ,4BACE,iBAAS,CACT,OAAM,CACN,QAAO,CACP,iBAAc,CCmfd,WAAO,CDjfP,yDAA8B,CAC9B,YAAQ,CCoeR,gCAAW,CDleX,UAAM,CGMN,aAAS,CHJT,mBAAe,CAEf,mDACE,gBAAa,CAEjB,0BGDE,aAAS,CFqBK,4BAAG,CAAH,yBAAG,CAAH,uBAAG,CAAH,wBAAG,CARN,oBAAG,CDThB,yBGJE,aAAS,CHOX,wBACE,iBAAS,CACT,UAAM,CACN,WAAO,CACP,MAAK,CACL,KAAI,CACJ,mBAAe,CAEb,gDACE,mBAAe,CACnB,+BGjBA,YAAS,CHmBT,iDGnBA,eAAS,CHsBX,2BCDgB,4BAAG,CAAH,yBAAG,CAAH,uBAAG,CAAH,wBAAG,CARN,oBAAG,CDWd,aAAY,CACZ,WAAU,CAEZ,4BC6cE,gBAAO,CDzcP,iCACE,UAAQ,CGhCV,aAAS,CHkCP,iBAAS,CCbG,6BAAG,CAAH,0BAAG,CARN,qBAAG,CDuBZ,MAAK,CACL,KAAI,CACJ,OAAM,CACN,QAAO,CIpDT,0BAAQ,CHmQV,SAAS,CAQH,eAAY,CACZ,WAAQ,CA5OE,6BAAG,CAAH,0BAAG,CAAH,wBAAG,CAAH,yBAAG,CARN,qBAAG,CDkCZ,iBAAW,CACb,uCACE,kBAAW,CC5BC,uCAAG,CAAH,oCAAG,CAAH,kCAAG,CAAH,mCAAG,CARN,+BAAG,CA2OhB,SAAS,CAWH,+DAAyE,CACzE,uBAAiC,CD/MzC,oBACE,iBAAS,CACT,yBExDE,eAAU","sourcesContent":["@import '~nib/index.styl'\n\n.geojs-map\n position relative\n user-select none\n overflow hidden\n\n .geo-attribution\n position absolute\n right 0\n bottom 0\n padding-right 5px\n cursor auto\n font 11px/1.5 \"Helvetica Neue\", Arial, Helvetica, sans-serif\n z-index 1001\n background rgba(255,255,255,0.7)\n clear both\n display block\n pointer-events auto\n\n .geo-attribution-layer\n padding-left 5px\n\n .canvas-canvas\n display block\n transform-origin 0px 0px\n .webgl-canvas\n display block\n\n .geojs-layer\n position absolute\n width 100%\n height 100%\n left 0\n top 0\n pointer-events none\n &.active:not(.hidden)\n > *\n pointer-events auto\n &.hidden\n display none\n &.hidden[renderer=\"webgl\"]\n display inherit\n\n .geo-tile-layer\n transform-origin 0px 0px\n line-height 0\n font-size 0\n\n &.annotation-input\n cursor crosshair\n\n &.highlight-focus\n &:after\n content \"\"\n display block\n position absolute\n box-sizing border-box\n left 0px\n top 0px\n right 0px\n bottom 0px\n // Highlight is technically a css2 color. We may need to specify it\n // explicitly. #3B66A6 seems close\n border 3px solid Highlight\n opacity 1\n transition opacity 0s\n visibility hidden\n &:focus:after\n visibility visible\n transition opacity 2.5s ease-in\n opacity 0\n\n.geo-tile-container\n position absolute\n &.crop\n overflow hidden\n","use('../nodes/vendor-helpers.js')\n@import 'config'\n\n/*\n * Alias \"nowrap\" as \"no-wrap\".\n */\n\nno-wrap = unquote('nowrap')\n\n/*\n * Helper to find out if a given value is a width\n */\n\nis-width(val)\n if auto == val\n return true\n else if val && 'unit' == type(val)\n // Stylus does not short circuit so we need to perform this as a distinct\n // operation to prevent errors\n return '' != unit(val)\n return false\n\n/*\n * Vendor support for the given prop / arguments, optionally specifying the\n * only prefixes to utilize, or those which should be ignored.\n */\n\nvendor(prop, args, only = null, ignore = null, vendor-property = true)\n need_normalize = !vendor-property or prop in ('transition' 'transition-property' 'border-image' 'border-image-slice')\n for prefix in vendor-prefixes\n unless (only and !(prefix in only)) or (ignore and prefix in ignore)\n if official == prefix\n if need_normalize\n {prop}: normalize(prop,('%s' % args))\n else\n {prop}: args\n else\n newprop = prop\n newprop = '-' + prefix + '-' + prop if vendor-property\n\n if need_normalize\n {newprop}: normalize(prop,('%s' % args),prefix)\n else\n {newprop}: args\n/*\n * Vendorize the given value.\n */\n\nvendor-value(arg, only = null, ignore = null)\n prop = current-property[0]\n for prefix in vendor-prefixes\n unless (only and !(prefix in only)) or (ignore and prefix in ignore) or official == prefix\n add-property(prop, '-%s-%s' % (prefix arg))\n arg\n\n/*\n * Vendor \"box-shadow\" support.\n */\n\nbox-shadow()\n vendor('box-shadow', arguments, only: webkit official)\n\n/*\n * Vendor \"user-select\" support.\n */\n\nuser-select()\n vendor('user-select', arguments, only: webkit moz ms official)\n\n/*\n * Vendor \"column-count\" support.\n */\n\ncolumn-count()\n vendor('column-count', arguments, only: webkit moz official)\n\n/*\n * Vendor \"column-gap\" support.\n */\n\ncolumn-gap()\n vendor('column-gap', arguments, only: webkit moz official)\n\n/*\n * Vendor \"column-rule\" support.\n */\n\ncolumn-rule()\n vendor('column-rule', arguments, only: webkit moz official)\n\n/*\n * Vendor \"column-rule-color\" support.\n */\n\ncolumn-rule-color()\n vendor('column-rule-color', arguments, only: webkit moz official)\n\n/*\n * Vendor \"column-rule-width\" support.\n */\n\ncolumn-rule-width()\n vendor('column-rule-width', arguments, only: webkit moz official)\n\n/*\n * Vendor \"column-rule-style\" support.\n */\n\ncolumn-rule-style()\n vendor('column-rule-style', arguments, only: webkit moz official)\n\n/*\n * Vendor \"column-width\" support.\n */\n\ncolumn-width()\n vendor('column-width', arguments, only: webkit moz official)\n\n/*\n * Vendor \"column-span\" support.\n */\n\ncolumn-span()\n vendor('column-span', arguments, only: webkit official)\n\n/*\n * Vendor \"column-fill\" support.\n */\n\ncolumn-fill()\n vendor('column-fill', arguments, only: moz)\n\n/*\n * Legacy syntax support for background-clip and background-origin\n */\n\nlegacy-bg-values(property, args)\n legacy_args = ()\n importance = unquote('')\n for subargs in args\n for arg in subargs\n if arg in (border-box padding-box content-box)\n arg = unquote('border') if arg == border-box\n arg = unquote('padding') if arg == padding-box\n arg = unquote('content') if arg == content-box\n if arg != '!important'\n push(legacy_args,arg)\n else\n importance = !important\n vendor(property, unquote(join(', ',legacy_args)) importance, only: moz webkit)\n\n/*\n * Vendor \"background-clip\" support.\n */\n\nbackground-clip()\n if arguments[0] == text\n vendor('background-clip', arguments, only: webkit)\n else\n legacy-bg-values('background-clip', arguments)\n background-clip: arguments\n\n/*\n * Vendor \"background-origin\" support.\n */\n\nbackground-origin()\n legacy-bg-values('background-origin', arguments)\n background-origin: arguments\n\n/*\n * Vendor \"background-size\" support.\n */\n\nbackground-size()\n vendor('background-size', arguments, only: webkit moz official)\n\n/*\n * Vendor \"transform\" support.\n */\n\ntransform()\n vendor('transform', arguments)\n\n/*\n * Vendor \"transform-origin\" support.\n */\ntransform-origin()\n vendor('transform-origin', arguments)\n\n/*\n * Vendor \"transform-style\" support.\n */\n\ntransform-style()\n vendor('transform-style', arguments)\n\n/*\n * Vendor \"border-image\" support.\n */\n\nborder-image()\n vendor('border-image', arguments, only: webkit moz o official)\n\n/*\n * Vendor \"transition\" support.\n */\n\ntransition()\n vendor('transition', arguments)\n\n/*\n * Vendor \"transition-property\" support.\n */\n\ntransition-property()\n vendor('transition-property', arguments)\n\n/*\n * Vendor \"transition-duration\" support.\n */\n\ntransition-duration()\n vendor('transition-duration', arguments)\n\n/*\n * Vendor \"transition-timing-function\" support.\n */\n\ntransition-timing-function()\n vendor('transition-timing-function', arguments)\n\n/*\n * Vendor \"transition-delay\" support.\n */\n\ntransition-delay()\n vendor('transition-delay', arguments)\n\n/*\n * Vendor \"backface-visibility\" support.\n */\n\nbackface-visibility()\n vendor('backface-visibility', arguments, only: webkit moz ms official)\n\n/*\n * Vendor \"perspective\" support.\n */\n\nperspective()\n if mixin\n vendor('perspective', arguments, only: webkit moz ms official)\n else\n 'perspective(%s)' % arguments\n\n/*\n * Vendor \"perspective-origin\" support.\n */\n\nperspective-origin()\n vendor('perspective-origin', arguments, only: webkit moz ms official)\n\n/*\n * Opacity with conditional IE support.\n */\n\nopacity(n, args...)\n opacity: n args\n if support-for-ie\n if n == inherit or n == initial\n -ms-filter: n args\n filter: n args\n else\n val = round(n * 100)\n if val == 100\n -ms-filter: none args\n filter: none args\n else\n -ms-filter: '\"progid:DXImageTransform.Microsoft.Alpha(Opacity=%s)\"' % val args\n filter: 'alpha(opacity=%s)' % val args\n\n/*\n * Vendor \"text-size-adjust\"\n */\n\ntext-size-adjust()\n vendor('text-size-adjust', arguments)\n\n/*\n * Alias the \"white-space\" property.\n */\n\nwhitespace()\n white-space: arguments\n\n/*\n * Vendor \"box-sizing\" support.\n */\n\nbox-sizing()\n vendor('box-sizing', arguments, only: webkit moz official)\n\n/*\n * Vendor \"box-orient\" support.\n */\n\nbox-orient()\n vendor('box-orient', arguments, only: webkit moz official)\n\n/*\n * Vendor \"box-flex-group\" support.\n */\n\nbox-flex-group()\n vendor('box-flex-group', arguments, only: webkit moz official)\n\n/*\n * Vendor \"box-ordinal-group\" support.\n */\n\nbox-ordinal-group()\n vendor('box-ordinal-group', arguments, only: webkit moz ms official)\n\n\n/*\n * Vendor \"box-align\" support.\n */\n\nbox-align()\n vendor('box-align', arguments, only: webkit moz ms official)\n\n/*\n * Vendor \"box-pack\" support.\n */\n\nbox-pack()\n vendor('box-pack', arguments, only: webkit moz ms official)\n\n/*\n * Vendor \"box-direction\" support.\n */\n\nbox-direction()\n vendor('box-direction', arguments, only: webkit moz ms official)\n\n/*\n * Vendor \"animation\" support.\n */\n\nanimation()\n vendor('animation', arguments)\n\n\n/*\n * Vendor \"animation-name\" support.\n */\n\nanimation-name()\n vendor('animation-name', arguments)\n\n/*\n * Vendor \"animation-duration\" support.\n */\n\nanimation-duration()\n vendor('animation-duration', arguments)\n\n/*\n * Vendor \"animation-delay\" support.\n */\n\nanimation-delay()\n vendor('animation-delay', arguments)\n\n/*\n * Vendor \"animation-direction\" support.\n */\n\nanimation-direction()\n vendor('animation-direction', arguments)\n\n/*\n * Vendor \"animation-iteration-count\" support.\n */\n\nanimation-iteration-count()\n vendor('animation-iteration-count', arguments)\n\n/*\n * Vendor \"animation-timing-function\" support.\n */\n\nanimation-timing-function()\n vendor('animation-timing-function', arguments)\n\n/*\n * Vendor \"animation-play-state\" support.\n */\n\nanimation-play-state()\n vendor('animation-play-state', arguments)\n\n/*\n * Vendor \"animation-fill-mode\" support.\n */\n\nanimation-fill-mode()\n vendor('animation-fill-mode', arguments)\n\n/*\n * Vendor \"hyphens\" support.\n */\n\nhyphens()\n vendor('hyphens', arguments, only: webkit moz ms official)\n\n/*\n * Vendor \"appearance\" support.\n */\n\nappearance()\n vendor('appearance', arguments, only: webkit moz official)\n\n/*\n * Vendor \"tab-size\" support.\n */\n\ntab-size()\n vendor('tab-size', arguments, only: moz o official)\n\n/*\n * Vendor \"overflow-scrolling\" support.\n */\n\noverflow-scrolling()\n vendor('overflow-scrolling', arguments, only: webkit official)\n\n/*\n * Vendor \"text-overflow\" support, , -o- for opera 9.* - 10.*\n */\n\ntext-overflow()\n vendor('text-overflow', arguments, only: official o)\n\n/*\n * Vendor \"text-size-adjust\" support.\n */\ntext-size-adjust()\n vendor('text-size-adjust', arguments, only: official webkit ms)\n\n/*\n * Vendor \"font-smoothing\" support, webkit only.\n */\nfont-smoothing()\n vendor('font-smoothing', arguments, only: webkit)\n\n\n/**\n * Vendor input-placeholder/placeholder support.\n *\n * Examples:\n * // Default syntax\n * body\n * placeholder(color #333, font-weight normal)\n *\n * // The comma is important\n * .placeholder-red\n * placeholder(color red,)\n *\n * // We can pass a function\n * green-placeholder()\n * color green\n * .placeholder-green\n * placeholder(green-placeholder)\n *\n * // We can pass a hash\n * textarea\n * placeholder((font-style italic) (font-weight bold) (padding '4px 10px'))\n */\nplaceholder()\n for v in ':-webkit-input' '-moz' ':-moz' '-ms-input'\n &:{v}-placeholder\n for pair in arguments\n if typeof(pair) == 'function'\n pair()\n else if pair is not null && pair[0] is not null\n {pair[0]}: type(pair[1]) == 'string' ? s(pair[1]) : pair[1]\ninput-placeholder = placeholder\n\n/*\n * Vendor background support (gradients).\n */\n\nbackground()\n if match('-gradient\\(', ''+arguments)\n vendor('background', arguments, vendor-property: false)\n else\n background arguments\n\nbackground-image()\n if match('-gradient\\(', ''+arguments)\n vendor('background-image', arguments, vendor-property: false)\n else\n background-image arguments\n\ncursor()\n if match('-gradient\\(', ''+arguments)\n vendor('cursor', arguments, vendor-property: false)\n else\n cursor arguments\n\nlist-style()\n if match('-gradient\\(', ''+arguments)\n vendor('list-style', arguments, vendor-property: false)\n else\n list-style arguments\n\nlist-style-image()\n if match('-gradient\\(', ''+arguments)\n vendor('list-style-image', arguments, vendor-property: false)\n else\n list-style-image arguments\n","/*\n * Overflow utility. Maps to regular overflow, and adds an ellipsis value.\n *\n * Synopsis:\n *\n * overflow: <type>\n *\n * Examples:\n *\n * overflow: auto\n * overflow: hidden\n * overflow: ellipsis\n *\n */\n\noverflow()\n if arguments[0] == ellipsis\n ellipsis()\n else\n overflow: arguments\n","/*\n * Vendor \"display: flex\" support with fallback to obsolete versions.\n */\n\nflex-version ?= box flex\n\n//\n// 1. Display values\n// - http://www.w3.org/TR/css3-flexbox/#flex-containers\n//\ndisplay(type, args...)\n if flex == type || inline-flex == type\n if box in flex-version\n if flex == type\n display: -ms-flexbox args\n display: vendor-value(box args, only: moz webkit)\n else\n display: -ms-inline-flexbox args\n display: vendor-value(inline-box args, only: moz webkit)\n if flex in flex-version\n display: vendor-value(arguments, only: webkit official) // overwrites old webkit\n else\n display: arguments\n\n/*\n * New syntax for browsers like Google Chrome.\n * Plus a translation to the old syntax, if possible.\n */\n\n\n//\n// 5. Ordering and Orientation\n// - http://www.w3.org/TR/css3-flexbox/#ordering-and-orientation\n//\n-flex-obsolete-direction(direction)\n if box in flex-version\n if row-reverse == direction || column-reverse == direction\n vendor('box-direction', reverse, ignore: ms official)\n\n if row == direction || row-reverse == direction\n vendor('box-orient', horizontal, ignore: ms official)\n else if column == direction || column-reverse == direction\n vendor('box-orient', vertical, ignore: ms official)\n\n-flex-obsolete-wrap(value)\n if box in flex-version\n // WARN: wrap-reverse does not have a box equivalent. This will render in different manners\n // on box vs. flex values.\n if 'wrap' == value || wrap-reverse == value\n vendor('box-lines', multiple, ignore: ms official)\n else if nowrap == value\n vendor('box-lines', single, ignore: ms official)\n\nflex-direction(direction)\n // obsolete\n -flex-obsolete-direction(direction)\n\n // new\n if flex in flex-version\n vendor('flex-direction', arguments, only: webkit ms official)\n\nflex-wrap(value)\n // obsolete\n -flex-obsolete-wrap(value)\n\n if flex in flex-version\n vendor('flex-wrap', arguments, only: webkit ms official)\n\nflex-flow()\n // obsolete\n -flex-obsolete-direction(arguments[0])\n -flex-obsolete-direction(arguments[1])\n -flex-obsolete-wrap(arguments[0])\n -flex-obsolete-wrap(arguments[1])\n\n // new\n if flex in flex-version\n vendor('flex-flow', arguments, only: webkit ms official)\n\n\norder()\n // obsolete\n if box in flex-version\n vendor('box-ordinal-group', arguments, ignore: ms official)\n\n // new\n if flex in flex-version\n vendor('flex-order', arguments, only: ms)\n vendor('order', arguments, only: webkit official)\n\n\n//\n// 7. Flexibility\n// - http://www.w3.org/TR/css3-flexbox/#flexibility\n//\nflex-grow(growth)\n // obsolete\n if box in flex-version\n vendor('box-flex', growth)\n\n // new\n if flex in flex-version\n vendor('flex-grow', arguments, only: webkit official)\n\nflex-basis()\n if flex in flex-version\n vendor('flex-basis', arguments, only: webkit official)\n\nflex-shrink()\n if flex in flex-version\n vendor('flex-shrink', arguments, only: webkit official)\n\nflex(growth)\n\n // obsolete\n if box in flex-version\n shrink = 1\n\n if none == growth || initial == growth\n // Well known values\n shrink = 0 if none == growth\n growth = 0\n else if is-width(growth) == true\n // Basis is defined as the first parameter\n growth = arguments[1] || 0\n shrink = arguments[2] if 3 <= length(arguments)\n else if arguments[1] && is-width(arguments[1]) == false\n // Growth is first and shrink is second\n shrink = arguments[1]\n\n // Since we can't make the distinction between growing and shrinking in the box model, take\n // the one that provides the most flexibility.\n vendor('box-flex', max(growth, shrink), ignore: ms)\n\n // new\n if flex in flex-version\n vendor('flex', arguments, only: webkit ms official)\n\n\n// converts the justification alignment\n-convert-justify(align)\n if flex-start == align\n return start\n else if flex-end == align\n return end\n else if space-around == align\n return distribute\n else if space-between == align\n return justify\n else\n return align\n\n//\n// 8. Alignment\n// - http://www.w3.org/TR/css3-flexbox/#alignment\n//\njustify-content(align)\n // obsolete\n if box in flex-version\n vendor('box-pack', -convert-justify(align), ignore: ms official)\n\n // new\n if flex in flex-version\n vendor('flex-pack', -convert-justify(align), only: ms)\n vendor('justify-content', align, only: webkit official)\n\nalign-content(align)\n // WARN: Obsolete spec does not allow for adjustment here\n if flex in flex-version\n vendor('flex-line-pack', -convert-justify(align), only: ms)\n vendor('align-content', align, only: webkit official)\n\n// converts alignment from 'flex' to normal value\n-convert-alignment(align)\n if flex-start == align\n return start\n else if flex-end == align\n return end\n else\n return align\n\nalign-items(align)\n // obsolete\n if box in flex-version\n vendor('box-align', -convert-alignment(align), ignore: ms official)\n\n // new\n if flex in flex-version\n vendor('flex-align', -convert-alignment(align), only: ms)\n vendor('align-items', arguments, only: webkit official)\n\nalign-self(align)\n // WARN: Obsolete spec does not allow for overriding alignment on individual items.\n if flex in flex-version\n vendor('align-self', align, only: webkit official)\n vendor('flex-item-align', -convert-alignment(align), only: ms)\n","/*\n * border: <color>\n * border: ...\n */\n\nborder(color, args...)\n if color is a 'color'\n border: 1px solid color args\n else\n border: arguments\n"],"sourceRoot":""}]);
46432
+ ___CSS_LOADER_EXPORT___.push([module.id, ".geojs-map{position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;overflow:hidden}.geojs-map .geo-attribution{position:absolute;right:0;bottom:0;padding-right:5px;cursor:auto;font:11px/1.5 \"Helvetica Neue\",Arial,Helvetica,sans-serif;z-index:1001;background:rgba(255,255,255,0.7);clear:both;display:block;pointer-events:auto}.geojs-map .geo-attribution .geo-attribution-layer{padding-left:5px}.geojs-map .canvas-canvas{display:block;-webkit-transform-origin:0 0;-moz-transform-origin:0 0;-o-transform-origin:0 0;-ms-transform-origin:0 0;transform-origin:0 0}.geojs-map .webgl-canvas{display:block}.geojs-map .geojs-layer{position:absolute;width:100%;height:100%;left:0;top:0;pointer-events:none}.geojs-map .geojs-layer.active:not(.hidden) > *{pointer-events:auto}.geojs-map .geojs-layer.hidden{display:none}.geojs-map .geojs-layer.hidden[renderer=\"webgl\"]{display:inherit}.geojs-map .geo-tile-layer{-webkit-transform-origin:0 0;-moz-transform-origin:0 0;-o-transform-origin:0 0;-ms-transform-origin:0 0;transform-origin:0 0;line-height:0;font-size:0}.geojs-map.annotation-input{cursor:crosshair}.geojs-map.annotation-input.annotation-intersect{cursor:url(" + ___CSS_LOADER_URL_REPLACEMENT_0___ + ") 12 12,crosshair}.geojs-map.annotation-input.annotation-difference{cursor:url(" + ___CSS_LOADER_URL_REPLACEMENT_1___ + ") 12 12,crosshair}.geojs-map.annotation-input.annotation-union{cursor:url(" + ___CSS_LOADER_URL_REPLACEMENT_2___ + ") 12 12,crosshair}.geojs-map.annotation-input.annotation-xor{cursor:url(" + ___CSS_LOADER_URL_REPLACEMENT_3___ + ") 12 12,crosshair}.geojs-map.highlight-focus:after{content:\"\";display:block;position:absolute;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;left:0;top:0;right:0;bottom:0;border:3px solid Highlight;opacity:1;-ms-filter:none;filter:none;-webkit-transition:opacity 0s;-moz-transition:opacity 0s;-o-transition:opacity 0s;-ms-transition:opacity 0s;transition:opacity 0s;visibility:hidden}.geojs-map.highlight-focus:focus:after{visibility:visible;-webkit-transition:opacity 2.5s ease-in;-moz-transition:opacity 2.5s ease-in;-o-transition:opacity 2.5s ease-in;-ms-transition:opacity 2.5s ease-in;transition:opacity 2.5s ease-in;opacity:0;-ms-filter:\"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)\";filter:alpha(opacity=0)}.geo-tile-container{position:absolute}.geo-tile-container.crop{overflow:hidden}", "",{"version":3,"sources":["webpack://./main.styl","webpack://./../node_modules/nib/lib/nib/vendor.styl","webpack://./../node_modules/nib/lib/nib/overflow.styl","webpack://./../node_modules/nib/lib/nib/flex.styl","webpack://./../node_modules/nib/lib/nib/border.styl"],"names":[],"mappings":"AAEA,WACE,iBAAS,CCwCO,wBAAG,CAAH,qBAAG,CAAH,oBAAG,CARN,gBAAG,CChBd,eAAU,CFZZ,4BACE,iBAAS,CACT,OAAM,CACN,QAAO,CACP,iBAAc,CCmfd,WAAO,CDjfP,yDAA8B,CAC9B,YAAQ,CCoeR,gCAAW,CDleX,UAAM,CGMN,aAAS,CHJT,mBAAe,CAEf,mDACE,gBAAa,CAEjB,0BGDE,aAAS,CFqBK,4BAAG,CAAH,yBAAG,CAAH,uBAAG,CAAH,wBAAG,CARN,oBAAG,CDThB,yBGJE,aAAS,CHOX,wBACE,iBAAS,CACT,UAAM,CACN,WAAO,CACP,MAAK,CACL,KAAI,CACJ,mBAAe,CAEb,gDACE,mBAAe,CACnB,+BGjBA,YAAS,CHmBT,iDGnBA,eAAS,CHsBX,2BCDgB,4BAAG,CAAH,yBAAG,CAAH,uBAAG,CAAH,wBAAG,CARN,oBAAG,CDWd,aAAY,CACZ,WAAU,CAEZ,4BC6cE,gBAAO,CD3cP,iDC2cA,8DAAO,CDzcP,kDCycA,8DAAO,CDvcP,6CCucA,8DAAO,CDrcP,2CCqcA,8DAAO,CDjcP,iCACE,UAAQ,CGxCV,aAAS,CH0CP,iBAAS,CCrBG,6BAAG,CAAH,0BAAG,CARN,qBAAG,CD+BZ,MAAK,CACL,KAAI,CACJ,OAAM,CACN,QAAO,CI5DT,0BAAQ,CHmQV,SAAS,CAQH,eAAY,CACZ,WAAQ,CA5OE,6BAAG,CAAH,0BAAG,CAAH,wBAAG,CAAH,yBAAG,CARN,qBAAG,CD0CZ,iBAAW,CACb,uCACE,kBAAW,CCpCC,uCAAG,CAAH,oCAAG,CAAH,kCAAG,CAAH,mCAAG,CARN,+BAAG,CA2OhB,SAAS,CAWH,+DAAyE,CACzE,uBAAiC,CDvMzC,oBACE,iBAAS,CACT,yBEhEE,eAAU","sourcesContent":["@import '~nib/index.styl'\n\n.geojs-map\n position relative\n user-select none\n overflow hidden\n\n .geo-attribution\n position absolute\n right 0\n bottom 0\n padding-right 5px\n cursor auto\n font 11px/1.5 \"Helvetica Neue\", Arial, Helvetica, sans-serif\n z-index 1001\n background rgba(255,255,255,0.7)\n clear both\n display block\n pointer-events auto\n\n .geo-attribution-layer\n padding-left 5px\n\n .canvas-canvas\n display block\n transform-origin 0px 0px\n .webgl-canvas\n display block\n\n .geojs-layer\n position absolute\n width 100%\n height 100%\n left 0\n top 0\n pointer-events none\n &.active:not(.hidden)\n > *\n pointer-events auto\n &.hidden\n display none\n &.hidden[renderer=\"webgl\"]\n display inherit\n\n .geo-tile-layer\n transform-origin 0px 0px\n line-height 0\n font-size 0\n\n &.annotation-input\n cursor crosshair\n &.annotation-intersect\n cursor embedurl(\"./css/cursor-crosshair-intersect.svg\") 12 12,crosshair\n &.annotation-difference\n cursor embedurl(\"./css/cursor-crosshair-difference.svg\") 12 12,crosshair\n &.annotation-union\n cursor embedurl(\"./css/cursor-crosshair-union.svg\") 12 12,crosshair\n &.annotation-xor\n cursor embedurl(\"./css/cursor-crosshair-xor.svg\") 12 12,crosshair\n\n &.highlight-focus\n &:after\n content \"\"\n display block\n position absolute\n box-sizing border-box\n left 0px\n top 0px\n right 0px\n bottom 0px\n // Highlight is technically a css2 color. We may need to specify it\n // explicitly. #3B66A6 seems close\n border 3px solid Highlight\n opacity 1\n transition opacity 0s\n visibility hidden\n &:focus:after\n visibility visible\n transition opacity 2.5s ease-in\n opacity 0\n\n.geo-tile-container\n position absolute\n &.crop\n overflow hidden\n","use('../nodes/vendor-helpers.js')\n@import 'config'\n\n/*\n * Alias \"nowrap\" as \"no-wrap\".\n */\n\nno-wrap = unquote('nowrap')\n\n/*\n * Helper to find out if a given value is a width\n */\n\nis-width(val)\n if auto == val\n return true\n else if val && 'unit' == type(val)\n // Stylus does not short circuit so we need to perform this as a distinct\n // operation to prevent errors\n return '' != unit(val)\n return false\n\n/*\n * Vendor support for the given prop / arguments, optionally specifying the\n * only prefixes to utilize, or those which should be ignored.\n */\n\nvendor(prop, args, only = null, ignore = null, vendor-property = true)\n need_normalize = !vendor-property or prop in ('transition' 'transition-property' 'border-image' 'border-image-slice')\n for prefix in vendor-prefixes\n unless (only and !(prefix in only)) or (ignore and prefix in ignore)\n if official == prefix\n if need_normalize\n {prop}: normalize(prop,('%s' % args))\n else\n {prop}: args\n else\n newprop = prop\n newprop = '-' + prefix + '-' + prop if vendor-property\n\n if need_normalize\n {newprop}: normalize(prop,('%s' % args),prefix)\n else\n {newprop}: args\n/*\n * Vendorize the given value.\n */\n\nvendor-value(arg, only = null, ignore = null)\n prop = current-property[0]\n for prefix in vendor-prefixes\n unless (only and !(prefix in only)) or (ignore and prefix in ignore) or official == prefix\n add-property(prop, '-%s-%s' % (prefix arg))\n arg\n\n/*\n * Vendor \"box-shadow\" support.\n */\n\nbox-shadow()\n vendor('box-shadow', arguments, only: webkit official)\n\n/*\n * Vendor \"user-select\" support.\n */\n\nuser-select()\n vendor('user-select', arguments, only: webkit moz ms official)\n\n/*\n * Vendor \"column-count\" support.\n */\n\ncolumn-count()\n vendor('column-count', arguments, only: webkit moz official)\n\n/*\n * Vendor \"column-gap\" support.\n */\n\ncolumn-gap()\n vendor('column-gap', arguments, only: webkit moz official)\n\n/*\n * Vendor \"column-rule\" support.\n */\n\ncolumn-rule()\n vendor('column-rule', arguments, only: webkit moz official)\n\n/*\n * Vendor \"column-rule-color\" support.\n */\n\ncolumn-rule-color()\n vendor('column-rule-color', arguments, only: webkit moz official)\n\n/*\n * Vendor \"column-rule-width\" support.\n */\n\ncolumn-rule-width()\n vendor('column-rule-width', arguments, only: webkit moz official)\n\n/*\n * Vendor \"column-rule-style\" support.\n */\n\ncolumn-rule-style()\n vendor('column-rule-style', arguments, only: webkit moz official)\n\n/*\n * Vendor \"column-width\" support.\n */\n\ncolumn-width()\n vendor('column-width', arguments, only: webkit moz official)\n\n/*\n * Vendor \"column-span\" support.\n */\n\ncolumn-span()\n vendor('column-span', arguments, only: webkit official)\n\n/*\n * Vendor \"column-fill\" support.\n */\n\ncolumn-fill()\n vendor('column-fill', arguments, only: moz)\n\n/*\n * Legacy syntax support for background-clip and background-origin\n */\n\nlegacy-bg-values(property, args)\n legacy_args = ()\n importance = unquote('')\n for subargs in args\n for arg in subargs\n if arg in (border-box padding-box content-box)\n arg = unquote('border') if arg == border-box\n arg = unquote('padding') if arg == padding-box\n arg = unquote('content') if arg == content-box\n if arg != '!important'\n push(legacy_args,arg)\n else\n importance = !important\n vendor(property, unquote(join(', ',legacy_args)) importance, only: moz webkit)\n\n/*\n * Vendor \"background-clip\" support.\n */\n\nbackground-clip()\n if arguments[0] == text\n vendor('background-clip', arguments, only: webkit)\n else\n legacy-bg-values('background-clip', arguments)\n background-clip: arguments\n\n/*\n * Vendor \"background-origin\" support.\n */\n\nbackground-origin()\n legacy-bg-values('background-origin', arguments)\n background-origin: arguments\n\n/*\n * Vendor \"background-size\" support.\n */\n\nbackground-size()\n vendor('background-size', arguments, only: webkit moz official)\n\n/*\n * Vendor \"transform\" support.\n */\n\ntransform()\n vendor('transform', arguments)\n\n/*\n * Vendor \"transform-origin\" support.\n */\ntransform-origin()\n vendor('transform-origin', arguments)\n\n/*\n * Vendor \"transform-style\" support.\n */\n\ntransform-style()\n vendor('transform-style', arguments)\n\n/*\n * Vendor \"border-image\" support.\n */\n\nborder-image()\n vendor('border-image', arguments, only: webkit moz o official)\n\n/*\n * Vendor \"transition\" support.\n */\n\ntransition()\n vendor('transition', arguments)\n\n/*\n * Vendor \"transition-property\" support.\n */\n\ntransition-property()\n vendor('transition-property', arguments)\n\n/*\n * Vendor \"transition-duration\" support.\n */\n\ntransition-duration()\n vendor('transition-duration', arguments)\n\n/*\n * Vendor \"transition-timing-function\" support.\n */\n\ntransition-timing-function()\n vendor('transition-timing-function', arguments)\n\n/*\n * Vendor \"transition-delay\" support.\n */\n\ntransition-delay()\n vendor('transition-delay', arguments)\n\n/*\n * Vendor \"backface-visibility\" support.\n */\n\nbackface-visibility()\n vendor('backface-visibility', arguments, only: webkit moz ms official)\n\n/*\n * Vendor \"perspective\" support.\n */\n\nperspective()\n if mixin\n vendor('perspective', arguments, only: webkit moz ms official)\n else\n 'perspective(%s)' % arguments\n\n/*\n * Vendor \"perspective-origin\" support.\n */\n\nperspective-origin()\n vendor('perspective-origin', arguments, only: webkit moz ms official)\n\n/*\n * Opacity with conditional IE support.\n */\n\nopacity(n, args...)\n opacity: n args\n if support-for-ie\n if n == inherit or n == initial\n -ms-filter: n args\n filter: n args\n else\n val = round(n * 100)\n if val == 100\n -ms-filter: none args\n filter: none args\n else\n -ms-filter: '\"progid:DXImageTransform.Microsoft.Alpha(Opacity=%s)\"' % val args\n filter: 'alpha(opacity=%s)' % val args\n\n/*\n * Vendor \"text-size-adjust\"\n */\n\ntext-size-adjust()\n vendor('text-size-adjust', arguments)\n\n/*\n * Alias the \"white-space\" property.\n */\n\nwhitespace()\n white-space: arguments\n\n/*\n * Vendor \"box-sizing\" support.\n */\n\nbox-sizing()\n vendor('box-sizing', arguments, only: webkit moz official)\n\n/*\n * Vendor \"box-orient\" support.\n */\n\nbox-orient()\n vendor('box-orient', arguments, only: webkit moz official)\n\n/*\n * Vendor \"box-flex-group\" support.\n */\n\nbox-flex-group()\n vendor('box-flex-group', arguments, only: webkit moz official)\n\n/*\n * Vendor \"box-ordinal-group\" support.\n */\n\nbox-ordinal-group()\n vendor('box-ordinal-group', arguments, only: webkit moz ms official)\n\n\n/*\n * Vendor \"box-align\" support.\n */\n\nbox-align()\n vendor('box-align', arguments, only: webkit moz ms official)\n\n/*\n * Vendor \"box-pack\" support.\n */\n\nbox-pack()\n vendor('box-pack', arguments, only: webkit moz ms official)\n\n/*\n * Vendor \"box-direction\" support.\n */\n\nbox-direction()\n vendor('box-direction', arguments, only: webkit moz ms official)\n\n/*\n * Vendor \"animation\" support.\n */\n\nanimation()\n vendor('animation', arguments)\n\n\n/*\n * Vendor \"animation-name\" support.\n */\n\nanimation-name()\n vendor('animation-name', arguments)\n\n/*\n * Vendor \"animation-duration\" support.\n */\n\nanimation-duration()\n vendor('animation-duration', arguments)\n\n/*\n * Vendor \"animation-delay\" support.\n */\n\nanimation-delay()\n vendor('animation-delay', arguments)\n\n/*\n * Vendor \"animation-direction\" support.\n */\n\nanimation-direction()\n vendor('animation-direction', arguments)\n\n/*\n * Vendor \"animation-iteration-count\" support.\n */\n\nanimation-iteration-count()\n vendor('animation-iteration-count', arguments)\n\n/*\n * Vendor \"animation-timing-function\" support.\n */\n\nanimation-timing-function()\n vendor('animation-timing-function', arguments)\n\n/*\n * Vendor \"animation-play-state\" support.\n */\n\nanimation-play-state()\n vendor('animation-play-state', arguments)\n\n/*\n * Vendor \"animation-fill-mode\" support.\n */\n\nanimation-fill-mode()\n vendor('animation-fill-mode', arguments)\n\n/*\n * Vendor \"hyphens\" support.\n */\n\nhyphens()\n vendor('hyphens', arguments, only: webkit moz ms official)\n\n/*\n * Vendor \"appearance\" support.\n */\n\nappearance()\n vendor('appearance', arguments, only: webkit moz official)\n\n/*\n * Vendor \"tab-size\" support.\n */\n\ntab-size()\n vendor('tab-size', arguments, only: moz o official)\n\n/*\n * Vendor \"overflow-scrolling\" support.\n */\n\noverflow-scrolling()\n vendor('overflow-scrolling', arguments, only: webkit official)\n\n/*\n * Vendor \"text-overflow\" support, , -o- for opera 9.* - 10.*\n */\n\ntext-overflow()\n vendor('text-overflow', arguments, only: official o)\n\n/*\n * Vendor \"text-size-adjust\" support.\n */\ntext-size-adjust()\n vendor('text-size-adjust', arguments, only: official webkit ms)\n\n/*\n * Vendor \"font-smoothing\" support, webkit only.\n */\nfont-smoothing()\n vendor('font-smoothing', arguments, only: webkit)\n\n\n/**\n * Vendor input-placeholder/placeholder support.\n *\n * Examples:\n * // Default syntax\n * body\n * placeholder(color #333, font-weight normal)\n *\n * // The comma is important\n * .placeholder-red\n * placeholder(color red,)\n *\n * // We can pass a function\n * green-placeholder()\n * color green\n * .placeholder-green\n * placeholder(green-placeholder)\n *\n * // We can pass a hash\n * textarea\n * placeholder((font-style italic) (font-weight bold) (padding '4px 10px'))\n */\nplaceholder()\n for v in ':-webkit-input' '-moz' ':-moz' '-ms-input'\n &:{v}-placeholder\n for pair in arguments\n if typeof(pair) == 'function'\n pair()\n else if pair is not null && pair[0] is not null\n {pair[0]}: type(pair[1]) == 'string' ? s(pair[1]) : pair[1]\ninput-placeholder = placeholder\n\n/*\n * Vendor background support (gradients).\n */\n\nbackground()\n if match('-gradient\\(', ''+arguments)\n vendor('background', arguments, vendor-property: false)\n else\n background arguments\n\nbackground-image()\n if match('-gradient\\(', ''+arguments)\n vendor('background-image', arguments, vendor-property: false)\n else\n background-image arguments\n\ncursor()\n if match('-gradient\\(', ''+arguments)\n vendor('cursor', arguments, vendor-property: false)\n else\n cursor arguments\n\nlist-style()\n if match('-gradient\\(', ''+arguments)\n vendor('list-style', arguments, vendor-property: false)\n else\n list-style arguments\n\nlist-style-image()\n if match('-gradient\\(', ''+arguments)\n vendor('list-style-image', arguments, vendor-property: false)\n else\n list-style-image arguments\n","/*\n * Overflow utility. Maps to regular overflow, and adds an ellipsis value.\n *\n * Synopsis:\n *\n * overflow: <type>\n *\n * Examples:\n *\n * overflow: auto\n * overflow: hidden\n * overflow: ellipsis\n *\n */\n\noverflow()\n if arguments[0] == ellipsis\n ellipsis()\n else\n overflow: arguments\n","/*\n * Vendor \"display: flex\" support with fallback to obsolete versions.\n */\n\nflex-version ?= box flex\n\n//\n// 1. Display values\n// - http://www.w3.org/TR/css3-flexbox/#flex-containers\n//\ndisplay(type, args...)\n if flex == type || inline-flex == type\n if box in flex-version\n if flex == type\n display: -ms-flexbox args\n display: vendor-value(box args, only: moz webkit)\n else\n display: -ms-inline-flexbox args\n display: vendor-value(inline-box args, only: moz webkit)\n if flex in flex-version\n display: vendor-value(arguments, only: webkit official) // overwrites old webkit\n else\n display: arguments\n\n/*\n * New syntax for browsers like Google Chrome.\n * Plus a translation to the old syntax, if possible.\n */\n\n\n//\n// 5. Ordering and Orientation\n// - http://www.w3.org/TR/css3-flexbox/#ordering-and-orientation\n//\n-flex-obsolete-direction(direction)\n if box in flex-version\n if row-reverse == direction || column-reverse == direction\n vendor('box-direction', reverse, ignore: ms official)\n\n if row == direction || row-reverse == direction\n vendor('box-orient', horizontal, ignore: ms official)\n else if column == direction || column-reverse == direction\n vendor('box-orient', vertical, ignore: ms official)\n\n-flex-obsolete-wrap(value)\n if box in flex-version\n // WARN: wrap-reverse does not have a box equivalent. This will render in different manners\n // on box vs. flex values.\n if 'wrap' == value || wrap-reverse == value\n vendor('box-lines', multiple, ignore: ms official)\n else if nowrap == value\n vendor('box-lines', single, ignore: ms official)\n\nflex-direction(direction)\n // obsolete\n -flex-obsolete-direction(direction)\n\n // new\n if flex in flex-version\n vendor('flex-direction', arguments, only: webkit ms official)\n\nflex-wrap(value)\n // obsolete\n -flex-obsolete-wrap(value)\n\n if flex in flex-version\n vendor('flex-wrap', arguments, only: webkit ms official)\n\nflex-flow()\n // obsolete\n -flex-obsolete-direction(arguments[0])\n -flex-obsolete-direction(arguments[1])\n -flex-obsolete-wrap(arguments[0])\n -flex-obsolete-wrap(arguments[1])\n\n // new\n if flex in flex-version\n vendor('flex-flow', arguments, only: webkit ms official)\n\n\norder()\n // obsolete\n if box in flex-version\n vendor('box-ordinal-group', arguments, ignore: ms official)\n\n // new\n if flex in flex-version\n vendor('flex-order', arguments, only: ms)\n vendor('order', arguments, only: webkit official)\n\n\n//\n// 7. Flexibility\n// - http://www.w3.org/TR/css3-flexbox/#flexibility\n//\nflex-grow(growth)\n // obsolete\n if box in flex-version\n vendor('box-flex', growth)\n\n // new\n if flex in flex-version\n vendor('flex-grow', arguments, only: webkit official)\n\nflex-basis()\n if flex in flex-version\n vendor('flex-basis', arguments, only: webkit official)\n\nflex-shrink()\n if flex in flex-version\n vendor('flex-shrink', arguments, only: webkit official)\n\nflex(growth)\n\n // obsolete\n if box in flex-version\n shrink = 1\n\n if none == growth || initial == growth\n // Well known values\n shrink = 0 if none == growth\n growth = 0\n else if is-width(growth) == true\n // Basis is defined as the first parameter\n growth = arguments[1] || 0\n shrink = arguments[2] if 3 <= length(arguments)\n else if arguments[1] && is-width(arguments[1]) == false\n // Growth is first and shrink is second\n shrink = arguments[1]\n\n // Since we can't make the distinction between growing and shrinking in the box model, take\n // the one that provides the most flexibility.\n vendor('box-flex', max(growth, shrink), ignore: ms)\n\n // new\n if flex in flex-version\n vendor('flex', arguments, only: webkit ms official)\n\n\n// converts the justification alignment\n-convert-justify(align)\n if flex-start == align\n return start\n else if flex-end == align\n return end\n else if space-around == align\n return distribute\n else if space-between == align\n return justify\n else\n return align\n\n//\n// 8. Alignment\n// - http://www.w3.org/TR/css3-flexbox/#alignment\n//\njustify-content(align)\n // obsolete\n if box in flex-version\n vendor('box-pack', -convert-justify(align), ignore: ms official)\n\n // new\n if flex in flex-version\n vendor('flex-pack', -convert-justify(align), only: ms)\n vendor('justify-content', align, only: webkit official)\n\nalign-content(align)\n // WARN: Obsolete spec does not allow for adjustment here\n if flex in flex-version\n vendor('flex-line-pack', -convert-justify(align), only: ms)\n vendor('align-content', align, only: webkit official)\n\n// converts alignment from 'flex' to normal value\n-convert-alignment(align)\n if flex-start == align\n return start\n else if flex-end == align\n return end\n else\n return align\n\nalign-items(align)\n // obsolete\n if box in flex-version\n vendor('box-align', -convert-alignment(align), ignore: ms official)\n\n // new\n if flex in flex-version\n vendor('flex-align', -convert-alignment(align), only: ms)\n vendor('align-items', arguments, only: webkit official)\n\nalign-self(align)\n // WARN: Obsolete spec does not allow for overriding alignment on individual items.\n if flex in flex-version\n vendor('align-self', align, only: webkit official)\n vendor('flex-item-align', -convert-alignment(align), only: ms)\n","/*\n * border: <color>\n * border: ...\n */\n\nborder(color, args...)\n if color is a 'color'\n border: 1px solid color args\n else\n border: arguments\n"],"sourceRoot":""}]);
45285
46433
  // Exports
45286
46434
  /* harmony default export */ __webpack_exports__["Z"] = (___CSS_LOADER_EXPORT___);
45287
46435
 
@@ -45437,6 +46585,42 @@ module.exports = function (cssWithMappingToString) {
45437
46585
 
45438
46586
  /***/ }),
45439
46587
 
46588
+ /***/ 1678:
46589
+ /***/ (function(module) {
46590
+
46591
+ "use strict";
46592
+
46593
+
46594
+ module.exports = function (url, options) {
46595
+ if (!options) {
46596
+ options = {};
46597
+ }
46598
+
46599
+ if (!url) {
46600
+ return url;
46601
+ }
46602
+
46603
+ url = String(url.__esModule ? url.default : url); // If url is already wrapped in quotes, remove them
46604
+
46605
+ if (/^['"].*['"]$/.test(url)) {
46606
+ url = url.slice(1, -1);
46607
+ }
46608
+
46609
+ if (options.hash) {
46610
+ url += options.hash;
46611
+ } // Should url be wrapped?
46612
+ // See https://drafts.csswg.org/css-values-3/#urls
46613
+
46614
+
46615
+ if (/["'() \t\n]|(%20)/.test(url) || options.needQuotes) {
46616
+ return "\"".concat(url.replace(/"/g, '\\"').replace(/\n/g, "\\n"), "\"");
46617
+ }
46618
+
46619
+ return url;
46620
+ };
46621
+
46622
+ /***/ }),
46623
+
45440
46624
  /***/ 559:
45441
46625
  /***/ (function(module) {
45442
46626
 
@@ -74480,6 +75664,1671 @@ var __WEBPACK_AMD_DEFINE_RESULT__;/*global define:false */
74480
75664
  }) (typeof window !== 'undefined' ? window : null, typeof window !== 'undefined' ? document : null);
74481
75665
 
74482
75666
 
75667
+ /***/ }),
75668
+
75669
+ /***/ 3291:
75670
+ /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
75671
+
75672
+ /*
75673
+ * @copyright 2016 Sean Connelly (@voidqk), http://syntheti.cc
75674
+ * @license MIT
75675
+ * @preserve Project Home: https://github.com/voidqk/polybooljs
75676
+ */
75677
+
75678
+ var BuildLog = __webpack_require__(1009);
75679
+ var Epsilon = __webpack_require__(1835);
75680
+ var Intersecter = __webpack_require__(7671);
75681
+ var SegmentChainer = __webpack_require__(9048);
75682
+ var SegmentSelector = __webpack_require__(571);
75683
+ var GeoJSON = __webpack_require__(3928);
75684
+
75685
+ var buildLog = false;
75686
+ var epsilon = Epsilon();
75687
+
75688
+ var PolyBool;
75689
+ PolyBool = {
75690
+ // getter/setter for buildLog
75691
+ buildLog: function(bl){
75692
+ if (bl === true)
75693
+ buildLog = BuildLog();
75694
+ else if (bl === false)
75695
+ buildLog = false;
75696
+ return buildLog === false ? false : buildLog.list;
75697
+ },
75698
+ // getter/setter for epsilon
75699
+ epsilon: function(v){
75700
+ return epsilon.epsilon(v);
75701
+ },
75702
+
75703
+ // core API
75704
+ segments: function(poly){
75705
+ var i = Intersecter(true, epsilon, buildLog);
75706
+ poly.regions.forEach(i.addRegion);
75707
+ return {
75708
+ segments: i.calculate(poly.inverted),
75709
+ inverted: poly.inverted
75710
+ };
75711
+ },
75712
+ combine: function(segments1, segments2){
75713
+ var i3 = Intersecter(false, epsilon, buildLog);
75714
+ return {
75715
+ combined: i3.calculate(
75716
+ segments1.segments, segments1.inverted,
75717
+ segments2.segments, segments2.inverted
75718
+ ),
75719
+ inverted1: segments1.inverted,
75720
+ inverted2: segments2.inverted
75721
+ };
75722
+ },
75723
+ selectUnion: function(combined){
75724
+ return {
75725
+ segments: SegmentSelector.union(combined.combined, buildLog),
75726
+ inverted: combined.inverted1 || combined.inverted2
75727
+ }
75728
+ },
75729
+ selectIntersect: function(combined){
75730
+ return {
75731
+ segments: SegmentSelector.intersect(combined.combined, buildLog),
75732
+ inverted: combined.inverted1 && combined.inverted2
75733
+ }
75734
+ },
75735
+ selectDifference: function(combined){
75736
+ return {
75737
+ segments: SegmentSelector.difference(combined.combined, buildLog),
75738
+ inverted: combined.inverted1 && !combined.inverted2
75739
+ }
75740
+ },
75741
+ selectDifferenceRev: function(combined){
75742
+ return {
75743
+ segments: SegmentSelector.differenceRev(combined.combined, buildLog),
75744
+ inverted: !combined.inverted1 && combined.inverted2
75745
+ }
75746
+ },
75747
+ selectXor: function(combined){
75748
+ return {
75749
+ segments: SegmentSelector.xor(combined.combined, buildLog),
75750
+ inverted: combined.inverted1 !== combined.inverted2
75751
+ }
75752
+ },
75753
+ polygon: function(segments){
75754
+ return {
75755
+ regions: SegmentChainer(segments.segments, epsilon, buildLog),
75756
+ inverted: segments.inverted
75757
+ };
75758
+ },
75759
+
75760
+ // GeoJSON converters
75761
+ polygonFromGeoJSON: function(geojson){
75762
+ return GeoJSON.toPolygon(PolyBool, geojson);
75763
+ },
75764
+ polygonToGeoJSON: function(poly){
75765
+ return GeoJSON.fromPolygon(PolyBool, epsilon, poly);
75766
+ },
75767
+
75768
+ // helper functions for common operations
75769
+ union: function(poly1, poly2){
75770
+ return operate(poly1, poly2, PolyBool.selectUnion);
75771
+ },
75772
+ intersect: function(poly1, poly2){
75773
+ return operate(poly1, poly2, PolyBool.selectIntersect);
75774
+ },
75775
+ difference: function(poly1, poly2){
75776
+ return operate(poly1, poly2, PolyBool.selectDifference);
75777
+ },
75778
+ differenceRev: function(poly1, poly2){
75779
+ return operate(poly1, poly2, PolyBool.selectDifferenceRev);
75780
+ },
75781
+ xor: function(poly1, poly2){
75782
+ return operate(poly1, poly2, PolyBool.selectXor);
75783
+ }
75784
+ };
75785
+
75786
+ function operate(poly1, poly2, selector){
75787
+ var seg1 = PolyBool.segments(poly1);
75788
+ var seg2 = PolyBool.segments(poly2);
75789
+ var comb = PolyBool.combine(seg1, seg2);
75790
+ var seg3 = selector(comb);
75791
+ return PolyBool.polygon(seg3);
75792
+ }
75793
+
75794
+ if (typeof window === 'object')
75795
+ window.PolyBool = PolyBool;
75796
+
75797
+ module.exports = PolyBool;
75798
+
75799
+
75800
+ /***/ }),
75801
+
75802
+ /***/ 1009:
75803
+ /***/ (function(module) {
75804
+
75805
+ // (c) Copyright 2016, Sean Connelly (@voidqk), http://syntheti.cc
75806
+ // MIT License
75807
+ // Project Home: https://github.com/voidqk/polybooljs
75808
+
75809
+ //
75810
+ // used strictly for logging the processing of the algorithm... only useful if you intend on
75811
+ // looking under the covers (for pretty UI's or debugging)
75812
+ //
75813
+
75814
+ function BuildLog(){
75815
+ var my;
75816
+ var nextSegmentId = 0;
75817
+ var curVert = false;
75818
+
75819
+ function push(type, data){
75820
+ my.list.push({
75821
+ type: type,
75822
+ data: data ? JSON.parse(JSON.stringify(data)) : void 0
75823
+ });
75824
+ return my;
75825
+ }
75826
+
75827
+ my = {
75828
+ list: [],
75829
+ segmentId: function(){
75830
+ return nextSegmentId++;
75831
+ },
75832
+ checkIntersection: function(seg1, seg2){
75833
+ return push('check', { seg1: seg1, seg2: seg2 });
75834
+ },
75835
+ segmentChop: function(seg, end){
75836
+ push('div_seg', { seg: seg, pt: end });
75837
+ return push('chop', { seg: seg, pt: end });
75838
+ },
75839
+ statusRemove: function(seg){
75840
+ return push('pop_seg', { seg: seg });
75841
+ },
75842
+ segmentUpdate: function(seg){
75843
+ return push('seg_update', { seg: seg });
75844
+ },
75845
+ segmentNew: function(seg, primary){
75846
+ return push('new_seg', { seg: seg, primary: primary });
75847
+ },
75848
+ segmentRemove: function(seg){
75849
+ return push('rem_seg', { seg: seg });
75850
+ },
75851
+ tempStatus: function(seg, above, below){
75852
+ return push('temp_status', { seg: seg, above: above, below: below });
75853
+ },
75854
+ rewind: function(seg){
75855
+ return push('rewind', { seg: seg });
75856
+ },
75857
+ status: function(seg, above, below){
75858
+ return push('status', { seg: seg, above: above, below: below });
75859
+ },
75860
+ vert: function(x){
75861
+ if (x === curVert)
75862
+ return my;
75863
+ curVert = x;
75864
+ return push('vert', { x: x });
75865
+ },
75866
+ log: function(data){
75867
+ if (typeof data !== 'string')
75868
+ data = JSON.stringify(data, false, ' ');
75869
+ return push('log', { txt: data });
75870
+ },
75871
+ reset: function(){
75872
+ return push('reset');
75873
+ },
75874
+ selected: function(segs){
75875
+ return push('selected', { segs: segs });
75876
+ },
75877
+ chainStart: function(seg){
75878
+ return push('chain_start', { seg: seg });
75879
+ },
75880
+ chainRemoveHead: function(index, pt){
75881
+ return push('chain_rem_head', { index: index, pt: pt });
75882
+ },
75883
+ chainRemoveTail: function(index, pt){
75884
+ return push('chain_rem_tail', { index: index, pt: pt });
75885
+ },
75886
+ chainNew: function(pt1, pt2){
75887
+ return push('chain_new', { pt1: pt1, pt2: pt2 });
75888
+ },
75889
+ chainMatch: function(index){
75890
+ return push('chain_match', { index: index });
75891
+ },
75892
+ chainClose: function(index){
75893
+ return push('chain_close', { index: index });
75894
+ },
75895
+ chainAddHead: function(index, pt){
75896
+ return push('chain_add_head', { index: index, pt: pt });
75897
+ },
75898
+ chainAddTail: function(index, pt){
75899
+ return push('chain_add_tail', { index: index, pt: pt, });
75900
+ },
75901
+ chainConnect: function(index1, index2){
75902
+ return push('chain_con', { index1: index1, index2: index2 });
75903
+ },
75904
+ chainReverse: function(index){
75905
+ return push('chain_rev', { index: index });
75906
+ },
75907
+ chainJoin: function(index1, index2){
75908
+ return push('chain_join', { index1: index1, index2: index2 });
75909
+ },
75910
+ done: function(){
75911
+ return push('done');
75912
+ }
75913
+ };
75914
+ return my;
75915
+ }
75916
+
75917
+ module.exports = BuildLog;
75918
+
75919
+
75920
+ /***/ }),
75921
+
75922
+ /***/ 1835:
75923
+ /***/ (function(module) {
75924
+
75925
+ // (c) Copyright 2016, Sean Connelly (@voidqk), http://syntheti.cc
75926
+ // MIT License
75927
+ // Project Home: https://github.com/voidqk/polybooljs
75928
+
75929
+ //
75930
+ // provides the raw computation functions that takes epsilon into account
75931
+ //
75932
+ // zero is defined to be between (-epsilon, epsilon) exclusive
75933
+ //
75934
+
75935
+ function Epsilon(eps){
75936
+ if (typeof eps !== 'number')
75937
+ eps = 0.0000000001; // sane default? sure why not
75938
+ var my = {
75939
+ epsilon: function(v){
75940
+ if (typeof v === 'number')
75941
+ eps = v;
75942
+ return eps;
75943
+ },
75944
+ pointAboveOrOnLine: function(pt, left, right){
75945
+ var Ax = left[0];
75946
+ var Ay = left[1];
75947
+ var Bx = right[0];
75948
+ var By = right[1];
75949
+ var Cx = pt[0];
75950
+ var Cy = pt[1];
75951
+ var ABx = Bx - Ax;
75952
+ var ABy = By - Ay;
75953
+ var AB = Math.sqrt(ABx * ABx + ABy * ABy);
75954
+ // algebraic distance of 'pt' to ('left', 'right') line is:
75955
+ // [ABx * (Cy - Ay) - ABy * (Cx - Ax)] / AB
75956
+ return ABx * (Cy - Ay) - ABy * (Cx - Ax) >= -eps * AB;
75957
+ },
75958
+ pointBetween: function(p, left, right){
75959
+ // p must be collinear with left->right
75960
+ // returns false if p == left, p == right, or left == right
75961
+ if (my.pointsSame(p, left) || my.pointsSame(p, right)) return false;
75962
+ var d_py_ly = p[1] - left[1];
75963
+ var d_rx_lx = right[0] - left[0];
75964
+ var d_px_lx = p[0] - left[0];
75965
+ var d_ry_ly = right[1] - left[1];
75966
+
75967
+ var dot = d_px_lx * d_rx_lx + d_py_ly * d_ry_ly;
75968
+ // dot < 0 is p is to the left of 'left'
75969
+ if (dot < 0) return false;
75970
+ var sqlen = d_rx_lx * d_rx_lx + d_ry_ly * d_ry_ly;
75971
+ // dot <= sqlen is p is to the left of 'right'
75972
+ return dot <= sqlen;
75973
+ },
75974
+ pointsSameX: function(p1, p2){
75975
+ return Math.abs(p1[0] - p2[0]) < eps;
75976
+ },
75977
+ pointsSameY: function(p1, p2){
75978
+ return Math.abs(p1[1] - p2[1]) < eps;
75979
+ },
75980
+ pointsSame: function(p1, p2){
75981
+ return my.pointsSameX(p1, p2) && my.pointsSameY(p1, p2);
75982
+ },
75983
+ pointsCompare: function(p1, p2){
75984
+ // returns -1 if p1 is smaller, 1 if p2 is smaller, 0 if equal
75985
+ if (my.pointsSameX(p1, p2))
75986
+ return my.pointsSameY(p1, p2) ? 0 : (p1[1] < p2[1] ? -1 : 1);
75987
+ return p1[0] < p2[0] ? -1 : 1;
75988
+ },
75989
+ pointsCollinear: function(pt1, pt2, pt3){
75990
+ // does pt1->pt2->pt3 make a straight line?
75991
+ // essentially this is just checking to see if the slope(pt1->pt2) === slope(pt2->pt3)
75992
+ // if slopes are equal, then they must be collinear, because they share pt2
75993
+ var dx1 = pt1[0] - pt2[0];
75994
+ var dy1 = pt1[1] - pt2[1];
75995
+ var dx2 = pt2[0] - pt3[0];
75996
+ var dy2 = pt2[1] - pt3[1];
75997
+ var n1 = Math.sqrt(dx1 * dx1 + dy1 * dy1);
75998
+ var n2 = Math.sqrt(dx2 * dx2 + dy2 * dy2);
75999
+ // Assuming det(u, v) = 0, we have:
76000
+ // |det(u + u_err, v + v_err)| = |det(u + u_err, v + v_err) - det(u,v)|
76001
+ // =|det(u, v_err) + det(u_err. v) + det(u_err, v_err)|
76002
+ // <= |det(u, v_err)| + |det(u_err, v)| + |det(u_err, v_err)|
76003
+ // <= N(u)N(v_err) + N(u_err)N(v) + N(u_err)N(v_err)
76004
+ // <= eps * (N(u) + N(v) + eps)
76005
+ // We have N(u) ~ N(u + u_err) and N(v) ~ N(v + v_err).
76006
+ // Assuming eps << N(u) and eps << N(v), we end with:
76007
+ // |det(u + u_err, v + v_err)| <= eps * (N(u + u_err) + N(v + v_err))
76008
+ return Math.abs(dx1 * dy2 - dx2 * dy1) <= eps * (n1 + n2);
76009
+ },
76010
+ linesIntersect: function(a0, a1, b0, b1){
76011
+ // returns false if the lines are coincident (e.g., parallel or on top of each other)
76012
+ //
76013
+ // returns an object if the lines intersect:
76014
+ // {
76015
+ // pt: [x, y], where the intersection point is at
76016
+ // alongA: where intersection point is along A,
76017
+ // alongB: where intersection point is along B
76018
+ // }
76019
+ //
76020
+ // alongA and alongB will each be one of: -2, -1, 0, 1, 2
76021
+ //
76022
+ // with the following meaning:
76023
+ //
76024
+ // -2 intersection point is before segment's first point
76025
+ // -1 intersection point is directly on segment's first point
76026
+ // 0 intersection point is between segment's first and second points (exclusive)
76027
+ // 1 intersection point is directly on segment's second point
76028
+ // 2 intersection point is after segment's second point
76029
+ var adx = a1[0] - a0[0];
76030
+ var ady = a1[1] - a0[1];
76031
+ var bdx = b1[0] - b0[0];
76032
+ var bdy = b1[1] - b0[1];
76033
+
76034
+ var axb = adx * bdy - ady * bdx;
76035
+ var n1 = Math.sqrt(adx * adx + ady * ady);
76036
+ var n2 = Math.sqrt(bdx * bdx + bdy * bdy);
76037
+ if (Math.abs(axb) <= eps * (n1 + n2))
76038
+ return false; // lines are coincident
76039
+
76040
+ var dx = a0[0] - b0[0];
76041
+ var dy = a0[1] - b0[1];
76042
+
76043
+ var A = (bdx * dy - bdy * dx) / axb;
76044
+ var B = (adx * dy - ady * dx) / axb;
76045
+ var pt = [
76046
+ a0[0] + A * adx,
76047
+ a0[1] + A * ady
76048
+ ];
76049
+
76050
+ var ret = {
76051
+ alongA: 0,
76052
+ alongB: 0,
76053
+ pt: pt
76054
+ };
76055
+
76056
+ // categorize where intersection point is along A and B
76057
+ if (my.pointsSame(pt, a0))
76058
+ ret.alongA = -1;
76059
+ else if (my.pointsSame(pt, a1))
76060
+ ret.alongA = 1;
76061
+ else if (A < 0)
76062
+ ret.alongA = -2;
76063
+ else if (A > 1)
76064
+ ret.alongA = 2;
76065
+
76066
+ if (my.pointsSame(pt, b0))
76067
+ ret.alongB = -1;
76068
+ else if (my.pointsSame(pt, b1))
76069
+ ret.alongB = 1;
76070
+ else if (B < 0)
76071
+ ret.alongB = -2;
76072
+ else if (B > 1)
76073
+ ret.alongB = 2;
76074
+
76075
+ return ret;
76076
+ },
76077
+ pointInsideRegion: function(pt, region){
76078
+ var x = pt[0];
76079
+ var y = pt[1];
76080
+ var last_x = region[region.length - 1][0];
76081
+ var last_y = region[region.length - 1][1];
76082
+ var inside = false;
76083
+ for (var i = 0; i < region.length; i++){
76084
+ var curr_x = region[i][0];
76085
+ var curr_y = region[i][1];
76086
+
76087
+ // if y is between curr_y and last_y, and
76088
+ // x is to the right of the boundary created by the line
76089
+ if ((curr_y - y > eps) != (last_y - y > eps) &&
76090
+ (last_x - curr_x) * (y - curr_y) / (last_y - curr_y) + curr_x - x > eps)
76091
+ inside = !inside
76092
+
76093
+ last_x = curr_x;
76094
+ last_y = curr_y;
76095
+ }
76096
+ return inside;
76097
+ }
76098
+ };
76099
+ return my;
76100
+ }
76101
+
76102
+ module.exports = Epsilon;
76103
+
76104
+
76105
+ /***/ }),
76106
+
76107
+ /***/ 3928:
76108
+ /***/ (function(module) {
76109
+
76110
+ // (c) Copyright 2017, Sean Connelly (@voidqk), http://syntheti.cc
76111
+ // MIT License
76112
+ // Project Home: https://github.com/voidqk/polybooljs
76113
+
76114
+ //
76115
+ // convert between PolyBool polygon format and GeoJSON formats (Polygon and MultiPolygon)
76116
+ //
76117
+
76118
+ var GeoJSON = {
76119
+ // convert a GeoJSON object to a PolyBool polygon
76120
+ toPolygon: function(PolyBool, geojson){
76121
+
76122
+ // converts list of LineString's to segments
76123
+ function GeoPoly(coords){
76124
+ // check for empty coords
76125
+ if (coords.length <= 0)
76126
+ return PolyBool.segments({ inverted: false, regions: [] });
76127
+
76128
+ // convert LineString to segments
76129
+ function LineString(ls){
76130
+ // remove tail which should be the same as head
76131
+ var reg = ls.slice(0, ls.length - 1);
76132
+ return PolyBool.segments({ inverted: false, regions: [reg] });
76133
+ }
76134
+
76135
+ // the first LineString is considered the outside
76136
+ var out = LineString(coords[0]);
76137
+
76138
+ // the rest of the LineStrings are considered interior holes, so subtract them from the
76139
+ // current result
76140
+ for (var i = 1; i < coords.length; i++)
76141
+ out = PolyBool.selectDifference(PolyBool.combine(out, LineString(coords[i])));
76142
+
76143
+ return out;
76144
+ }
76145
+
76146
+ if (geojson.type === 'Polygon'){
76147
+ // single polygon, so just convert it and we're done
76148
+ return PolyBool.polygon(GeoPoly(geojson.coordinates));
76149
+ }
76150
+ else if (geojson.type === 'MultiPolygon'){
76151
+ // multiple polygons, so union all the polygons together
76152
+ var out = PolyBool.segments({ inverted: false, regions: [] });
76153
+ for (var i = 0; i < geojson.coordinates.length; i++)
76154
+ out = PolyBool.selectUnion(PolyBool.combine(out, GeoPoly(geojson.coordinates[i])));
76155
+ return PolyBool.polygon(out);
76156
+ }
76157
+ throw new Error('PolyBool: Cannot convert GeoJSON object to PolyBool polygon');
76158
+ },
76159
+
76160
+ // convert a PolyBool polygon to a GeoJSON object
76161
+ fromPolygon: function(PolyBool, eps, poly){
76162
+ // make sure out polygon is clean
76163
+ poly = PolyBool.polygon(PolyBool.segments(poly));
76164
+
76165
+ // test if r1 is inside r2
76166
+ function regionInsideRegion(r1, r2){
76167
+ // we're guaranteed no lines intersect (because the polygon is clean), but a vertex
76168
+ // could be on the edge -- so we just average pt[0] and pt[1] to produce a point on the
76169
+ // edge of the first line, which cannot be on an edge
76170
+ return eps.pointInsideRegion([
76171
+ (r1[0][0] + r1[1][0]) * 0.5,
76172
+ (r1[0][1] + r1[1][1]) * 0.5
76173
+ ], r2);
76174
+ }
76175
+
76176
+ // calculate inside heirarchy
76177
+ //
76178
+ // _____________________ _______ roots -> A -> F
76179
+ // | A | | F | | |
76180
+ // | _______ _______ | | ___ | +-- B +-- G
76181
+ // | | B | | C | | | | | | | |
76182
+ // | | ___ | | ___ | | | | | | | +-- D
76183
+ // | | | D | | | | E | | | | | G | | |
76184
+ // | | |___| | | |___| | | | | | | +-- C
76185
+ // | |_______| |_______| | | |___| | |
76186
+ // |_____________________| |_______| +-- E
76187
+
76188
+ function newNode(region){
76189
+ return {
76190
+ region: region,
76191
+ children: []
76192
+ };
76193
+ }
76194
+
76195
+ var roots = newNode(null);
76196
+
76197
+ function addChild(root, region){
76198
+ // first check if we're inside any children
76199
+ for (var i = 0; i < root.children.length; i++){
76200
+ var child = root.children[i];
76201
+ if (regionInsideRegion(region, child.region)){
76202
+ // we are, so insert inside them instead
76203
+ addChild(child, region);
76204
+ return;
76205
+ }
76206
+ }
76207
+
76208
+ // not inside any children, so check to see if any children are inside us
76209
+ var node = newNode(region);
76210
+ for (var i = 0; i < root.children.length; i++){
76211
+ var child = root.children[i];
76212
+ if (regionInsideRegion(child.region, region)){
76213
+ // oops... move the child beneath us, and remove them from root
76214
+ node.children.push(child);
76215
+ root.children.splice(i, 1);
76216
+ i--;
76217
+ }
76218
+ }
76219
+
76220
+ // now we can add ourselves
76221
+ root.children.push(node);
76222
+ }
76223
+
76224
+ // add all regions to the root
76225
+ for (var i = 0; i < poly.regions.length; i++){
76226
+ var region = poly.regions[i];
76227
+ if (region.length < 3) // regions must have at least 3 points (sanity check)
76228
+ continue;
76229
+ addChild(roots, region);
76230
+ }
76231
+
76232
+ // with our heirarchy, we can distinguish between exterior borders, and interior holes
76233
+ // the root nodes are exterior, children are interior, children's children are exterior,
76234
+ // children's children's children are interior, etc
76235
+
76236
+ // while we're at it, exteriors are counter-clockwise, and interiors are clockwise
76237
+
76238
+ function forceWinding(region, clockwise){
76239
+ // first, see if we're clockwise or counter-clockwise
76240
+ // https://en.wikipedia.org/wiki/Shoelace_formula
76241
+ var winding = 0;
76242
+ var last_x = region[region.length - 1][0];
76243
+ var last_y = region[region.length - 1][1];
76244
+ var copy = [];
76245
+ for (var i = 0; i < region.length; i++){
76246
+ var curr_x = region[i][0];
76247
+ var curr_y = region[i][1];
76248
+ copy.push([curr_x, curr_y]); // create a copy while we're at it
76249
+ winding += curr_y * last_x - curr_x * last_y;
76250
+ last_x = curr_x;
76251
+ last_y = curr_y;
76252
+ }
76253
+ // this assumes Cartesian coordinates (Y is positive going up)
76254
+ var isclockwise = winding < 0;
76255
+ if (isclockwise !== clockwise)
76256
+ copy.reverse();
76257
+ // while we're here, the last point must be the first point...
76258
+ copy.push([copy[0][0], copy[0][1]]);
76259
+ return copy;
76260
+ }
76261
+
76262
+ var geopolys = [];
76263
+
76264
+ function addExterior(node){
76265
+ var poly = [forceWinding(node.region, false)];
76266
+ geopolys.push(poly);
76267
+ // children of exteriors are interior
76268
+ for (var i = 0; i < node.children.length; i++)
76269
+ poly.push(getInterior(node.children[i]));
76270
+ }
76271
+
76272
+ function getInterior(node){
76273
+ // children of interiors are exterior
76274
+ for (var i = 0; i < node.children.length; i++)
76275
+ addExterior(node.children[i]);
76276
+ // return the clockwise interior
76277
+ return forceWinding(node.region, true);
76278
+ }
76279
+
76280
+ // root nodes are exterior
76281
+ for (var i = 0; i < roots.children.length; i++)
76282
+ addExterior(roots.children[i]);
76283
+
76284
+ // lastly, construct the approrpriate GeoJSON object
76285
+
76286
+ if (geopolys.length <= 0) // empty GeoJSON Polygon
76287
+ return { type: 'Polygon', coordinates: [] };
76288
+ if (geopolys.length == 1) // use a GeoJSON Polygon
76289
+ return { type: 'Polygon', coordinates: geopolys[0] };
76290
+ return { // otherwise, use a GeoJSON MultiPolygon
76291
+ type: 'MultiPolygon',
76292
+ coordinates: geopolys
76293
+ };
76294
+ }
76295
+ };
76296
+
76297
+ module.exports = GeoJSON;
76298
+
76299
+
76300
+ /***/ }),
76301
+
76302
+ /***/ 7671:
76303
+ /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
76304
+
76305
+ // (c) Copyright 2016, Sean Connelly (@voidqk), http://syntheti.cc
76306
+ // MIT License
76307
+ // Project Home: https://github.com/voidqk/polybooljs
76308
+
76309
+ //
76310
+ // this is the core work-horse
76311
+ //
76312
+
76313
+ var LinkedList = __webpack_require__(9186);
76314
+
76315
+ function Intersecter(selfIntersection, eps, buildLog){
76316
+ // selfIntersection is true/false depending on the phase of the overall algorithm
76317
+
76318
+ //
76319
+ // segment creation
76320
+ //
76321
+
76322
+ function segmentNew(start, end){
76323
+ return {
76324
+ id: buildLog ? buildLog.segmentId() : -1,
76325
+ start: start,
76326
+ end: end,
76327
+ myFill: {
76328
+ above: null, // is there fill above us?
76329
+ below: null // is there fill below us?
76330
+ },
76331
+ otherFill: null
76332
+ };
76333
+ }
76334
+
76335
+ function segmentCopy(start, end, seg){
76336
+ return {
76337
+ id: buildLog ? buildLog.segmentId() : -1,
76338
+ start: start,
76339
+ end: end,
76340
+ myFill: {
76341
+ above: seg.myFill.above,
76342
+ below: seg.myFill.below
76343
+ },
76344
+ otherFill: null
76345
+ };
76346
+ }
76347
+
76348
+ //
76349
+ // event logic
76350
+ //
76351
+
76352
+ var event_root = LinkedList.create();
76353
+
76354
+ function eventCompare(p1_isStart, p1_1, p1_2, p2_isStart, p2_1, p2_2){
76355
+ // compare the selected points first
76356
+ var comp = eps.pointsCompare(p1_1, p2_1);
76357
+ if (comp !== 0)
76358
+ return comp;
76359
+ // the selected points are the same
76360
+
76361
+ if (eps.pointsSame(p1_2, p2_2)) // if the non-selected points are the same too...
76362
+ return 0; // then the segments are equal
76363
+
76364
+ if (p1_isStart !== p2_isStart) // if one is a start and the other isn't...
76365
+ return p1_isStart ? 1 : -1; // favor the one that isn't the start
76366
+
76367
+ // otherwise, we'll have to calculate which one is below the other manually
76368
+ return eps.pointAboveOrOnLine(p1_2,
76369
+ p2_isStart ? p2_1 : p2_2, // order matters
76370
+ p2_isStart ? p2_2 : p2_1
76371
+ ) ? 1 : -1;
76372
+ }
76373
+
76374
+ function eventAdd(ev, other_pt){
76375
+ event_root.insertBefore(ev, function(here){
76376
+ // should ev be inserted before here?
76377
+ var comp = eventCompare(
76378
+ ev .isStart, ev .pt, other_pt,
76379
+ here.isStart, here.pt, here.other.pt
76380
+ );
76381
+ return comp < 0;
76382
+ });
76383
+ }
76384
+
76385
+ function eventAddSegmentStart(seg, primary){
76386
+ var ev_start = LinkedList.node({
76387
+ isStart: true,
76388
+ pt: seg.start,
76389
+ seg: seg,
76390
+ primary: primary,
76391
+ other: null,
76392
+ status: null
76393
+ });
76394
+ eventAdd(ev_start, seg.end);
76395
+ return ev_start;
76396
+ }
76397
+
76398
+ function eventAddSegmentEnd(ev_start, seg, primary){
76399
+ var ev_end = LinkedList.node({
76400
+ isStart: false,
76401
+ pt: seg.end,
76402
+ seg: seg,
76403
+ primary: primary,
76404
+ other: ev_start,
76405
+ status: null
76406
+ });
76407
+ ev_start.other = ev_end;
76408
+ eventAdd(ev_end, ev_start.pt);
76409
+ }
76410
+
76411
+ function eventAddSegment(seg, primary){
76412
+ var ev_start = eventAddSegmentStart(seg, primary);
76413
+ eventAddSegmentEnd(ev_start, seg, primary);
76414
+ return ev_start;
76415
+ }
76416
+
76417
+ function eventUpdateEnd(ev, end){
76418
+ // slides an end backwards
76419
+ // (start)------------(end) to:
76420
+ // (start)---(end)
76421
+
76422
+ if (buildLog)
76423
+ buildLog.segmentChop(ev.seg, end);
76424
+
76425
+ ev.other.remove();
76426
+ ev.seg.end = end;
76427
+ ev.other.pt = end;
76428
+ eventAdd(ev.other, ev.pt);
76429
+ }
76430
+
76431
+ function eventDivide(ev, pt){
76432
+ var ns = segmentCopy(pt, ev.seg.end, ev.seg);
76433
+ eventUpdateEnd(ev, pt);
76434
+ return eventAddSegment(ns, ev.primary);
76435
+ }
76436
+
76437
+ function calculate(primaryPolyInverted, secondaryPolyInverted){
76438
+ // if selfIntersection is true then there is no secondary polygon, so that isn't used
76439
+
76440
+ //
76441
+ // status logic
76442
+ //
76443
+
76444
+ var status_root = LinkedList.create();
76445
+
76446
+ function statusCompare(ev1, ev2){
76447
+ var a1 = ev1.seg.start;
76448
+ var a2 = ev1.seg.end;
76449
+ var b1 = ev2.seg.start;
76450
+ var b2 = ev2.seg.end;
76451
+
76452
+ if (eps.pointsCollinear(a1, b1, b2)){
76453
+ if (eps.pointsCollinear(a2, b1, b2))
76454
+ return 1;//eventCompare(true, a1, a2, true, b1, b2);
76455
+ return eps.pointAboveOrOnLine(a2, b1, b2) ? 1 : -1;
76456
+ }
76457
+ return eps.pointAboveOrOnLine(a1, b1, b2) ? 1 : -1;
76458
+ }
76459
+
76460
+ function statusFindSurrounding(ev){
76461
+ return status_root.findTransition(function(here){
76462
+ var comp = statusCompare(ev, here.ev);
76463
+ return comp > 0;
76464
+ });
76465
+ }
76466
+
76467
+ function checkIntersection(ev1, ev2){
76468
+ // returns the segment equal to ev1, or false if nothing equal
76469
+
76470
+ var seg1 = ev1.seg;
76471
+ var seg2 = ev2.seg;
76472
+ var a1 = seg1.start;
76473
+ var a2 = seg1.end;
76474
+ var b1 = seg2.start;
76475
+ var b2 = seg2.end;
76476
+
76477
+ if (buildLog)
76478
+ buildLog.checkIntersection(seg1, seg2);
76479
+
76480
+ var i = eps.linesIntersect(a1, a2, b1, b2);
76481
+
76482
+ if (i === false){
76483
+ // segments are parallel or coincident
76484
+
76485
+ // if points aren't collinear, then the segments are parallel, so no intersections
76486
+ if (!eps.pointsCollinear(a1, a2, b1))
76487
+ return false;
76488
+ // otherwise, segments are on top of each other somehow (aka coincident)
76489
+
76490
+ if (eps.pointsSame(a1, b2) || eps.pointsSame(a2, b1))
76491
+ return false; // segments touch at endpoints... no intersection
76492
+
76493
+ var a1_equ_b1 = eps.pointsSame(a1, b1);
76494
+ var a2_equ_b2 = eps.pointsSame(a2, b2);
76495
+
76496
+ if (a1_equ_b1 && a2_equ_b2)
76497
+ return ev2; // segments are exactly equal
76498
+
76499
+ var a1_between = !a1_equ_b1 && eps.pointBetween(a1, b1, b2);
76500
+ var a2_between = !a2_equ_b2 && eps.pointBetween(a2, b1, b2);
76501
+
76502
+ // handy for debugging:
76503
+ // buildLog.log({
76504
+ // a1_equ_b1: a1_equ_b1,
76505
+ // a2_equ_b2: a2_equ_b2,
76506
+ // a1_between: a1_between,
76507
+ // a2_between: a2_between
76508
+ // });
76509
+
76510
+ if (a1_equ_b1){
76511
+ if (a2_between){
76512
+ // (a1)---(a2)
76513
+ // (b1)----------(b2)
76514
+ eventDivide(ev2, a2);
76515
+ }
76516
+ else{
76517
+ // (a1)----------(a2)
76518
+ // (b1)---(b2)
76519
+ eventDivide(ev1, b2);
76520
+ }
76521
+ return ev2;
76522
+ }
76523
+ else if (a1_between){
76524
+ if (!a2_equ_b2){
76525
+ // make a2 equal to b2
76526
+ if (a2_between){
76527
+ // (a1)---(a2)
76528
+ // (b1)-----------------(b2)
76529
+ eventDivide(ev2, a2);
76530
+ }
76531
+ else{
76532
+ // (a1)----------(a2)
76533
+ // (b1)----------(b2)
76534
+ eventDivide(ev1, b2);
76535
+ }
76536
+ }
76537
+
76538
+ // (a1)---(a2)
76539
+ // (b1)----------(b2)
76540
+ eventDivide(ev2, a1);
76541
+ }
76542
+ }
76543
+ else{
76544
+ // otherwise, lines intersect at i.pt, which may or may not be between the endpoints
76545
+
76546
+ // is A divided between its endpoints? (exclusive)
76547
+ if (i.alongA === 0){
76548
+ if (i.alongB === -1) // yes, at exactly b1
76549
+ eventDivide(ev1, b1);
76550
+ else if (i.alongB === 0) // yes, somewhere between B's endpoints
76551
+ eventDivide(ev1, i.pt);
76552
+ else if (i.alongB === 1) // yes, at exactly b2
76553
+ eventDivide(ev1, b2);
76554
+ }
76555
+
76556
+ // is B divided between its endpoints? (exclusive)
76557
+ if (i.alongB === 0){
76558
+ if (i.alongA === -1) // yes, at exactly a1
76559
+ eventDivide(ev2, a1);
76560
+ else if (i.alongA === 0) // yes, somewhere between A's endpoints (exclusive)
76561
+ eventDivide(ev2, i.pt);
76562
+ else if (i.alongA === 1) // yes, at exactly a2
76563
+ eventDivide(ev2, a2);
76564
+ }
76565
+ }
76566
+ return false;
76567
+ }
76568
+
76569
+ //
76570
+ // main event loop
76571
+ //
76572
+ var segments = [];
76573
+ while (!event_root.isEmpty()){
76574
+ var ev = event_root.getHead();
76575
+
76576
+ if (buildLog)
76577
+ buildLog.vert(ev.pt[0]);
76578
+
76579
+ if (ev.isStart){
76580
+
76581
+ if (buildLog)
76582
+ buildLog.segmentNew(ev.seg, ev.primary);
76583
+
76584
+ var surrounding = statusFindSurrounding(ev);
76585
+ var above = surrounding.before ? surrounding.before.ev : null;
76586
+ var below = surrounding.after ? surrounding.after.ev : null;
76587
+
76588
+ if (buildLog){
76589
+ buildLog.tempStatus(
76590
+ ev.seg,
76591
+ above ? above.seg : false,
76592
+ below ? below.seg : false
76593
+ );
76594
+ }
76595
+
76596
+ function checkBothIntersections(){
76597
+ if (above){
76598
+ var eve = checkIntersection(ev, above);
76599
+ if (eve)
76600
+ return eve;
76601
+ }
76602
+ if (below)
76603
+ return checkIntersection(ev, below);
76604
+ return false;
76605
+ }
76606
+
76607
+ var eve = checkBothIntersections();
76608
+ if (eve){
76609
+ // ev and eve are equal
76610
+ // we'll keep eve and throw away ev
76611
+
76612
+ // merge ev.seg's fill information into eve.seg
76613
+
76614
+ if (selfIntersection){
76615
+ var toggle; // are we a toggling edge?
76616
+ if (ev.seg.myFill.below === null)
76617
+ toggle = true;
76618
+ else
76619
+ toggle = ev.seg.myFill.above !== ev.seg.myFill.below;
76620
+
76621
+ // merge two segments that belong to the same polygon
76622
+ // think of this as sandwiching two segments together, where `eve.seg` is
76623
+ // the bottom -- this will cause the above fill flag to toggle
76624
+ if (toggle)
76625
+ eve.seg.myFill.above = !eve.seg.myFill.above;
76626
+ }
76627
+ else{
76628
+ // merge two segments that belong to different polygons
76629
+ // each segment has distinct knowledge, so no special logic is needed
76630
+ // note that this can only happen once per segment in this phase, because we
76631
+ // are guaranteed that all self-intersections are gone
76632
+ eve.seg.otherFill = ev.seg.myFill;
76633
+ }
76634
+
76635
+ if (buildLog)
76636
+ buildLog.segmentUpdate(eve.seg);
76637
+
76638
+ ev.other.remove();
76639
+ ev.remove();
76640
+ }
76641
+
76642
+ if (event_root.getHead() !== ev){
76643
+ // something was inserted before us in the event queue, so loop back around and
76644
+ // process it before continuing
76645
+ if (buildLog)
76646
+ buildLog.rewind(ev.seg);
76647
+ continue;
76648
+ }
76649
+
76650
+ //
76651
+ // calculate fill flags
76652
+ //
76653
+ if (selfIntersection){
76654
+ var toggle; // are we a toggling edge?
76655
+ if (ev.seg.myFill.below === null) // if we are a new segment...
76656
+ toggle = true; // then we toggle
76657
+ else // we are a segment that has previous knowledge from a division
76658
+ toggle = ev.seg.myFill.above !== ev.seg.myFill.below; // calculate toggle
76659
+
76660
+ // next, calculate whether we are filled below us
76661
+ if (!below){ // if nothing is below us...
76662
+ // we are filled below us if the polygon is inverted
76663
+ ev.seg.myFill.below = primaryPolyInverted;
76664
+ }
76665
+ else{
76666
+ // otherwise, we know the answer -- it's the same if whatever is below
76667
+ // us is filled above it
76668
+ ev.seg.myFill.below = below.seg.myFill.above;
76669
+ }
76670
+
76671
+ // since now we know if we're filled below us, we can calculate whether
76672
+ // we're filled above us by applying toggle to whatever is below us
76673
+ if (toggle)
76674
+ ev.seg.myFill.above = !ev.seg.myFill.below;
76675
+ else
76676
+ ev.seg.myFill.above = ev.seg.myFill.below;
76677
+ }
76678
+ else{
76679
+ // now we fill in any missing transition information, since we are all-knowing
76680
+ // at this point
76681
+
76682
+ if (ev.seg.otherFill === null){
76683
+ // if we don't have other information, then we need to figure out if we're
76684
+ // inside the other polygon
76685
+ var inside;
76686
+ if (!below){
76687
+ // if nothing is below us, then we're inside if the other polygon is
76688
+ // inverted
76689
+ inside =
76690
+ ev.primary ? secondaryPolyInverted : primaryPolyInverted;
76691
+ }
76692
+ else{ // otherwise, something is below us
76693
+ // so copy the below segment's other polygon's above
76694
+ if (ev.primary === below.primary)
76695
+ inside = below.seg.otherFill.above;
76696
+ else
76697
+ inside = below.seg.myFill.above;
76698
+ }
76699
+ ev.seg.otherFill = {
76700
+ above: inside,
76701
+ below: inside
76702
+ };
76703
+ }
76704
+ }
76705
+
76706
+ if (buildLog){
76707
+ buildLog.status(
76708
+ ev.seg,
76709
+ above ? above.seg : false,
76710
+ below ? below.seg : false
76711
+ );
76712
+ }
76713
+
76714
+ // insert the status and remember it for later removal
76715
+ ev.other.status = surrounding.insert(LinkedList.node({ ev: ev }));
76716
+ }
76717
+ else{
76718
+ var st = ev.status;
76719
+
76720
+ if (st === null){
76721
+ throw new Error('PolyBool: Zero-length segment detected; your epsilon is ' +
76722
+ 'probably too small or too large');
76723
+ }
76724
+
76725
+ // removing the status will create two new adjacent edges, so we'll need to check
76726
+ // for those
76727
+ if (status_root.exists(st.prev) && status_root.exists(st.next))
76728
+ checkIntersection(st.prev.ev, st.next.ev);
76729
+
76730
+ if (buildLog)
76731
+ buildLog.statusRemove(st.ev.seg);
76732
+
76733
+ // remove the status
76734
+ st.remove();
76735
+
76736
+ // if we've reached this point, we've calculated everything there is to know, so
76737
+ // save the segment for reporting
76738
+ if (!ev.primary){
76739
+ // make sure `seg.myFill` actually points to the primary polygon though
76740
+ var s = ev.seg.myFill;
76741
+ ev.seg.myFill = ev.seg.otherFill;
76742
+ ev.seg.otherFill = s;
76743
+ }
76744
+ segments.push(ev.seg);
76745
+ }
76746
+
76747
+ // remove the event and continue
76748
+ event_root.getHead().remove();
76749
+ }
76750
+
76751
+ if (buildLog)
76752
+ buildLog.done();
76753
+
76754
+ return segments;
76755
+ }
76756
+
76757
+ // return the appropriate API depending on what we're doing
76758
+ if (!selfIntersection){
76759
+ // performing combination of polygons, so only deal with already-processed segments
76760
+ return {
76761
+ calculate: function(segments1, inverted1, segments2, inverted2){
76762
+ // segmentsX come from the self-intersection API, or this API
76763
+ // invertedX is whether we treat that list of segments as an inverted polygon or not
76764
+ // returns segments that can be used for further operations
76765
+ segments1.forEach(function(seg){
76766
+ eventAddSegment(segmentCopy(seg.start, seg.end, seg), true);
76767
+ });
76768
+ segments2.forEach(function(seg){
76769
+ eventAddSegment(segmentCopy(seg.start, seg.end, seg), false);
76770
+ });
76771
+ return calculate(inverted1, inverted2);
76772
+ }
76773
+ };
76774
+ }
76775
+
76776
+ // otherwise, performing self-intersection, so deal with regions
76777
+ return {
76778
+ addRegion: function(region){
76779
+ // regions are a list of points:
76780
+ // [ [0, 0], [100, 0], [50, 100] ]
76781
+ // you can add multiple regions before running calculate
76782
+ var pt1;
76783
+ var pt2 = region[region.length - 1];
76784
+ for (var i = 0; i < region.length; i++){
76785
+ pt1 = pt2;
76786
+ pt2 = region[i];
76787
+
76788
+ var forward = eps.pointsCompare(pt1, pt2);
76789
+ if (forward === 0) // points are equal, so we have a zero-length segment
76790
+ continue; // just skip it
76791
+
76792
+ eventAddSegment(
76793
+ segmentNew(
76794
+ forward < 0 ? pt1 : pt2,
76795
+ forward < 0 ? pt2 : pt1
76796
+ ),
76797
+ true
76798
+ );
76799
+ }
76800
+ },
76801
+ calculate: function(inverted){
76802
+ // is the polygon inverted?
76803
+ // returns segments
76804
+ return calculate(inverted, false);
76805
+ }
76806
+ };
76807
+ }
76808
+
76809
+ module.exports = Intersecter;
76810
+
76811
+
76812
+ /***/ }),
76813
+
76814
+ /***/ 9186:
76815
+ /***/ (function(module) {
76816
+
76817
+ // (c) Copyright 2016, Sean Connelly (@voidqk), http://syntheti.cc
76818
+ // MIT License
76819
+ // Project Home: https://github.com/voidqk/polybooljs
76820
+
76821
+ //
76822
+ // simple linked list implementation that allows you to traverse down nodes and save positions
76823
+ //
76824
+
76825
+ var LinkedList = {
76826
+ create: function(){
76827
+ var my = {
76828
+ root: { root: true, next: null },
76829
+ exists: function(node){
76830
+ if (node === null || node === my.root)
76831
+ return false;
76832
+ return true;
76833
+ },
76834
+ isEmpty: function(){
76835
+ return my.root.next === null;
76836
+ },
76837
+ getHead: function(){
76838
+ return my.root.next;
76839
+ },
76840
+ insertBefore: function(node, check){
76841
+ var last = my.root;
76842
+ var here = my.root.next;
76843
+ while (here !== null){
76844
+ if (check(here)){
76845
+ node.prev = here.prev;
76846
+ node.next = here;
76847
+ here.prev.next = node;
76848
+ here.prev = node;
76849
+ return;
76850
+ }
76851
+ last = here;
76852
+ here = here.next;
76853
+ }
76854
+ last.next = node;
76855
+ node.prev = last;
76856
+ node.next = null;
76857
+ },
76858
+ findTransition: function(check){
76859
+ var prev = my.root;
76860
+ var here = my.root.next;
76861
+ while (here !== null){
76862
+ if (check(here))
76863
+ break;
76864
+ prev = here;
76865
+ here = here.next;
76866
+ }
76867
+ return {
76868
+ before: prev === my.root ? null : prev,
76869
+ after: here,
76870
+ insert: function(node){
76871
+ node.prev = prev;
76872
+ node.next = here;
76873
+ prev.next = node;
76874
+ if (here !== null)
76875
+ here.prev = node;
76876
+ return node;
76877
+ }
76878
+ };
76879
+ }
76880
+ };
76881
+ return my;
76882
+ },
76883
+ node: function(data){
76884
+ data.prev = null;
76885
+ data.next = null;
76886
+ data.remove = function(){
76887
+ data.prev.next = data.next;
76888
+ if (data.next)
76889
+ data.next.prev = data.prev;
76890
+ data.prev = null;
76891
+ data.next = null;
76892
+ };
76893
+ return data;
76894
+ }
76895
+ };
76896
+
76897
+ module.exports = LinkedList;
76898
+
76899
+
76900
+ /***/ }),
76901
+
76902
+ /***/ 9048:
76903
+ /***/ (function(module) {
76904
+
76905
+ // (c) Copyright 2016, Sean Connelly (@voidqk), http://syntheti.cc
76906
+ // MIT License
76907
+ // Project Home: https://github.com/voidqk/polybooljs
76908
+
76909
+ //
76910
+ // converts a list of segments into a list of regions, while also removing unnecessary verticies
76911
+ //
76912
+
76913
+ function SegmentChainer(segments, eps, buildLog){
76914
+ var chains = [];
76915
+ var regions = [];
76916
+
76917
+ segments.forEach(function(seg){
76918
+ var pt1 = seg.start;
76919
+ var pt2 = seg.end;
76920
+ if (eps.pointsSame(pt1, pt2)){
76921
+ console.warn('PolyBool: Warning: Zero-length segment detected; your epsilon is ' +
76922
+ 'probably too small or too large');
76923
+ return;
76924
+ }
76925
+
76926
+ if (buildLog)
76927
+ buildLog.chainStart(seg);
76928
+
76929
+ // search for two chains that this segment matches
76930
+ var first_match = {
76931
+ index: 0,
76932
+ matches_head: false,
76933
+ matches_pt1: false
76934
+ };
76935
+ var second_match = {
76936
+ index: 0,
76937
+ matches_head: false,
76938
+ matches_pt1: false
76939
+ };
76940
+ var next_match = first_match;
76941
+ function setMatch(index, matches_head, matches_pt1){
76942
+ // return true if we've matched twice
76943
+ next_match.index = index;
76944
+ next_match.matches_head = matches_head;
76945
+ next_match.matches_pt1 = matches_pt1;
76946
+ if (next_match === first_match){
76947
+ next_match = second_match;
76948
+ return false;
76949
+ }
76950
+ next_match = null;
76951
+ return true; // we've matched twice, we're done here
76952
+ }
76953
+ for (var i = 0; i < chains.length; i++){
76954
+ var chain = chains[i];
76955
+ var head = chain[0];
76956
+ var head2 = chain[1];
76957
+ var tail = chain[chain.length - 1];
76958
+ var tail2 = chain[chain.length - 2];
76959
+ if (eps.pointsSame(head, pt1)){
76960
+ if (setMatch(i, true, true))
76961
+ break;
76962
+ }
76963
+ else if (eps.pointsSame(head, pt2)){
76964
+ if (setMatch(i, true, false))
76965
+ break;
76966
+ }
76967
+ else if (eps.pointsSame(tail, pt1)){
76968
+ if (setMatch(i, false, true))
76969
+ break;
76970
+ }
76971
+ else if (eps.pointsSame(tail, pt2)){
76972
+ if (setMatch(i, false, false))
76973
+ break;
76974
+ }
76975
+ }
76976
+
76977
+ if (next_match === first_match){
76978
+ // we didn't match anything, so create a new chain
76979
+ chains.push([ pt1, pt2 ]);
76980
+ if (buildLog)
76981
+ buildLog.chainNew(pt1, pt2);
76982
+ return;
76983
+ }
76984
+
76985
+ if (next_match === second_match){
76986
+ // we matched a single chain
76987
+
76988
+ if (buildLog)
76989
+ buildLog.chainMatch(first_match.index);
76990
+
76991
+ // add the other point to the apporpriate end, and check to see if we've closed the
76992
+ // chain into a loop
76993
+
76994
+ var index = first_match.index;
76995
+ var pt = first_match.matches_pt1 ? pt2 : pt1; // if we matched pt1, then we add pt2, etc
76996
+ var addToHead = first_match.matches_head; // if we matched at head, then add to the head
76997
+
76998
+ var chain = chains[index];
76999
+ var grow = addToHead ? chain[0] : chain[chain.length - 1];
77000
+ var grow2 = addToHead ? chain[1] : chain[chain.length - 2];
77001
+ var oppo = addToHead ? chain[chain.length - 1] : chain[0];
77002
+ var oppo2 = addToHead ? chain[chain.length - 2] : chain[1];
77003
+
77004
+ if (eps.pointsCollinear(grow2, grow, pt)){
77005
+ // grow isn't needed because it's directly between grow2 and pt:
77006
+ // grow2 ---grow---> pt
77007
+ if (addToHead){
77008
+ if (buildLog)
77009
+ buildLog.chainRemoveHead(first_match.index, pt);
77010
+ chain.shift();
77011
+ }
77012
+ else{
77013
+ if (buildLog)
77014
+ buildLog.chainRemoveTail(first_match.index, pt);
77015
+ chain.pop();
77016
+ }
77017
+ grow = grow2; // old grow is gone... new grow is what grow2 was
77018
+ }
77019
+
77020
+ if (eps.pointsSame(oppo, pt)){
77021
+ // we're closing the loop, so remove chain from chains
77022
+ chains.splice(index, 1);
77023
+
77024
+ if (eps.pointsCollinear(oppo2, oppo, grow)){
77025
+ // oppo isn't needed because it's directly between oppo2 and grow:
77026
+ // oppo2 ---oppo--->grow
77027
+ if (addToHead){
77028
+ if (buildLog)
77029
+ buildLog.chainRemoveTail(first_match.index, grow);
77030
+ chain.pop();
77031
+ }
77032
+ else{
77033
+ if (buildLog)
77034
+ buildLog.chainRemoveHead(first_match.index, grow);
77035
+ chain.shift();
77036
+ }
77037
+ }
77038
+
77039
+ if (buildLog)
77040
+ buildLog.chainClose(first_match.index);
77041
+
77042
+ // we have a closed chain!
77043
+ regions.push(chain);
77044
+ return;
77045
+ }
77046
+
77047
+ // not closing a loop, so just add it to the apporpriate side
77048
+ if (addToHead){
77049
+ if (buildLog)
77050
+ buildLog.chainAddHead(first_match.index, pt);
77051
+ chain.unshift(pt);
77052
+ }
77053
+ else{
77054
+ if (buildLog)
77055
+ buildLog.chainAddTail(first_match.index, pt);
77056
+ chain.push(pt);
77057
+ }
77058
+ return;
77059
+ }
77060
+
77061
+ // otherwise, we matched two chains, so we need to combine those chains together
77062
+
77063
+ function reverseChain(index){
77064
+ if (buildLog)
77065
+ buildLog.chainReverse(index);
77066
+ chains[index].reverse(); // gee, that's easy
77067
+ }
77068
+
77069
+ function appendChain(index1, index2){
77070
+ // index1 gets index2 appended to it, and index2 is removed
77071
+ var chain1 = chains[index1];
77072
+ var chain2 = chains[index2];
77073
+ var tail = chain1[chain1.length - 1];
77074
+ var tail2 = chain1[chain1.length - 2];
77075
+ var head = chain2[0];
77076
+ var head2 = chain2[1];
77077
+
77078
+ if (eps.pointsCollinear(tail2, tail, head)){
77079
+ // tail isn't needed because it's directly between tail2 and head
77080
+ // tail2 ---tail---> head
77081
+ if (buildLog)
77082
+ buildLog.chainRemoveTail(index1, tail);
77083
+ chain1.pop();
77084
+ tail = tail2; // old tail is gone... new tail is what tail2 was
77085
+ }
77086
+
77087
+ if (eps.pointsCollinear(tail, head, head2)){
77088
+ // head isn't needed because it's directly between tail and head2
77089
+ // tail ---head---> head2
77090
+ if (buildLog)
77091
+ buildLog.chainRemoveHead(index2, head);
77092
+ chain2.shift();
77093
+ }
77094
+
77095
+ if (buildLog)
77096
+ buildLog.chainJoin(index1, index2);
77097
+ chains[index1] = chain1.concat(chain2);
77098
+ chains.splice(index2, 1);
77099
+ }
77100
+
77101
+ var F = first_match.index;
77102
+ var S = second_match.index;
77103
+
77104
+ if (buildLog)
77105
+ buildLog.chainConnect(F, S);
77106
+
77107
+ var reverseF = chains[F].length < chains[S].length; // reverse the shorter chain, if needed
77108
+ if (first_match.matches_head){
77109
+ if (second_match.matches_head){
77110
+ if (reverseF){
77111
+ // <<<< F <<<< --- >>>> S >>>>
77112
+ reverseChain(F);
77113
+ // >>>> F >>>> --- >>>> S >>>>
77114
+ appendChain(F, S);
77115
+ }
77116
+ else{
77117
+ // <<<< F <<<< --- >>>> S >>>>
77118
+ reverseChain(S);
77119
+ // <<<< F <<<< --- <<<< S <<<< logically same as:
77120
+ // >>>> S >>>> --- >>>> F >>>>
77121
+ appendChain(S, F);
77122
+ }
77123
+ }
77124
+ else{
77125
+ // <<<< F <<<< --- <<<< S <<<< logically same as:
77126
+ // >>>> S >>>> --- >>>> F >>>>
77127
+ appendChain(S, F);
77128
+ }
77129
+ }
77130
+ else{
77131
+ if (second_match.matches_head){
77132
+ // >>>> F >>>> --- >>>> S >>>>
77133
+ appendChain(F, S);
77134
+ }
77135
+ else{
77136
+ if (reverseF){
77137
+ // >>>> F >>>> --- <<<< S <<<<
77138
+ reverseChain(F);
77139
+ // <<<< F <<<< --- <<<< S <<<< logically same as:
77140
+ // >>>> S >>>> --- >>>> F >>>>
77141
+ appendChain(S, F);
77142
+ }
77143
+ else{
77144
+ // >>>> F >>>> --- <<<< S <<<<
77145
+ reverseChain(S);
77146
+ // >>>> F >>>> --- >>>> S >>>>
77147
+ appendChain(F, S);
77148
+ }
77149
+ }
77150
+ }
77151
+ });
77152
+
77153
+ return regions;
77154
+ }
77155
+
77156
+ module.exports = SegmentChainer;
77157
+
77158
+
77159
+ /***/ }),
77160
+
77161
+ /***/ 571:
77162
+ /***/ (function(module) {
77163
+
77164
+ // (c) Copyright 2016, Sean Connelly (@voidqk), http://syntheti.cc
77165
+ // MIT License
77166
+ // Project Home: https://github.com/voidqk/polybooljs
77167
+
77168
+ //
77169
+ // filter a list of segments based on boolean operations
77170
+ //
77171
+
77172
+ function select(segments, selection, buildLog){
77173
+ var result = [];
77174
+ segments.forEach(function(seg){
77175
+ var index =
77176
+ (seg.myFill.above ? 8 : 0) +
77177
+ (seg.myFill.below ? 4 : 0) +
77178
+ ((seg.otherFill && seg.otherFill.above) ? 2 : 0) +
77179
+ ((seg.otherFill && seg.otherFill.below) ? 1 : 0);
77180
+ if (selection[index] !== 0){
77181
+ // copy the segment to the results, while also calculating the fill status
77182
+ result.push({
77183
+ id: buildLog ? buildLog.segmentId() : -1,
77184
+ start: seg.start,
77185
+ end: seg.end,
77186
+ myFill: {
77187
+ above: selection[index] === 1, // 1 if filled above
77188
+ below: selection[index] === 2 // 2 if filled below
77189
+ },
77190
+ otherFill: null
77191
+ });
77192
+ }
77193
+ });
77194
+
77195
+ if (buildLog)
77196
+ buildLog.selected(result);
77197
+
77198
+ return result;
77199
+ }
77200
+
77201
+ var SegmentSelector = {
77202
+ union: function(segments, buildLog){ // primary | secondary
77203
+ // above1 below1 above2 below2 Keep? Value
77204
+ // 0 0 0 0 => no 0
77205
+ // 0 0 0 1 => yes filled below 2
77206
+ // 0 0 1 0 => yes filled above 1
77207
+ // 0 0 1 1 => no 0
77208
+ // 0 1 0 0 => yes filled below 2
77209
+ // 0 1 0 1 => yes filled below 2
77210
+ // 0 1 1 0 => no 0
77211
+ // 0 1 1 1 => no 0
77212
+ // 1 0 0 0 => yes filled above 1
77213
+ // 1 0 0 1 => no 0
77214
+ // 1 0 1 0 => yes filled above 1
77215
+ // 1 0 1 1 => no 0
77216
+ // 1 1 0 0 => no 0
77217
+ // 1 1 0 1 => no 0
77218
+ // 1 1 1 0 => no 0
77219
+ // 1 1 1 1 => no 0
77220
+ return select(segments, [
77221
+ 0, 2, 1, 0,
77222
+ 2, 2, 0, 0,
77223
+ 1, 0, 1, 0,
77224
+ 0, 0, 0, 0
77225
+ ], buildLog);
77226
+ },
77227
+ intersect: function(segments, buildLog){ // primary & secondary
77228
+ // above1 below1 above2 below2 Keep? Value
77229
+ // 0 0 0 0 => no 0
77230
+ // 0 0 0 1 => no 0
77231
+ // 0 0 1 0 => no 0
77232
+ // 0 0 1 1 => no 0
77233
+ // 0 1 0 0 => no 0
77234
+ // 0 1 0 1 => yes filled below 2
77235
+ // 0 1 1 0 => no 0
77236
+ // 0 1 1 1 => yes filled below 2
77237
+ // 1 0 0 0 => no 0
77238
+ // 1 0 0 1 => no 0
77239
+ // 1 0 1 0 => yes filled above 1
77240
+ // 1 0 1 1 => yes filled above 1
77241
+ // 1 1 0 0 => no 0
77242
+ // 1 1 0 1 => yes filled below 2
77243
+ // 1 1 1 0 => yes filled above 1
77244
+ // 1 1 1 1 => no 0
77245
+ return select(segments, [
77246
+ 0, 0, 0, 0,
77247
+ 0, 2, 0, 2,
77248
+ 0, 0, 1, 1,
77249
+ 0, 2, 1, 0
77250
+ ], buildLog);
77251
+ },
77252
+ difference: function(segments, buildLog){ // primary - secondary
77253
+ // above1 below1 above2 below2 Keep? Value
77254
+ // 0 0 0 0 => no 0
77255
+ // 0 0 0 1 => no 0
77256
+ // 0 0 1 0 => no 0
77257
+ // 0 0 1 1 => no 0
77258
+ // 0 1 0 0 => yes filled below 2
77259
+ // 0 1 0 1 => no 0
77260
+ // 0 1 1 0 => yes filled below 2
77261
+ // 0 1 1 1 => no 0
77262
+ // 1 0 0 0 => yes filled above 1
77263
+ // 1 0 0 1 => yes filled above 1
77264
+ // 1 0 1 0 => no 0
77265
+ // 1 0 1 1 => no 0
77266
+ // 1 1 0 0 => no 0
77267
+ // 1 1 0 1 => yes filled above 1
77268
+ // 1 1 1 0 => yes filled below 2
77269
+ // 1 1 1 1 => no 0
77270
+ return select(segments, [
77271
+ 0, 0, 0, 0,
77272
+ 2, 0, 2, 0,
77273
+ 1, 1, 0, 0,
77274
+ 0, 1, 2, 0
77275
+ ], buildLog);
77276
+ },
77277
+ differenceRev: function(segments, buildLog){ // secondary - primary
77278
+ // above1 below1 above2 below2 Keep? Value
77279
+ // 0 0 0 0 => no 0
77280
+ // 0 0 0 1 => yes filled below 2
77281
+ // 0 0 1 0 => yes filled above 1
77282
+ // 0 0 1 1 => no 0
77283
+ // 0 1 0 0 => no 0
77284
+ // 0 1 0 1 => no 0
77285
+ // 0 1 1 0 => yes filled above 1
77286
+ // 0 1 1 1 => yes filled above 1
77287
+ // 1 0 0 0 => no 0
77288
+ // 1 0 0 1 => yes filled below 2
77289
+ // 1 0 1 0 => no 0
77290
+ // 1 0 1 1 => yes filled below 2
77291
+ // 1 1 0 0 => no 0
77292
+ // 1 1 0 1 => no 0
77293
+ // 1 1 1 0 => no 0
77294
+ // 1 1 1 1 => no 0
77295
+ return select(segments, [
77296
+ 0, 2, 1, 0,
77297
+ 0, 0, 1, 1,
77298
+ 0, 2, 0, 2,
77299
+ 0, 0, 0, 0
77300
+ ], buildLog);
77301
+ },
77302
+ xor: function(segments, buildLog){ // primary ^ secondary
77303
+ // above1 below1 above2 below2 Keep? Value
77304
+ // 0 0 0 0 => no 0
77305
+ // 0 0 0 1 => yes filled below 2
77306
+ // 0 0 1 0 => yes filled above 1
77307
+ // 0 0 1 1 => no 0
77308
+ // 0 1 0 0 => yes filled below 2
77309
+ // 0 1 0 1 => no 0
77310
+ // 0 1 1 0 => no 0
77311
+ // 0 1 1 1 => yes filled above 1
77312
+ // 1 0 0 0 => yes filled above 1
77313
+ // 1 0 0 1 => no 0
77314
+ // 1 0 1 0 => no 0
77315
+ // 1 0 1 1 => yes filled below 2
77316
+ // 1 1 0 0 => no 0
77317
+ // 1 1 0 1 => yes filled above 1
77318
+ // 1 1 1 0 => yes filled below 2
77319
+ // 1 1 1 1 => no 0
77320
+ return select(segments, [
77321
+ 0, 2, 1, 0,
77322
+ 2, 0, 0, 1,
77323
+ 1, 0, 0, 2,
77324
+ 0, 1, 2, 0
77325
+ ], buildLog);
77326
+ }
77327
+ };
77328
+
77329
+ module.exports = SegmentSelector;
77330
+
77331
+
74483
77332
  /***/ }),
74484
77333
 
74485
77334
  /***/ 6886:
@@ -83919,6 +86768,38 @@ module.exports = styleTagTransform;
83919
86768
 
83920
86769
  /***/ }),
83921
86770
 
86771
+ /***/ 4144:
86772
+ /***/ (function(module) {
86773
+
86774
+ "use strict";
86775
+ module.exports = "data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjMyIiBoZWlnaHQ9IjMyIj4KPHBhdGggZD0iTTAsMTFsMTEsMGwwLC0xMWwyLDBsMCwxMWwxMSwwbDAsMmwtMTEsMGwwLDExbC0yLDBsMCwtMTFsLTExLDB6IiBmaWxsPSJibGFjayIgc3Ryb2tlLXdpZHRoPSIwIi8+CjxwYXRoIGQ9Ik0yNCwyN2w4LDBsMCwybC04LDB6IiBmaWxsPSJibGFjayIgc3Ryb2tlLXdpZHRoPSIwIi8+Cjwvc3ZnPgo=";
86776
+
86777
+ /***/ }),
86778
+
86779
+ /***/ 237:
86780
+ /***/ (function(module) {
86781
+
86782
+ "use strict";
86783
+ module.exports = "data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjMyIiBoZWlnaHQ9IjMyIj4KPHBhdGggZD0iTTAsMTFsMTEsMGwwLC0xMWwyLDBsMCwxMWwxMSwwbDAsMmwtMTEsMGwwLDExbC0yLDBsMCwtMTFsLTExLDB6IiBmaWxsPSJibGFjayIgc3Ryb2tlLXdpZHRoPSIwIi8+CjxwYXRoIGQ9Ik0yNCwyN2wzLDBsMCwtM2wyLDBsMCwzbDMsMGwwLDJsLTMsMGwwLDNsLTIsMGwwLC0zbC0zLDB6IiBmaWxsPSJibGFjayIgc3Ryb2tlLXdpZHRoPSIwIi8+Cjwvc3ZnPgo=";
86784
+
86785
+ /***/ }),
86786
+
86787
+ /***/ 3554:
86788
+ /***/ (function(module) {
86789
+
86790
+ "use strict";
86791
+ module.exports = "data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjMyIiBoZWlnaHQ9IjMyIj4KPHBhdGggZD0iTTAsMTFsMTEsMGwwLC0xMWwyLDBsMCwxMWwxMSwwbDAsMmwtMTEsMGwwLDExbC0yLDBsMCwtMTFsLTExLDB6IiBmaWxsPSJibGFjayIgc3Ryb2tlLXdpZHRoPSIwIi8+CjxwYXRoIGQ9Ik0yNCwzMmwwLC00YTQsNCwwLDAsMSw4LDBsMCw0bC0yLDBsMCwtNGEyLDIsMCwwLDAsLTQsMGwwLDR6IiBmaWxsPSJibGFjayIgc3Ryb2tlLXdpZHRoPSIwIi8+Cjwvc3ZnPgo=";
86792
+
86793
+ /***/ }),
86794
+
86795
+ /***/ 9490:
86796
+ /***/ (function(module) {
86797
+
86798
+ "use strict";
86799
+ module.exports = "data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjMyIiBoZWlnaHQ9IjMyIj4KPHBhdGggZD0iTTAsMTFsMTEsMGwwLC0xMWwyLDBsMCwxMWwxMSwwbDAsMmwtMTEsMGwwLDExbC0yLDBsMCwtMTFsLTExLDB6IiBmaWxsPSJibGFjayIgc3Ryb2tlLXdpZHRoPSIwIi8+CjxwYXRoIGQ9Ik0zMiwzMC41OWwtMS40MSwxLjQxbC0yLjEyLC0yLjEybC0yLjEyLDIuMTJsLTEuNDEsLTEuNDFsMi4xMiwtMi4xMmwtMi4xMiwtMi4xMmwxLjQxLC0xLjQxbDIuMTIsMi4xMmwyLjEyLC0yLjEybDEuNDEsMS40MWwtMi4xMiwyLjEyeiIgZmlsbD0iYmxhY2siIHN0cm9rZS13aWR0aD0iMCIvPgo8L3N2Zz4K";
86800
+
86801
+ /***/ }),
86802
+
83922
86803
  /***/ 9990:
83923
86804
  /***/ (function(module) {
83924
86805
 
@@ -83975,6 +86856,9 @@ module.exports = __WEBPACK_EXTERNAL_MODULE__3877__;
83975
86856
  /******/ return module.exports;
83976
86857
  /******/ }
83977
86858
  /******/
86859
+ /******/ // expose the modules object (__webpack_modules__)
86860
+ /******/ __webpack_require__.m = __webpack_modules__;
86861
+ /******/
83978
86862
  /************************************************************************/
83979
86863
  /******/ /* webpack/runtime/compat get default export */
83980
86864
  /******/ !function() {
@@ -84028,6 +86912,33 @@ module.exports = __WEBPACK_EXTERNAL_MODULE__3877__;
84028
86912
  /******/ };
84029
86913
  /******/ }();
84030
86914
  /******/
86915
+ /******/ /* webpack/runtime/jsonp chunk loading */
86916
+ /******/ !function() {
86917
+ /******/ __webpack_require__.b = document.baseURI || self.location.href;
86918
+ /******/
86919
+ /******/ // object to store loaded and loading chunks
86920
+ /******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched
86921
+ /******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded
86922
+ /******/ var installedChunks = {
86923
+ /******/ 387: 0,
86924
+ /******/ 93: 0
86925
+ /******/ };
86926
+ /******/
86927
+ /******/ // no chunk on demand loading
86928
+ /******/
86929
+ /******/ // no prefetching
86930
+ /******/
86931
+ /******/ // no preloaded
86932
+ /******/
86933
+ /******/ // no HMR
86934
+ /******/
86935
+ /******/ // no HMR manifest
86936
+ /******/
86937
+ /******/ // no on chunks loaded
86938
+ /******/
86939
+ /******/ // no jsonp function
86940
+ /******/ }();
86941
+ /******/
84031
86942
  /************************************************************************/
84032
86943
  /******/
84033
86944
  /******/ // startup