From: Martin Raifer Date: Mon, 31 Jan 2022 17:10:00 +0000 (+0100) Subject: Update to iD v2.20.3 X-Git-Tag: live~1844^2 X-Git-Url: https://git.openstreetmap.org./rails.git/commitdiff_plain/7473925ac23b4c4915e6dc4091c12670787b9ed5?hp=4ea6a3c16df7a5dcd7620ddabfd7ecd3f6fbd396 Update to iD v2.20.3 --- diff --git a/vendor/assets/iD/iD.css.erb b/vendor/assets/iD/iD.css.erb index ad817760e..297ef2f53 100644 --- a/vendor/assets/iD/iD.css.erb +++ b/vendor/assets/iD/iD.css.erb @@ -2252,6 +2252,55 @@ stroke-dasharray: 8, 8; } +/** Closed Paths */ +.ideditor path.line.shadow.tag-highway.tag-status.tag-status-construction.tag-construction-path, +.ideditor path.line.shadow.tag-highway.tag-status.tag-status-construction.tag-construction-footway, +.ideditor path.line.shadow.tag-highway.tag-status.tag-status-construction.tag-construction-cycleway, +.ideditor path.line.shadow.tag-highway.tag-status.tag-status-construction.tag-construction-bridleway, +.ideditor path.line.shadow.tag-highway.tag-status.tag-status-construction.tag-construction-steps { + stroke-width: 15; +} +.ideditor path.line.casing.tag-highway.tag-status.tag-status-construction.tag-construction-path, +.ideditor path.line.casing.tag-highway.tag-status.tag-status-construction.tag-construction-footway, +.ideditor path.line.casing.tag-highway.tag-status.tag-status-construction.tag-construction-cycleway, +.ideditor path.line.casing.tag-highway.tag-status.tag-status-construction.tag-construction-bridleway, +.ideditor path.line.casing.tag-highway.tag-status.tag-status-construction.tag-construction-steps { + stroke-width: 5; + stroke-linecap: butt; + stroke-dasharray: none +} +.ideditor path.line.stroke.tag-highway.tag-status.tag-status-construction.tag-construction-path, +.ideditor path.line.stroke.tag-highway.tag-status.tag-status-construction.tag-construction-footway, +.ideditor path.line.stroke.tag-highway.tag-status.tag-status-construction.tag-construction-cycleway, +.ideditor path.line.stroke.tag-highway.tag-status.tag-status-construction.tag-construction-bridleway, +.ideditor path.line.stroke.tag-highway.tag-status.tag-status-construction.tag-construction-steps { + stroke-width: 4; + stroke-linecap: butt; + stroke-dasharray: 10, 10; +} + +/** Proposed Paths */ +.ideditor path.line.shadow.tag-highway.tag-status.tag-status-proposed.tag-proposed-path, +.ideditor path.line.shadow.tag-highway.tag-status.tag-status-proposed.tag-proposed-footway, +.ideditor path.line.shadow.tag-highway.tag-status.tag-status-proposed.tag-proposed-cycleway, +.ideditor path.line.shadow.tag-highway.tag-status.tag-status-proposed.tag-proposed-bridleway, +.ideditor path.line.shadow.tag-highway.tag-status.tag-status-proposed.tag-proposed-steps { + stroke-width: 15; +} +.ideditor path.line.casing.tag-highway.tag-status.tag-status-proposed.tag-proposed-path, +.ideditor path.line.casing.tag-highway.tag-status.tag-status-proposed.tag-proposed-footway, +.ideditor path.line.casing.tag-highway.tag-status.tag-status-proposed.tag-proposed-cycleway, +.ideditor path.line.casing.tag-highway.tag-status.tag-status-proposed.tag-proposed-bridleway, +.ideditor path.line.casing.tag-highway.tag-status.tag-status-proposed.tag-proposed-steps { + stroke-width: 4.5; +} +.ideditor path.line.stroke.tag-highway.tag-status.tag-status-proposed.tag-proposed-path, +.ideditor path.line.stroke.tag-highway.tag-status.tag-status-proposed.tag-proposed-footway, +.ideditor path.line.stroke.tag-highway.tag-status.tag-status-proposed.tag-proposed-cycleway, +.ideditor path.line.stroke.tag-highway.tag-status.tag-status-proposed.tag-proposed-bridleway, +.ideditor path.line.stroke.tag-highway.tag-status.tag-status-proposed.tag-proposed-steps { + stroke-width: 3; +} /* Buildings */ .ideditor path.stroke.tag-building { @@ -2399,9 +2448,8 @@ /* photo viewer div */ .ideditor .photoviewer { position: relative; - -webkit-flex-shrink: 0; - -ms-flex-negative: 0; - flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; margin-bottom: 10px; width: 330px; height: 250px; @@ -2636,14 +2684,14 @@ } -/* OpenStreetCam Image Layer */ -.ideditor .layer-openstreetcam { +/* KartaView Image Layer */ +.ideditor .layer-kartaview { pointer-events: none; } -.ideditor .layer-openstreetcam .viewfield-group * { +.ideditor .layer-kartaview .viewfield-group * { fill: #20c4ff; } -.ideditor .layer-openstreetcam .sequence { +.ideditor .layer-kartaview .sequence { stroke: #20c4ff; } @@ -2654,20 +2702,16 @@ } .ideditor .ms-wrapper .photo-attribution .attribution-row { display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; - -webkit-flex-flow: row nowrap; -ms-flex-flow: row nowrap; flex-flow: row nowrap; -webkit-box-pack: justify; - -webkit-justify-content: space-between; -ms-flex-pack: justify; justify-content: space-between; -webkit-box-align: center; - -webkit-align-items: center; -ms-flex-align: center; align-items: center; padding: 0 5px; @@ -2723,22 +2767,18 @@ .ideditor .mly-wrapper .mapillary-attribution-container { display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-align: center; - -webkit-align-items: center; -ms-flex-align: center; align-items: center; } .ideditor .mly-wrapper .mapillary-attribution-container .mapillary-attribution-icon-container { display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-align: center; - -webkit-align-items: center; -ms-flex-align: center; align-items: center; } @@ -2751,8 +2791,8 @@ margin-right: 6px; } -/* OpenStreetCam viewer */ -.ideditor .osc-wrapper { +/* KartaView viewer */ +.ideditor .kartaview-wrapper { position: relative; background-color: #000; background-image: url(<%= asset_path("iD/img/loader-black.gif") %>); @@ -2760,16 +2800,16 @@ background-repeat: no-repeat; } -.ideditor .osc-wrapper .photo-attribution a:active { +.ideditor .kartaview-wrapper .photo-attribution a:active { color: #20c4ff; } @media (hover: hover) { - .ideditor .osc-wrapper .photo-attribution a:hover { + .ideditor .kartaview-wrapper .photo-attribution a:hover { color: #20c4ff; } } -.ideditor .osc-image-wrap { +.ideditor .kartaview-image-wrap { width: 100%; height: 100%; -webkit-transform-origin:0 0; @@ -2870,15 +2910,12 @@ } .ideditor .qa-header-icon { display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-align: center; - -webkit-align-items: center; -ms-flex-align: center; align-items: center; -webkit-box-pack: center; - -webkit-justify-content: center; -ms-flex-pack: center; justify-content: center; } @@ -3094,6 +3131,59 @@ .ideditor.mode-select-note .fill-partial path.area.fill { pointer-events: visibleStroke; } +.ideditor svg.preset-icon-category-border path { + stroke-width: 1; + stroke: rgb(170, 170, 170); + fill: rgba(170, 170, 170, 0.3); +} + +.ideditor .preset-category-barrier svg.preset-icon-category-border path { + stroke: rgb(200, 144, 144); + fill: rgba(200, 144, 144, 0.3); +} + +.ideditor .preset-category-building svg.preset-icon-category-border path { + stroke: rgb(224, 110, 95); + fill: rgba(224, 110, 95, 0.3); +} + +.ideditor .preset-category-landuse svg.preset-icon-category-border path { + stroke: rgb(196, 189, 25); + fill: rgba(196, 189, 25, 0.3); +} + +.ideditor .preset-category-natural svg.preset-icon-category-border path, +.ideditor .preset-category-playground svg.preset-icon-category-border path, +.ideditor .preset-category-golf svg.preset-icon-category-border path { + stroke: rgb(140, 208, 95); + fill: rgba(140, 208, 95, 0.3); +} + +.ideditor .preset-category-water svg.preset-icon-category-border path, +.ideditor .preset-category-waterway svg.preset-icon-category-border path { + stroke: rgb(119, 211, 222); + fill: rgba(119, 211, 222, 0.3); +} + +.ideditor .preset-category-utility svg.preset-icon-category-border path { + stroke: rgb(125, 125, 125); + fill: rgba(219, 219, 125, 0.3); +} + +.ideditor .preset-category-path svg.preset-icon-category-border path { + stroke: rgb(221, 221, 204); + fill: rgba(221, 221, 204, 0.3); +} + +.ideditor .preset-category-road_service svg.preset-icon-category-border path, +.ideditor .preset-category-road_minor svg.preset-icon-category-border path, +.ideditor .preset-category-road_major svg.preset-icon-category-border path { + stroke: #999; +} + +.ideditor .preset-category-rail svg.preset-icon-category-border path { + stroke: #555; +} /* Basics ------------------------------------------------------- */ /* the root element of iD */ @@ -3133,12 +3223,10 @@ .ideditor .main-content { position: relative; display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: vertical; -webkit-box-direction: normal; - -webkit-flex-direction: column; -ms-flex-direction: column; flex-direction: column; overflow: hidden; @@ -3195,9 +3283,14 @@ font-weight: bold; margin-bottom: 20px; } +.ideditor .header h2 { + font-size: 20px; + line-height: 1.25; + font-weight: bold; + margin-bottom: 0px; +} .ideditor h3:last-child, -.ideditor h2:last-child, .ideditor h4:last-child { margin-bottom: 0;} .ideditor h3 { @@ -3325,7 +3418,8 @@ .ideditor input[type=url], .ideditor input[type=tel], .ideditor input[type=email], -.ideditor input[type=date] { +.ideditor input[type=date], +.ideditor input[type=color] { /* need this since line-height interpretation may vary by font or browser */ height: 2.585em; } @@ -3658,16 +3752,13 @@ } .ideditor .top-toolbar { display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; - -webkit-flex-flow: row nowrap; -ms-flex-flow: row nowrap; flex-flow: row nowrap; -webkit-box-pack: justify; - -webkit-justify-content: space-between; -ms-flex-pack: justify; justify-content: space-between; padding: 10px 0 0 0; @@ -3685,39 +3776,31 @@ } .ideditor .top-toolbar .toolbar-item { display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-flex: 0; - -webkit-flex: 0 1 auto; -ms-flex: 0 1 auto; flex: 0 1 auto; -webkit-box-orient: vertical; -webkit-box-direction: normal; - -webkit-flex-flow: column wrap; -ms-flex-flow: column wrap; flex-flow: column wrap; -webkit-box-pack: center; - -webkit-justify-content: center; -ms-flex-pack: center; justify-content: center; } .ideditor .top-toolbar .toolbar-item .item-content { display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-flex: 0; - -webkit-flex: 0 1 auto; -ms-flex: 0 1 auto; flex: 0 1 auto; -webkit-box-orient: horizontal; -webkit-box-direction: normal; - -webkit-flex-flow: row nowrap; -ms-flex-flow: row nowrap; flex-flow: row nowrap; -webkit-box-pack: center; - -webkit-justify-content: center; -ms-flex-pack: center; justify-content: center; height: 40px; @@ -3749,19 +3832,16 @@ .ideditor .top-toolbar .toolbar-item.spacer { width: 100%; -webkit-box-flex: 2; - -webkit-flex-grow: 2; -ms-flex-positive: 2; flex-grow: 2; } .ideditor .top-toolbar .toolbar-item:first-child { -webkit-box-pack: start; - -webkit-justify-content: flex-start; -ms-flex-pack: start; justify-content: flex-start; } .ideditor .top-toolbar .toolbar-item:last-child { -webkit-box-pack: end; - -webkit-justify-content: flex-end; -ms-flex-pack: end; justify-content: flex-end; } @@ -3770,36 +3850,30 @@ } .ideditor button.bar-button { -webkit-box-flex: 0; - -webkit-flex: 0 0 auto; -ms-flex: 0 0 auto; flex: 0 0 auto; -webkit-box-orient: horizontal; -webkit-box-direction: normal; - -webkit-flex-flow: row nowrap; -ms-flex-flow: row nowrap; flex-flow: row nowrap; -webkit-box-align: center; - -webkit-align-items: center; -ms-flex-align: center; align-items: center; padding: 0 10px; min-width: 30px; white-space: nowrap; display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; font-weight: bold; } .ideditor button.bar-button .icon { -webkit-box-flex: 0; - -webkit-flex: 0 0 20px; -ms-flex: 0 0 20px; flex: 0 0 20px; } .ideditor button.bar-button .label { -webkit-box-flex: 0; - -webkit-flex: 0 1 auto; -ms-flex: 0 1 auto; flex: 0 1 auto; padding: 0 5px; @@ -3891,19 +3965,15 @@ padding: 20px 40px; position: relative; display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-align: center; - -webkit-align-items: center; -ms-flex-align: center; align-items: center; -webkit-box-pack: center; - -webkit-justify-content: center; -ms-flex-pack: center; justify-content: center; -webkit-box-flex: 0; - -webkit-flex: 0 0 auto; -ms-flex: 0 0 auto; flex: 0 0 auto; } @@ -3982,27 +4052,22 @@ width: 100%; height: 2.5em; z-index: 1; - -webkit-flex-wrap: wrap; - -ms-flex-wrap: wrap; - flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; -webkit-box-pack: justify; - -webkit-justify-content: space-between; -ms-flex-pack: justify; justify-content: space-between; -webkit-box-align: center; - -webkit-align-items: center; -ms-flex-align: center; align-items: center; list-style: none; display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; } .ideditor .footer > a { -webkit-box-pack: center; - -webkit-justify-content: center; -ms-flex-pack: center; justify-content: center; } @@ -4080,12 +4145,10 @@ bottom: 0; right: 0; display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: vertical; -webkit-box-direction: normal; - -webkit-flex-direction: column; -ms-flex-direction: column; flex-direction: column; } @@ -4110,12 +4173,10 @@ top: 0; bottom: 2.5em; display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: vertical; -webkit-box-direction: normal; - -webkit-flex-direction: column; -ms-flex-direction: column; flex-direction: column; } @@ -4129,12 +4190,10 @@ } .ideditor .feature-list-pane { display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: vertical; -webkit-box-direction: normal; - -webkit-flex-direction: column; -ms-flex-direction: column; flex-direction: column; height: 100%; @@ -4157,7 +4216,6 @@ position: relative; height: 100%; -webkit-box-flex: 1; - -webkit-flex: 1 1 100%; -ms-flex: 1 1 100%; flex: 1 1 100%; } @@ -4173,7 +4231,6 @@ position: relative; overflow: hidden; -webkit-box-flex: 0; - -webkit-flex: 0 0 auto; -ms-flex: 0 0 auto; flex: 0 0 auto; } @@ -4233,7 +4290,6 @@ .ideditor .feature-list-item { display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; } @@ -4245,7 +4301,6 @@ text-overflow: ellipsis; overflow: hidden; -webkit-box-flex: 1; - -webkit-flex: 1 1 auto; -ms-flex: 1 1 auto; flex: 1 1 auto; } @@ -4325,7 +4380,6 @@ .ideditor .preset-list-button-wrap { min-height: 62px; display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; border: 1px solid #ccc; @@ -4337,11 +4391,9 @@ height: 100%; position: relative; display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-align: center; - -webkit-align-items: center; -ms-flex-align: center; align-items: center; } @@ -4356,19 +4408,15 @@ height: 60px; text-align: center; display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-align: center; - -webkit-align-items: center; -ms-flex-align: center; align-items: center; -webkit-box-pack: center; - -webkit-justify-content: center; -ms-flex-pack: center; justify-content: center; -webkit-box-flex: 0; - -webkit-flex: 0 0 auto; -ms-flex: 0 0 auto; flex: 0 0 auto; } @@ -4376,7 +4424,6 @@ width: 40px; height: 40px; -webkit-box-flex: 0; - -webkit-flex: 0 0 auto; -ms-flex: 0 0 auto; flex: 0 0 auto; } @@ -4526,16 +4573,13 @@ .ideditor .preset-list-button .label { display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; - -webkit-flex-flow: row wrap; -ms-flex-flow: row wrap; flex-flow: row wrap; -webkit-box-align: center; - -webkit-align-items: center; -ms-flex-align: center; align-items: center; background: #f6f6f6; @@ -4543,12 +4587,10 @@ padding: 5px 10px; border-left: 1px solid rgba(0, 0, 0, .1); -webkit-box-flex: 1; - -webkit-flex: 1 1 100%; -ms-flex: 1 1 100%; flex: 1 1 100%; - -webkit-align-self: stretch; - -ms-flex-item-align: stretch; - align-self: stretch; + -ms-flex-item-align: stretch; + align-self: stretch; } .ideditor[dir='rtl'] .preset-list-button .label { text-align: right; @@ -4601,7 +4643,6 @@ .ideditor .preset-list-button-wrap button.tag-reference-button { width: 32px; -webkit-box-flex: 0; - -webkit-flex: 0 0 auto; -ms-flex: 0 0 auto; flex: 0 0 auto; } @@ -4625,7 +4666,6 @@ } .ideditor .preset-list-button-wrap .accessory-buttons { display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; } @@ -4678,16 +4718,13 @@ ------------------------------------------------------- */ .ideditor .quick-links { display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; - -webkit-flex-flow: row wrap; -ms-flex-flow: row wrap; flex-flow: row wrap; -webkit-box-pack: end; - -webkit-justify-content: flex-end; -ms-flex-pack: end; justify-content: flex-end; padding: 5px 0 0 0; @@ -4732,12 +4769,10 @@ .ideditor .form-field { display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; - -webkit-flex-flow: row wrap; -ms-flex-flow: row wrap; flex-flow: row wrap; margin-bottom: 10px; @@ -4755,16 +4790,13 @@ /* A `label` element that wraps the top section */ .ideditor .field-label { display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; - -webkit-flex-flow: row nowrap; -ms-flex-flow: row nowrap; flex-flow: row nowrap; -webkit-box-flex: 1; - -webkit-flex: 1 1 100%; -ms-flex: 1 1 100%; flex: 1 1 100%; position: relative; @@ -4780,7 +4812,6 @@ -o-text-overflow: ellipsis; text-overflow: ellipsis; -webkit-box-flex: 1; - -webkit-flex: 1 1 auto; -ms-flex: 1 1 auto; flex: 1 1 auto; padding: 5px 0 4px 10px; @@ -4803,7 +4834,6 @@ .ideditor .field-label button { -webkit-box-flex: 0; - -webkit-flex: 0 0 auto; -ms-flex: 0 0 auto; flex: 0 0 auto; border-left: 1px solid #ccc; @@ -4836,17 +4866,14 @@ /* A `div` element that wraps the bottom section */ .ideditor .form-field-input-wrap { display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; - -webkit-flex-flow: row nowrap; -ms-flex-flow: row nowrap; flex-flow: row nowrap; width: 100%; -webkit-box-flex: 1; - -webkit-flex: 1 1 auto; -ms-flex: 1 1 auto; flex: 1 1 auto; border-top: 0; @@ -4862,7 +4889,6 @@ .ideditor .form-field-input-wrap > textarea, .ideditor .form-field-input-wrap > ul.chiplist { -webkit-box-flex: 1; - -webkit-flex: 1 1 auto; -ms-flex: 1 1 auto; flex: 1 1 auto; border: 1px solid #ccc; @@ -4878,7 +4904,6 @@ /* Buttons inside fields */ .ideditor .form-field-button { -webkit-box-flex: 0; - -webkit-flex: 0 0 auto; -ms-flex: 0 0 auto; flex: 0 0 auto; width: 32px; @@ -4907,6 +4932,34 @@ fill: #333; opacity: .5; } +.ideditor .form-field-button.colour-preview { + border-radius: 0 0 4px 0; +} +.ideditor .form-field-button.colour-preview > div.colour-box { + border: 3px solid #fff; + height: 100%; + border-radius: 8px; + cursor: pointer; + text-align: center; + line-height: 20px; + padding: 1px 0 0 1px; +} +.ideditor .inspector-hover .form-field-button.colour-preview > div.colour-box { + border-color: #ececec; +} +.ideditor .form-field-button.colour-preview:active > div.colour-box, +.ideditor .form-field-button.colour-preview:focus > div.colour-box { + border-color: #f1f1f1; +} +@media (hover: hover) { + .ideditor .form-field-button.colour-preview:hover > div.colour-box { + border-color: #f1f1f1; + } +} +.ideditor .form-field-button.colour-selector { + visibility: hidden; + position: absolute; +} /* round corners of first/last child elements */ @@ -4923,16 +4976,13 @@ .ideditor .form-field-input-access, .ideditor .form-field-input-cycleway { -webkit-box-flex: 1; - -webkit-flex: 1 1 auto; -ms-flex: 1 1 auto; flex: 1 1 auto; display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; - -webkit-flex-flow: row wrap; -ms-flex-flow: row wrap; flex-flow: row wrap; } @@ -4941,7 +4991,6 @@ ------------------------------------------------------- */ .ideditor .form-field ul.rows { -webkit-box-flex: 1; - -webkit-flex: 1 1 auto; -ms-flex: 1 1 auto; flex: 1 1 auto; border: 1px solid #ccc; @@ -4958,19 +5007,16 @@ } .ideditor .form-field ul.rows li { display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; - -webkit-flex-flow: row nowrap; -ms-flex-flow: row nowrap; flex-flow: row nowrap; } .ideditor .form-field ul.rows li.labeled-input > span, .ideditor .form-field ul.rows li.labeled-input > div { -webkit-box-flex: 1; - -webkit-flex: 1 1 auto; -ms-flex: 1 1 auto; flex: 1 1 auto; width: 100%; @@ -5043,16 +5089,13 @@ .ideditor .form-field-input-multicombo li { display: -webkit-inline-box; - display: -webkit-inline-flex; display: -ms-inline-flexbox; display: inline-flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; - -webkit-flex-flow: row nowrap; -ms-flex-flow: row nowrap; flex-flow: row nowrap; -webkit-box-align: center; - -webkit-align-items: center; -ms-flex-align: center; align-items: center; margin-bottom: 3px; @@ -5101,7 +5144,6 @@ .ideditor .form-field-input-multicombo li.chip span { display: block; -webkit-box-flex: 1; - -webkit-flex: 1 1 auto; -ms-flex: 1 1 auto; flex: 1 1 auto; overflow: hidden; @@ -5118,7 +5160,6 @@ display: block; text-align: center; -webkit-box-flex: 0; - -webkit-flex: 0 0 auto; -ms-flex: 0 0 auto; flex: 0 0 auto; } @@ -5146,12 +5187,13 @@ /* Field - Text / Numeric ------------------------------------------------------- */ -.ideditor .form-field-input-text > input:only-of-type, +.ideditor .form-field-input-text > input:only-child, .ideditor .form-field-input-tel > input:only-of-type, .ideditor .form-field-input-email > input:only-of-type, .ideditor .form-field-input-url > input:only-child { border-radius: 0 0 4px 4px; } +.ideditor .form-field-input-text > input:not(:only-child), .ideditor .form-field-input-url > input:not(:only-child) { border-radius: 0 0 0 4px; } @@ -5204,11 +5246,9 @@ ------------------------------------------------------- */ .ideditor .form-field-input-check { display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-align: center; - -webkit-align-items: center; -ms-flex-align: center; align-items: center; background: #fff; @@ -5220,7 +5260,6 @@ } .ideditor .form-field-input-check > input[type="checkbox"] { -webkit-box-flex: 0; - -webkit-flex: 0 1 auto; -ms-flex: 0 1 auto; flex: 0 1 auto; width: 20px; @@ -5228,7 +5267,6 @@ } .ideditor .form-field-input-check > span { -webkit-box-flex: 1; - -webkit-flex: 1 1 auto; -ms-flex: 1 1 auto; flex: 1 1 auto; } @@ -5237,7 +5275,6 @@ } .ideditor .form-field-input-check > .reverser { -webkit-box-flex: 0; - -webkit-flex: 0 1 auto; -ms-flex: 0 1 auto; flex: 0 1 auto; background-color: #eff2f7; @@ -5285,35 +5322,28 @@ ------------------------------------------------------- */ .ideditor .form-field-input-radio { -webkit-box-flex: 1; - -webkit-flex: 1 1 auto; -ms-flex: 1 1 auto; flex: 1 1 auto; display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; - -webkit-flex-flow: row wrap; -ms-flex-flow: row wrap; flex-flow: row wrap; } .ideditor .form-field-input-radio > label { -webkit-box-flex: 1; - -webkit-flex: 1 1 auto; -ms-flex: 1 1 auto; flex: 1 1 auto; display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; - -webkit-flex-flow: row nowrap; -ms-flex-flow: row nowrap; flex-flow: row nowrap; -webkit-box-align: center; - -webkit-align-items: center; -ms-flex-align: center; align-items: center; width: 100%; @@ -5345,14 +5375,12 @@ } .ideditor .form-field-input-radio > label > input[type="radio"] { -webkit-box-flex: 0; - -webkit-flex: 0 1 auto; -ms-flex: 0 1 auto; flex: 0 1 auto; width: 20px; } .ideditor .form-field-input-radio > label > span { -webkit-box-flex: 1; - -webkit-flex: 1 1 auto; -ms-flex: 1 1 auto; flex: 1 1 auto; overflow: hidden; @@ -5378,21 +5406,18 @@ .ideditor .form-field-input-roadheight input.roadheight-number, .ideditor .form-field-input-roadheight input.roadheight-secondary-number, .ideditor .form-field-input-roadspeed input.roadspeed-number { - -webkit-flex-basis: 0; - -ms-flex-preferred-size: 0; - flex-basis: 0; + -ms-flex-preferred-size: 0; + flex-basis: 0; } .ideditor .form-field-input-roadheight input.roadheight-unit, .ideditor .form-field-input-roadheight input.roadheight-secondary-unit { -webkit-box-flex: 0; - -webkit-flex: 0 1 auto; -ms-flex: 0 1 auto; flex: 0 1 auto; width: 60px; } .ideditor .form-field-input-roadspeed input.roadspeed-unit { -webkit-box-flex: 0; - -webkit-flex: 0 1 auto; -ms-flex: 0 1 auto; flex: 0 1 auto; width: 80px; @@ -5444,9 +5469,8 @@ /* nested subfields for name in different languages */ .ideditor .localized-multilingual { padding: 0 10px; - -webkit-flex-basis: 100%; - -ms-flex-preferred-size: 100%; - flex-basis: 100%; + -ms-flex-preferred-size: 100%; + flex-basis: 100%; } .ideditor .localized-multilingual .entry { position: relative; @@ -5483,16 +5507,13 @@ ------------------------------------------------------- */ .ideditor .form-field-input-address { -webkit-box-flex: 1; - -webkit-flex: 1 1 auto; -ms-flex: 1 1 auto; flex: 1 1 auto; display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; - -webkit-flex-flow: row wrap; -ms-flex-flow: row wrap; flex-flow: row wrap; border: 1px solid #ccc; @@ -5501,11 +5522,9 @@ .ideditor .addr-row { -webkit-box-flex: 1; - -webkit-flex: 1 1 auto; -ms-flex: 1 1 auto; flex: 1 1 auto; display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; width: 100%; @@ -5513,7 +5532,6 @@ .ideditor .addr-row > input { -webkit-box-flex: 1; - -webkit-flex: 1 1 auto; -ms-flex: 1 1 auto; flex: 1 1 auto; border-radius: 0; @@ -5552,16 +5570,13 @@ ------------------------------------------------------- */ .ideditor .form-field-input-wikipedia { display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; - -webkit-flex-flow: row wrap; -ms-flex-flow: row wrap; flex-flow: row wrap; -webkit-box-flex: 1; - -webkit-flex: 1 1 auto; -ms-flex: 1 1 auto; flex: 1 1 auto; } @@ -5569,16 +5584,13 @@ .ideditor .wiki-lang-container, .ideditor .wiki-title-container { display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; - -webkit-flex-flow: row nowrap; -ms-flex-flow: row nowrap; flex-flow: row nowrap; -webkit-box-flex: 1; - -webkit-flex: 1 1 auto; -ms-flex: 1 1 auto; flex: 1 1 auto; width: 100%; @@ -5587,7 +5599,6 @@ .ideditor .wiki-lang-container > input.wiki-lang, .ideditor .wiki-title-container > input.wiki-title { -webkit-box-flex: 1; - -webkit-flex: 1 1 auto; -ms-flex: 1 1 auto; flex: 1 1 auto; border-top: 0; @@ -5780,9 +5791,8 @@ height: 5px; width: 30px !important; margin-left: -30px; - -webkit-align-self: center; - -ms-flex-item-align: center; - align-self: center; + -ms-flex-item-align: center; + align-self: center; vertical-align: middle; cursor: pointer; } @@ -5927,20 +5937,16 @@ .ideditor .more-fields label { display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; - -webkit-flex-flow: row nowrap; -ms-flex-flow: row nowrap; flex-flow: row nowrap; -webkit-box-pack: justify; - -webkit-justify-content: space-between; -ms-flex-pack: justify; justify-content: space-between; -webkit-box-align: center; - -webkit-align-items: center; -ms-flex-align: center; align-items: center; } @@ -5948,7 +5954,6 @@ .ideditor .more-fields input { margin-left: 10px; -webkit-box-flex: 1; - -webkit-flex: 1 1 auto; -ms-flex: 1 1 auto; flex: 1 1 auto; } @@ -5967,23 +5972,19 @@ ------------------------------------------------------- */ .ideditor .raw-tag-options { display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; - -webkit-flex-flow: row nowrap; -ms-flex-flow: row nowrap; flex-flow: row nowrap; -webkit-box-pack: end; - -webkit-justify-content: flex-end; -ms-flex-pack: end; justify-content: flex-end; margin-top: -28px; } .ideditor button.raw-tag-option { -webkit-box-flex: 0; - -webkit-flex: 0 0 auto; -ms-flex: 0 0 auto; flex: 0 0 auto; padding: 3px; @@ -6039,12 +6040,10 @@ } .ideditor .tag-row .inner-wrap { display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; - -webkit-flex-flow: row nowrap; -ms-flex-flow: row nowrap; flex-flow: row nowrap; width: 100%; @@ -6053,7 +6052,6 @@ .ideditor .tag-row .key-wrap, .ideditor .tag-row .value-wrap { -webkit-box-flex: 1; - -webkit-flex: 1 1 50%; -ms-flex: 1 1 50%; flex: 1 1 50%; } @@ -6107,7 +6105,6 @@ } .ideditor .tag-row button { -webkit-box-flex: 0; - -webkit-flex: 0 0 auto; -ms-flex: 0 0 auto; flex: 0 0 auto; width: 32px; @@ -6171,7 +6168,6 @@ .ideditor .tag-reference-body { -webkit-box-flex: 1; - -webkit-flex: 1 1 auto; -ms-flex: 1 1 auto; flex: 1 1 auto; width: 100%; @@ -6257,7 +6253,6 @@ .ideditor .member-row-new .member-entity-input { -webkit-box-flex: 1; - -webkit-flex: 1 1 100%; -ms-flex: 1 1 100%; flex: 1 1 100%; border-radius: 4px 4px 0 0; @@ -6275,13 +6270,11 @@ /* add tag, add relation buttons */ .ideditor .add-row { display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; width: 100%; -webkit-box-orient: horizontal; -webkit-box-direction: normal; - -webkit-flex-flow: row nowrap; -ms-flex-flow: row nowrap; flex-flow: row nowrap; } @@ -6289,13 +6282,11 @@ .ideditor .add-row .add-relation, .ideditor .add-row .space-value { -webkit-box-flex: 1; - -webkit-flex: 1 1 50%; -ms-flex: 1 1 50%; flex: 1 1 50%; } .ideditor .add-row .space-buttons { -webkit-box-flex: 0; - -webkit-flex: 0 0 62px; -ms-flex: 0 0 62px; flex: 0 0 62px; } @@ -6330,16 +6321,13 @@ border-radius: 5px; border: 1px solid #ccc; display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; - -webkit-flex-flow: row nowrap; -ms-flex-flow: row nowrap; flex-flow: row nowrap; -webkit-box-align: center; - -webkit-align-items: center; -ms-flex-align: center; align-items: center; } @@ -6349,7 +6337,6 @@ background-color: #fff; padding: 10px; -webkit-box-flex: 0; - -webkit-flex: 0 0 auto; -ms-flex: 0 0 auto; flex: 0 0 auto; position: relative; @@ -6386,7 +6373,6 @@ background-color: #f6f6f6; padding: 0 15px; -webkit-box-flex: 1; - -webkit-flex: 1 1 100%; -ms-flex: 1 1 100%; flex: 1 1 100%; font-size: 14px; @@ -6415,19 +6401,16 @@ border: 1px solid #ccc; margin: 10px auto; display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; - -webkit-flex-flow: row nowrap; -ms-flex-flow: row nowrap; flex-flow: row nowrap; } .ideditor .comment-avatar { padding: 10px; -webkit-box-flex: 0; - -webkit-flex: 0 0 auto; -ms-flex: 0 0 auto; flex: 0 0 auto; } @@ -6442,12 +6425,10 @@ .ideditor .comment-main { padding: 10px 10px 10px 0; -webkit-box-flex: 1; - -webkit-flex: 1 1 100%; -ms-flex: 1 1 100%; flex: 1 1 100%; -webkit-box-orient: vertical; -webkit-box-direction: normal; - -webkit-flex-flow: column nowrap; -ms-flex-flow: column nowrap; flex-flow: column nowrap; overflow: hidden; @@ -6460,11 +6441,9 @@ .ideditor .comment-metadata { -webkit-box-orient: horizontal; -webkit-box-direction: normal; - -webkit-flex-flow: row nowrap; -ms-flex-flow: row nowrap; flex-flow: row nowrap; -webkit-box-pack: justify; - -webkit-justify-content: space-between; -ms-flex-pack: justify; justify-content: space-between; } @@ -6497,12 +6476,10 @@ border-radius: 4px; border: 1px solid #ccc; display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: vertical; -webkit-box-direction: normal; - -webkit-flex-direction: column; -ms-flex-direction: column; flex-direction: column; } @@ -6547,16 +6524,13 @@ border-radius: 5px; border: 1px solid #ccc; display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; - -webkit-flex-flow: row nowrap; -ms-flex-flow: row nowrap; flex-flow: row nowrap; -webkit-box-align: center; - -webkit-align-items: center; -ms-flex-align: center; align-items: center; } @@ -6565,7 +6539,6 @@ background-color: #fff; padding: 10px; -webkit-box-flex: 0; - -webkit-flex: 0 0 auto; -ms-flex: 0 0 auto; flex: 0 0 auto; position: relative; @@ -6589,7 +6562,6 @@ background-color: #f6f6f6; padding: 0 15px; -webkit-box-flex: 1; - -webkit-flex: 1 1 100%; -ms-flex: 1 1 100%; flex: 1 1 100%; font-size: 14px; @@ -6615,16 +6587,13 @@ height: 100%; pointer-events: none; display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: reverse; - -webkit-flex-direction: row-reverse; -ms-flex-direction: row-reverse; flex-direction: row-reverse; -webkit-box-align: end; - -webkit-align-items: flex-end; -ms-flex-align: end; align-items: flex-end; overflow: hidden; @@ -6642,29 +6611,37 @@ /* Map Controls ------------------------------------------------------- */ +.ideditor .map-controls-wrap { + position: absolute; + left: 0; + right: 0; + height: 100%; + z-index: 100; + display: block; + overflow-x: hidden; + overflow-y: auto; + pointer-events: none; + -ms-overflow-style: none; + scrollbar-width: none; +} +.ideditor .map-controls-wrap::-webkit-scrollbar { + display: none; +} .ideditor .map-controls { right: 0; top: 0; width: 40px; position: absolute; - z-index: 100; bottom: 0; display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: vertical; -webkit-box-direction: normal; - -webkit-flex-direction: column; -ms-flex-direction: column; flex-direction: column; padding: 5px 0; pointer-events: none; - overflow-x: hidden; - overflow-y: auto; -} -.ideditor .map-controls::-webkit-scrollbar { - display: none; } .ideditor .map-controls:before { content: ''; @@ -6674,7 +6651,6 @@ height: 100%; max-height: 70px; -webkit-box-flex: 0; - -webkit-flex: 0 1 auto; -ms-flex: 0 1 auto; flex: 0 1 auto; } @@ -6686,12 +6662,10 @@ .ideditor .map-control { position: relative; display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: vertical; -webkit-box-direction: normal; - -webkit-flex-direction: column; -ms-flex-direction: column; flex-direction: column; } @@ -6819,7 +6793,6 @@ color: #7092ff; position: relative; display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; } @@ -6859,7 +6832,6 @@ .ideditor .layer-list li.best > div.best { padding: 5px; -webkit-box-flex: 0; - -webkit-flex: 0 0 auto; -ms-flex: 0 0 auto; flex: 0 0 auto; } @@ -6879,15 +6851,12 @@ padding: 5px 10px; cursor: pointer; -webkit-box-flex: 1; - -webkit-flex: 1 1 auto; -ms-flex: 1 1 auto; flex: 1 1 auto; display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-align: center; - -webkit-align-items: center; -ms-flex-align: center; align-items: center; overflow: hidden; @@ -6907,7 +6876,6 @@ -o-text-overflow: ellipsis; text-overflow: ellipsis; -webkit-box-flex: 1; - -webkit-flex-grow: 1; -ms-flex-positive: 1; flex-grow: 1; } @@ -6963,12 +6931,10 @@ .ideditor .issue-label .issue-text { width: 100%; display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; - -webkit-flex-flow: row nowrap; -ms-flex-flow: row nowrap; flex-flow: row nowrap; cursor: pointer; @@ -6978,21 +6944,18 @@ .ideditor .issue-text .issue-icon { -webkit-box-flex: 0; - -webkit-flex: 0 0 auto; -ms-flex: 0 0 auto; flex: 0 0 auto; padding: 2px 3px; } .ideditor .issue-text .issue-message { -webkit-box-flex: 1; - -webkit-flex: 1 1 auto; -ms-flex: 1 1 auto; flex: 1 1 auto; padding: 4px 5px; } .ideditor .issue-label .issue-autofix { -webkit-box-flex: 0; - -webkit-flex: 0 0 auto; -ms-flex: 0 0 auto; flex: 0 0 auto; padding: 5px 8px; @@ -7001,7 +6964,6 @@ height: unset; width: 32px; -webkit-box-flex: 0; - -webkit-flex: 0 0 auto; -ms-flex: 0 0 auto; flex: 0 0 auto; border-left: 1px solid #ccc; @@ -7026,7 +6988,6 @@ .ideditor button.autofix.action { -webkit-box-flex: 0; - -webkit-flex: 0 0 20px; -ms-flex: 0 0 20px; flex: 0 0 20px; height: 20px; @@ -7048,16 +7009,13 @@ /* fix all */ .ideditor .autofix-all { display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; - -webkit-flex-flow: row nowrap; -ms-flex-flow: row nowrap; flex-flow: row nowrap; -webkit-box-pack: end; - -webkit-justify-content: flex-end; -ms-flex-pack: end; justify-content: flex-end; margin-top: -25px; @@ -7215,16 +7173,13 @@ } .ideditor .section-footer { display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; - -webkit-flex-flow: row nowrap; -ms-flex-flow: row nowrap; flex-flow: row nowrap; -webkit-box-pack: end; - -webkit-justify-content: flex-end; -ms-flex-pack: end; justify-content: flex-end; height: 30px; @@ -7239,7 +7194,6 @@ background: #c6ffca; padding: 5px !important; display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; } @@ -7343,7 +7297,6 @@ .ideditor .issue-info { -webkit-box-flex: 1; - -webkit-flex: 1 1 auto; -ms-flex: 1 1 auto; flex: 1 1 auto; width: 100%; @@ -7386,22 +7339,21 @@ padding: 10px; } -.ideditor .display-control h5 { +.ideditor .display-options-container label { padding-bottom: 0; padding-top: 10px; } -.ideditor .display-control h5 span { +.ideditor .display-options-container label span { + font-weight: bold; margin: 5px; } .ideditor .display-control .control-wrap { display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-align: center; - -webkit-align-items: center; -ms-flex-align: center; align-items: center; width: 100%; @@ -7409,7 +7361,6 @@ .ideditor .display-control .display-option-input { height: 20px; -webkit-box-flex: 1; - -webkit-flex: 1 1 100%; -ms-flex: 1 1 100%; flex: 1 1 100%; } @@ -7422,7 +7373,6 @@ vertical-align: text-bottom; border-radius: 4px; -webkit-box-flex: 0; - -webkit-flex: 0 0 auto; -ms-flex: 0 0 auto; flex: 0 0 auto; } @@ -7453,15 +7403,12 @@ border-radius: 2px; padding: 20px 0; display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-pack: center; - -webkit-justify-content: center; -ms-flex-pack: center; justify-content: center; -webkit-box-align: center; - -webkit-align-items: center; -ms-flex-align: center; align-items: center; margin: 45px; @@ -7586,7 +7533,6 @@ ------------------------------------------------------- */ .ideditor .map-panes { -webkit-box-flex: 0; - -webkit-flex: 0 1 auto; -ms-flex: 0 1 auto; flex: 0 1 auto; position: relative; @@ -7601,12 +7547,10 @@ height: 100%; z-index: 10; display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: vertical; -webkit-box-direction: normal; - -webkit-flex-direction: column; -ms-flex-direction: column; flex-direction: column; } @@ -7617,21 +7561,17 @@ .ideditor .pane-heading { display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; - -webkit-flex-flow: row nowrap; -ms-flex-flow: row nowrap; flex-flow: row nowrap; -webkit-box-pack: justify; - -webkit-justify-content: space-between; -ms-flex-pack: justify; justify-content: space-between; border-bottom: 1px solid #ccc; -webkit-box-flex: 0; - -webkit-flex: 0 0 auto; -ms-flex: 0 0 auto; flex: 0 0 auto; } @@ -8121,16 +8061,13 @@ ------------------------------------------------------- */ .ideditor .info-panels { display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; - -webkit-flex-flow: row wrap-reverse; -ms-flex-flow: row wrap-reverse; flex-flow: row wrap-reverse; -webkit-box-pack: end; - -webkit-justify-content: flex-end; -ms-flex-pack: end; justify-content: flex-end; width: 100%; @@ -8157,7 +8094,6 @@ .ideditor .panel-container { -webkit-box-flex: 0; - -webkit-flex: 0 0 auto; -ms-flex: 0 0 auto; flex: 0 0 auto; margin: 0 2px 2px 0; @@ -8176,11 +8112,9 @@ .ideditor .panel-title { padding: 5px 10px; display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-pack: justify; - -webkit-justify-content: space-between; -ms-flex-pack: justify; justify-content: space-between; } @@ -8259,17 +8193,14 @@ border-radius: 0; pointer-events: none; display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: vertical; -webkit-box-direction: normal; - -webkit-flex-direction: column; -ms-flex-direction: column; flex-direction: column; -ms-user-select: element; -webkit-box-flex: 0; - -webkit-flex: 0 0 auto; -ms-flex: 0 0 auto; flex: 0 0 auto; } @@ -8284,20 +8215,16 @@ .ideditor .main-footer-wrap, .ideditor .flash-wrap { display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-flex: 0; - -webkit-flex: 0 0 100%; -ms-flex: 0 0 100%; flex: 0 0 100%; -webkit-box-orient: horizontal; -webkit-box-direction: normal; - -webkit-flex-flow: row nowrap; -ms-flex-flow: row nowrap; flex-flow: row nowrap; -webkit-box-pack: justify; - -webkit-justify-content: space-between; -ms-flex-pack: justify; justify-content: space-between; height: 100%; @@ -8329,15 +8256,12 @@ left: 5px; right: 5px; display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-pack: justify; - -webkit-justify-content: space-between; -ms-flex-pack: justify; justify-content: space-between; -webkit-box-align: end; - -webkit-align-items: flex-end; -ms-flex-align: end; align-items: flex-end; z-index: 0; @@ -8390,20 +8314,16 @@ ------------------------------------------------------- */ .ideditor .flash-content { display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-flex: 1; - -webkit-flex: 1 0 auto; -ms-flex: 1 0 auto; flex: 1 0 auto; -webkit-box-orient: horizontal; -webkit-box-direction: normal; - -webkit-flex-flow: row nowrap; -ms-flex-flow: row nowrap; flex-flow: row nowrap; -webkit-box-align: center; - -webkit-align-items: center; -ms-flex-align: center; align-items: center; padding: 2px; @@ -8411,7 +8331,6 @@ .ideditor .flash-icon { -webkit-box-flex: 0; - -webkit-flex: 0 0 auto; -ms-flex: 0 0 auto; flex: 0 0 auto; width: 20px; @@ -8438,7 +8357,6 @@ .ideditor .flash-text { -webkit-box-flex: 1; - -webkit-flex: 1 1 auto; -ms-flex: 1 1 auto; flex: 1 1 auto; } @@ -8449,7 +8367,6 @@ vertical-align: bottom; width: 250px; -webkit-box-flex: 0; - -webkit-flex: 0 0 auto; -ms-flex: 0 0 auto; flex: 0 0 auto; -webkit-user-select: none; @@ -8457,9 +8374,8 @@ -ms-user-select: none; user-select: none; height: 30px; - -webkit-align-self: center; - -ms-flex-item-align: center; - align-self: center; + -ms-flex-item-align: center; + align-self: center; } .ideditor .scale-block .scale { @@ -8492,7 +8408,6 @@ ------------------------------------------------------- */ .ideditor .map-footer-bar .info-block { -webkit-box-flex: 1; - -webkit-flex: 1 1 100%; -ms-flex: 1 1 100%; flex: 1 1 100%; overflow: hidden; @@ -8500,17 +8415,14 @@ .ideditor .map-footer-list { display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; - -webkit-flex-flow: row nowrap; -ms-flex-flow: row nowrap; flex-flow: row nowrap; height: 100%; -webkit-box-pack: end; - -webkit-justify-content: flex-end; -ms-flex-pack: end; justify-content: flex-end; } @@ -8518,11 +8430,9 @@ .ideditor .map-footer-list li { height: 100%; display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-align: center; - -webkit-align-items: center; -ms-flex-align: center; align-items: center; white-space: nowrap; @@ -8583,7 +8493,6 @@ padding: 1px 10px; color: #eee; -webkit-box-flex: 1; - -webkit-flex: 1 1 auto; -ms-flex: 1 1 auto; flex: 1 1 auto; } @@ -8620,7 +8529,6 @@ /* For an icon (e.g. new version) */ .ideditor .badge { display: -webkit-inline-box; - display: -webkit-inline-flex; display: -ms-inline-flexbox; display: inline-flex; background: #d32232; @@ -8628,11 +8536,9 @@ height: 21px; border-radius: 50%; -webkit-box-align: center; - -webkit-align-items: center; -ms-flex-align: center; align-items: center; -webkit-box-pack: center; - -webkit-justify-content: center; -ms-flex-pack: center; justify-content: center; } @@ -8648,7 +8554,6 @@ height: 11px; color: #fff; -webkit-box-flex: 0; - -webkit-flex: 0 0 auto; -ms-flex: 0 0 auto; flex: 0 0 auto; } @@ -8686,12 +8591,10 @@ min-width: 200px; max-width: 550px; display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: vertical; -webkit-box-direction: normal; - -webkit-flex-direction: column; -ms-flex-direction: column; flex-direction: column; } @@ -8749,15 +8652,12 @@ .ideditor .save-section .buttons { display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; - -webkit-flex-wrap: wrap; - -ms-flex-wrap: wrap; - flex-wrap: wrap; - -webkit-justify-content: space-around; - -ms-flex-pack: distribute; - justify-content: space-around; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + -ms-flex-pack: distribute; + justify-content: space-around; } .ideditor .save-section .buttons .action, @@ -8773,7 +8673,6 @@ } .ideditor .modal-actions { display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; } @@ -8917,6 +8816,14 @@ color: #7092ff; } +.ideditor .modal-splash .section-preferences-third-party { + margin-top: 20px; +} + +.ideditor .modal-splash .section-preferences-third-party .privacy-link { + display: none; +} + /* Shortcuts Modal ------------------------------------------------------- */ @@ -8962,17 +8869,14 @@ .ideditor .modal-shortcuts .shortcut-tab { display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; - -webkit-flex-flow: row wrap; -ms-flex-flow: row wrap; flex-flow: row wrap; - -webkit-justify-content: space-around; - -ms-flex-pack: distribute; - justify-content: space-around; + -ms-flex-pack: distribute; + justify-content: space-around; } .ideditor .modal-shortcuts .shortcut-column { @@ -8981,7 +8885,6 @@ .ideditor .modal-shortcuts .shortcut-tab-tools .shortcut-column { -webkit-box-flex: 1; - -webkit-flex: 1 1 100%; -ms-flex: 1 1 100%; flex: 1 1 100%; width: 100%; @@ -9341,22 +9244,26 @@ /* dark tooltips for sidebar / panels */ .ideditor .tooltip.dark.top .popover-arrow, .ideditor .map-pane .tooltip.top .popover-arrow, -.ideditor .sidebar .tooltip.top .popover-arrow { +.ideditor .sidebar .tooltip.top .popover-arrow, +.ideditor .modal .tooltip.top .popover-arrow { border-top-color: #000; } .ideditor .tooltip.dark.bottom .popover-arrow, .ideditor .map-pane .tooltip.bottom .popover-arrow, -.ideditor .sidebar .tooltip.bottom .popover-arrow { +.ideditor .sidebar .tooltip.bottom .popover-arrow, +.ideditor .modal .tooltip.bottom .popover-arrow { border-bottom-color: #000; } .ideditor .tooltip.dark.left .popover-arrow, .ideditor .map-pane .tooltip.left .popover-arrow, -.ideditor .sidebar .tooltip.left .popover-arrow { +.ideditor .sidebar .tooltip.left .popover-arrow, +.ideditor .modal .tooltip.left .popover-arrow { border-left-color: #000; } .ideditor .tooltip.dark.right .popover-arrow, .ideditor .map-pane .tooltip.right .popover-arrow, -.ideditor .sidebar .tooltip.right .popover-arrow { +.ideditor .sidebar .tooltip.right .popover-arrow, +.ideditor .modal .tooltip.right .popover-arrow { border-right-color: #000; } .ideditor .tooltip.dark .popover-inner, @@ -9367,7 +9274,8 @@ .ideditor .map-pane .keyhint-wrap, .ideditor .sidebar .popover-inner, .ideditor .sidebar .tooltip-heading, -.ideditor .sidebar .keyhint-wrap { +.ideditor .sidebar .keyhint-wrap, +.ideditor .modal .popover-inner { background: #000; color: #ccc; } @@ -9416,12 +9324,10 @@ .ideditor .edit-menu { position: absolute; display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: vertical; -webkit-box-direction: normal; - -webkit-flex-direction: column; -ms-flex-direction: column; flex-direction: column; background: #fff; @@ -9435,11 +9341,9 @@ .ideditor .edit-menu-item { display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-align: center; - -webkit-align-items: center; -ms-flex-align: center; align-items: center; border-radius: 0; @@ -9524,12 +9428,10 @@ .ideditor .intro-nav-wrap { display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; - -webkit-flex-direction: row; -ms-flex-direction: row; flex-direction: row; position: absolute; @@ -9542,7 +9444,6 @@ .ideditor .intro-nav-wrap .intro-nav-wrap-logo { -webkit-box-flex: 0; - -webkit-flex: 0 0 auto; -ms-flex: 0 0 auto; flex: 0 0 auto; height: 40px; @@ -9554,23 +9455,19 @@ .ideditor .intro-nav-wrap .joined { -webkit-box-flex: 1; - -webkit-flex: 1 1 auto; -ms-flex: 1 1 auto; flex: 1 1 auto; display: -webkit-box; - display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; - -webkit-flex-direction: row; -ms-flex-direction: row; flex-direction: row; } .ideditor .intro-nav-wrap button.chapter { -webkit-box-flex: 1; - -webkit-flex: 1 1 100%; -ms-flex: 1 1 100%; flex: 1 1 100%; padding: 0px 5px; diff --git a/vendor/assets/iD/iD.js b/vendor/assets/iD/iD.js index 929da2dd8..c91915940 100644 --- a/vendor/assets/iD/iD.js +++ b/vendor/assets/iD/iD.js @@ -7,7 +7,7 @@ }; // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028 - var global$F = + var global$1m = // eslint-disable-next-line es/no-global-this -- safe check(typeof globalThis == 'object' && globalThis) || check(typeof window == 'object' && window) || @@ -19,7 +19,7 @@ var objectGetOwnPropertyDescriptor = {}; - var fails$N = function (exec) { + var fails$S = function (exec) { try { return !!exec(); } catch (error) { @@ -27,29 +27,35 @@ } }; - var fails$M = fails$N; + var fails$R = fails$S; // Detect IE8's incomplete defineProperty implementation - var descriptors = !fails$M(function () { + var descriptors = !fails$R(function () { // eslint-disable-next-line es/no-object-defineproperty -- required for testing return Object.defineProperty({}, 1, { get: function () { return 7; } })[1] != 7; }); + var call$q = Function.prototype.call; + + var functionCall = call$q.bind ? call$q.bind(call$q) : function () { + return call$q.apply(call$q, arguments); + }; + var objectPropertyIsEnumerable = {}; - var $propertyIsEnumerable$1 = {}.propertyIsEnumerable; + var $propertyIsEnumerable$2 = {}.propertyIsEnumerable; // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe var getOwnPropertyDescriptor$5 = Object.getOwnPropertyDescriptor; // Nashorn ~ JDK8 bug - var NASHORN_BUG = getOwnPropertyDescriptor$5 && !$propertyIsEnumerable$1.call({ 1: 2 }, 1); + var NASHORN_BUG = getOwnPropertyDescriptor$5 && !$propertyIsEnumerable$2.call({ 1: 2 }, 1); // `Object.prototype.propertyIsEnumerable` method implementation // https://tc39.es/ecma262/#sec-object.prototype.propertyisenumerable objectPropertyIsEnumerable.f = NASHORN_BUG ? function propertyIsEnumerable(V) { var descriptor = getOwnPropertyDescriptor$5(this, V); return !!descriptor && descriptor.enumerable; - } : $propertyIsEnumerable$1; + } : $propertyIsEnumerable$2; var createPropertyDescriptor$7 = function (bitmap, value) { return { @@ -60,30 +66,53 @@ }; }; - var toString$2 = {}.toString; + var FunctionPrototype$3 = Function.prototype; + var bind$h = FunctionPrototype$3.bind; + var call$p = FunctionPrototype$3.call; + var callBind = bind$h && bind$h.bind(call$p); + + var functionUncurryThis = bind$h ? function (fn) { + return fn && callBind(call$p, fn); + } : function (fn) { + return fn && function () { + return call$p.apply(fn, arguments); + }; + }; + + var uncurryThis$X = functionUncurryThis; + + var toString$n = uncurryThis$X({}.toString); + var stringSlice$c = uncurryThis$X(''.slice); var classofRaw$1 = function (it) { - return toString$2.call(it).slice(8, -1); + return stringSlice$c(toString$n(it), 8, -1); }; - var fails$L = fails$N; - var classof$c = classofRaw$1; + var global$1l = global$1m; + var uncurryThis$W = functionUncurryThis; + var fails$Q = fails$S; + var classof$e = classofRaw$1; - var split$1 = ''.split; + var Object$5 = global$1l.Object; + var split$4 = uncurryThis$W(''.split); // fallback for non-array-like ES3 and non-enumerable old V8 strings - var indexedObject = fails$L(function () { + var indexedObject = fails$Q(function () { // throws an error in rhino, see https://github.com/mozilla/rhino/issues/346 // eslint-disable-next-line no-prototype-builtins -- safe - return !Object('z').propertyIsEnumerable(0); + return !Object$5('z').propertyIsEnumerable(0); }) ? function (it) { - return classof$c(it) == 'String' ? split$1.call(it, '') : Object(it); - } : Object; + return classof$e(it) == 'String' ? split$4(it, '') : Object$5(it); + } : Object$5; + + var global$1k = global$1m; + + var TypeError$o = global$1k.TypeError; // `RequireObjectCoercible` abstract operation // https://tc39.es/ecma262/#sec-requireobjectcoercible var requireObjectCoercible$e = function (it) { - if (it == undefined) throw TypeError("Can't call method on " + it); + if (it == undefined) throw TypeError$o("Can't call method on " + it); return it; }; @@ -91,74 +120,316 @@ var IndexedObject$4 = indexedObject; var requireObjectCoercible$d = requireObjectCoercible$e; - var toIndexedObject$b = function (it) { + var toIndexedObject$c = function (it) { return IndexedObject$4(requireObjectCoercible$d(it)); }; - var isObject$r = function (it) { - return typeof it === 'object' ? it !== null : typeof it === 'function'; + // `IsCallable` abstract operation + // https://tc39.es/ecma262/#sec-iscallable + var isCallable$r = function (argument) { + return typeof argument == 'function'; }; - var isObject$q = isObject$r; + var isCallable$q = isCallable$r; - // `ToPrimitive` abstract operation - // https://tc39.es/ecma262/#sec-toprimitive - // instead of the ES6 spec version, we didn't implement @@toPrimitive case - // and the second argument - flag - preferred type is a string - var toPrimitive$7 = function (input, PREFERRED_STRING) { - if (!isObject$q(input)) return input; + var isObject$s = function (it) { + return typeof it == 'object' ? it !== null : isCallable$q(it); + }; + + var global$1j = global$1m; + var isCallable$p = isCallable$r; + + var aFunction = function (argument) { + return isCallable$p(argument) ? argument : undefined; + }; + + var getBuiltIn$b = function (namespace, method) { + return arguments.length < 2 ? aFunction(global$1j[namespace]) : global$1j[namespace] && global$1j[namespace][method]; + }; + + var uncurryThis$V = functionUncurryThis; + + var objectIsPrototypeOf = uncurryThis$V({}.isPrototypeOf); + + var getBuiltIn$a = getBuiltIn$b; + + var engineUserAgent = getBuiltIn$a('navigator', 'userAgent') || ''; + + var global$1i = global$1m; + var userAgent$7 = engineUserAgent; + + var process$4 = global$1i.process; + var Deno = global$1i.Deno; + var versions = process$4 && process$4.versions || Deno && Deno.version; + var v8 = versions && versions.v8; + var match, version$1; + + if (v8) { + match = v8.split('.'); + // in old Chrome, versions of V8 isn't V8 = Chrome / 10 + // but their correct versions are not interesting for us + version$1 = match[0] > 0 && match[0] < 4 ? 1 : +(match[0] + match[1]); + } + + // BrowserFS NodeJS `process` polyfill incorrectly set `.v8` to `0.0` + // so check `userAgent` even if `.v8` exists, but 0 + if (!version$1 && userAgent$7) { + match = userAgent$7.match(/Edge\/(\d+)/); + if (!match || match[1] >= 74) { + match = userAgent$7.match(/Chrome\/(\d+)/); + if (match) version$1 = +match[1]; + } + } + + var engineV8Version = version$1; + + /* eslint-disable es/no-symbol -- required for testing */ + + var V8_VERSION$3 = engineV8Version; + var fails$P = fails$S; + + // eslint-disable-next-line es/no-object-getownpropertysymbols -- required for testing + var nativeSymbol = !!Object.getOwnPropertySymbols && !fails$P(function () { + var symbol = Symbol(); + // Chrome 38 Symbol has incorrect toString conversion + // `get-own-property-symbols` polyfill symbols converted to object are not Symbol instances + return !String(symbol) || !(Object(symbol) instanceof Symbol) || + // Chrome 38-40 symbols are not inherited from DOM collections prototypes to instances + !Symbol.sham && V8_VERSION$3 && V8_VERSION$3 < 41; + }); + + /* eslint-disable es/no-symbol -- required for testing */ + + var NATIVE_SYMBOL$3 = nativeSymbol; + + var useSymbolAsUid = NATIVE_SYMBOL$3 + && !Symbol.sham + && typeof Symbol.iterator == 'symbol'; + + var global$1h = global$1m; + var getBuiltIn$9 = getBuiltIn$b; + var isCallable$o = isCallable$r; + var isPrototypeOf$9 = objectIsPrototypeOf; + var USE_SYMBOL_AS_UID$1 = useSymbolAsUid; + + var Object$4 = global$1h.Object; + + var isSymbol$6 = USE_SYMBOL_AS_UID$1 ? function (it) { + return typeof it == 'symbol'; + } : function (it) { + var $Symbol = getBuiltIn$9('Symbol'); + return isCallable$o($Symbol) && isPrototypeOf$9($Symbol.prototype, Object$4(it)); + }; + + var global$1g = global$1m; + + var String$6 = global$1g.String; + + var tryToString$5 = function (argument) { + try { + return String$6(argument); + } catch (error) { + return 'Object'; + } + }; + + var global$1f = global$1m; + var isCallable$n = isCallable$r; + var tryToString$4 = tryToString$5; + + var TypeError$n = global$1f.TypeError; + + // `Assert: IsCallable(argument) is true` + var aCallable$a = function (argument) { + if (isCallable$n(argument)) return argument; + throw TypeError$n(tryToString$4(argument) + ' is not a function'); + }; + + var aCallable$9 = aCallable$a; + + // `GetMethod` abstract operation + // https://tc39.es/ecma262/#sec-getmethod + var getMethod$7 = function (V, P) { + var func = V[P]; + return func == null ? undefined : aCallable$9(func); + }; + + var global$1e = global$1m; + var call$o = functionCall; + var isCallable$m = isCallable$r; + var isObject$r = isObject$s; + + var TypeError$m = global$1e.TypeError; + + // `OrdinaryToPrimitive` abstract operation + // https://tc39.es/ecma262/#sec-ordinarytoprimitive + var ordinaryToPrimitive$1 = function (input, pref) { var fn, val; - if (PREFERRED_STRING && typeof (fn = input.toString) == 'function' && !isObject$q(val = fn.call(input))) return val; - if (typeof (fn = input.valueOf) == 'function' && !isObject$q(val = fn.call(input))) return val; - if (!PREFERRED_STRING && typeof (fn = input.toString) == 'function' && !isObject$q(val = fn.call(input))) return val; - throw TypeError("Can't convert object to primitive value"); + if (pref === 'string' && isCallable$m(fn = input.toString) && !isObject$r(val = call$o(fn, input))) return val; + if (isCallable$m(fn = input.valueOf) && !isObject$r(val = call$o(fn, input))) return val; + if (pref !== 'string' && isCallable$m(fn = input.toString) && !isObject$r(val = call$o(fn, input))) return val; + throw TypeError$m("Can't convert object to primitive value"); + }; + + var shared$5 = {exports: {}}; + + var isPure = false; + + var global$1d = global$1m; + + // eslint-disable-next-line es/no-object-defineproperty -- safe + var defineProperty$b = Object.defineProperty; + + var setGlobal$3 = function (key, value) { + try { + defineProperty$b(global$1d, key, { value: value, configurable: true, writable: true }); + } catch (error) { + global$1d[key] = value; + } return value; }; + var global$1c = global$1m; + var setGlobal$2 = setGlobal$3; + + var SHARED = '__core-js_shared__'; + var store$4 = global$1c[SHARED] || setGlobal$2(SHARED, {}); + + var sharedStore = store$4; + + var store$3 = sharedStore; + + (shared$5.exports = function (key, value) { + return store$3[key] || (store$3[key] = value !== undefined ? value : {}); + })('versions', []).push({ + version: '3.19.1', + mode: 'global', + copyright: '© 2021 Denis Pushkarev (zloirock.ru)' + }); + + var global$1b = global$1m; var requireObjectCoercible$c = requireObjectCoercible$e; + var Object$3 = global$1b.Object; + // `ToObject` abstract operation // https://tc39.es/ecma262/#sec-toobject - var toObject$i = function (argument) { - return Object(requireObjectCoercible$c(argument)); + var toObject$j = function (argument) { + return Object$3(requireObjectCoercible$c(argument)); + }; + + var uncurryThis$U = functionUncurryThis; + var toObject$i = toObject$j; + + var hasOwnProperty$3 = uncurryThis$U({}.hasOwnProperty); + + // `HasOwnProperty` abstract operation + // https://tc39.es/ecma262/#sec-hasownproperty + var hasOwnProperty_1 = Object.hasOwn || function hasOwn(it, key) { + return hasOwnProperty$3(toObject$i(it), key); }; - var toObject$h = toObject$i; + var uncurryThis$T = functionUncurryThis; + + var id$2 = 0; + var postfix = Math.random(); + var toString$m = uncurryThis$T(1.0.toString); + + var uid$5 = function (key) { + return 'Symbol(' + (key === undefined ? '' : key) + ')_' + toString$m(++id$2 + postfix, 36); + }; - var hasOwnProperty$3 = {}.hasOwnProperty; + var global$1a = global$1m; + var shared$4 = shared$5.exports; + var hasOwn$l = hasOwnProperty_1; + var uid$4 = uid$5; + var NATIVE_SYMBOL$2 = nativeSymbol; + var USE_SYMBOL_AS_UID = useSymbolAsUid; - var has$j = Object.hasOwn || function hasOwn(it, key) { - return hasOwnProperty$3.call(toObject$h(it), key); + var WellKnownSymbolsStore$1 = shared$4('wks'); + var Symbol$3 = global$1a.Symbol; + var symbolFor = Symbol$3 && Symbol$3['for']; + var createWellKnownSymbol = USE_SYMBOL_AS_UID ? Symbol$3 : Symbol$3 && Symbol$3.withoutSetter || uid$4; + + var wellKnownSymbol$t = function (name) { + if (!hasOwn$l(WellKnownSymbolsStore$1, name) || !(NATIVE_SYMBOL$2 || typeof WellKnownSymbolsStore$1[name] == 'string')) { + var description = 'Symbol.' + name; + if (NATIVE_SYMBOL$2 && hasOwn$l(Symbol$3, name)) { + WellKnownSymbolsStore$1[name] = Symbol$3[name]; + } else if (USE_SYMBOL_AS_UID && symbolFor) { + WellKnownSymbolsStore$1[name] = symbolFor(description); + } else { + WellKnownSymbolsStore$1[name] = createWellKnownSymbol(description); + } + } return WellKnownSymbolsStore$1[name]; }; - var global$E = global$F; - var isObject$p = isObject$r; + var global$19 = global$1m; + var call$n = functionCall; + var isObject$q = isObject$s; + var isSymbol$5 = isSymbol$6; + var getMethod$6 = getMethod$7; + var ordinaryToPrimitive = ordinaryToPrimitive$1; + var wellKnownSymbol$s = wellKnownSymbol$t; + + var TypeError$l = global$19.TypeError; + var TO_PRIMITIVE$1 = wellKnownSymbol$s('toPrimitive'); + + // `ToPrimitive` abstract operation + // https://tc39.es/ecma262/#sec-toprimitive + var toPrimitive$3 = function (input, pref) { + if (!isObject$q(input) || isSymbol$5(input)) return input; + var exoticToPrim = getMethod$6(input, TO_PRIMITIVE$1); + var result; + if (exoticToPrim) { + if (pref === undefined) pref = 'default'; + result = call$n(exoticToPrim, input, pref); + if (!isObject$q(result) || isSymbol$5(result)) return result; + throw TypeError$l("Can't convert object to primitive value"); + } + if (pref === undefined) pref = 'number'; + return ordinaryToPrimitive(input, pref); + }; - var document$3 = global$E.document; + var toPrimitive$2 = toPrimitive$3; + var isSymbol$4 = isSymbol$6; + + // `ToPropertyKey` abstract operation + // https://tc39.es/ecma262/#sec-topropertykey + var toPropertyKey$5 = function (argument) { + var key = toPrimitive$2(argument, 'string'); + return isSymbol$4(key) ? key : key + ''; + }; + + var global$18 = global$1m; + var isObject$p = isObject$s; + + var document$3 = global$18.document; // typeof document.createElement is 'object' in old IE - var EXISTS = isObject$p(document$3) && isObject$p(document$3.createElement); + var EXISTS$1 = isObject$p(document$3) && isObject$p(document$3.createElement); - var documentCreateElement$1 = function (it) { - return EXISTS ? document$3.createElement(it) : {}; + var documentCreateElement$2 = function (it) { + return EXISTS$1 ? document$3.createElement(it) : {}; }; - var DESCRIPTORS$m = descriptors; - var fails$K = fails$N; - var createElement$1 = documentCreateElement$1; + var DESCRIPTORS$n = descriptors; + var fails$O = fails$S; + var createElement$1 = documentCreateElement$2; // Thank's IE8 for his funny defineProperty - var ie8DomDefine = !DESCRIPTORS$m && !fails$K(function () { + var ie8DomDefine = !DESCRIPTORS$n && !fails$O(function () { // eslint-disable-next-line es/no-object-defineproperty -- requied for testing return Object.defineProperty(createElement$1('div'), 'a', { get: function () { return 7; } }).a != 7; }); - var DESCRIPTORS$l = descriptors; + var DESCRIPTORS$m = descriptors; + var call$m = functionCall; var propertyIsEnumerableModule$2 = objectPropertyIsEnumerable; var createPropertyDescriptor$6 = createPropertyDescriptor$7; - var toIndexedObject$a = toIndexedObject$b; - var toPrimitive$6 = toPrimitive$7; - var has$i = has$j; + var toIndexedObject$b = toIndexedObject$c; + var toPropertyKey$4 = toPropertyKey$5; + var hasOwn$k = hasOwnProperty_1; var IE8_DOM_DEFINE$1 = ie8DomDefine; // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe @@ -166,225 +437,220 @@ // `Object.getOwnPropertyDescriptor` method // https://tc39.es/ecma262/#sec-object.getownpropertydescriptor - objectGetOwnPropertyDescriptor.f = DESCRIPTORS$l ? $getOwnPropertyDescriptor$1 : function getOwnPropertyDescriptor(O, P) { - O = toIndexedObject$a(O); - P = toPrimitive$6(P, true); + objectGetOwnPropertyDescriptor.f = DESCRIPTORS$m ? $getOwnPropertyDescriptor$1 : function getOwnPropertyDescriptor(O, P) { + O = toIndexedObject$b(O); + P = toPropertyKey$4(P); if (IE8_DOM_DEFINE$1) try { return $getOwnPropertyDescriptor$1(O, P); } catch (error) { /* empty */ } - if (has$i(O, P)) return createPropertyDescriptor$6(!propertyIsEnumerableModule$2.f.call(O, P), O[P]); + if (hasOwn$k(O, P)) return createPropertyDescriptor$6(!call$m(propertyIsEnumerableModule$2.f, O, P), O[P]); }; var objectDefineProperty = {}; - var isObject$o = isObject$r; + var global$17 = global$1m; + var isObject$o = isObject$s; - var anObject$m = function (it) { - if (!isObject$o(it)) { - throw TypeError(String(it) + ' is not an object'); - } return it; + var String$5 = global$17.String; + var TypeError$k = global$17.TypeError; + + // `Assert: Type(argument) is Object` + var anObject$n = function (argument) { + if (isObject$o(argument)) return argument; + throw TypeError$k(String$5(argument) + ' is not an object'); }; - var DESCRIPTORS$k = descriptors; + var global$16 = global$1m; + var DESCRIPTORS$l = descriptors; var IE8_DOM_DEFINE = ie8DomDefine; - var anObject$l = anObject$m; - var toPrimitive$5 = toPrimitive$7; + var anObject$m = anObject$n; + var toPropertyKey$3 = toPropertyKey$5; + var TypeError$j = global$16.TypeError; // eslint-disable-next-line es/no-object-defineproperty -- safe var $defineProperty$1 = Object.defineProperty; // `Object.defineProperty` method // https://tc39.es/ecma262/#sec-object.defineproperty - objectDefineProperty.f = DESCRIPTORS$k ? $defineProperty$1 : function defineProperty(O, P, Attributes) { - anObject$l(O); - P = toPrimitive$5(P, true); - anObject$l(Attributes); + objectDefineProperty.f = DESCRIPTORS$l ? $defineProperty$1 : function defineProperty(O, P, Attributes) { + anObject$m(O); + P = toPropertyKey$3(P); + anObject$m(Attributes); if (IE8_DOM_DEFINE) try { return $defineProperty$1(O, P, Attributes); } catch (error) { /* empty */ } - if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported'); + if ('get' in Attributes || 'set' in Attributes) throw TypeError$j('Accessors not supported'); if ('value' in Attributes) O[P] = Attributes.value; return O; }; - var DESCRIPTORS$j = descriptors; + var DESCRIPTORS$k = descriptors; var definePropertyModule$7 = objectDefineProperty; var createPropertyDescriptor$5 = createPropertyDescriptor$7; - var createNonEnumerableProperty$e = DESCRIPTORS$j ? function (object, key, value) { + var createNonEnumerableProperty$b = DESCRIPTORS$k ? function (object, key, value) { return definePropertyModule$7.f(object, key, createPropertyDescriptor$5(1, value)); } : function (object, key, value) { object[key] = value; return object; }; - var redefine$g = {exports: {}}; - - var global$D = global$F; - var createNonEnumerableProperty$d = createNonEnumerableProperty$e; - - var setGlobal$3 = function (key, value) { - try { - createNonEnumerableProperty$d(global$D, key, value); - } catch (error) { - global$D[key] = value; - } return value; - }; - - var global$C = global$F; - var setGlobal$2 = setGlobal$3; - - var SHARED = '__core-js_shared__'; - var store$4 = global$C[SHARED] || setGlobal$2(SHARED, {}); - - var sharedStore = store$4; + var redefine$h = {exports: {}}; - var store$3 = sharedStore; + var uncurryThis$S = functionUncurryThis; + var isCallable$l = isCallable$r; + var store$2 = sharedStore; - var functionToString = Function.toString; + var functionToString$1 = uncurryThis$S(Function.toString); // this helper broken in `core-js@3.4.1-3.4.4`, so we can't use `shared` helper - if (typeof store$3.inspectSource != 'function') { - store$3.inspectSource = function (it) { - return functionToString.call(it); + if (!isCallable$l(store$2.inspectSource)) { + store$2.inspectSource = function (it) { + return functionToString$1(it); }; } - var inspectSource$3 = store$3.inspectSource; - - var global$B = global$F; - var inspectSource$2 = inspectSource$3; - - var WeakMap$1 = global$B.WeakMap; - - var nativeWeakMap = typeof WeakMap$1 === 'function' && /native code/.test(inspectSource$2(WeakMap$1)); - - var shared$5 = {exports: {}}; - - var isPure = false; - - var store$2 = sharedStore; + var inspectSource$4 = store$2.inspectSource; - (shared$5.exports = function (key, value) { - return store$2[key] || (store$2[key] = value !== undefined ? value : {}); - })('versions', []).push({ - version: '3.15.0', - mode: 'global', - copyright: '© 2021 Denis Pushkarev (zloirock.ru)' - }); + var global$15 = global$1m; + var isCallable$k = isCallable$r; + var inspectSource$3 = inspectSource$4; - var id$2 = 0; - var postfix = Math.random(); + var WeakMap$1 = global$15.WeakMap; - var uid$5 = function (key) { - return 'Symbol(' + String(key === undefined ? '' : key) + ')_' + (++id$2 + postfix).toString(36); - }; + var nativeWeakMap = isCallable$k(WeakMap$1) && /native code/.test(inspectSource$3(WeakMap$1)); - var shared$4 = shared$5.exports; - var uid$4 = uid$5; + var shared$3 = shared$5.exports; + var uid$3 = uid$5; - var keys$3 = shared$4('keys'); + var keys$3 = shared$3('keys'); var sharedKey$4 = function (key) { - return keys$3[key] || (keys$3[key] = uid$4(key)); + return keys$3[key] || (keys$3[key] = uid$3(key)); }; var hiddenKeys$6 = {}; var NATIVE_WEAK_MAP = nativeWeakMap; - var global$A = global$F; - var isObject$n = isObject$r; - var createNonEnumerableProperty$c = createNonEnumerableProperty$e; - var objectHas = has$j; - var shared$3 = sharedStore; + var global$14 = global$1m; + var uncurryThis$R = functionUncurryThis; + var isObject$n = isObject$s; + var createNonEnumerableProperty$a = createNonEnumerableProperty$b; + var hasOwn$j = hasOwnProperty_1; + var shared$2 = sharedStore; var sharedKey$3 = sharedKey$4; var hiddenKeys$5 = hiddenKeys$6; var OBJECT_ALREADY_INITIALIZED = 'Object already initialized'; - var WeakMap = global$A.WeakMap; - var set$4, get$5, has$h; + var TypeError$i = global$14.TypeError; + var WeakMap = global$14.WeakMap; + var set$4, get$5, has; var enforce = function (it) { - return has$h(it) ? get$5(it) : set$4(it, {}); + return has(it) ? get$5(it) : set$4(it, {}); }; var getterFor = function (TYPE) { return function (it) { var state; if (!isObject$n(it) || (state = get$5(it)).type !== TYPE) { - throw TypeError('Incompatible receiver, ' + TYPE + ' required'); + throw TypeError$i('Incompatible receiver, ' + TYPE + ' required'); } return state; }; }; - if (NATIVE_WEAK_MAP || shared$3.state) { - var store$1 = shared$3.state || (shared$3.state = new WeakMap()); - var wmget = store$1.get; - var wmhas = store$1.has; - var wmset = store$1.set; + if (NATIVE_WEAK_MAP || shared$2.state) { + var store$1 = shared$2.state || (shared$2.state = new WeakMap()); + var wmget = uncurryThis$R(store$1.get); + var wmhas = uncurryThis$R(store$1.has); + var wmset = uncurryThis$R(store$1.set); set$4 = function (it, metadata) { - if (wmhas.call(store$1, it)) throw new TypeError(OBJECT_ALREADY_INITIALIZED); + if (wmhas(store$1, it)) throw new TypeError$i(OBJECT_ALREADY_INITIALIZED); metadata.facade = it; - wmset.call(store$1, it, metadata); + wmset(store$1, it, metadata); return metadata; }; get$5 = function (it) { - return wmget.call(store$1, it) || {}; + return wmget(store$1, it) || {}; }; - has$h = function (it) { - return wmhas.call(store$1, it); + has = function (it) { + return wmhas(store$1, it); }; } else { var STATE = sharedKey$3('state'); hiddenKeys$5[STATE] = true; set$4 = function (it, metadata) { - if (objectHas(it, STATE)) throw new TypeError(OBJECT_ALREADY_INITIALIZED); + if (hasOwn$j(it, STATE)) throw new TypeError$i(OBJECT_ALREADY_INITIALIZED); metadata.facade = it; - createNonEnumerableProperty$c(it, STATE, metadata); + createNonEnumerableProperty$a(it, STATE, metadata); return metadata; }; get$5 = function (it) { - return objectHas(it, STATE) ? it[STATE] : {}; + return hasOwn$j(it, STATE) ? it[STATE] : {}; }; - has$h = function (it) { - return objectHas(it, STATE); + has = function (it) { + return hasOwn$j(it, STATE); }; } var internalState = { set: set$4, get: get$5, - has: has$h, + has: has, enforce: enforce, getterFor: getterFor }; - var global$z = global$F; - var createNonEnumerableProperty$b = createNonEnumerableProperty$e; - var has$g = has$j; + var DESCRIPTORS$j = descriptors; + var hasOwn$i = hasOwnProperty_1; + + var FunctionPrototype$2 = Function.prototype; + // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe + var getDescriptor = DESCRIPTORS$j && Object.getOwnPropertyDescriptor; + + var EXISTS = hasOwn$i(FunctionPrototype$2, 'name'); + // additional protection from minified / mangled / dropped function names + var PROPER = EXISTS && (function something() { /* empty */ }).name === 'something'; + var CONFIGURABLE = EXISTS && (!DESCRIPTORS$j || (DESCRIPTORS$j && getDescriptor(FunctionPrototype$2, 'name').configurable)); + + var functionName = { + EXISTS: EXISTS, + PROPER: PROPER, + CONFIGURABLE: CONFIGURABLE + }; + + var global$13 = global$1m; + var isCallable$j = isCallable$r; + var hasOwn$h = hasOwnProperty_1; + var createNonEnumerableProperty$9 = createNonEnumerableProperty$b; var setGlobal$1 = setGlobal$3; - var inspectSource$1 = inspectSource$3; + var inspectSource$2 = inspectSource$4; var InternalStateModule$9 = internalState; + var CONFIGURABLE_FUNCTION_NAME$2 = functionName.CONFIGURABLE; var getInternalState$7 = InternalStateModule$9.get; var enforceInternalState$1 = InternalStateModule$9.enforce; var TEMPLATE = String(String).split('String'); - (redefine$g.exports = function (O, key, value, options) { + (redefine$h.exports = function (O, key, value, options) { var unsafe = options ? !!options.unsafe : false; var simple = options ? !!options.enumerable : false; var noTargetGet = options ? !!options.noTargetGet : false; + var name = options && options.name !== undefined ? options.name : key; var state; - if (typeof value == 'function') { - if (typeof key == 'string' && !has$g(value, 'name')) { - createNonEnumerableProperty$b(value, 'name', key); + if (isCallable$j(value)) { + if (String(name).slice(0, 7) === 'Symbol(') { + name = '[' + String(name).replace(/^Symbol\(([^)]*)\)/, '$1') + ']'; + } + if (!hasOwn$h(value, 'name') || (CONFIGURABLE_FUNCTION_NAME$2 && value.name !== name)) { + createNonEnumerableProperty$9(value, 'name', name); } state = enforceInternalState$1(value); if (!state.source) { - state.source = TEMPLATE.join(typeof key == 'string' ? key : ''); + state.source = TEMPLATE.join(typeof name == 'string' ? name : ''); } } - if (O === global$z) { + if (O === global$13) { if (simple) O[key] = value; else setGlobal$1(key, value); return; @@ -394,71 +660,65 @@ simple = true; } if (simple) O[key] = value; - else createNonEnumerableProperty$b(O, key, value); + else createNonEnumerableProperty$9(O, key, value); // add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative })(Function.prototype, 'toString', function toString() { - return typeof this == 'function' && getInternalState$7(this).source || inspectSource$1(this); + return isCallable$j(this) && getInternalState$7(this).source || inspectSource$2(this); }); - var global$y = global$F; - - var path$2 = global$y; - - var path$1 = path$2; - var global$x = global$F; - - var aFunction$a = function (variable) { - return typeof variable == 'function' ? variable : undefined; - }; + var objectGetOwnPropertyNames = {}; - var getBuiltIn$9 = function (namespace, method) { - return arguments.length < 2 ? aFunction$a(path$1[namespace]) || aFunction$a(global$x[namespace]) - : path$1[namespace] && path$1[namespace][method] || global$x[namespace] && global$x[namespace][method]; + var ceil$1 = Math.ceil; + var floor$8 = Math.floor; + + // `ToIntegerOrInfinity` abstract operation + // https://tc39.es/ecma262/#sec-tointegerorinfinity + var toIntegerOrInfinity$b = function (argument) { + var number = +argument; + // eslint-disable-next-line no-self-compare -- safe + return number !== number || number === 0 ? 0 : (number > 0 ? floor$8 : ceil$1)(number); }; - var objectGetOwnPropertyNames = {}; + var toIntegerOrInfinity$a = toIntegerOrInfinity$b; - var ceil$1 = Math.ceil; - var floor$7 = Math.floor; + var max$4 = Math.max; + var min$9 = Math.min; - // `ToInteger` abstract operation - // https://tc39.es/ecma262/#sec-tointeger - var toInteger$b = function (argument) { - return isNaN(argument = +argument) ? 0 : (argument > 0 ? floor$7 : ceil$1)(argument); + // Helper for a popular repeating case of the spec: + // Let integer be ? ToInteger(index). + // If integer < 0, let result be max((length + integer), 0); else let result be min(integer, length). + var toAbsoluteIndex$8 = function (index, length) { + var integer = toIntegerOrInfinity$a(index); + return integer < 0 ? max$4(integer + length, 0) : min$9(integer, length); }; - var toInteger$a = toInteger$b; + var toIntegerOrInfinity$9 = toIntegerOrInfinity$b; - var min$9 = Math.min; + var min$8 = Math.min; // `ToLength` abstract operation // https://tc39.es/ecma262/#sec-tolength - var toLength$q = function (argument) { - return argument > 0 ? min$9(toInteger$a(argument), 0x1FFFFFFFFFFFFF) : 0; // 2 ** 53 - 1 == 9007199254740991 + var toLength$c = function (argument) { + return argument > 0 ? min$8(toIntegerOrInfinity$9(argument), 0x1FFFFFFFFFFFFF) : 0; // 2 ** 53 - 1 == 9007199254740991 }; - var toInteger$9 = toInteger$b; - - var max$4 = Math.max; - var min$8 = Math.min; + var toLength$b = toLength$c; - // Helper for a popular repeating case of the spec: - // Let integer be ? ToInteger(index). - // If integer < 0, let result be max((length + integer), 0); else let result be min(integer, length). - var toAbsoluteIndex$8 = function (index, length) { - var integer = toInteger$9(index); - return integer < 0 ? max$4(integer + length, 0) : min$8(integer, length); + // `LengthOfArrayLike` abstract operation + // https://tc39.es/ecma262/#sec-lengthofarraylike + var lengthOfArrayLike$g = function (obj) { + return toLength$b(obj.length); }; - var toIndexedObject$9 = toIndexedObject$b; - var toLength$p = toLength$q; + var toIndexedObject$a = toIndexedObject$c; var toAbsoluteIndex$7 = toAbsoluteIndex$8; + var lengthOfArrayLike$f = lengthOfArrayLike$g; // `Array.prototype.{ indexOf, includes }` methods implementation var createMethod$6 = function (IS_INCLUDES) { return function ($this, el, fromIndex) { - var O = toIndexedObject$9($this); - var length = toLength$p(O.length); + var O = toIndexedObject$a($this); + var length = lengthOfArrayLike$f(O); var index = toAbsoluteIndex$7(fromIndex, length); var value; // Array#includes uses SameValueZero equality algorithm @@ -483,20 +743,23 @@ indexOf: createMethod$6(false) }; - var has$f = has$j; - var toIndexedObject$8 = toIndexedObject$b; - var indexOf = arrayIncludes.indexOf; + var uncurryThis$Q = functionUncurryThis; + var hasOwn$g = hasOwnProperty_1; + var toIndexedObject$9 = toIndexedObject$c; + var indexOf$1 = arrayIncludes.indexOf; var hiddenKeys$4 = hiddenKeys$6; + var push$a = uncurryThis$Q([].push); + var objectKeysInternal = function (object, names) { - var O = toIndexedObject$8(object); + var O = toIndexedObject$9(object); var i = 0; var result = []; var key; - for (key in O) !has$f(hiddenKeys$4, key) && has$f(O, key) && result.push(key); + for (key in O) !hasOwn$g(hiddenKeys$4, key) && hasOwn$g(O, key) && push$a(result, key); // Don't enum bug & hidden keys - while (names.length > i) if (has$f(O, key = names[i++])) { - ~indexOf(result, key) || result.push(key); + while (names.length > i) if (hasOwn$g(O, key = names[i++])) { + ~indexOf$1(result, key) || push$a(result, key); } return result; }; @@ -529,19 +792,22 @@ // eslint-disable-next-line es/no-object-getownpropertysymbols -- safe objectGetOwnPropertySymbols.f = Object.getOwnPropertySymbols; - var getBuiltIn$8 = getBuiltIn$9; - var getOwnPropertyNamesModule$1 = objectGetOwnPropertyNames; + var getBuiltIn$8 = getBuiltIn$b; + var uncurryThis$P = functionUncurryThis; + var getOwnPropertyNamesModule$2 = objectGetOwnPropertyNames; var getOwnPropertySymbolsModule$2 = objectGetOwnPropertySymbols; - var anObject$k = anObject$m; + var anObject$l = anObject$n; + + var concat$3 = uncurryThis$P([].concat); // all object keys, includes non-enumerable and symbols var ownKeys$1 = getBuiltIn$8('Reflect', 'ownKeys') || function ownKeys(it) { - var keys = getOwnPropertyNamesModule$1.f(anObject$k(it)); + var keys = getOwnPropertyNamesModule$2.f(anObject$l(it)); var getOwnPropertySymbols = getOwnPropertySymbolsModule$2.f; - return getOwnPropertySymbols ? keys.concat(getOwnPropertySymbols(it)) : keys; + return getOwnPropertySymbols ? concat$3(keys, getOwnPropertySymbols(it)) : keys; }; - var has$e = has$j; + var hasOwn$f = hasOwnProperty_1; var ownKeys = ownKeys$1; var getOwnPropertyDescriptorModule$3 = objectGetOwnPropertyDescriptor; var definePropertyModule$6 = objectDefineProperty; @@ -552,11 +818,12 @@ var getOwnPropertyDescriptor = getOwnPropertyDescriptorModule$3.f; for (var i = 0; i < keys.length; i++) { var key = keys[i]; - if (!has$e(target, key)) defineProperty(target, key, getOwnPropertyDescriptor(source, key)); + if (!hasOwn$f(target, key)) defineProperty(target, key, getOwnPropertyDescriptor(source, key)); } }; - var fails$J = fails$N; + var fails$N = fails$S; + var isCallable$i = isCallable$r; var replacement = /#|\.prototype\./; @@ -564,7 +831,7 @@ var value = data[normalize$1(feature)]; return value == POLYFILL ? true : value == NATIVE ? false - : typeof detection == 'function' ? fails$J(detection) + : isCallable$i(detection) ? fails$N(detection) : !!detection; }; @@ -578,10 +845,10 @@ var isForced_1 = isForced$5; - var global$w = global$F; + var global$12 = global$1m; var getOwnPropertyDescriptor$4 = objectGetOwnPropertyDescriptor.f; - var createNonEnumerableProperty$a = createNonEnumerableProperty$e; - var redefine$f = redefine$g.exports; + var createNonEnumerableProperty$8 = createNonEnumerableProperty$b; + var redefine$g = redefine$h.exports; var setGlobal = setGlobal$3; var copyConstructorProperties$1 = copyConstructorProperties$2; var isForced$4 = isForced_1; @@ -599,6 +866,7 @@ options.sham - add a flag to not completely full polyfills options.enumerable - export as enumerable property options.noTargetGet - prevent calling a getter on target + options.name - the .name of the function if it does not match the key */ var _export = function (options, source) { var TARGET = options.target; @@ -606,11 +874,11 @@ var STATIC = options.stat; var FORCED, target, key, targetProperty, sourceProperty, descriptor; if (GLOBAL) { - target = global$w; + target = global$12; } else if (STATIC) { - target = global$w[TARGET] || setGlobal(TARGET, {}); + target = global$12[TARGET] || setGlobal(TARGET, {}); } else { - target = (global$w[TARGET] || {}).prototype; + target = (global$12[TARGET] || {}).prototype; } if (target) for (key in source) { sourceProperty = source[key]; @@ -621,43 +889,49 @@ FORCED = isForced$4(GLOBAL ? key : TARGET + (STATIC ? '.' : '#') + key, options.forced); // contained in target if (!FORCED && targetProperty !== undefined) { - if (typeof sourceProperty === typeof targetProperty) continue; + if (typeof sourceProperty == typeof targetProperty) continue; copyConstructorProperties$1(sourceProperty, targetProperty); } // add a flag to not completely full polyfills if (options.sham || (targetProperty && targetProperty.sham)) { - createNonEnumerableProperty$a(sourceProperty, 'sham', true); + createNonEnumerableProperty$8(sourceProperty, 'sham', true); } // extend global - redefine$f(target, key, sourceProperty, options); + redefine$g(target, key, sourceProperty, options); } }; - var $$16 = _export; + var $$1e = _export; + var global$11 = global$1m; + var uncurryThis$O = functionUncurryThis; + + var Date$1 = global$11.Date; + var getTime$2 = uncurryThis$O(Date$1.prototype.getTime); // `Date.now` method // https://tc39.es/ecma262/#sec-date.now - $$16({ target: 'Date', stat: true }, { + $$1e({ target: 'Date', stat: true }, { now: function now() { - return new Date().getTime(); + return getTime$2(new Date$1()); } }); - var redefine$e = redefine$g.exports; + var uncurryThis$N = functionUncurryThis; + var redefine$f = redefine$h.exports; var DatePrototype$1 = Date.prototype; var INVALID_DATE = 'Invalid Date'; var TO_STRING$1 = 'toString'; - var nativeDateToString = DatePrototype$1[TO_STRING$1]; - var getTime$1 = DatePrototype$1.getTime; + var un$DateToString = uncurryThis$N(DatePrototype$1[TO_STRING$1]); + var getTime$1 = uncurryThis$N(DatePrototype$1.getTime); // `Date.prototype.toString` method // https://tc39.es/ecma262/#sec-date.prototype.tostring - if (new Date(NaN) + '' != INVALID_DATE) { - redefine$e(DatePrototype$1, TO_STRING$1, function toString() { - var value = getTime$1.call(this); + if (String(new Date(NaN)) != INVALID_DATE) { + redefine$f(DatePrototype$1, TO_STRING$1, function toString() { + var value = getTime$1(this); // eslint-disable-next-line no-self-compare -- NaN check - return value === value ? nativeDateToString.call(this) : INVALID_DATE; + return value === value ? un$DateToString(this) : INVALID_DATE; }); } @@ -846,89 +1120,33 @@ }; } - var wellKnownSymbolWrapped = {}; - - var getBuiltIn$7 = getBuiltIn$9; - - var engineUserAgent = getBuiltIn$7('navigator', 'userAgent') || ''; - - var global$v = global$F; - var userAgent$5 = engineUserAgent; - - var process$4 = global$v.process; - var versions = process$4 && process$4.versions; - var v8 = versions && versions.v8; - var match, version$1; - - if (v8) { - match = v8.split('.'); - version$1 = match[0] < 4 ? 1 : match[0] + match[1]; - } else if (userAgent$5) { - match = userAgent$5.match(/Edge\/(\d+)/); - if (!match || match[1] >= 74) { - match = userAgent$5.match(/Chrome\/(\d+)/); - if (match) version$1 = match[1]; - } - } - - var engineV8Version = version$1 && +version$1; - - /* eslint-disable es/no-symbol -- required for testing */ - - var V8_VERSION$3 = engineV8Version; - var fails$I = fails$N; + var $$1d = _export; + var global$10 = global$1m; - // eslint-disable-next-line es/no-object-getownpropertysymbols -- required for testing - var nativeSymbol = !!Object.getOwnPropertySymbols && !fails$I(function () { - var symbol = Symbol(); - // Chrome 38 Symbol has incorrect toString conversion - // `get-own-property-symbols` polyfill symbols converted to object are not Symbol instances - return !String(symbol) || !(Object(symbol) instanceof Symbol) || - // Chrome 38-40 symbols are not inherited from DOM collections prototypes to instances - !Symbol.sham && V8_VERSION$3 && V8_VERSION$3 < 41; + // `globalThis` object + // https://tc39.es/ecma262/#sec-globalthis + $$1d({ global: true }, { + globalThis: global$10 }); - /* eslint-disable es/no-symbol -- required for testing */ - - var NATIVE_SYMBOL$2 = nativeSymbol; - - var useSymbolAsUid = NATIVE_SYMBOL$2 - && !Symbol.sham - && typeof Symbol.iterator == 'symbol'; - - var global$u = global$F; - var shared$2 = shared$5.exports; - var has$d = has$j; - var uid$3 = uid$5; - var NATIVE_SYMBOL$1 = nativeSymbol; - var USE_SYMBOL_AS_UID$1 = useSymbolAsUid; + var global$$ = global$1m; - var WellKnownSymbolsStore$1 = shared$2('wks'); - var Symbol$1 = global$u.Symbol; - var createWellKnownSymbol = USE_SYMBOL_AS_UID$1 ? Symbol$1 : Symbol$1 && Symbol$1.withoutSetter || uid$3; + var path$1 = global$$; - var wellKnownSymbol$s = function (name) { - if (!has$d(WellKnownSymbolsStore$1, name) || !(NATIVE_SYMBOL$1 || typeof WellKnownSymbolsStore$1[name] == 'string')) { - if (NATIVE_SYMBOL$1 && has$d(Symbol$1, name)) { - WellKnownSymbolsStore$1[name] = Symbol$1[name]; - } else { - WellKnownSymbolsStore$1[name] = createWellKnownSymbol('Symbol.' + name); - } - } return WellKnownSymbolsStore$1[name]; - }; + var wellKnownSymbolWrapped = {}; - var wellKnownSymbol$r = wellKnownSymbol$s; + var wellKnownSymbol$r = wellKnownSymbol$t; wellKnownSymbolWrapped.f = wellKnownSymbol$r; - var path = path$2; - var has$c = has$j; + var path = path$1; + var hasOwn$e = hasOwnProperty_1; var wrappedWellKnownSymbolModule$1 = wellKnownSymbolWrapped; var defineProperty$a = objectDefineProperty.f; var defineWellKnownSymbol$4 = function (NAME) { var Symbol = path.Symbol || (path.Symbol = {}); - if (!has$c(Symbol, NAME)) defineProperty$a(Symbol, NAME, { + if (!hasOwn$e(Symbol, NAME)) defineProperty$a(Symbol, NAME, { value: wrappedWellKnownSymbolModule$1.f(NAME) }); }; @@ -951,32 +1169,36 @@ var DESCRIPTORS$i = descriptors; var definePropertyModule$5 = objectDefineProperty; - var anObject$j = anObject$m; + var anObject$k = anObject$n; + var toIndexedObject$8 = toIndexedObject$c; var objectKeys$3 = objectKeys$4; // `Object.defineProperties` method // https://tc39.es/ecma262/#sec-object.defineproperties // eslint-disable-next-line es/no-object-defineproperties -- safe var objectDefineProperties = DESCRIPTORS$i ? Object.defineProperties : function defineProperties(O, Properties) { - anObject$j(O); + anObject$k(O); + var props = toIndexedObject$8(Properties); var keys = objectKeys$3(Properties); var length = keys.length; var index = 0; var key; - while (length > index) definePropertyModule$5.f(O, key = keys[index++], Properties[key]); + while (length > index) definePropertyModule$5.f(O, key = keys[index++], props[key]); return O; }; - var getBuiltIn$6 = getBuiltIn$9; + var getBuiltIn$7 = getBuiltIn$b; + + var html$2 = getBuiltIn$7('document', 'documentElement'); - var html$2 = getBuiltIn$6('document', 'documentElement'); + /* global ActiveXObject -- old IE, WSH */ - var anObject$i = anObject$m; + var anObject$j = anObject$n; var defineProperties$2 = objectDefineProperties; var enumBugKeys = enumBugKeys$3; var hiddenKeys$2 = hiddenKeys$6; var html$1 = html$2; - var documentCreateElement = documentCreateElement$1; + var documentCreateElement$1 = documentCreateElement$2; var sharedKey$2 = sharedKey$4; var GT = '>'; @@ -1003,7 +1225,7 @@ // Create object with fake `null` prototype: use iframe Object with cleared prototype var NullProtoObjectViaIFrame = function () { // Thrash, waste and sodomy: IE GC bug - var iframe = documentCreateElement('iframe'); + var iframe = documentCreateElement$1('iframe'); var JS = 'java' + SCRIPT + ':'; var iframeDocument; iframe.style.display = 'none'; @@ -1025,10 +1247,13 @@ var activeXDocument; var NullProtoObject = function () { try { - /* global ActiveXObject -- old IE */ - activeXDocument = document.domain && new ActiveXObject('htmlfile'); + activeXDocument = new ActiveXObject('htmlfile'); } catch (error) { /* ignore */ } - NullProtoObject = activeXDocument ? NullProtoObjectViaActiveX(activeXDocument) : NullProtoObjectViaIFrame(); + NullProtoObject = typeof document != 'undefined' + ? document.domain && activeXDocument + ? NullProtoObjectViaActiveX(activeXDocument) // old IE + : NullProtoObjectViaIFrame() + : NullProtoObjectViaActiveX(activeXDocument); // WSH var length = enumBugKeys.length; while (length--) delete NullProtoObject[PROTOTYPE$2][enumBugKeys[length]]; return NullProtoObject(); @@ -1041,7 +1266,7 @@ var objectCreate = Object.create || function create(O, Properties) { var result; if (O !== null) { - EmptyConstructor[PROTOTYPE$2] = anObject$i(O); + EmptyConstructor[PROTOTYPE$2] = anObject$j(O); result = new EmptyConstructor(); EmptyConstructor[PROTOTYPE$2] = null; // add "__proto__" for Object.getPrototypeOf polyfill @@ -1050,8 +1275,8 @@ return Properties === undefined ? result : defineProperties$2(result, Properties); }; - var wellKnownSymbol$q = wellKnownSymbol$s; - var create$b = objectCreate; + var wellKnownSymbol$q = wellKnownSymbol$t; + var create$a = objectCreate; var definePropertyModule$4 = objectDefineProperty; var UNSCOPABLES = wellKnownSymbol$q('unscopables'); @@ -1062,56 +1287,57 @@ if (ArrayPrototype$1[UNSCOPABLES] == undefined) { definePropertyModule$4.f(ArrayPrototype$1, UNSCOPABLES, { configurable: true, - value: create$b(null) + value: create$a(null) }); } // add a key to Array.prototype[@@unscopables] - var addToUnscopables$5 = function (key) { + var addToUnscopables$6 = function (key) { ArrayPrototype$1[UNSCOPABLES][key] = true; }; var iterators = {}; - var fails$H = fails$N; + var fails$M = fails$S; - var correctPrototypeGetter = !fails$H(function () { + var correctPrototypeGetter = !fails$M(function () { function F() { /* empty */ } F.prototype.constructor = null; // eslint-disable-next-line es/no-object-getprototypeof -- required for testing return Object.getPrototypeOf(new F()) !== F.prototype; }); - var has$b = has$j; - var toObject$g = toObject$i; + var global$_ = global$1m; + var hasOwn$d = hasOwnProperty_1; + var isCallable$h = isCallable$r; + var toObject$h = toObject$j; var sharedKey$1 = sharedKey$4; var CORRECT_PROTOTYPE_GETTER$1 = correctPrototypeGetter; var IE_PROTO = sharedKey$1('IE_PROTO'); - var ObjectPrototype$3 = Object.prototype; + var Object$2 = global$_.Object; + var ObjectPrototype$4 = Object$2.prototype; // `Object.getPrototypeOf` method // https://tc39.es/ecma262/#sec-object.getprototypeof - // eslint-disable-next-line es/no-object-getprototypeof -- safe - var objectGetPrototypeOf = CORRECT_PROTOTYPE_GETTER$1 ? Object.getPrototypeOf : function (O) { - O = toObject$g(O); - if (has$b(O, IE_PROTO)) return O[IE_PROTO]; - if (typeof O.constructor == 'function' && O instanceof O.constructor) { - return O.constructor.prototype; - } return O instanceof Object ? ObjectPrototype$3 : null; + var objectGetPrototypeOf = CORRECT_PROTOTYPE_GETTER$1 ? Object$2.getPrototypeOf : function (O) { + var object = toObject$h(O); + if (hasOwn$d(object, IE_PROTO)) return object[IE_PROTO]; + var constructor = object.constructor; + if (isCallable$h(constructor) && object instanceof constructor) { + return constructor.prototype; + } return object instanceof Object$2 ? ObjectPrototype$4 : null; }; - var fails$G = fails$N; + var fails$L = fails$S; + var isCallable$g = isCallable$r; var getPrototypeOf$4 = objectGetPrototypeOf; - var createNonEnumerableProperty$9 = createNonEnumerableProperty$e; - var has$a = has$j; - var wellKnownSymbol$p = wellKnownSymbol$s; + var redefine$e = redefine$h.exports; + var wellKnownSymbol$p = wellKnownSymbol$t; - var ITERATOR$8 = wellKnownSymbol$p('iterator'); + var ITERATOR$a = wellKnownSymbol$p('iterator'); var BUGGY_SAFARI_ITERATORS$1 = false; - var returnThis$2 = function () { return this; }; - // `%IteratorPrototype%` object // https://tc39.es/ecma262/#sec-%iteratorprototype%-object var IteratorPrototype$2, PrototypeOfArrayIteratorPrototype, arrayIterator; @@ -1127,18 +1353,20 @@ } } - var NEW_ITERATOR_PROTOTYPE = IteratorPrototype$2 == undefined || fails$G(function () { + var NEW_ITERATOR_PROTOTYPE = IteratorPrototype$2 == undefined || fails$L(function () { var test = {}; // FF44- legacy iterators case - return IteratorPrototype$2[ITERATOR$8].call(test) !== test; + return IteratorPrototype$2[ITERATOR$a].call(test) !== test; }); if (NEW_ITERATOR_PROTOTYPE) IteratorPrototype$2 = {}; // `%IteratorPrototype%[@@iterator]()` method // https://tc39.es/ecma262/#sec-%iteratorprototype%-@@iterator - if (!has$a(IteratorPrototype$2, ITERATOR$8)) { - createNonEnumerableProperty$9(IteratorPrototype$2, ITERATOR$8, returnThis$2); + if (!isCallable$g(IteratorPrototype$2[ITERATOR$a])) { + redefine$e(IteratorPrototype$2, ITERATOR$a, function () { + return this; + }); } var iteratorsCore = { @@ -1147,19 +1375,19 @@ }; var defineProperty$9 = objectDefineProperty.f; - var has$9 = has$j; - var wellKnownSymbol$o = wellKnownSymbol$s; + var hasOwn$c = hasOwnProperty_1; + var wellKnownSymbol$o = wellKnownSymbol$t; var TO_STRING_TAG$4 = wellKnownSymbol$o('toStringTag'); var setToStringTag$a = function (it, TAG, STATIC) { - if (it && !has$9(it = STATIC ? it : it.prototype, TO_STRING_TAG$4)) { + if (it && !hasOwn$c(it = STATIC ? it : it.prototype, TO_STRING_TAG$4)) { defineProperty$9(it, TO_STRING_TAG$4, { configurable: true, value: TAG }); } }; var IteratorPrototype$1 = iteratorsCore.IteratorPrototype; - var create$a = objectCreate; + var create$9 = objectCreate; var createPropertyDescriptor$4 = createPropertyDescriptor$7; var setToStringTag$9 = setToStringTag$a; var Iterators$4 = iterators; @@ -1168,23 +1396,27 @@ var createIteratorConstructor$2 = function (IteratorConstructor, NAME, next) { var TO_STRING_TAG = NAME + ' Iterator'; - IteratorConstructor.prototype = create$a(IteratorPrototype$1, { next: createPropertyDescriptor$4(1, next) }); + IteratorConstructor.prototype = create$9(IteratorPrototype$1, { next: createPropertyDescriptor$4(1, next) }); setToStringTag$9(IteratorConstructor, TO_STRING_TAG, false); Iterators$4[TO_STRING_TAG] = returnThis$1; return IteratorConstructor; }; - var isObject$m = isObject$r; + var global$Z = global$1m; + var isCallable$f = isCallable$r; - var aPossiblePrototype$1 = function (it) { - if (!isObject$m(it) && it !== null) { - throw TypeError("Can't set " + String(it) + ' as a prototype'); - } return it; + var String$4 = global$Z.String; + var TypeError$h = global$Z.TypeError; + + var aPossiblePrototype$1 = function (argument) { + if (typeof argument == 'object' || isCallable$f(argument)) return argument; + throw TypeError$h("Can't set " + String$4(argument) + ' as a prototype'); }; /* eslint-disable no-proto -- safe */ - var anObject$h = anObject$m; + var uncurryThis$M = functionUncurryThis; + var anObject$i = anObject$n; var aPossiblePrototype = aPossiblePrototype$1; // `Object.setPrototypeOf` method @@ -1197,33 +1429,38 @@ var setter; try { // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe - setter = Object.getOwnPropertyDescriptor(Object.prototype, '__proto__').set; - setter.call(test, []); + setter = uncurryThis$M(Object.getOwnPropertyDescriptor(Object.prototype, '__proto__').set); + setter(test, []); CORRECT_SETTER = test instanceof Array; } catch (error) { /* empty */ } return function setPrototypeOf(O, proto) { - anObject$h(O); + anObject$i(O); aPossiblePrototype(proto); - if (CORRECT_SETTER) setter.call(O, proto); + if (CORRECT_SETTER) setter(O, proto); else O.__proto__ = proto; return O; }; }() : undefined); - var $$15 = _export; + var $$1c = _export; + var call$l = functionCall; + var FunctionName$1 = functionName; + var isCallable$e = isCallable$r; var createIteratorConstructor$1 = createIteratorConstructor$2; var getPrototypeOf$3 = objectGetPrototypeOf; var setPrototypeOf$6 = objectSetPrototypeOf; var setToStringTag$8 = setToStringTag$a; - var createNonEnumerableProperty$8 = createNonEnumerableProperty$e; - var redefine$d = redefine$g.exports; - var wellKnownSymbol$n = wellKnownSymbol$s; + var createNonEnumerableProperty$7 = createNonEnumerableProperty$b; + var redefine$d = redefine$h.exports; + var wellKnownSymbol$n = wellKnownSymbol$t; var Iterators$3 = iterators; var IteratorsCore = iteratorsCore; + var PROPER_FUNCTION_NAME$4 = FunctionName$1.PROPER; + var CONFIGURABLE_FUNCTION_NAME$1 = FunctionName$1.CONFIGURABLE; var IteratorPrototype = IteratorsCore.IteratorPrototype; var BUGGY_SAFARI_ITERATORS = IteratorsCore.BUGGY_SAFARI_ITERATORS; - var ITERATOR$7 = wellKnownSymbol$n('iterator'); + var ITERATOR$9 = wellKnownSymbol$n('iterator'); var KEYS = 'keys'; var VALUES = 'values'; var ENTRIES = 'entries'; @@ -1246,7 +1483,7 @@ var TO_STRING_TAG = NAME + ' Iterator'; var INCORRECT_VALUES_NAME = false; var IterablePrototype = Iterable.prototype; - var nativeIterator = IterablePrototype[ITERATOR$7] + var nativeIterator = IterablePrototype[ITERATOR$9] || IterablePrototype['@@iterator'] || DEFAULT && IterablePrototype[DEFAULT]; var defaultIterator = !BUGGY_SAFARI_ITERATORS && nativeIterator || getIterationMethod(DEFAULT); @@ -1256,12 +1493,12 @@ // fix native if (anyNativeIterator) { CurrentIteratorPrototype = getPrototypeOf$3(anyNativeIterator.call(new Iterable())); - if (IteratorPrototype !== Object.prototype && CurrentIteratorPrototype.next) { + if (CurrentIteratorPrototype !== Object.prototype && CurrentIteratorPrototype.next) { if (getPrototypeOf$3(CurrentIteratorPrototype) !== IteratorPrototype) { if (setPrototypeOf$6) { setPrototypeOf$6(CurrentIteratorPrototype, IteratorPrototype); - } else if (typeof CurrentIteratorPrototype[ITERATOR$7] != 'function') { - createNonEnumerableProperty$8(CurrentIteratorPrototype, ITERATOR$7, returnThis); + } else if (!isCallable$e(CurrentIteratorPrototype[ITERATOR$9])) { + redefine$d(CurrentIteratorPrototype, ITERATOR$9, returnThis); } } // Set @@toStringTag to native iterators @@ -1270,16 +1507,14 @@ } // fix Array.prototype.{ values, @@iterator }.name in V8 / FF - if (DEFAULT == VALUES && nativeIterator && nativeIterator.name !== VALUES) { - INCORRECT_VALUES_NAME = true; - defaultIterator = function values() { return nativeIterator.call(this); }; - } - - // define iterator - if (IterablePrototype[ITERATOR$7] !== defaultIterator) { - createNonEnumerableProperty$8(IterablePrototype, ITERATOR$7, defaultIterator); + if (PROPER_FUNCTION_NAME$4 && DEFAULT == VALUES && nativeIterator && nativeIterator.name !== VALUES) { + if (CONFIGURABLE_FUNCTION_NAME$1) { + createNonEnumerableProperty$7(IterablePrototype, 'name', VALUES); + } else { + INCORRECT_VALUES_NAME = true; + defaultIterator = function values() { return call$l(nativeIterator, this); }; + } } - Iterators$3[NAME] = defaultIterator; // export additional methods if (DEFAULT) { @@ -1292,14 +1527,20 @@ if (BUGGY_SAFARI_ITERATORS || INCORRECT_VALUES_NAME || !(KEY in IterablePrototype)) { redefine$d(IterablePrototype, KEY, methods[KEY]); } - } else $$15({ target: NAME, proto: true, forced: BUGGY_SAFARI_ITERATORS || INCORRECT_VALUES_NAME }, methods); + } else $$1c({ target: NAME, proto: true, forced: BUGGY_SAFARI_ITERATORS || INCORRECT_VALUES_NAME }, methods); } + // define iterator + if (IterablePrototype[ITERATOR$9] !== defaultIterator) { + redefine$d(IterablePrototype, ITERATOR$9, defaultIterator, { name: DEFAULT }); + } + Iterators$3[NAME] = defaultIterator; + return methods; }; - var toIndexedObject$7 = toIndexedObject$b; - var addToUnscopables$4 = addToUnscopables$5; + var toIndexedObject$7 = toIndexedObject$c; + var addToUnscopables$5 = addToUnscopables$6; var Iterators$2 = iterators; var InternalStateModule$8 = internalState; var defineIterator$2 = defineIterator$3; @@ -1347,11 +1588,11 @@ Iterators$2.Arguments = Iterators$2.Array; // https://tc39.es/ecma262/#sec-array.prototype-@@unscopables - addToUnscopables$4('keys'); - addToUnscopables$4('values'); - addToUnscopables$4('entries'); + addToUnscopables$5('keys'); + addToUnscopables$5('values'); + addToUnscopables$5('entries'); - var wellKnownSymbol$m = wellKnownSymbol$s; + var wellKnownSymbol$m = wellKnownSymbol$t; var TO_STRING_TAG$3 = wellKnownSymbol$m('toStringTag'); var test$2 = {}; @@ -1360,11 +1601,15 @@ var toStringTagSupport = String(test$2) === '[object z]'; + var global$Y = global$1m; var TO_STRING_TAG_SUPPORT$2 = toStringTagSupport; + var isCallable$d = isCallable$r; var classofRaw = classofRaw$1; - var wellKnownSymbol$l = wellKnownSymbol$s; + var wellKnownSymbol$l = wellKnownSymbol$t; var TO_STRING_TAG$2 = wellKnownSymbol$l('toStringTag'); + var Object$1 = global$Y.Object; + // ES3 wrong here var CORRECT_ARGUMENTS = classofRaw(function () { return arguments; }()) == 'Arguments'; @@ -1376,52 +1621,71 @@ }; // getting tag from ES6+ `Object.prototype.toString` - var classof$b = TO_STRING_TAG_SUPPORT$2 ? classofRaw : function (it) { + var classof$d = TO_STRING_TAG_SUPPORT$2 ? classofRaw : function (it) { var O, tag, result; return it === undefined ? 'Undefined' : it === null ? 'Null' // @@toStringTag case - : typeof (tag = tryGet(O = Object(it), TO_STRING_TAG$2)) == 'string' ? tag + : typeof (tag = tryGet(O = Object$1(it), TO_STRING_TAG$2)) == 'string' ? tag // builtinTag case : CORRECT_ARGUMENTS ? classofRaw(O) // ES3 arguments fallback - : (result = classofRaw(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : result; + : (result = classofRaw(O)) == 'Object' && isCallable$d(O.callee) ? 'Arguments' : result; }; var TO_STRING_TAG_SUPPORT$1 = toStringTagSupport; - var classof$a = classof$b; + var classof$c = classof$d; // `Object.prototype.toString` method implementation // https://tc39.es/ecma262/#sec-object.prototype.tostring var objectToString$1 = TO_STRING_TAG_SUPPORT$1 ? {}.toString : function toString() { - return '[object ' + classof$a(this) + ']'; + return '[object ' + classof$c(this) + ']'; }; var TO_STRING_TAG_SUPPORT = toStringTagSupport; - var redefine$c = redefine$g.exports; - var toString$1 = objectToString$1; + var redefine$c = redefine$h.exports; + var toString$l = objectToString$1; // `Object.prototype.toString` method // https://tc39.es/ecma262/#sec-object.prototype.tostring if (!TO_STRING_TAG_SUPPORT) { - redefine$c(Object.prototype, 'toString', toString$1, { unsafe: true }); + redefine$c(Object.prototype, 'toString', toString$l, { unsafe: true }); } - var toInteger$8 = toInteger$b; + var global$X = global$1m; + var classof$b = classof$d; + + var String$3 = global$X.String; + + var toString$k = function (argument) { + if (classof$b(argument) === 'Symbol') throw TypeError('Cannot convert a Symbol value to a string'); + return String$3(argument); + }; + + var uncurryThis$L = functionUncurryThis; + var toIntegerOrInfinity$8 = toIntegerOrInfinity$b; + var toString$j = toString$k; var requireObjectCoercible$b = requireObjectCoercible$e; - // `String.prototype.{ codePointAt, at }` methods implementation + var charAt$8 = uncurryThis$L(''.charAt); + var charCodeAt$2 = uncurryThis$L(''.charCodeAt); + var stringSlice$b = uncurryThis$L(''.slice); + var createMethod$5 = function (CONVERT_TO_STRING) { return function ($this, pos) { - var S = String(requireObjectCoercible$b($this)); - var position = toInteger$8(pos); + var S = toString$j(requireObjectCoercible$b($this)); + var position = toIntegerOrInfinity$8(pos); var size = S.length; var first, second; if (position < 0 || position >= size) return CONVERT_TO_STRING ? '' : undefined; - first = S.charCodeAt(position); + first = charCodeAt$2(S, position); return first < 0xD800 || first > 0xDBFF || position + 1 === size - || (second = S.charCodeAt(position + 1)) < 0xDC00 || second > 0xDFFF - ? CONVERT_TO_STRING ? S.charAt(position) : first - : CONVERT_TO_STRING ? S.slice(position, position + 2) : (first - 0xD800 << 10) + (second - 0xDC00) + 0x10000; + || (second = charCodeAt$2(S, position + 1)) < 0xDC00 || second > 0xDFFF + ? CONVERT_TO_STRING + ? charAt$8(S, position) + : first + : CONVERT_TO_STRING + ? stringSlice$b(S, position, position + 2) + : (first - 0xD800 << 10) + (second - 0xDC00) + 0x10000; }; }; @@ -1434,7 +1698,8 @@ charAt: createMethod$5(true) }; - var charAt$1 = stringMultibyte.charAt; + var charAt$7 = stringMultibyte.charAt; + var toString$i = toString$k; var InternalStateModule$7 = internalState; var defineIterator$1 = defineIterator$3; @@ -1447,7 +1712,7 @@ defineIterator$1(String, 'String', function (iterated) { setInternalState$7(this, { type: STRING_ITERATOR, - string: String(iterated), + string: toString$i(iterated), index: 0 }); // `%StringIteratorPrototype%.next` method @@ -1458,7 +1723,7 @@ var index = state.index; var point; if (index >= string.length) return { value: undefined, done: true }; - point = charAt$1(string, index); + point = charAt$7(string, index); state.index += point.length; return { value: point, done: false }; }); @@ -1499,57 +1764,84 @@ TouchList: 0 }; - var global$t = global$F; + // in old WebKit versions, `element.classList` is not an instance of global `DOMTokenList` + var documentCreateElement = documentCreateElement$2; + + var classList$1 = documentCreateElement('span').classList; + var DOMTokenListPrototype$2 = classList$1 && classList$1.constructor && classList$1.constructor.prototype; + + var domTokenListPrototype = DOMTokenListPrototype$2 === Object.prototype ? undefined : DOMTokenListPrototype$2; + + var global$W = global$1m; var DOMIterables$1 = domIterables; + var DOMTokenListPrototype$1 = domTokenListPrototype; var ArrayIteratorMethods = es_array_iterator; - var createNonEnumerableProperty$7 = createNonEnumerableProperty$e; - var wellKnownSymbol$k = wellKnownSymbol$s; + var createNonEnumerableProperty$6 = createNonEnumerableProperty$b; + var wellKnownSymbol$k = wellKnownSymbol$t; - var ITERATOR$6 = wellKnownSymbol$k('iterator'); + var ITERATOR$8 = wellKnownSymbol$k('iterator'); var TO_STRING_TAG$1 = wellKnownSymbol$k('toStringTag'); var ArrayValues = ArrayIteratorMethods.values; - for (var COLLECTION_NAME$1 in DOMIterables$1) { - var Collection$1 = global$t[COLLECTION_NAME$1]; - var CollectionPrototype$1 = Collection$1 && Collection$1.prototype; - if (CollectionPrototype$1) { + var handlePrototype$1 = function (CollectionPrototype, COLLECTION_NAME) { + if (CollectionPrototype) { // some Chrome versions have non-configurable methods on DOMTokenList - if (CollectionPrototype$1[ITERATOR$6] !== ArrayValues) try { - createNonEnumerableProperty$7(CollectionPrototype$1, ITERATOR$6, ArrayValues); + if (CollectionPrototype[ITERATOR$8] !== ArrayValues) try { + createNonEnumerableProperty$6(CollectionPrototype, ITERATOR$8, ArrayValues); } catch (error) { - CollectionPrototype$1[ITERATOR$6] = ArrayValues; + CollectionPrototype[ITERATOR$8] = ArrayValues; } - if (!CollectionPrototype$1[TO_STRING_TAG$1]) { - createNonEnumerableProperty$7(CollectionPrototype$1, TO_STRING_TAG$1, COLLECTION_NAME$1); + if (!CollectionPrototype[TO_STRING_TAG$1]) { + createNonEnumerableProperty$6(CollectionPrototype, TO_STRING_TAG$1, COLLECTION_NAME); } - if (DOMIterables$1[COLLECTION_NAME$1]) for (var METHOD_NAME in ArrayIteratorMethods) { + if (DOMIterables$1[COLLECTION_NAME]) for (var METHOD_NAME in ArrayIteratorMethods) { // some Chrome versions have non-configurable methods on DOMTokenList - if (CollectionPrototype$1[METHOD_NAME] !== ArrayIteratorMethods[METHOD_NAME]) try { - createNonEnumerableProperty$7(CollectionPrototype$1, METHOD_NAME, ArrayIteratorMethods[METHOD_NAME]); + if (CollectionPrototype[METHOD_NAME] !== ArrayIteratorMethods[METHOD_NAME]) try { + createNonEnumerableProperty$6(CollectionPrototype, METHOD_NAME, ArrayIteratorMethods[METHOD_NAME]); } catch (error) { - CollectionPrototype$1[METHOD_NAME] = ArrayIteratorMethods[METHOD_NAME]; + CollectionPrototype[METHOD_NAME] = ArrayIteratorMethods[METHOD_NAME]; } } } + }; + + for (var COLLECTION_NAME$1 in DOMIterables$1) { + handlePrototype$1(global$W[COLLECTION_NAME$1] && global$W[COLLECTION_NAME$1].prototype, COLLECTION_NAME$1); } - var classof$9 = classofRaw$1; + handlePrototype$1(DOMTokenListPrototype$1, 'DOMTokenList'); + + var FunctionPrototype$1 = Function.prototype; + var apply$9 = FunctionPrototype$1.apply; + var bind$g = FunctionPrototype$1.bind; + var call$k = FunctionPrototype$1.call; + + // eslint-disable-next-line es/no-reflect -- safe + var functionApply = typeof Reflect == 'object' && Reflect.apply || (bind$g ? call$k.bind(apply$9) : function () { + return call$k.apply(apply$9, arguments); + }); + + var classof$a = classofRaw$1; // `IsArray` abstract operation // https://tc39.es/ecma262/#sec-isarray // eslint-disable-next-line es/no-array-isarray -- safe - var isArray$6 = Array.isArray || function isArray(arg) { - return classof$9(arg) == 'Array'; + var isArray$8 = Array.isArray || function isArray(argument) { + return classof$a(argument) == 'Array'; }; var objectGetOwnPropertyNamesExternal = {}; + var uncurryThis$K = functionUncurryThis; + + var arraySlice$c = uncurryThis$K([].slice); + /* eslint-disable es/no-object-getownpropertynames -- safe */ - var toIndexedObject$6 = toIndexedObject$b; + var classof$9 = classofRaw$1; + var toIndexedObject$6 = toIndexedObject$c; var $getOwnPropertyNames$1 = objectGetOwnPropertyNames.f; - - var toString = {}.toString; + var arraySlice$b = arraySlice$c; var windowNames = typeof window == 'object' && window && Object.getOwnPropertyNames ? Object.getOwnPropertyNames(window) : []; @@ -1558,94 +1850,132 @@ try { return $getOwnPropertyNames$1(it); } catch (error) { - return windowNames.slice(); + return arraySlice$b(windowNames); } }; // fallback for IE11 buggy Object.getOwnPropertyNames with iframe and window objectGetOwnPropertyNamesExternal.f = function getOwnPropertyNames(it) { - return windowNames && toString.call(it) == '[object Window]' + return windowNames && classof$9(it) == 'Window' ? getWindowNames(it) : $getOwnPropertyNames$1(toIndexedObject$6(it)); }; - var aFunction$9 = function (it) { - if (typeof it != 'function') { - throw TypeError(String(it) + ' is not a function'); - } return it; - }; + var uncurryThis$J = functionUncurryThis; + var aCallable$8 = aCallable$a; - var aFunction$8 = aFunction$9; + var bind$f = uncurryThis$J(uncurryThis$J.bind); // optional / simple context binding - var functionBindContext = function (fn, that, length) { - aFunction$8(fn); - if (that === undefined) return fn; - switch (length) { - case 0: return function () { - return fn.call(that); - }; - case 1: return function (a) { - return fn.call(that, a); - }; - case 2: return function (a, b) { - return fn.call(that, a, b); - }; - case 3: return function (a, b, c) { - return fn.call(that, a, b, c); - }; - } - return function (/* ...args */) { + var functionBindContext = function (fn, that) { + aCallable$8(fn); + return that === undefined ? fn : bind$f ? bind$f(fn, that) : function (/* ...args */) { return fn.apply(that, arguments); }; }; - var isObject$l = isObject$r; - var isArray$5 = isArray$6; - var wellKnownSymbol$j = wellKnownSymbol$s; + var uncurryThis$I = functionUncurryThis; + var fails$K = fails$S; + var isCallable$c = isCallable$r; + var classof$8 = classof$d; + var getBuiltIn$6 = getBuiltIn$b; + var inspectSource$1 = inspectSource$4; + + var noop$2 = function () { /* empty */ }; + var empty$1 = []; + var construct$1 = getBuiltIn$6('Reflect', 'construct'); + var constructorRegExp = /^\s*(?:class|function)\b/; + var exec$6 = uncurryThis$I(constructorRegExp.exec); + var INCORRECT_TO_STRING = !constructorRegExp.exec(noop$2); + + var isConstructorModern = function (argument) { + if (!isCallable$c(argument)) return false; + try { + construct$1(noop$2, empty$1, argument); + return true; + } catch (error) { + return false; + } + }; + + var isConstructorLegacy = function (argument) { + if (!isCallable$c(argument)) return false; + switch (classof$8(argument)) { + case 'AsyncFunction': + case 'GeneratorFunction': + case 'AsyncGeneratorFunction': return false; + // we can't check .prototype since constructors produced by .bind haven't it + } return INCORRECT_TO_STRING || !!exec$6(constructorRegExp, inspectSource$1(argument)); + }; + + // `IsConstructor` abstract operation + // https://tc39.es/ecma262/#sec-isconstructor + var isConstructor$4 = !construct$1 || fails$K(function () { + var called; + return isConstructorModern(isConstructorModern.call) + || !isConstructorModern(Object) + || !isConstructorModern(function () { called = true; }) + || called; + }) ? isConstructorLegacy : isConstructorModern; + + var global$V = global$1m; + var isArray$7 = isArray$8; + var isConstructor$3 = isConstructor$4; + var isObject$m = isObject$s; + var wellKnownSymbol$j = wellKnownSymbol$t; var SPECIES$6 = wellKnownSymbol$j('species'); + var Array$6 = global$V.Array; - // `ArraySpeciesCreate` abstract operation + // a part of `ArraySpeciesCreate` abstract operation // https://tc39.es/ecma262/#sec-arrayspeciescreate - var arraySpeciesCreate$3 = function (originalArray, length) { + var arraySpeciesConstructor$1 = function (originalArray) { var C; - if (isArray$5(originalArray)) { + if (isArray$7(originalArray)) { C = originalArray.constructor; // cross-realm fallback - if (typeof C == 'function' && (C === Array || isArray$5(C.prototype))) C = undefined; - else if (isObject$l(C)) { + if (isConstructor$3(C) && (C === Array$6 || isArray$7(C.prototype))) C = undefined; + else if (isObject$m(C)) { C = C[SPECIES$6]; if (C === null) C = undefined; } - } return new (C === undefined ? Array : C)(length === 0 ? 0 : length); + } return C === undefined ? Array$6 : C; }; - var bind$b = functionBindContext; + var arraySpeciesConstructor = arraySpeciesConstructor$1; + + // `ArraySpeciesCreate` abstract operation + // https://tc39.es/ecma262/#sec-arrayspeciescreate + var arraySpeciesCreate$4 = function (originalArray, length) { + return new (arraySpeciesConstructor(originalArray))(length === 0 ? 0 : length); + }; + + var bind$e = functionBindContext; + var uncurryThis$H = functionUncurryThis; var IndexedObject$3 = indexedObject; - var toObject$f = toObject$i; - var toLength$o = toLength$q; - var arraySpeciesCreate$2 = arraySpeciesCreate$3; + var toObject$g = toObject$j; + var lengthOfArrayLike$e = lengthOfArrayLike$g; + var arraySpeciesCreate$3 = arraySpeciesCreate$4; - var push = [].push; + var push$9 = uncurryThis$H([].push); - // `Array.prototype.{ forEach, map, filter, some, every, find, findIndex, filterOut }` methods implementation + // `Array.prototype.{ forEach, map, filter, some, every, find, findIndex, filterReject }` methods implementation var createMethod$4 = function (TYPE) { var IS_MAP = TYPE == 1; var IS_FILTER = TYPE == 2; var IS_SOME = TYPE == 3; var IS_EVERY = TYPE == 4; var IS_FIND_INDEX = TYPE == 6; - var IS_FILTER_OUT = TYPE == 7; + var IS_FILTER_REJECT = TYPE == 7; var NO_HOLES = TYPE == 5 || IS_FIND_INDEX; return function ($this, callbackfn, that, specificCreate) { - var O = toObject$f($this); + var O = toObject$g($this); var self = IndexedObject$3(O); - var boundFunction = bind$b(callbackfn, that, 3); - var length = toLength$o(self.length); + var boundFunction = bind$e(callbackfn, that); + var length = lengthOfArrayLike$e(self); var index = 0; - var create = specificCreate || arraySpeciesCreate$2; - var target = IS_MAP ? create($this, length) : IS_FILTER || IS_FILTER_OUT ? create($this, 0) : undefined; + var create = specificCreate || arraySpeciesCreate$3; + var target = IS_MAP ? create($this, length) : IS_FILTER || IS_FILTER_REJECT ? create($this, 0) : undefined; var value, result; for (;length > index; index++) if (NO_HOLES || index in self) { value = self[index]; @@ -1656,10 +1986,10 @@ case 3: return true; // some case 5: return value; // find case 6: return index; // findIndex - case 2: push.call(target, value); // filter + case 2: push$9(target, value); // filter } else switch (TYPE) { case 4: return false; // every - case 7: push.call(target, value); // filterOut + case 7: push$9(target, value); // filterReject } } } @@ -1689,41 +2019,47 @@ // `Array.prototype.findIndex` method // https://tc39.es/ecma262/#sec-array.prototype.findIndex findIndex: createMethod$4(6), - // `Array.prototype.filterOut` method + // `Array.prototype.filterReject` method // https://github.com/tc39/proposal-array-filtering - filterOut: createMethod$4(7) + filterReject: createMethod$4(7) }; - var $$14 = _export; - var global$s = global$F; - var getBuiltIn$5 = getBuiltIn$9; + var $$1b = _export; + var global$U = global$1m; + var getBuiltIn$5 = getBuiltIn$b; + var apply$8 = functionApply; + var call$j = functionCall; + var uncurryThis$G = functionUncurryThis; var DESCRIPTORS$h = descriptors; - var NATIVE_SYMBOL = nativeSymbol; - var USE_SYMBOL_AS_UID = useSymbolAsUid; - var fails$F = fails$N; - var has$8 = has$j; - var isArray$4 = isArray$6; - var isObject$k = isObject$r; - var anObject$g = anObject$m; - var toObject$e = toObject$i; - var toIndexedObject$5 = toIndexedObject$b; - var toPrimitive$4 = toPrimitive$7; + var NATIVE_SYMBOL$1 = nativeSymbol; + var fails$J = fails$S; + var hasOwn$b = hasOwnProperty_1; + var isArray$6 = isArray$8; + var isCallable$b = isCallable$r; + var isObject$l = isObject$s; + var isPrototypeOf$8 = objectIsPrototypeOf; + var isSymbol$3 = isSymbol$6; + var anObject$h = anObject$n; + var toObject$f = toObject$j; + var toIndexedObject$5 = toIndexedObject$c; + var toPropertyKey$2 = toPropertyKey$5; + var $toString$3 = toString$k; var createPropertyDescriptor$3 = createPropertyDescriptor$7; var nativeObjectCreate = objectCreate; var objectKeys$2 = objectKeys$4; - var getOwnPropertyNamesModule = objectGetOwnPropertyNames; + var getOwnPropertyNamesModule$1 = objectGetOwnPropertyNames; var getOwnPropertyNamesExternal = objectGetOwnPropertyNamesExternal; var getOwnPropertySymbolsModule$1 = objectGetOwnPropertySymbols; var getOwnPropertyDescriptorModule$2 = objectGetOwnPropertyDescriptor; var definePropertyModule$3 = objectDefineProperty; var propertyIsEnumerableModule$1 = objectPropertyIsEnumerable; - var createNonEnumerableProperty$6 = createNonEnumerableProperty$e; - var redefine$b = redefine$g.exports; + var arraySlice$a = arraySlice$c; + var redefine$b = redefine$h.exports; var shared$1 = shared$5.exports; var sharedKey = sharedKey$4; var hiddenKeys$1 = hiddenKeys$6; var uid$2 = uid$5; - var wellKnownSymbol$i = wellKnownSymbol$s; + var wellKnownSymbol$i = wellKnownSymbol$t; var wrappedWellKnownSymbolModule = wellKnownSymbolWrapped; var defineWellKnownSymbol$2 = defineWellKnownSymbol$4; var setToStringTag$7 = setToStringTag$a; @@ -1734,40 +2070,47 @@ var SYMBOL = 'Symbol'; var PROTOTYPE$1 = 'prototype'; var TO_PRIMITIVE = wellKnownSymbol$i('toPrimitive'); + var setInternalState$6 = InternalStateModule$6.set; var getInternalState$4 = InternalStateModule$6.getterFor(SYMBOL); - var ObjectPrototype$2 = Object[PROTOTYPE$1]; - var $Symbol = global$s.Symbol; + + var ObjectPrototype$3 = Object[PROTOTYPE$1]; + var $Symbol = global$U.Symbol; + var SymbolPrototype$1 = $Symbol && $Symbol[PROTOTYPE$1]; + var TypeError$g = global$U.TypeError; + var QObject = global$U.QObject; var $stringify = getBuiltIn$5('JSON', 'stringify'); var nativeGetOwnPropertyDescriptor$2 = getOwnPropertyDescriptorModule$2.f; var nativeDefineProperty$1 = definePropertyModule$3.f; var nativeGetOwnPropertyNames = getOwnPropertyNamesExternal.f; var nativePropertyIsEnumerable = propertyIsEnumerableModule$1.f; + var push$8 = uncurryThis$G([].push); + var AllSymbols = shared$1('symbols'); var ObjectPrototypeSymbols = shared$1('op-symbols'); var StringToSymbolRegistry = shared$1('string-to-symbol-registry'); var SymbolToStringRegistry = shared$1('symbol-to-string-registry'); var WellKnownSymbolsStore = shared$1('wks'); - var QObject = global$s.QObject; + // Don't use setters in Qt Script, https://github.com/zloirock/core-js/issues/173 var USE_SETTER = !QObject || !QObject[PROTOTYPE$1] || !QObject[PROTOTYPE$1].findChild; // fallback for old Android, https://code.google.com/p/v8/issues/detail?id=687 - var setSymbolDescriptor = DESCRIPTORS$h && fails$F(function () { + var setSymbolDescriptor = DESCRIPTORS$h && fails$J(function () { return nativeObjectCreate(nativeDefineProperty$1({}, 'a', { get: function () { return nativeDefineProperty$1(this, 'a', { value: 7 }).a; } })).a != 7; }) ? function (O, P, Attributes) { - var ObjectPrototypeDescriptor = nativeGetOwnPropertyDescriptor$2(ObjectPrototype$2, P); - if (ObjectPrototypeDescriptor) delete ObjectPrototype$2[P]; + var ObjectPrototypeDescriptor = nativeGetOwnPropertyDescriptor$2(ObjectPrototype$3, P); + if (ObjectPrototypeDescriptor) delete ObjectPrototype$3[P]; nativeDefineProperty$1(O, P, Attributes); - if (ObjectPrototypeDescriptor && O !== ObjectPrototype$2) { - nativeDefineProperty$1(ObjectPrototype$2, P, ObjectPrototypeDescriptor); + if (ObjectPrototypeDescriptor && O !== ObjectPrototype$3) { + nativeDefineProperty$1(ObjectPrototype$3, P, ObjectPrototypeDescriptor); } } : nativeDefineProperty$1; var wrap$2 = function (tag, description) { - var symbol = AllSymbols[tag] = nativeObjectCreate($Symbol[PROTOTYPE$1]); + var symbol = AllSymbols[tag] = nativeObjectCreate(SymbolPrototype$1); setInternalState$6(symbol, { type: SYMBOL, tag: tag, @@ -1777,34 +2120,28 @@ return symbol; }; - var isSymbol$1 = USE_SYMBOL_AS_UID ? function (it) { - return typeof it == 'symbol'; - } : function (it) { - return Object(it) instanceof $Symbol; - }; - var $defineProperty = function defineProperty(O, P, Attributes) { - if (O === ObjectPrototype$2) $defineProperty(ObjectPrototypeSymbols, P, Attributes); - anObject$g(O); - var key = toPrimitive$4(P, true); - anObject$g(Attributes); - if (has$8(AllSymbols, key)) { + if (O === ObjectPrototype$3) $defineProperty(ObjectPrototypeSymbols, P, Attributes); + anObject$h(O); + var key = toPropertyKey$2(P); + anObject$h(Attributes); + if (hasOwn$b(AllSymbols, key)) { if (!Attributes.enumerable) { - if (!has$8(O, HIDDEN)) nativeDefineProperty$1(O, HIDDEN, createPropertyDescriptor$3(1, {})); + if (!hasOwn$b(O, HIDDEN)) nativeDefineProperty$1(O, HIDDEN, createPropertyDescriptor$3(1, {})); O[HIDDEN][key] = true; } else { - if (has$8(O, HIDDEN) && O[HIDDEN][key]) O[HIDDEN][key] = false; + if (hasOwn$b(O, HIDDEN) && O[HIDDEN][key]) O[HIDDEN][key] = false; Attributes = nativeObjectCreate(Attributes, { enumerable: createPropertyDescriptor$3(0, false) }); } return setSymbolDescriptor(O, key, Attributes); } return nativeDefineProperty$1(O, key, Attributes); }; var $defineProperties = function defineProperties(O, Properties) { - anObject$g(O); + anObject$h(O); var properties = toIndexedObject$5(Properties); var keys = objectKeys$2(properties).concat($getOwnPropertySymbols(properties)); $forEach$2(keys, function (key) { - if (!DESCRIPTORS$h || $propertyIsEnumerable.call(properties, key)) $defineProperty(O, key, properties[key]); + if (!DESCRIPTORS$h || call$j($propertyIsEnumerable$1, properties, key)) $defineProperty(O, key, properties[key]); }); return O; }; @@ -1813,19 +2150,20 @@ return Properties === undefined ? nativeObjectCreate(O) : $defineProperties(nativeObjectCreate(O), Properties); }; - var $propertyIsEnumerable = function propertyIsEnumerable(V) { - var P = toPrimitive$4(V, true); - var enumerable = nativePropertyIsEnumerable.call(this, P); - if (this === ObjectPrototype$2 && has$8(AllSymbols, P) && !has$8(ObjectPrototypeSymbols, P)) return false; - return enumerable || !has$8(this, P) || !has$8(AllSymbols, P) || has$8(this, HIDDEN) && this[HIDDEN][P] ? enumerable : true; + var $propertyIsEnumerable$1 = function propertyIsEnumerable(V) { + var P = toPropertyKey$2(V); + var enumerable = call$j(nativePropertyIsEnumerable, this, P); + if (this === ObjectPrototype$3 && hasOwn$b(AllSymbols, P) && !hasOwn$b(ObjectPrototypeSymbols, P)) return false; + return enumerable || !hasOwn$b(this, P) || !hasOwn$b(AllSymbols, P) || hasOwn$b(this, HIDDEN) && this[HIDDEN][P] + ? enumerable : true; }; var $getOwnPropertyDescriptor = function getOwnPropertyDescriptor(O, P) { var it = toIndexedObject$5(O); - var key = toPrimitive$4(P, true); - if (it === ObjectPrototype$2 && has$8(AllSymbols, key) && !has$8(ObjectPrototypeSymbols, key)) return; + var key = toPropertyKey$2(P); + if (it === ObjectPrototype$3 && hasOwn$b(AllSymbols, key) && !hasOwn$b(ObjectPrototypeSymbols, key)) return; var descriptor = nativeGetOwnPropertyDescriptor$2(it, key); - if (descriptor && has$8(AllSymbols, key) && !(has$8(it, HIDDEN) && it[HIDDEN][key])) { + if (descriptor && hasOwn$b(AllSymbols, key) && !(hasOwn$b(it, HIDDEN) && it[HIDDEN][key])) { descriptor.enumerable = true; } return descriptor; @@ -1835,18 +2173,18 @@ var names = nativeGetOwnPropertyNames(toIndexedObject$5(O)); var result = []; $forEach$2(names, function (key) { - if (!has$8(AllSymbols, key) && !has$8(hiddenKeys$1, key)) result.push(key); + if (!hasOwn$b(AllSymbols, key) && !hasOwn$b(hiddenKeys$1, key)) push$8(result, key); }); return result; }; var $getOwnPropertySymbols = function getOwnPropertySymbols(O) { - var IS_OBJECT_PROTOTYPE = O === ObjectPrototype$2; + var IS_OBJECT_PROTOTYPE = O === ObjectPrototype$3; var names = nativeGetOwnPropertyNames(IS_OBJECT_PROTOTYPE ? ObjectPrototypeSymbols : toIndexedObject$5(O)); var result = []; $forEach$2(names, function (key) { - if (has$8(AllSymbols, key) && (!IS_OBJECT_PROTOTYPE || has$8(ObjectPrototype$2, key))) { - result.push(AllSymbols[key]); + if (hasOwn$b(AllSymbols, key) && (!IS_OBJECT_PROTOTYPE || hasOwn$b(ObjectPrototype$3, key))) { + push$8(result, AllSymbols[key]); } }); return result; @@ -1854,21 +2192,23 @@ // `Symbol` constructor // https://tc39.es/ecma262/#sec-symbol-constructor - if (!NATIVE_SYMBOL) { + if (!NATIVE_SYMBOL$1) { $Symbol = function Symbol() { - if (this instanceof $Symbol) throw TypeError('Symbol is not a constructor'); - var description = !arguments.length || arguments[0] === undefined ? undefined : String(arguments[0]); + if (isPrototypeOf$8(SymbolPrototype$1, this)) throw TypeError$g('Symbol is not a constructor'); + var description = !arguments.length || arguments[0] === undefined ? undefined : $toString$3(arguments[0]); var tag = uid$2(description); var setter = function (value) { - if (this === ObjectPrototype$2) setter.call(ObjectPrototypeSymbols, value); - if (has$8(this, HIDDEN) && has$8(this[HIDDEN], tag)) this[HIDDEN][tag] = false; + if (this === ObjectPrototype$3) call$j(setter, ObjectPrototypeSymbols, value); + if (hasOwn$b(this, HIDDEN) && hasOwn$b(this[HIDDEN], tag)) this[HIDDEN][tag] = false; setSymbolDescriptor(this, tag, createPropertyDescriptor$3(1, value)); }; - if (DESCRIPTORS$h && USE_SETTER) setSymbolDescriptor(ObjectPrototype$2, tag, { configurable: true, set: setter }); + if (DESCRIPTORS$h && USE_SETTER) setSymbolDescriptor(ObjectPrototype$3, tag, { configurable: true, set: setter }); return wrap$2(tag, description); }; - redefine$b($Symbol[PROTOTYPE$1], 'toString', function toString() { + SymbolPrototype$1 = $Symbol[PROTOTYPE$1]; + + redefine$b(SymbolPrototype$1, 'toString', function toString() { return getInternalState$4(this).tag; }); @@ -1876,10 +2216,10 @@ return wrap$2(uid$2(description), description); }); - propertyIsEnumerableModule$1.f = $propertyIsEnumerable; + propertyIsEnumerableModule$1.f = $propertyIsEnumerable$1; definePropertyModule$3.f = $defineProperty; getOwnPropertyDescriptorModule$2.f = $getOwnPropertyDescriptor; - getOwnPropertyNamesModule.f = getOwnPropertyNamesExternal.f = $getOwnPropertyNames; + getOwnPropertyNamesModule$1.f = getOwnPropertyNamesExternal.f = $getOwnPropertyNames; getOwnPropertySymbolsModule$1.f = $getOwnPropertySymbols; wrappedWellKnownSymbolModule.f = function (name) { @@ -1888,19 +2228,19 @@ if (DESCRIPTORS$h) { // https://github.com/tc39/proposal-Symbol-description - nativeDefineProperty$1($Symbol[PROTOTYPE$1], 'description', { + nativeDefineProperty$1(SymbolPrototype$1, 'description', { configurable: true, get: function description() { return getInternalState$4(this).description; } }); { - redefine$b(ObjectPrototype$2, 'propertyIsEnumerable', $propertyIsEnumerable, { unsafe: true }); + redefine$b(ObjectPrototype$3, 'propertyIsEnumerable', $propertyIsEnumerable$1, { unsafe: true }); } } } - $$14({ global: true, wrap: true, forced: !NATIVE_SYMBOL, sham: !NATIVE_SYMBOL }, { + $$1b({ global: true, wrap: true, forced: !NATIVE_SYMBOL$1, sham: !NATIVE_SYMBOL$1 }, { Symbol: $Symbol }); @@ -1908,12 +2248,12 @@ defineWellKnownSymbol$2(name); }); - $$14({ target: SYMBOL, stat: true, forced: !NATIVE_SYMBOL }, { + $$1b({ target: SYMBOL, stat: true, forced: !NATIVE_SYMBOL$1 }, { // `Symbol.for` method // https://tc39.es/ecma262/#sec-symbol.for 'for': function (key) { - var string = String(key); - if (has$8(StringToSymbolRegistry, string)) return StringToSymbolRegistry[string]; + var string = $toString$3(key); + if (hasOwn$b(StringToSymbolRegistry, string)) return StringToSymbolRegistry[string]; var symbol = $Symbol(string); StringToSymbolRegistry[string] = symbol; SymbolToStringRegistry[symbol] = string; @@ -1922,14 +2262,14 @@ // `Symbol.keyFor` method // https://tc39.es/ecma262/#sec-symbol.keyfor keyFor: function keyFor(sym) { - if (!isSymbol$1(sym)) throw TypeError(sym + ' is not a symbol'); - if (has$8(SymbolToStringRegistry, sym)) return SymbolToStringRegistry[sym]; + if (!isSymbol$3(sym)) throw TypeError$g(sym + ' is not a symbol'); + if (hasOwn$b(SymbolToStringRegistry, sym)) return SymbolToStringRegistry[sym]; }, useSetter: function () { USE_SETTER = true; }, useSimple: function () { USE_SETTER = false; } }); - $$14({ target: 'Object', stat: true, forced: !NATIVE_SYMBOL, sham: !DESCRIPTORS$h }, { + $$1b({ target: 'Object', stat: true, forced: !NATIVE_SYMBOL$1, sham: !DESCRIPTORS$h }, { // `Object.create` method // https://tc39.es/ecma262/#sec-object.create create: $create, @@ -1944,7 +2284,7 @@ getOwnPropertyDescriptor: $getOwnPropertyDescriptor }); - $$14({ target: 'Object', stat: true, forced: !NATIVE_SYMBOL }, { + $$1b({ target: 'Object', stat: true, forced: !NATIVE_SYMBOL$1 }, { // `Object.getOwnPropertyNames` method // https://tc39.es/ecma262/#sec-object.getownpropertynames getOwnPropertyNames: $getOwnPropertyNames, @@ -1955,16 +2295,16 @@ // Chrome 38 and 39 `Object.getOwnPropertySymbols` fails on primitives // https://bugs.chromium.org/p/v8/issues/detail?id=3443 - $$14({ target: 'Object', stat: true, forced: fails$F(function () { getOwnPropertySymbolsModule$1.f(1); }) }, { + $$1b({ target: 'Object', stat: true, forced: fails$J(function () { getOwnPropertySymbolsModule$1.f(1); }) }, { getOwnPropertySymbols: function getOwnPropertySymbols(it) { - return getOwnPropertySymbolsModule$1.f(toObject$e(it)); + return getOwnPropertySymbolsModule$1.f(toObject$f(it)); } }); // `JSON.stringify` method behavior with symbols // https://tc39.es/ecma262/#sec-json.stringify if ($stringify) { - var FORCED_JSON_STRINGIFY = !NATIVE_SYMBOL || fails$F(function () { + var FORCED_JSON_STRINGIFY = !NATIVE_SYMBOL$1 || fails$J(function () { var symbol = $Symbol(); // MS Edge converts symbol values to JSON as {} return $stringify([symbol]) != '[null]' @@ -1974,29 +2314,31 @@ || $stringify(Object(symbol)) != '{}'; }); - $$14({ target: 'JSON', stat: true, forced: FORCED_JSON_STRINGIFY }, { + $$1b({ target: 'JSON', stat: true, forced: FORCED_JSON_STRINGIFY }, { // eslint-disable-next-line no-unused-vars -- required for `.length` stringify: function stringify(it, replacer, space) { - var args = [it]; - var index = 1; - var $replacer; - while (arguments.length > index) args.push(arguments[index++]); - $replacer = replacer; - if (!isObject$k(replacer) && it === undefined || isSymbol$1(it)) return; // IE8 returns string on undefined - if (!isArray$4(replacer)) replacer = function (key, value) { - if (typeof $replacer == 'function') value = $replacer.call(this, key, value); - if (!isSymbol$1(value)) return value; + var args = arraySlice$a(arguments); + var $replacer = replacer; + if (!isObject$l(replacer) && it === undefined || isSymbol$3(it)) return; // IE8 returns string on undefined + if (!isArray$6(replacer)) replacer = function (key, value) { + if (isCallable$b($replacer)) value = call$j($replacer, this, key, value); + if (!isSymbol$3(value)) return value; }; args[1] = replacer; - return $stringify.apply(null, args); + return apply$8($stringify, null, args); } }); } // `Symbol.prototype[@@toPrimitive]` method // https://tc39.es/ecma262/#sec-symbol.prototype-@@toprimitive - if (!$Symbol[PROTOTYPE$1][TO_PRIMITIVE]) { - createNonEnumerableProperty$6($Symbol[PROTOTYPE$1], TO_PRIMITIVE, $Symbol[PROTOTYPE$1].valueOf); + if (!SymbolPrototype$1[TO_PRIMITIVE]) { + var valueOf = SymbolPrototype$1.valueOf; + // eslint-disable-next-line no-unused-vars -- required for .length + redefine$b(SymbolPrototype$1, TO_PRIMITIVE, function (hint) { + // TODO: improve hint logic + return call$j(valueOf, this); + }); } // `Symbol.prototype[@@toStringTag]` property // https://tc39.es/ecma262/#sec-symbol.prototype-@@tostringtag @@ -2004,92 +2346,111 @@ hiddenKeys$1[HIDDEN] = true; - var $$13 = _export; + var $$1a = _export; var DESCRIPTORS$g = descriptors; - var global$r = global$F; - var has$7 = has$j; - var isObject$j = isObject$r; + var global$T = global$1m; + var uncurryThis$F = functionUncurryThis; + var hasOwn$a = hasOwnProperty_1; + var isCallable$a = isCallable$r; + var isPrototypeOf$7 = objectIsPrototypeOf; + var toString$h = toString$k; var defineProperty$8 = objectDefineProperty.f; var copyConstructorProperties = copyConstructorProperties$2; - var NativeSymbol = global$r.Symbol; + var NativeSymbol = global$T.Symbol; + var SymbolPrototype = NativeSymbol && NativeSymbol.prototype; - if (DESCRIPTORS$g && typeof NativeSymbol == 'function' && (!('description' in NativeSymbol.prototype) || + if (DESCRIPTORS$g && isCallable$a(NativeSymbol) && (!('description' in SymbolPrototype) || // Safari 12 bug NativeSymbol().description !== undefined )) { var EmptyStringDescriptionStore = {}; // wrap Symbol constructor for correct work with undefined description var SymbolWrapper = function Symbol() { - var description = arguments.length < 1 || arguments[0] === undefined ? undefined : String(arguments[0]); - var result = this instanceof SymbolWrapper + var description = arguments.length < 1 || arguments[0] === undefined ? undefined : toString$h(arguments[0]); + var result = isPrototypeOf$7(SymbolPrototype, this) ? new NativeSymbol(description) // in Edge 13, String(Symbol(undefined)) === 'Symbol(undefined)' : description === undefined ? NativeSymbol() : NativeSymbol(description); if (description === '') EmptyStringDescriptionStore[result] = true; return result; }; + copyConstructorProperties(SymbolWrapper, NativeSymbol); - var symbolPrototype = SymbolWrapper.prototype = NativeSymbol.prototype; - symbolPrototype.constructor = SymbolWrapper; + SymbolWrapper.prototype = SymbolPrototype; + SymbolPrototype.constructor = SymbolWrapper; - var symbolToString = symbolPrototype.toString; - var native = String(NativeSymbol('test')) == 'Symbol(test)'; + var NATIVE_SYMBOL = String(NativeSymbol('test')) == 'Symbol(test)'; + var symbolToString$1 = uncurryThis$F(SymbolPrototype.toString); + var symbolValueOf = uncurryThis$F(SymbolPrototype.valueOf); var regexp = /^Symbol\((.*)\)[^)]+$/; - defineProperty$8(symbolPrototype, 'description', { + var replace$8 = uncurryThis$F(''.replace); + var stringSlice$a = uncurryThis$F(''.slice); + + defineProperty$8(SymbolPrototype, 'description', { configurable: true, get: function description() { - var symbol = isObject$j(this) ? this.valueOf() : this; - var string = symbolToString.call(symbol); - if (has$7(EmptyStringDescriptionStore, symbol)) return ''; - var desc = native ? string.slice(7, -1) : string.replace(regexp, '$1'); + var symbol = symbolValueOf(this); + var string = symbolToString$1(symbol); + if (hasOwn$a(EmptyStringDescriptionStore, symbol)) return ''; + var desc = NATIVE_SYMBOL ? stringSlice$a(string, 7, -1) : replace$8(string, regexp, '$1'); return desc === '' ? undefined : desc; } }); - $$13({ global: true, forced: true }, { + $$1a({ global: true, forced: true }, { Symbol: SymbolWrapper }); } // eslint-disable-next-line es/no-typed-arrays -- safe - var arrayBufferNative = typeof ArrayBuffer !== 'undefined' && typeof DataView !== 'undefined'; + var arrayBufferNative = typeof ArrayBuffer != 'undefined' && typeof DataView != 'undefined'; - var redefine$a = redefine$g.exports; + var redefine$a = redefine$h.exports; var redefineAll$4 = function (target, src, options) { for (var key in src) redefine$a(target, key, src[key], options); return target; }; - var anInstance$7 = function (it, Constructor, name) { - if (!(it instanceof Constructor)) { - throw TypeError('Incorrect ' + (name ? name + ' ' : '') + 'invocation'); - } return it; + var global$S = global$1m; + var isPrototypeOf$6 = objectIsPrototypeOf; + + var TypeError$f = global$S.TypeError; + + var anInstance$7 = function (it, Prototype) { + if (isPrototypeOf$6(Prototype, it)) return it; + throw TypeError$f('Incorrect invocation'); }; - var toInteger$7 = toInteger$b; - var toLength$n = toLength$q; + var global$R = global$1m; + var toIntegerOrInfinity$7 = toIntegerOrInfinity$b; + var toLength$a = toLength$c; + + var RangeError$b = global$R.RangeError; // `ToIndex` abstract operation // https://tc39.es/ecma262/#sec-toindex var toIndex$2 = function (it) { if (it === undefined) return 0; - var number = toInteger$7(it); - var length = toLength$n(number); - if (number !== length) throw RangeError('Wrong length or index'); + var number = toIntegerOrInfinity$7(it); + var length = toLength$a(number); + if (number !== length) throw RangeError$b('Wrong length or index'); return length; }; // IEEE754 conversions based on https://github.com/feross/ieee754 + var global$Q = global$1m; + + var Array$5 = global$Q.Array; var abs$4 = Math.abs; var pow$2 = Math.pow; - var floor$6 = Math.floor; + var floor$7 = Math.floor; var log$2 = Math.log; var LN2 = Math.LN2; var pack = function (number, mantissaLength, bytes) { - var buffer = new Array(bytes); + var buffer = Array$5(bytes); var exponentLength = bytes * 8 - mantissaLength - 1; var eMax = (1 << exponentLength) - 1; var eBias = eMax >> 1; @@ -2104,7 +2465,7 @@ mantissa = number != number ? 1 : 0; exponent = eMax; } else { - exponent = floor$6(log$2(number) / LN2); + exponent = floor$7(log$2(number) / LN2); if (number * (c = pow$2(2, -exponent)) < 1) { exponent--; c *= 2; @@ -2168,15 +2529,15 @@ unpack: unpack }; - var toObject$d = toObject$i; + var toObject$e = toObject$j; var toAbsoluteIndex$6 = toAbsoluteIndex$8; - var toLength$m = toLength$q; + var lengthOfArrayLike$d = lengthOfArrayLike$g; // `Array.prototype.fill` method implementation // https://tc39.es/ecma262/#sec-array.prototype.fill var arrayFill$1 = function fill(value /* , start = 0, end = @length */) { - var O = toObject$d(this); - var length = toLength$m(O.length); + var O = toObject$e(this); + var length = lengthOfArrayLike$d(O); var argumentsLength = arguments.length; var index = toAbsoluteIndex$6(argumentsLength > 1 ? arguments[1] : undefined, length); var end = argumentsLength > 2 ? arguments[2] : undefined; @@ -2185,15 +2546,17 @@ return O; }; - var global$q = global$F; + var global$P = global$1m; + var uncurryThis$E = functionUncurryThis; var DESCRIPTORS$f = descriptors; var NATIVE_ARRAY_BUFFER$2 = arrayBufferNative; - var createNonEnumerableProperty$5 = createNonEnumerableProperty$e; + var FunctionName = functionName; + var createNonEnumerableProperty$5 = createNonEnumerableProperty$b; var redefineAll$3 = redefineAll$4; - var fails$E = fails$N; + var fails$I = fails$S; var anInstance$6 = anInstance$7; - var toInteger$6 = toInteger$b; - var toLength$l = toLength$q; + var toIntegerOrInfinity$6 = toIntegerOrInfinity$b; + var toLength$9 = toLength$c; var toIndex$1 = toIndex$2; var IEEE754 = ieee754$2; var getPrototypeOf$2 = objectGetPrototypeOf; @@ -2201,9 +2564,12 @@ var getOwnPropertyNames$4 = objectGetOwnPropertyNames.f; var defineProperty$7 = objectDefineProperty.f; var arrayFill = arrayFill$1; + var arraySlice$9 = arraySlice$c; var setToStringTag$6 = setToStringTag$a; var InternalStateModule$5 = internalState; + var PROPER_FUNCTION_NAME$3 = FunctionName.PROPER; + var CONFIGURABLE_FUNCTION_NAME = FunctionName.CONFIGURABLE; var getInternalState$3 = InternalStateModule$5.get; var setInternalState$5 = InternalStateModule$5.set; var ARRAY_BUFFER$1 = 'ArrayBuffer'; @@ -2211,12 +2577,16 @@ var PROTOTYPE = 'prototype'; var WRONG_LENGTH$1 = 'Wrong length'; var WRONG_INDEX = 'Wrong index'; - var NativeArrayBuffer$1 = global$q[ARRAY_BUFFER$1]; + var NativeArrayBuffer$1 = global$P[ARRAY_BUFFER$1]; var $ArrayBuffer = NativeArrayBuffer$1; - var $DataView = global$q[DATA_VIEW]; - var $DataViewPrototype = $DataView && $DataView[PROTOTYPE]; - var ObjectPrototype$1 = Object.prototype; - var RangeError$2 = global$q.RangeError; + var ArrayBufferPrototype$1 = $ArrayBuffer && $ArrayBuffer[PROTOTYPE]; + var $DataView = global$P[DATA_VIEW]; + var DataViewPrototype$1 = $DataView && $DataView[PROTOTYPE]; + var ObjectPrototype$2 = Object.prototype; + var Array$4 = global$P.Array; + var RangeError$a = global$P.RangeError; + var fill$1 = uncurryThis$E(arrayFill); + var reverse = uncurryThis$E([].reverse); var packIEEE754 = IEEE754.pack; var unpackIEEE754 = IEEE754.unpack; @@ -2252,17 +2622,17 @@ var get$4 = function (view, count, index, isLittleEndian) { var intIndex = toIndex$1(index); var store = getInternalState$3(view); - if (intIndex + count > store.byteLength) throw RangeError$2(WRONG_INDEX); + if (intIndex + count > store.byteLength) throw RangeError$a(WRONG_INDEX); var bytes = getInternalState$3(store.buffer).bytes; var start = intIndex + store.byteOffset; - var pack = bytes.slice(start, start + count); - return isLittleEndian ? pack : pack.reverse(); + var pack = arraySlice$9(bytes, start, start + count); + return isLittleEndian ? pack : reverse(pack); }; var set$3 = function (view, count, index, conversion, value, isLittleEndian) { var intIndex = toIndex$1(index); var store = getInternalState$3(view); - if (intIndex + count > store.byteLength) throw RangeError$2(WRONG_INDEX); + if (intIndex + count > store.byteLength) throw RangeError$a(WRONG_INDEX); var bytes = getInternalState$3(store.buffer).bytes; var start = intIndex + store.byteOffset; var pack = conversion(+value); @@ -2271,23 +2641,25 @@ if (!NATIVE_ARRAY_BUFFER$2) { $ArrayBuffer = function ArrayBuffer(length) { - anInstance$6(this, $ArrayBuffer, ARRAY_BUFFER$1); + anInstance$6(this, ArrayBufferPrototype$1); var byteLength = toIndex$1(length); setInternalState$5(this, { - bytes: arrayFill.call(new Array(byteLength), 0), + bytes: fill$1(Array$4(byteLength), 0), byteLength: byteLength }); if (!DESCRIPTORS$f) this.byteLength = byteLength; }; + ArrayBufferPrototype$1 = $ArrayBuffer[PROTOTYPE]; + $DataView = function DataView(buffer, byteOffset, byteLength) { - anInstance$6(this, $DataView, DATA_VIEW); - anInstance$6(buffer, $ArrayBuffer, DATA_VIEW); + anInstance$6(this, DataViewPrototype$1); + anInstance$6(buffer, ArrayBufferPrototype$1); var bufferLength = getInternalState$3(buffer).byteLength; - var offset = toInteger$6(byteOffset); - if (offset < 0 || offset > bufferLength) throw RangeError$2('Wrong offset'); - byteLength = byteLength === undefined ? bufferLength - offset : toLength$l(byteLength); - if (offset + byteLength > bufferLength) throw RangeError$2(WRONG_LENGTH$1); + var offset = toIntegerOrInfinity$6(byteOffset); + if (offset < 0 || offset > bufferLength) throw RangeError$a('Wrong offset'); + byteLength = byteLength === undefined ? bufferLength - offset : toLength$9(byteLength); + if (offset + byteLength > bufferLength) throw RangeError$a(WRONG_LENGTH$1); setInternalState$5(this, { buffer: buffer, byteLength: byteLength, @@ -2300,6 +2672,8 @@ } }; + DataViewPrototype$1 = $DataView[PROTOTYPE]; + if (DESCRIPTORS$f) { addGetter$1($ArrayBuffer, 'byteLength'); addGetter$1($DataView, 'buffer'); @@ -2307,7 +2681,7 @@ addGetter$1($DataView, 'byteOffset'); } - redefineAll$3($DataView[PROTOTYPE], { + redefineAll$3(DataViewPrototype$1, { getInt8: function getInt8(byteOffset) { return get$4(this, 1, byteOffset)[0] << 24 >> 24; }, @@ -2360,47 +2734,53 @@ } }); } else { + var INCORRECT_ARRAY_BUFFER_NAME = PROPER_FUNCTION_NAME$3 && NativeArrayBuffer$1.name !== ARRAY_BUFFER$1; /* eslint-disable no-new -- required for testing */ - if (!fails$E(function () { + if (!fails$I(function () { NativeArrayBuffer$1(1); - }) || !fails$E(function () { + }) || !fails$I(function () { new NativeArrayBuffer$1(-1); - }) || fails$E(function () { + }) || fails$I(function () { new NativeArrayBuffer$1(); new NativeArrayBuffer$1(1.5); new NativeArrayBuffer$1(NaN); - return NativeArrayBuffer$1.name != ARRAY_BUFFER$1; + return INCORRECT_ARRAY_BUFFER_NAME && !CONFIGURABLE_FUNCTION_NAME; })) { /* eslint-enable no-new -- required for testing */ $ArrayBuffer = function ArrayBuffer(length) { - anInstance$6(this, $ArrayBuffer); + anInstance$6(this, ArrayBufferPrototype$1); return new NativeArrayBuffer$1(toIndex$1(length)); }; - var ArrayBufferPrototype = $ArrayBuffer[PROTOTYPE] = NativeArrayBuffer$1[PROTOTYPE]; + + $ArrayBuffer[PROTOTYPE] = ArrayBufferPrototype$1; + for (var keys$2 = getOwnPropertyNames$4(NativeArrayBuffer$1), j$2 = 0, key$1; keys$2.length > j$2;) { if (!((key$1 = keys$2[j$2++]) in $ArrayBuffer)) { createNonEnumerableProperty$5($ArrayBuffer, key$1, NativeArrayBuffer$1[key$1]); } } - ArrayBufferPrototype.constructor = $ArrayBuffer; + + ArrayBufferPrototype$1.constructor = $ArrayBuffer; + } else if (INCORRECT_ARRAY_BUFFER_NAME && CONFIGURABLE_FUNCTION_NAME) { + createNonEnumerableProperty$5(NativeArrayBuffer$1, 'name', ARRAY_BUFFER$1); } // WebKit bug - the same parent prototype for typed arrays and data view - if (setPrototypeOf$5 && getPrototypeOf$2($DataViewPrototype) !== ObjectPrototype$1) { - setPrototypeOf$5($DataViewPrototype, ObjectPrototype$1); + if (setPrototypeOf$5 && getPrototypeOf$2(DataViewPrototype$1) !== ObjectPrototype$2) { + setPrototypeOf$5(DataViewPrototype$1, ObjectPrototype$2); } // iOS Safari 7.x bug var testView = new $DataView(new $ArrayBuffer(2)); - var $setInt8 = $DataViewPrototype.setInt8; + var $setInt8 = uncurryThis$E(DataViewPrototype$1.setInt8); testView.setInt8(0, 2147483648); testView.setInt8(1, 2147483649); - if (testView.getInt8(0) || !testView.getInt8(1)) redefineAll$3($DataViewPrototype, { + if (testView.getInt8(0) || !testView.getInt8(1)) redefineAll$3(DataViewPrototype$1, { setInt8: function setInt8(byteOffset, value) { - $setInt8.call(this, byteOffset, value << 24 >> 24); + $setInt8(this, byteOffset, value << 24 >> 24); }, setUint8: function setUint8(byteOffset, value) { - $setInt8.call(this, byteOffset, value << 24 >> 24); + $setInt8(this, byteOffset, value << 24 >> 24); } }, { unsafe: true }); } @@ -2413,95 +2793,115 @@ DataView: $DataView }; - var anObject$f = anObject$m; - var aFunction$7 = aFunction$9; - var wellKnownSymbol$h = wellKnownSymbol$s; + var global$O = global$1m; + var isConstructor$2 = isConstructor$4; + var tryToString$3 = tryToString$5; + + var TypeError$e = global$O.TypeError; + + // `Assert: IsConstructor(argument) is true` + var aConstructor$3 = function (argument) { + if (isConstructor$2(argument)) return argument; + throw TypeError$e(tryToString$3(argument) + ' is not a constructor'); + }; + + var anObject$g = anObject$n; + var aConstructor$2 = aConstructor$3; + var wellKnownSymbol$h = wellKnownSymbol$t; var SPECIES$5 = wellKnownSymbol$h('species'); // `SpeciesConstructor` abstract operation // https://tc39.es/ecma262/#sec-speciesconstructor - var speciesConstructor$8 = function (O, defaultConstructor) { - var C = anObject$f(O).constructor; + var speciesConstructor$5 = function (O, defaultConstructor) { + var C = anObject$g(O).constructor; var S; - return C === undefined || (S = anObject$f(C)[SPECIES$5]) == undefined ? defaultConstructor : aFunction$7(S); + return C === undefined || (S = anObject$g(C)[SPECIES$5]) == undefined ? defaultConstructor : aConstructor$2(S); }; - var $$12 = _export; - var fails$D = fails$N; + var $$19 = _export; + var uncurryThis$D = functionUncurryThis; + var fails$H = fails$S; var ArrayBufferModule$2 = arrayBuffer; - var anObject$e = anObject$m; + var anObject$f = anObject$n; var toAbsoluteIndex$5 = toAbsoluteIndex$8; - var toLength$k = toLength$q; - var speciesConstructor$7 = speciesConstructor$8; + var toLength$8 = toLength$c; + var speciesConstructor$4 = speciesConstructor$5; var ArrayBuffer$4 = ArrayBufferModule$2.ArrayBuffer; var DataView$2 = ArrayBufferModule$2.DataView; - var nativeArrayBufferSlice = ArrayBuffer$4.prototype.slice; + var DataViewPrototype = DataView$2.prototype; + var un$ArrayBufferSlice = uncurryThis$D(ArrayBuffer$4.prototype.slice); + var getUint8 = uncurryThis$D(DataViewPrototype.getUint8); + var setUint8 = uncurryThis$D(DataViewPrototype.setUint8); - var INCORRECT_SLICE = fails$D(function () { + var INCORRECT_SLICE = fails$H(function () { return !new ArrayBuffer$4(2).slice(1, undefined).byteLength; }); // `ArrayBuffer.prototype.slice` method // https://tc39.es/ecma262/#sec-arraybuffer.prototype.slice - $$12({ target: 'ArrayBuffer', proto: true, unsafe: true, forced: INCORRECT_SLICE }, { + $$19({ target: 'ArrayBuffer', proto: true, unsafe: true, forced: INCORRECT_SLICE }, { slice: function slice(start, end) { - if (nativeArrayBufferSlice !== undefined && end === undefined) { - return nativeArrayBufferSlice.call(anObject$e(this), start); // FF fix + if (un$ArrayBufferSlice && end === undefined) { + return un$ArrayBufferSlice(anObject$f(this), start); // FF fix } - var length = anObject$e(this).byteLength; + var length = anObject$f(this).byteLength; var first = toAbsoluteIndex$5(start, length); var fin = toAbsoluteIndex$5(end === undefined ? length : end, length); - var result = new (speciesConstructor$7(this, ArrayBuffer$4))(toLength$k(fin - first)); + var result = new (speciesConstructor$4(this, ArrayBuffer$4))(toLength$8(fin - first)); var viewSource = new DataView$2(this); var viewTarget = new DataView$2(result); var index = 0; while (first < fin) { - viewTarget.setUint8(index++, viewSource.getUint8(first++)); + setUint8(viewTarget, index++, getUint8(viewSource, first++)); } return result; } }); - var $$11 = _export; + var $$18 = _export; var ArrayBufferModule$1 = arrayBuffer; var NATIVE_ARRAY_BUFFER$1 = arrayBufferNative; // `DataView` constructor // https://tc39.es/ecma262/#sec-dataview-constructor - $$11({ global: true, forced: !NATIVE_ARRAY_BUFFER$1 }, { + $$18({ global: true, forced: !NATIVE_ARRAY_BUFFER$1 }, { DataView: ArrayBufferModule$1.DataView }); var NATIVE_ARRAY_BUFFER = arrayBufferNative; var DESCRIPTORS$e = descriptors; - var global$p = global$F; - var isObject$i = isObject$r; - var has$6 = has$j; - var classof$8 = classof$b; - var createNonEnumerableProperty$4 = createNonEnumerableProperty$e; - var redefine$9 = redefine$g.exports; + var global$N = global$1m; + var isCallable$9 = isCallable$r; + var isObject$k = isObject$s; + var hasOwn$9 = hasOwnProperty_1; + var classof$7 = classof$d; + var tryToString$2 = tryToString$5; + var createNonEnumerableProperty$4 = createNonEnumerableProperty$b; + var redefine$9 = redefine$h.exports; var defineProperty$6 = objectDefineProperty.f; + var isPrototypeOf$5 = objectIsPrototypeOf; var getPrototypeOf$1 = objectGetPrototypeOf; var setPrototypeOf$4 = objectSetPrototypeOf; - var wellKnownSymbol$g = wellKnownSymbol$s; + var wellKnownSymbol$g = wellKnownSymbol$t; var uid$1 = uid$5; - var Int8Array$3 = global$p.Int8Array; + var Int8Array$3 = global$N.Int8Array; var Int8ArrayPrototype = Int8Array$3 && Int8Array$3.prototype; - var Uint8ClampedArray = global$p.Uint8ClampedArray; + var Uint8ClampedArray = global$N.Uint8ClampedArray; var Uint8ClampedArrayPrototype = Uint8ClampedArray && Uint8ClampedArray.prototype; var TypedArray$1 = Int8Array$3 && getPrototypeOf$1(Int8Array$3); var TypedArrayPrototype$1 = Int8ArrayPrototype && getPrototypeOf$1(Int8ArrayPrototype); - var ObjectPrototype = Object.prototype; - var isPrototypeOf = ObjectPrototype.isPrototypeOf; + var ObjectPrototype$1 = Object.prototype; + var TypeError$d = global$N.TypeError; var TO_STRING_TAG = wellKnownSymbol$g('toStringTag'); var TYPED_ARRAY_TAG$1 = uid$1('TYPED_ARRAY_TAG'); + var TYPED_ARRAY_CONSTRUCTOR$2 = uid$1('TYPED_ARRAY_CONSTRUCTOR'); // Fixing native typed arrays in Opera Presto crashes the browser, see #595 - var NATIVE_ARRAY_BUFFER_VIEWS$3 = NATIVE_ARRAY_BUFFER && !!setPrototypeOf$4 && classof$8(global$p.opera) !== 'Opera'; + var NATIVE_ARRAY_BUFFER_VIEWS$3 = NATIVE_ARRAY_BUFFER && !!setPrototypeOf$4 && classof$7(global$N.opera) !== 'Opera'; var TYPED_ARRAY_TAG_REQIRED = false; - var NAME$1; + var NAME$1, Constructor, Prototype; var TypedArrayConstructorsList = { Int8Array: 1, @@ -2521,41 +2921,35 @@ }; var isView = function isView(it) { - if (!isObject$i(it)) return false; - var klass = classof$8(it); + if (!isObject$k(it)) return false; + var klass = classof$7(it); return klass === 'DataView' - || has$6(TypedArrayConstructorsList, klass) - || has$6(BigIntArrayConstructorsList, klass); + || hasOwn$9(TypedArrayConstructorsList, klass) + || hasOwn$9(BigIntArrayConstructorsList, klass); }; var isTypedArray$1 = function (it) { - if (!isObject$i(it)) return false; - var klass = classof$8(it); - return has$6(TypedArrayConstructorsList, klass) - || has$6(BigIntArrayConstructorsList, klass); + if (!isObject$k(it)) return false; + var klass = classof$7(it); + return hasOwn$9(TypedArrayConstructorsList, klass) + || hasOwn$9(BigIntArrayConstructorsList, klass); }; var aTypedArray$m = function (it) { if (isTypedArray$1(it)) return it; - throw TypeError('Target is not a typed array'); + throw TypeError$d('Target is not a typed array'); }; - var aTypedArrayConstructor$5 = function (C) { - if (setPrototypeOf$4) { - if (isPrototypeOf.call(TypedArray$1, C)) return C; - } else for (var ARRAY in TypedArrayConstructorsList) if (has$6(TypedArrayConstructorsList, NAME$1)) { - var TypedArrayConstructor = global$p[ARRAY]; - if (TypedArrayConstructor && (C === TypedArrayConstructor || isPrototypeOf.call(TypedArrayConstructor, C))) { - return C; - } - } throw TypeError('Target is not a typed array constructor'); + var aTypedArrayConstructor$3 = function (C) { + if (isCallable$9(C) && (!setPrototypeOf$4 || isPrototypeOf$5(TypedArray$1, C))) return C; + throw TypeError$d(tryToString$2(C) + ' is not a typed array constructor'); }; var exportTypedArrayMethod$n = function (KEY, property, forced) { if (!DESCRIPTORS$e) return; if (forced) for (var ARRAY in TypedArrayConstructorsList) { - var TypedArrayConstructor = global$p[ARRAY]; - if (TypedArrayConstructor && has$6(TypedArrayConstructor.prototype, KEY)) try { + var TypedArrayConstructor = global$N[ARRAY]; + if (TypedArrayConstructor && hasOwn$9(TypedArrayConstructor.prototype, KEY)) try { delete TypedArrayConstructor.prototype[KEY]; } catch (error) { /* empty */ } } @@ -2570,8 +2964,8 @@ if (!DESCRIPTORS$e) return; if (setPrototypeOf$4) { if (forced) for (ARRAY in TypedArrayConstructorsList) { - TypedArrayConstructor = global$p[ARRAY]; - if (TypedArrayConstructor && has$6(TypedArrayConstructor, KEY)) try { + TypedArrayConstructor = global$N[ARRAY]; + if (TypedArrayConstructor && hasOwn$9(TypedArrayConstructor, KEY)) try { delete TypedArrayConstructor[KEY]; } catch (error) { /* empty */ } } @@ -2583,7 +2977,7 @@ } else return; } for (ARRAY in TypedArrayConstructorsList) { - TypedArrayConstructor = global$p[ARRAY]; + TypedArrayConstructor = global$N[ARRAY]; if (TypedArrayConstructor && (!TypedArrayConstructor[KEY] || forced)) { redefine$9(TypedArrayConstructor, KEY, property); } @@ -2591,24 +2985,33 @@ }; for (NAME$1 in TypedArrayConstructorsList) { - if (!global$p[NAME$1]) NATIVE_ARRAY_BUFFER_VIEWS$3 = false; + Constructor = global$N[NAME$1]; + Prototype = Constructor && Constructor.prototype; + if (Prototype) createNonEnumerableProperty$4(Prototype, TYPED_ARRAY_CONSTRUCTOR$2, Constructor); + else NATIVE_ARRAY_BUFFER_VIEWS$3 = false; + } + + for (NAME$1 in BigIntArrayConstructorsList) { + Constructor = global$N[NAME$1]; + Prototype = Constructor && Constructor.prototype; + if (Prototype) createNonEnumerableProperty$4(Prototype, TYPED_ARRAY_CONSTRUCTOR$2, Constructor); } // WebKit bug - typed arrays constructors prototype is Object.prototype - if (!NATIVE_ARRAY_BUFFER_VIEWS$3 || typeof TypedArray$1 != 'function' || TypedArray$1 === Function.prototype) { + if (!NATIVE_ARRAY_BUFFER_VIEWS$3 || !isCallable$9(TypedArray$1) || TypedArray$1 === Function.prototype) { // eslint-disable-next-line no-shadow -- safe TypedArray$1 = function TypedArray() { - throw TypeError('Incorrect invocation'); + throw TypeError$d('Incorrect invocation'); }; if (NATIVE_ARRAY_BUFFER_VIEWS$3) for (NAME$1 in TypedArrayConstructorsList) { - if (global$p[NAME$1]) setPrototypeOf$4(global$p[NAME$1], TypedArray$1); + if (global$N[NAME$1]) setPrototypeOf$4(global$N[NAME$1], TypedArray$1); } } - if (!NATIVE_ARRAY_BUFFER_VIEWS$3 || !TypedArrayPrototype$1 || TypedArrayPrototype$1 === ObjectPrototype) { + if (!NATIVE_ARRAY_BUFFER_VIEWS$3 || !TypedArrayPrototype$1 || TypedArrayPrototype$1 === ObjectPrototype$1) { TypedArrayPrototype$1 = TypedArray$1.prototype; if (NATIVE_ARRAY_BUFFER_VIEWS$3) for (NAME$1 in TypedArrayConstructorsList) { - if (global$p[NAME$1]) setPrototypeOf$4(global$p[NAME$1].prototype, TypedArrayPrototype$1); + if (global$N[NAME$1]) setPrototypeOf$4(global$N[NAME$1].prototype, TypedArrayPrototype$1); } } @@ -2617,21 +3020,22 @@ setPrototypeOf$4(Uint8ClampedArrayPrototype, TypedArrayPrototype$1); } - if (DESCRIPTORS$e && !has$6(TypedArrayPrototype$1, TO_STRING_TAG)) { + if (DESCRIPTORS$e && !hasOwn$9(TypedArrayPrototype$1, TO_STRING_TAG)) { TYPED_ARRAY_TAG_REQIRED = true; defineProperty$6(TypedArrayPrototype$1, TO_STRING_TAG, { get: function () { - return isObject$i(this) ? this[TYPED_ARRAY_TAG$1] : undefined; + return isObject$k(this) ? this[TYPED_ARRAY_TAG$1] : undefined; } }); - for (NAME$1 in TypedArrayConstructorsList) if (global$p[NAME$1]) { - createNonEnumerableProperty$4(global$p[NAME$1], TYPED_ARRAY_TAG$1, NAME$1); + for (NAME$1 in TypedArrayConstructorsList) if (global$N[NAME$1]) { + createNonEnumerableProperty$4(global$N[NAME$1], TYPED_ARRAY_TAG$1, NAME$1); } } var arrayBufferViewCore = { NATIVE_ARRAY_BUFFER_VIEWS: NATIVE_ARRAY_BUFFER_VIEWS$3, + TYPED_ARRAY_CONSTRUCTOR: TYPED_ARRAY_CONSTRUCTOR$2, TYPED_ARRAY_TAG: TYPED_ARRAY_TAG_REQIRED && TYPED_ARRAY_TAG$1, aTypedArray: aTypedArray$m, - aTypedArrayConstructor: aTypedArrayConstructor$5, + aTypedArrayConstructor: aTypedArrayConstructor$3, exportTypedArrayMethod: exportTypedArrayMethod$n, exportTypedArrayStaticMethod: exportTypedArrayStaticMethod$1, isView: isView, @@ -2640,20 +3044,20 @@ TypedArrayPrototype: TypedArrayPrototype$1 }; - var $$10 = _export; - var ArrayBufferViewCore$n = arrayBufferViewCore; + var $$17 = _export; + var ArrayBufferViewCore$o = arrayBufferViewCore; - var NATIVE_ARRAY_BUFFER_VIEWS$2 = ArrayBufferViewCore$n.NATIVE_ARRAY_BUFFER_VIEWS; + var NATIVE_ARRAY_BUFFER_VIEWS$2 = ArrayBufferViewCore$o.NATIVE_ARRAY_BUFFER_VIEWS; // `ArrayBuffer.isView` method // https://tc39.es/ecma262/#sec-arraybuffer.isview - $$10({ target: 'ArrayBuffer', stat: true, forced: !NATIVE_ARRAY_BUFFER_VIEWS$2 }, { - isView: ArrayBufferViewCore$n.isView + $$17({ target: 'ArrayBuffer', stat: true, forced: !NATIVE_ARRAY_BUFFER_VIEWS$2 }, { + isView: ArrayBufferViewCore$o.isView }); - var getBuiltIn$4 = getBuiltIn$9; + var getBuiltIn$4 = getBuiltIn$b; var definePropertyModule$2 = objectDefineProperty; - var wellKnownSymbol$f = wellKnownSymbol$s; + var wellKnownSymbol$f = wellKnownSymbol$t; var DESCRIPTORS$d = descriptors; var SPECIES$4 = wellKnownSymbol$f('species'); @@ -2670,56 +3074,245 @@ } }; - var $$$ = _export; - var global$o = global$F; + var $$16 = _export; + var global$M = global$1m; var arrayBufferModule = arrayBuffer; var setSpecies$4 = setSpecies$5; var ARRAY_BUFFER = 'ArrayBuffer'; var ArrayBuffer$3 = arrayBufferModule[ARRAY_BUFFER]; - var NativeArrayBuffer = global$o[ARRAY_BUFFER]; + var NativeArrayBuffer = global$M[ARRAY_BUFFER]; // `ArrayBuffer` constructor // https://tc39.es/ecma262/#sec-arraybuffer-constructor - $$$({ global: true, forced: NativeArrayBuffer !== ArrayBuffer$3 }, { + $$16({ global: true, forced: NativeArrayBuffer !== ArrayBuffer$3 }, { ArrayBuffer: ArrayBuffer$3 }); setSpecies$4(ARRAY_BUFFER); - var fails$C = fails$N; + var fails$G = fails$S; - var arrayMethodIsStrict$8 = function (METHOD_NAME, argument) { + var arrayMethodIsStrict$9 = function (METHOD_NAME, argument) { var method = [][METHOD_NAME]; - return !!method && fails$C(function () { + return !!method && fails$G(function () { // eslint-disable-next-line no-useless-call,no-throw-literal -- required for testing method.call(null, argument || function () { throw 1; }, 1); }); }; /* eslint-disable es/no-array-prototype-indexof -- required for testing */ - var $$_ = _export; - var $indexOf$1 = arrayIncludes.indexOf; - var arrayMethodIsStrict$7 = arrayMethodIsStrict$8; + var $$15 = _export; + var uncurryThis$C = functionUncurryThis; + var $IndexOf = arrayIncludes.indexOf; + var arrayMethodIsStrict$8 = arrayMethodIsStrict$9; - var nativeIndexOf = [].indexOf; + var un$IndexOf = uncurryThis$C([].indexOf); - var NEGATIVE_ZERO$1 = !!nativeIndexOf && 1 / [1].indexOf(1, -0) < 0; - var STRICT_METHOD$7 = arrayMethodIsStrict$7('indexOf'); + var NEGATIVE_ZERO$1 = !!un$IndexOf && 1 / un$IndexOf([1], 1, -0) < 0; + var STRICT_METHOD$8 = arrayMethodIsStrict$8('indexOf'); // `Array.prototype.indexOf` method // https://tc39.es/ecma262/#sec-array.prototype.indexof - $$_({ target: 'Array', proto: true, forced: NEGATIVE_ZERO$1 || !STRICT_METHOD$7 }, { + $$15({ target: 'Array', proto: true, forced: NEGATIVE_ZERO$1 || !STRICT_METHOD$8 }, { indexOf: function indexOf(searchElement /* , fromIndex = 0 */) { + var fromIndex = arguments.length > 1 ? arguments[1] : undefined; return NEGATIVE_ZERO$1 // convert -0 to +0 - ? nativeIndexOf.apply(this, arguments) || 0 - : $indexOf$1(this, searchElement, arguments.length > 1 ? arguments[1] : undefined); + ? un$IndexOf(this, searchElement, fromIndex) || 0 + : $IndexOf(this, searchElement, fromIndex); } }); - var fails$B = fails$N; - var wellKnownSymbol$e = wellKnownSymbol$s; + var anObject$e = anObject$n; + + // `RegExp.prototype.flags` getter implementation + // https://tc39.es/ecma262/#sec-get-regexp.prototype.flags + var regexpFlags$1 = function () { + var that = anObject$e(this); + var result = ''; + if (that.global) result += 'g'; + if (that.ignoreCase) result += 'i'; + if (that.multiline) result += 'm'; + if (that.dotAll) result += 's'; + if (that.unicode) result += 'u'; + if (that.sticky) result += 'y'; + return result; + }; + + var regexpStickyHelpers = {}; + + var fails$F = fails$S; + var global$L = global$1m; + + // babel-minify and Closure Compiler transpiles RegExp('a', 'y') -> /a/y and it causes SyntaxError + var $RegExp$2 = global$L.RegExp; + + regexpStickyHelpers.UNSUPPORTED_Y = fails$F(function () { + var re = $RegExp$2('a', 'y'); + re.lastIndex = 2; + return re.exec('abcd') != null; + }); + + regexpStickyHelpers.BROKEN_CARET = fails$F(function () { + // https://bugzilla.mozilla.org/show_bug.cgi?id=773687 + var re = $RegExp$2('^r', 'gy'); + re.lastIndex = 2; + return re.exec('str') != null; + }); + + var fails$E = fails$S; + var global$K = global$1m; + + // babel-minify and Closure Compiler transpiles RegExp('.', 's') -> /./s and it causes SyntaxError + var $RegExp$1 = global$K.RegExp; + + var regexpUnsupportedDotAll = fails$E(function () { + var re = $RegExp$1('.', 's'); + return !(re.dotAll && re.exec('\n') && re.flags === 's'); + }); + + var fails$D = fails$S; + var global$J = global$1m; + + // babel-minify and Closure Compiler transpiles RegExp('(?b)', 'g') -> /(?b)/g and it causes SyntaxError + var $RegExp = global$J.RegExp; + + var regexpUnsupportedNcg = fails$D(function () { + var re = $RegExp('(?b)', 'g'); + return re.exec('b').groups.a !== 'b' || + 'b'.replace(re, '$c') !== 'bc'; + }); + + /* eslint-disable regexp/no-empty-capturing-group, regexp/no-empty-group, regexp/no-lazy-ends -- testing */ + /* eslint-disable regexp/no-useless-quantifier -- testing */ + var call$i = functionCall; + var uncurryThis$B = functionUncurryThis; + var toString$g = toString$k; + var regexpFlags = regexpFlags$1; + var stickyHelpers$2 = regexpStickyHelpers; + var shared = shared$5.exports; + var create$8 = objectCreate; + var getInternalState$2 = internalState.get; + var UNSUPPORTED_DOT_ALL$1 = regexpUnsupportedDotAll; + var UNSUPPORTED_NCG$1 = regexpUnsupportedNcg; + + var nativeReplace = shared('native-string-replace', String.prototype.replace); + var nativeExec = RegExp.prototype.exec; + var patchedExec = nativeExec; + var charAt$6 = uncurryThis$B(''.charAt); + var indexOf = uncurryThis$B(''.indexOf); + var replace$7 = uncurryThis$B(''.replace); + var stringSlice$9 = uncurryThis$B(''.slice); + + var UPDATES_LAST_INDEX_WRONG = (function () { + var re1 = /a/; + var re2 = /b*/g; + call$i(nativeExec, re1, 'a'); + call$i(nativeExec, re2, 'a'); + return re1.lastIndex !== 0 || re2.lastIndex !== 0; + })(); + + var UNSUPPORTED_Y$2 = stickyHelpers$2.UNSUPPORTED_Y || stickyHelpers$2.BROKEN_CARET; + + // nonparticipating capturing group, copied from es5-shim's String#split patch. + var NPCG_INCLUDED = /()??/.exec('')[1] !== undefined; + + var PATCH = UPDATES_LAST_INDEX_WRONG || NPCG_INCLUDED || UNSUPPORTED_Y$2 || UNSUPPORTED_DOT_ALL$1 || UNSUPPORTED_NCG$1; + + if (PATCH) { + // eslint-disable-next-line max-statements -- TODO + patchedExec = function exec(string) { + var re = this; + var state = getInternalState$2(re); + var str = toString$g(string); + var raw = state.raw; + var result, reCopy, lastIndex, match, i, object, group; + + if (raw) { + raw.lastIndex = re.lastIndex; + result = call$i(patchedExec, raw, str); + re.lastIndex = raw.lastIndex; + return result; + } + + var groups = state.groups; + var sticky = UNSUPPORTED_Y$2 && re.sticky; + var flags = call$i(regexpFlags, re); + var source = re.source; + var charsAdded = 0; + var strCopy = str; + + if (sticky) { + flags = replace$7(flags, 'y', ''); + if (indexOf(flags, 'g') === -1) { + flags += 'g'; + } + + strCopy = stringSlice$9(str, re.lastIndex); + // Support anchored sticky behavior. + if (re.lastIndex > 0 && (!re.multiline || re.multiline && charAt$6(str, re.lastIndex - 1) !== '\n')) { + source = '(?: ' + source + ')'; + strCopy = ' ' + strCopy; + charsAdded++; + } + // ^(? + rx + ) is needed, in combination with some str slicing, to + // simulate the 'y' flag. + reCopy = new RegExp('^(?:' + source + ')', flags); + } + + if (NPCG_INCLUDED) { + reCopy = new RegExp('^' + source + '$(?!\\s)', flags); + } + if (UPDATES_LAST_INDEX_WRONG) lastIndex = re.lastIndex; + + match = call$i(nativeExec, sticky ? reCopy : re, strCopy); + + if (sticky) { + if (match) { + match.input = stringSlice$9(match.input, charsAdded); + match[0] = stringSlice$9(match[0], charsAdded); + match.index = re.lastIndex; + re.lastIndex += match[0].length; + } else re.lastIndex = 0; + } else if (UPDATES_LAST_INDEX_WRONG && match) { + re.lastIndex = re.global ? match.index + match[0].length : lastIndex; + } + if (NPCG_INCLUDED && match && match.length > 1) { + // Fix browsers whose `exec` methods don't consistently return `undefined` + // for NPCG, like IE8. NOTE: This doesn' work for /(.?)?/ + call$i(nativeReplace, match[0], reCopy, function () { + for (i = 1; i < arguments.length - 2; i++) { + if (arguments[i] === undefined) match[i] = undefined; + } + }); + } + + if (match && groups) { + match.groups = object = create$8(null); + for (i = 0; i < groups.length; i++) { + group = groups[i]; + object[group[0]] = match[group[1]]; + } + } + + return match; + }; + } + + var regexpExec$3 = patchedExec; + + var $$14 = _export; + var exec$5 = regexpExec$3; + + // `RegExp.prototype.exec` method + // https://tc39.es/ecma262/#sec-regexp.prototype.exec + $$14({ target: 'RegExp', proto: true, forced: /./.exec !== exec$5 }, { + exec: exec$5 + }); + + var fails$C = fails$S; + var wellKnownSymbol$e = wellKnownSymbol$t; var V8_VERSION$2 = engineV8Version; var SPECIES$3 = wellKnownSymbol$e('species'); @@ -2728,7 +3321,7 @@ // We can't use this feature detection in V8 since it causes // deoptimization and serious performance degradation // https://github.com/zloirock/core-js/issues/677 - return V8_VERSION$2 >= 51 || !fails$B(function () { + return V8_VERSION$2 >= 51 || !fails$C(function () { var array = []; var constructor = array.constructor = {}; constructor[SPECIES$3] = function () { @@ -2738,7 +3331,7 @@ }); }; - var $$Z = _export; + var $$13 = _export; var $map$1 = arrayIteration.map; var arrayMethodHasSpeciesSupport$4 = arrayMethodHasSpeciesSupport$5; @@ -2747,136 +3340,183 @@ // `Array.prototype.map` method // https://tc39.es/ecma262/#sec-array.prototype.map // with adding support of @@species - $$Z({ target: 'Array', proto: true, forced: !HAS_SPECIES_SUPPORT$3 }, { + $$13({ target: 'Array', proto: true, forced: !HAS_SPECIES_SUPPORT$3 }, { map: function map(callbackfn /* , thisArg */) { return $map$1(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined); } }); var $forEach$1 = arrayIteration.forEach; - var arrayMethodIsStrict$6 = arrayMethodIsStrict$8; + var arrayMethodIsStrict$7 = arrayMethodIsStrict$9; - var STRICT_METHOD$6 = arrayMethodIsStrict$6('forEach'); + var STRICT_METHOD$7 = arrayMethodIsStrict$7('forEach'); // `Array.prototype.forEach` method implementation // https://tc39.es/ecma262/#sec-array.prototype.foreach - var arrayForEach = !STRICT_METHOD$6 ? function forEach(callbackfn /* , thisArg */) { + var arrayForEach = !STRICT_METHOD$7 ? function forEach(callbackfn /* , thisArg */) { return $forEach$1(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined); // eslint-disable-next-line es/no-array-prototype-foreach -- safe } : [].forEach; - var $$Y = _export; + var $$12 = _export; var forEach$3 = arrayForEach; // `Array.prototype.forEach` method // https://tc39.es/ecma262/#sec-array.prototype.foreach // eslint-disable-next-line es/no-array-prototype-foreach -- safe - $$Y({ target: 'Array', proto: true, forced: [].forEach != forEach$3 }, { + $$12({ target: 'Array', proto: true, forced: [].forEach != forEach$3 }, { forEach: forEach$3 }); - var global$n = global$F; + var global$I = global$1m; var DOMIterables = domIterables; + var DOMTokenListPrototype = domTokenListPrototype; var forEach$2 = arrayForEach; - var createNonEnumerableProperty$3 = createNonEnumerableProperty$e; + var createNonEnumerableProperty$3 = createNonEnumerableProperty$b; - for (var COLLECTION_NAME in DOMIterables) { - var Collection = global$n[COLLECTION_NAME]; - var CollectionPrototype = Collection && Collection.prototype; + var handlePrototype = function (CollectionPrototype) { // some Chrome versions have non-configurable methods on DOMTokenList if (CollectionPrototype && CollectionPrototype.forEach !== forEach$2) try { createNonEnumerableProperty$3(CollectionPrototype, 'forEach', forEach$2); } catch (error) { CollectionPrototype.forEach = forEach$2; } + }; + + for (var COLLECTION_NAME in DOMIterables) { + if (DOMIterables[COLLECTION_NAME]) { + handlePrototype(global$I[COLLECTION_NAME] && global$I[COLLECTION_NAME].prototype); + } } - var $$X = _export; - var isArray$3 = isArray$6; + handlePrototype(DOMTokenListPrototype); + + var $$11 = _export; + var isArray$5 = isArray$8; // `Array.isArray` method // https://tc39.es/ecma262/#sec-array.isarray - $$X({ target: 'Array', stat: true }, { - isArray: isArray$3 + $$11({ target: 'Array', stat: true }, { + isArray: isArray$5 }); - var $$W = _export; - var fails$A = fails$N; + var $$10 = _export; + var fails$B = fails$S; var getOwnPropertyNames$3 = objectGetOwnPropertyNamesExternal.f; // eslint-disable-next-line es/no-object-getownpropertynames -- required for testing - var FAILS_ON_PRIMITIVES$4 = fails$A(function () { return !Object.getOwnPropertyNames(1); }); + var FAILS_ON_PRIMITIVES$5 = fails$B(function () { return !Object.getOwnPropertyNames(1); }); // `Object.getOwnPropertyNames` method // https://tc39.es/ecma262/#sec-object.getownpropertynames - $$W({ target: 'Object', stat: true, forced: FAILS_ON_PRIMITIVES$4 }, { + $$10({ target: 'Object', stat: true, forced: FAILS_ON_PRIMITIVES$5 }, { getOwnPropertyNames: getOwnPropertyNames$3 }); - var global$m = global$F; + var global$H = global$1m; - var nativePromiseConstructor = global$m.Promise; + var nativePromiseConstructor = global$H.Promise; - var wellKnownSymbol$d = wellKnownSymbol$s; + var wellKnownSymbol$d = wellKnownSymbol$t; var Iterators$1 = iterators; - var ITERATOR$5 = wellKnownSymbol$d('iterator'); + var ITERATOR$7 = wellKnownSymbol$d('iterator'); var ArrayPrototype = Array.prototype; // check on default Array iterator var isArrayIteratorMethod$3 = function (it) { - return it !== undefined && (Iterators$1.Array === it || ArrayPrototype[ITERATOR$5] === it); + return it !== undefined && (Iterators$1.Array === it || ArrayPrototype[ITERATOR$7] === it); }; - var classof$7 = classof$b; + var classof$6 = classof$d; + var getMethod$5 = getMethod$7; var Iterators = iterators; - var wellKnownSymbol$c = wellKnownSymbol$s; + var wellKnownSymbol$c = wellKnownSymbol$t; - var ITERATOR$4 = wellKnownSymbol$c('iterator'); + var ITERATOR$6 = wellKnownSymbol$c('iterator'); var getIteratorMethod$5 = function (it) { - if (it != undefined) return it[ITERATOR$4] - || it['@@iterator'] - || Iterators[classof$7(it)]; + if (it != undefined) return getMethod$5(it, ITERATOR$6) + || getMethod$5(it, '@@iterator') + || Iterators[classof$6(it)]; }; - var anObject$d = anObject$m; + var global$G = global$1m; + var call$h = functionCall; + var aCallable$7 = aCallable$a; + var anObject$d = anObject$n; + var tryToString$1 = tryToString$5; + var getIteratorMethod$4 = getIteratorMethod$5; + + var TypeError$c = global$G.TypeError; + + var getIterator$4 = function (argument, usingIterator) { + var iteratorMethod = arguments.length < 2 ? getIteratorMethod$4(argument) : usingIterator; + if (aCallable$7(iteratorMethod)) return anObject$d(call$h(iteratorMethod, argument)); + throw TypeError$c(tryToString$1(argument) + ' is not iterable'); + }; + + var call$g = functionCall; + var anObject$c = anObject$n; + var getMethod$4 = getMethod$7; - var iteratorClose$2 = function (iterator) { - var returnMethod = iterator['return']; - if (returnMethod !== undefined) { - return anObject$d(returnMethod.call(iterator)).value; + var iteratorClose$2 = function (iterator, kind, value) { + var innerResult, innerError; + anObject$c(iterator); + try { + innerResult = getMethod$4(iterator, 'return'); + if (!innerResult) { + if (kind === 'throw') throw value; + return value; + } + innerResult = call$g(innerResult, iterator); + } catch (error) { + innerError = true; + innerResult = error; } + if (kind === 'throw') throw value; + if (innerError) throw innerResult; + anObject$c(innerResult); + return value; }; - var anObject$c = anObject$m; + var global$F = global$1m; + var bind$d = functionBindContext; + var call$f = functionCall; + var anObject$b = anObject$n; + var tryToString = tryToString$5; var isArrayIteratorMethod$2 = isArrayIteratorMethod$3; - var toLength$j = toLength$q; - var bind$a = functionBindContext; - var getIteratorMethod$4 = getIteratorMethod$5; + var lengthOfArrayLike$c = lengthOfArrayLike$g; + var isPrototypeOf$4 = objectIsPrototypeOf; + var getIterator$3 = getIterator$4; + var getIteratorMethod$3 = getIteratorMethod$5; var iteratorClose$1 = iteratorClose$2; + var TypeError$b = global$F.TypeError; + var Result = function (stopped, result) { this.stopped = stopped; this.result = result; }; + var ResultPrototype = Result.prototype; + var iterate$3 = function (iterable, unboundFunction, options) { var that = options && options.that; var AS_ENTRIES = !!(options && options.AS_ENTRIES); var IS_ITERATOR = !!(options && options.IS_ITERATOR); var INTERRUPTED = !!(options && options.INTERRUPTED); - var fn = bind$a(unboundFunction, that, 1 + AS_ENTRIES + INTERRUPTED); + var fn = bind$d(unboundFunction, that); var iterator, iterFn, index, length, result, next, step; var stop = function (condition) { - if (iterator) iteratorClose$1(iterator); + if (iterator) iteratorClose$1(iterator, 'normal', condition); return new Result(true, condition); }; var callFn = function (value) { if (AS_ENTRIES) { - anObject$c(value); + anObject$b(value); return INTERRUPTED ? fn(value[0], value[1], stop) : fn(value[0], value[1]); } return INTERRUPTED ? fn(value, stop) : fn(value); }; @@ -2884,33 +3524,32 @@ if (IS_ITERATOR) { iterator = iterable; } else { - iterFn = getIteratorMethod$4(iterable); - if (typeof iterFn != 'function') throw TypeError('Target is not iterable'); + iterFn = getIteratorMethod$3(iterable); + if (!iterFn) throw TypeError$b(tryToString(iterable) + ' is not iterable'); // optimisation for array iterators if (isArrayIteratorMethod$2(iterFn)) { - for (index = 0, length = toLength$j(iterable.length); length > index; index++) { + for (index = 0, length = lengthOfArrayLike$c(iterable); length > index; index++) { result = callFn(iterable[index]); - if (result && result instanceof Result) return result; + if (result && isPrototypeOf$4(ResultPrototype, result)) return result; } return new Result(false); } - iterator = iterFn.call(iterable); + iterator = getIterator$3(iterable, iterFn); } next = iterator.next; - while (!(step = next.call(iterator)).done) { + while (!(step = call$f(next, iterator)).done) { try { result = callFn(step.value); } catch (error) { - iteratorClose$1(iterator); - throw error; + iteratorClose$1(iterator, 'throw', error); } - if (typeof result == 'object' && result && result instanceof Result) return result; + if (typeof result == 'object' && result && isPrototypeOf$4(ResultPrototype, result)) return result; } return new Result(false); }; - var wellKnownSymbol$b = wellKnownSymbol$s; + var wellKnownSymbol$b = wellKnownSymbol$t; - var ITERATOR$3 = wellKnownSymbol$b('iterator'); + var ITERATOR$5 = wellKnownSymbol$b('iterator'); var SAFE_CLOSING = false; try { @@ -2923,7 +3562,7 @@ SAFE_CLOSING = true; } }; - iteratorWithReturn[ITERATOR$3] = function () { + iteratorWithReturn[ITERATOR$5] = function () { return this; }; // eslint-disable-next-line es/no-array-from, no-throw-literal -- required for testing @@ -2935,7 +3574,7 @@ var ITERATION_SUPPORT = false; try { var object = {}; - object[ITERATOR$3] = function () { + object[ITERATOR$5] = function () { return { next: function () { return { done: ITERATION_SUPPORT = true }; @@ -2947,37 +3586,46 @@ return ITERATION_SUPPORT; }; - var userAgent$4 = engineUserAgent; + var userAgent$6 = engineUserAgent; - var engineIsIos = /(?:iphone|ipod|ipad).*applewebkit/i.test(userAgent$4); + var engineIsIos = /(?:ipad|iphone|ipod).*applewebkit/i.test(userAgent$6); - var classof$6 = classofRaw$1; - var global$l = global$F; + var classof$5 = classofRaw$1; + var global$E = global$1m; - var engineIsNode = classof$6(global$l.process) == 'process'; + var engineIsNode = classof$5(global$E.process) == 'process'; - var global$k = global$F; - var fails$z = fails$N; - var bind$9 = functionBindContext; + var global$D = global$1m; + var apply$7 = functionApply; + var bind$c = functionBindContext; + var isCallable$8 = isCallable$r; + var hasOwn$8 = hasOwnProperty_1; + var fails$A = fails$S; var html = html$2; - var createElement = documentCreateElement$1; + var arraySlice$8 = arraySlice$c; + var createElement = documentCreateElement$2; var IS_IOS$1 = engineIsIos; - var IS_NODE$3 = engineIsNode; - - var location$1 = global$k.location; - var set$2 = global$k.setImmediate; - var clear = global$k.clearImmediate; - var process$3 = global$k.process; - var MessageChannel = global$k.MessageChannel; - var Dispatch$1 = global$k.Dispatch; + var IS_NODE$4 = engineIsNode; + + var set$2 = global$D.setImmediate; + var clear = global$D.clearImmediate; + var process$3 = global$D.process; + var Dispatch$1 = global$D.Dispatch; + var Function$3 = global$D.Function; + var MessageChannel = global$D.MessageChannel; + var String$2 = global$D.String; var counter = 0; var queue = {}; var ONREADYSTATECHANGE = 'onreadystatechange'; - var defer, channel, port; + var location$1, defer, channel, port; + + try { + // Deno throws a ReferenceError on `location` access without `--location` flag + location$1 = global$D.location; + } catch (error) { /* empty */ } var run = function (id) { - // eslint-disable-next-line no-prototype-builtins -- safe - if (queue.hasOwnProperty(id)) { + if (hasOwn$8(queue, id)) { var fn = queue[id]; delete queue[id]; fn(); @@ -2996,18 +3644,15 @@ var post = function (id) { // old engines have not location.origin - global$k.postMessage(id + '', location$1.protocol + '//' + location$1.host); + global$D.postMessage(String$2(id), location$1.protocol + '//' + location$1.host); }; // Node.js 0.9+ & IE10+ has setImmediate, otherwise: if (!set$2 || !clear) { set$2 = function setImmediate(fn) { - var args = []; - var i = 1; - while (arguments.length > i) args.push(arguments[i++]); + var args = arraySlice$8(arguments, 1); queue[++counter] = function () { - // eslint-disable-next-line no-new-func -- spec requirement - (typeof fn == 'function' ? fn : Function(fn)).apply(undefined, args); + apply$7(isCallable$8(fn) ? fn : Function$3(fn), undefined, args); }; defer(counter); return counter; @@ -3016,7 +3661,7 @@ delete queue[id]; }; // Node.js 0.8- - if (IS_NODE$3) { + if (IS_NODE$4) { defer = function (id) { process$3.nextTick(runner(id)); }; @@ -3031,18 +3676,18 @@ channel = new MessageChannel(); port = channel.port2; channel.port1.onmessage = listener; - defer = bind$9(port.postMessage, port, 1); + defer = bind$c(port.postMessage, port); // Browsers with postMessage, skip WebWorkers // IE8 has postMessage, but it's sync & typeof its postMessage is 'object' } else if ( - global$k.addEventListener && - typeof postMessage == 'function' && - !global$k.importScripts && + global$D.addEventListener && + isCallable$8(global$D.postMessage) && + !global$D.importScripts && location$1 && location$1.protocol !== 'file:' && - !fails$z(post) + !fails$A(post) ) { defer = post; - global$k.addEventListener('message', listener, false); + global$D.addEventListener('message', listener, false); // IE8- } else if (ONREADYSTATECHANGE in createElement('script')) { defer = function (id) { @@ -3064,23 +3709,30 @@ clear: clear }; - var userAgent$3 = engineUserAgent; + var userAgent$5 = engineUserAgent; + var global$C = global$1m; + + var engineIsIosPebble = /ipad|iphone|ipod/i.test(userAgent$5) && global$C.Pebble !== undefined; - var engineIsWebosWebkit = /web0s(?!.*chrome)/i.test(userAgent$3); + var userAgent$4 = engineUserAgent; + + var engineIsWebosWebkit = /web0s(?!.*chrome)/i.test(userAgent$4); - var global$j = global$F; + var global$B = global$1m; + var bind$b = functionBindContext; var getOwnPropertyDescriptor$3 = objectGetOwnPropertyDescriptor.f; var macrotask = task$1.set; var IS_IOS = engineIsIos; + var IS_IOS_PEBBLE = engineIsIosPebble; var IS_WEBOS_WEBKIT = engineIsWebosWebkit; - var IS_NODE$2 = engineIsNode; + var IS_NODE$3 = engineIsNode; - var MutationObserver = global$j.MutationObserver || global$j.WebKitMutationObserver; - var document$2 = global$j.document; - var process$2 = global$j.process; - var Promise$1 = global$j.Promise; + var MutationObserver = global$B.MutationObserver || global$B.WebKitMutationObserver; + var document$2 = global$B.document; + var process$2 = global$B.process; + var Promise$1 = global$B.Promise; // Node.js 11 shows ExperimentalWarning on getting `queueMicrotask` - var queueMicrotaskDescriptor = getOwnPropertyDescriptor$3(global$j, 'queueMicrotask'); + var queueMicrotaskDescriptor = getOwnPropertyDescriptor$3(global$B, 'queueMicrotask'); var queueMicrotask = queueMicrotaskDescriptor && queueMicrotaskDescriptor.value; var flush, head, last, notify$1, toggle, node, promise, then; @@ -3089,7 +3741,7 @@ if (!queueMicrotask) { flush = function () { var parent, fn; - if (IS_NODE$2 && (parent = process$2.domain)) parent.exit(); + if (IS_NODE$3 && (parent = process$2.domain)) parent.exit(); while (head) { fn = head.fn; head = head.next; @@ -3106,7 +3758,7 @@ // browsers with MutationObserver, except iOS - https://github.com/zloirock/core-js/issues/339 // also except WebOS Webkit https://github.com/zloirock/core-js/issues/898 - if (!IS_IOS && !IS_NODE$2 && !IS_WEBOS_WEBKIT && MutationObserver && document$2) { + if (!IS_IOS && !IS_NODE$3 && !IS_WEBOS_WEBKIT && MutationObserver && document$2) { toggle = true; node = document$2.createTextNode(''); new MutationObserver(flush).observe(node, { characterData: true }); @@ -3114,17 +3766,17 @@ node.data = toggle = !toggle; }; // environments with maybe non-completely correct, but existent Promise - } else if (Promise$1 && Promise$1.resolve) { + } else if (!IS_IOS_PEBBLE && Promise$1 && Promise$1.resolve) { // Promise.resolve without an argument throws an error in LG WebOS 2 promise = Promise$1.resolve(undefined); // workaround of WebKit ~ iOS Safari 10.1 bug promise.constructor = Promise$1; - then = promise.then; + then = bind$b(promise.then, promise); notify$1 = function () { - then.call(promise, flush); + then(flush); }; // Node.js without promises - } else if (IS_NODE$2) { + } else if (IS_NODE$3) { notify$1 = function () { process$2.nextTick(flush); }; @@ -3135,9 +3787,10 @@ // - onreadystatechange // - setTimeout } else { + // strange IE + webpack dev server bug - use .bind(global) + macrotask = bind$b(macrotask, global$B); notify$1 = function () { - // strange IE + webpack dev server bug - use .call(global) - macrotask.call(global$j, flush); + macrotask(flush); }; } } @@ -3153,7 +3806,7 @@ var newPromiseCapability$2 = {}; - var aFunction$6 = aFunction$9; + var aCallable$6 = aCallable$a; var PromiseCapability = function (C) { var resolve, reject; @@ -3162,8 +3815,8 @@ resolve = $$resolve; reject = $$reject; }); - this.resolve = aFunction$6(resolve); - this.reject = aFunction$6(reject); + this.resolve = aCallable$6(resolve); + this.reject = aCallable$6(reject); }; // `NewPromiseCapability` abstract operation @@ -3172,25 +3825,25 @@ return new PromiseCapability(C); }; - var anObject$b = anObject$m; - var isObject$h = isObject$r; + var anObject$a = anObject$n; + var isObject$j = isObject$s; var newPromiseCapability$1 = newPromiseCapability$2; var promiseResolve$2 = function (C, x) { - anObject$b(C); - if (isObject$h(x) && x.constructor === C) return x; + anObject$a(C); + if (isObject$j(x) && x.constructor === C) return x; var promiseCapability = newPromiseCapability$1.f(C); var resolve = promiseCapability.resolve; resolve(x); return promiseCapability.promise; }; - var global$i = global$F; + var global$A = global$1m; var hostReportErrors$1 = function (a, b) { - var console = global$i.console; + var console = global$A.console; if (console && console.error) { - arguments.length === 1 ? console.error(a) : console.error(a, b); + arguments.length == 1 ? console.error(a) : console.error(a, b); } }; @@ -3204,22 +3857,24 @@ var engineIsBrowser = typeof window == 'object'; - var $$V = _export; - var global$h = global$F; - var getBuiltIn$3 = getBuiltIn$9; + var $$$ = _export; + var global$z = global$1m; + var getBuiltIn$3 = getBuiltIn$b; + var call$e = functionCall; var NativePromise$1 = nativePromiseConstructor; - var redefine$8 = redefine$g.exports; + var redefine$8 = redefine$h.exports; var redefineAll$2 = redefineAll$4; var setPrototypeOf$3 = objectSetPrototypeOf; var setToStringTag$5 = setToStringTag$a; var setSpecies$3 = setSpecies$5; - var isObject$g = isObject$r; - var aFunction$5 = aFunction$9; + var aCallable$5 = aCallable$a; + var isCallable$7 = isCallable$r; + var isObject$i = isObject$s; var anInstance$5 = anInstance$7; - var inspectSource = inspectSource$3; + var inspectSource = inspectSource$4; var iterate$2 = iterate$3; var checkCorrectnessOfIteration$3 = checkCorrectnessOfIteration$4; - var speciesConstructor$6 = speciesConstructor$8; + var speciesConstructor$3 = speciesConstructor$5; var task = task$1.set; var microtask = microtask$1; var promiseResolve$1 = promiseResolve$2; @@ -3228,26 +3883,28 @@ var perform = perform$1; var InternalStateModule$4 = internalState; var isForced$3 = isForced_1; - var wellKnownSymbol$a = wellKnownSymbol$s; + var wellKnownSymbol$a = wellKnownSymbol$t; var IS_BROWSER = engineIsBrowser; - var IS_NODE$1 = engineIsNode; + var IS_NODE$2 = engineIsNode; var V8_VERSION$1 = engineV8Version; var SPECIES$2 = wellKnownSymbol$a('species'); var PROMISE = 'Promise'; - var getInternalState$2 = InternalStateModule$4.get; + + var getInternalState$1 = InternalStateModule$4.get; var setInternalState$4 = InternalStateModule$4.set; var getInternalPromiseState = InternalStateModule$4.getterFor(PROMISE); var NativePromisePrototype = NativePromise$1 && NativePromise$1.prototype; var PromiseConstructor = NativePromise$1; - var PromiseConstructorPrototype = NativePromisePrototype; - var TypeError$1 = global$h.TypeError; - var document$1 = global$h.document; - var process$1 = global$h.process; + var PromisePrototype = NativePromisePrototype; + var TypeError$a = global$z.TypeError; + var document$1 = global$z.document; + var process$1 = global$z.process; var newPromiseCapability = newPromiseCapabilityModule.f; var newGenericPromiseCapability = newPromiseCapability; - var DISPATCH_EVENT = !!(document$1 && document$1.createEvent && global$h.dispatchEvent); - var NATIVE_REJECTION_EVENT = typeof PromiseRejectionEvent == 'function'; + + var DISPATCH_EVENT = !!(document$1 && document$1.createEvent && global$z.dispatchEvent); + var NATIVE_REJECTION_EVENT = isCallable$7(global$z.PromiseRejectionEvent); var UNHANDLED_REJECTION = 'unhandledrejection'; var REJECTION_HANDLED = 'rejectionhandled'; var PENDING = 0; @@ -3256,10 +3913,12 @@ var HANDLED = 1; var UNHANDLED = 2; var SUBCLASSING = false; + var Internal, OwnPromiseCapability, PromiseWrapper, nativeThen; - var FORCED$f = isForced$3(PROMISE, function () { - var GLOBAL_CORE_JS_PROMISE = inspectSource(PromiseConstructor) !== String(PromiseConstructor); + var FORCED$h = isForced$3(PROMISE, function () { + var PROMISE_CONSTRUCTOR_SOURCE = inspectSource(PromiseConstructor); + var GLOBAL_CORE_JS_PROMISE = PROMISE_CONSTRUCTOR_SOURCE !== String(PromiseConstructor); // V8 6.6 (Node 10 and Chrome 66) have a bug with resolving custom thenables // https://bugs.chromium.org/p/chromium/issues/detail?id=830565 // We can't detect it synchronously, so just check versions @@ -3267,7 +3926,7 @@ // We can't use @@species feature detection in V8 since it causes // deoptimization and performance degradation // https://github.com/zloirock/core-js/issues/679 - if (V8_VERSION$1 >= 51 && /native code/.test(PromiseConstructor)) return false; + if (V8_VERSION$1 >= 51 && /native code/.test(PROMISE_CONSTRUCTOR_SOURCE)) return false; // Detect correctness of subclassing with @@species support var promise = new PromiseConstructor(function (resolve) { resolve(1); }); var FakePromise = function (exec) { @@ -3281,14 +3940,14 @@ return !GLOBAL_CORE_JS_PROMISE && IS_BROWSER && !NATIVE_REJECTION_EVENT; }); - var INCORRECT_ITERATION$1 = FORCED$f || !checkCorrectnessOfIteration$3(function (iterable) { + var INCORRECT_ITERATION$1 = FORCED$h || !checkCorrectnessOfIteration$3(function (iterable) { PromiseConstructor.all(iterable)['catch'](function () { /* empty */ }); }); // helpers var isThenable = function (it) { var then; - return isObject$g(it) && typeof (then = it.then) == 'function' ? then : false; + return isObject$i(it) && isCallable$7(then = it.then) ? then : false; }; var notify = function (state, isReject) { @@ -3323,9 +3982,9 @@ } } if (result === reaction.promise) { - reject(TypeError$1('Promise-chain cycle')); + reject(TypeError$a('Promise-chain cycle')); } else if (then = isThenable(result)) { - then.call(result, resolve, reject); + call$e(then, result, resolve, reject); } else resolve(result); } else reject(value); } catch (error) { @@ -3346,26 +4005,26 @@ event.promise = promise; event.reason = reason; event.initEvent(name, false, true); - global$h.dispatchEvent(event); + global$z.dispatchEvent(event); } else event = { promise: promise, reason: reason }; - if (!NATIVE_REJECTION_EVENT && (handler = global$h['on' + name])) handler(event); + if (!NATIVE_REJECTION_EVENT && (handler = global$z['on' + name])) handler(event); else if (name === UNHANDLED_REJECTION) hostReportErrors('Unhandled promise rejection', reason); }; var onUnhandled = function (state) { - task.call(global$h, function () { + call$e(task, global$z, function () { var promise = state.facade; var value = state.value; var IS_UNHANDLED = isUnhandled(state); var result; if (IS_UNHANDLED) { result = perform(function () { - if (IS_NODE$1) { + if (IS_NODE$2) { process$1.emit('unhandledRejection', value, promise); } else dispatchEvent$1(UNHANDLED_REJECTION, promise, value); }); // Browsers should not trigger `rejectionHandled` event if it was handled here, NodeJS - should - state.rejection = IS_NODE$1 || isUnhandled(state) ? UNHANDLED : HANDLED; + state.rejection = IS_NODE$2 || isUnhandled(state) ? UNHANDLED : HANDLED; if (result.error) throw result.value; } }); @@ -3376,15 +4035,15 @@ }; var onHandleUnhandled = function (state) { - task.call(global$h, function () { + call$e(task, global$z, function () { var promise = state.facade; - if (IS_NODE$1) { + if (IS_NODE$2) { process$1.emit('rejectionHandled', promise); } else dispatchEvent$1(REJECTION_HANDLED, promise, state.value); }); }; - var bind$8 = function (fn, state, unwrap) { + var bind$a = function (fn, state, unwrap) { return function (value) { fn(state, value, unwrap); }; @@ -3404,15 +4063,15 @@ state.done = true; if (unwrap) state = unwrap; try { - if (state.facade === value) throw TypeError$1("Promise can't be resolved itself"); + if (state.facade === value) throw TypeError$a("Promise can't be resolved itself"); var then = isThenable(value); if (then) { microtask(function () { var wrapper = { done: false }; try { - then.call(value, - bind$8(internalResolve, wrapper, state), - bind$8(internalReject, wrapper, state) + call$e(then, value, + bind$a(internalResolve, wrapper, state), + bind$a(internalReject, wrapper, state) ); } catch (error) { internalReject(wrapper, error, state); @@ -3429,20 +4088,20 @@ }; // constructor polyfill - if (FORCED$f) { + if (FORCED$h) { // 25.4.3.1 Promise(executor) PromiseConstructor = function Promise(executor) { - anInstance$5(this, PromiseConstructor, PROMISE); - aFunction$5(executor); - Internal.call(this); - var state = getInternalState$2(this); + anInstance$5(this, PromisePrototype); + aCallable$5(executor); + call$e(Internal, this); + var state = getInternalState$1(this); try { - executor(bind$8(internalResolve, state), bind$8(internalReject, state)); + executor(bind$a(internalResolve, state), bind$a(internalReject, state)); } catch (error) { internalReject(state, error); } }; - PromiseConstructorPrototype = PromiseConstructor.prototype; + PromisePrototype = PromiseConstructor.prototype; // eslint-disable-next-line no-unused-vars -- required for `.length` Internal = function Promise(executor) { setInternalState$4(this, { @@ -3456,17 +4115,18 @@ value: undefined }); }; - Internal.prototype = redefineAll$2(PromiseConstructorPrototype, { + Internal.prototype = redefineAll$2(PromisePrototype, { // `Promise.prototype.then` method // https://tc39.es/ecma262/#sec-promise.prototype.then then: function then(onFulfilled, onRejected) { var state = getInternalPromiseState(this); - var reaction = newPromiseCapability(speciesConstructor$6(this, PromiseConstructor)); - reaction.ok = typeof onFulfilled == 'function' ? onFulfilled : true; - reaction.fail = typeof onRejected == 'function' && onRejected; - reaction.domain = IS_NODE$1 ? process$1.domain : undefined; + var reactions = state.reactions; + var reaction = newPromiseCapability(speciesConstructor$3(this, PromiseConstructor)); + reaction.ok = isCallable$7(onFulfilled) ? onFulfilled : true; + reaction.fail = isCallable$7(onRejected) && onRejected; + reaction.domain = IS_NODE$2 ? process$1.domain : undefined; state.parent = true; - state.reactions.push(reaction); + reactions[reactions.length] = reaction; if (state.state != PENDING) notify(state, false); return reaction.promise; }, @@ -3478,10 +4138,10 @@ }); OwnPromiseCapability = function () { var promise = new Internal(); - var state = getInternalState$2(promise); + var state = getInternalState$1(promise); this.promise = promise; - this.resolve = bind$8(internalResolve, state); - this.reject = bind$8(internalReject, state); + this.resolve = bind$a(internalResolve, state); + this.reject = bind$a(internalReject, state); }; newPromiseCapabilityModule.f = newPromiseCapability = function (C) { return C === PromiseConstructor || C === PromiseWrapper @@ -3489,7 +4149,7 @@ : newGenericPromiseCapability(C); }; - if (typeof NativePromise$1 == 'function' && NativePromisePrototype !== Object.prototype) { + if (isCallable$7(NativePromise$1) && NativePromisePrototype !== Object.prototype) { nativeThen = NativePromisePrototype.then; if (!SUBCLASSING) { @@ -3497,13 +4157,13 @@ redefine$8(NativePromisePrototype, 'then', function then(onFulfilled, onRejected) { var that = this; return new PromiseConstructor(function (resolve, reject) { - nativeThen.call(that, resolve, reject); + call$e(nativeThen, that, resolve, reject); }).then(onFulfilled, onRejected); // https://github.com/zloirock/core-js/issues/640 }, { unsafe: true }); // makes sure that native promise-based APIs `Promise#catch` properly works with patched `Promise#then` - redefine$8(NativePromisePrototype, 'catch', PromiseConstructorPrototype['catch'], { unsafe: true }); + redefine$8(NativePromisePrototype, 'catch', PromisePrototype['catch'], { unsafe: true }); } // make `.constructor === Promise` work for native promise-based APIs @@ -3513,12 +4173,12 @@ // make `instanceof Promise` work for native promise-based APIs if (setPrototypeOf$3) { - setPrototypeOf$3(NativePromisePrototype, PromiseConstructorPrototype); + setPrototypeOf$3(NativePromisePrototype, PromisePrototype); } } } - $$V({ global: true, wrap: true, forced: FORCED$f }, { + $$$({ global: true, wrap: true, forced: FORCED$h }, { Promise: PromiseConstructor }); @@ -3528,17 +4188,17 @@ PromiseWrapper = getBuiltIn$3(PROMISE); // statics - $$V({ target: PROMISE, stat: true, forced: FORCED$f }, { + $$$({ target: PROMISE, stat: true, forced: FORCED$h }, { // `Promise.reject` method // https://tc39.es/ecma262/#sec-promise.reject reject: function reject(r) { var capability = newPromiseCapability(this); - capability.reject.call(undefined, r); + call$e(capability.reject, undefined, r); return capability.promise; } }); - $$V({ target: PROMISE, stat: true, forced: FORCED$f }, { + $$$({ target: PROMISE, stat: true, forced: FORCED$h }, { // `Promise.resolve` method // https://tc39.es/ecma262/#sec-promise.resolve resolve: function resolve(x) { @@ -3546,7 +4206,7 @@ } }); - $$V({ target: PROMISE, stat: true, forced: INCORRECT_ITERATION$1 }, { + $$$({ target: PROMISE, stat: true, forced: INCORRECT_ITERATION$1 }, { // `Promise.all` method // https://tc39.es/ecma262/#sec-promise.all all: function all(iterable) { @@ -3555,16 +4215,15 @@ var resolve = capability.resolve; var reject = capability.reject; var result = perform(function () { - var $promiseResolve = aFunction$5(C.resolve); + var $promiseResolve = aCallable$5(C.resolve); var values = []; var counter = 0; var remaining = 1; iterate$2(iterable, function (promise) { var index = counter++; var alreadyCalled = false; - values.push(undefined); remaining++; - $promiseResolve.call(C, promise).then(function (value) { + call$e($promiseResolve, C, promise).then(function (value) { if (alreadyCalled) return; alreadyCalled = true; values[index] = value; @@ -3583,9 +4242,9 @@ var capability = newPromiseCapability(C); var reject = capability.reject; var result = perform(function () { - var $promiseResolve = aFunction$5(C.resolve); + var $promiseResolve = aCallable$5(C.resolve); iterate$2(iterable, function (promise) { - $promiseResolve.call(C, promise).then(capability.resolve, reject); + call$e($promiseResolve, C, promise).then(capability.resolve, reject); }); }); if (result.error) reject(result.value); @@ -3597,78 +4256,100 @@ /* eslint-disable no-new -- required for testing */ - var global$g = global$F; - var fails$y = fails$N; + var global$y = global$1m; + var fails$z = fails$S; var checkCorrectnessOfIteration$2 = checkCorrectnessOfIteration$4; var NATIVE_ARRAY_BUFFER_VIEWS$1 = arrayBufferViewCore.NATIVE_ARRAY_BUFFER_VIEWS; - var ArrayBuffer$2 = global$g.ArrayBuffer; - var Int8Array$2 = global$g.Int8Array; + var ArrayBuffer$2 = global$y.ArrayBuffer; + var Int8Array$2 = global$y.Int8Array; - var typedArrayConstructorsRequireWrappers = !NATIVE_ARRAY_BUFFER_VIEWS$1 || !fails$y(function () { + var typedArrayConstructorsRequireWrappers = !NATIVE_ARRAY_BUFFER_VIEWS$1 || !fails$z(function () { Int8Array$2(1); - }) || !fails$y(function () { + }) || !fails$z(function () { new Int8Array$2(-1); }) || !checkCorrectnessOfIteration$2(function (iterable) { new Int8Array$2(); new Int8Array$2(null); new Int8Array$2(1.5); new Int8Array$2(iterable); - }, true) || fails$y(function () { + }, true) || fails$z(function () { // Safari (11+) bug - a reason why even Safari 13 should load a typed array polyfill return new Int8Array$2(new ArrayBuffer$2(2), 1, undefined).length !== 1; }); - var toInteger$5 = toInteger$b; + var isObject$h = isObject$s; + + var floor$6 = Math.floor; + + // `IsIntegralNumber` abstract operation + // https://tc39.es/ecma262/#sec-isintegralnumber + // eslint-disable-next-line es/no-number-isinteger -- safe + var isIntegralNumber$1 = Number.isInteger || function isInteger(it) { + return !isObject$h(it) && isFinite(it) && floor$6(it) === it; + }; + + var global$x = global$1m; + var toIntegerOrInfinity$5 = toIntegerOrInfinity$b; + + var RangeError$9 = global$x.RangeError; var toPositiveInteger$1 = function (it) { - var result = toInteger$5(it); - if (result < 0) throw RangeError("The argument can't be less than 0"); + var result = toIntegerOrInfinity$5(it); + if (result < 0) throw RangeError$9("The argument can't be less than 0"); return result; }; + var global$w = global$1m; var toPositiveInteger = toPositiveInteger$1; + var RangeError$8 = global$w.RangeError; + var toOffset$2 = function (it, BYTES) { var offset = toPositiveInteger(it); - if (offset % BYTES) throw RangeError('Wrong offset'); + if (offset % BYTES) throw RangeError$8('Wrong offset'); return offset; }; - var toObject$c = toObject$i; - var toLength$i = toLength$q; - var getIteratorMethod$3 = getIteratorMethod$5; + var bind$9 = functionBindContext; + var call$d = functionCall; + var aConstructor$1 = aConstructor$3; + var toObject$d = toObject$j; + var lengthOfArrayLike$b = lengthOfArrayLike$g; + var getIterator$2 = getIterator$4; + var getIteratorMethod$2 = getIteratorMethod$5; var isArrayIteratorMethod$1 = isArrayIteratorMethod$3; - var bind$7 = functionBindContext; - var aTypedArrayConstructor$4 = arrayBufferViewCore.aTypedArrayConstructor; + var aTypedArrayConstructor$2 = arrayBufferViewCore.aTypedArrayConstructor; var typedArrayFrom$2 = function from(source /* , mapfn, thisArg */) { - var O = toObject$c(source); + var C = aConstructor$1(this); + var O = toObject$d(source); var argumentsLength = arguments.length; var mapfn = argumentsLength > 1 ? arguments[1] : undefined; var mapping = mapfn !== undefined; - var iteratorMethod = getIteratorMethod$3(O); + var iteratorMethod = getIteratorMethod$2(O); var i, length, result, step, iterator, next; - if (iteratorMethod != undefined && !isArrayIteratorMethod$1(iteratorMethod)) { - iterator = iteratorMethod.call(O); + if (iteratorMethod && !isArrayIteratorMethod$1(iteratorMethod)) { + iterator = getIterator$2(O, iteratorMethod); next = iterator.next; O = []; - while (!(step = next.call(iterator)).done) { + while (!(step = call$d(next, iterator)).done) { O.push(step.value); } } if (mapping && argumentsLength > 2) { - mapfn = bind$7(mapfn, arguments[2], 2); + mapfn = bind$9(mapfn, arguments[2]); } - length = toLength$i(O.length); - result = new (aTypedArrayConstructor$4(this))(length); + length = lengthOfArrayLike$b(O); + result = new (aTypedArrayConstructor$2(C))(length); for (i = 0; length > i; i++) { result[i] = mapping ? mapfn(O[i], i) : O[i]; } return result; }; - var isObject$f = isObject$r; + var isCallable$6 = isCallable$r; + var isObject$g = isObject$s; var setPrototypeOf$2 = objectSetPrototypeOf; // makes subclassing work correct for wrapped built-ins @@ -3678,31 +4359,35 @@ // it can work only with native `setPrototypeOf` setPrototypeOf$2 && // we haven't completely correct pre-ES6 way for getting `new.target`, so use this - typeof (NewTarget = dummy.constructor) == 'function' && + isCallable$6(NewTarget = dummy.constructor) && NewTarget !== Wrapper && - isObject$f(NewTargetPrototype = NewTarget.prototype) && + isObject$g(NewTargetPrototype = NewTarget.prototype) && NewTargetPrototype !== Wrapper.prototype ) setPrototypeOf$2($this, NewTargetPrototype); return $this; }; - var $$U = _export; - var global$f = global$F; + var $$_ = _export; + var global$v = global$1m; + var call$c = functionCall; var DESCRIPTORS$c = descriptors; var TYPED_ARRAYS_CONSTRUCTORS_REQUIRES_WRAPPERS$1 = typedArrayConstructorsRequireWrappers; - var ArrayBufferViewCore$m = arrayBufferViewCore; + var ArrayBufferViewCore$n = arrayBufferViewCore; var ArrayBufferModule = arrayBuffer; var anInstance$4 = anInstance$7; var createPropertyDescriptor$2 = createPropertyDescriptor$7; - var createNonEnumerableProperty$2 = createNonEnumerableProperty$e; - var toLength$h = toLength$q; + var createNonEnumerableProperty$2 = createNonEnumerableProperty$b; + var isIntegralNumber = isIntegralNumber$1; + var toLength$7 = toLength$c; var toIndex = toIndex$2; var toOffset$1 = toOffset$2; - var toPrimitive$3 = toPrimitive$7; - var has$5 = has$j; - var classof$5 = classof$b; - var isObject$e = isObject$r; - var create$9 = objectCreate; + var toPropertyKey$1 = toPropertyKey$5; + var hasOwn$7 = hasOwnProperty_1; + var classof$4 = classof$d; + var isObject$f = isObject$s; + var isSymbol$2 = isSymbol$6; + var create$7 = objectCreate; + var isPrototypeOf$3 = objectIsPrototypeOf; var setPrototypeOf$1 = objectSetPrototypeOf; var getOwnPropertyNames$2 = objectGetOwnPropertyNames.f; var typedArrayFrom$1 = typedArrayFrom$2; @@ -3713,65 +4398,71 @@ var InternalStateModule$3 = internalState; var inheritIfRequired$3 = inheritIfRequired$4; - var getInternalState$1 = InternalStateModule$3.get; + var getInternalState = InternalStateModule$3.get; var setInternalState$3 = InternalStateModule$3.set; var nativeDefineProperty = definePropertyModule$1.f; var nativeGetOwnPropertyDescriptor$1 = getOwnPropertyDescriptorModule$1.f; var round = Math.round; - var RangeError$1 = global$f.RangeError; + var RangeError$7 = global$v.RangeError; var ArrayBuffer$1 = ArrayBufferModule.ArrayBuffer; + var ArrayBufferPrototype = ArrayBuffer$1.prototype; var DataView$1 = ArrayBufferModule.DataView; - var NATIVE_ARRAY_BUFFER_VIEWS = ArrayBufferViewCore$m.NATIVE_ARRAY_BUFFER_VIEWS; - var TYPED_ARRAY_TAG = ArrayBufferViewCore$m.TYPED_ARRAY_TAG; - var TypedArray = ArrayBufferViewCore$m.TypedArray; - var TypedArrayPrototype = ArrayBufferViewCore$m.TypedArrayPrototype; - var aTypedArrayConstructor$3 = ArrayBufferViewCore$m.aTypedArrayConstructor; - var isTypedArray = ArrayBufferViewCore$m.isTypedArray; + var NATIVE_ARRAY_BUFFER_VIEWS = ArrayBufferViewCore$n.NATIVE_ARRAY_BUFFER_VIEWS; + var TYPED_ARRAY_CONSTRUCTOR$1 = ArrayBufferViewCore$n.TYPED_ARRAY_CONSTRUCTOR; + var TYPED_ARRAY_TAG = ArrayBufferViewCore$n.TYPED_ARRAY_TAG; + var TypedArray = ArrayBufferViewCore$n.TypedArray; + var TypedArrayPrototype = ArrayBufferViewCore$n.TypedArrayPrototype; + var aTypedArrayConstructor$1 = ArrayBufferViewCore$n.aTypedArrayConstructor; + var isTypedArray = ArrayBufferViewCore$n.isTypedArray; var BYTES_PER_ELEMENT = 'BYTES_PER_ELEMENT'; var WRONG_LENGTH = 'Wrong length'; var fromList = function (C, list) { + aTypedArrayConstructor$1(C); var index = 0; var length = list.length; - var result = new (aTypedArrayConstructor$3(C))(length); + var result = new C(length); while (length > index) result[index] = list[index++]; return result; }; var addGetter = function (it, key) { nativeDefineProperty(it, key, { get: function () { - return getInternalState$1(this)[key]; + return getInternalState(this)[key]; } }); }; var isArrayBuffer = function (it) { var klass; - return it instanceof ArrayBuffer$1 || (klass = classof$5(it)) == 'ArrayBuffer' || klass == 'SharedArrayBuffer'; + return isPrototypeOf$3(ArrayBufferPrototype, it) || (klass = classof$4(it)) == 'ArrayBuffer' || klass == 'SharedArrayBuffer'; }; var isTypedArrayIndex = function (target, key) { return isTypedArray(target) - && typeof key != 'symbol' + && !isSymbol$2(key) && key in target - && String(+key) == String(key); + && isIntegralNumber(+key) + && key >= 0; }; var wrappedGetOwnPropertyDescriptor = function getOwnPropertyDescriptor(target, key) { - return isTypedArrayIndex(target, key = toPrimitive$3(key, true)) + key = toPropertyKey$1(key); + return isTypedArrayIndex(target, key) ? createPropertyDescriptor$2(2, target[key]) : nativeGetOwnPropertyDescriptor$1(target, key); }; var wrappedDefineProperty = function defineProperty(target, key, descriptor) { - if (isTypedArrayIndex(target, key = toPrimitive$3(key, true)) - && isObject$e(descriptor) - && has$5(descriptor, 'value') - && !has$5(descriptor, 'get') - && !has$5(descriptor, 'set') + key = toPropertyKey$1(key); + if (isTypedArrayIndex(target, key) + && isObject$f(descriptor) + && hasOwn$7(descriptor, 'value') + && !hasOwn$7(descriptor, 'get') + && !hasOwn$7(descriptor, 'set') // TODO: add validation descriptor w/o calling accessors && !descriptor.configurable - && (!has$5(descriptor, 'writable') || descriptor.writable) - && (!has$5(descriptor, 'enumerable') || descriptor.enumerable) + && (!hasOwn$7(descriptor, 'writable') || descriptor.writable) + && (!hasOwn$7(descriptor, 'enumerable') || descriptor.enumerable) ) { target[key] = descriptor.value; return target; @@ -3788,7 +4479,7 @@ addGetter(TypedArrayPrototype, 'length'); } - $$U({ target: 'Object', stat: true, forced: !NATIVE_ARRAY_BUFFER_VIEWS }, { + $$_({ target: 'Object', stat: true, forced: !NATIVE_ARRAY_BUFFER_VIEWS }, { getOwnPropertyDescriptor: wrappedGetOwnPropertyDescriptor, defineProperty: wrappedDefineProperty }); @@ -3798,18 +4489,18 @@ var CONSTRUCTOR_NAME = TYPE + (CLAMPED ? 'Clamped' : '') + 'Array'; var GETTER = 'get' + TYPE; var SETTER = 'set' + TYPE; - var NativeTypedArrayConstructor = global$f[CONSTRUCTOR_NAME]; + var NativeTypedArrayConstructor = global$v[CONSTRUCTOR_NAME]; var TypedArrayConstructor = NativeTypedArrayConstructor; var TypedArrayConstructorPrototype = TypedArrayConstructor && TypedArrayConstructor.prototype; var exported = {}; var getter = function (that, index) { - var data = getInternalState$1(that); + var data = getInternalState(that); return data.view[GETTER](index * BYTES + data.byteOffset, true); }; var setter = function (that, index, value) { - var data = getInternalState$1(that); + var data = getInternalState(that); if (CLAMPED) value = (value = round(value)) < 0 ? 0 : value > 0xFF ? 0xFF : value & 0xFF; data.view[SETTER](index * BYTES + data.byteOffset, value, true); }; @@ -3828,11 +4519,11 @@ if (!NATIVE_ARRAY_BUFFER_VIEWS) { TypedArrayConstructor = wrapper(function (that, data, offset, $length) { - anInstance$4(that, TypedArrayConstructor, CONSTRUCTOR_NAME); + anInstance$4(that, TypedArrayConstructorPrototype); var index = 0; var byteOffset = 0; var buffer, byteLength, length; - if (!isObject$e(data)) { + if (!isObject$f(data)) { length = toIndex(data); byteLength = length * BYTES; buffer = new ArrayBuffer$1(byteLength); @@ -3841,18 +4532,18 @@ byteOffset = toOffset$1(offset, BYTES); var $len = data.byteLength; if ($length === undefined) { - if ($len % BYTES) throw RangeError$1(WRONG_LENGTH); + if ($len % BYTES) throw RangeError$7(WRONG_LENGTH); byteLength = $len - byteOffset; - if (byteLength < 0) throw RangeError$1(WRONG_LENGTH); + if (byteLength < 0) throw RangeError$7(WRONG_LENGTH); } else { - byteLength = toLength$h($length) * BYTES; - if (byteLength + byteOffset > $len) throw RangeError$1(WRONG_LENGTH); + byteLength = toLength$7($length) * BYTES; + if (byteLength + byteOffset > $len) throw RangeError$7(WRONG_LENGTH); } length = byteLength / BYTES; } else if (isTypedArray(data)) { return fromList(TypedArrayConstructor, data); } else { - return typedArrayFrom$1.call(TypedArrayConstructor, data); + return call$c(typedArrayFrom$1, TypedArrayConstructor, data); } setInternalState$3(that, { buffer: buffer, @@ -3865,19 +4556,19 @@ }); if (setPrototypeOf$1) setPrototypeOf$1(TypedArrayConstructor, TypedArray); - TypedArrayConstructorPrototype = TypedArrayConstructor.prototype = create$9(TypedArrayPrototype); + TypedArrayConstructorPrototype = TypedArrayConstructor.prototype = create$7(TypedArrayPrototype); } else if (TYPED_ARRAYS_CONSTRUCTORS_REQUIRES_WRAPPERS$1) { TypedArrayConstructor = wrapper(function (dummy, data, typedArrayOffset, $length) { - anInstance$4(dummy, TypedArrayConstructor, CONSTRUCTOR_NAME); + anInstance$4(dummy, TypedArrayConstructorPrototype); return inheritIfRequired$3(function () { - if (!isObject$e(data)) return new NativeTypedArrayConstructor(toIndex(data)); + if (!isObject$f(data)) return new NativeTypedArrayConstructor(toIndex(data)); if (isArrayBuffer(data)) return $length !== undefined ? new NativeTypedArrayConstructor(data, toOffset$1(typedArrayOffset, BYTES), $length) : typedArrayOffset !== undefined ? new NativeTypedArrayConstructor(data, toOffset$1(typedArrayOffset, BYTES)) : new NativeTypedArrayConstructor(data); if (isTypedArray(data)) return fromList(TypedArrayConstructor, data); - return typedArrayFrom$1.call(TypedArrayConstructor, data); + return call$c(typedArrayFrom$1, TypedArrayConstructor, data); }(), dummy, TypedArrayConstructor); }); @@ -3894,13 +4585,15 @@ createNonEnumerableProperty$2(TypedArrayConstructorPrototype, 'constructor', TypedArrayConstructor); } + createNonEnumerableProperty$2(TypedArrayConstructorPrototype, TYPED_ARRAY_CONSTRUCTOR$1, TypedArrayConstructor); + if (TYPED_ARRAY_TAG) { createNonEnumerableProperty$2(TypedArrayConstructorPrototype, TYPED_ARRAY_TAG, CONSTRUCTOR_NAME); } exported[CONSTRUCTOR_NAME] = TypedArrayConstructor; - $$U({ + $$_({ global: true, forced: TypedArrayConstructor != NativeTypedArrayConstructor, sham: !NATIVE_ARRAY_BUFFER_VIEWS }, exported); @@ -3926,9 +4619,9 @@ }; }); - var toObject$b = toObject$i; + var toObject$c = toObject$j; var toAbsoluteIndex$4 = toAbsoluteIndex$8; - var toLength$g = toLength$q; + var lengthOfArrayLike$a = lengthOfArrayLike$g; var min$7 = Math.min; @@ -3936,8 +4629,8 @@ // https://tc39.es/ecma262/#sec-array.prototype.copywithin // eslint-disable-next-line es/no-array-prototype-copywithin -- safe var arrayCopyWithin = [].copyWithin || function copyWithin(target /* = 0 */, start /* = 0, end = @length */) { - var O = toObject$b(this); - var len = toLength$g(O.length); + var O = toObject$c(this); + var len = lengthOfArrayLike$a(O); var to = toAbsoluteIndex$4(target, len); var from = toAbsoluteIndex$4(start, len); var end = arguments.length > 2 ? arguments[2] : undefined; @@ -3956,23 +4649,25 @@ } return O; }; - var ArrayBufferViewCore$l = arrayBufferViewCore; - var $copyWithin = arrayCopyWithin; + var uncurryThis$A = functionUncurryThis; + var ArrayBufferViewCore$m = arrayBufferViewCore; + var $ArrayCopyWithin = arrayCopyWithin; - var aTypedArray$l = ArrayBufferViewCore$l.aTypedArray; - var exportTypedArrayMethod$m = ArrayBufferViewCore$l.exportTypedArrayMethod; + var u$ArrayCopyWithin = uncurryThis$A($ArrayCopyWithin); + var aTypedArray$l = ArrayBufferViewCore$m.aTypedArray; + var exportTypedArrayMethod$m = ArrayBufferViewCore$m.exportTypedArrayMethod; // `%TypedArray%.prototype.copyWithin` method // https://tc39.es/ecma262/#sec-%typedarray%.prototype.copywithin exportTypedArrayMethod$m('copyWithin', function copyWithin(target, start /* , end */) { - return $copyWithin.call(aTypedArray$l(this), target, start, arguments.length > 2 ? arguments[2] : undefined); + return u$ArrayCopyWithin(aTypedArray$l(this), target, start, arguments.length > 2 ? arguments[2] : undefined); }); - var ArrayBufferViewCore$k = arrayBufferViewCore; + var ArrayBufferViewCore$l = arrayBufferViewCore; var $every$1 = arrayIteration.every; - var aTypedArray$k = ArrayBufferViewCore$k.aTypedArray; - var exportTypedArrayMethod$l = ArrayBufferViewCore$k.exportTypedArrayMethod; + var aTypedArray$k = ArrayBufferViewCore$l.aTypedArray; + var exportTypedArrayMethod$l = ArrayBufferViewCore$l.exportTypedArrayMethod; // `%TypedArray%.prototype.every` method // https://tc39.es/ecma262/#sec-%typedarray%.prototype.every @@ -3980,31 +4675,53 @@ return $every$1(aTypedArray$k(this), callbackfn, arguments.length > 1 ? arguments[1] : undefined); }); - var ArrayBufferViewCore$j = arrayBufferViewCore; + var ArrayBufferViewCore$k = arrayBufferViewCore; + var call$b = functionCall; var $fill = arrayFill$1; - var aTypedArray$j = ArrayBufferViewCore$j.aTypedArray; - var exportTypedArrayMethod$k = ArrayBufferViewCore$j.exportTypedArrayMethod; + var aTypedArray$j = ArrayBufferViewCore$k.aTypedArray; + var exportTypedArrayMethod$k = ArrayBufferViewCore$k.exportTypedArrayMethod; // `%TypedArray%.prototype.fill` method // https://tc39.es/ecma262/#sec-%typedarray%.prototype.fill - // eslint-disable-next-line no-unused-vars -- required for `.length` exportTypedArrayMethod$k('fill', function fill(value /* , start, end */) { - return $fill.apply(aTypedArray$j(this), arguments); + var length = arguments.length; + return call$b( + $fill, + aTypedArray$j(this), + value, + length > 1 ? arguments[1] : undefined, + length > 2 ? arguments[2] : undefined + ); }); - var aTypedArrayConstructor$2 = arrayBufferViewCore.aTypedArrayConstructor; - var speciesConstructor$5 = speciesConstructor$8; - - var typedArrayFromSpeciesAndList = function (instance, list) { - var C = speciesConstructor$5(instance, instance.constructor); + var arrayFromConstructorAndList$1 = function (Constructor, list) { var index = 0; var length = list.length; - var result = new (aTypedArrayConstructor$2(C))(length); + var result = new Constructor(length); while (length > index) result[index] = list[index++]; return result; }; + var ArrayBufferViewCore$j = arrayBufferViewCore; + var speciesConstructor$2 = speciesConstructor$5; + + var TYPED_ARRAY_CONSTRUCTOR = ArrayBufferViewCore$j.TYPED_ARRAY_CONSTRUCTOR; + var aTypedArrayConstructor = ArrayBufferViewCore$j.aTypedArrayConstructor; + + // a part of `TypedArraySpeciesCreate` abstract operation + // https://tc39.es/ecma262/#typedarray-species-create + var typedArraySpeciesConstructor$4 = function (originalArray) { + return aTypedArrayConstructor(speciesConstructor$2(originalArray, originalArray[TYPED_ARRAY_CONSTRUCTOR])); + }; + + var arrayFromConstructorAndList = arrayFromConstructorAndList$1; + var typedArraySpeciesConstructor$3 = typedArraySpeciesConstructor$4; + + var typedArrayFromSpeciesAndList = function (instance, list) { + return arrayFromConstructorAndList(typedArraySpeciesConstructor$3(instance), list); + }; + var ArrayBufferViewCore$i = arrayBufferViewCore; var $filter$1 = arrayIteration.filter; var fromSpeciesAndList = typedArrayFromSpeciesAndList; @@ -4079,84 +4796,87 @@ return $indexOf(aTypedArray$d(this), searchElement, arguments.length > 1 ? arguments[1] : undefined); }); - var global$e = global$F; + var global$u = global$1m; + var uncurryThis$z = functionUncurryThis; + var PROPER_FUNCTION_NAME$2 = functionName.PROPER; var ArrayBufferViewCore$c = arrayBufferViewCore; var ArrayIterators = es_array_iterator; - var wellKnownSymbol$9 = wellKnownSymbol$s; + var wellKnownSymbol$9 = wellKnownSymbol$t; - var ITERATOR$2 = wellKnownSymbol$9('iterator'); - var Uint8Array$2 = global$e.Uint8Array; - var arrayValues = ArrayIterators.values; - var arrayKeys = ArrayIterators.keys; - var arrayEntries = ArrayIterators.entries; + var ITERATOR$4 = wellKnownSymbol$9('iterator'); + var Uint8Array$2 = global$u.Uint8Array; + var arrayValues = uncurryThis$z(ArrayIterators.values); + var arrayKeys = uncurryThis$z(ArrayIterators.keys); + var arrayEntries = uncurryThis$z(ArrayIterators.entries); var aTypedArray$c = ArrayBufferViewCore$c.aTypedArray; var exportTypedArrayMethod$d = ArrayBufferViewCore$c.exportTypedArrayMethod; - var nativeTypedArrayIterator = Uint8Array$2 && Uint8Array$2.prototype[ITERATOR$2]; + var nativeTypedArrayIterator = Uint8Array$2 && Uint8Array$2.prototype[ITERATOR$4]; - var CORRECT_ITER_NAME = !!nativeTypedArrayIterator - && (nativeTypedArrayIterator.name == 'values' || nativeTypedArrayIterator.name == undefined); + var PROPER_ARRAY_VALUES_NAME = !!nativeTypedArrayIterator && nativeTypedArrayIterator.name === 'values'; var typedArrayValues = function values() { - return arrayValues.call(aTypedArray$c(this)); + return arrayValues(aTypedArray$c(this)); }; // `%TypedArray%.prototype.entries` method // https://tc39.es/ecma262/#sec-%typedarray%.prototype.entries exportTypedArrayMethod$d('entries', function entries() { - return arrayEntries.call(aTypedArray$c(this)); + return arrayEntries(aTypedArray$c(this)); }); // `%TypedArray%.prototype.keys` method // https://tc39.es/ecma262/#sec-%typedarray%.prototype.keys exportTypedArrayMethod$d('keys', function keys() { - return arrayKeys.call(aTypedArray$c(this)); + return arrayKeys(aTypedArray$c(this)); }); // `%TypedArray%.prototype.values` method // https://tc39.es/ecma262/#sec-%typedarray%.prototype.values - exportTypedArrayMethod$d('values', typedArrayValues, !CORRECT_ITER_NAME); + exportTypedArrayMethod$d('values', typedArrayValues, PROPER_FUNCTION_NAME$2 && !PROPER_ARRAY_VALUES_NAME); // `%TypedArray%.prototype[@@iterator]` method // https://tc39.es/ecma262/#sec-%typedarray%.prototype-@@iterator - exportTypedArrayMethod$d(ITERATOR$2, typedArrayValues, !CORRECT_ITER_NAME); + exportTypedArrayMethod$d(ITERATOR$4, typedArrayValues, PROPER_FUNCTION_NAME$2 && !PROPER_ARRAY_VALUES_NAME); var ArrayBufferViewCore$b = arrayBufferViewCore; + var uncurryThis$y = functionUncurryThis; var aTypedArray$b = ArrayBufferViewCore$b.aTypedArray; var exportTypedArrayMethod$c = ArrayBufferViewCore$b.exportTypedArrayMethod; - var $join = [].join; + var $join = uncurryThis$y([].join); // `%TypedArray%.prototype.join` method // https://tc39.es/ecma262/#sec-%typedarray%.prototype.join - // eslint-disable-next-line no-unused-vars -- required for `.length` exportTypedArrayMethod$c('join', function join(separator) { - return $join.apply(aTypedArray$b(this), arguments); + return $join(aTypedArray$b(this), separator); }); /* eslint-disable es/no-array-prototype-lastindexof -- safe */ - var toIndexedObject$4 = toIndexedObject$b; - var toInteger$4 = toInteger$b; - var toLength$f = toLength$q; - var arrayMethodIsStrict$5 = arrayMethodIsStrict$8; + var apply$6 = functionApply; + var toIndexedObject$4 = toIndexedObject$c; + var toIntegerOrInfinity$4 = toIntegerOrInfinity$b; + var lengthOfArrayLike$9 = lengthOfArrayLike$g; + var arrayMethodIsStrict$6 = arrayMethodIsStrict$9; var min$6 = Math.min; var $lastIndexOf$1 = [].lastIndexOf; var NEGATIVE_ZERO = !!$lastIndexOf$1 && 1 / [1].lastIndexOf(1, -0) < 0; - var STRICT_METHOD$5 = arrayMethodIsStrict$5('lastIndexOf'); - var FORCED$e = NEGATIVE_ZERO || !STRICT_METHOD$5; + var STRICT_METHOD$6 = arrayMethodIsStrict$6('lastIndexOf'); + var FORCED$g = NEGATIVE_ZERO || !STRICT_METHOD$6; // `Array.prototype.lastIndexOf` method implementation // https://tc39.es/ecma262/#sec-array.prototype.lastindexof - var arrayLastIndexOf = FORCED$e ? function lastIndexOf(searchElement /* , fromIndex = @[*-1] */) { + var arrayLastIndexOf = FORCED$g ? function lastIndexOf(searchElement /* , fromIndex = @[*-1] */) { // convert -0 to +0 - if (NEGATIVE_ZERO) return $lastIndexOf$1.apply(this, arguments) || 0; + if (NEGATIVE_ZERO) return apply$6($lastIndexOf$1, this, arguments) || 0; var O = toIndexedObject$4(this); - var length = toLength$f(O.length); + var length = lengthOfArrayLike$9(O); var index = length - 1; - if (arguments.length > 1) index = min$6(index, toInteger$4(arguments[1])); + if (arguments.length > 1) index = min$6(index, toIntegerOrInfinity$4(arguments[1])); if (index < 0) index = length + index; for (;index >= 0; index--) if (index in O && O[index] === searchElement) return index || 0; return -1; } : $lastIndexOf$1; var ArrayBufferViewCore$a = arrayBufferViewCore; + var apply$5 = functionApply; var $lastIndexOf = arrayLastIndexOf; var aTypedArray$a = ArrayBufferViewCore$a.aTypedArray; @@ -4164,39 +4884,41 @@ // `%TypedArray%.prototype.lastIndexOf` method // https://tc39.es/ecma262/#sec-%typedarray%.prototype.lastindexof - // eslint-disable-next-line no-unused-vars -- required for `.length` exportTypedArrayMethod$b('lastIndexOf', function lastIndexOf(searchElement /* , fromIndex */) { - return $lastIndexOf.apply(aTypedArray$a(this), arguments); + var length = arguments.length; + return apply$5($lastIndexOf, aTypedArray$a(this), length > 1 ? [searchElement, arguments[1]] : [searchElement]); }); var ArrayBufferViewCore$9 = arrayBufferViewCore; var $map = arrayIteration.map; - var speciesConstructor$4 = speciesConstructor$8; + var typedArraySpeciesConstructor$2 = typedArraySpeciesConstructor$4; var aTypedArray$9 = ArrayBufferViewCore$9.aTypedArray; - var aTypedArrayConstructor$1 = ArrayBufferViewCore$9.aTypedArrayConstructor; var exportTypedArrayMethod$a = ArrayBufferViewCore$9.exportTypedArrayMethod; // `%TypedArray%.prototype.map` method // https://tc39.es/ecma262/#sec-%typedarray%.prototype.map exportTypedArrayMethod$a('map', function map(mapfn /* , thisArg */) { return $map(aTypedArray$9(this), mapfn, arguments.length > 1 ? arguments[1] : undefined, function (O, length) { - return new (aTypedArrayConstructor$1(speciesConstructor$4(O, O.constructor)))(length); + return new (typedArraySpeciesConstructor$2(O))(length); }); }); - var aFunction$4 = aFunction$9; - var toObject$a = toObject$i; + var global$t = global$1m; + var aCallable$4 = aCallable$a; + var toObject$b = toObject$j; var IndexedObject$2 = indexedObject; - var toLength$e = toLength$q; + var lengthOfArrayLike$8 = lengthOfArrayLike$g; + + var TypeError$9 = global$t.TypeError; // `Array.prototype.{ reduce, reduceRight }` methods implementation var createMethod$3 = function (IS_RIGHT) { return function (that, callbackfn, argumentsLength, memo) { - aFunction$4(callbackfn); - var O = toObject$a(that); + aCallable$4(callbackfn); + var O = toObject$b(that); var self = IndexedObject$2(O); - var length = toLength$e(O.length); + var length = lengthOfArrayLike$8(O); var index = IS_RIGHT ? length - 1 : 0; var i = IS_RIGHT ? -1 : 1; if (argumentsLength < 2) while (true) { @@ -4207,7 +4929,7 @@ } index += i; if (IS_RIGHT ? index < 0 : length <= index) { - throw TypeError('Reduce of empty array with no initial value'); + throw TypeError$9('Reduce of empty array with no initial value'); } } for (;IS_RIGHT ? index >= 0 : length > index; index += i) if (index in self) { @@ -4235,11 +4957,12 @@ // `%TypedArray%.prototype.reduce` method // https://tc39.es/ecma262/#sec-%typedarray%.prototype.reduce exportTypedArrayMethod$9('reduce', function reduce(callbackfn /* , initialValue */) { - return $reduce$1(aTypedArray$8(this), callbackfn, arguments.length, arguments.length > 1 ? arguments[1] : undefined); + var length = arguments.length; + return $reduce$1(aTypedArray$8(this), callbackfn, length, length > 1 ? arguments[1] : undefined); }); var ArrayBufferViewCore$7 = arrayBufferViewCore; - var $reduceRight = arrayReduce.right; + var $reduceRight$1 = arrayReduce.right; var aTypedArray$7 = ArrayBufferViewCore$7.aTypedArray; var exportTypedArrayMethod$8 = ArrayBufferViewCore$7.exportTypedArrayMethod; @@ -4247,7 +4970,8 @@ // `%TypedArray%.prototype.reduceRicht` method // https://tc39.es/ecma262/#sec-%typedarray%.prototype.reduceright exportTypedArrayMethod$8('reduceRight', function reduceRight(callbackfn /* , initialValue */) { - return $reduceRight(aTypedArray$7(this), callbackfn, arguments.length, arguments.length > 1 ? arguments[1] : undefined); + var length = arguments.length; + return $reduceRight$1(aTypedArray$7(this), callbackfn, length, length > 1 ? arguments[1] : undefined); }); var ArrayBufferViewCore$6 = arrayBufferViewCore; @@ -4271,16 +4995,18 @@ } return that; }); + var global$s = global$1m; var ArrayBufferViewCore$5 = arrayBufferViewCore; - var toLength$d = toLength$q; + var lengthOfArrayLike$7 = lengthOfArrayLike$g; var toOffset = toOffset$2; - var toObject$9 = toObject$i; - var fails$x = fails$N; + var toObject$a = toObject$j; + var fails$y = fails$S; + var RangeError$6 = global$s.RangeError; var aTypedArray$5 = ArrayBufferViewCore$5.aTypedArray; var exportTypedArrayMethod$6 = ArrayBufferViewCore$5.exportTypedArrayMethod; - var FORCED$d = fails$x(function () { + var FORCED$f = fails$y(function () { // eslint-disable-next-line es/no-typed-arrays -- required for testing new Int8Array(1).set({}); }); @@ -4291,23 +5017,22 @@ aTypedArray$5(this); var offset = toOffset(arguments.length > 1 ? arguments[1] : undefined, 1); var length = this.length; - var src = toObject$9(arrayLike); - var len = toLength$d(src.length); + var src = toObject$a(arrayLike); + var len = lengthOfArrayLike$7(src); var index = 0; - if (len + offset > length) throw RangeError('Wrong length'); + if (len + offset > length) throw RangeError$6('Wrong length'); while (index < len) this[offset + index] = src[index++]; - }, FORCED$d); + }, FORCED$f); var ArrayBufferViewCore$4 = arrayBufferViewCore; - var speciesConstructor$3 = speciesConstructor$8; - var fails$w = fails$N; + var typedArraySpeciesConstructor$1 = typedArraySpeciesConstructor$4; + var fails$x = fails$S; + var arraySlice$7 = arraySlice$c; var aTypedArray$4 = ArrayBufferViewCore$4.aTypedArray; - var aTypedArrayConstructor = ArrayBufferViewCore$4.aTypedArrayConstructor; var exportTypedArrayMethod$5 = ArrayBufferViewCore$4.exportTypedArrayMethod; - var $slice$1 = [].slice; - var FORCED$c = fails$w(function () { + var FORCED$e = fails$x(function () { // eslint-disable-next-line es/no-typed-arrays -- required for testing new Int8Array(1).slice(); }); @@ -4315,14 +5040,14 @@ // `%TypedArray%.prototype.slice` method // https://tc39.es/ecma262/#sec-%typedarray%.prototype.slice exportTypedArrayMethod$5('slice', function slice(start, end) { - var list = $slice$1.call(aTypedArray$4(this), start, end); - var C = speciesConstructor$3(this, this.constructor); + var list = arraySlice$7(aTypedArray$4(this), start, end); + var C = typedArraySpeciesConstructor$1(this); var index = 0; var length = list.length; - var result = new (aTypedArrayConstructor(C))(length); + var result = new C(length); while (length > index) result[index] = list[index++]; return result; - }, FORCED$c); + }, FORCED$e); var ArrayBufferViewCore$3 = arrayBufferViewCore; var $some$1 = arrayIteration.some; @@ -4336,15 +5061,17 @@ return $some$1(aTypedArray$3(this), callbackfn, arguments.length > 1 ? arguments[1] : undefined); }); - // TODO: use something more complex like timsort? + var arraySlice$6 = arraySlice$c; + var floor$4 = Math.floor; var mergeSort = function (array, comparefn) { var length = array.length; var middle = floor$4(length / 2); return length < 8 ? insertionSort(array, comparefn) : merge$5( - mergeSort(array.slice(0, middle), comparefn), - mergeSort(array.slice(middle), comparefn), + array, + mergeSort(arraySlice$6(array, 0, middle), comparefn), + mergeSort(arraySlice$6(array, middle), comparefn), comparefn ); }; @@ -4364,27 +5091,24 @@ } return array; }; - var merge$5 = function (left, right, comparefn) { + var merge$5 = function (array, left, right, comparefn) { var llength = left.length; var rlength = right.length; var lindex = 0; var rindex = 0; - var result = []; while (lindex < llength || rindex < rlength) { - if (lindex < llength && rindex < rlength) { - result.push(comparefn(left[lindex], right[rindex]) <= 0 ? left[lindex++] : right[rindex++]); - } else { - result.push(lindex < llength ? left[lindex++] : right[rindex++]); - } - } return result; + array[lindex + rindex] = (lindex < llength && rindex < rlength) + ? comparefn(left[lindex], right[rindex]) <= 0 ? left[lindex++] : right[rindex++] + : lindex < llength ? left[lindex++] : right[rindex++]; + } return array; }; - var arraySort = mergeSort; + var arraySort$1 = mergeSort; - var userAgent$2 = engineUserAgent; + var userAgent$3 = engineUserAgent; - var firefox = userAgent$2.match(/firefox\/(\d+)/i); + var firefox = userAgent$3.match(/firefox\/(\d+)/i); var engineFfVersion = !!firefox && +firefox[1]; @@ -4392,36 +5116,37 @@ var engineIsIeOrEdge = /MSIE|Trident/.test(UA); - var userAgent$1 = engineUserAgent; + var userAgent$2 = engineUserAgent; - var webkit = userAgent$1.match(/AppleWebKit\/(\d+)\./); + var webkit = userAgent$2.match(/AppleWebKit\/(\d+)\./); var engineWebkitVersion = !!webkit && +webkit[1]; + var global$r = global$1m; + var uncurryThis$x = functionUncurryThis; + var fails$w = fails$S; + var aCallable$3 = aCallable$a; + var internalSort$1 = arraySort$1; var ArrayBufferViewCore$2 = arrayBufferViewCore; - var global$d = global$F; - var fails$v = fails$N; - var aFunction$3 = aFunction$9; - var toLength$c = toLength$q; - var internalSort$1 = arraySort; var FF$1 = engineFfVersion; var IE_OR_EDGE$1 = engineIsIeOrEdge; var V8$1 = engineV8Version; var WEBKIT$1 = engineWebkitVersion; + var Array$3 = global$r.Array; var aTypedArray$2 = ArrayBufferViewCore$2.aTypedArray; var exportTypedArrayMethod$3 = ArrayBufferViewCore$2.exportTypedArrayMethod; - var Uint16Array = global$d.Uint16Array; - var nativeSort$1 = Uint16Array && Uint16Array.prototype.sort; + var Uint16Array = global$r.Uint16Array; + var un$Sort$1 = Uint16Array && uncurryThis$x(Uint16Array.prototype.sort); // WebKit - var ACCEPT_INCORRECT_ARGUMENTS = !!nativeSort$1 && !fails$v(function () { - var array = new Uint16Array(2); - array.sort(null); - array.sort({}); - }); + var ACCEPT_INCORRECT_ARGUMENTS = !!un$Sort$1 && !(fails$w(function () { + un$Sort$1(new Uint16Array(2), null); + }) && fails$w(function () { + un$Sort$1(new Uint16Array(2), {}); + })); - var STABLE_SORT$1 = !!nativeSort$1 && !fails$v(function () { + var STABLE_SORT$1 = !!un$Sort$1 && !fails$w(function () { // feature detection can be too slow, so check engines versions if (V8$1) return V8$1 < 74; if (FF$1) return FF$1 < 67; @@ -4429,7 +5154,7 @@ if (WEBKIT$1) return WEBKIT$1 < 602; var array = new Uint16Array(516); - var expected = Array(516); + var expected = Array$3(516); var index, mod; for (index = 0; index < 516; index++) { @@ -4438,7 +5163,7 @@ expected[index] = index - 2 * mod + 3; } - array.sort(function (a, b) { + un$Sort$1(array, function (a, b) { return (a / 4 | 0) - (b / 4 | 0); }); @@ -4462,32 +5187,16 @@ // `%TypedArray%.prototype.sort` method // https://tc39.es/ecma262/#sec-%typedarray%.prototype.sort exportTypedArrayMethod$3('sort', function sort(comparefn) { - var array = this; - if (comparefn !== undefined) aFunction$3(comparefn); - if (STABLE_SORT$1) return nativeSort$1.call(array, comparefn); - - aTypedArray$2(array); - var arrayLength = toLength$c(array.length); - var items = Array(arrayLength); - var index; - - for (index = 0; index < arrayLength; index++) { - items[index] = array[index]; - } + if (comparefn !== undefined) aCallable$3(comparefn); + if (STABLE_SORT$1) return un$Sort$1(this, comparefn); - items = internalSort$1(array, getSortCompare$1(comparefn)); - - for (index = 0; index < arrayLength; index++) { - array[index] = items[index]; - } - - return array; + return internalSort$1(aTypedArray$2(this), getSortCompare$1(comparefn)); }, !STABLE_SORT$1 || ACCEPT_INCORRECT_ARGUMENTS); var ArrayBufferViewCore$1 = arrayBufferViewCore; - var toLength$b = toLength$q; + var toLength$6 = toLength$c; var toAbsoluteIndex$3 = toAbsoluteIndex$8; - var speciesConstructor$2 = speciesConstructor$8; + var typedArraySpeciesConstructor = typedArraySpeciesConstructor$4; var aTypedArray$1 = ArrayBufferViewCore$1.aTypedArray; var exportTypedArrayMethod$2 = ArrayBufferViewCore$1.exportTypedArrayMethod; @@ -4498,52 +5207,59 @@ var O = aTypedArray$1(this); var length = O.length; var beginIndex = toAbsoluteIndex$3(begin, length); - return new (speciesConstructor$2(O, O.constructor))( + var C = typedArraySpeciesConstructor(O); + return new C( O.buffer, O.byteOffset + beginIndex * O.BYTES_PER_ELEMENT, - toLength$b((end === undefined ? length : toAbsoluteIndex$3(end, length)) - beginIndex) + toLength$6((end === undefined ? length : toAbsoluteIndex$3(end, length)) - beginIndex) ); }); - var global$c = global$F; + var global$q = global$1m; + var apply$4 = functionApply; var ArrayBufferViewCore = arrayBufferViewCore; - var fails$u = fails$N; + var fails$v = fails$S; + var arraySlice$5 = arraySlice$c; - var Int8Array$1 = global$c.Int8Array; + var Int8Array$1 = global$q.Int8Array; var aTypedArray = ArrayBufferViewCore.aTypedArray; var exportTypedArrayMethod$1 = ArrayBufferViewCore.exportTypedArrayMethod; var $toLocaleString = [].toLocaleString; - var $slice = [].slice; // iOS Safari 6.x fails here - var TO_LOCALE_STRING_BUG = !!Int8Array$1 && fails$u(function () { + var TO_LOCALE_STRING_BUG = !!Int8Array$1 && fails$v(function () { $toLocaleString.call(new Int8Array$1(1)); }); - var FORCED$b = fails$u(function () { + var FORCED$d = fails$v(function () { return [1, 2].toLocaleString() != new Int8Array$1([1, 2]).toLocaleString(); - }) || !fails$u(function () { + }) || !fails$v(function () { Int8Array$1.prototype.toLocaleString.call([1, 2]); }); // `%TypedArray%.prototype.toLocaleString` method // https://tc39.es/ecma262/#sec-%typedarray%.prototype.tolocalestring exportTypedArrayMethod$1('toLocaleString', function toLocaleString() { - return $toLocaleString.apply(TO_LOCALE_STRING_BUG ? $slice.call(aTypedArray(this)) : aTypedArray(this), arguments); - }, FORCED$b); + return apply$4( + $toLocaleString, + TO_LOCALE_STRING_BUG ? arraySlice$5(aTypedArray(this)) : aTypedArray(this), + arraySlice$5(arguments) + ); + }, FORCED$d); var exportTypedArrayMethod = arrayBufferViewCore.exportTypedArrayMethod; - var fails$t = fails$N; - var global$b = global$F; + var fails$u = fails$S; + var global$p = global$1m; + var uncurryThis$w = functionUncurryThis; - var Uint8Array$1 = global$b.Uint8Array; + var Uint8Array$1 = global$p.Uint8Array; var Uint8ArrayPrototype = Uint8Array$1 && Uint8Array$1.prototype || {}; var arrayToString = [].toString; - var arrayJoin = [].join; + var join$5 = uncurryThis$w([].join); - if (fails$t(function () { arrayToString.call({}); })) { + if (fails$u(function () { arrayToString.call({}); })) { arrayToString = function toString() { - return arrayJoin.call(this); + return join$5(this); }; } @@ -4553,88 +5269,92 @@ // https://tc39.es/ecma262/#sec-%typedarray%.prototype.tostring exportTypedArrayMethod('toString', arrayToString, IS_NOT_ARRAY_METHOD); - var $$T = _export; + var $$Z = _export; + var uncurryThis$v = functionUncurryThis; var IndexedObject$1 = indexedObject; - var toIndexedObject$3 = toIndexedObject$b; - var arrayMethodIsStrict$4 = arrayMethodIsStrict$8; + var toIndexedObject$3 = toIndexedObject$c; + var arrayMethodIsStrict$5 = arrayMethodIsStrict$9; - var nativeJoin = [].join; + var un$Join = uncurryThis$v([].join); var ES3_STRINGS = IndexedObject$1 != Object; - var STRICT_METHOD$4 = arrayMethodIsStrict$4('join', ','); + var STRICT_METHOD$5 = arrayMethodIsStrict$5('join', ','); // `Array.prototype.join` method // https://tc39.es/ecma262/#sec-array.prototype.join - $$T({ target: 'Array', proto: true, forced: ES3_STRINGS || !STRICT_METHOD$4 }, { + $$Z({ target: 'Array', proto: true, forced: ES3_STRINGS || !STRICT_METHOD$5 }, { join: function join(separator) { - return nativeJoin.call(toIndexedObject$3(this), separator === undefined ? ',' : separator); + return un$Join(toIndexedObject$3(this), separator === undefined ? ',' : separator); } }); - var toPrimitive$2 = toPrimitive$7; + var toPropertyKey = toPropertyKey$5; var definePropertyModule = objectDefineProperty; var createPropertyDescriptor$1 = createPropertyDescriptor$7; var createProperty$4 = function (object, key, value) { - var propertyKey = toPrimitive$2(key); + var propertyKey = toPropertyKey(key); if (propertyKey in object) definePropertyModule.f(object, propertyKey, createPropertyDescriptor$1(0, value)); else object[propertyKey] = value; }; - var $$S = _export; - var isObject$d = isObject$r; - var isArray$2 = isArray$6; + var $$Y = _export; + var global$o = global$1m; + var isArray$4 = isArray$8; + var isConstructor$1 = isConstructor$4; + var isObject$e = isObject$s; var toAbsoluteIndex$2 = toAbsoluteIndex$8; - var toLength$a = toLength$q; - var toIndexedObject$2 = toIndexedObject$b; + var lengthOfArrayLike$6 = lengthOfArrayLike$g; + var toIndexedObject$2 = toIndexedObject$c; var createProperty$3 = createProperty$4; - var wellKnownSymbol$8 = wellKnownSymbol$s; + var wellKnownSymbol$8 = wellKnownSymbol$t; var arrayMethodHasSpeciesSupport$3 = arrayMethodHasSpeciesSupport$5; + var un$Slice = arraySlice$c; var HAS_SPECIES_SUPPORT$2 = arrayMethodHasSpeciesSupport$3('slice'); var SPECIES$1 = wellKnownSymbol$8('species'); - var nativeSlice = [].slice; + var Array$2 = global$o.Array; var max$3 = Math.max; // `Array.prototype.slice` method // https://tc39.es/ecma262/#sec-array.prototype.slice // fallback for not array-like ES3 strings and DOM objects - $$S({ target: 'Array', proto: true, forced: !HAS_SPECIES_SUPPORT$2 }, { + $$Y({ target: 'Array', proto: true, forced: !HAS_SPECIES_SUPPORT$2 }, { slice: function slice(start, end) { var O = toIndexedObject$2(this); - var length = toLength$a(O.length); + var length = lengthOfArrayLike$6(O); var k = toAbsoluteIndex$2(start, length); var fin = toAbsoluteIndex$2(end === undefined ? length : end, length); // inline `ArraySpeciesCreate` for usage native `Array#slice` where it's possible var Constructor, result, n; - if (isArray$2(O)) { + if (isArray$4(O)) { Constructor = O.constructor; // cross-realm fallback - if (typeof Constructor == 'function' && (Constructor === Array || isArray$2(Constructor.prototype))) { + if (isConstructor$1(Constructor) && (Constructor === Array$2 || isArray$4(Constructor.prototype))) { Constructor = undefined; - } else if (isObject$d(Constructor)) { + } else if (isObject$e(Constructor)) { Constructor = Constructor[SPECIES$1]; if (Constructor === null) Constructor = undefined; } - if (Constructor === Array || Constructor === undefined) { - return nativeSlice.call(O, k, fin); + if (Constructor === Array$2 || Constructor === undefined) { + return un$Slice(O, k, fin); } } - result = new (Constructor === undefined ? Array : Constructor)(max$3(fin - k, 0)); + result = new (Constructor === undefined ? Array$2 : Constructor)(max$3(fin - k, 0)); for (n = 0; k < fin; k++, n++) if (k in O) createProperty$3(result, n, O[k]); result.length = n; return result; } }); - var fails$s = fails$N; - var wellKnownSymbol$7 = wellKnownSymbol$s; + var fails$t = fails$S; + var wellKnownSymbol$7 = wellKnownSymbol$t; var IS_PURE = isPure; - var ITERATOR$1 = wellKnownSymbol$7('iterator'); + var ITERATOR$3 = wellKnownSymbol$7('iterator'); - var nativeUrl = !fails$s(function () { + var nativeUrl = !fails$t(function () { var url = new URL('b?a=1&b=2&c=3', 'http://a'); var searchParams = url.searchParams; var result = ''; @@ -4648,7 +5368,7 @@ || url.href !== 'http://a/c%20d?a=1&c=3' || searchParams.get('c') !== '3' || String(new URLSearchParams('?a=1')) !== 'a=1' - || !searchParams[ITERATOR$1] + || !searchParams[ITERATOR$3] // throws in Edge || new URL('https://a@b').username !== 'a' || new URLSearchParams(new URLSearchParams('a=b')).get('a') !== 'b' @@ -4662,346 +5382,82 @@ || new URL('http://x', undefined).host !== 'x'; }); - var DESCRIPTORS$b = descriptors; - var fails$r = fails$N; - var objectKeys$1 = objectKeys$4; - var getOwnPropertySymbolsModule = objectGetOwnPropertySymbols; - var propertyIsEnumerableModule = objectPropertyIsEnumerable; - var toObject$8 = toObject$i; - var IndexedObject = indexedObject; - - // eslint-disable-next-line es/no-object-assign -- safe - var $assign = Object.assign; - // eslint-disable-next-line es/no-object-defineproperty -- required for testing - var defineProperty$5 = Object.defineProperty; - - // `Object.assign` method - // https://tc39.es/ecma262/#sec-object.assign - var objectAssign = !$assign || fails$r(function () { - // should have correct order of operations (Edge bug) - if (DESCRIPTORS$b && $assign({ b: 1 }, $assign(defineProperty$5({}, 'a', { - enumerable: true, - get: function () { - defineProperty$5(this, 'b', { - value: 3, - enumerable: false - }); - } - }), { b: 2 })).b !== 1) return true; - // should work with symbols and should have deterministic property order (V8 bug) - var A = {}; - var B = {}; - // eslint-disable-next-line es/no-symbol -- safe - var symbol = Symbol(); - var alphabet = 'abcdefghijklmnopqrst'; - A[symbol] = 7; - alphabet.split('').forEach(function (chr) { B[chr] = chr; }); - return $assign({}, A)[symbol] != 7 || objectKeys$1($assign({}, B)).join('') != alphabet; - }) ? function assign(target, source) { // eslint-disable-line no-unused-vars -- required for `.length` - var T = toObject$8(target); - var argumentsLength = arguments.length; - var index = 1; - var getOwnPropertySymbols = getOwnPropertySymbolsModule.f; - var propertyIsEnumerable = propertyIsEnumerableModule.f; - while (argumentsLength > index) { - var S = IndexedObject(arguments[index++]); - var keys = getOwnPropertySymbols ? objectKeys$1(S).concat(getOwnPropertySymbols(S)) : objectKeys$1(S); - var length = keys.length; - var j = 0; - var key; - while (length > j) { - key = keys[j++]; - if (!DESCRIPTORS$b || propertyIsEnumerable.call(S, key)) T[key] = S[key]; - } - } return T; - } : $assign; - - var anObject$a = anObject$m; - var iteratorClose = iteratorClose$2; - - // call something on iterator step with safe closing on error - var callWithSafeIterationClosing$1 = function (iterator, fn, value, ENTRIES) { - try { - return ENTRIES ? fn(anObject$a(value)[0], value[1]) : fn(value); - } catch (error) { - iteratorClose(iterator); - throw error; - } - }; - - var bind$6 = functionBindContext; - var toObject$7 = toObject$i; - var callWithSafeIterationClosing = callWithSafeIterationClosing$1; - var isArrayIteratorMethod = isArrayIteratorMethod$3; - var toLength$9 = toLength$q; - var createProperty$2 = createProperty$4; - var getIteratorMethod$2 = getIteratorMethod$5; - - // `Array.from` method implementation - // https://tc39.es/ecma262/#sec-array.from - var arrayFrom$1 = function from(arrayLike /* , mapfn = undefined, thisArg = undefined */) { - var O = toObject$7(arrayLike); - var C = typeof this == 'function' ? this : Array; - var argumentsLength = arguments.length; - var mapfn = argumentsLength > 1 ? arguments[1] : undefined; - var mapping = mapfn !== undefined; - var iteratorMethod = getIteratorMethod$2(O); - var index = 0; - var length, result, step, iterator, next, value; - if (mapping) mapfn = bind$6(mapfn, argumentsLength > 2 ? arguments[2] : undefined, 2); - // if the target is not iterable or it's an array with the default iterator - use a simple case - if (iteratorMethod != undefined && !(C == Array && isArrayIteratorMethod(iteratorMethod))) { - iterator = iteratorMethod.call(O); - next = iterator.next; - result = new C(); - for (;!(step = next.call(iterator)).done; index++) { - value = mapping ? callWithSafeIterationClosing(iterator, mapfn, [step.value, index], true) : step.value; - createProperty$2(result, index, value); - } - } else { - length = toLength$9(O.length); - result = new C(length); - for (;length > index; index++) { - value = mapping ? mapfn(O[index], index) : O[index]; - createProperty$2(result, index, value); - } - } - result.length = index; - return result; - }; - - // based on https://github.com/bestiejs/punycode.js/blob/master/punycode.js - var maxInt = 2147483647; // aka. 0x7FFFFFFF or 2^31-1 - var base = 36; - var tMin = 1; - var tMax = 26; - var skew = 38; - var damp = 700; - var initialBias = 72; - var initialN = 128; // 0x80 - var delimiter = '-'; // '\x2D' - var regexNonASCII = /[^\0-\u007E]/; // non-ASCII chars - var regexSeparators = /[.\u3002\uFF0E\uFF61]/g; // RFC 3490 separators - var OVERFLOW_ERROR = 'Overflow: input needs wider integers to process'; - var baseMinusTMin = base - tMin; - var floor$3 = Math.floor; - var stringFromCharCode = String.fromCharCode; - - /** - * Creates an array containing the numeric code points of each Unicode - * character in the string. While JavaScript uses UCS-2 internally, - * this function will convert a pair of surrogate halves (each of which - * UCS-2 exposes as separate characters) into a single code point, - * matching UTF-16. - */ - var ucs2decode = function (string) { - var output = []; - var counter = 0; - var length = string.length; - while (counter < length) { - var value = string.charCodeAt(counter++); - if (value >= 0xD800 && value <= 0xDBFF && counter < length) { - // It's a high surrogate, and there is a next character. - var extra = string.charCodeAt(counter++); - if ((extra & 0xFC00) == 0xDC00) { // Low surrogate. - output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000); - } else { - // It's an unmatched surrogate; only append this code unit, in case the - // next code unit is the high surrogate of a surrogate pair. - output.push(value); - counter--; - } - } else { - output.push(value); - } - } - return output; - }; - - /** - * Converts a digit/integer into a basic code point. - */ - var digitToBasic = function (digit) { - // 0..25 map to ASCII a..z or A..Z - // 26..35 map to ASCII 0..9 - return digit + 22 + 75 * (digit < 26); - }; - - /** - * Bias adaptation function as per section 3.4 of RFC 3492. - * https://tools.ietf.org/html/rfc3492#section-3.4 - */ - var adapt = function (delta, numPoints, firstTime) { - var k = 0; - delta = firstTime ? floor$3(delta / damp) : delta >> 1; - delta += floor$3(delta / numPoints); - for (; delta > baseMinusTMin * tMax >> 1; k += base) { - delta = floor$3(delta / baseMinusTMin); - } - return floor$3(k + (baseMinusTMin + 1) * delta / (delta + skew)); - }; - - /** - * Converts a string of Unicode symbols (e.g. a domain name label) to a - * Punycode string of ASCII-only symbols. - */ - // eslint-disable-next-line max-statements -- TODO - var encode = function (input) { - var output = []; - - // Convert the input in UCS-2 to an array of Unicode code points. - input = ucs2decode(input); - - // Cache the length. - var inputLength = input.length; - - // Initialize the state. - var n = initialN; - var delta = 0; - var bias = initialBias; - var i, currentValue; - - // Handle the basic code points. - for (i = 0; i < input.length; i++) { - currentValue = input[i]; - if (currentValue < 0x80) { - output.push(stringFromCharCode(currentValue)); - } - } - - var basicLength = output.length; // number of basic code points. - var handledCPCount = basicLength; // number of code points that have been handled; - - // Finish the basic string with a delimiter unless it's empty. - if (basicLength) { - output.push(delimiter); - } - - // Main encoding loop: - while (handledCPCount < inputLength) { - // All non-basic code points < n have been handled already. Find the next larger one: - var m = maxInt; - for (i = 0; i < input.length; i++) { - currentValue = input[i]; - if (currentValue >= n && currentValue < m) { - m = currentValue; - } - } - - // Increase `delta` enough to advance the decoder's state to , but guard against overflow. - var handledCPCountPlusOne = handledCPCount + 1; - if (m - n > floor$3((maxInt - delta) / handledCPCountPlusOne)) { - throw RangeError(OVERFLOW_ERROR); - } - - delta += (m - n) * handledCPCountPlusOne; - n = m; - - for (i = 0; i < input.length; i++) { - currentValue = input[i]; - if (currentValue < n && ++delta > maxInt) { - throw RangeError(OVERFLOW_ERROR); - } - if (currentValue == n) { - // Represent delta as a generalized variable-length integer. - var q = delta; - for (var k = base; /* no condition */; k += base) { - var t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); - if (q < t) break; - var qMinusT = q - t; - var baseMinusT = base - t; - output.push(stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT))); - q = floor$3(qMinusT / baseMinusT); - } - - output.push(stringFromCharCode(digitToBasic(q))); - bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength); - delta = 0; - ++handledCPCount; - } - } - - ++delta; - ++n; - } - return output.join(''); - }; - - var stringPunycodeToAscii = function (input) { - var encoded = []; - var labels = input.toLowerCase().replace(regexSeparators, '\u002E').split('.'); - var i, label; - for (i = 0; i < labels.length; i++) { - label = labels[i]; - encoded.push(regexNonASCII.test(label) ? 'xn--' + encode(label) : label); - } - return encoded.join('.'); - }; - - var anObject$9 = anObject$m; - var getIteratorMethod$1 = getIteratorMethod$5; - - var getIterator$1 = function (it) { - var iteratorMethod = getIteratorMethod$1(it); - if (typeof iteratorMethod != 'function') { - throw TypeError(String(it) + ' is not iterable'); - } return anObject$9(iteratorMethod.call(it)); - }; - // TODO: in core-js@4, move /modules/ dependencies to public entries for better optimization by tools like `preset-env` - var $$R = _export; - var getBuiltIn$2 = getBuiltIn$9; + var $$X = _export; + var global$n = global$1m; + var getBuiltIn$2 = getBuiltIn$b; + var call$a = functionCall; + var uncurryThis$u = functionUncurryThis; var USE_NATIVE_URL$1 = nativeUrl; - var redefine$7 = redefine$g.exports; + var redefine$7 = redefine$h.exports; var redefineAll$1 = redefineAll$4; var setToStringTag$4 = setToStringTag$a; var createIteratorConstructor = createIteratorConstructor$2; var InternalStateModule$2 = internalState; var anInstance$3 = anInstance$7; - var hasOwn = has$j; - var bind$5 = functionBindContext; - var classof$4 = classof$b; - var anObject$8 = anObject$m; - var isObject$c = isObject$r; - var create$8 = objectCreate; + var isCallable$5 = isCallable$r; + var hasOwn$6 = hasOwnProperty_1; + var bind$8 = functionBindContext; + var classof$3 = classof$d; + var anObject$9 = anObject$n; + var isObject$d = isObject$s; + var $toString$2 = toString$k; + var create$6 = objectCreate; var createPropertyDescriptor = createPropertyDescriptor$7; - var getIterator = getIterator$1; - var getIteratorMethod = getIteratorMethod$5; - var wellKnownSymbol$6 = wellKnownSymbol$s; + var getIterator$1 = getIterator$4; + var getIteratorMethod$1 = getIteratorMethod$5; + var wellKnownSymbol$6 = wellKnownSymbol$t; + var arraySort = arraySort$1; - var $fetch = getBuiltIn$2('fetch'); - var Headers$1 = getBuiltIn$2('Headers'); - var ITERATOR = wellKnownSymbol$6('iterator'); + var ITERATOR$2 = wellKnownSymbol$6('iterator'); var URL_SEARCH_PARAMS = 'URLSearchParams'; var URL_SEARCH_PARAMS_ITERATOR = URL_SEARCH_PARAMS + 'Iterator'; var setInternalState$2 = InternalStateModule$2.set; var getInternalParamsState = InternalStateModule$2.getterFor(URL_SEARCH_PARAMS); var getInternalIteratorState = InternalStateModule$2.getterFor(URL_SEARCH_PARAMS_ITERATOR); + var n$Fetch = getBuiltIn$2('fetch'); + var N$Request = getBuiltIn$2('Request'); + var Headers$1 = getBuiltIn$2('Headers'); + var RequestPrototype = N$Request && N$Request.prototype; + var HeadersPrototype = Headers$1 && Headers$1.prototype; + var RegExp$1 = global$n.RegExp; + var TypeError$8 = global$n.TypeError; + var decodeURIComponent$1 = global$n.decodeURIComponent; + var encodeURIComponent$1 = global$n.encodeURIComponent; + var charAt$5 = uncurryThis$u(''.charAt); + var join$4 = uncurryThis$u([].join); + var push$7 = uncurryThis$u([].push); + var replace$6 = uncurryThis$u(''.replace); + var shift$1 = uncurryThis$u([].shift); + var splice = uncurryThis$u([].splice); + var split$3 = uncurryThis$u(''.split); + var stringSlice$8 = uncurryThis$u(''.slice); + var plus = /\+/g; var sequences = Array(4); var percentSequence = function (bytes) { - return sequences[bytes - 1] || (sequences[bytes - 1] = RegExp('((?:%[\\da-f]{2}){' + bytes + '})', 'gi')); + return sequences[bytes - 1] || (sequences[bytes - 1] = RegExp$1('((?:%[\\da-f]{2}){' + bytes + '})', 'gi')); }; var percentDecode = function (sequence) { try { - return decodeURIComponent(sequence); + return decodeURIComponent$1(sequence); } catch (error) { return sequence; } }; var deserialize = function (it) { - var result = it.replace(plus, ' '); + var result = replace$6(it, plus, ' '); var bytes = 4; try { - return decodeURIComponent(result); + return decodeURIComponent$1(result); } catch (error) { while (bytes) { - result = result.replace(percentSequence(bytes--), percentDecode); + result = replace$6(result, percentSequence(bytes--), percentDecode); } return result; } @@ -5009,7 +5465,7 @@ var find$1 = /[!'()~]|%20/g; - var replace$1 = { + var replacements = { '!': '%21', "'": '%27', '(': '%28', @@ -5019,25 +5475,25 @@ }; var replacer = function (match) { - return replace$1[match]; + return replacements[match]; }; var serialize = function (it) { - return encodeURIComponent(it).replace(find$1, replacer); + return replace$6(encodeURIComponent$1(it), find$1, replacer); }; var parseSearchParams = function (result, query) { if (query) { - var attributes = query.split('&'); + var attributes = split$3(query, '&'); var index = 0; var attribute, entry; while (index < attributes.length) { attribute = attributes[index++]; if (attribute.length) { - entry = attribute.split('='); - result.push({ - key: deserialize(entry.shift()), - value: deserialize(entry.join('=')) + entry = split$3(attribute, '='); + push$7(result, { + key: deserialize(shift$1(entry)), + value: deserialize(join$4(entry, '=')) }); } } @@ -5050,13 +5506,13 @@ }; var validateArgumentsLength = function (passed, required) { - if (passed < required) throw TypeError('Not enough arguments'); + if (passed < required) throw TypeError$8('Not enough arguments'); }; var URLSearchParamsIterator = createIteratorConstructor(function Iterator(params, kind) { setInternalState$2(this, { type: URL_SEARCH_PARAMS_ITERATOR, - iterator: getIterator(getInternalParamsState(params).entries), + iterator: getIterator$1(getInternalParamsState(params).entries), kind: kind }); }, 'Iterator', function next() { @@ -5072,7 +5528,7 @@ // `URLSearchParams` constructor // https://url.spec.whatwg.org/#interface-urlsearchparams var URLSearchParamsConstructor = function URLSearchParams(/* init */) { - anInstance$3(this, URLSearchParamsConstructor, URL_SEARCH_PARAMS); + anInstance$3(this, URLSearchParamsPrototype); var init = arguments.length > 0 ? arguments[0] : undefined; var that = this; var entries = []; @@ -5086,24 +5542,27 @@ }); if (init !== undefined) { - if (isObject$c(init)) { - iteratorMethod = getIteratorMethod(init); - if (typeof iteratorMethod === 'function') { - iterator = iteratorMethod.call(init); + if (isObject$d(init)) { + iteratorMethod = getIteratorMethod$1(init); + if (iteratorMethod) { + iterator = getIterator$1(init, iteratorMethod); next = iterator.next; - while (!(step = next.call(iterator)).done) { - entryIterator = getIterator(anObject$8(step.value)); + while (!(step = call$a(next, iterator)).done) { + entryIterator = getIterator$1(anObject$9(step.value)); entryNext = entryIterator.next; if ( - (first = entryNext.call(entryIterator)).done || - (second = entryNext.call(entryIterator)).done || - !entryNext.call(entryIterator).done - ) throw TypeError('Expected sequence with length 2'); - entries.push({ key: first.value + '', value: second.value + '' }); + (first = call$a(entryNext, entryIterator)).done || + (second = call$a(entryNext, entryIterator)).done || + !call$a(entryNext, entryIterator).done + ) throw TypeError$8('Expected sequence with length 2'); + push$7(entries, { key: $toString$2(first.value), value: $toString$2(second.value) }); } - } else for (key in init) if (hasOwn(init, key)) entries.push({ key: key, value: init[key] + '' }); + } else for (key in init) if (hasOwn$6(init, key)) push$7(entries, { key: key, value: $toString$2(init[key]) }); } else { - parseSearchParams(entries, typeof init === 'string' ? init.charAt(0) === '?' ? init.slice(1) : init : init + ''); + parseSearchParams( + entries, + typeof init == 'string' ? charAt$5(init, 0) === '?' ? stringSlice$8(init, 1) : init : $toString$2(init) + ); } } }; @@ -5116,7 +5575,7 @@ append: function append(name, value) { validateArgumentsLength(arguments.length, 2); var state = getInternalParamsState(this); - state.entries.push({ key: name + '', value: value + '' }); + push$7(state.entries, { key: $toString$2(name), value: $toString$2(value) }); state.updateURL(); }, // `URLSearchParams.prototype.delete` method @@ -5125,10 +5584,10 @@ validateArgumentsLength(arguments.length, 1); var state = getInternalParamsState(this); var entries = state.entries; - var key = name + ''; + var key = $toString$2(name); var index = 0; while (index < entries.length) { - if (entries[index].key === key) entries.splice(index, 1); + if (entries[index].key === key) splice(entries, index, 1); else index++; } state.updateURL(); @@ -5138,7 +5597,7 @@ get: function get(name) { validateArgumentsLength(arguments.length, 1); var entries = getInternalParamsState(this).entries; - var key = name + ''; + var key = $toString$2(name); var index = 0; for (; index < entries.length; index++) { if (entries[index].key === key) return entries[index].value; @@ -5150,11 +5609,11 @@ getAll: function getAll(name) { validateArgumentsLength(arguments.length, 1); var entries = getInternalParamsState(this).entries; - var key = name + ''; + var key = $toString$2(name); var result = []; var index = 0; for (; index < entries.length; index++) { - if (entries[index].key === key) result.push(entries[index].value); + if (entries[index].key === key) push$7(result, entries[index].value); } return result; }, @@ -5163,7 +5622,7 @@ has: function has(name) { validateArgumentsLength(arguments.length, 1); var entries = getInternalParamsState(this).entries; - var key = name + ''; + var key = $toString$2(name); var index = 0; while (index < entries.length) { if (entries[index++].key === key) return true; @@ -5177,48 +5636,36 @@ var state = getInternalParamsState(this); var entries = state.entries; var found = false; - var key = name + ''; - var val = value + ''; + var key = $toString$2(name); + var val = $toString$2(value); var index = 0; var entry; for (; index < entries.length; index++) { entry = entries[index]; if (entry.key === key) { - if (found) entries.splice(index--, 1); + if (found) splice(entries, index--, 1); else { found = true; entry.value = val; } } } - if (!found) entries.push({ key: key, value: val }); + if (!found) push$7(entries, { key: key, value: val }); state.updateURL(); }, // `URLSearchParams.prototype.sort` method // https://url.spec.whatwg.org/#dom-urlsearchparams-sort sort: function sort() { var state = getInternalParamsState(this); - var entries = state.entries; - // Array#sort is not stable in some engines - var slice = entries.slice(); - var entry, entriesIndex, sliceIndex; - entries.length = 0; - for (sliceIndex = 0; sliceIndex < slice.length; sliceIndex++) { - entry = slice[sliceIndex]; - for (entriesIndex = 0; entriesIndex < sliceIndex; entriesIndex++) { - if (entries[entriesIndex].key > entry.key) { - entries.splice(entriesIndex, 0, entry); - break; - } - } - if (entriesIndex === sliceIndex) entries.push(entry); - } + arraySort(state.entries, function (a, b) { + return a.key > b.key ? 1 : -1; + }); state.updateURL(); }, // `URLSearchParams.prototype.forEach` method forEach: function forEach(callback /* , thisArg */) { var entries = getInternalParamsState(this).entries; - var boundFunction = bind$5(callback, arguments.length > 1 ? arguments[1] : undefined, 3); + var boundFunction = bind$8(callback, arguments.length > 1 ? arguments[1] : undefined); var index = 0; var entry; while (index < entries.length) { @@ -5241,7 +5688,7 @@ }, { enumerable: true }); // `URLSearchParams.prototype[@@iterator]` method - redefine$7(URLSearchParamsPrototype, ITERATOR, URLSearchParamsPrototype.entries); + redefine$7(URLSearchParamsPrototype, ITERATOR$2, URLSearchParamsPrototype.entries, { name: 'entries' }); // `URLSearchParams.prototype.toString` method // https://url.spec.whatwg.org/#urlsearchparams-stringification-behavior @@ -5252,42 +5699,59 @@ var entry; while (index < entries.length) { entry = entries[index++]; - result.push(serialize(entry.key) + '=' + serialize(entry.value)); - } return result.join('&'); + push$7(result, serialize(entry.key) + '=' + serialize(entry.value)); + } return join$4(result, '&'); }, { enumerable: true }); setToStringTag$4(URLSearchParamsConstructor, URL_SEARCH_PARAMS); - $$R({ global: true, forced: !USE_NATIVE_URL$1 }, { + $$X({ global: true, forced: !USE_NATIVE_URL$1 }, { URLSearchParams: URLSearchParamsConstructor }); - // Wrap `fetch` for correct work with polyfilled `URLSearchParams` - // https://github.com/zloirock/core-js/issues/674 - if (!USE_NATIVE_URL$1 && typeof $fetch == 'function' && typeof Headers$1 == 'function') { - $$R({ global: true, enumerable: true, forced: true }, { - fetch: function fetch(input /* , init */) { - var args = [input]; - var init, body, headers; - if (arguments.length > 1) { - init = arguments[1]; - if (isObject$c(init)) { - body = init.body; - if (classof$4(body) === URL_SEARCH_PARAMS) { - headers = init.headers ? new Headers$1(init.headers) : new Headers$1(); - if (!headers.has('content-type')) { - headers.set('content-type', 'application/x-www-form-urlencoded;charset=UTF-8'); - } - init = create$8(init, { - body: createPropertyDescriptor(0, String(body)), - headers: createPropertyDescriptor(0, headers) - }); - } - } - args.push(init); - } return $fetch.apply(this, args); - } - }); + // Wrap `fetch` and `Request` for correct work with polyfilled `URLSearchParams` + if (!USE_NATIVE_URL$1 && isCallable$5(Headers$1)) { + var headersHas = uncurryThis$u(HeadersPrototype.has); + var headersSet = uncurryThis$u(HeadersPrototype.set); + + var wrapRequestOptions = function (init) { + if (isObject$d(init)) { + var body = init.body; + var headers; + if (classof$3(body) === URL_SEARCH_PARAMS) { + headers = init.headers ? new Headers$1(init.headers) : new Headers$1(); + if (!headersHas(headers, 'content-type')) { + headersSet(headers, 'content-type', 'application/x-www-form-urlencoded;charset=UTF-8'); + } + return create$6(init, { + body: createPropertyDescriptor(0, $toString$2(body)), + headers: createPropertyDescriptor(0, headers) + }); + } + } return init; + }; + + if (isCallable$5(n$Fetch)) { + $$X({ global: true, enumerable: true, forced: true }, { + fetch: function fetch(input /* , init */) { + return n$Fetch(input, arguments.length > 1 ? wrapRequestOptions(arguments[1]) : {}); + } + }); + } + + if (isCallable$5(N$Request)) { + var RequestConstructor = function Request(input /* , init */) { + anInstance$3(this, RequestPrototype); + return new N$Request(input, arguments.length > 1 ? wrapRequestOptions(arguments[1]) : {}); + }; + + RequestPrototype.constructor = RequestConstructor; + RequestConstructor.prototype = RequestPrototype; + + $$X({ global: true, forced: true }, { + Request: RequestConstructor + }); + } } var web_urlSearchParams = { @@ -5295,4619 +5759,3634 @@ getState: getInternalParamsState }; - // TODO: in core-js@4, move /modules/ dependencies to public entries for better optimization by tools like `preset-env` + var uncurryThis$t = functionUncurryThis; + var PROPER_FUNCTION_NAME$1 = functionName.PROPER; + var redefine$6 = redefine$h.exports; + var anObject$8 = anObject$n; + var isPrototypeOf$2 = objectIsPrototypeOf; + var $toString$1 = toString$k; + var fails$s = fails$S; + var regExpFlags$2 = regexpFlags$1; - var $$Q = _export; - var DESCRIPTORS$a = descriptors; - var USE_NATIVE_URL = nativeUrl; - var global$a = global$F; - var defineProperties$1 = objectDefineProperties; - var redefine$6 = redefine$g.exports; - var anInstance$2 = anInstance$7; - var has$4 = has$j; - var assign$2 = objectAssign; - var arrayFrom = arrayFrom$1; - var codeAt = stringMultibyte.codeAt; - var toASCII = stringPunycodeToAscii; - var setToStringTag$3 = setToStringTag$a; - var URLSearchParamsModule = web_urlSearchParams; - var InternalStateModule$1 = internalState; + var TO_STRING = 'toString'; + var RegExpPrototype$3 = RegExp.prototype; + var n$ToString = RegExpPrototype$3[TO_STRING]; + var getFlags$1 = uncurryThis$t(regExpFlags$2); - var NativeURL = global$a.URL; - var URLSearchParams$1 = URLSearchParamsModule.URLSearchParams; - var getInternalSearchParamsState = URLSearchParamsModule.getState; - var setInternalState$1 = InternalStateModule$1.set; - var getInternalURLState = InternalStateModule$1.getterFor('URL'); - var floor$2 = Math.floor; - var pow$1 = Math.pow; + var NOT_GENERIC = fails$s(function () { return n$ToString.call({ source: 'a', flags: 'b' }) != '/a/b'; }); + // FF44- RegExp#toString has a wrong name + var INCORRECT_NAME = PROPER_FUNCTION_NAME$1 && n$ToString.name != TO_STRING; - var INVALID_AUTHORITY = 'Invalid authority'; - var INVALID_SCHEME = 'Invalid scheme'; - var INVALID_HOST = 'Invalid host'; - var INVALID_PORT = 'Invalid port'; + // `RegExp.prototype.toString` method + // https://tc39.es/ecma262/#sec-regexp.prototype.tostring + if (NOT_GENERIC || INCORRECT_NAME) { + redefine$6(RegExp.prototype, TO_STRING, function toString() { + var R = anObject$8(this); + var p = $toString$1(R.source); + var rf = R.flags; + var f = $toString$1(rf === undefined && isPrototypeOf$2(RegExpPrototype$3, R) && !('flags' in RegExpPrototype$3) ? getFlags$1(R) : rf); + return '/' + p + '/' + f; + }, { unsafe: true }); + } - var ALPHA = /[A-Za-z]/; - // eslint-disable-next-line regexp/no-obscure-range -- safe - var ALPHANUMERIC = /[\d+-.A-Za-z]/; - var DIGIT = /\d/; - var HEX_START = /^0x/i; - var OCT = /^[0-7]+$/; - var DEC = /^\d+$/; - var HEX = /^[\dA-Fa-f]+$/; - /* eslint-disable no-control-regex -- safe */ - var FORBIDDEN_HOST_CODE_POINT = /[\0\t\n\r #%/:<>?@[\\\]^|]/; - var FORBIDDEN_HOST_CODE_POINT_EXCLUDING_PERCENT = /[\0\t\n\r #/:<>?@[\\\]^|]/; - var LEADING_AND_TRAILING_C0_CONTROL_OR_SPACE = /^[\u0000-\u001F ]+|[\u0000-\u001F ]+$/g; - var TAB_AND_NEW_LINE = /[\t\n\r]/g; - /* eslint-enable no-control-regex -- safe */ - var EOF; + // TODO: Remove from `core-js@4` since it's moved to entry points - var parseHost = function (url, input) { - var result, codePoints, index; - if (input.charAt(0) == '[') { - if (input.charAt(input.length - 1) != ']') return INVALID_HOST; - result = parseIPv6(input.slice(1, -1)); - if (!result) return INVALID_HOST; - url.host = result; - // opaque host - } else if (!isSpecial(url)) { - if (FORBIDDEN_HOST_CODE_POINT_EXCLUDING_PERCENT.test(input)) return INVALID_HOST; - result = ''; - codePoints = arrayFrom(input); - for (index = 0; index < codePoints.length; index++) { - result += percentEncode(codePoints[index], C0ControlPercentEncodeSet); - } - url.host = result; - } else { - input = toASCII(input); - if (FORBIDDEN_HOST_CODE_POINT.test(input)) return INVALID_HOST; - result = parseIPv4(input); - if (result === null) return INVALID_HOST; - url.host = result; - } - }; + var uncurryThis$s = functionUncurryThis; + var redefine$5 = redefine$h.exports; + var regexpExec$2 = regexpExec$3; + var fails$r = fails$S; + var wellKnownSymbol$5 = wellKnownSymbol$t; + var createNonEnumerableProperty$1 = createNonEnumerableProperty$b; - var parseIPv4 = function (input) { - var parts = input.split('.'); - var partsLength, numbers, index, part, radix, number, ipv4; - if (parts.length && parts[parts.length - 1] == '') { - parts.pop(); - } - partsLength = parts.length; - if (partsLength > 4) return input; - numbers = []; - for (index = 0; index < partsLength; index++) { - part = parts[index]; - if (part == '') return input; - radix = 10; - if (part.length > 1 && part.charAt(0) == '0') { - radix = HEX_START.test(part) ? 16 : 8; - part = part.slice(radix == 8 ? 1 : 2); - } - if (part === '') { - number = 0; - } else { - if (!(radix == 10 ? DEC : radix == 8 ? OCT : HEX).test(part)) return input; - number = parseInt(part, radix); - } - numbers.push(number); - } - for (index = 0; index < partsLength; index++) { - number = numbers[index]; - if (index == partsLength - 1) { - if (number >= pow$1(256, 5 - partsLength)) return null; - } else if (number > 255) return null; - } - ipv4 = numbers.pop(); - for (index = 0; index < numbers.length; index++) { - ipv4 += numbers[index] * pow$1(256, 3 - index); - } - return ipv4; - }; + var SPECIES = wellKnownSymbol$5('species'); + var RegExpPrototype$2 = RegExp.prototype; - // eslint-disable-next-line max-statements -- TODO - var parseIPv6 = function (input) { - var address = [0, 0, 0, 0, 0, 0, 0, 0]; - var pieceIndex = 0; - var compress = null; - var pointer = 0; - var value, length, numbersSeen, ipv4Piece, number, swaps, swap; + var fixRegexpWellKnownSymbolLogic = function (KEY, exec, FORCED, SHAM) { + var SYMBOL = wellKnownSymbol$5(KEY); - var char = function () { - return input.charAt(pointer); - }; + var DELEGATES_TO_SYMBOL = !fails$r(function () { + // String methods call symbol-named RegEp methods + var O = {}; + O[SYMBOL] = function () { return 7; }; + return ''[KEY](O) != 7; + }); - if (char() == ':') { - if (input.charAt(1) != ':') return; - pointer += 2; - pieceIndex++; - compress = pieceIndex; - } - while (char()) { - if (pieceIndex == 8) return; - if (char() == ':') { - if (compress !== null) return; - pointer++; - pieceIndex++; - compress = pieceIndex; - continue; - } - value = length = 0; - while (length < 4 && HEX.test(char())) { - value = value * 16 + parseInt(char(), 16); - pointer++; - length++; + var DELEGATES_TO_EXEC = DELEGATES_TO_SYMBOL && !fails$r(function () { + // Symbol-named RegExp methods call .exec + var execCalled = false; + var re = /a/; + + if (KEY === 'split') { + // We can't use real regex here since it causes deoptimization + // and serious performance degradation in V8 + // https://github.com/zloirock/core-js/issues/306 + re = {}; + // RegExp[@@split] doesn't call the regex's exec method, but first creates + // a new one. We need to return the patched regex when creating the new one. + re.constructor = {}; + re.constructor[SPECIES] = function () { return re; }; + re.flags = ''; + re[SYMBOL] = /./[SYMBOL]; } - if (char() == '.') { - if (length == 0) return; - pointer -= length; - if (pieceIndex > 6) return; - numbersSeen = 0; - while (char()) { - ipv4Piece = null; - if (numbersSeen > 0) { - if (char() == '.' && numbersSeen < 4) pointer++; - else return; - } - if (!DIGIT.test(char())) return; - while (DIGIT.test(char())) { - number = parseInt(char(), 10); - if (ipv4Piece === null) ipv4Piece = number; - else if (ipv4Piece == 0) return; - else ipv4Piece = ipv4Piece * 10 + number; - if (ipv4Piece > 255) return; - pointer++; + + re.exec = function () { execCalled = true; return null; }; + + re[SYMBOL](''); + return !execCalled; + }); + + if ( + !DELEGATES_TO_SYMBOL || + !DELEGATES_TO_EXEC || + FORCED + ) { + var uncurriedNativeRegExpMethod = uncurryThis$s(/./[SYMBOL]); + var methods = exec(SYMBOL, ''[KEY], function (nativeMethod, regexp, str, arg2, forceStringMethod) { + var uncurriedNativeMethod = uncurryThis$s(nativeMethod); + var $exec = regexp.exec; + if ($exec === regexpExec$2 || $exec === RegExpPrototype$2.exec) { + if (DELEGATES_TO_SYMBOL && !forceStringMethod) { + // The native String method already delegates to @@method (this + // polyfilled function), leasing to infinite recursion. + // We avoid it by directly calling the native @@method method. + return { done: true, value: uncurriedNativeRegExpMethod(regexp, str, arg2) }; } - address[pieceIndex] = address[pieceIndex] * 256 + ipv4Piece; - numbersSeen++; - if (numbersSeen == 2 || numbersSeen == 4) pieceIndex++; + return { done: true, value: uncurriedNativeMethod(str, regexp, arg2) }; } - if (numbersSeen != 4) return; - break; - } else if (char() == ':') { - pointer++; - if (!char()) return; - } else if (char()) return; - address[pieceIndex++] = value; - } - if (compress !== null) { - swaps = pieceIndex - compress; - pieceIndex = 7; - while (pieceIndex != 0 && swaps > 0) { - swap = address[pieceIndex]; - address[pieceIndex--] = address[compress + swaps - 1]; - address[compress + --swaps] = swap; - } - } else if (pieceIndex != 8) return; - return address; - }; + return { done: false }; + }); - var findLongestZeroSequence = function (ipv6) { - var maxIndex = null; - var maxLength = 1; - var currStart = null; - var currLength = 0; - var index = 0; - for (; index < 8; index++) { - if (ipv6[index] !== 0) { - if (currLength > maxLength) { - maxIndex = currStart; - maxLength = currLength; - } - currStart = null; - currLength = 0; - } else { - if (currStart === null) currStart = index; - ++currLength; - } - } - if (currLength > maxLength) { - maxIndex = currStart; - maxLength = currLength; + redefine$5(String.prototype, KEY, methods[0]); + redefine$5(RegExpPrototype$2, SYMBOL, methods[1]); } - return maxIndex; - }; - var serializeHost = function (host) { - var result, index, compress, ignore0; - // ipv4 - if (typeof host == 'number') { - result = []; - for (index = 0; index < 4; index++) { - result.unshift(host % 256); - host = floor$2(host / 256); - } return result.join('.'); - // ipv6 - } else if (typeof host == 'object') { - result = ''; - compress = findLongestZeroSequence(host); - for (index = 0; index < 8; index++) { - if (ignore0 && host[index] === 0) continue; - if (ignore0) ignore0 = false; - if (compress === index) { - result += index ? ':' : '::'; - ignore0 = true; - } else { - result += host[index].toString(16); - if (index < 7) result += ':'; - } - } - return '[' + result + ']'; - } return host; + if (SHAM) createNonEnumerableProperty$1(RegExpPrototype$2[SYMBOL], 'sham', true); }; - var C0ControlPercentEncodeSet = {}; - var fragmentPercentEncodeSet = assign$2({}, C0ControlPercentEncodeSet, { - ' ': 1, '"': 1, '<': 1, '>': 1, '`': 1 - }); - var pathPercentEncodeSet = assign$2({}, fragmentPercentEncodeSet, { - '#': 1, '?': 1, '{': 1, '}': 1 - }); - var userinfoPercentEncodeSet = assign$2({}, pathPercentEncodeSet, { - '/': 1, ':': 1, ';': 1, '=': 1, '@': 1, '[': 1, '\\': 1, ']': 1, '^': 1, '|': 1 - }); - - var percentEncode = function (char, set) { - var code = codeAt(char, 0); - return code > 0x20 && code < 0x7F && !has$4(set, char) ? char : encodeURIComponent(char); - }; + var charAt$4 = stringMultibyte.charAt; - var specialSchemes = { - ftp: 21, - file: null, - http: 80, - https: 443, - ws: 80, - wss: 443 + // `AdvanceStringIndex` abstract operation + // https://tc39.es/ecma262/#sec-advancestringindex + var advanceStringIndex$3 = function (S, index, unicode) { + return index + (unicode ? charAt$4(S, index).length : 1); }; - var isSpecial = function (url) { - return has$4(specialSchemes, url.scheme); - }; + var uncurryThis$r = functionUncurryThis; + var toObject$9 = toObject$j; - var includesCredentials = function (url) { - return url.username != '' || url.password != ''; - }; + var floor$3 = Math.floor; + var charAt$3 = uncurryThis$r(''.charAt); + var replace$5 = uncurryThis$r(''.replace); + var stringSlice$7 = uncurryThis$r(''.slice); + var SUBSTITUTION_SYMBOLS = /\$([$&'`]|\d{1,2}|<[^>]*>)/g; + var SUBSTITUTION_SYMBOLS_NO_NAMED = /\$([$&'`]|\d{1,2})/g; - var cannotHaveUsernamePasswordPort = function (url) { - return !url.host || url.cannotBeABaseURL || url.scheme == 'file'; + // `GetSubstitution` abstract operation + // https://tc39.es/ecma262/#sec-getsubstitution + var getSubstitution$1 = function (matched, str, position, captures, namedCaptures, replacement) { + var tailPos = position + matched.length; + var m = captures.length; + var symbols = SUBSTITUTION_SYMBOLS_NO_NAMED; + if (namedCaptures !== undefined) { + namedCaptures = toObject$9(namedCaptures); + symbols = SUBSTITUTION_SYMBOLS; + } + return replace$5(replacement, symbols, function (match, ch) { + var capture; + switch (charAt$3(ch, 0)) { + case '$': return '$'; + case '&': return matched; + case '`': return stringSlice$7(str, 0, position); + case "'": return stringSlice$7(str, tailPos); + case '<': + capture = namedCaptures[stringSlice$7(ch, 1, -1)]; + break; + default: // \d\d? + var n = +ch; + if (n === 0) return match; + if (n > m) { + var f = floor$3(n / 10); + if (f === 0) return match; + if (f <= m) return captures[f - 1] === undefined ? charAt$3(ch, 1) : captures[f - 1] + charAt$3(ch, 1); + return match; + } + capture = captures[n - 1]; + } + return capture === undefined ? '' : capture; + }); }; - var isWindowsDriveLetter = function (string, normalized) { - var second; - return string.length == 2 && ALPHA.test(string.charAt(0)) - && ((second = string.charAt(1)) == ':' || (!normalized && second == '|')); - }; + var global$m = global$1m; + var call$9 = functionCall; + var anObject$7 = anObject$n; + var isCallable$4 = isCallable$r; + var classof$2 = classofRaw$1; + var regexpExec$1 = regexpExec$3; - var startsWithWindowsDriveLetter = function (string) { - var third; - return string.length > 1 && isWindowsDriveLetter(string.slice(0, 2)) && ( - string.length == 2 || - ((third = string.charAt(2)) === '/' || third === '\\' || third === '?' || third === '#') - ); - }; + var TypeError$7 = global$m.TypeError; - var shortenURLsPath = function (url) { - var path = url.path; - var pathSize = path.length; - if (pathSize && (url.scheme != 'file' || pathSize != 1 || !isWindowsDriveLetter(path[0], true))) { - path.pop(); + // `RegExpExec` abstract operation + // https://tc39.es/ecma262/#sec-regexpexec + var regexpExecAbstract = function (R, S) { + var exec = R.exec; + if (isCallable$4(exec)) { + var result = call$9(exec, R, S); + if (result !== null) anObject$7(result); + return result; } + if (classof$2(R) === 'RegExp') return call$9(regexpExec$1, R, S); + throw TypeError$7('RegExp#exec called on incompatible receiver'); }; - var isSingleDot = function (segment) { - return segment === '.' || segment.toLowerCase() === '%2e'; - }; + var apply$3 = functionApply; + var call$8 = functionCall; + var uncurryThis$q = functionUncurryThis; + var fixRegExpWellKnownSymbolLogic$3 = fixRegexpWellKnownSymbolLogic; + var fails$q = fails$S; + var anObject$6 = anObject$n; + var isCallable$3 = isCallable$r; + var toIntegerOrInfinity$3 = toIntegerOrInfinity$b; + var toLength$5 = toLength$c; + var toString$f = toString$k; + var requireObjectCoercible$a = requireObjectCoercible$e; + var advanceStringIndex$2 = advanceStringIndex$3; + var getMethod$3 = getMethod$7; + var getSubstitution = getSubstitution$1; + var regExpExec$3 = regexpExecAbstract; + var wellKnownSymbol$4 = wellKnownSymbol$t; - var isDoubleDot = function (segment) { - segment = segment.toLowerCase(); - return segment === '..' || segment === '%2e.' || segment === '.%2e' || segment === '%2e%2e'; - }; + var REPLACE = wellKnownSymbol$4('replace'); + var max$2 = Math.max; + var min$5 = Math.min; + var concat$2 = uncurryThis$q([].concat); + var push$6 = uncurryThis$q([].push); + var stringIndexOf$2 = uncurryThis$q(''.indexOf); + var stringSlice$6 = uncurryThis$q(''.slice); - // States: - var SCHEME_START = {}; - var SCHEME = {}; - var NO_SCHEME = {}; - var SPECIAL_RELATIVE_OR_AUTHORITY = {}; - var PATH_OR_AUTHORITY = {}; - var RELATIVE = {}; - var RELATIVE_SLASH = {}; - var SPECIAL_AUTHORITY_SLASHES = {}; - var SPECIAL_AUTHORITY_IGNORE_SLASHES = {}; - var AUTHORITY = {}; - var HOST = {}; - var HOSTNAME = {}; - var PORT = {}; - var FILE = {}; - var FILE_SLASH = {}; - var FILE_HOST = {}; - var PATH_START = {}; - var PATH = {}; - var CANNOT_BE_A_BASE_URL_PATH = {}; - var QUERY = {}; - var FRAGMENT = {}; + var maybeToString = function (it) { + return it === undefined ? it : String(it); + }; - // eslint-disable-next-line max-statements -- TODO - var parseURL = function (url, input, stateOverride, base) { - var state = stateOverride || SCHEME_START; - var pointer = 0; - var buffer = ''; - var seenAt = false; - var seenBracket = false; - var seenPasswordToken = false; - var codePoints, char, bufferCodePoints, failure; + // IE <= 11 replaces $0 with the whole match, as if it was $& + // https://stackoverflow.com/questions/6024666/getting-ie-to-replace-a-regex-with-the-literal-string-0 + var REPLACE_KEEPS_$0 = (function () { + // eslint-disable-next-line regexp/prefer-escape-replacement-dollar-char -- required for testing + return 'a'.replace(/./, '$0') === '$0'; + })(); - if (!stateOverride) { - url.scheme = ''; - url.username = ''; - url.password = ''; - url.host = null; - url.port = null; - url.path = []; - url.query = null; - url.fragment = null; - url.cannotBeABaseURL = false; - input = input.replace(LEADING_AND_TRAILING_C0_CONTROL_OR_SPACE, ''); + // Safari <= 13.0.3(?) substitutes nth capture where n>m with an empty string + var REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE = (function () { + if (/./[REPLACE]) { + return /./[REPLACE]('a', '$0') === ''; } + return false; + })(); - input = input.replace(TAB_AND_NEW_LINE, ''); + var REPLACE_SUPPORTS_NAMED_GROUPS = !fails$q(function () { + var re = /./; + re.exec = function () { + var result = []; + result.groups = { a: '7' }; + return result; + }; + // eslint-disable-next-line regexp/no-useless-dollar-replacements -- false positive + return ''.replace(re, '$') !== '7'; + }); - codePoints = arrayFrom(input); + // @@replace logic + fixRegExpWellKnownSymbolLogic$3('replace', function (_, nativeReplace, maybeCallNative) { + var UNSAFE_SUBSTITUTE = REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE ? '$' : '$0'; - while (pointer <= codePoints.length) { - char = codePoints[pointer]; - switch (state) { - case SCHEME_START: - if (char && ALPHA.test(char)) { - buffer += char.toLowerCase(); - state = SCHEME; - } else if (!stateOverride) { - state = NO_SCHEME; - continue; - } else return INVALID_SCHEME; - break; + return [ + // `String.prototype.replace` method + // https://tc39.es/ecma262/#sec-string.prototype.replace + function replace(searchValue, replaceValue) { + var O = requireObjectCoercible$a(this); + var replacer = searchValue == undefined ? undefined : getMethod$3(searchValue, REPLACE); + return replacer + ? call$8(replacer, searchValue, O, replaceValue) + : call$8(nativeReplace, toString$f(O), searchValue, replaceValue); + }, + // `RegExp.prototype[@@replace]` method + // https://tc39.es/ecma262/#sec-regexp.prototype-@@replace + function (string, replaceValue) { + var rx = anObject$6(this); + var S = toString$f(string); - case SCHEME: - if (char && (ALPHANUMERIC.test(char) || char == '+' || char == '-' || char == '.')) { - buffer += char.toLowerCase(); - } else if (char == ':') { - if (stateOverride && ( - (isSpecial(url) != has$4(specialSchemes, buffer)) || - (buffer == 'file' && (includesCredentials(url) || url.port !== null)) || - (url.scheme == 'file' && !url.host) - )) return; - url.scheme = buffer; - if (stateOverride) { - if (isSpecial(url) && specialSchemes[url.scheme] == url.port) url.port = null; - return; - } - buffer = ''; - if (url.scheme == 'file') { - state = FILE; - } else if (isSpecial(url) && base && base.scheme == url.scheme) { - state = SPECIAL_RELATIVE_OR_AUTHORITY; - } else if (isSpecial(url)) { - state = SPECIAL_AUTHORITY_SLASHES; - } else if (codePoints[pointer + 1] == '/') { - state = PATH_OR_AUTHORITY; - pointer++; - } else { - url.cannotBeABaseURL = true; - url.path.push(''); - state = CANNOT_BE_A_BASE_URL_PATH; - } - } else if (!stateOverride) { - buffer = ''; - state = NO_SCHEME; - pointer = 0; - continue; - } else return INVALID_SCHEME; - break; + if ( + typeof replaceValue == 'string' && + stringIndexOf$2(replaceValue, UNSAFE_SUBSTITUTE) === -1 && + stringIndexOf$2(replaceValue, '$<') === -1 + ) { + var res = maybeCallNative(nativeReplace, rx, S, replaceValue); + if (res.done) return res.value; + } - case NO_SCHEME: - if (!base || (base.cannotBeABaseURL && char != '#')) return INVALID_SCHEME; - if (base.cannotBeABaseURL && char == '#') { - url.scheme = base.scheme; - url.path = base.path.slice(); - url.query = base.query; - url.fragment = ''; - url.cannotBeABaseURL = true; - state = FRAGMENT; - break; - } - state = base.scheme == 'file' ? FILE : RELATIVE; - continue; + var functionalReplace = isCallable$3(replaceValue); + if (!functionalReplace) replaceValue = toString$f(replaceValue); - case SPECIAL_RELATIVE_OR_AUTHORITY: - if (char == '/' && codePoints[pointer + 1] == '/') { - state = SPECIAL_AUTHORITY_IGNORE_SLASHES; - pointer++; - } else { - state = RELATIVE; - continue; - } break; + var global = rx.global; + if (global) { + var fullUnicode = rx.unicode; + rx.lastIndex = 0; + } + var results = []; + while (true) { + var result = regExpExec$3(rx, S); + if (result === null) break; - case PATH_OR_AUTHORITY: - if (char == '/') { - state = AUTHORITY; - break; + push$6(results, result); + if (!global) break; + + var matchStr = toString$f(result[0]); + if (matchStr === '') rx.lastIndex = advanceStringIndex$2(S, toLength$5(rx.lastIndex), fullUnicode); + } + + var accumulatedResult = ''; + var nextSourcePosition = 0; + for (var i = 0; i < results.length; i++) { + result = results[i]; + + var matched = toString$f(result[0]); + var position = max$2(min$5(toIntegerOrInfinity$3(result.index), S.length), 0); + var captures = []; + // NOTE: This is equivalent to + // captures = result.slice(1).map(maybeToString) + // but for some reason `nativeSlice.call(result, 1, result.length)` (called in + // the slice polyfill when slicing native arrays) "doesn't work" in safari 9 and + // causes a crash (https://pastebin.com/N21QzeQA) when trying to debug it. + for (var j = 1; j < result.length; j++) push$6(captures, maybeToString(result[j])); + var namedCaptures = result.groups; + if (functionalReplace) { + var replacerArgs = concat$2([matched], captures, position, S); + if (namedCaptures !== undefined) push$6(replacerArgs, namedCaptures); + var replacement = toString$f(apply$3(replaceValue, undefined, replacerArgs)); } else { - state = PATH; - continue; + replacement = getSubstitution(matched, S, position, captures, namedCaptures, replaceValue); } + if (position >= nextSourcePosition) { + accumulatedResult += stringSlice$6(S, nextSourcePosition, position) + replacement; + nextSourcePosition = position + matched.length; + } + } + return accumulatedResult + stringSlice$6(S, nextSourcePosition); + } + ]; + }, !REPLACE_SUPPORTS_NAMED_GROUPS || !REPLACE_KEEPS_$0 || REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE); - case RELATIVE: - url.scheme = base.scheme; - if (char == EOF) { - url.username = base.username; - url.password = base.password; - url.host = base.host; - url.port = base.port; - url.path = base.path.slice(); - url.query = base.query; - } else if (char == '/' || (char == '\\' && isSpecial(url))) { - state = RELATIVE_SLASH; - } else if (char == '?') { - url.username = base.username; - url.password = base.password; - url.host = base.host; - url.port = base.port; - url.path = base.path.slice(); - url.query = ''; - state = QUERY; - } else if (char == '#') { - url.username = base.username; - url.password = base.password; - url.host = base.host; - url.port = base.port; - url.path = base.path.slice(); - url.query = base.query; - url.fragment = ''; - state = FRAGMENT; - } else { - url.username = base.username; - url.password = base.password; - url.host = base.host; - url.port = base.port; - url.path = base.path.slice(); - url.path.pop(); - state = PATH; - continue; - } break; - - case RELATIVE_SLASH: - if (isSpecial(url) && (char == '/' || char == '\\')) { - state = SPECIAL_AUTHORITY_IGNORE_SLASHES; - } else if (char == '/') { - state = AUTHORITY; - } else { - url.username = base.username; - url.password = base.password; - url.host = base.host; - url.port = base.port; - state = PATH; - continue; - } break; - - case SPECIAL_AUTHORITY_SLASHES: - state = SPECIAL_AUTHORITY_IGNORE_SLASHES; - if (char != '/' || buffer.charAt(pointer + 1) != '/') continue; - pointer++; - break; + var isObject$c = isObject$s; + var classof$1 = classofRaw$1; + var wellKnownSymbol$3 = wellKnownSymbol$t; - case SPECIAL_AUTHORITY_IGNORE_SLASHES: - if (char != '/' && char != '\\') { - state = AUTHORITY; - continue; - } break; + var MATCH$2 = wellKnownSymbol$3('match'); - case AUTHORITY: - if (char == '@') { - if (seenAt) buffer = '%40' + buffer; - seenAt = true; - bufferCodePoints = arrayFrom(buffer); - for (var i = 0; i < bufferCodePoints.length; i++) { - var codePoint = bufferCodePoints[i]; - if (codePoint == ':' && !seenPasswordToken) { - seenPasswordToken = true; - continue; - } - var encodedCodePoints = percentEncode(codePoint, userinfoPercentEncodeSet); - if (seenPasswordToken) url.password += encodedCodePoints; - else url.username += encodedCodePoints; - } - buffer = ''; - } else if ( - char == EOF || char == '/' || char == '?' || char == '#' || - (char == '\\' && isSpecial(url)) - ) { - if (seenAt && buffer == '') return INVALID_AUTHORITY; - pointer -= arrayFrom(buffer).length + 1; - buffer = ''; - state = HOST; - } else buffer += char; - break; + // `IsRegExp` abstract operation + // https://tc39.es/ecma262/#sec-isregexp + var isRegexp = function (it) { + var isRegExp; + return isObject$c(it) && ((isRegExp = it[MATCH$2]) !== undefined ? !!isRegExp : classof$1(it) == 'RegExp'); + }; - case HOST: - case HOSTNAME: - if (stateOverride && url.scheme == 'file') { - state = FILE_HOST; - continue; - } else if (char == ':' && !seenBracket) { - if (buffer == '') return INVALID_HOST; - failure = parseHost(url, buffer); - if (failure) return failure; - buffer = ''; - state = PORT; - if (stateOverride == HOSTNAME) return; - } else if ( - char == EOF || char == '/' || char == '?' || char == '#' || - (char == '\\' && isSpecial(url)) - ) { - if (isSpecial(url) && buffer == '') return INVALID_HOST; - if (stateOverride && buffer == '' && (includesCredentials(url) || url.port !== null)) return; - failure = parseHost(url, buffer); - if (failure) return failure; - buffer = ''; - state = PATH_START; - if (stateOverride) return; - continue; - } else { - if (char == '[') seenBracket = true; - else if (char == ']') seenBracket = false; - buffer += char; - } break; + var apply$2 = functionApply; + var call$7 = functionCall; + var uncurryThis$p = functionUncurryThis; + var fixRegExpWellKnownSymbolLogic$2 = fixRegexpWellKnownSymbolLogic; + var isRegExp$2 = isRegexp; + var anObject$5 = anObject$n; + var requireObjectCoercible$9 = requireObjectCoercible$e; + var speciesConstructor$1 = speciesConstructor$5; + var advanceStringIndex$1 = advanceStringIndex$3; + var toLength$4 = toLength$c; + var toString$e = toString$k; + var getMethod$2 = getMethod$7; + var arraySlice$4 = arraySlice$c; + var callRegExpExec = regexpExecAbstract; + var regexpExec = regexpExec$3; + var stickyHelpers$1 = regexpStickyHelpers; + var fails$p = fails$S; - case PORT: - if (DIGIT.test(char)) { - buffer += char; - } else if ( - char == EOF || char == '/' || char == '?' || char == '#' || - (char == '\\' && isSpecial(url)) || - stateOverride - ) { - if (buffer != '') { - var port = parseInt(buffer, 10); - if (port > 0xFFFF) return INVALID_PORT; - url.port = (isSpecial(url) && port === specialSchemes[url.scheme]) ? null : port; - buffer = ''; - } - if (stateOverride) return; - state = PATH_START; - continue; - } else return INVALID_PORT; - break; + var UNSUPPORTED_Y$1 = stickyHelpers$1.UNSUPPORTED_Y; + var MAX_UINT32 = 0xFFFFFFFF; + var min$4 = Math.min; + var $push = [].push; + var exec$4 = uncurryThis$p(/./.exec); + var push$5 = uncurryThis$p($push); + var stringSlice$5 = uncurryThis$p(''.slice); - case FILE: - url.scheme = 'file'; - if (char == '/' || char == '\\') state = FILE_SLASH; - else if (base && base.scheme == 'file') { - if (char == EOF) { - url.host = base.host; - url.path = base.path.slice(); - url.query = base.query; - } else if (char == '?') { - url.host = base.host; - url.path = base.path.slice(); - url.query = ''; - state = QUERY; - } else if (char == '#') { - url.host = base.host; - url.path = base.path.slice(); - url.query = base.query; - url.fragment = ''; - state = FRAGMENT; - } else { - if (!startsWithWindowsDriveLetter(codePoints.slice(pointer).join(''))) { - url.host = base.host; - url.path = base.path.slice(); - shortenURLsPath(url); - } - state = PATH; - continue; - } - } else { - state = PATH; - continue; - } break; + // Chrome 51 has a buggy "split" implementation when RegExp#exec !== nativeExec + // Weex JS has frozen built-in prototypes, so use try / catch wrapper + var SPLIT_WORKS_WITH_OVERWRITTEN_EXEC = !fails$p(function () { + // eslint-disable-next-line regexp/no-empty-group -- required for testing + var re = /(?:)/; + var originalExec = re.exec; + re.exec = function () { return originalExec.apply(this, arguments); }; + var result = 'ab'.split(re); + return result.length !== 2 || result[0] !== 'a' || result[1] !== 'b'; + }); - case FILE_SLASH: - if (char == '/' || char == '\\') { - state = FILE_HOST; - break; - } - if (base && base.scheme == 'file' && !startsWithWindowsDriveLetter(codePoints.slice(pointer).join(''))) { - if (isWindowsDriveLetter(base.path[0], true)) url.path.push(base.path[0]); - else url.host = base.host; + // @@split logic + fixRegExpWellKnownSymbolLogic$2('split', function (SPLIT, nativeSplit, maybeCallNative) { + var internalSplit; + if ( + 'abbc'.split(/(b)*/)[1] == 'c' || + // eslint-disable-next-line regexp/no-empty-group -- required for testing + 'test'.split(/(?:)/, -1).length != 4 || + 'ab'.split(/(?:ab)*/).length != 2 || + '.'.split(/(.?)(.?)/).length != 4 || + // eslint-disable-next-line regexp/no-empty-capturing-group, regexp/no-empty-group -- required for testing + '.'.split(/()()/).length > 1 || + ''.split(/.?/).length + ) { + // based on es5-shim implementation, need to rework it + internalSplit = function (separator, limit) { + var string = toString$e(requireObjectCoercible$9(this)); + var lim = limit === undefined ? MAX_UINT32 : limit >>> 0; + if (lim === 0) return []; + if (separator === undefined) return [string]; + // If `separator` is not a regex, use native split + if (!isRegExp$2(separator)) { + return call$7(nativeSplit, string, separator, lim); + } + var output = []; + var flags = (separator.ignoreCase ? 'i' : '') + + (separator.multiline ? 'm' : '') + + (separator.unicode ? 'u' : '') + + (separator.sticky ? 'y' : ''); + var lastLastIndex = 0; + // Make `global` and avoid `lastIndex` issues by working with a copy + var separatorCopy = new RegExp(separator.source, flags + 'g'); + var match, lastIndex, lastLength; + while (match = call$7(regexpExec, separatorCopy, string)) { + lastIndex = separatorCopy.lastIndex; + if (lastIndex > lastLastIndex) { + push$5(output, stringSlice$5(string, lastLastIndex, match.index)); + if (match.length > 1 && match.index < string.length) apply$2($push, output, arraySlice$4(match, 1)); + lastLength = match[0].length; + lastLastIndex = lastIndex; + if (output.length >= lim) break; } - state = PATH; - continue; + if (separatorCopy.lastIndex === match.index) separatorCopy.lastIndex++; // Avoid an infinite loop + } + if (lastLastIndex === string.length) { + if (lastLength || !exec$4(separatorCopy, '')) push$5(output, ''); + } else push$5(output, stringSlice$5(string, lastLastIndex)); + return output.length > lim ? arraySlice$4(output, 0, lim) : output; + }; + // Chakra, V8 + } else if ('0'.split(undefined, 0).length) { + internalSplit = function (separator, limit) { + return separator === undefined && limit === 0 ? [] : call$7(nativeSplit, this, separator, limit); + }; + } else internalSplit = nativeSplit; - case FILE_HOST: - if (char == EOF || char == '/' || char == '\\' || char == '?' || char == '#') { - if (!stateOverride && isWindowsDriveLetter(buffer)) { - state = PATH; - } else if (buffer == '') { - url.host = ''; - if (stateOverride) return; - state = PATH_START; - } else { - failure = parseHost(url, buffer); - if (failure) return failure; - if (url.host == 'localhost') url.host = ''; - if (stateOverride) return; - buffer = ''; - state = PATH_START; - } continue; - } else buffer += char; - break; + return [ + // `String.prototype.split` method + // https://tc39.es/ecma262/#sec-string.prototype.split + function split(separator, limit) { + var O = requireObjectCoercible$9(this); + var splitter = separator == undefined ? undefined : getMethod$2(separator, SPLIT); + return splitter + ? call$7(splitter, separator, O, limit) + : call$7(internalSplit, toString$e(O), separator, limit); + }, + // `RegExp.prototype[@@split]` method + // https://tc39.es/ecma262/#sec-regexp.prototype-@@split + // + // NOTE: This cannot be properly polyfilled in engines that don't support + // the 'y' flag. + function (string, limit) { + var rx = anObject$5(this); + var S = toString$e(string); + var res = maybeCallNative(internalSplit, rx, S, limit, internalSplit !== nativeSplit); - case PATH_START: - if (isSpecial(url)) { - state = PATH; - if (char != '/' && char != '\\') continue; - } else if (!stateOverride && char == '?') { - url.query = ''; - state = QUERY; - } else if (!stateOverride && char == '#') { - url.fragment = ''; - state = FRAGMENT; - } else if (char != EOF) { - state = PATH; - if (char != '/') continue; - } break; + if (res.done) return res.value; - case PATH: + var C = speciesConstructor$1(rx, RegExp); + + var unicodeMatching = rx.unicode; + var flags = (rx.ignoreCase ? 'i' : '') + + (rx.multiline ? 'm' : '') + + (rx.unicode ? 'u' : '') + + (UNSUPPORTED_Y$1 ? 'g' : 'y'); + + // ^(? + rx + ) is needed, in combination with some S slicing, to + // simulate the 'y' flag. + var splitter = new C(UNSUPPORTED_Y$1 ? '^(?:' + rx.source + ')' : rx, flags); + var lim = limit === undefined ? MAX_UINT32 : limit >>> 0; + if (lim === 0) return []; + if (S.length === 0) return callRegExpExec(splitter, S) === null ? [S] : []; + var p = 0; + var q = 0; + var A = []; + while (q < S.length) { + splitter.lastIndex = UNSUPPORTED_Y$1 ? 0 : q; + var z = callRegExpExec(splitter, UNSUPPORTED_Y$1 ? stringSlice$5(S, q) : S); + var e; if ( - char == EOF || char == '/' || - (char == '\\' && isSpecial(url)) || - (!stateOverride && (char == '?' || char == '#')) + z === null || + (e = min$4(toLength$4(splitter.lastIndex + (UNSUPPORTED_Y$1 ? q : 0)), S.length)) === p ) { - if (isDoubleDot(buffer)) { - shortenURLsPath(url); - if (char != '/' && !(char == '\\' && isSpecial(url))) { - url.path.push(''); - } - } else if (isSingleDot(buffer)) { - if (char != '/' && !(char == '\\' && isSpecial(url))) { - url.path.push(''); - } - } else { - if (url.scheme == 'file' && !url.path.length && isWindowsDriveLetter(buffer)) { - if (url.host) url.host = ''; - buffer = buffer.charAt(0) + ':'; // normalize windows drive letter - } - url.path.push(buffer); - } - buffer = ''; - if (url.scheme == 'file' && (char == EOF || char == '?' || char == '#')) { - while (url.path.length > 1 && url.path[0] === '') { - url.path.shift(); - } - } - if (char == '?') { - url.query = ''; - state = QUERY; - } else if (char == '#') { - url.fragment = ''; - state = FRAGMENT; - } + q = advanceStringIndex$1(S, q, unicodeMatching); } else { - buffer += percentEncode(char, pathPercentEncodeSet); - } break; + push$5(A, stringSlice$5(S, p, q)); + if (A.length === lim) return A; + for (var i = 1; i <= z.length - 1; i++) { + push$5(A, z[i]); + if (A.length === lim) return A; + } + q = p = e; + } + } + push$5(A, stringSlice$5(S, p)); + return A; + } + ]; + }, !SPLIT_WORKS_WITH_OVERWRITTEN_EXEC, UNSUPPORTED_Y$1); - case CANNOT_BE_A_BASE_URL_PATH: - if (char == '?') { - url.query = ''; - state = QUERY; - } else if (char == '#') { - url.fragment = ''; - state = FRAGMENT; - } else if (char != EOF) { - url.path[0] += percentEncode(char, C0ControlPercentEncodeSet); - } break; + // a string of all valid unicode whitespaces + var whitespaces$4 = '\u0009\u000A\u000B\u000C\u000D\u0020\u00A0\u1680\u2000\u2001\u2002' + + '\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF'; - case QUERY: - if (!stateOverride && char == '#') { - url.fragment = ''; - state = FRAGMENT; - } else if (char != EOF) { - if (char == "'" && isSpecial(url)) url.query += '%27'; - else if (char == '#') url.query += '%23'; - else url.query += percentEncode(char, C0ControlPercentEncodeSet); - } break; + var uncurryThis$o = functionUncurryThis; + var requireObjectCoercible$8 = requireObjectCoercible$e; + var toString$d = toString$k; + var whitespaces$3 = whitespaces$4; - case FRAGMENT: - if (char != EOF) url.fragment += percentEncode(char, fragmentPercentEncodeSet); - break; - } + var replace$4 = uncurryThis$o(''.replace); + var whitespace = '[' + whitespaces$3 + ']'; + var ltrim = RegExp('^' + whitespace + whitespace + '*'); + var rtrim$2 = RegExp(whitespace + whitespace + '*$'); - pointer++; - } + // `String.prototype.{ trim, trimStart, trimEnd, trimLeft, trimRight }` methods implementation + var createMethod$2 = function (TYPE) { + return function ($this) { + var string = toString$d(requireObjectCoercible$8($this)); + if (TYPE & 1) string = replace$4(string, ltrim, ''); + if (TYPE & 2) string = replace$4(string, rtrim$2, ''); + return string; + }; }; - // `URL` constructor - // https://url.spec.whatwg.org/#url-class - var URLConstructor = function URL(url /* , base */) { - var that = anInstance$2(this, URLConstructor, 'URL'); - var base = arguments.length > 1 ? arguments[1] : undefined; - var urlString = String(url); - var state = setInternalState$1(that, { type: 'URL' }); - var baseState, failure; - if (base !== undefined) { - if (base instanceof URLConstructor) baseState = getInternalURLState(base); - else { - failure = parseURL(baseState = {}, String(base)); - if (failure) throw TypeError(failure); - } - } - failure = parseURL(state, urlString, null, baseState); - if (failure) throw TypeError(failure); - var searchParams = state.searchParams = new URLSearchParams$1(); - var searchParamsState = getInternalSearchParamsState(searchParams); - searchParamsState.updateSearchParams(state.query); - searchParamsState.updateURL = function () { - state.query = String(searchParams) || null; - }; - if (!DESCRIPTORS$a) { - that.href = serializeURL.call(that); - that.origin = getOrigin.call(that); - that.protocol = getProtocol.call(that); - that.username = getUsername.call(that); - that.password = getPassword.call(that); - that.host = getHost.call(that); - that.hostname = getHostname.call(that); - that.port = getPort.call(that); - that.pathname = getPathname.call(that); - that.search = getSearch.call(that); - that.searchParams = getSearchParams.call(that); - that.hash = getHash.call(that); - } + var stringTrim = { + // `String.prototype.{ trimLeft, trimStart }` methods + // https://tc39.es/ecma262/#sec-string.prototype.trimstart + start: createMethod$2(1), + // `String.prototype.{ trimRight, trimEnd }` methods + // https://tc39.es/ecma262/#sec-string.prototype.trimend + end: createMethod$2(2), + // `String.prototype.trim` method + // https://tc39.es/ecma262/#sec-string.prototype.trim + trim: createMethod$2(3) }; - var URLPrototype = URLConstructor.prototype; + var PROPER_FUNCTION_NAME = functionName.PROPER; + var fails$o = fails$S; + var whitespaces$2 = whitespaces$4; - var serializeURL = function () { - var url = getInternalURLState(this); - var scheme = url.scheme; - var username = url.username; - var password = url.password; - var host = url.host; - var port = url.port; - var path = url.path; - var query = url.query; - var fragment = url.fragment; - var output = scheme + ':'; - if (host !== null) { - output += '//'; - if (includesCredentials(url)) { - output += username + (password ? ':' + password : '') + '@'; - } - output += serializeHost(host); - if (port !== null) output += ':' + port; - } else if (scheme == 'file') output += '//'; - output += url.cannotBeABaseURL ? path[0] : path.length ? '/' + path.join('/') : ''; - if (query !== null) output += '?' + query; - if (fragment !== null) output += '#' + fragment; - return output; + var non = '\u200B\u0085\u180E'; + + // check that a method works with the correct list + // of whitespaces and has a correct name + var stringTrimForced = function (METHOD_NAME) { + return fails$o(function () { + return !!whitespaces$2[METHOD_NAME]() + || non[METHOD_NAME]() !== non + || (PROPER_FUNCTION_NAME && whitespaces$2[METHOD_NAME].name !== METHOD_NAME); + }); }; - var getOrigin = function () { - var url = getInternalURLState(this); - var scheme = url.scheme; - var port = url.port; - if (scheme == 'blob') try { - return new URLConstructor(scheme.path[0]).origin; - } catch (error) { - return 'null'; + var $$W = _export; + var $trim = stringTrim.trim; + var forcedStringTrimMethod$2 = stringTrimForced; + + // `String.prototype.trim` method + // https://tc39.es/ecma262/#sec-string.prototype.trim + $$W({ target: 'String', proto: true, forced: forcedStringTrimMethod$2('trim') }, { + trim: function trim() { + return $trim(this); } - if (scheme == 'file' || !isSpecial(url)) return 'null'; - return scheme + '://' + serializeHost(url.host) + (port !== null ? ':' + port : ''); - }; + }); - var getProtocol = function () { - return getInternalURLState(this).scheme + ':'; - }; + var DESCRIPTORS$b = descriptors; + var FUNCTION_NAME_EXISTS = functionName.EXISTS; + var uncurryThis$n = functionUncurryThis; + var defineProperty$5 = objectDefineProperty.f; - var getUsername = function () { - return getInternalURLState(this).username; - }; + var FunctionPrototype = Function.prototype; + var functionToString = uncurryThis$n(FunctionPrototype.toString); + var nameRE = /^\s*function ([^ (]*)/; + var regExpExec$2 = uncurryThis$n(nameRE.exec); + var NAME = 'name'; - var getPassword = function () { - return getInternalURLState(this).password; - }; + // Function instances `.name` property + // https://tc39.es/ecma262/#sec-function-instances-name + if (DESCRIPTORS$b && !FUNCTION_NAME_EXISTS) { + defineProperty$5(FunctionPrototype, NAME, { + configurable: true, + get: function () { + try { + return regExpExec$2(nameRE, functionToString(this))[1]; + } catch (error) { + return ''; + } + } + }); + } - var getHost = function () { - var url = getInternalURLState(this); - var host = url.host; - var port = url.port; - return host === null ? '' - : port === null ? serializeHost(host) - : serializeHost(host) + ':' + port; - }; + var $$V = _export; + var DESCRIPTORS$a = descriptors; + var create$5 = objectCreate; - var getHostname = function () { - var host = getInternalURLState(this).host; - return host === null ? '' : serializeHost(host); - }; + // `Object.create` method + // https://tc39.es/ecma262/#sec-object.create + $$V({ target: 'Object', stat: true, sham: !DESCRIPTORS$a }, { + create: create$5 + }); - var getPort = function () { - var port = getInternalURLState(this).port; - return port === null ? '' : String(port); - }; + var $$U = _export; + var global$l = global$1m; + var apply$1 = functionApply; + var isCallable$2 = isCallable$r; + var userAgent$1 = engineUserAgent; + var arraySlice$3 = arraySlice$c; - var getPathname = function () { - var url = getInternalURLState(this); - var path = url.path; - return url.cannotBeABaseURL ? path[0] : path.length ? '/' + path.join('/') : ''; - }; + var MSIE = /MSIE .\./.test(userAgent$1); // <- dirty ie9- check + var Function$2 = global$l.Function; - var getSearch = function () { - var query = getInternalURLState(this).query; - return query ? '?' + query : ''; + var wrap$1 = function (scheduler) { + return function (handler, timeout /* , ...arguments */) { + var boundArgs = arguments.length > 2; + var args = boundArgs ? arraySlice$3(arguments, 2) : undefined; + return scheduler(boundArgs ? function () { + apply$1(isCallable$2(handler) ? handler : Function$2(handler), this, args); + } : handler, timeout); + }; }; - var getSearchParams = function () { - return getInternalURLState(this).searchParams; - }; + // ie9- setTimeout & setInterval additional parameters fix + // https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers + $$U({ global: true, bind: true, forced: MSIE }, { + // `setTimeout` method + // https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#dom-settimeout + setTimeout: wrap$1(global$l.setTimeout), + // `setInterval` method + // https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#dom-setinterval + setInterval: wrap$1(global$l.setInterval) + }); - var getHash = function () { - var fragment = getInternalURLState(this).fragment; - return fragment ? '#' + fragment : ''; + var global$k = typeof globalThis !== 'undefined' && globalThis || typeof self !== 'undefined' && self || typeof global$k !== 'undefined' && global$k; + var support = { + searchParams: 'URLSearchParams' in global$k, + iterable: 'Symbol' in global$k && 'iterator' in Symbol, + blob: 'FileReader' in global$k && 'Blob' in global$k && function () { + try { + new Blob(); + return true; + } catch (e) { + return false; + } + }(), + formData: 'FormData' in global$k, + arrayBuffer: 'ArrayBuffer' in global$k }; - var accessorDescriptor = function (getter, setter) { - return { get: getter, set: setter, configurable: true, enumerable: true }; - }; + function isDataView(obj) { + return obj && DataView.prototype.isPrototypeOf(obj); + } - if (DESCRIPTORS$a) { - defineProperties$1(URLPrototype, { - // `URL.prototype.href` accessors pair - // https://url.spec.whatwg.org/#dom-url-href - href: accessorDescriptor(serializeURL, function (href) { - var url = getInternalURLState(this); - var urlString = String(href); - var failure = parseURL(url, urlString); - if (failure) throw TypeError(failure); - getInternalSearchParamsState(url.searchParams).updateSearchParams(url.query); - }), - // `URL.prototype.origin` getter - // https://url.spec.whatwg.org/#dom-url-origin - origin: accessorDescriptor(getOrigin), - // `URL.prototype.protocol` accessors pair - // https://url.spec.whatwg.org/#dom-url-protocol - protocol: accessorDescriptor(getProtocol, function (protocol) { - var url = getInternalURLState(this); - parseURL(url, String(protocol) + ':', SCHEME_START); - }), - // `URL.prototype.username` accessors pair - // https://url.spec.whatwg.org/#dom-url-username - username: accessorDescriptor(getUsername, function (username) { - var url = getInternalURLState(this); - var codePoints = arrayFrom(String(username)); - if (cannotHaveUsernamePasswordPort(url)) return; - url.username = ''; - for (var i = 0; i < codePoints.length; i++) { - url.username += percentEncode(codePoints[i], userinfoPercentEncodeSet); - } - }), - // `URL.prototype.password` accessors pair - // https://url.spec.whatwg.org/#dom-url-password - password: accessorDescriptor(getPassword, function (password) { - var url = getInternalURLState(this); - var codePoints = arrayFrom(String(password)); - if (cannotHaveUsernamePasswordPort(url)) return; - url.password = ''; - for (var i = 0; i < codePoints.length; i++) { - url.password += percentEncode(codePoints[i], userinfoPercentEncodeSet); - } - }), - // `URL.prototype.host` accessors pair - // https://url.spec.whatwg.org/#dom-url-host - host: accessorDescriptor(getHost, function (host) { - var url = getInternalURLState(this); - if (url.cannotBeABaseURL) return; - parseURL(url, String(host), HOST); - }), - // `URL.prototype.hostname` accessors pair - // https://url.spec.whatwg.org/#dom-url-hostname - hostname: accessorDescriptor(getHostname, function (hostname) { - var url = getInternalURLState(this); - if (url.cannotBeABaseURL) return; - parseURL(url, String(hostname), HOSTNAME); - }), - // `URL.prototype.port` accessors pair - // https://url.spec.whatwg.org/#dom-url-port - port: accessorDescriptor(getPort, function (port) { - var url = getInternalURLState(this); - if (cannotHaveUsernamePasswordPort(url)) return; - port = String(port); - if (port == '') url.port = null; - else parseURL(url, port, PORT); - }), - // `URL.prototype.pathname` accessors pair - // https://url.spec.whatwg.org/#dom-url-pathname - pathname: accessorDescriptor(getPathname, function (pathname) { - var url = getInternalURLState(this); - if (url.cannotBeABaseURL) return; - url.path = []; - parseURL(url, pathname + '', PATH_START); - }), - // `URL.prototype.search` accessors pair - // https://url.spec.whatwg.org/#dom-url-search - search: accessorDescriptor(getSearch, function (search) { - var url = getInternalURLState(this); - search = String(search); - if (search == '') { - url.query = null; - } else { - if ('?' == search.charAt(0)) search = search.slice(1); - url.query = ''; - parseURL(url, search, QUERY); - } - getInternalSearchParamsState(url.searchParams).updateSearchParams(url.query); - }), - // `URL.prototype.searchParams` getter - // https://url.spec.whatwg.org/#dom-url-searchparams - searchParams: accessorDescriptor(getSearchParams), - // `URL.prototype.hash` accessors pair - // https://url.spec.whatwg.org/#dom-url-hash - hash: accessorDescriptor(getHash, function (hash) { - var url = getInternalURLState(this); - hash = String(hash); - if (hash == '') { - url.fragment = null; - return; - } - if ('#' == hash.charAt(0)) hash = hash.slice(1); - url.fragment = ''; - parseURL(url, hash, FRAGMENT); - }) - }); + if (support.arrayBuffer) { + var viewClasses = ['[object Int8Array]', '[object Uint8Array]', '[object Uint8ClampedArray]', '[object Int16Array]', '[object Uint16Array]', '[object Int32Array]', '[object Uint32Array]', '[object Float32Array]', '[object Float64Array]']; + + var isArrayBufferView = ArrayBuffer.isView || function (obj) { + return obj && viewClasses.indexOf(Object.prototype.toString.call(obj)) > -1; + }; } - // `URL.prototype.toJSON` method - // https://url.spec.whatwg.org/#dom-url-tojson - redefine$6(URLPrototype, 'toJSON', function toJSON() { - return serializeURL.call(this); - }, { enumerable: true }); + function normalizeName(name) { + if (typeof name !== 'string') { + name = String(name); + } - // `URL.prototype.toString` method - // https://url.spec.whatwg.org/#URL-stringification-behavior - redefine$6(URLPrototype, 'toString', function toString() { - return serializeURL.call(this); - }, { enumerable: true }); + if (/[^a-z0-9\-#$%&'*+.^_`|~!]/i.test(name) || name === '') { + throw new TypeError('Invalid character in header field name: "' + name + '"'); + } - if (NativeURL) { - var nativeCreateObjectURL = NativeURL.createObjectURL; - var nativeRevokeObjectURL = NativeURL.revokeObjectURL; - // `URL.createObjectURL` method - // https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL - // eslint-disable-next-line no-unused-vars -- required for `.length` - if (nativeCreateObjectURL) redefine$6(URLConstructor, 'createObjectURL', function createObjectURL(blob) { - return nativeCreateObjectURL.apply(NativeURL, arguments); - }); - // `URL.revokeObjectURL` method - // https://developer.mozilla.org/en-US/docs/Web/API/URL/revokeObjectURL - // eslint-disable-next-line no-unused-vars -- required for `.length` - if (nativeRevokeObjectURL) redefine$6(URLConstructor, 'revokeObjectURL', function revokeObjectURL(url) { - return nativeRevokeObjectURL.apply(NativeURL, arguments); - }); + return name.toLowerCase(); } - setToStringTag$3(URLConstructor, 'URL'); + function normalizeValue(value) { + if (typeof value !== 'string') { + value = String(value); + } - $$Q({ global: true, forced: !USE_NATIVE_URL, sham: !DESCRIPTORS$a }, { - URL: URLConstructor - }); + return value; + } // Build a destructive iterator for the value list - var anObject$7 = anObject$m; - // `RegExp.prototype.flags` getter implementation - // https://tc39.es/ecma262/#sec-get-regexp.prototype.flags - var regexpFlags$1 = function () { - var that = anObject$7(this); - var result = ''; - if (that.global) result += 'g'; - if (that.ignoreCase) result += 'i'; - if (that.multiline) result += 'm'; - if (that.dotAll) result += 's'; - if (that.unicode) result += 'u'; - if (that.sticky) result += 'y'; - return result; - }; + function iteratorFor(items) { + var iterator = { + next: function next() { + var value = items.shift(); + return { + done: value === undefined, + value: value + }; + } + }; - var redefine$5 = redefine$g.exports; - var anObject$6 = anObject$m; - var fails$q = fails$N; - var flags = regexpFlags$1; + if (support.iterable) { + iterator[Symbol.iterator] = function () { + return iterator; + }; + } - var TO_STRING = 'toString'; - var RegExpPrototype$2 = RegExp.prototype; - var nativeToString = RegExpPrototype$2[TO_STRING]; + return iterator; + } - var NOT_GENERIC = fails$q(function () { return nativeToString.call({ source: 'a', flags: 'b' }) != '/a/b'; }); - // FF44- RegExp#toString has a wrong name - var INCORRECT_NAME = nativeToString.name != TO_STRING; + function Headers(headers) { + this.map = {}; - // `RegExp.prototype.toString` method - // https://tc39.es/ecma262/#sec-regexp.prototype.tostring - if (NOT_GENERIC || INCORRECT_NAME) { - redefine$5(RegExp.prototype, TO_STRING, function toString() { - var R = anObject$6(this); - var p = String(R.source); - var rf = R.flags; - var f = String(rf === undefined && R instanceof RegExp && !('flags' in RegExpPrototype$2) ? flags.call(R) : rf); - return '/' + p + '/' + f; - }, { unsafe: true }); + if (headers instanceof Headers) { + headers.forEach(function (value, name) { + this.append(name, value); + }, this); + } else if (Array.isArray(headers)) { + headers.forEach(function (header) { + this.append(header[0], header[1]); + }, this); + } else if (headers) { + Object.getOwnPropertyNames(headers).forEach(function (name) { + this.append(name, headers[name]); + }, this); + } } - var regexpStickyHelpers = {}; + Headers.prototype.append = function (name, value) { + name = normalizeName(name); + value = normalizeValue(value); + var oldValue = this.map[name]; + this.map[name] = oldValue ? oldValue + ', ' + value : value; + }; - var fails$p = fails$N; + Headers.prototype['delete'] = function (name) { + delete this.map[normalizeName(name)]; + }; - // babel-minify transpiles RegExp('a', 'y') -> /a/y and it causes SyntaxError, - var RE = function (s, f) { - return RegExp(s, f); + Headers.prototype.get = function (name) { + name = normalizeName(name); + return this.has(name) ? this.map[name] : null; }; - regexpStickyHelpers.UNSUPPORTED_Y = fails$p(function () { - var re = RE('a', 'y'); - re.lastIndex = 2; - return re.exec('abcd') != null; - }); + Headers.prototype.has = function (name) { + return this.map.hasOwnProperty(normalizeName(name)); + }; - regexpStickyHelpers.BROKEN_CARET = fails$p(function () { - // https://bugzilla.mozilla.org/show_bug.cgi?id=773687 - var re = RE('^r', 'gy'); - re.lastIndex = 2; - return re.exec('str') != null; - }); + Headers.prototype.set = function (name, value) { + this.map[normalizeName(name)] = normalizeValue(value); + }; - var fails$o = fails$N; + Headers.prototype.forEach = function (callback, thisArg) { + for (var name in this.map) { + if (this.map.hasOwnProperty(name)) { + callback.call(thisArg, this.map[name], name, this); + } + } + }; - var regexpUnsupportedDotAll = fails$o(function () { - // babel-minify transpiles RegExp('.', 's') -> /./s and it causes SyntaxError - var re = RegExp('.', (typeof '').charAt(0)); - return !(re.dotAll && re.exec('\n') && re.flags === 's'); - }); + Headers.prototype.keys = function () { + var items = []; + this.forEach(function (value, name) { + items.push(name); + }); + return iteratorFor(items); + }; - var fails$n = fails$N; + Headers.prototype.values = function () { + var items = []; + this.forEach(function (value) { + items.push(value); + }); + return iteratorFor(items); + }; - var regexpUnsupportedNcg = fails$n(function () { - // babel-minify transpiles RegExp('.', 'g') -> /./g and it causes SyntaxError - var re = RegExp('(?b)', (typeof '').charAt(5)); - return re.exec('b').groups.a !== 'b' || - 'b'.replace(re, '$c') !== 'bc'; - }); + Headers.prototype.entries = function () { + var items = []; + this.forEach(function (value, name) { + items.push([name, value]); + }); + return iteratorFor(items); + }; - /* eslint-disable regexp/no-assertion-capturing-group, regexp/no-empty-group, regexp/no-lazy-ends -- testing */ - /* eslint-disable regexp/no-useless-quantifier -- testing */ - var regexpFlags = regexpFlags$1; - var stickyHelpers$2 = regexpStickyHelpers; - var shared = shared$5.exports; - var create$7 = objectCreate; - var getInternalState = internalState.get; - var UNSUPPORTED_DOT_ALL$1 = regexpUnsupportedDotAll; - var UNSUPPORTED_NCG$1 = regexpUnsupportedNcg; + if (support.iterable) { + Headers.prototype[Symbol.iterator] = Headers.prototype.entries; + } - var nativeExec = RegExp.prototype.exec; - var nativeReplace = shared('native-string-replace', String.prototype.replace); + function consumed(body) { + if (body.bodyUsed) { + return Promise.reject(new TypeError('Already read')); + } - var patchedExec = nativeExec; + body.bodyUsed = true; + } - var UPDATES_LAST_INDEX_WRONG = (function () { - var re1 = /a/; - var re2 = /b*/g; - nativeExec.call(re1, 'a'); - nativeExec.call(re2, 'a'); - return re1.lastIndex !== 0 || re2.lastIndex !== 0; - })(); + function fileReaderReady(reader) { + return new Promise(function (resolve, reject) { + reader.onload = function () { + resolve(reader.result); + }; - var UNSUPPORTED_Y$2 = stickyHelpers$2.UNSUPPORTED_Y || stickyHelpers$2.BROKEN_CARET; + reader.onerror = function () { + reject(reader.error); + }; + }); + } - // nonparticipating capturing group, copied from es5-shim's String#split patch. - var NPCG_INCLUDED = /()??/.exec('')[1] !== undefined; + function readBlobAsArrayBuffer(blob) { + var reader = new FileReader(); + var promise = fileReaderReady(reader); + reader.readAsArrayBuffer(blob); + return promise; + } - var PATCH = UPDATES_LAST_INDEX_WRONG || NPCG_INCLUDED || UNSUPPORTED_Y$2 || UNSUPPORTED_DOT_ALL$1 || UNSUPPORTED_NCG$1; + function readBlobAsText(blob) { + var reader = new FileReader(); + var promise = fileReaderReady(reader); + reader.readAsText(blob); + return promise; + } - if (PATCH) { - // eslint-disable-next-line max-statements -- TODO - patchedExec = function exec(str) { - var re = this; - var state = getInternalState(re); - var raw = state.raw; - var result, reCopy, lastIndex, match, i, object, group; + function readArrayBufferAsText(buf) { + var view = new Uint8Array(buf); + var chars = new Array(view.length); - if (raw) { - raw.lastIndex = re.lastIndex; - result = patchedExec.call(raw, str); - re.lastIndex = raw.lastIndex; - return result; - } + for (var i = 0; i < view.length; i++) { + chars[i] = String.fromCharCode(view[i]); + } - var groups = state.groups; - var sticky = UNSUPPORTED_Y$2 && re.sticky; - var flags = regexpFlags.call(re); - var source = re.source; - var charsAdded = 0; - var strCopy = str; + return chars.join(''); + } - if (sticky) { - flags = flags.replace('y', ''); - if (flags.indexOf('g') === -1) { - flags += 'g'; - } + function bufferClone(buf) { + if (buf.slice) { + return buf.slice(0); + } else { + var view = new Uint8Array(buf.byteLength); + view.set(new Uint8Array(buf)); + return view.buffer; + } + } - strCopy = String(str).slice(re.lastIndex); - // Support anchored sticky behavior. - if (re.lastIndex > 0 && (!re.multiline || re.multiline && str[re.lastIndex - 1] !== '\n')) { - source = '(?: ' + source + ')'; - strCopy = ' ' + strCopy; - charsAdded++; - } - // ^(? + rx + ) is needed, in combination with some str slicing, to - // simulate the 'y' flag. - reCopy = new RegExp('^(?:' + source + ')', flags); - } + function Body() { + this.bodyUsed = false; - if (NPCG_INCLUDED) { - reCopy = new RegExp('^' + source + '$(?!\\s)', flags); - } - if (UPDATES_LAST_INDEX_WRONG) lastIndex = re.lastIndex; + this._initBody = function (body) { + /* + fetch-mock wraps the Response object in an ES6 Proxy to + provide useful test harness features such as flush. However, on + ES5 browsers without fetch or Proxy support pollyfills must be used; + the proxy-pollyfill is unable to proxy an attribute unless it exists + on the object before the Proxy is created. This change ensures + Response.bodyUsed exists on the instance, while maintaining the + semantic of setting Request.bodyUsed in the constructor before + _initBody is called. + */ + this.bodyUsed = this.bodyUsed; + this._bodyInit = body; - match = nativeExec.call(sticky ? reCopy : re, strCopy); + if (!body) { + this._bodyText = ''; + } else if (typeof body === 'string') { + this._bodyText = body; + } else if (support.blob && Blob.prototype.isPrototypeOf(body)) { + this._bodyBlob = body; + } else if (support.formData && FormData.prototype.isPrototypeOf(body)) { + this._bodyFormData = body; + } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) { + this._bodyText = body.toString(); + } else if (support.arrayBuffer && support.blob && isDataView(body)) { + this._bodyArrayBuffer = bufferClone(body.buffer); // IE 10-11 can't handle a DataView body. - if (sticky) { - if (match) { - match.input = match.input.slice(charsAdded); - match[0] = match[0].slice(charsAdded); - match.index = re.lastIndex; - re.lastIndex += match[0].length; - } else re.lastIndex = 0; - } else if (UPDATES_LAST_INDEX_WRONG && match) { - re.lastIndex = re.global ? match.index + match[0].length : lastIndex; - } - if (NPCG_INCLUDED && match && match.length > 1) { - // Fix browsers whose `exec` methods don't consistently return `undefined` - // for NPCG, like IE8. NOTE: This doesn' work for /(.?)?/ - nativeReplace.call(match[0], reCopy, function () { - for (i = 1; i < arguments.length - 2; i++) { - if (arguments[i] === undefined) match[i] = undefined; - } - }); + this._bodyInit = new Blob([this._bodyArrayBuffer]); + } else if (support.arrayBuffer && (ArrayBuffer.prototype.isPrototypeOf(body) || isArrayBufferView(body))) { + this._bodyArrayBuffer = bufferClone(body); + } else { + this._bodyText = body = Object.prototype.toString.call(body); } - if (match && groups) { - match.groups = object = create$7(null); - for (i = 0; i < groups.length; i++) { - group = groups[i]; - object[group[0]] = match[group[1]]; + if (!this.headers.get('content-type')) { + if (typeof body === 'string') { + this.headers.set('content-type', 'text/plain;charset=UTF-8'); + } else if (this._bodyBlob && this._bodyBlob.type) { + this.headers.set('content-type', this._bodyBlob.type); + } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) { + this.headers.set('content-type', 'application/x-www-form-urlencoded;charset=UTF-8'); } } - - return match; }; - } - - var regexpExec$3 = patchedExec; - var $$P = _export; - var exec = regexpExec$3; + if (support.blob) { + this.blob = function () { + var rejected = consumed(this); - // `RegExp.prototype.exec` method - // https://tc39.es/ecma262/#sec-regexp.prototype.exec - $$P({ target: 'RegExp', proto: true, forced: /./.exec !== exec }, { - exec: exec - }); + if (rejected) { + return rejected; + } - // TODO: Remove from `core-js@4` since it's moved to entry points + if (this._bodyBlob) { + return Promise.resolve(this._bodyBlob); + } else if (this._bodyArrayBuffer) { + return Promise.resolve(new Blob([this._bodyArrayBuffer])); + } else if (this._bodyFormData) { + throw new Error('could not read FormData body as blob'); + } else { + return Promise.resolve(new Blob([this._bodyText])); + } + }; - var redefine$4 = redefine$g.exports; - var regexpExec$2 = regexpExec$3; - var fails$m = fails$N; - var wellKnownSymbol$5 = wellKnownSymbol$s; - var createNonEnumerableProperty$1 = createNonEnumerableProperty$e; + this.arrayBuffer = function () { + if (this._bodyArrayBuffer) { + var isConsumed = consumed(this); - var SPECIES = wellKnownSymbol$5('species'); - var RegExpPrototype$1 = RegExp.prototype; + if (isConsumed) { + return isConsumed; + } - var fixRegexpWellKnownSymbolLogic = function (KEY, exec, FORCED, SHAM) { - var SYMBOL = wellKnownSymbol$5(KEY); + if (ArrayBuffer.isView(this._bodyArrayBuffer)) { + return Promise.resolve(this._bodyArrayBuffer.buffer.slice(this._bodyArrayBuffer.byteOffset, this._bodyArrayBuffer.byteOffset + this._bodyArrayBuffer.byteLength)); + } else { + return Promise.resolve(this._bodyArrayBuffer); + } + } else { + return this.blob().then(readBlobAsArrayBuffer); + } + }; + } - var DELEGATES_TO_SYMBOL = !fails$m(function () { - // String methods call symbol-named RegEp methods - var O = {}; - O[SYMBOL] = function () { return 7; }; - return ''[KEY](O) != 7; - }); + this.text = function () { + var rejected = consumed(this); - var DELEGATES_TO_EXEC = DELEGATES_TO_SYMBOL && !fails$m(function () { - // Symbol-named RegExp methods call .exec - var execCalled = false; - var re = /a/; + if (rejected) { + return rejected; + } - if (KEY === 'split') { - // We can't use real regex here since it causes deoptimization - // and serious performance degradation in V8 - // https://github.com/zloirock/core-js/issues/306 - re = {}; - // RegExp[@@split] doesn't call the regex's exec method, but first creates - // a new one. We need to return the patched regex when creating the new one. - re.constructor = {}; - re.constructor[SPECIES] = function () { return re; }; - re.flags = ''; - re[SYMBOL] = /./[SYMBOL]; + if (this._bodyBlob) { + return readBlobAsText(this._bodyBlob); + } else if (this._bodyArrayBuffer) { + return Promise.resolve(readArrayBufferAsText(this._bodyArrayBuffer)); + } else if (this._bodyFormData) { + throw new Error('could not read FormData body as text'); + } else { + return Promise.resolve(this._bodyText); } + }; - re.exec = function () { execCalled = true; return null; }; + if (support.formData) { + this.formData = function () { + return this.text().then(decode); + }; + } - re[SYMBOL](''); - return !execCalled; - }); + this.json = function () { + return this.text().then(JSON.parse); + }; - if ( - !DELEGATES_TO_SYMBOL || - !DELEGATES_TO_EXEC || - FORCED - ) { - var nativeRegExpMethod = /./[SYMBOL]; - var methods = exec(SYMBOL, ''[KEY], function (nativeMethod, regexp, str, arg2, forceStringMethod) { - var $exec = regexp.exec; - if ($exec === regexpExec$2 || $exec === RegExpPrototype$1.exec) { - if (DELEGATES_TO_SYMBOL && !forceStringMethod) { - // The native String method already delegates to @@method (this - // polyfilled function), leasing to infinite recursion. - // We avoid it by directly calling the native @@method method. - return { done: true, value: nativeRegExpMethod.call(regexp, str, arg2) }; - } - return { done: true, value: nativeMethod.call(str, regexp, arg2) }; - } - return { done: false }; - }); + return this; + } // HTTP methods whose capitalization should be normalized - redefine$4(String.prototype, KEY, methods[0]); - redefine$4(RegExpPrototype$1, SYMBOL, methods[1]); - } - if (SHAM) createNonEnumerableProperty$1(RegExpPrototype$1[SYMBOL], 'sham', true); - }; + var methods = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT']; - var charAt = stringMultibyte.charAt; + function normalizeMethod(method) { + var upcased = method.toUpperCase(); + return methods.indexOf(upcased) > -1 ? upcased : method; + } - // `AdvanceStringIndex` abstract operation - // https://tc39.es/ecma262/#sec-advancestringindex - var advanceStringIndex$3 = function (S, index, unicode) { - return index + (unicode ? charAt(S, index).length : 1); - }; + function Request(input, options) { + if (!(this instanceof Request)) { + throw new TypeError('Please use the "new" operator, this DOM object constructor cannot be called as a function.'); + } - var toObject$6 = toObject$i; + options = options || {}; + var body = options.body; - var floor$1 = Math.floor; - var replace = ''.replace; - var SUBSTITUTION_SYMBOLS = /\$([$&'`]|\d{1,2}|<[^>]*>)/g; - var SUBSTITUTION_SYMBOLS_NO_NAMED = /\$([$&'`]|\d{1,2})/g; + if (input instanceof Request) { + if (input.bodyUsed) { + throw new TypeError('Already read'); + } - // `GetSubstitution` abstract operation - // https://tc39.es/ecma262/#sec-getsubstitution - var getSubstitution$1 = function (matched, str, position, captures, namedCaptures, replacement) { - var tailPos = position + matched.length; - var m = captures.length; - var symbols = SUBSTITUTION_SYMBOLS_NO_NAMED; - if (namedCaptures !== undefined) { - namedCaptures = toObject$6(namedCaptures); - symbols = SUBSTITUTION_SYMBOLS; - } - return replace.call(replacement, symbols, function (match, ch) { - var capture; - switch (ch.charAt(0)) { - case '$': return '$'; - case '&': return matched; - case '`': return str.slice(0, position); - case "'": return str.slice(tailPos); - case '<': - capture = namedCaptures[ch.slice(1, -1)]; - break; - default: // \d\d? - var n = +ch; - if (n === 0) return match; - if (n > m) { - var f = floor$1(n / 10); - if (f === 0) return match; - if (f <= m) return captures[f - 1] === undefined ? ch.charAt(1) : captures[f - 1] + ch.charAt(1); - return match; - } - capture = captures[n - 1]; + this.url = input.url; + this.credentials = input.credentials; + + if (!options.headers) { + this.headers = new Headers(input.headers); } - return capture === undefined ? '' : capture; - }); - }; - var classof$3 = classofRaw$1; - var regexpExec$1 = regexpExec$3; + this.method = input.method; + this.mode = input.mode; + this.signal = input.signal; - // `RegExpExec` abstract operation - // https://tc39.es/ecma262/#sec-regexpexec - var regexpExecAbstract = function (R, S) { - var exec = R.exec; - if (typeof exec === 'function') { - var result = exec.call(R, S); - if (typeof result !== 'object') { - throw TypeError('RegExp exec method returned something other than an Object or null'); + if (!body && input._bodyInit != null) { + body = input._bodyInit; + input.bodyUsed = true; } - return result; + } else { + this.url = String(input); } - if (classof$3(R) !== 'RegExp') { - throw TypeError('RegExp#exec called on incompatible receiver'); - } + this.credentials = options.credentials || this.credentials || 'same-origin'; - return regexpExec$1.call(R, S); - }; + if (options.headers || !this.headers) { + this.headers = new Headers(options.headers); + } - var fixRegExpWellKnownSymbolLogic$3 = fixRegexpWellKnownSymbolLogic; - var fails$l = fails$N; - var anObject$5 = anObject$m; - var toLength$8 = toLength$q; - var toInteger$3 = toInteger$b; - var requireObjectCoercible$a = requireObjectCoercible$e; - var advanceStringIndex$2 = advanceStringIndex$3; - var getSubstitution = getSubstitution$1; - var regExpExec$2 = regexpExecAbstract; - var wellKnownSymbol$4 = wellKnownSymbol$s; + this.method = normalizeMethod(options.method || this.method || 'GET'); + this.mode = options.mode || this.mode || null; + this.signal = options.signal || this.signal; + this.referrer = null; - var REPLACE = wellKnownSymbol$4('replace'); - var max$2 = Math.max; - var min$5 = Math.min; + if ((this.method === 'GET' || this.method === 'HEAD') && body) { + throw new TypeError('Body not allowed for GET or HEAD requests'); + } - var maybeToString = function (it) { - return it === undefined ? it : String(it); - }; + this._initBody(body); - // IE <= 11 replaces $0 with the whole match, as if it was $& - // https://stackoverflow.com/questions/6024666/getting-ie-to-replace-a-regex-with-the-literal-string-0 - var REPLACE_KEEPS_$0 = (function () { - // eslint-disable-next-line regexp/prefer-escape-replacement-dollar-char -- required for testing - return 'a'.replace(/./, '$0') === '$0'; - })(); + if (this.method === 'GET' || this.method === 'HEAD') { + if (options.cache === 'no-store' || options.cache === 'no-cache') { + // Search for a '_' parameter in the query string + var reParamSearch = /([?&])_=[^&]*/; - // Safari <= 13.0.3(?) substitutes nth capture where n>m with an empty string - var REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE = (function () { - if (/./[REPLACE]) { - return /./[REPLACE]('a', '$0') === ''; + if (reParamSearch.test(this.url)) { + // If it already exists then set the value with the current time + this.url = this.url.replace(reParamSearch, '$1_=' + new Date().getTime()); + } else { + // Otherwise add a new '_' parameter to the end with the current time + var reQueryString = /\?/; + this.url += (reQueryString.test(this.url) ? '&' : '?') + '_=' + new Date().getTime(); + } + } } - return false; - })(); - - var REPLACE_SUPPORTS_NAMED_GROUPS = !fails$l(function () { - var re = /./; - re.exec = function () { - var result = []; - result.groups = { a: '7' }; - return result; - }; - return ''.replace(re, '$') !== '7'; - }); + } - // @@replace logic - fixRegExpWellKnownSymbolLogic$3('replace', function (_, nativeReplace, maybeCallNative) { - var UNSAFE_SUBSTITUTE = REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE ? '$' : '$0'; + Request.prototype.clone = function () { + return new Request(this, { + body: this._bodyInit + }); + }; - return [ - // `String.prototype.replace` method - // https://tc39.es/ecma262/#sec-string.prototype.replace - function replace(searchValue, replaceValue) { - var O = requireObjectCoercible$a(this); - var replacer = searchValue == undefined ? undefined : searchValue[REPLACE]; - return replacer !== undefined - ? replacer.call(searchValue, O, replaceValue) - : nativeReplace.call(String(O), searchValue, replaceValue); - }, - // `RegExp.prototype[@@replace]` method - // https://tc39.es/ecma262/#sec-regexp.prototype-@@replace - function (string, replaceValue) { - if ( - typeof replaceValue === 'string' && - replaceValue.indexOf(UNSAFE_SUBSTITUTE) === -1 && - replaceValue.indexOf('$<') === -1 - ) { - var res = maybeCallNative(nativeReplace, this, string, replaceValue); - if (res.done) return res.value; - } + function decode(body) { + var form = new FormData(); + body.trim().split('&').forEach(function (bytes) { + if (bytes) { + var split = bytes.split('='); + var name = split.shift().replace(/\+/g, ' '); + var value = split.join('=').replace(/\+/g, ' '); + form.append(decodeURIComponent(name), decodeURIComponent(value)); + } + }); + return form; + } - var rx = anObject$5(this); - var S = String(string); + function parseHeaders(rawHeaders) { + var headers = new Headers(); // Replace instances of \r\n and \n followed by at least one space or horizontal tab with a space + // https://tools.ietf.org/html/rfc7230#section-3.2 - var functionalReplace = typeof replaceValue === 'function'; - if (!functionalReplace) replaceValue = String(replaceValue); + var preProcessedHeaders = rawHeaders.replace(/\r?\n[\t ]+/g, ' '); // Avoiding split via regex to work around a common IE11 bug with the core-js 3.6.0 regex polyfill + // https://github.com/github/fetch/issues/748 + // https://github.com/zloirock/core-js/issues/751 - var global = rx.global; - if (global) { - var fullUnicode = rx.unicode; - rx.lastIndex = 0; - } - var results = []; - while (true) { - var result = regExpExec$2(rx, S); - if (result === null) break; + preProcessedHeaders.split('\r').map(function (header) { + return header.indexOf('\n') === 0 ? header.substr(1, header.length) : header; + }).forEach(function (line) { + var parts = line.split(':'); + var key = parts.shift().trim(); - results.push(result); - if (!global) break; + if (key) { + var value = parts.join(':').trim(); + headers.append(key, value); + } + }); + return headers; + } - var matchStr = String(result[0]); - if (matchStr === '') rx.lastIndex = advanceStringIndex$2(S, toLength$8(rx.lastIndex), fullUnicode); - } + Body.call(Request.prototype); + function Response(bodyInit, options) { + if (!(this instanceof Response)) { + throw new TypeError('Please use the "new" operator, this DOM object constructor cannot be called as a function.'); + } - var accumulatedResult = ''; - var nextSourcePosition = 0; - for (var i = 0; i < results.length; i++) { - result = results[i]; + if (!options) { + options = {}; + } - var matched = String(result[0]); - var position = max$2(min$5(toInteger$3(result.index), S.length), 0); - var captures = []; - // NOTE: This is equivalent to - // captures = result.slice(1).map(maybeToString) - // but for some reason `nativeSlice.call(result, 1, result.length)` (called in - // the slice polyfill when slicing native arrays) "doesn't work" in safari 9 and - // causes a crash (https://pastebin.com/N21QzeQA) when trying to debug it. - for (var j = 1; j < result.length; j++) captures.push(maybeToString(result[j])); - var namedCaptures = result.groups; - if (functionalReplace) { - var replacerArgs = [matched].concat(captures, position, S); - if (namedCaptures !== undefined) replacerArgs.push(namedCaptures); - var replacement = String(replaceValue.apply(undefined, replacerArgs)); - } else { - replacement = getSubstitution(matched, S, position, captures, namedCaptures, replaceValue); - } - if (position >= nextSourcePosition) { - accumulatedResult += S.slice(nextSourcePosition, position) + replacement; - nextSourcePosition = position + matched.length; - } - } - return accumulatedResult + S.slice(nextSourcePosition); - } - ]; - }, !REPLACE_SUPPORTS_NAMED_GROUPS || !REPLACE_KEEPS_$0 || REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE); + this.type = 'default'; + this.status = options.status === undefined ? 200 : options.status; + this.ok = this.status >= 200 && this.status < 300; + this.statusText = options.statusText === undefined ? '' : '' + options.statusText; + this.headers = new Headers(options.headers); + this.url = options.url || ''; - var isObject$b = isObject$r; - var classof$2 = classofRaw$1; - var wellKnownSymbol$3 = wellKnownSymbol$s; + this._initBody(bodyInit); + } + Body.call(Response.prototype); - var MATCH$2 = wellKnownSymbol$3('match'); + Response.prototype.clone = function () { + return new Response(this._bodyInit, { + status: this.status, + statusText: this.statusText, + headers: new Headers(this.headers), + url: this.url + }); + }; - // `IsRegExp` abstract operation - // https://tc39.es/ecma262/#sec-isregexp - var isRegexp = function (it) { - var isRegExp; - return isObject$b(it) && ((isRegExp = it[MATCH$2]) !== undefined ? !!isRegExp : classof$2(it) == 'RegExp'); + Response.error = function () { + var response = new Response(null, { + status: 0, + statusText: '' + }); + response.type = 'error'; + return response; }; - var fixRegExpWellKnownSymbolLogic$2 = fixRegexpWellKnownSymbolLogic; - var isRegExp$2 = isRegexp; - var anObject$4 = anObject$m; - var requireObjectCoercible$9 = requireObjectCoercible$e; - var speciesConstructor$1 = speciesConstructor$8; - var advanceStringIndex$1 = advanceStringIndex$3; - var toLength$7 = toLength$q; - var callRegExpExec = regexpExecAbstract; - var regexpExec = regexpExec$3; - var stickyHelpers$1 = regexpStickyHelpers; - var fails$k = fails$N; + var redirectStatuses = [301, 302, 303, 307, 308]; - var UNSUPPORTED_Y$1 = stickyHelpers$1.UNSUPPORTED_Y; - var arrayPush = [].push; - var min$4 = Math.min; - var MAX_UINT32 = 0xFFFFFFFF; + Response.redirect = function (url, status) { + if (redirectStatuses.indexOf(status) === -1) { + throw new RangeError('Invalid status code'); + } - // Chrome 51 has a buggy "split" implementation when RegExp#exec !== nativeExec - // Weex JS has frozen built-in prototypes, so use try / catch wrapper - var SPLIT_WORKS_WITH_OVERWRITTEN_EXEC = !fails$k(function () { - // eslint-disable-next-line regexp/no-empty-group -- required for testing - var re = /(?:)/; - var originalExec = re.exec; - re.exec = function () { return originalExec.apply(this, arguments); }; - var result = 'ab'.split(re); - return result.length !== 2 || result[0] !== 'a' || result[1] !== 'b'; - }); + return new Response(null, { + status: status, + headers: { + location: url + } + }); + }; - // @@split logic - fixRegExpWellKnownSymbolLogic$2('split', function (SPLIT, nativeSplit, maybeCallNative) { - var internalSplit; - if ( - 'abbc'.split(/(b)*/)[1] == 'c' || - // eslint-disable-next-line regexp/no-empty-group -- required for testing - 'test'.split(/(?:)/, -1).length != 4 || - 'ab'.split(/(?:ab)*/).length != 2 || - '.'.split(/(.?)(.?)/).length != 4 || - // eslint-disable-next-line regexp/no-assertion-capturing-group, regexp/no-empty-group -- required for testing - '.'.split(/()()/).length > 1 || - ''.split(/.?/).length - ) { - // based on es5-shim implementation, need to rework it - internalSplit = function (separator, limit) { - var string = String(requireObjectCoercible$9(this)); - var lim = limit === undefined ? MAX_UINT32 : limit >>> 0; - if (lim === 0) return []; - if (separator === undefined) return [string]; - // If `separator` is not a regex, use native split - if (!isRegExp$2(separator)) { - return nativeSplit.call(string, separator, lim); - } - var output = []; - var flags = (separator.ignoreCase ? 'i' : '') + - (separator.multiline ? 'm' : '') + - (separator.unicode ? 'u' : '') + - (separator.sticky ? 'y' : ''); - var lastLastIndex = 0; - // Make `global` and avoid `lastIndex` issues by working with a copy - var separatorCopy = new RegExp(separator.source, flags + 'g'); - var match, lastIndex, lastLength; - while (match = regexpExec.call(separatorCopy, string)) { - lastIndex = separatorCopy.lastIndex; - if (lastIndex > lastLastIndex) { - output.push(string.slice(lastLastIndex, match.index)); - if (match.length > 1 && match.index < string.length) arrayPush.apply(output, match.slice(1)); - lastLength = match[0].length; - lastLastIndex = lastIndex; - if (output.length >= lim) break; - } - if (separatorCopy.lastIndex === match.index) separatorCopy.lastIndex++; // Avoid an infinite loop - } - if (lastLastIndex === string.length) { - if (lastLength || !separatorCopy.test('')) output.push(''); - } else output.push(string.slice(lastLastIndex)); - return output.length > lim ? output.slice(0, lim) : output; - }; - // Chakra, V8 - } else if ('0'.split(undefined, 0).length) { - internalSplit = function (separator, limit) { - return separator === undefined && limit === 0 ? [] : nativeSplit.call(this, separator, limit); - }; - } else internalSplit = nativeSplit; + var DOMException$1 = global$k.DOMException; - return [ - // `String.prototype.split` method - // https://tc39.es/ecma262/#sec-string.prototype.split - function split(separator, limit) { - var O = requireObjectCoercible$9(this); - var splitter = separator == undefined ? undefined : separator[SPLIT]; - return splitter !== undefined - ? splitter.call(separator, O, limit) - : internalSplit.call(String(O), separator, limit); - }, - // `RegExp.prototype[@@split]` method - // https://tc39.es/ecma262/#sec-regexp.prototype-@@split - // - // NOTE: This cannot be properly polyfilled in engines that don't support - // the 'y' flag. - function (string, limit) { - var res = maybeCallNative(internalSplit, this, string, limit, internalSplit !== nativeSplit); - if (res.done) return res.value; + try { + new DOMException$1(); + } catch (err) { + DOMException$1 = function DOMException(message, name) { + this.message = message; + this.name = name; + var error = Error(message); + this.stack = error.stack; + }; - var rx = anObject$4(this); - var S = String(string); - var C = speciesConstructor$1(rx, RegExp); + DOMException$1.prototype = Object.create(Error.prototype); + DOMException$1.prototype.constructor = DOMException$1; + } - var unicodeMatching = rx.unicode; - var flags = (rx.ignoreCase ? 'i' : '') + - (rx.multiline ? 'm' : '') + - (rx.unicode ? 'u' : '') + - (UNSUPPORTED_Y$1 ? 'g' : 'y'); + function fetch$1(input, init) { + return new Promise(function (resolve, reject) { + var request = new Request(input, init); - // ^(? + rx + ) is needed, in combination with some S slicing, to - // simulate the 'y' flag. - var splitter = new C(UNSUPPORTED_Y$1 ? '^(?:' + rx.source + ')' : rx, flags); - var lim = limit === undefined ? MAX_UINT32 : limit >>> 0; - if (lim === 0) return []; - if (S.length === 0) return callRegExpExec(splitter, S) === null ? [S] : []; - var p = 0; - var q = 0; - var A = []; - while (q < S.length) { - splitter.lastIndex = UNSUPPORTED_Y$1 ? 0 : q; - var z = callRegExpExec(splitter, UNSUPPORTED_Y$1 ? S.slice(q) : S); - var e; - if ( - z === null || - (e = min$4(toLength$7(splitter.lastIndex + (UNSUPPORTED_Y$1 ? q : 0)), S.length)) === p - ) { - q = advanceStringIndex$1(S, q, unicodeMatching); - } else { - A.push(S.slice(p, q)); - if (A.length === lim) return A; - for (var i = 1; i <= z.length - 1; i++) { - A.push(z[i]); - if (A.length === lim) return A; - } - q = p = e; - } - } - A.push(S.slice(p)); - return A; + if (request.signal && request.signal.aborted) { + return reject(new DOMException$1('Aborted', 'AbortError')); } - ]; - }, !SPLIT_WORKS_WITH_OVERWRITTEN_EXEC, UNSUPPORTED_Y$1); - // a string of all valid unicode whitespaces - var whitespaces$4 = '\u0009\u000A\u000B\u000C\u000D\u0020\u00A0\u1680\u2000\u2001\u2002' + - '\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF'; + var xhr = new XMLHttpRequest(); - var requireObjectCoercible$8 = requireObjectCoercible$e; - var whitespaces$3 = whitespaces$4; + function abortXhr() { + xhr.abort(); + } - var whitespace = '[' + whitespaces$3 + ']'; - var ltrim = RegExp('^' + whitespace + whitespace + '*'); - var rtrim$2 = RegExp(whitespace + whitespace + '*$'); + xhr.onload = function () { + var options = { + status: xhr.status, + statusText: xhr.statusText, + headers: parseHeaders(xhr.getAllResponseHeaders() || '') + }; + options.url = 'responseURL' in xhr ? xhr.responseURL : options.headers.get('X-Request-URL'); + var body = 'response' in xhr ? xhr.response : xhr.responseText; + setTimeout(function () { + resolve(new Response(body, options)); + }, 0); + }; - // `String.prototype.{ trim, trimStart, trimEnd, trimLeft, trimRight }` methods implementation - var createMethod$2 = function (TYPE) { - return function ($this) { - var string = String(requireObjectCoercible$8($this)); - if (TYPE & 1) string = string.replace(ltrim, ''); - if (TYPE & 2) string = string.replace(rtrim$2, ''); - return string; - }; - }; + xhr.onerror = function () { + setTimeout(function () { + reject(new TypeError('Network request failed')); + }, 0); + }; - var stringTrim = { - // `String.prototype.{ trimLeft, trimStart }` methods - // https://tc39.es/ecma262/#sec-string.prototype.trimstart - start: createMethod$2(1), - // `String.prototype.{ trimRight, trimEnd }` methods - // https://tc39.es/ecma262/#sec-string.prototype.trimend - end: createMethod$2(2), - // `String.prototype.trim` method - // https://tc39.es/ecma262/#sec-string.prototype.trim - trim: createMethod$2(3) - }; + xhr.ontimeout = function () { + setTimeout(function () { + reject(new TypeError('Network request failed')); + }, 0); + }; - var fails$j = fails$N; - var whitespaces$2 = whitespaces$4; + xhr.onabort = function () { + setTimeout(function () { + reject(new DOMException$1('Aborted', 'AbortError')); + }, 0); + }; - var non = '\u200B\u0085\u180E'; + function fixUrl(url) { + try { + return url === '' && global$k.location.href ? global$k.location.href : url; + } catch (e) { + return url; + } + } - // check that a method works with the correct list - // of whitespaces and has a correct name - var stringTrimForced = function (METHOD_NAME) { - return fails$j(function () { - return !!whitespaces$2[METHOD_NAME]() || non[METHOD_NAME]() != non || whitespaces$2[METHOD_NAME].name !== METHOD_NAME; - }); - }; + xhr.open(request.method, fixUrl(request.url), true); - var $$O = _export; - var $trim = stringTrim.trim; - var forcedStringTrimMethod = stringTrimForced; + if (request.credentials === 'include') { + xhr.withCredentials = true; + } else if (request.credentials === 'omit') { + xhr.withCredentials = false; + } - // `String.prototype.trim` method - // https://tc39.es/ecma262/#sec-string.prototype.trim - $$O({ target: 'String', proto: true, forced: forcedStringTrimMethod('trim') }, { - trim: function trim() { - return $trim(this); - } - }); + if ('responseType' in xhr) { + if (support.blob) { + xhr.responseType = 'blob'; + } else if (support.arrayBuffer && request.headers.get('Content-Type') && request.headers.get('Content-Type').indexOf('application/octet-stream') !== -1) { + xhr.responseType = 'arraybuffer'; + } + } - var DESCRIPTORS$9 = descriptors; - var defineProperty$4 = objectDefineProperty.f; + if (init && _typeof(init.headers) === 'object' && !(init.headers instanceof Headers)) { + Object.getOwnPropertyNames(init.headers).forEach(function (name) { + xhr.setRequestHeader(name, normalizeValue(init.headers[name])); + }); + } else { + request.headers.forEach(function (value, name) { + xhr.setRequestHeader(name, value); + }); + } - var FunctionPrototype = Function.prototype; - var FunctionPrototypeToString = FunctionPrototype.toString; - var nameRE = /^\s*function ([^ (]*)/; - var NAME = 'name'; + if (request.signal) { + request.signal.addEventListener('abort', abortXhr); - // Function instances `.name` property - // https://tc39.es/ecma262/#sec-function-instances-name - if (DESCRIPTORS$9 && !(NAME in FunctionPrototype)) { - defineProperty$4(FunctionPrototype, NAME, { - configurable: true, - get: function () { - try { - return FunctionPrototypeToString.call(this).match(nameRE)[1]; - } catch (error) { - return ''; - } + xhr.onreadystatechange = function () { + // DONE (success or failure) + if (xhr.readyState === 4) { + request.signal.removeEventListener('abort', abortXhr); + } + }; } + + xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit); }); } + fetch$1.polyfill = true; - var $$N = _export; - var DESCRIPTORS$8 = descriptors; - var create$6 = objectCreate; + if (!global$k.fetch) { + global$k.fetch = fetch$1; + global$k.Headers = Headers; + global$k.Request = Request; + global$k.Response = Response; + } - // `Object.create` method - // https://tc39.es/ecma262/#sec-object.create - $$N({ target: 'Object', stat: true, sham: !DESCRIPTORS$8 }, { - create: create$6 + var $$T = _export; + var DESCRIPTORS$9 = descriptors; + var objectDefinePropertyModile = objectDefineProperty; + + // `Object.defineProperty` method + // https://tc39.es/ecma262/#sec-object.defineproperty + $$T({ target: 'Object', stat: true, forced: !DESCRIPTORS$9, sham: !DESCRIPTORS$9 }, { + defineProperty: objectDefinePropertyModile.f }); - var $$M = _export; - var global$9 = global$F; - var userAgent = engineUserAgent; + var $$S = _export; + var setPrototypeOf = objectSetPrototypeOf; - var slice$3 = [].slice; - var MSIE = /MSIE .\./.test(userAgent); // <- dirty ie9- check + // `Object.setPrototypeOf` method + // https://tc39.es/ecma262/#sec-object.setprototypeof + $$S({ target: 'Object', stat: true }, { + setPrototypeOf: setPrototypeOf + }); - var wrap$1 = function (scheduler) { - return function (handler, timeout /* , ...arguments */) { - var boundArgs = arguments.length > 2; - var args = boundArgs ? slice$3.call(arguments, 2) : undefined; - return scheduler(boundArgs ? function () { - // eslint-disable-next-line no-new-func -- spec requirement - (typeof handler == 'function' ? handler : Function(handler)).apply(this, args); - } : handler, timeout); - }; - }; + var $$R = _export; + var fails$n = fails$S; + var toObject$8 = toObject$j; + var nativeGetPrototypeOf = objectGetPrototypeOf; + var CORRECT_PROTOTYPE_GETTER = correctPrototypeGetter; - // ie9- setTimeout & setInterval additional parameters fix - // https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers - $$M({ global: true, bind: true, forced: MSIE }, { - // `setTimeout` method - // https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#dom-settimeout - setTimeout: wrap$1(global$9.setTimeout), - // `setInterval` method - // https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#dom-setinterval - setInterval: wrap$1(global$9.setInterval) + var FAILS_ON_PRIMITIVES$4 = fails$n(function () { nativeGetPrototypeOf(1); }); + + // `Object.getPrototypeOf` method + // https://tc39.es/ecma262/#sec-object.getprototypeof + $$R({ target: 'Object', stat: true, forced: FAILS_ON_PRIMITIVES$4, sham: !CORRECT_PROTOTYPE_GETTER }, { + getPrototypeOf: function getPrototypeOf(it) { + return nativeGetPrototypeOf(toObject$8(it)); + } }); - var global$8 = typeof globalThis !== 'undefined' && globalThis || typeof self !== 'undefined' && self || typeof global$8 !== 'undefined' && global$8; - var support = { - searchParams: 'URLSearchParams' in global$8, - iterable: 'Symbol' in global$8 && 'iterator' in Symbol, - blob: 'FileReader' in global$8 && 'Blob' in global$8 && function () { - try { - new Blob(); - return true; - } catch (e) { - return false; - } - }(), - formData: 'FormData' in global$8, - arrayBuffer: 'ArrayBuffer' in global$8 - }; + var global$j = global$1m; + var uncurryThis$m = functionUncurryThis; + var aCallable$2 = aCallable$a; + var isObject$b = isObject$s; + var hasOwn$5 = hasOwnProperty_1; + var arraySlice$2 = arraySlice$c; - function isDataView(obj) { - return obj && DataView.prototype.isPrototypeOf(obj); - } + var Function$1 = global$j.Function; + var concat$1 = uncurryThis$m([].concat); + var join$3 = uncurryThis$m([].join); + var factories = {}; - if (support.arrayBuffer) { - var viewClasses = ['[object Int8Array]', '[object Uint8Array]', '[object Uint8ClampedArray]', '[object Int16Array]', '[object Uint16Array]', '[object Int32Array]', '[object Uint32Array]', '[object Float32Array]', '[object Float64Array]']; + var construct = function (C, argsLength, args) { + if (!hasOwn$5(factories, argsLength)) { + for (var list = [], i = 0; i < argsLength; i++) list[i] = 'a[' + i + ']'; + factories[argsLength] = Function$1('C,a', 'return new C(' + join$3(list, ',') + ')'); + } return factories[argsLength](C, args); + }; - var isArrayBufferView = ArrayBuffer.isView || function (obj) { - return obj && viewClasses.indexOf(Object.prototype.toString.call(obj)) > -1; + // `Function.prototype.bind` method implementation + // https://tc39.es/ecma262/#sec-function.prototype.bind + var functionBind = Function$1.bind || function bind(that /* , ...args */) { + var F = aCallable$2(this); + var Prototype = F.prototype; + var partArgs = arraySlice$2(arguments, 1); + var boundFunction = function bound(/* args... */) { + var args = concat$1(partArgs, arraySlice$2(arguments)); + return this instanceof boundFunction ? construct(F, args.length, args) : F.apply(that, args); }; - } - - function normalizeName(name) { - if (typeof name !== 'string') { - name = String(name); - } + if (isObject$b(Prototype)) boundFunction.prototype = Prototype; + return boundFunction; + }; - if (/[^a-z0-9\-#$%&'*+.^_`|~!]/i.test(name) || name === '') { - throw new TypeError('Invalid character in header field name: "' + name + '"'); - } + var $$Q = _export; + var getBuiltIn$1 = getBuiltIn$b; + var apply = functionApply; + var bind$7 = functionBind; + var aConstructor = aConstructor$3; + var anObject$4 = anObject$n; + var isObject$a = isObject$s; + var create$4 = objectCreate; + var fails$m = fails$S; - return name.toLowerCase(); - } + var nativeConstruct = getBuiltIn$1('Reflect', 'construct'); + var ObjectPrototype = Object.prototype; + var push$4 = [].push; - function normalizeValue(value) { - if (typeof value !== 'string') { - value = String(value); - } + // `Reflect.construct` method + // https://tc39.es/ecma262/#sec-reflect.construct + // MS Edge supports only 2 arguments and argumentsList argument is optional + // FF Nightly sets third argument as `new.target`, but does not create `this` from it + var NEW_TARGET_BUG = fails$m(function () { + function F() { /* empty */ } + return !(nativeConstruct(function () { /* empty */ }, [], F) instanceof F); + }); - return value; - } // Build a destructive iterator for the value list + var ARGS_BUG = !fails$m(function () { + nativeConstruct(function () { /* empty */ }); + }); + var FORCED$c = NEW_TARGET_BUG || ARGS_BUG; - function iteratorFor(items) { - var iterator = { - next: function next() { - var value = items.shift(); - return { - done: value === undefined, - value: value - }; + $$Q({ target: 'Reflect', stat: true, forced: FORCED$c, sham: FORCED$c }, { + construct: function construct(Target, args /* , newTarget */) { + aConstructor(Target); + anObject$4(args); + var newTarget = arguments.length < 3 ? Target : aConstructor(arguments[2]); + if (ARGS_BUG && !NEW_TARGET_BUG) return nativeConstruct(Target, args, newTarget); + if (Target == newTarget) { + // w/o altered newTarget, optimization for 0-4 arguments + switch (args.length) { + case 0: return new Target(); + case 1: return new Target(args[0]); + case 2: return new Target(args[0], args[1]); + case 3: return new Target(args[0], args[1], args[2]); + case 4: return new Target(args[0], args[1], args[2], args[3]); + } + // w/o altered newTarget, lot of arguments case + var $args = [null]; + apply(push$4, $args, args); + return new (apply(bind$7, Target, $args))(); } - }; - - if (support.iterable) { - iterator[Symbol.iterator] = function () { - return iterator; - }; + // with altered newTarget, not support built-in constructors + var proto = newTarget.prototype; + var instance = create$4(isObject$a(proto) ? proto : ObjectPrototype); + var result = apply(Target, instance, args); + return isObject$a(result) ? result : instance; } + }); - return iterator; - } + var hasOwn$4 = hasOwnProperty_1; - function Headers(headers) { - this.map = {}; + var isDataDescriptor$1 = function (descriptor) { + return descriptor !== undefined && (hasOwn$4(descriptor, 'value') || hasOwn$4(descriptor, 'writable')); + }; - if (headers instanceof Headers) { - headers.forEach(function (value, name) { - this.append(name, value); - }, this); - } else if (Array.isArray(headers)) { - headers.forEach(function (header) { - this.append(header[0], header[1]); - }, this); - } else if (headers) { - Object.getOwnPropertyNames(headers).forEach(function (name) { - this.append(name, headers[name]); - }, this); - } + var $$P = _export; + var call$6 = functionCall; + var isObject$9 = isObject$s; + var anObject$3 = anObject$n; + var isDataDescriptor = isDataDescriptor$1; + var getOwnPropertyDescriptorModule = objectGetOwnPropertyDescriptor; + var getPrototypeOf = objectGetPrototypeOf; + + // `Reflect.get` method + // https://tc39.es/ecma262/#sec-reflect.get + function get$3(target, propertyKey /* , receiver */) { + var receiver = arguments.length < 3 ? target : arguments[2]; + var descriptor, prototype; + if (anObject$3(target) === receiver) return target[propertyKey]; + descriptor = getOwnPropertyDescriptorModule.f(target, propertyKey); + if (descriptor) return isDataDescriptor(descriptor) + ? descriptor.value + : descriptor.get === undefined ? undefined : call$6(descriptor.get, receiver); + if (isObject$9(prototype = getPrototypeOf(target))) return get$3(prototype, propertyKey, receiver); } - Headers.prototype.append = function (name, value) { - name = normalizeName(name); - value = normalizeValue(value); - var oldValue = this.map[name]; - this.map[name] = oldValue ? oldValue + ', ' + value : value; - }; + $$P({ target: 'Reflect', stat: true }, { + get: get$3 + }); - Headers.prototype['delete'] = function (name) { - delete this.map[normalizeName(name)]; - }; + var $$O = _export; + var fails$l = fails$S; + var toIndexedObject$1 = toIndexedObject$c; + var nativeGetOwnPropertyDescriptor = objectGetOwnPropertyDescriptor.f; + var DESCRIPTORS$8 = descriptors; - Headers.prototype.get = function (name) { - name = normalizeName(name); - return this.has(name) ? this.map[name] : null; - }; + var FAILS_ON_PRIMITIVES$3 = fails$l(function () { nativeGetOwnPropertyDescriptor(1); }); + var FORCED$b = !DESCRIPTORS$8 || FAILS_ON_PRIMITIVES$3; - Headers.prototype.has = function (name) { - return this.map.hasOwnProperty(normalizeName(name)); - }; + // `Object.getOwnPropertyDescriptor` method + // https://tc39.es/ecma262/#sec-object.getownpropertydescriptor + $$O({ target: 'Object', stat: true, forced: FORCED$b, sham: !DESCRIPTORS$8 }, { + getOwnPropertyDescriptor: function getOwnPropertyDescriptor(it, key) { + return nativeGetOwnPropertyDescriptor(toIndexedObject$1(it), key); + } + }); - Headers.prototype.set = function (name, value) { - this.map[normalizeName(name)] = normalizeValue(value); - }; + var $$N = _export; + var global$i = global$1m; + var toAbsoluteIndex$1 = toAbsoluteIndex$8; + var toIntegerOrInfinity$2 = toIntegerOrInfinity$b; + var lengthOfArrayLike$5 = lengthOfArrayLike$g; + var toObject$7 = toObject$j; + var arraySpeciesCreate$2 = arraySpeciesCreate$4; + var createProperty$2 = createProperty$4; + var arrayMethodHasSpeciesSupport$2 = arrayMethodHasSpeciesSupport$5; - Headers.prototype.forEach = function (callback, thisArg) { - for (var name in this.map) { - if (this.map.hasOwnProperty(name)) { - callback.call(thisArg, this.map[name], name, this); + var HAS_SPECIES_SUPPORT$1 = arrayMethodHasSpeciesSupport$2('splice'); + + var TypeError$6 = global$i.TypeError; + var max$1 = Math.max; + var min$3 = Math.min; + var MAX_SAFE_INTEGER$1 = 0x1FFFFFFFFFFFFF; + var MAXIMUM_ALLOWED_LENGTH_EXCEEDED = 'Maximum allowed length exceeded'; + + // `Array.prototype.splice` method + // https://tc39.es/ecma262/#sec-array.prototype.splice + // with adding support of @@species + $$N({ target: 'Array', proto: true, forced: !HAS_SPECIES_SUPPORT$1 }, { + splice: function splice(start, deleteCount /* , ...items */) { + var O = toObject$7(this); + var len = lengthOfArrayLike$5(O); + var actualStart = toAbsoluteIndex$1(start, len); + var argumentsLength = arguments.length; + var insertCount, actualDeleteCount, A, k, from, to; + if (argumentsLength === 0) { + insertCount = actualDeleteCount = 0; + } else if (argumentsLength === 1) { + insertCount = 0; + actualDeleteCount = len - actualStart; + } else { + insertCount = argumentsLength - 2; + actualDeleteCount = min$3(max$1(toIntegerOrInfinity$2(deleteCount), 0), len - actualStart); + } + if (len + insertCount - actualDeleteCount > MAX_SAFE_INTEGER$1) { + throw TypeError$6(MAXIMUM_ALLOWED_LENGTH_EXCEEDED); + } + A = arraySpeciesCreate$2(O, actualDeleteCount); + for (k = 0; k < actualDeleteCount; k++) { + from = actualStart + k; + if (from in O) createProperty$2(A, k, O[from]); + } + A.length = actualDeleteCount; + if (insertCount < actualDeleteCount) { + for (k = actualStart; k < len - actualDeleteCount; k++) { + from = k + actualDeleteCount; + to = k + insertCount; + if (from in O) O[to] = O[from]; + else delete O[to]; + } + for (k = len; k > len - actualDeleteCount + insertCount; k--) delete O[k - 1]; + } else if (insertCount > actualDeleteCount) { + for (k = len - actualDeleteCount; k > actualStart; k--) { + from = k + actualDeleteCount - 1; + to = k + insertCount - 1; + if (from in O) O[to] = O[from]; + else delete O[to]; + } + } + for (k = 0; k < insertCount; k++) { + O[k + actualStart] = arguments[k + 2]; } + O.length = len - actualDeleteCount + insertCount; + return A; } - }; + }); - Headers.prototype.keys = function () { - var items = []; - this.forEach(function (value, name) { - items.push(name); - }); - return iteratorFor(items); - }; + var defineWellKnownSymbol$1 = defineWellKnownSymbol$4; - Headers.prototype.values = function () { - var items = []; - this.forEach(function (value) { - items.push(value); - }); - return iteratorFor(items); - }; + // `Symbol.toStringTag` well-known symbol + // https://tc39.es/ecma262/#sec-symbol.tostringtag + defineWellKnownSymbol$1('toStringTag'); - Headers.prototype.entries = function () { - var items = []; - this.forEach(function (value, name) { - items.push([name, value]); - }); - return iteratorFor(items); - }; + var global$h = global$1m; + var setToStringTag$3 = setToStringTag$a; - if (support.iterable) { - Headers.prototype[Symbol.iterator] = Headers.prototype.entries; - } + // JSON[@@toStringTag] property + // https://tc39.es/ecma262/#sec-json-@@tostringtag + setToStringTag$3(global$h.JSON, 'JSON', true); - function consumed(body) { - if (body.bodyUsed) { - return Promise.reject(new TypeError('Already read')); - } + var setToStringTag$2 = setToStringTag$a; - body.bodyUsed = true; - } + // Math[@@toStringTag] property + // https://tc39.es/ecma262/#sec-math-@@tostringtag + setToStringTag$2(Math, 'Math', true); - function fileReaderReady(reader) { - return new Promise(function (resolve, reject) { - reader.onload = function () { - resolve(reader.result); - }; + (function (factory) { + factory(); + })(function () { - reader.onerror = function () { - reject(reader.error); - }; - }); - } + function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + } - function readBlobAsArrayBuffer(blob) { - var reader = new FileReader(); - var promise = fileReaderReady(reader); - reader.readAsArrayBuffer(blob); - return promise; - } + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } - function readBlobAsText(blob) { - var reader = new FileReader(); - var promise = fileReaderReady(reader); - reader.readAsText(blob); - return promise; - } + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; + } - function readArrayBufferAsText(buf) { - var view = new Uint8Array(buf); - var chars = new Array(view.length); + function _inherits(subClass, superClass) { + if (typeof superClass !== "function" && superClass !== null) { + throw new TypeError("Super expression must either be null or a function"); + } - for (var i = 0; i < view.length; i++) { - chars[i] = String.fromCharCode(view[i]); + subClass.prototype = Object.create(superClass && superClass.prototype, { + constructor: { + value: subClass, + writable: true, + configurable: true + } + }); + if (superClass) _setPrototypeOf(subClass, superClass); } - return chars.join(''); - } - - function bufferClone(buf) { - if (buf.slice) { - return buf.slice(0); - } else { - var view = new Uint8Array(buf.byteLength); - view.set(new Uint8Array(buf)); - return view.buffer; + function _getPrototypeOf(o) { + _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { + return o.__proto__ || Object.getPrototypeOf(o); + }; + return _getPrototypeOf(o); } - } - function Body() { - this.bodyUsed = false; + function _setPrototypeOf(o, p) { + _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { + o.__proto__ = p; + return o; + }; - this._initBody = function (body) { - /* - fetch-mock wraps the Response object in an ES6 Proxy to - provide useful test harness features such as flush. However, on - ES5 browsers without fetch or Proxy support pollyfills must be used; - the proxy-pollyfill is unable to proxy an attribute unless it exists - on the object before the Proxy is created. This change ensures - Response.bodyUsed exists on the instance, while maintaining the - semantic of setting Request.bodyUsed in the constructor before - _initBody is called. - */ - this.bodyUsed = this.bodyUsed; - this._bodyInit = body; + return _setPrototypeOf(o, p); + } - if (!body) { - this._bodyText = ''; - } else if (typeof body === 'string') { - this._bodyText = body; - } else if (support.blob && Blob.prototype.isPrototypeOf(body)) { - this._bodyBlob = body; - } else if (support.formData && FormData.prototype.isPrototypeOf(body)) { - this._bodyFormData = body; - } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) { - this._bodyText = body.toString(); - } else if (support.arrayBuffer && support.blob && isDataView(body)) { - this._bodyArrayBuffer = bufferClone(body.buffer); // IE 10-11 can't handle a DataView body. + function _isNativeReflectConstruct() { + if (typeof Reflect === "undefined" || !Reflect.construct) return false; + if (Reflect.construct.sham) return false; + if (typeof Proxy === "function") return true; - this._bodyInit = new Blob([this._bodyArrayBuffer]); - } else if (support.arrayBuffer && (ArrayBuffer.prototype.isPrototypeOf(body) || isArrayBufferView(body))) { - this._bodyArrayBuffer = bufferClone(body); - } else { - this._bodyText = body = Object.prototype.toString.call(body); + try { + Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); + return true; + } catch (e) { + return false; } + } - if (!this.headers.get('content-type')) { - if (typeof body === 'string') { - this.headers.set('content-type', 'text/plain;charset=UTF-8'); - } else if (this._bodyBlob && this._bodyBlob.type) { - this.headers.set('content-type', this._bodyBlob.type); - } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) { - this.headers.set('content-type', 'application/x-www-form-urlencoded;charset=UTF-8'); - } + function _assertThisInitialized(self) { + if (self === void 0) { + throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } - }; - if (support.blob) { - this.blob = function () { - var rejected = consumed(this); + return self; + } - if (rejected) { - return rejected; - } + function _possibleConstructorReturn(self, call) { + if (call && (_typeof(call) === "object" || typeof call === "function")) { + return call; + } - if (this._bodyBlob) { - return Promise.resolve(this._bodyBlob); - } else if (this._bodyArrayBuffer) { - return Promise.resolve(new Blob([this._bodyArrayBuffer])); - } else if (this._bodyFormData) { - throw new Error('could not read FormData body as blob'); - } else { - return Promise.resolve(new Blob([this._bodyText])); - } - }; + return _assertThisInitialized(self); + } - this.arrayBuffer = function () { - if (this._bodyArrayBuffer) { - var isConsumed = consumed(this); + function _createSuper(Derived) { + var hasNativeReflectConstruct = _isNativeReflectConstruct(); - if (isConsumed) { - return isConsumed; - } + return function _createSuperInternal() { + var Super = _getPrototypeOf(Derived), + result; - if (ArrayBuffer.isView(this._bodyArrayBuffer)) { - return Promise.resolve(this._bodyArrayBuffer.buffer.slice(this._bodyArrayBuffer.byteOffset, this._bodyArrayBuffer.byteOffset + this._bodyArrayBuffer.byteLength)); - } else { - return Promise.resolve(this._bodyArrayBuffer); - } + if (hasNativeReflectConstruct) { + var NewTarget = _getPrototypeOf(this).constructor; + + result = Reflect.construct(Super, arguments, NewTarget); } else { - return this.blob().then(readBlobAsArrayBuffer); + result = Super.apply(this, arguments); } + + return _possibleConstructorReturn(this, result); }; } - this.text = function () { - var rejected = consumed(this); - - if (rejected) { - return rejected; - } - - if (this._bodyBlob) { - return readBlobAsText(this._bodyBlob); - } else if (this._bodyArrayBuffer) { - return Promise.resolve(readArrayBufferAsText(this._bodyArrayBuffer)); - } else if (this._bodyFormData) { - throw new Error('could not read FormData body as text'); - } else { - return Promise.resolve(this._bodyText); + function _superPropBase(object, property) { + while (!Object.prototype.hasOwnProperty.call(object, property)) { + object = _getPrototypeOf(object); + if (object === null) break; } - }; - if (support.formData) { - this.formData = function () { - return this.text().then(decode); - }; + return object; } - this.json = function () { - return this.text().then(JSON.parse); - }; - - return this; - } // HTTP methods whose capitalization should be normalized + function _get(target, property, receiver) { + if (typeof Reflect !== "undefined" && Reflect.get) { + _get = Reflect.get; + } else { + _get = function _get(target, property, receiver) { + var base = _superPropBase(target, property); + if (!base) return; + var desc = Object.getOwnPropertyDescriptor(base, property); - var methods = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT']; + if (desc.get) { + return desc.get.call(receiver); + } - function normalizeMethod(method) { - var upcased = method.toUpperCase(); - return methods.indexOf(upcased) > -1 ? upcased : method; - } + return desc.value; + }; + } - function Request(input, options) { - if (!(this instanceof Request)) { - throw new TypeError('Please use the "new" operator, this DOM object constructor cannot be called as a function.'); + return _get(target, property, receiver || target); } - options = options || {}; - var body = options.body; + var Emitter = /*#__PURE__*/function () { + function Emitter() { + _classCallCheck(this, Emitter); - if (input instanceof Request) { - if (input.bodyUsed) { - throw new TypeError('Already read'); + Object.defineProperty(this, 'listeners', { + value: {}, + writable: true, + configurable: true + }); } - this.url = input.url; - this.credentials = input.credentials; - - if (!options.headers) { - this.headers = new Headers(input.headers); - } - - this.method = input.method; - this.mode = input.mode; - this.signal = input.signal; + _createClass(Emitter, [{ + key: "addEventListener", + value: function addEventListener(type, callback, options) { + if (!(type in this.listeners)) { + this.listeners[type] = []; + } - if (!body && input._bodyInit != null) { - body = input._bodyInit; - input.bodyUsed = true; - } - } else { - this.url = String(input); - } + this.listeners[type].push({ + callback: callback, + options: options + }); + } + }, { + key: "removeEventListener", + value: function removeEventListener(type, callback) { + if (!(type in this.listeners)) { + return; + } - this.credentials = options.credentials || this.credentials || 'same-origin'; + var stack = this.listeners[type]; - if (options.headers || !this.headers) { - this.headers = new Headers(options.headers); - } + for (var i = 0, l = stack.length; i < l; i++) { + if (stack[i].callback === callback) { + stack.splice(i, 1); + return; + } + } + } + }, { + key: "dispatchEvent", + value: function dispatchEvent(event) { + if (!(event.type in this.listeners)) { + return; + } - this.method = normalizeMethod(options.method || this.method || 'GET'); - this.mode = options.mode || this.mode || null; - this.signal = options.signal || this.signal; - this.referrer = null; + var stack = this.listeners[event.type]; + var stackToCall = stack.slice(); - if ((this.method === 'GET' || this.method === 'HEAD') && body) { - throw new TypeError('Body not allowed for GET or HEAD requests'); - } + for (var i = 0, l = stackToCall.length; i < l; i++) { + var listener = stackToCall[i]; - this._initBody(body); + try { + listener.callback.call(this, event); + } catch (e) { + Promise.resolve().then(function () { + throw e; + }); + } - if (this.method === 'GET' || this.method === 'HEAD') { - if (options.cache === 'no-store' || options.cache === 'no-cache') { - // Search for a '_' parameter in the query string - var reParamSearch = /([?&])_=[^&]*/; + if (listener.options && listener.options.once) { + this.removeEventListener(event.type, listener.callback); + } + } - if (reParamSearch.test(this.url)) { - // If it already exists then set the value with the current time - this.url = this.url.replace(reParamSearch, '$1_=' + new Date().getTime()); - } else { - // Otherwise add a new '_' parameter to the end with the current time - var reQueryString = /\?/; - this.url += (reQueryString.test(this.url) ? '&' : '?') + '_=' + new Date().getTime(); + return !event.defaultPrevented; } - } - } - } - - Request.prototype.clone = function () { - return new Request(this, { - body: this._bodyInit - }); - }; + }]); - function decode(body) { - var form = new FormData(); - body.trim().split('&').forEach(function (bytes) { - if (bytes) { - var split = bytes.split('='); - var name = split.shift().replace(/\+/g, ' '); - var value = split.join('=').replace(/\+/g, ' '); - form.append(decodeURIComponent(name), decodeURIComponent(value)); - } - }); - return form; - } + return Emitter; + }(); - function parseHeaders(rawHeaders) { - var headers = new Headers(); // Replace instances of \r\n and \n followed by at least one space or horizontal tab with a space - // https://tools.ietf.org/html/rfc7230#section-3.2 + var AbortSignal = /*#__PURE__*/function (_Emitter) { + _inherits(AbortSignal, _Emitter); - var preProcessedHeaders = rawHeaders.replace(/\r?\n[\t ]+/g, ' '); // Avoiding split via regex to work around a common IE11 bug with the core-js 3.6.0 regex polyfill - // https://github.com/github/fetch/issues/748 - // https://github.com/zloirock/core-js/issues/751 + var _super = _createSuper(AbortSignal); - preProcessedHeaders.split('\r').map(function (header) { - return header.indexOf('\n') === 0 ? header.substr(1, header.length) : header; - }).forEach(function (line) { - var parts = line.split(':'); - var key = parts.shift().trim(); + function AbortSignal() { + var _this; - if (key) { - var value = parts.join(':').trim(); - headers.append(key, value); - } - }); - return headers; - } + _classCallCheck(this, AbortSignal); - Body.call(Request.prototype); - function Response(bodyInit, options) { - if (!(this instanceof Response)) { - throw new TypeError('Please use the "new" operator, this DOM object constructor cannot be called as a function.'); - } + _this = _super.call(this); // Some versions of babel does not transpile super() correctly for IE <= 10, if the parent + // constructor has failed to run, then "this.listeners" will still be undefined and then we call + // the parent constructor directly instead as a workaround. For general details, see babel bug: + // https://github.com/babel/babel/issues/3041 + // This hack was added as a fix for the issue described here: + // https://github.com/Financial-Times/polyfill-library/pull/59#issuecomment-477558042 - if (!options) { - options = {}; - } + if (!_this.listeners) { + Emitter.call(_assertThisInitialized(_this)); + } // Compared to assignment, Object.defineProperty makes properties non-enumerable by default and + // we want Object.keys(new AbortController().signal) to be [] for compat with the native impl - this.type = 'default'; - this.status = options.status === undefined ? 200 : options.status; - this.ok = this.status >= 200 && this.status < 300; - this.statusText = options.statusText === undefined ? '' : '' + options.statusText; - this.headers = new Headers(options.headers); - this.url = options.url || ''; - this._initBody(bodyInit); - } - Body.call(Response.prototype); + Object.defineProperty(_assertThisInitialized(_this), 'aborted', { + value: false, + writable: true, + configurable: true + }); + Object.defineProperty(_assertThisInitialized(_this), 'onabort', { + value: null, + writable: true, + configurable: true + }); + return _this; + } - Response.prototype.clone = function () { - return new Response(this._bodyInit, { - status: this.status, - statusText: this.statusText, - headers: new Headers(this.headers), - url: this.url - }); - }; + _createClass(AbortSignal, [{ + key: "toString", + value: function toString() { + return '[object AbortSignal]'; + } + }, { + key: "dispatchEvent", + value: function dispatchEvent(event) { + if (event.type === 'abort') { + this.aborted = true; - Response.error = function () { - var response = new Response(null, { - status: 0, - statusText: '' - }); - response.type = 'error'; - return response; - }; + if (typeof this.onabort === 'function') { + this.onabort.call(this, event); + } + } - var redirectStatuses = [301, 302, 303, 307, 308]; + _get(_getPrototypeOf(AbortSignal.prototype), "dispatchEvent", this).call(this, event); + } + }]); - Response.redirect = function (url, status) { - if (redirectStatuses.indexOf(status) === -1) { - throw new RangeError('Invalid status code'); - } + return AbortSignal; + }(Emitter); - return new Response(null, { - status: status, - headers: { - location: url - } - }); - }; + var AbortController = /*#__PURE__*/function () { + function AbortController() { + _classCallCheck(this, AbortController); // Compared to assignment, Object.defineProperty makes properties non-enumerable by default and + // we want Object.keys(new AbortController()) to be [] for compat with the native impl - var DOMException$1 = global$8.DOMException; - try { - new DOMException$1(); - } catch (err) { - DOMException$1 = function DOMException(message, name) { - this.message = message; - this.name = name; - var error = Error(message); - this.stack = error.stack; - }; + Object.defineProperty(this, 'signal', { + value: new AbortSignal(), + writable: true, + configurable: true + }); + } - DOMException$1.prototype = Object.create(Error.prototype); - DOMException$1.prototype.constructor = DOMException$1; - } + _createClass(AbortController, [{ + key: "abort", + value: function abort() { + var event; - function fetch$1(input, init) { - return new Promise(function (resolve, reject) { - var request = new Request(input, init); + try { + event = new Event('abort'); + } catch (e) { + if (typeof document !== 'undefined') { + if (!document.createEvent) { + // For Internet Explorer 8: + event = document.createEventObject(); + event.type = 'abort'; + } else { + // For Internet Explorer 11: + event = document.createEvent('Event'); + event.initEvent('abort', false, false); + } + } else { + // Fallback where document isn't available: + event = { + type: 'abort', + bubbles: false, + cancelable: false + }; + } + } - if (request.signal && request.signal.aborted) { - return reject(new DOMException$1('Aborted', 'AbortError')); - } + this.signal.dispatchEvent(event); + } + }, { + key: "toString", + value: function toString() { + return '[object AbortController]'; + } + }]); - var xhr = new XMLHttpRequest(); + return AbortController; + }(); - function abortXhr() { - xhr.abort(); - } + if (typeof Symbol !== 'undefined' && Symbol.toStringTag) { + // These are necessary to make sure that we get correct output for: + // Object.prototype.toString.call(new AbortController()) + AbortController.prototype[Symbol.toStringTag] = 'AbortController'; + AbortSignal.prototype[Symbol.toStringTag] = 'AbortSignal'; + } - xhr.onload = function () { - var options = { - status: xhr.status, - statusText: xhr.statusText, - headers: parseHeaders(xhr.getAllResponseHeaders() || '') - }; - options.url = 'responseURL' in xhr ? xhr.responseURL : options.headers.get('X-Request-URL'); - var body = 'response' in xhr ? xhr.response : xhr.responseText; - setTimeout(function () { - resolve(new Response(body, options)); - }, 0); - }; + function polyfillNeeded(self) { + if (self.__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL) { + console.log('__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL=true is set, will force install polyfill'); + return true; + } // Note that the "unfetch" minimal fetch polyfill defines fetch() without + // defining window.Request, and this polyfill need to work on top of unfetch + // so the below feature detection needs the !self.AbortController part. + // The Request.prototype check is also needed because Safari versions 11.1.2 + // up to and including 12.1.x has a window.AbortController present but still + // does NOT correctly implement abortable fetch: + // https://bugs.webkit.org/show_bug.cgi?id=174980#c2 - xhr.onerror = function () { - setTimeout(function () { - reject(new TypeError('Network request failed')); - }, 0); - }; - xhr.ontimeout = function () { - setTimeout(function () { - reject(new TypeError('Network request failed')); - }, 0); - }; + return typeof self.Request === 'function' && !self.Request.prototype.hasOwnProperty('signal') || !self.AbortController; + } + /** + * Note: the "fetch.Request" default value is available for fetch imported from + * the "node-fetch" package and not in browsers. This is OK since browsers + * will be importing umd-polyfill.js from that path "self" is passed the + * decorator so the default value will not be used (because browsers that define + * fetch also has Request). One quirky setup where self.fetch exists but + * self.Request does not is when the "unfetch" minimal fetch polyfill is used + * on top of IE11; for this case the browser will try to use the fetch.Request + * default value which in turn will be undefined but then then "if (Request)" + * will ensure that you get a patched fetch but still no Request (as expected). + * @param {fetch, Request = fetch.Request} + * @returns {fetch: abortableFetch, Request: AbortableRequest} + */ - xhr.onabort = function () { - setTimeout(function () { - reject(new DOMException$1('Aborted', 'AbortError')); - }, 0); - }; - function fixUrl(url) { - try { - return url === '' && global$8.location.href ? global$8.location.href : url; - } catch (e) { - return url; - } + function abortableFetchDecorator(patchTargets) { + if ('function' === typeof patchTargets) { + patchTargets = { + fetch: patchTargets + }; } - xhr.open(request.method, fixUrl(request.url), true); + var _patchTargets = patchTargets, + fetch = _patchTargets.fetch, + _patchTargets$Request = _patchTargets.Request, + NativeRequest = _patchTargets$Request === void 0 ? fetch.Request : _patchTargets$Request, + NativeAbortController = _patchTargets.AbortController, + _patchTargets$__FORCE = _patchTargets.__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL, + __FORCE_INSTALL_ABORTCONTROLLER_POLYFILL = _patchTargets$__FORCE === void 0 ? false : _patchTargets$__FORCE; - if (request.credentials === 'include') { - xhr.withCredentials = true; - } else if (request.credentials === 'omit') { - xhr.withCredentials = false; + if (!polyfillNeeded({ + fetch: fetch, + Request: NativeRequest, + AbortController: NativeAbortController, + __FORCE_INSTALL_ABORTCONTROLLER_POLYFILL: __FORCE_INSTALL_ABORTCONTROLLER_POLYFILL + })) { + return { + fetch: fetch, + Request: Request + }; } - if ('responseType' in xhr) { - if (support.blob) { - xhr.responseType = 'blob'; - } else if (support.arrayBuffer && request.headers.get('Content-Type') && request.headers.get('Content-Type').indexOf('application/octet-stream') !== -1) { - xhr.responseType = 'arraybuffer'; - } - } + var Request = NativeRequest; // Note that the "unfetch" minimal fetch polyfill defines fetch() without + // defining window.Request, and this polyfill need to work on top of unfetch + // hence we only patch it if it's available. Also we don't patch it if signal + // is already available on the Request prototype because in this case support + // is present and the patching below can cause a crash since it assigns to + // request.signal which is technically a read-only property. This latter error + // happens when you run the main5.js node-fetch example in the repo + // "abortcontroller-polyfill-examples". The exact error is: + // request.signal = init.signal; + // ^ + // TypeError: Cannot set property signal of # which has only a getter - if (init && _typeof(init.headers) === 'object' && !(init.headers instanceof Headers)) { - Object.getOwnPropertyNames(init.headers).forEach(function (name) { - xhr.setRequestHeader(name, normalizeValue(init.headers[name])); - }); - } else { - request.headers.forEach(function (value, name) { - xhr.setRequestHeader(name, value); - }); - } + if (Request && !Request.prototype.hasOwnProperty('signal') || __FORCE_INSTALL_ABORTCONTROLLER_POLYFILL) { + Request = function Request(input, init) { + var signal; - if (request.signal) { - request.signal.addEventListener('abort', abortXhr); + if (init && init.signal) { + signal = init.signal; // Never pass init.signal to the native Request implementation when the polyfill has + // been installed because if we're running on top of a browser with a + // working native AbortController (i.e. the polyfill was installed due to + // __FORCE_INSTALL_ABORTCONTROLLER_POLYFILL being set), then passing our + // fake AbortSignal to the native fetch will trigger: + // TypeError: Failed to construct 'Request': member signal is not of type AbortSignal. - xhr.onreadystatechange = function () { - // DONE (success or failure) - if (xhr.readyState === 4) { - request.signal.removeEventListener('abort', abortXhr); + delete init.signal; } - }; - } - xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit); - }); - } - fetch$1.polyfill = true; + var request = new NativeRequest(input, init); - if (!global$8.fetch) { - global$8.fetch = fetch$1; - global$8.Headers = Headers; - global$8.Request = Request; - global$8.Response = Response; - } + if (signal) { + Object.defineProperty(request, 'signal', { + writable: false, + enumerable: false, + configurable: true, + value: signal + }); + } - var $$L = _export; - var DESCRIPTORS$7 = descriptors; - var objectDefinePropertyModile = objectDefineProperty; + return request; + }; - // `Object.defineProperty` method - // https://tc39.es/ecma262/#sec-object.defineproperty - $$L({ target: 'Object', stat: true, forced: !DESCRIPTORS$7, sham: !DESCRIPTORS$7 }, { - defineProperty: objectDefinePropertyModile.f - }); + Request.prototype = NativeRequest.prototype; + } - var $$K = _export; - var setPrototypeOf = objectSetPrototypeOf; + var realFetch = fetch; - // `Object.setPrototypeOf` method - // https://tc39.es/ecma262/#sec-object.setprototypeof - $$K({ target: 'Object', stat: true }, { - setPrototypeOf: setPrototypeOf - }); + var abortableFetch = function abortableFetch(input, init) { + var signal = Request && Request.prototype.isPrototypeOf(input) ? input.signal : init ? init.signal : undefined; - var $$J = _export; - var fails$i = fails$N; - var toObject$5 = toObject$i; - var nativeGetPrototypeOf = objectGetPrototypeOf; - var CORRECT_PROTOTYPE_GETTER = correctPrototypeGetter; + if (signal) { + var abortError; - var FAILS_ON_PRIMITIVES$3 = fails$i(function () { nativeGetPrototypeOf(1); }); + try { + abortError = new DOMException('Aborted', 'AbortError'); + } catch (err) { + // IE 11 does not support calling the DOMException constructor, use a + // regular error object on it instead. + abortError = new Error('Aborted'); + abortError.name = 'AbortError'; + } // Return early if already aborted, thus avoiding making an HTTP request - // `Object.getPrototypeOf` method - // https://tc39.es/ecma262/#sec-object.getprototypeof - $$J({ target: 'Object', stat: true, forced: FAILS_ON_PRIMITIVES$3, sham: !CORRECT_PROTOTYPE_GETTER }, { - getPrototypeOf: function getPrototypeOf(it) { - return nativeGetPrototypeOf(toObject$5(it)); - } - }); - var aFunction$2 = aFunction$9; - var isObject$a = isObject$r; + if (signal.aborted) { + return Promise.reject(abortError); + } // Turn an event into a promise, reject it once `abort` is dispatched - var slice$2 = [].slice; - var factories = {}; - var construct = function (C, argsLength, args) { - if (!(argsLength in factories)) { - for (var list = [], i = 0; i < argsLength; i++) list[i] = 'a[' + i + ']'; - // eslint-disable-next-line no-new-func -- we have no proper alternatives, IE8- only - factories[argsLength] = Function('C,a', 'return new C(' + list.join(',') + ')'); - } return factories[argsLength](C, args); - }; + var cancellation = new Promise(function (_, reject) { + signal.addEventListener('abort', function () { + return reject(abortError); + }, { + once: true + }); + }); - // `Function.prototype.bind` method implementation - // https://tc39.es/ecma262/#sec-function.prototype.bind - var functionBind = Function.bind || function bind(that /* , ...args */) { - var fn = aFunction$2(this); - var partArgs = slice$2.call(arguments, 1); - var boundFunction = function bound(/* args... */) { - var args = partArgs.concat(slice$2.call(arguments)); - return this instanceof boundFunction ? construct(fn, args.length, args) : fn.apply(that, args); - }; - if (isObject$a(fn.prototype)) boundFunction.prototype = fn.prototype; - return boundFunction; - }; + if (init && init.signal) { + // Never pass .signal to the native implementation when the polyfill has + // been installed because if we're running on top of a browser with a + // working native AbortController (i.e. the polyfill was installed due to + // __FORCE_INSTALL_ABORTCONTROLLER_POLYFILL being set), then passing our + // fake AbortSignal to the native fetch will trigger: + // TypeError: Failed to execute 'fetch' on 'Window': member signal is not of type AbortSignal. + delete init.signal; + } // Return the fastest promise (don't need to wait for request to finish) - var $$I = _export; - var getBuiltIn$1 = getBuiltIn$9; - var aFunction$1 = aFunction$9; - var anObject$3 = anObject$m; - var isObject$9 = isObject$r; - var create$5 = objectCreate; - var bind$4 = functionBind; - var fails$h = fails$N; - var nativeConstruct = getBuiltIn$1('Reflect', 'construct'); + return Promise.race([cancellation, realFetch(input, init)]); + } - // `Reflect.construct` method - // https://tc39.es/ecma262/#sec-reflect.construct - // MS Edge supports only 2 arguments and argumentsList argument is optional - // FF Nightly sets third argument as `new.target`, but does not create `this` from it - var NEW_TARGET_BUG = fails$h(function () { - function F() { /* empty */ } - return !(nativeConstruct(function () { /* empty */ }, [], F) instanceof F); - }); - var ARGS_BUG = !fails$h(function () { - nativeConstruct(function () { /* empty */ }); - }); - var FORCED$a = NEW_TARGET_BUG || ARGS_BUG; + return realFetch(input, init); + }; - $$I({ target: 'Reflect', stat: true, forced: FORCED$a, sham: FORCED$a }, { - construct: function construct(Target, args /* , newTarget */) { - aFunction$1(Target); - anObject$3(args); - var newTarget = arguments.length < 3 ? Target : aFunction$1(arguments[2]); - if (ARGS_BUG && !NEW_TARGET_BUG) return nativeConstruct(Target, args, newTarget); - if (Target == newTarget) { - // w/o altered newTarget, optimization for 0-4 arguments - switch (args.length) { - case 0: return new Target(); - case 1: return new Target(args[0]); - case 2: return new Target(args[0], args[1]); - case 3: return new Target(args[0], args[1], args[2]); - case 4: return new Target(args[0], args[1], args[2], args[3]); - } - // w/o altered newTarget, lot of arguments case - var $args = [null]; - $args.push.apply($args, args); - return new (bind$4.apply(Target, $args))(); - } - // with altered newTarget, not support built-in constructors - var proto = newTarget.prototype; - var instance = create$5(isObject$9(proto) ? proto : Object.prototype); - var result = Function.apply.call(Target, instance, args); - return isObject$9(result) ? result : instance; + return { + fetch: abortableFetch, + Request: Request + }; } - }); - var $$H = _export; - var isObject$8 = isObject$r; - var anObject$2 = anObject$m; - var has$3 = has$j; - var getOwnPropertyDescriptorModule = objectGetOwnPropertyDescriptor; - var getPrototypeOf = objectGetPrototypeOf; + (function (self) { + if (!polyfillNeeded(self)) { + return; + } - // `Reflect.get` method - // https://tc39.es/ecma262/#sec-reflect.get - function get$3(target, propertyKey /* , receiver */) { - var receiver = arguments.length < 3 ? target : arguments[2]; - var descriptor, prototype; - if (anObject$2(target) === receiver) return target[propertyKey]; - if (descriptor = getOwnPropertyDescriptorModule.f(target, propertyKey)) return has$3(descriptor, 'value') - ? descriptor.value - : descriptor.get === undefined - ? undefined - : descriptor.get.call(receiver); - if (isObject$8(prototype = getPrototypeOf(target))) return get$3(prototype, propertyKey, receiver); - } + if (!self.fetch) { + console.warn('fetch() is not available, cannot install abortcontroller-polyfill'); + return; + } - $$H({ target: 'Reflect', stat: true }, { - get: get$3 + var _abortableFetch = abortableFetchDecorator(self), + fetch = _abortableFetch.fetch, + Request = _abortableFetch.Request; + + self.fetch = fetch; + self.Request = Request; + Object.defineProperty(self, 'AbortController', { + writable: true, + enumerable: false, + configurable: true, + value: AbortController + }); + Object.defineProperty(self, 'AbortSignal', { + writable: true, + enumerable: false, + configurable: true, + value: AbortSignal + }); + })(typeof self !== 'undefined' ? self : commonjsGlobal); }); - var $$G = _export; - var fails$g = fails$N; - var toIndexedObject$1 = toIndexedObject$b; - var nativeGetOwnPropertyDescriptor = objectGetOwnPropertyDescriptor.f; - var DESCRIPTORS$6 = descriptors; + function actionAddEntity(way) { + return function (graph) { + return graph.replace(way); + }; + } + + var $$M = _export; + var global$g = global$1m; + var fails$k = fails$S; + var isArray$3 = isArray$8; + var isObject$8 = isObject$s; + var toObject$6 = toObject$j; + var lengthOfArrayLike$4 = lengthOfArrayLike$g; + var createProperty$1 = createProperty$4; + var arraySpeciesCreate$1 = arraySpeciesCreate$4; + var arrayMethodHasSpeciesSupport$1 = arrayMethodHasSpeciesSupport$5; + var wellKnownSymbol$2 = wellKnownSymbol$t; + var V8_VERSION = engineV8Version; - var FAILS_ON_PRIMITIVES$2 = fails$g(function () { nativeGetOwnPropertyDescriptor(1); }); - var FORCED$9 = !DESCRIPTORS$6 || FAILS_ON_PRIMITIVES$2; + var IS_CONCAT_SPREADABLE = wellKnownSymbol$2('isConcatSpreadable'); + var MAX_SAFE_INTEGER = 0x1FFFFFFFFFFFFF; + var MAXIMUM_ALLOWED_INDEX_EXCEEDED = 'Maximum allowed index exceeded'; + var TypeError$5 = global$g.TypeError; - // `Object.getOwnPropertyDescriptor` method - // https://tc39.es/ecma262/#sec-object.getownpropertydescriptor - $$G({ target: 'Object', stat: true, forced: FORCED$9, sham: !DESCRIPTORS$6 }, { - getOwnPropertyDescriptor: function getOwnPropertyDescriptor(it, key) { - return nativeGetOwnPropertyDescriptor(toIndexedObject$1(it), key); - } + // We can't use this feature detection in V8 since it causes + // deoptimization and serious performance degradation + // https://github.com/zloirock/core-js/issues/679 + var IS_CONCAT_SPREADABLE_SUPPORT = V8_VERSION >= 51 || !fails$k(function () { + var array = []; + array[IS_CONCAT_SPREADABLE] = false; + return array.concat()[0] !== array; }); - var $$F = _export; - var toAbsoluteIndex$1 = toAbsoluteIndex$8; - var toInteger$2 = toInteger$b; - var toLength$6 = toLength$q; - var toObject$4 = toObject$i; - var arraySpeciesCreate$1 = arraySpeciesCreate$3; - var createProperty$1 = createProperty$4; - var arrayMethodHasSpeciesSupport$2 = arrayMethodHasSpeciesSupport$5; + var SPECIES_SUPPORT = arrayMethodHasSpeciesSupport$1('concat'); - var HAS_SPECIES_SUPPORT$1 = arrayMethodHasSpeciesSupport$2('splice'); + var isConcatSpreadable = function (O) { + if (!isObject$8(O)) return false; + var spreadable = O[IS_CONCAT_SPREADABLE]; + return spreadable !== undefined ? !!spreadable : isArray$3(O); + }; - var max$1 = Math.max; - var min$3 = Math.min; - var MAX_SAFE_INTEGER$1 = 0x1FFFFFFFFFFFFF; - var MAXIMUM_ALLOWED_LENGTH_EXCEEDED = 'Maximum allowed length exceeded'; + var FORCED$a = !IS_CONCAT_SPREADABLE_SUPPORT || !SPECIES_SUPPORT; - // `Array.prototype.splice` method - // https://tc39.es/ecma262/#sec-array.prototype.splice - // with adding support of @@species - $$F({ target: 'Array', proto: true, forced: !HAS_SPECIES_SUPPORT$1 }, { - splice: function splice(start, deleteCount /* , ...items */) { - var O = toObject$4(this); - var len = toLength$6(O.length); - var actualStart = toAbsoluteIndex$1(start, len); - var argumentsLength = arguments.length; - var insertCount, actualDeleteCount, A, k, from, to; - if (argumentsLength === 0) { - insertCount = actualDeleteCount = 0; - } else if (argumentsLength === 1) { - insertCount = 0; - actualDeleteCount = len - actualStart; - } else { - insertCount = argumentsLength - 2; - actualDeleteCount = min$3(max$1(toInteger$2(deleteCount), 0), len - actualStart); - } - if (len + insertCount - actualDeleteCount > MAX_SAFE_INTEGER$1) { - throw TypeError(MAXIMUM_ALLOWED_LENGTH_EXCEEDED); - } - A = arraySpeciesCreate$1(O, actualDeleteCount); - for (k = 0; k < actualDeleteCount; k++) { - from = actualStart + k; - if (from in O) createProperty$1(A, k, O[from]); - } - A.length = actualDeleteCount; - if (insertCount < actualDeleteCount) { - for (k = actualStart; k < len - actualDeleteCount; k++) { - from = k + actualDeleteCount; - to = k + insertCount; - if (from in O) O[to] = O[from]; - else delete O[to]; - } - for (k = len; k > len - actualDeleteCount + insertCount; k--) delete O[k - 1]; - } else if (insertCount > actualDeleteCount) { - for (k = len - actualDeleteCount; k > actualStart; k--) { - from = k + actualDeleteCount - 1; - to = k + insertCount - 1; - if (from in O) O[to] = O[from]; - else delete O[to]; + // `Array.prototype.concat` method + // https://tc39.es/ecma262/#sec-array.prototype.concat + // with adding support of @@isConcatSpreadable and @@species + $$M({ target: 'Array', proto: true, forced: FORCED$a }, { + // eslint-disable-next-line no-unused-vars -- required for `.length` + concat: function concat(arg) { + var O = toObject$6(this); + var A = arraySpeciesCreate$1(O, 0); + var n = 0; + var i, k, length, len, E; + for (i = -1, length = arguments.length; i < length; i++) { + E = i === -1 ? O : arguments[i]; + if (isConcatSpreadable(E)) { + len = lengthOfArrayLike$4(E); + if (n + len > MAX_SAFE_INTEGER) throw TypeError$5(MAXIMUM_ALLOWED_INDEX_EXCEEDED); + for (k = 0; k < len; k++, n++) if (k in E) createProperty$1(A, n, E[k]); + } else { + if (n >= MAX_SAFE_INTEGER) throw TypeError$5(MAXIMUM_ALLOWED_INDEX_EXCEEDED); + createProperty$1(A, n++, E); } } - for (k = 0; k < insertCount; k++) { - O[k + actualStart] = arguments[k + 2]; - } - O.length = len - actualDeleteCount + insertCount; + A.length = n; return A; } }); - var defineWellKnownSymbol$1 = defineWellKnownSymbol$4; - - // `Symbol.toStringTag` well-known symbol - // https://tc39.es/ecma262/#sec-symbol.tostringtag - defineWellKnownSymbol$1('toStringTag'); + var DESCRIPTORS$7 = descriptors; + var uncurryThis$l = functionUncurryThis; + var call$5 = functionCall; + var fails$j = fails$S; + var objectKeys$1 = objectKeys$4; + var getOwnPropertySymbolsModule = objectGetOwnPropertySymbols; + var propertyIsEnumerableModule = objectPropertyIsEnumerable; + var toObject$5 = toObject$j; + var IndexedObject = indexedObject; - var global$7 = global$F; - var setToStringTag$2 = setToStringTag$a; + // eslint-disable-next-line es/no-object-assign -- safe + var $assign = Object.assign; + // eslint-disable-next-line es/no-object-defineproperty -- required for testing + var defineProperty$4 = Object.defineProperty; + var concat = uncurryThis$l([].concat); - // JSON[@@toStringTag] property - // https://tc39.es/ecma262/#sec-json-@@tostringtag - setToStringTag$2(global$7.JSON, 'JSON', true); + // `Object.assign` method + // https://tc39.es/ecma262/#sec-object.assign + var objectAssign = !$assign || fails$j(function () { + // should have correct order of operations (Edge bug) + if (DESCRIPTORS$7 && $assign({ b: 1 }, $assign(defineProperty$4({}, 'a', { + enumerable: true, + get: function () { + defineProperty$4(this, 'b', { + value: 3, + enumerable: false + }); + } + }), { b: 2 })).b !== 1) return true; + // should work with symbols and should have deterministic property order (V8 bug) + var A = {}; + var B = {}; + // eslint-disable-next-line es/no-symbol -- safe + var symbol = Symbol(); + var alphabet = 'abcdefghijklmnopqrst'; + A[symbol] = 7; + alphabet.split('').forEach(function (chr) { B[chr] = chr; }); + return $assign({}, A)[symbol] != 7 || objectKeys$1($assign({}, B)).join('') != alphabet; + }) ? function assign(target, source) { // eslint-disable-line no-unused-vars -- required for `.length` + var T = toObject$5(target); + var argumentsLength = arguments.length; + var index = 1; + var getOwnPropertySymbols = getOwnPropertySymbolsModule.f; + var propertyIsEnumerable = propertyIsEnumerableModule.f; + while (argumentsLength > index) { + var S = IndexedObject(arguments[index++]); + var keys = getOwnPropertySymbols ? concat(objectKeys$1(S), getOwnPropertySymbols(S)) : objectKeys$1(S); + var length = keys.length; + var j = 0; + var key; + while (length > j) { + key = keys[j++]; + if (!DESCRIPTORS$7 || call$5(propertyIsEnumerable, S, key)) T[key] = S[key]; + } + } return T; + } : $assign; - var setToStringTag$1 = setToStringTag$a; + var $$L = _export; + var assign$2 = objectAssign; - // Math[@@toStringTag] property - // https://tc39.es/ecma262/#sec-math-@@tostringtag - setToStringTag$1(Math, 'Math', true); + // `Object.assign` method + // https://tc39.es/ecma262/#sec-object.assign + // eslint-disable-next-line es/no-object-assign -- required for testing + $$L({ target: 'Object', stat: true, forced: Object.assign !== assign$2 }, { + assign: assign$2 + }); - (function (factory) { - factory(); - })(function () { + var $$K = _export; + var $filter = arrayIteration.filter; + var arrayMethodHasSpeciesSupport = arrayMethodHasSpeciesSupport$5; - function _classCallCheck(instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } - } + var HAS_SPECIES_SUPPORT = arrayMethodHasSpeciesSupport('filter'); - function _defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i]; - descriptor.enumerable = descriptor.enumerable || false; - descriptor.configurable = true; - if ("value" in descriptor) descriptor.writable = true; - Object.defineProperty(target, descriptor.key, descriptor); - } + // `Array.prototype.filter` method + // https://tc39.es/ecma262/#sec-array.prototype.filter + // with adding support of @@species + $$K({ target: 'Array', proto: true, forced: !HAS_SPECIES_SUPPORT }, { + filter: function filter(callbackfn /* , thisArg */) { + return $filter(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined); } + }); - function _createClass(Constructor, protoProps, staticProps) { - if (protoProps) _defineProperties(Constructor.prototype, protoProps); - if (staticProps) _defineProperties(Constructor, staticProps); - return Constructor; - } + var $$J = _export; + var toObject$4 = toObject$j; + var nativeKeys = objectKeys$4; + var fails$i = fails$S; - function _inherits(subClass, superClass) { - if (typeof superClass !== "function" && superClass !== null) { - throw new TypeError("Super expression must either be null or a function"); - } + var FAILS_ON_PRIMITIVES$2 = fails$i(function () { nativeKeys(1); }); - subClass.prototype = Object.create(superClass && superClass.prototype, { - constructor: { - value: subClass, - writable: true, - configurable: true - } - }); - if (superClass) _setPrototypeOf(subClass, superClass); + // `Object.keys` method + // https://tc39.es/ecma262/#sec-object.keys + $$J({ target: 'Object', stat: true, forced: FAILS_ON_PRIMITIVES$2 }, { + keys: function keys(it) { + return nativeKeys(toObject$4(it)); } + }); - function _getPrototypeOf(o) { - _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { - return o.__proto__ || Object.getPrototypeOf(o); - }; - return _getPrototypeOf(o); - } + var $$I = _export; + var uncurryThis$k = functionUncurryThis; + var isArray$2 = isArray$8; - function _setPrototypeOf(o, p) { - _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { - o.__proto__ = p; - return o; - }; + var un$Reverse = uncurryThis$k([].reverse); + var test$1 = [1, 2]; - return _setPrototypeOf(o, p); + // `Array.prototype.reverse` method + // https://tc39.es/ecma262/#sec-array.prototype.reverse + // fix for Safari 12.0 bug + // https://bugs.webkit.org/show_bug.cgi?id=188794 + $$I({ target: 'Array', proto: true, forced: String(test$1) === String(test$1.reverse()) }, { + reverse: function reverse() { + // eslint-disable-next-line no-self-assign -- dirty hack + if (isArray$2(this)) this.length = this.length; + return un$Reverse(this); } + }); - function _isNativeReflectConstruct() { - if (typeof Reflect === "undefined" || !Reflect.construct) return false; - if (Reflect.construct.sham) return false; - if (typeof Proxy === "function") return true; + var global$f = global$1m; + var fails$h = fails$S; + var uncurryThis$j = functionUncurryThis; + var toString$c = toString$k; + var trim$4 = stringTrim.trim; + var whitespaces$1 = whitespaces$4; - try { - Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); - return true; - } catch (e) { - return false; - } - } + var charAt$2 = uncurryThis$j(''.charAt); + var n$ParseFloat = global$f.parseFloat; + var Symbol$2 = global$f.Symbol; + var ITERATOR$1 = Symbol$2 && Symbol$2.iterator; + var FORCED$9 = 1 / n$ParseFloat(whitespaces$1 + '-0') !== -Infinity + // MS Edge 18- broken with boxed symbols + || (ITERATOR$1 && !fails$h(function () { n$ParseFloat(Object(ITERATOR$1)); })); - function _assertThisInitialized(self) { - if (self === void 0) { - throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); - } + // `parseFloat` method + // https://tc39.es/ecma262/#sec-parsefloat-string + var numberParseFloat = FORCED$9 ? function parseFloat(string) { + var trimmedString = trim$4(toString$c(string)); + var result = n$ParseFloat(trimmedString); + return result === 0 && charAt$2(trimmedString, 0) == '-' ? -0 : result; + } : n$ParseFloat; - return self; - } + var $$H = _export; + var $parseFloat = numberParseFloat; - function _possibleConstructorReturn(self, call) { - if (call && (_typeof(call) === "object" || typeof call === "function")) { - return call; - } + // `parseFloat` method + // https://tc39.es/ecma262/#sec-parsefloat-string + $$H({ global: true, forced: parseFloat != $parseFloat }, { + parseFloat: $parseFloat + }); - return _assertThisInitialized(self); - } + /* + Order the nodes of a way in reverse order and reverse any direction dependent tags + other than `oneway`. (We assume that correcting a backwards oneway is the primary + reason for reversing a way.) - function _createSuper(Derived) { - var hasNativeReflectConstruct = _isNativeReflectConstruct(); + In addition, numeric-valued `incline` tags are negated. - return function _createSuperInternal() { - var Super = _getPrototypeOf(Derived), - result; + The JOSM implementation was used as a guide, but transformations that were of unclear benefit + or adjusted tags that don't seem to be used in practice were omitted. - if (hasNativeReflectConstruct) { - var NewTarget = _getPrototypeOf(this).constructor; + References: + http://wiki.openstreetmap.org/wiki/Forward_%26_backward,_left_%26_right + http://wiki.openstreetmap.org/wiki/Key:direction#Steps + http://wiki.openstreetmap.org/wiki/Key:incline + http://wiki.openstreetmap.org/wiki/Route#Members + http://josm.openstreetmap.de/browser/josm/trunk/src/org/openstreetmap/josm/corrector/ReverseWayTagCorrector.java + http://wiki.openstreetmap.org/wiki/Tag:highway%3Dstop + http://wiki.openstreetmap.org/wiki/Key:traffic_sign#On_a_way_or_area + */ + function actionReverse(entityID, options) { + var ignoreKey = /^.*(_|:)?(description|name|note|website|ref|source|comment|watch|attribution)(_|:)?/; + var numeric = /^([+\-]?)(?=[\d.])/; + var directionKey = /direction$/; + var turn_lanes = /^turn:lanes:?/; + var keyReplacements = [[/:right$/, ':left'], [/:left$/, ':right'], [/:forward$/, ':backward'], [/:backward$/, ':forward'], [/:right:/, ':left:'], [/:left:/, ':right:'], [/:forward:/, ':backward:'], [/:backward:/, ':forward:']]; + var valueReplacements = { + left: 'right', + right: 'left', + up: 'down', + down: 'up', + forward: 'backward', + backward: 'forward', + forwards: 'backward', + backwards: 'forward' + }; + var roleReplacements = { + forward: 'backward', + backward: 'forward', + forwards: 'backward', + backwards: 'forward' + }; + var onewayReplacements = { + yes: '-1', + '1': '-1', + '-1': 'yes' + }; + var compassReplacements = { + N: 'S', + NNE: 'SSW', + NE: 'SW', + ENE: 'WSW', + E: 'W', + ESE: 'WNW', + SE: 'NW', + SSE: 'NNW', + S: 'N', + SSW: 'NNE', + SW: 'NE', + WSW: 'ENE', + W: 'E', + WNW: 'ESE', + NW: 'SE', + NNW: 'SSE' + }; - result = Reflect.construct(Super, arguments, NewTarget); - } else { - result = Super.apply(this, arguments); + function reverseKey(key) { + for (var i = 0; i < keyReplacements.length; ++i) { + var replacement = keyReplacements[i]; + + if (replacement[0].test(key)) { + return key.replace(replacement[0], replacement[1]); } + } - return _possibleConstructorReturn(this, result); - }; + return key; } - function _superPropBase(object, property) { - while (!Object.prototype.hasOwnProperty.call(object, property)) { - object = _getPrototypeOf(object); - if (object === null) break; + function reverseValue(key, value, includeAbsolute) { + if (ignoreKey.test(key)) return value; // Turn lanes are left/right to key (not way) direction - #5674 + + if (turn_lanes.test(key)) { + return value; + } else if (key === 'incline' && numeric.test(value)) { + return value.replace(numeric, function (_, sign) { + return sign === '-' ? '' : '-'; + }); + } else if (options && options.reverseOneway && key === 'oneway') { + return onewayReplacements[value] || value; + } else if (includeAbsolute && directionKey.test(key)) { + if (compassReplacements[value]) return compassReplacements[value]; + var degrees = parseFloat(value); + + if (typeof degrees === 'number' && !isNaN(degrees)) { + if (degrees < 180) { + degrees += 180; + } else { + degrees -= 180; + } + + return degrees.toString(); + } } - return object; - } + return valueReplacements[value] || value; + } // Reverse the direction of tags attached to the nodes - #3076 - function _get(target, property, receiver) { - if (typeof Reflect !== "undefined" && Reflect.get) { - _get = Reflect.get; - } else { - _get = function _get(target, property, receiver) { - var base = _superPropBase(target, property); - if (!base) return; - var desc = Object.getOwnPropertyDescriptor(base, property); + function reverseNodeTags(graph, nodeIDs) { + for (var i = 0; i < nodeIDs.length; i++) { + var node = graph.hasEntity(nodeIDs[i]); + if (!node || !Object.keys(node.tags).length) continue; + var tags = {}; - if (desc.get) { - return desc.get.call(receiver); - } + for (var key in node.tags) { + tags[reverseKey(key)] = reverseValue(key, node.tags[key], node.id === entityID); + } - return desc.value; - }; + graph = graph.replace(node.update({ + tags: tags + })); } - return _get(target, property, receiver || target); + return graph; } - var Emitter = /*#__PURE__*/function () { - function Emitter() { - _classCallCheck(this, Emitter); + function reverseWay(graph, way) { + var nodes = way.nodes.slice().reverse(); + var tags = {}; + var role; - Object.defineProperty(this, 'listeners', { - value: {}, - writable: true, - configurable: true - }); + for (var key in way.tags) { + tags[reverseKey(key)] = reverseValue(key, way.tags[key]); } - _createClass(Emitter, [{ - key: "addEventListener", - value: function addEventListener(type, callback, options) { - if (!(type in this.listeners)) { - this.listeners[type] = []; + graph.parentRelations(way).forEach(function (relation) { + relation.members.forEach(function (member, index) { + if (member.id === way.id && (role = roleReplacements[member.role])) { + relation = relation.updateMember({ + role: role + }, index); + graph = graph.replace(relation); } + }); + }); // Reverse any associated directions on nodes on the way and then replace + // the way itself with the reversed node ids and updated way tags - this.listeners[type].push({ - callback: callback, - options: options - }); - } - }, { - key: "removeEventListener", - value: function removeEventListener(type, callback) { - if (!(type in this.listeners)) { - return; - } + return reverseNodeTags(graph, nodes).replace(way.update({ + nodes: nodes, + tags: tags + })); + } - var stack = this.listeners[type]; + var action = function action(graph) { + var entity = graph.entity(entityID); - for (var i = 0, l = stack.length; i < l; i++) { - if (stack[i].callback === callback) { - stack.splice(i, 1); - return; - } - } - } - }, { - key: "dispatchEvent", - value: function dispatchEvent(event) { - if (!(event.type in this.listeners)) { - return; - } - - var stack = this.listeners[event.type]; - var stackToCall = stack.slice(); + if (entity.type === 'way') { + return reverseWay(graph, entity); + } - for (var i = 0, l = stackToCall.length; i < l; i++) { - var listener = stackToCall[i]; + return reverseNodeTags(graph, [entityID]); + }; - try { - listener.callback.call(this, event); - } catch (e) { - Promise.resolve().then(function () { - throw e; - }); - } + action.disabled = function (graph) { + var entity = graph.hasEntity(entityID); + if (!entity || entity.type === 'way') return false; - if (listener.options && listener.options.once) { - this.removeEventListener(event.type, listener.callback); - } - } + for (var key in entity.tags) { + var value = entity.tags[key]; - return !event.defaultPrevented; + if (reverseKey(key) !== key || reverseValue(key, value, true) !== value) { + return false; } - }]); - - return Emitter; - }(); - - var AbortSignal = /*#__PURE__*/function (_Emitter) { - _inherits(AbortSignal, _Emitter); - - var _super = _createSuper(AbortSignal); + } - function AbortSignal() { - var _this; + return 'nondirectional_node'; + }; - _classCallCheck(this, AbortSignal); + action.entityID = function () { + return entityID; + }; - _this = _super.call(this); // Some versions of babel does not transpile super() correctly for IE <= 10, if the parent - // constructor has failed to run, then "this.listeners" will still be undefined and then we call - // the parent constructor directly instead as a workaround. For general details, see babel bug: - // https://github.com/babel/babel/issues/3041 - // This hack was added as a fix for the issue described here: - // https://github.com/Financial-Times/polyfill-library/pull/59#issuecomment-477558042 + return action; + } - if (!_this.listeners) { - Emitter.call(_assertThisInitialized(_this)); - } // Compared to assignment, Object.defineProperty makes properties non-enumerable by default and - // we want Object.keys(new AbortController().signal) to be [] for compat with the native impl + function osmIsInterestingTag(key) { + return key !== 'attribution' && key !== 'created_by' && key !== 'source' && key !== 'odbl' && key.indexOf('source:') !== 0 && key.indexOf('source_ref') !== 0 && // purposely exclude colon + key.indexOf('tiger:') !== 0; + } + var osmAreaKeys = {}; + function osmSetAreaKeys(value) { + osmAreaKeys = value; + } // returns an object with the tag from `tags` that implies an area geometry, if any + function osmTagSuggestingArea(tags) { + if (tags.area === 'yes') return { + area: 'yes' + }; + if (tags.area === 'no') return null; // `highway` and `railway` are typically linear features, but there + // are a few exceptions that should be treated as areas, even in the + // absence of a proper `area=yes` or `areaKeys` tag.. see #4194 - Object.defineProperty(_assertThisInitialized(_this), 'aborted', { - value: false, - writable: true, - configurable: true - }); - Object.defineProperty(_assertThisInitialized(_this), 'onabort', { - value: null, - writable: true, - configurable: true - }); - return _this; + var lineKeys = { + highway: { + rest_area: true, + services: true + }, + railway: { + roundhouse: true, + station: true, + traverser: true, + turntable: true, + wash: true } + }; + var returnTags = {}; - _createClass(AbortSignal, [{ - key: "toString", - value: function toString() { - return '[object AbortSignal]'; - } - }, { - key: "dispatchEvent", - value: function dispatchEvent(event) { - if (event.type === 'abort') { - this.aborted = true; - - if (typeof this.onabort === 'function') { - this.onabort.call(this, event); - } - } + for (var key in tags) { + if (key in osmAreaKeys && !(tags[key] in osmAreaKeys[key])) { + returnTags[key] = tags[key]; + return returnTags; + } - _get(_getPrototypeOf(AbortSignal.prototype), "dispatchEvent", this).call(this, event); - } - }]); + if (key in lineKeys && tags[key] in lineKeys[key]) { + returnTags[key] = tags[key]; + return returnTags; + } + } - return AbortSignal; - }(Emitter); + return null; + } // Tags that indicate a node can be a standalone point + // e.g. { amenity: { bar: true, parking: true, ... } ... } - var AbortController = /*#__PURE__*/function () { - function AbortController() { - _classCallCheck(this, AbortController); // Compared to assignment, Object.defineProperty makes properties non-enumerable by default and - // we want Object.keys(new AbortController()) to be [] for compat with the native impl + var osmPointTags = {}; + function osmSetPointTags(value) { + osmPointTags = value; + } // Tags that indicate a node can be part of a way + // e.g. { amenity: { parking: true, ... }, highway: { stop: true ... } ... } + var osmVertexTags = {}; + function osmSetVertexTags(value) { + osmVertexTags = value; + } + function osmNodeGeometriesForTags(nodeTags) { + var geometries = {}; - Object.defineProperty(this, 'signal', { - value: new AbortSignal(), - writable: true, - configurable: true - }); + for (var key in nodeTags) { + if (osmPointTags[key] && (osmPointTags[key]['*'] || osmPointTags[key][nodeTags[key]])) { + geometries.point = true; } - _createClass(AbortController, [{ - key: "abort", - value: function abort() { - var event; - - try { - event = new Event('abort'); - } catch (e) { - if (typeof document !== 'undefined') { - if (!document.createEvent) { - // For Internet Explorer 8: - event = document.createEventObject(); - event.type = 'abort'; - } else { - // For Internet Explorer 11: - event = document.createEvent('Event'); - event.initEvent('abort', false, false); - } - } else { - // Fallback where document isn't available: - event = { - type: 'abort', - bubbles: false, - cancelable: false - }; - } - } - - this.signal.dispatchEvent(event); - } - }, { - key: "toString", - value: function toString() { - return '[object AbortController]'; - } - }]); + if (osmVertexTags[key] && (osmVertexTags[key]['*'] || osmVertexTags[key][nodeTags[key]])) { + geometries.vertex = true; + } // break early if both are already supported - return AbortController; - }(); - if (typeof Symbol !== 'undefined' && Symbol.toStringTag) { - // These are necessary to make sure that we get correct output for: - // Object.prototype.toString.call(new AbortController()) - AbortController.prototype[Symbol.toStringTag] = 'AbortController'; - AbortSignal.prototype[Symbol.toStringTag] = 'AbortSignal'; + if (geometries.point && geometries.vertex) break; } - function polyfillNeeded(self) { - if (self.__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL) { - console.log('__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL=true is set, will force install polyfill'); - return true; - } // Note that the "unfetch" minimal fetch polyfill defines fetch() without - // defining window.Request, and this polyfill need to work on top of unfetch - // so the below feature detection needs the !self.AbortController part. - // The Request.prototype check is also needed because Safari versions 11.1.2 - // up to and including 12.1.x has a window.AbortController present but still - // does NOT correctly implement abortable fetch: - // https://bugs.webkit.org/show_bug.cgi?id=174980#c2 - - - return typeof self.Request === 'function' && !self.Request.prototype.hasOwnProperty('signal') || !self.AbortController; + return geometries; + } + var osmOneWayTags = { + 'aerialway': { + 'chair_lift': true, + 'drag_lift': true, + 'j-bar': true, + 'magic_carpet': true, + 'mixed_lift': true, + 'platter': true, + 'rope_tow': true, + 't-bar': true, + 'zip_line': true + }, + 'highway': { + 'motorway': true + }, + 'junction': { + 'circular': true, + 'roundabout': true + }, + 'man_made': { + 'goods_conveyor': true, + 'piste:halfpipe': true + }, + 'piste:type': { + 'downhill': true, + 'sled': true, + 'yes': true + }, + 'seamark:type': { + 'separation_lane': true, + 'separation_roundabout': true + }, + 'waterway': { + 'canal': true, + 'ditch': true, + 'drain': true, + 'fish_pass': true, + 'river': true, + 'stream': true, + 'tidal_channel': true } - /** - * Note: the "fetch.Request" default value is available for fetch imported from - * the "node-fetch" package and not in browsers. This is OK since browsers - * will be importing umd-polyfill.js from that path "self" is passed the - * decorator so the default value will not be used (because browsers that define - * fetch also has Request). One quirky setup where self.fetch exists but - * self.Request does not is when the "unfetch" minimal fetch polyfill is used - * on top of IE11; for this case the browser will try to use the fetch.Request - * default value which in turn will be undefined but then then "if (Request)" - * will ensure that you get a patched fetch but still no Request (as expected). - * @param {fetch, Request = fetch.Request} - * @returns {fetch: abortableFetch, Request: AbortableRequest} - */ + }; // solid and smooth surfaces akin to the assumed default road surface in OSM + var osmPavedTags = { + 'surface': { + 'paved': true, + 'asphalt': true, + 'concrete': true, + 'concrete:lanes': true, + 'concrete:plates': true + }, + 'tracktype': { + 'grade1': true + } + }; // solid, if somewhat uncommon surfaces with a high range of smoothness - function abortableFetchDecorator(patchTargets) { - if ('function' === typeof patchTargets) { - patchTargets = { - fetch: patchTargets - }; - } + var osmSemipavedTags = { + 'surface': { + 'cobblestone': true, + 'cobblestone:flattened': true, + 'unhewn_cobblestone': true, + 'sett': true, + 'paving_stones': true, + 'metal': true, + 'wood': true + } + }; + var osmRightSideIsInsideTags = { + 'natural': { + 'cliff': true, + 'coastline': 'coastline' + }, + 'barrier': { + 'retaining_wall': true, + 'kerb': true, + 'guard_rail': true, + 'city_wall': true + }, + 'man_made': { + 'embankment': true + }, + 'waterway': { + 'weir': true + } + }; // "highway" tag values for pedestrian or vehicle right-of-ways that make up the routable network + // (does not include `raceway`) - var _patchTargets = patchTargets, - fetch = _patchTargets.fetch, - _patchTargets$Request = _patchTargets.Request, - NativeRequest = _patchTargets$Request === void 0 ? fetch.Request : _patchTargets$Request, - NativeAbortController = _patchTargets.AbortController, - _patchTargets$__FORCE = _patchTargets.__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL, - __FORCE_INSTALL_ABORTCONTROLLER_POLYFILL = _patchTargets$__FORCE === void 0 ? false : _patchTargets$__FORCE; + var osmRoutableHighwayTagValues = { + motorway: true, + trunk: true, + primary: true, + secondary: true, + tertiary: true, + residential: true, + motorway_link: true, + trunk_link: true, + primary_link: true, + secondary_link: true, + tertiary_link: true, + unclassified: true, + road: true, + service: true, + track: true, + living_street: true, + bus_guideway: true, + path: true, + footway: true, + cycleway: true, + bridleway: true, + pedestrian: true, + corridor: true, + steps: true + }; // "highway" tag values that generally do not allow motor vehicles - if (!polyfillNeeded({ - fetch: fetch, - Request: NativeRequest, - AbortController: NativeAbortController, - __FORCE_INSTALL_ABORTCONTROLLER_POLYFILL: __FORCE_INSTALL_ABORTCONTROLLER_POLYFILL - })) { - return { - fetch: fetch, - Request: Request - }; - } + var osmPathHighwayTagValues = { + path: true, + footway: true, + cycleway: true, + bridleway: true, + pedestrian: true, + corridor: true, + steps: true + }; // "railway" tag values representing existing railroad tracks (purposely does not include 'abandoned') - var Request = NativeRequest; // Note that the "unfetch" minimal fetch polyfill defines fetch() without - // defining window.Request, and this polyfill need to work on top of unfetch - // hence we only patch it if it's available. Also we don't patch it if signal - // is already available on the Request prototype because in this case support - // is present and the patching below can cause a crash since it assigns to - // request.signal which is technically a read-only property. This latter error - // happens when you run the main5.js node-fetch example in the repo - // "abortcontroller-polyfill-examples". The exact error is: - // request.signal = init.signal; - // ^ - // TypeError: Cannot set property signal of # which has only a getter + var osmRailwayTrackTagValues = { + rail: true, + light_rail: true, + tram: true, + subway: true, + monorail: true, + funicular: true, + miniature: true, + narrow_gauge: true, + disused: true, + preserved: true + }; // "waterway" tag values for line features representing water flow - if (Request && !Request.prototype.hasOwnProperty('signal') || __FORCE_INSTALL_ABORTCONTROLLER_POLYFILL) { - Request = function Request(input, init) { - var signal; + var osmFlowingWaterwayTagValues = { + canal: true, + ditch: true, + drain: true, + fish_pass: true, + river: true, + stream: true, + tidal_channel: true + }; - if (init && init.signal) { - signal = init.signal; // Never pass init.signal to the native Request implementation when the polyfill has - // been installed because if we're running on top of a browser with a - // working native AbortController (i.e. the polyfill was installed due to - // __FORCE_INSTALL_ABORTCONTROLLER_POLYFILL being set), then passing our - // fake AbortSignal to the native fetch will trigger: - // TypeError: Failed to construct 'Request': member signal is not of type AbortSignal. + var global$e = global$1m; + var fails$g = fails$S; + var uncurryThis$i = functionUncurryThis; + var toString$b = toString$k; + var trim$3 = stringTrim.trim; + var whitespaces = whitespaces$4; - delete init.signal; - } + var $parseInt$1 = global$e.parseInt; + var Symbol$1 = global$e.Symbol; + var ITERATOR = Symbol$1 && Symbol$1.iterator; + var hex$2 = /^[+-]?0x/i; + var exec$3 = uncurryThis$i(hex$2.exec); + var FORCED$8 = $parseInt$1(whitespaces + '08') !== 8 || $parseInt$1(whitespaces + '0x16') !== 22 + // MS Edge 18- broken with boxed symbols + || (ITERATOR && !fails$g(function () { $parseInt$1(Object(ITERATOR)); })); - var request = new NativeRequest(input, init); + // `parseInt` method + // https://tc39.es/ecma262/#sec-parseint-string-radix + var numberParseInt = FORCED$8 ? function parseInt(string, radix) { + var S = trim$3(toString$b(string)); + return $parseInt$1(S, (radix >>> 0) || (exec$3(hex$2, S) ? 16 : 10)); + } : $parseInt$1; - if (signal) { - Object.defineProperty(request, 'signal', { - writable: false, - enumerable: false, - configurable: true, - value: signal - }); - } + var $$G = _export; + var $parseInt = numberParseInt; - return request; - }; + // `parseInt` method + // https://tc39.es/ecma262/#sec-parseint-string-radix + $$G({ global: true, forced: parseInt != $parseInt }, { + parseInt: $parseInt + }); - Request.prototype = NativeRequest.prototype; - } + var internalMetadata = {exports: {}}; - var realFetch = fetch; + // FF26- bug: ArrayBuffers are non-extensible, but Object.isExtensible does not report it + var fails$f = fails$S; - var abortableFetch = function abortableFetch(input, init) { - var signal = Request && Request.prototype.isPrototypeOf(input) ? input.signal : init ? init.signal : undefined; + var arrayBufferNonExtensible = fails$f(function () { + if (typeof ArrayBuffer == 'function') { + var buffer = new ArrayBuffer(8); + // eslint-disable-next-line es/no-object-isextensible, es/no-object-defineproperty -- safe + if (Object.isExtensible(buffer)) Object.defineProperty(buffer, 'a', { value: 8 }); + } + }); - if (signal) { - var abortError; + var fails$e = fails$S; + var isObject$7 = isObject$s; + var classof = classofRaw$1; + var ARRAY_BUFFER_NON_EXTENSIBLE = arrayBufferNonExtensible; - try { - abortError = new DOMException('Aborted', 'AbortError'); - } catch (err) { - // IE 11 does not support calling the DOMException constructor, use a - // regular error object on it instead. - abortError = new Error('Aborted'); - abortError.name = 'AbortError'; - } // Return early if already aborted, thus avoiding making an HTTP request + // eslint-disable-next-line es/no-object-isextensible -- safe + var $isExtensible = Object.isExtensible; + var FAILS_ON_PRIMITIVES$1 = fails$e(function () { $isExtensible(1); }); + // `Object.isExtensible` method + // https://tc39.es/ecma262/#sec-object.isextensible + var objectIsExtensible = (FAILS_ON_PRIMITIVES$1 || ARRAY_BUFFER_NON_EXTENSIBLE) ? function isExtensible(it) { + if (!isObject$7(it)) return false; + if (ARRAY_BUFFER_NON_EXTENSIBLE && classof(it) == 'ArrayBuffer') return false; + return $isExtensible ? $isExtensible(it) : true; + } : $isExtensible; - if (signal.aborted) { - return Promise.reject(abortError); - } // Turn an event into a promise, reject it once `abort` is dispatched + var fails$d = fails$S; + var freezing = !fails$d(function () { + // eslint-disable-next-line es/no-object-isextensible, es/no-object-preventextensions -- required for testing + return Object.isExtensible(Object.preventExtensions({})); + }); - var cancellation = new Promise(function (_, reject) { - signal.addEventListener('abort', function () { - return reject(abortError); - }, { - once: true - }); - }); + var $$F = _export; + var uncurryThis$h = functionUncurryThis; + var hiddenKeys = hiddenKeys$6; + var isObject$6 = isObject$s; + var hasOwn$3 = hasOwnProperty_1; + var defineProperty$3 = objectDefineProperty.f; + var getOwnPropertyNamesModule = objectGetOwnPropertyNames; + var getOwnPropertyNamesExternalModule = objectGetOwnPropertyNamesExternal; + var isExtensible = objectIsExtensible; + var uid = uid$5; + var FREEZING$1 = freezing; - if (init && init.signal) { - // Never pass .signal to the native implementation when the polyfill has - // been installed because if we're running on top of a browser with a - // working native AbortController (i.e. the polyfill was installed due to - // __FORCE_INSTALL_ABORTCONTROLLER_POLYFILL being set), then passing our - // fake AbortSignal to the native fetch will trigger: - // TypeError: Failed to execute 'fetch' on 'Window': member signal is not of type AbortSignal. - delete init.signal; - } // Return the fastest promise (don't need to wait for request to finish) + var REQUIRED = false; + var METADATA = uid('meta'); + var id$1 = 0; + var setMetadata = function (it) { + defineProperty$3(it, METADATA, { value: { + objectID: 'O' + id$1++, // object ID + weakData: {} // weak collections IDs + } }); + }; - return Promise.race([cancellation, realFetch(input, init)]); - } + var fastKey$1 = function (it, create) { + // return a primitive with prefix + if (!isObject$6(it)) return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it; + if (!hasOwn$3(it, METADATA)) { + // can't set metadata to uncaught frozen object + if (!isExtensible(it)) return 'F'; + // not necessary to add metadata + if (!create) return 'E'; + // add missing metadata + setMetadata(it); + // return object ID + } return it[METADATA].objectID; + }; - return realFetch(input, init); - }; + var getWeakData = function (it, create) { + if (!hasOwn$3(it, METADATA)) { + // can't set metadata to uncaught frozen object + if (!isExtensible(it)) return true; + // not necessary to add metadata + if (!create) return false; + // add missing metadata + setMetadata(it); + // return the store of weak collections IDs + } return it[METADATA].weakData; + }; - return { - fetch: abortableFetch, - Request: Request + // add metadata on freeze-family methods calling + var onFreeze$1 = function (it) { + if (FREEZING$1 && REQUIRED && isExtensible(it) && !hasOwn$3(it, METADATA)) setMetadata(it); + return it; + }; + + var enable = function () { + meta.enable = function () { /* empty */ }; + REQUIRED = true; + var getOwnPropertyNames = getOwnPropertyNamesModule.f; + var splice = uncurryThis$h([].splice); + var test = {}; + test[METADATA] = 1; + + // prevent exposing of metadata key + if (getOwnPropertyNames(test).length) { + getOwnPropertyNamesModule.f = function (it) { + var result = getOwnPropertyNames(it); + for (var i = 0, length = result.length; i < length; i++) { + if (result[i] === METADATA) { + splice(result, i, 1); + break; + } + } return result; }; + + $$F({ target: 'Object', stat: true, forced: true }, { + getOwnPropertyNames: getOwnPropertyNamesExternalModule.f + }); } + }; - (function (self) { - if (!polyfillNeeded(self)) { - return; - } + var meta = internalMetadata.exports = { + enable: enable, + fastKey: fastKey$1, + getWeakData: getWeakData, + onFreeze: onFreeze$1 + }; - if (!self.fetch) { - console.warn('fetch() is not available, cannot install abortcontroller-polyfill'); - return; - } + hiddenKeys[METADATA] = true; - var _abortableFetch = abortableFetchDecorator(self), - fetch = _abortableFetch.fetch, - Request = _abortableFetch.Request; + var $$E = _export; + var global$d = global$1m; + var uncurryThis$g = functionUncurryThis; + var isForced$2 = isForced_1; + var redefine$4 = redefine$h.exports; + var InternalMetadataModule = internalMetadata.exports; + var iterate$1 = iterate$3; + var anInstance$2 = anInstance$7; + var isCallable$1 = isCallable$r; + var isObject$5 = isObject$s; + var fails$c = fails$S; + var checkCorrectnessOfIteration$1 = checkCorrectnessOfIteration$4; + var setToStringTag$1 = setToStringTag$a; + var inheritIfRequired$2 = inheritIfRequired$4; - self.fetch = fetch; - self.Request = Request; - Object.defineProperty(self, 'AbortController', { - writable: true, - enumerable: false, - configurable: true, - value: AbortController - }); - Object.defineProperty(self, 'AbortSignal', { - writable: true, - enumerable: false, - configurable: true, - value: AbortSignal - }); - })(typeof self !== 'undefined' ? self : commonjsGlobal); - }); + var collection$2 = function (CONSTRUCTOR_NAME, wrapper, common) { + var IS_MAP = CONSTRUCTOR_NAME.indexOf('Map') !== -1; + var IS_WEAK = CONSTRUCTOR_NAME.indexOf('Weak') !== -1; + var ADDER = IS_MAP ? 'set' : 'add'; + var NativeConstructor = global$d[CONSTRUCTOR_NAME]; + var NativePrototype = NativeConstructor && NativeConstructor.prototype; + var Constructor = NativeConstructor; + var exported = {}; - function actionAddEntity(way) { - return function (graph) { - return graph.replace(way); + var fixMethod = function (KEY) { + var uncurriedNativeMethod = uncurryThis$g(NativePrototype[KEY]); + redefine$4(NativePrototype, KEY, + KEY == 'add' ? function add(value) { + uncurriedNativeMethod(this, value === 0 ? 0 : value); + return this; + } : KEY == 'delete' ? function (key) { + return IS_WEAK && !isObject$5(key) ? false : uncurriedNativeMethod(this, key === 0 ? 0 : key); + } : KEY == 'get' ? function get(key) { + return IS_WEAK && !isObject$5(key) ? undefined : uncurriedNativeMethod(this, key === 0 ? 0 : key); + } : KEY == 'has' ? function has(key) { + return IS_WEAK && !isObject$5(key) ? false : uncurriedNativeMethod(this, key === 0 ? 0 : key); + } : function set(key, value) { + uncurriedNativeMethod(this, key === 0 ? 0 : key, value); + return this; + } + ); }; - } - - var $$E = _export; - var fails$f = fails$N; - var isArray$1 = isArray$6; - var isObject$7 = isObject$r; - var toObject$3 = toObject$i; - var toLength$5 = toLength$q; - var createProperty = createProperty$4; - var arraySpeciesCreate = arraySpeciesCreate$3; - var arrayMethodHasSpeciesSupport$1 = arrayMethodHasSpeciesSupport$5; - var wellKnownSymbol$2 = wellKnownSymbol$s; - var V8_VERSION = engineV8Version; - var IS_CONCAT_SPREADABLE = wellKnownSymbol$2('isConcatSpreadable'); - var MAX_SAFE_INTEGER = 0x1FFFFFFFFFFFFF; - var MAXIMUM_ALLOWED_INDEX_EXCEEDED = 'Maximum allowed index exceeded'; + var REPLACE = isForced$2( + CONSTRUCTOR_NAME, + !isCallable$1(NativeConstructor) || !(IS_WEAK || NativePrototype.forEach && !fails$c(function () { + new NativeConstructor().entries().next(); + })) + ); - // We can't use this feature detection in V8 since it causes - // deoptimization and serious performance degradation - // https://github.com/zloirock/core-js/issues/679 - var IS_CONCAT_SPREADABLE_SUPPORT = V8_VERSION >= 51 || !fails$f(function () { - var array = []; - array[IS_CONCAT_SPREADABLE] = false; - return array.concat()[0] !== array; - }); + if (REPLACE) { + // create collection constructor + Constructor = common.getConstructor(wrapper, CONSTRUCTOR_NAME, IS_MAP, ADDER); + InternalMetadataModule.enable(); + } else if (isForced$2(CONSTRUCTOR_NAME, true)) { + var instance = new Constructor(); + // early implementations not supports chaining + var HASNT_CHAINING = instance[ADDER](IS_WEAK ? {} : -0, 1) != instance; + // V8 ~ Chromium 40- weak-collections throws on primitives, but should return false + var THROWS_ON_PRIMITIVES = fails$c(function () { instance.has(1); }); + // most early implementations doesn't supports iterables, most modern - not close it correctly + // eslint-disable-next-line no-new -- required for testing + var ACCEPT_ITERABLES = checkCorrectnessOfIteration$1(function (iterable) { new NativeConstructor(iterable); }); + // for early implementations -0 and +0 not the same + var BUGGY_ZERO = !IS_WEAK && fails$c(function () { + // V8 ~ Chromium 42- fails only with 5+ elements + var $instance = new NativeConstructor(); + var index = 5; + while (index--) $instance[ADDER](index, index); + return !$instance.has(-0); + }); - var SPECIES_SUPPORT = arrayMethodHasSpeciesSupport$1('concat'); + if (!ACCEPT_ITERABLES) { + Constructor = wrapper(function (dummy, iterable) { + anInstance$2(dummy, NativePrototype); + var that = inheritIfRequired$2(new NativeConstructor(), dummy, Constructor); + if (iterable != undefined) iterate$1(iterable, that[ADDER], { that: that, AS_ENTRIES: IS_MAP }); + return that; + }); + Constructor.prototype = NativePrototype; + NativePrototype.constructor = Constructor; + } - var isConcatSpreadable = function (O) { - if (!isObject$7(O)) return false; - var spreadable = O[IS_CONCAT_SPREADABLE]; - return spreadable !== undefined ? !!spreadable : isArray$1(O); - }; + if (THROWS_ON_PRIMITIVES || BUGGY_ZERO) { + fixMethod('delete'); + fixMethod('has'); + IS_MAP && fixMethod('get'); + } - var FORCED$8 = !IS_CONCAT_SPREADABLE_SUPPORT || !SPECIES_SUPPORT; + if (BUGGY_ZERO || HASNT_CHAINING) fixMethod(ADDER); - // `Array.prototype.concat` method - // https://tc39.es/ecma262/#sec-array.prototype.concat - // with adding support of @@isConcatSpreadable and @@species - $$E({ target: 'Array', proto: true, forced: FORCED$8 }, { - // eslint-disable-next-line no-unused-vars -- required for `.length` - concat: function concat(arg) { - var O = toObject$3(this); - var A = arraySpeciesCreate(O, 0); - var n = 0; - var i, k, length, len, E; - for (i = -1, length = arguments.length; i < length; i++) { - E = i === -1 ? O : arguments[i]; - if (isConcatSpreadable(E)) { - len = toLength$5(E.length); - if (n + len > MAX_SAFE_INTEGER) throw TypeError(MAXIMUM_ALLOWED_INDEX_EXCEEDED); - for (k = 0; k < len; k++, n++) if (k in E) createProperty(A, n, E[k]); - } else { - if (n >= MAX_SAFE_INTEGER) throw TypeError(MAXIMUM_ALLOWED_INDEX_EXCEEDED); - createProperty(A, n++, E); - } - } - A.length = n; - return A; + // weak collections should not contains .clear method + if (IS_WEAK && NativePrototype.clear) delete NativePrototype.clear; } - }); - var $$D = _export; - var assign$1 = objectAssign; + exported[CONSTRUCTOR_NAME] = Constructor; + $$E({ global: true, forced: Constructor != NativeConstructor }, exported); - // `Object.assign` method - // https://tc39.es/ecma262/#sec-object.assign - // eslint-disable-next-line es/no-object-assign -- required for testing - $$D({ target: 'Object', stat: true, forced: Object.assign !== assign$1 }, { - assign: assign$1 - }); + setToStringTag$1(Constructor, CONSTRUCTOR_NAME); - var $$C = _export; - var $filter = arrayIteration.filter; - var arrayMethodHasSpeciesSupport = arrayMethodHasSpeciesSupport$5; + if (!IS_WEAK) common.setStrong(Constructor, CONSTRUCTOR_NAME, IS_MAP); - var HAS_SPECIES_SUPPORT = arrayMethodHasSpeciesSupport('filter'); + return Constructor; + }; - // `Array.prototype.filter` method - // https://tc39.es/ecma262/#sec-array.prototype.filter - // with adding support of @@species - $$C({ target: 'Array', proto: true, forced: !HAS_SPECIES_SUPPORT }, { - filter: function filter(callbackfn /* , thisArg */) { - return $filter(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined); - } - }); + var defineProperty$2 = objectDefineProperty.f; + var create$3 = objectCreate; + var redefineAll = redefineAll$4; + var bind$6 = functionBindContext; + var anInstance$1 = anInstance$7; + var iterate = iterate$3; + var defineIterator = defineIterator$3; + var setSpecies$1 = setSpecies$5; + var DESCRIPTORS$6 = descriptors; + var fastKey = internalMetadata.exports.fastKey; + var InternalStateModule$1 = internalState; - var $$B = _export; - var toObject$2 = toObject$i; - var nativeKeys = objectKeys$4; - var fails$e = fails$N; + var setInternalState$1 = InternalStateModule$1.set; + var internalStateGetterFor = InternalStateModule$1.getterFor; - var FAILS_ON_PRIMITIVES$1 = fails$e(function () { nativeKeys(1); }); + var collectionStrong$2 = { + getConstructor: function (wrapper, CONSTRUCTOR_NAME, IS_MAP, ADDER) { + var Constructor = wrapper(function (that, iterable) { + anInstance$1(that, Prototype); + setInternalState$1(that, { + type: CONSTRUCTOR_NAME, + index: create$3(null), + first: undefined, + last: undefined, + size: 0 + }); + if (!DESCRIPTORS$6) that.size = 0; + if (iterable != undefined) iterate(iterable, that[ADDER], { that: that, AS_ENTRIES: IS_MAP }); + }); - // `Object.keys` method - // https://tc39.es/ecma262/#sec-object.keys - $$B({ target: 'Object', stat: true, forced: FAILS_ON_PRIMITIVES$1 }, { - keys: function keys(it) { - return nativeKeys(toObject$2(it)); - } - }); + var Prototype = Constructor.prototype; - var $$A = _export; - var isArray = isArray$6; + var getInternalState = internalStateGetterFor(CONSTRUCTOR_NAME); - var nativeReverse = [].reverse; - var test$1 = [1, 2]; + var define = function (that, key, value) { + var state = getInternalState(that); + var entry = getEntry(that, key); + var previous, index; + // change existing entry + if (entry) { + entry.value = value; + // create new entry + } else { + state.last = entry = { + index: index = fastKey(key, true), + key: key, + value: value, + previous: previous = state.last, + next: undefined, + removed: false + }; + if (!state.first) state.first = entry; + if (previous) previous.next = entry; + if (DESCRIPTORS$6) state.size++; + else that.size++; + // add to index + if (index !== 'F') state.index[index] = entry; + } return that; + }; - // `Array.prototype.reverse` method - // https://tc39.es/ecma262/#sec-array.prototype.reverse - // fix for Safari 12.0 bug - // https://bugs.webkit.org/show_bug.cgi?id=188794 - $$A({ target: 'Array', proto: true, forced: String(test$1) === String(test$1.reverse()) }, { - reverse: function reverse() { - // eslint-disable-next-line no-self-assign -- dirty hack - if (isArray(this)) this.length = this.length; - return nativeReverse.call(this); - } - }); + var getEntry = function (that, key) { + var state = getInternalState(that); + // fast case + var index = fastKey(key); + var entry; + if (index !== 'F') return state.index[index]; + // frozen object case + for (entry = state.first; entry; entry = entry.next) { + if (entry.key == key) return entry; + } + }; - var global$6 = global$F; - var trim$4 = stringTrim.trim; - var whitespaces$1 = whitespaces$4; + redefineAll(Prototype, { + // `{ Map, Set }.prototype.clear()` methods + // https://tc39.es/ecma262/#sec-map.prototype.clear + // https://tc39.es/ecma262/#sec-set.prototype.clear + clear: function clear() { + var that = this; + var state = getInternalState(that); + var data = state.index; + var entry = state.first; + while (entry) { + entry.removed = true; + if (entry.previous) entry.previous = entry.previous.next = undefined; + delete data[entry.index]; + entry = entry.next; + } + state.first = state.last = undefined; + if (DESCRIPTORS$6) state.size = 0; + else that.size = 0; + }, + // `{ Map, Set }.prototype.delete(key)` methods + // https://tc39.es/ecma262/#sec-map.prototype.delete + // https://tc39.es/ecma262/#sec-set.prototype.delete + 'delete': function (key) { + var that = this; + var state = getInternalState(that); + var entry = getEntry(that, key); + if (entry) { + var next = entry.next; + var prev = entry.previous; + delete state.index[entry.index]; + entry.removed = true; + if (prev) prev.next = next; + if (next) next.previous = prev; + if (state.first == entry) state.first = next; + if (state.last == entry) state.last = prev; + if (DESCRIPTORS$6) state.size--; + else that.size--; + } return !!entry; + }, + // `{ Map, Set }.prototype.forEach(callbackfn, thisArg = undefined)` methods + // https://tc39.es/ecma262/#sec-map.prototype.foreach + // https://tc39.es/ecma262/#sec-set.prototype.foreach + forEach: function forEach(callbackfn /* , that = undefined */) { + var state = getInternalState(this); + var boundFunction = bind$6(callbackfn, arguments.length > 1 ? arguments[1] : undefined); + var entry; + while (entry = entry ? entry.next : state.first) { + boundFunction(entry.value, entry.key, this); + // revert to the last existing entry + while (entry && entry.removed) entry = entry.previous; + } + }, + // `{ Map, Set}.prototype.has(key)` methods + // https://tc39.es/ecma262/#sec-map.prototype.has + // https://tc39.es/ecma262/#sec-set.prototype.has + has: function has(key) { + return !!getEntry(this, key); + } + }); - var $parseFloat = global$6.parseFloat; - var FORCED$7 = 1 / $parseFloat(whitespaces$1 + '-0') !== -Infinity; + redefineAll(Prototype, IS_MAP ? { + // `Map.prototype.get(key)` method + // https://tc39.es/ecma262/#sec-map.prototype.get + get: function get(key) { + var entry = getEntry(this, key); + return entry && entry.value; + }, + // `Map.prototype.set(key, value)` method + // https://tc39.es/ecma262/#sec-map.prototype.set + set: function set(key, value) { + return define(this, key === 0 ? 0 : key, value); + } + } : { + // `Set.prototype.add(value)` method + // https://tc39.es/ecma262/#sec-set.prototype.add + add: function add(value) { + return define(this, value = value === 0 ? 0 : value, value); + } + }); + if (DESCRIPTORS$6) defineProperty$2(Prototype, 'size', { + get: function () { + return getInternalState(this).size; + } + }); + return Constructor; + }, + setStrong: function (Constructor, CONSTRUCTOR_NAME, IS_MAP) { + var ITERATOR_NAME = CONSTRUCTOR_NAME + ' Iterator'; + var getInternalCollectionState = internalStateGetterFor(CONSTRUCTOR_NAME); + var getInternalIteratorState = internalStateGetterFor(ITERATOR_NAME); + // `{ Map, Set }.prototype.{ keys, values, entries, @@iterator }()` methods + // https://tc39.es/ecma262/#sec-map.prototype.entries + // https://tc39.es/ecma262/#sec-map.prototype.keys + // https://tc39.es/ecma262/#sec-map.prototype.values + // https://tc39.es/ecma262/#sec-map.prototype-@@iterator + // https://tc39.es/ecma262/#sec-set.prototype.entries + // https://tc39.es/ecma262/#sec-set.prototype.keys + // https://tc39.es/ecma262/#sec-set.prototype.values + // https://tc39.es/ecma262/#sec-set.prototype-@@iterator + defineIterator(Constructor, CONSTRUCTOR_NAME, function (iterated, kind) { + setInternalState$1(this, { + type: ITERATOR_NAME, + target: iterated, + state: getInternalCollectionState(iterated), + kind: kind, + last: undefined + }); + }, function () { + var state = getInternalIteratorState(this); + var kind = state.kind; + var entry = state.last; + // revert to the last existing entry + while (entry && entry.removed) entry = entry.previous; + // get next entry + if (!state.target || !(state.last = entry = entry ? entry.next : state.state.first)) { + // or finish the iteration + state.target = undefined; + return { value: undefined, done: true }; + } + // return step by kind + if (kind == 'keys') return { value: entry.key, done: false }; + if (kind == 'values') return { value: entry.value, done: false }; + return { value: [entry.key, entry.value], done: false }; + }, IS_MAP ? 'entries' : 'values', !IS_MAP, true); - // `parseFloat` method - // https://tc39.es/ecma262/#sec-parsefloat-string - var numberParseFloat = FORCED$7 ? function parseFloat(string) { - var trimmedString = trim$4(String(string)); - var result = $parseFloat(trimmedString); - return result === 0 && trimmedString.charAt(0) == '-' ? -0 : result; - } : $parseFloat; + // `{ Map, Set }.prototype[@@species]` accessors + // https://tc39.es/ecma262/#sec-get-map-@@species + // https://tc39.es/ecma262/#sec-get-set-@@species + setSpecies$1(CONSTRUCTOR_NAME); + } + }; - var $$z = _export; - var parseFloatImplementation = numberParseFloat; + var collection$1 = collection$2; + var collectionStrong$1 = collectionStrong$2; - // `parseFloat` method - // https://tc39.es/ecma262/#sec-parsefloat-string - $$z({ global: true, forced: parseFloat != parseFloatImplementation }, { - parseFloat: parseFloatImplementation - }); + // `Set` constructor + // https://tc39.es/ecma262/#sec-set-objects + collection$1('Set', function (init) { + return function Set() { return init(this, arguments.length ? arguments[0] : undefined); }; + }, collectionStrong$1); - /* - Order the nodes of a way in reverse order and reverse any direction dependent tags - other than `oneway`. (We assume that correcting a backwards oneway is the primary - reason for reversing a way.) + function d3_ascending (a, b) { + return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; + } - In addition, numeric-valued `incline` tags are negated. + function d3_bisector (f) { + var delta = f; + var compare = f; - The JOSM implementation was used as a guide, but transformations that were of unclear benefit - or adjusted tags that don't seem to be used in practice were omitted. + if (f.length === 1) { + delta = function delta(d, x) { + return f(d) - x; + }; - References: - http://wiki.openstreetmap.org/wiki/Forward_%26_backward,_left_%26_right - http://wiki.openstreetmap.org/wiki/Key:direction#Steps - http://wiki.openstreetmap.org/wiki/Key:incline - http://wiki.openstreetmap.org/wiki/Route#Members - http://josm.openstreetmap.de/browser/josm/trunk/src/org/openstreetmap/josm/corrector/ReverseWayTagCorrector.java - http://wiki.openstreetmap.org/wiki/Tag:highway%3Dstop - http://wiki.openstreetmap.org/wiki/Key:traffic_sign#On_a_way_or_area - */ - function actionReverse(entityID, options) { - var ignoreKey = /^.*(_|:)?(description|name|note|website|ref|source|comment|watch|attribution)(_|:)?/; - var numeric = /^([+\-]?)(?=[\d.])/; - var directionKey = /direction$/; - var turn_lanes = /^turn:lanes:?/; - var keyReplacements = [[/:right$/, ':left'], [/:left$/, ':right'], [/:forward$/, ':backward'], [/:backward$/, ':forward'], [/:right:/, ':left:'], [/:left:/, ':right:'], [/:forward:/, ':backward:'], [/:backward:/, ':forward:']]; - var valueReplacements = { - left: 'right', - right: 'left', - up: 'down', - down: 'up', - forward: 'backward', - backward: 'forward', - forwards: 'backward', - backwards: 'forward' - }; - var roleReplacements = { - forward: 'backward', - backward: 'forward', - forwards: 'backward', - backwards: 'forward' - }; - var onewayReplacements = { - yes: '-1', - '1': '-1', - '-1': 'yes' - }; - var compassReplacements = { - N: 'S', - NNE: 'SSW', - NE: 'SW', - ENE: 'WSW', - E: 'W', - ESE: 'WNW', - SE: 'NW', - SSE: 'NNW', - S: 'N', - SSW: 'NNE', - SW: 'NE', - WSW: 'ENE', - W: 'E', - WNW: 'ESE', - NW: 'SE', - NNW: 'SSE' - }; + compare = ascendingComparator(f); + } - function reverseKey(key) { - for (var i = 0; i < keyReplacements.length; ++i) { - var replacement = keyReplacements[i]; + function left(a, x, lo, hi) { + if (lo == null) lo = 0; + if (hi == null) hi = a.length; - if (replacement[0].test(key)) { - return key.replace(replacement[0], replacement[1]); - } + while (lo < hi) { + var mid = lo + hi >>> 1; + if (compare(a[mid], x) < 0) lo = mid + 1;else hi = mid; } - return key; + return lo; } - function reverseValue(key, value, includeAbsolute) { - if (ignoreKey.test(key)) return value; // Turn lanes are left/right to key (not way) direction - #5674 - - if (turn_lanes.test(key)) { - return value; - } else if (key === 'incline' && numeric.test(value)) { - return value.replace(numeric, function (_, sign) { - return sign === '-' ? '' : '-'; - }); - } else if (options && options.reverseOneway && key === 'oneway') { - return onewayReplacements[value] || value; - } else if (includeAbsolute && directionKey.test(key)) { - if (compassReplacements[value]) return compassReplacements[value]; - var degrees = parseFloat(value); - - if (typeof degrees === 'number' && !isNaN(degrees)) { - if (degrees < 180) { - degrees += 180; - } else { - degrees -= 180; - } + function right(a, x, lo, hi) { + if (lo == null) lo = 0; + if (hi == null) hi = a.length; - return degrees.toString(); - } + while (lo < hi) { + var mid = lo + hi >>> 1; + if (compare(a[mid], x) > 0) hi = mid;else lo = mid + 1; } - return valueReplacements[value] || value; - } // Reverse the direction of tags attached to the nodes - #3076 - + return lo; + } - function reverseNodeTags(graph, nodeIDs) { - for (var i = 0; i < nodeIDs.length; i++) { - var node = graph.hasEntity(nodeIDs[i]); - if (!node || !Object.keys(node.tags).length) continue; - var tags = {}; + function center(a, x, lo, hi) { + if (lo == null) lo = 0; + if (hi == null) hi = a.length; + var i = left(a, x, lo, hi - 1); + return i > lo && delta(a[i - 1], x) > -delta(a[i], x) ? i - 1 : i; + } - for (var key in node.tags) { - tags[reverseKey(key)] = reverseValue(key, node.tags[key], node.id === entityID); - } + return { + left: left, + center: center, + right: right + }; + } - graph = graph.replace(node.update({ - tags: tags - })); - } + function ascendingComparator(f) { + return function (d, x) { + return d3_ascending(f(d), x); + }; + } - return graph; - } + var defineWellKnownSymbol = defineWellKnownSymbol$4; - function reverseWay(graph, way) { - var nodes = way.nodes.slice().reverse(); - var tags = {}; - var role; + // `Symbol.asyncIterator` well-known symbol + // https://tc39.es/ecma262/#sec-symbol.asynciterator + defineWellKnownSymbol('asyncIterator'); - for (var key in way.tags) { - tags[reverseKey(key)] = reverseValue(key, way.tags[key]); - } + var runtime = {exports: {}}; - graph.parentRelations(way).forEach(function (relation) { - relation.members.forEach(function (member, index) { - if (member.id === way.id && (role = roleReplacements[member.role])) { - relation = relation.updateMember({ - role: role - }, index); - graph = graph.replace(relation); - } - }); - }); // Reverse any associated directions on nodes on the way and then replace - // the way itself with the reversed node ids and updated way tags + (function (module) { + var runtime = function (exports) { - return reverseNodeTags(graph, nodes).replace(way.update({ - nodes: nodes, - tags: tags - })); - } + var Op = Object.prototype; + var hasOwn = Op.hasOwnProperty; + var undefined$1; // More compressible than void 0. - var action = function action(graph) { - var entity = graph.entity(entityID); + var $Symbol = typeof Symbol === "function" ? Symbol : {}; + var iteratorSymbol = $Symbol.iterator || "@@iterator"; + var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator"; + var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; - if (entity.type === 'way') { - return reverseWay(graph, entity); + function define(obj, key, value) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + return obj[key]; } - return reverseNodeTags(graph, [entityID]); - }; + try { + // IE 8 has a broken Object.defineProperty that only works on DOM objects. + define({}, ""); + } catch (err) { + define = function define(obj, key, value) { + return obj[key] = value; + }; + } - action.disabled = function (graph) { - var entity = graph.hasEntity(entityID); - if (!entity || entity.type === 'way') return false; + function wrap(innerFn, outerFn, self, tryLocsList) { + // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator. + var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator; + var generator = Object.create(protoGenerator.prototype); + var context = new Context(tryLocsList || []); // The ._invoke method unifies the implementations of the .next, + // .throw, and .return methods. - for (var key in entity.tags) { - var value = entity.tags[key]; + generator._invoke = makeInvokeMethod(innerFn, self, context); + return generator; + } - if (reverseKey(key) !== key || reverseValue(key, value, true) !== value) { - return false; + exports.wrap = wrap; // Try/catch helper to minimize deoptimizations. Returns a completion + // record like context.tryEntries[i].completion. This interface could + // have been (and was previously) designed to take a closure to be + // invoked without arguments, but in all the cases we care about we + // already have an existing method we want to call, so there's no need + // to create a new function object. We can even get away with assuming + // the method takes exactly one argument, since that happens to be true + // in every case, so we don't have to touch the arguments object. The + // only additional allocation required is the completion record, which + // has a stable shape and so hopefully should be cheap to allocate. + + function tryCatch(fn, obj, arg) { + try { + return { + type: "normal", + arg: fn.call(obj, arg) + }; + } catch (err) { + return { + type: "throw", + arg: err + }; } } - return 'nondirectional_node'; - }; + var GenStateSuspendedStart = "suspendedStart"; + var GenStateSuspendedYield = "suspendedYield"; + var GenStateExecuting = "executing"; + var GenStateCompleted = "completed"; // Returning this object from the innerFn has the same effect as + // breaking out of the dispatch switch statement. - action.entityID = function () { - return entityID; - }; + var ContinueSentinel = {}; // Dummy constructor functions that we use as the .constructor and + // .constructor.prototype properties for functions that return Generator + // objects. For full spec compliance, you may wish to configure your + // minifier not to mangle the names of these two functions. - return action; - } + function Generator() {} - function osmIsInterestingTag(key) { - return key !== 'attribution' && key !== 'created_by' && key !== 'source' && key !== 'odbl' && key.indexOf('source:') !== 0 && key.indexOf('source_ref') !== 0 && // purposely exclude colon - key.indexOf('tiger:') !== 0; - } - var osmAreaKeys = {}; - function osmSetAreaKeys(value) { - osmAreaKeys = value; - } // returns an object with the tag from `tags` that implies an area geometry, if any + function GeneratorFunction() {} - function osmTagSuggestingArea(tags) { - if (tags.area === 'yes') return { - area: 'yes' - }; - if (tags.area === 'no') return null; // `highway` and `railway` are typically linear features, but there - // are a few exceptions that should be treated as areas, even in the - // absence of a proper `area=yes` or `areaKeys` tag.. see #4194 + function GeneratorFunctionPrototype() {} // This is a polyfill for %IteratorPrototype% for environments that + // don't natively support it. - var lineKeys = { - highway: { - rest_area: true, - services: true - }, - railway: { - roundhouse: true, - station: true, - traverser: true, - turntable: true, - wash: true - } - }; - var returnTags = {}; - for (var key in tags) { - if (key in osmAreaKeys && !(tags[key] in osmAreaKeys[key])) { - returnTags[key] = tags[key]; - return returnTags; - } + var IteratorPrototype = {}; + define(IteratorPrototype, iteratorSymbol, function () { + return this; + }); + var getProto = Object.getPrototypeOf; + var NativeIteratorPrototype = getProto && getProto(getProto(values([]))); - if (key in lineKeys && tags[key] in lineKeys[key]) { - returnTags[key] = tags[key]; - return returnTags; + if (NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) { + // This environment has a native %IteratorPrototype%; use it instead + // of the polyfill. + IteratorPrototype = NativeIteratorPrototype; } - } - return null; - } // Tags that indicate a node can be a standalone point - // e.g. { amenity: { bar: true, parking: true, ... } ... } + var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype); + GeneratorFunction.prototype = GeneratorFunctionPrototype; + define(Gp, "constructor", GeneratorFunctionPrototype); + define(GeneratorFunctionPrototype, "constructor", GeneratorFunction); + GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"); // Helper for defining the .next, .throw, and .return methods of the + // Iterator interface in terms of a single ._invoke method. - var osmPointTags = {}; - function osmSetPointTags(value) { - osmPointTags = value; - } // Tags that indicate a node can be part of a way - // e.g. { amenity: { parking: true, ... }, highway: { stop: true ... } ... } + function defineIteratorMethods(prototype) { + ["next", "throw", "return"].forEach(function (method) { + define(prototype, method, function (arg) { + return this._invoke(method, arg); + }); + }); + } - var osmVertexTags = {}; - function osmSetVertexTags(value) { - osmVertexTags = value; - } - function osmNodeGeometriesForTags(nodeTags) { - var geometries = {}; + exports.isGeneratorFunction = function (genFun) { + var ctor = typeof genFun === "function" && genFun.constructor; + return ctor ? ctor === GeneratorFunction || // For the native GeneratorFunction constructor, the best we can + // do is to check its .name property. + (ctor.displayName || ctor.name) === "GeneratorFunction" : false; + }; - for (var key in nodeTags) { - if (osmPointTags[key] && (osmPointTags[key]['*'] || osmPointTags[key][nodeTags[key]])) { - geometries.point = true; - } + exports.mark = function (genFun) { + if (Object.setPrototypeOf) { + Object.setPrototypeOf(genFun, GeneratorFunctionPrototype); + } else { + genFun.__proto__ = GeneratorFunctionPrototype; + define(genFun, toStringTagSymbol, "GeneratorFunction"); + } - if (osmVertexTags[key] && (osmVertexTags[key]['*'] || osmVertexTags[key][nodeTags[key]])) { - geometries.vertex = true; - } // break early if both are already supported + genFun.prototype = Object.create(Gp); + return genFun; + }; // Within the body of any async function, `await x` is transformed to + // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test + // `hasOwn.call(value, "__await")` to determine if the yielded value is + // meant to be awaited. - if (geometries.point && geometries.vertex) break; - } + exports.awrap = function (arg) { + return { + __await: arg + }; + }; - return geometries; - } - var osmOneWayTags = { - 'aerialway': { - 'chair_lift': true, - 'drag_lift': true, - 'j-bar': true, - 'magic_carpet': true, - 'mixed_lift': true, - 'platter': true, - 'rope_tow': true, - 't-bar': true, - 'zip_line': true - }, - 'highway': { - 'motorway': true - }, - 'junction': { - 'circular': true, - 'roundabout': true - }, - 'man_made': { - 'goods_conveyor': true, - 'piste:halfpipe': true - }, - 'piste:type': { - 'downhill': true, - 'sled': true, - 'yes': true - }, - 'waterway': { - 'canal': true, - 'ditch': true, - 'drain': true, - 'fish_pass': true, - 'river': true, - 'stream': true, - 'tidal_channel': true - } - }; // solid and smooth surfaces akin to the assumed default road surface in OSM + function AsyncIterator(generator, PromiseImpl) { + function invoke(method, arg, resolve, reject) { + var record = tryCatch(generator[method], generator, arg); - var osmPavedTags = { - 'surface': { - 'paved': true, - 'asphalt': true, - 'concrete': true, - 'concrete:lanes': true, - 'concrete:plates': true - }, - 'tracktype': { - 'grade1': true - } - }; // solid, if somewhat uncommon surfaces with a high range of smoothness + if (record.type === "throw") { + reject(record.arg); + } else { + var result = record.arg; + var value = result.value; - var osmSemipavedTags = { - 'surface': { - 'cobblestone': true, - 'cobblestone:flattened': true, - 'unhewn_cobblestone': true, - 'sett': true, - 'paving_stones': true, - 'metal': true, - 'wood': true - } - }; - var osmRightSideIsInsideTags = { - 'natural': { - 'cliff': true, - 'coastline': 'coastline' - }, - 'barrier': { - 'retaining_wall': true, - 'kerb': true, - 'guard_rail': true, - 'city_wall': true - }, - 'man_made': { - 'embankment': true - }, - 'waterway': { - 'weir': true - } - }; // "highway" tag values for pedestrian or vehicle right-of-ways that make up the routable network - // (does not include `raceway`) + if (value && _typeof(value) === "object" && hasOwn.call(value, "__await")) { + return PromiseImpl.resolve(value.__await).then(function (value) { + invoke("next", value, resolve, reject); + }, function (err) { + invoke("throw", err, resolve, reject); + }); + } - var osmRoutableHighwayTagValues = { - motorway: true, - trunk: true, - primary: true, - secondary: true, - tertiary: true, - residential: true, - motorway_link: true, - trunk_link: true, - primary_link: true, - secondary_link: true, - tertiary_link: true, - unclassified: true, - road: true, - service: true, - track: true, - living_street: true, - bus_guideway: true, - path: true, - footway: true, - cycleway: true, - bridleway: true, - pedestrian: true, - corridor: true, - steps: true - }; // "highway" tag values that generally do not allow motor vehicles + return PromiseImpl.resolve(value).then(function (unwrapped) { + // When a yielded Promise is resolved, its final value becomes + // the .value of the Promise<{value,done}> result for the + // current iteration. + result.value = unwrapped; + resolve(result); + }, function (error) { + // If a rejected Promise was yielded, throw the rejection back + // into the async generator function so it can be handled there. + return invoke("throw", error, resolve, reject); + }); + } + } - var osmPathHighwayTagValues = { - path: true, - footway: true, - cycleway: true, - bridleway: true, - pedestrian: true, - corridor: true, - steps: true - }; // "railway" tag values representing existing railroad tracks (purposely does not include 'abandoned') + var previousPromise; - var osmRailwayTrackTagValues = { - rail: true, - light_rail: true, - tram: true, - subway: true, - monorail: true, - funicular: true, - miniature: true, - narrow_gauge: true, - disused: true, - preserved: true - }; // "waterway" tag values for line features representing water flow + function enqueue(method, arg) { + function callInvokeWithMethodAndArg() { + return new PromiseImpl(function (resolve, reject) { + invoke(method, arg, resolve, reject); + }); + } - var osmFlowingWaterwayTagValues = { - canal: true, - ditch: true, - drain: true, - fish_pass: true, - river: true, - stream: true, - tidal_channel: true - }; + return previousPromise = // If enqueue has been called before, then we want to wait until + // all previous Promises have been resolved before calling invoke, + // so that results are always delivered in the correct order. If + // enqueue has not been called before, then it is important to + // call invoke immediately, without waiting on a callback to fire, + // so that the async generator function has the opportunity to do + // any necessary setup in a predictable way. This predictability + // is why the Promise constructor synchronously invokes its + // executor callback, and why async functions synchronously + // execute code before the first await. Since we implement simple + // async functions in terms of async generators, it is especially + // important to get this right, even though it requires care. + previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, // Avoid propagating failures to Promises returned by later + // invocations of the iterator. + callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); + } // Define the unified helper method that is used to implement .next, + // .throw, and .return (see defineIteratorMethods). - var global$5 = global$F; - var trim$3 = stringTrim.trim; - var whitespaces = whitespaces$4; - var $parseInt = global$5.parseInt; - var hex$2 = /^[+-]?0[Xx]/; - var FORCED$6 = $parseInt(whitespaces + '08') !== 8 || $parseInt(whitespaces + '0x16') !== 22; + this._invoke = enqueue; + } - // `parseInt` method - // https://tc39.es/ecma262/#sec-parseint-string-radix - var numberParseInt = FORCED$6 ? function parseInt(string, radix) { - var S = trim$3(String(string)); - return $parseInt(S, (radix >>> 0) || (hex$2.test(S) ? 16 : 10)); - } : $parseInt; + defineIteratorMethods(AsyncIterator.prototype); + define(AsyncIterator.prototype, asyncIteratorSymbol, function () { + return this; + }); + exports.AsyncIterator = AsyncIterator; // Note that simple async functions are implemented on top of + // AsyncIterator objects; they just return a Promise for the value of + // the final result produced by the iterator. - var $$y = _export; - var parseIntImplementation = numberParseInt; + exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) { + if (PromiseImpl === void 0) PromiseImpl = Promise; + var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl); + return exports.isGeneratorFunction(outerFn) ? iter // If outerFn is a generator, return the full iterator. + : iter.next().then(function (result) { + return result.done ? result.value : iter.next(); + }); + }; - // `parseInt` method - // https://tc39.es/ecma262/#sec-parseint-string-radix - $$y({ global: true, forced: parseInt != parseIntImplementation }, { - parseInt: parseIntImplementation - }); + function makeInvokeMethod(innerFn, self, context) { + var state = GenStateSuspendedStart; + return function invoke(method, arg) { + if (state === GenStateExecuting) { + throw new Error("Generator is already running"); + } - var internalMetadata = {exports: {}}; + if (state === GenStateCompleted) { + if (method === "throw") { + throw arg; + } // Be forgiving, per 25.3.3.3.3 of the spec: + // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume - var fails$d = fails$N; - var freezing = !fails$d(function () { - // eslint-disable-next-line es/no-object-isextensible, es/no-object-preventextensions -- required for testing - return Object.isExtensible(Object.preventExtensions({})); - }); + return doneResult(); + } - var hiddenKeys = hiddenKeys$6; - var isObject$6 = isObject$r; - var has$2 = has$j; - var defineProperty$3 = objectDefineProperty.f; - var uid = uid$5; - var FREEZING$1 = freezing; + context.method = method; + context.arg = arg; - var METADATA = uid('meta'); - var id$1 = 0; + while (true) { + var delegate = context.delegate; - // eslint-disable-next-line es/no-object-isextensible -- safe - var isExtensible = Object.isExtensible || function () { - return true; - }; + if (delegate) { + var delegateResult = maybeInvokeDelegate(delegate, context); - var setMetadata = function (it) { - defineProperty$3(it, METADATA, { value: { - objectID: 'O' + ++id$1, // object ID - weakData: {} // weak collections IDs - } }); - }; + if (delegateResult) { + if (delegateResult === ContinueSentinel) continue; + return delegateResult; + } + } - var fastKey$1 = function (it, create) { - // return a primitive with prefix - if (!isObject$6(it)) return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it; - if (!has$2(it, METADATA)) { - // can't set metadata to uncaught frozen object - if (!isExtensible(it)) return 'F'; - // not necessary to add metadata - if (!create) return 'E'; - // add missing metadata - setMetadata(it); - // return object ID - } return it[METADATA].objectID; - }; + if (context.method === "next") { + // Setting context._sent for legacy support of Babel's + // function.sent implementation. + context.sent = context._sent = context.arg; + } else if (context.method === "throw") { + if (state === GenStateSuspendedStart) { + state = GenStateCompleted; + throw context.arg; + } - var getWeakData = function (it, create) { - if (!has$2(it, METADATA)) { - // can't set metadata to uncaught frozen object - if (!isExtensible(it)) return true; - // not necessary to add metadata - if (!create) return false; - // add missing metadata - setMetadata(it); - // return the store of weak collections IDs - } return it[METADATA].weakData; - }; + context.dispatchException(context.arg); + } else if (context.method === "return") { + context.abrupt("return", context.arg); + } - // add metadata on freeze-family methods calling - var onFreeze$1 = function (it) { - if (FREEZING$1 && meta.REQUIRED && isExtensible(it) && !has$2(it, METADATA)) setMetadata(it); - return it; - }; + state = GenStateExecuting; + var record = tryCatch(innerFn, self, context); - var meta = internalMetadata.exports = { - REQUIRED: false, - fastKey: fastKey$1, - getWeakData: getWeakData, - onFreeze: onFreeze$1 - }; + if (record.type === "normal") { + // If an exception is thrown from innerFn, we leave state === + // GenStateExecuting and loop back for another invocation. + state = context.done ? GenStateCompleted : GenStateSuspendedYield; - hiddenKeys[METADATA] = true; + if (record.arg === ContinueSentinel) { + continue; + } - var $$x = _export; - var global$4 = global$F; - var isForced$2 = isForced_1; - var redefine$3 = redefine$g.exports; - var InternalMetadataModule = internalMetadata.exports; - var iterate$1 = iterate$3; - var anInstance$1 = anInstance$7; - var isObject$5 = isObject$r; - var fails$c = fails$N; - var checkCorrectnessOfIteration$1 = checkCorrectnessOfIteration$4; - var setToStringTag = setToStringTag$a; - var inheritIfRequired$2 = inheritIfRequired$4; + return { + value: record.arg, + done: context.done + }; + } else if (record.type === "throw") { + state = GenStateCompleted; // Dispatch the exception by looping back around to the + // context.dispatchException(context.arg) call above. - var collection$2 = function (CONSTRUCTOR_NAME, wrapper, common) { - var IS_MAP = CONSTRUCTOR_NAME.indexOf('Map') !== -1; - var IS_WEAK = CONSTRUCTOR_NAME.indexOf('Weak') !== -1; - var ADDER = IS_MAP ? 'set' : 'add'; - var NativeConstructor = global$4[CONSTRUCTOR_NAME]; - var NativePrototype = NativeConstructor && NativeConstructor.prototype; - var Constructor = NativeConstructor; - var exported = {}; + context.method = "throw"; + context.arg = record.arg; + } + } + }; + } // Call delegate.iterator[context.method](context.arg) and handle the + // result, either by returning a { value, done } result from the + // delegate iterator, or by modifying context.method and context.arg, + // setting context.delegate to null, and returning the ContinueSentinel. - var fixMethod = function (KEY) { - var nativeMethod = NativePrototype[KEY]; - redefine$3(NativePrototype, KEY, - KEY == 'add' ? function add(value) { - nativeMethod.call(this, value === 0 ? 0 : value); - return this; - } : KEY == 'delete' ? function (key) { - return IS_WEAK && !isObject$5(key) ? false : nativeMethod.call(this, key === 0 ? 0 : key); - } : KEY == 'get' ? function get(key) { - return IS_WEAK && !isObject$5(key) ? undefined : nativeMethod.call(this, key === 0 ? 0 : key); - } : KEY == 'has' ? function has(key) { - return IS_WEAK && !isObject$5(key) ? false : nativeMethod.call(this, key === 0 ? 0 : key); - } : function set(key, value) { - nativeMethod.call(this, key === 0 ? 0 : key, value); - return this; - } - ); - }; - var REPLACE = isForced$2( - CONSTRUCTOR_NAME, - typeof NativeConstructor != 'function' || !(IS_WEAK || NativePrototype.forEach && !fails$c(function () { - new NativeConstructor().entries().next(); - })) - ); + function maybeInvokeDelegate(delegate, context) { + var method = delegate.iterator[context.method]; - if (REPLACE) { - // create collection constructor - Constructor = common.getConstructor(wrapper, CONSTRUCTOR_NAME, IS_MAP, ADDER); - InternalMetadataModule.REQUIRED = true; - } else if (isForced$2(CONSTRUCTOR_NAME, true)) { - var instance = new Constructor(); - // early implementations not supports chaining - var HASNT_CHAINING = instance[ADDER](IS_WEAK ? {} : -0, 1) != instance; - // V8 ~ Chromium 40- weak-collections throws on primitives, but should return false - var THROWS_ON_PRIMITIVES = fails$c(function () { instance.has(1); }); - // most early implementations doesn't supports iterables, most modern - not close it correctly - // eslint-disable-next-line no-new -- required for testing - var ACCEPT_ITERABLES = checkCorrectnessOfIteration$1(function (iterable) { new NativeConstructor(iterable); }); - // for early implementations -0 and +0 not the same - var BUGGY_ZERO = !IS_WEAK && fails$c(function () { - // V8 ~ Chromium 42- fails only with 5+ elements - var $instance = new NativeConstructor(); - var index = 5; - while (index--) $instance[ADDER](index, index); - return !$instance.has(-0); - }); + if (method === undefined$1) { + // A .throw or .return when the delegate iterator has no .throw + // method always terminates the yield* loop. + context.delegate = null; - if (!ACCEPT_ITERABLES) { - Constructor = wrapper(function (dummy, iterable) { - anInstance$1(dummy, Constructor, CONSTRUCTOR_NAME); - var that = inheritIfRequired$2(new NativeConstructor(), dummy, Constructor); - if (iterable != undefined) iterate$1(iterable, that[ADDER], { that: that, AS_ENTRIES: IS_MAP }); - return that; - }); - Constructor.prototype = NativePrototype; - NativePrototype.constructor = Constructor; - } + if (context.method === "throw") { + // Note: ["return"] must be used for ES3 parsing compatibility. + if (delegate.iterator["return"]) { + // If the delegate iterator has a return method, give it a + // chance to clean up. + context.method = "return"; + context.arg = undefined$1; + maybeInvokeDelegate(delegate, context); - if (THROWS_ON_PRIMITIVES || BUGGY_ZERO) { - fixMethod('delete'); - fixMethod('has'); - IS_MAP && fixMethod('get'); - } + if (context.method === "throw") { + // If maybeInvokeDelegate(context) changed context.method from + // "return" to "throw", let that override the TypeError below. + return ContinueSentinel; + } + } - if (BUGGY_ZERO || HASNT_CHAINING) fixMethod(ADDER); + context.method = "throw"; + context.arg = new TypeError("The iterator does not provide a 'throw' method"); + } - // weak collections should not contains .clear method - if (IS_WEAK && NativePrototype.clear) delete NativePrototype.clear; - } + return ContinueSentinel; + } - exported[CONSTRUCTOR_NAME] = Constructor; - $$x({ global: true, forced: Constructor != NativeConstructor }, exported); + var record = tryCatch(method, delegate.iterator, context.arg); - setToStringTag(Constructor, CONSTRUCTOR_NAME); + if (record.type === "throw") { + context.method = "throw"; + context.arg = record.arg; + context.delegate = null; + return ContinueSentinel; + } - if (!IS_WEAK) common.setStrong(Constructor, CONSTRUCTOR_NAME, IS_MAP); + var info = record.arg; - return Constructor; - }; + if (!info) { + context.method = "throw"; + context.arg = new TypeError("iterator result is not an object"); + context.delegate = null; + return ContinueSentinel; + } - var defineProperty$2 = objectDefineProperty.f; - var create$4 = objectCreate; - var redefineAll = redefineAll$4; - var bind$3 = functionBindContext; - var anInstance = anInstance$7; - var iterate = iterate$3; - var defineIterator = defineIterator$3; - var setSpecies$1 = setSpecies$5; - var DESCRIPTORS$5 = descriptors; - var fastKey = internalMetadata.exports.fastKey; - var InternalStateModule = internalState; + if (info.done) { + // Assign the result of the finished delegate to the temporary + // variable specified by delegate.resultName (see delegateYield). + context[delegate.resultName] = info.value; // Resume execution at the desired location (see delegateYield). - var setInternalState = InternalStateModule.set; - var internalStateGetterFor = InternalStateModule.getterFor; + context.next = delegate.nextLoc; // If context.method was "throw" but the delegate handled the + // exception, let the outer generator proceed normally. If + // context.method was "next", forget context.arg since it has been + // "consumed" by the delegate iterator. If context.method was + // "return", allow the original .return call to continue in the + // outer generator. - var collectionStrong$2 = { - getConstructor: function (wrapper, CONSTRUCTOR_NAME, IS_MAP, ADDER) { - var C = wrapper(function (that, iterable) { - anInstance(that, C, CONSTRUCTOR_NAME); - setInternalState(that, { - type: CONSTRUCTOR_NAME, - index: create$4(null), - first: undefined, - last: undefined, - size: 0 - }); - if (!DESCRIPTORS$5) that.size = 0; - if (iterable != undefined) iterate(iterable, that[ADDER], { that: that, AS_ENTRIES: IS_MAP }); - }); + if (context.method !== "return") { + context.method = "next"; + context.arg = undefined$1; + } + } else { + // Re-yield the result returned by the delegate method. + return info; + } // The delegate iterator is finished, so forget it and continue with + // the outer generator. - var getInternalState = internalStateGetterFor(CONSTRUCTOR_NAME); - var define = function (that, key, value) { - var state = getInternalState(that); - var entry = getEntry(that, key); - var previous, index; - // change existing entry - if (entry) { - entry.value = value; - // create new entry - } else { - state.last = entry = { - index: index = fastKey(key, true), - key: key, - value: value, - previous: previous = state.last, - next: undefined, - removed: false - }; - if (!state.first) state.first = entry; - if (previous) previous.next = entry; - if (DESCRIPTORS$5) state.size++; - else that.size++; - // add to index - if (index !== 'F') state.index[index] = entry; - } return that; - }; + context.delegate = null; + return ContinueSentinel; + } // Define Generator.prototype.{next,throw,return} in terms of the + // unified ._invoke helper method. - var getEntry = function (that, key) { - var state = getInternalState(that); - // fast case - var index = fastKey(key); - var entry; - if (index !== 'F') return state.index[index]; - // frozen object case - for (entry = state.first; entry; entry = entry.next) { - if (entry.key == key) return entry; - } - }; - redefineAll(C.prototype, { - // `{ Map, Set }.prototype.clear()` methods - // https://tc39.es/ecma262/#sec-map.prototype.clear - // https://tc39.es/ecma262/#sec-set.prototype.clear - clear: function clear() { - var that = this; - var state = getInternalState(that); - var data = state.index; - var entry = state.first; - while (entry) { - entry.removed = true; - if (entry.previous) entry.previous = entry.previous.next = undefined; - delete data[entry.index]; - entry = entry.next; - } - state.first = state.last = undefined; - if (DESCRIPTORS$5) state.size = 0; - else that.size = 0; - }, - // `{ Map, Set }.prototype.delete(key)` methods - // https://tc39.es/ecma262/#sec-map.prototype.delete - // https://tc39.es/ecma262/#sec-set.prototype.delete - 'delete': function (key) { - var that = this; - var state = getInternalState(that); - var entry = getEntry(that, key); - if (entry) { - var next = entry.next; - var prev = entry.previous; - delete state.index[entry.index]; - entry.removed = true; - if (prev) prev.next = next; - if (next) next.previous = prev; - if (state.first == entry) state.first = next; - if (state.last == entry) state.last = prev; - if (DESCRIPTORS$5) state.size--; - else that.size--; - } return !!entry; - }, - // `{ Map, Set }.prototype.forEach(callbackfn, thisArg = undefined)` methods - // https://tc39.es/ecma262/#sec-map.prototype.foreach - // https://tc39.es/ecma262/#sec-set.prototype.foreach - forEach: function forEach(callbackfn /* , that = undefined */) { - var state = getInternalState(this); - var boundFunction = bind$3(callbackfn, arguments.length > 1 ? arguments[1] : undefined, 3); - var entry; - while (entry = entry ? entry.next : state.first) { - boundFunction(entry.value, entry.key, this); - // revert to the last existing entry - while (entry && entry.removed) entry = entry.previous; - } - }, - // `{ Map, Set}.prototype.has(key)` methods - // https://tc39.es/ecma262/#sec-map.prototype.has - // https://tc39.es/ecma262/#sec-set.prototype.has - has: function has(key) { - return !!getEntry(this, key); - } - }); + defineIteratorMethods(Gp); + define(Gp, toStringTagSymbol, "Generator"); // A Generator should always return itself as the iterator object when the + // @@iterator function is called on it. Some browsers' implementations of the + // iterator prototype chain incorrectly implement this, causing the Generator + // object to not be returned from this call. This ensures that doesn't happen. + // See https://github.com/facebook/regenerator/issues/274 for more details. - redefineAll(C.prototype, IS_MAP ? { - // `Map.prototype.get(key)` method - // https://tc39.es/ecma262/#sec-map.prototype.get - get: function get(key) { - var entry = getEntry(this, key); - return entry && entry.value; - }, - // `Map.prototype.set(key, value)` method - // https://tc39.es/ecma262/#sec-map.prototype.set - set: function set(key, value) { - return define(this, key === 0 ? 0 : key, value); - } - } : { - // `Set.prototype.add(value)` method - // https://tc39.es/ecma262/#sec-set.prototype.add - add: function add(value) { - return define(this, value = value === 0 ? 0 : value, value); - } + define(Gp, iteratorSymbol, function () { + return this; }); - if (DESCRIPTORS$5) defineProperty$2(C.prototype, 'size', { - get: function () { - return getInternalState(this).size; - } + define(Gp, "toString", function () { + return "[object Generator]"; }); - return C; - }, - setStrong: function (C, CONSTRUCTOR_NAME, IS_MAP) { - var ITERATOR_NAME = CONSTRUCTOR_NAME + ' Iterator'; - var getInternalCollectionState = internalStateGetterFor(CONSTRUCTOR_NAME); - var getInternalIteratorState = internalStateGetterFor(ITERATOR_NAME); - // `{ Map, Set }.prototype.{ keys, values, entries, @@iterator }()` methods - // https://tc39.es/ecma262/#sec-map.prototype.entries - // https://tc39.es/ecma262/#sec-map.prototype.keys - // https://tc39.es/ecma262/#sec-map.prototype.values - // https://tc39.es/ecma262/#sec-map.prototype-@@iterator - // https://tc39.es/ecma262/#sec-set.prototype.entries - // https://tc39.es/ecma262/#sec-set.prototype.keys - // https://tc39.es/ecma262/#sec-set.prototype.values - // https://tc39.es/ecma262/#sec-set.prototype-@@iterator - defineIterator(C, CONSTRUCTOR_NAME, function (iterated, kind) { - setInternalState(this, { - type: ITERATOR_NAME, - target: iterated, - state: getInternalCollectionState(iterated), - kind: kind, - last: undefined - }); - }, function () { - var state = getInternalIteratorState(this); - var kind = state.kind; - var entry = state.last; - // revert to the last existing entry - while (entry && entry.removed) entry = entry.previous; - // get next entry - if (!state.target || !(state.last = entry = entry ? entry.next : state.state.first)) { - // or finish the iteration - state.target = undefined; - return { value: undefined, done: true }; - } - // return step by kind - if (kind == 'keys') return { value: entry.key, done: false }; - if (kind == 'values') return { value: entry.value, done: false }; - return { value: [entry.key, entry.value], done: false }; - }, IS_MAP ? 'entries' : 'values', !IS_MAP, true); - - // `{ Map, Set }.prototype[@@species]` accessors - // https://tc39.es/ecma262/#sec-get-map-@@species - // https://tc39.es/ecma262/#sec-get-set-@@species - setSpecies$1(CONSTRUCTOR_NAME); - } - }; - - var collection$1 = collection$2; - var collectionStrong$1 = collectionStrong$2; - - // `Set` constructor - // https://tc39.es/ecma262/#sec-set-objects - collection$1('Set', function (init) { - return function Set() { return init(this, arguments.length ? arguments[0] : undefined); }; - }, collectionStrong$1); - - function d3_ascending (a, b) { - return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; - } - function d3_bisector (f) { - var delta = f; - var compare = f; - - if (f.length === 1) { - delta = function delta(d, x) { - return f(d) - x; - }; + function pushTryEntry(locs) { + var entry = { + tryLoc: locs[0] + }; - compare = ascendingComparator(f); - } + if (1 in locs) { + entry.catchLoc = locs[1]; + } - function left(a, x, lo, hi) { - if (lo == null) lo = 0; - if (hi == null) hi = a.length; + if (2 in locs) { + entry.finallyLoc = locs[2]; + entry.afterLoc = locs[3]; + } - while (lo < hi) { - var mid = lo + hi >>> 1; - if (compare(a[mid], x) < 0) lo = mid + 1;else hi = mid; + this.tryEntries.push(entry); } - return lo; - } - - function right(a, x, lo, hi) { - if (lo == null) lo = 0; - if (hi == null) hi = a.length; + function resetTryEntry(entry) { + var record = entry.completion || {}; + record.type = "normal"; + delete record.arg; + entry.completion = record; + } - while (lo < hi) { - var mid = lo + hi >>> 1; - if (compare(a[mid], x) > 0) hi = mid;else lo = mid + 1; + function Context(tryLocsList) { + // The root entry object (effectively a try statement without a catch + // or a finally block) gives us a place to store values thrown from + // locations where there is no enclosing try statement. + this.tryEntries = [{ + tryLoc: "root" + }]; + tryLocsList.forEach(pushTryEntry, this); + this.reset(true); } - return lo; - } + exports.keys = function (object) { + var keys = []; - function center(a, x, lo, hi) { - if (lo == null) lo = 0; - if (hi == null) hi = a.length; - var i = left(a, x, lo, hi - 1); - return i > lo && delta(a[i - 1], x) > -delta(a[i], x) ? i - 1 : i; - } + for (var key in object) { + keys.push(key); + } - return { - left: left, - center: center, - right: right - }; - } + keys.reverse(); // Rather than returning an object with a next method, we keep + // things simple and return the next function itself. - function ascendingComparator(f) { - return function (d, x) { - return d3_ascending(f(d), x); - }; - } + return function next() { + while (keys.length) { + var key = keys.pop(); - var defineWellKnownSymbol = defineWellKnownSymbol$4; + if (key in object) { + next.value = key; + next.done = false; + return next; + } + } // To avoid creating an additional object, we just hang the .value + // and .done properties off the next function object itself. This + // also ensures that the minifier will not anonymize the function. - // `Symbol.asyncIterator` well-known symbol - // https://tc39.es/ecma262/#sec-symbol.asynciterator - defineWellKnownSymbol('asyncIterator'); - var runtime = {exports: {}}; + next.done = true; + return next; + }; + }; - (function (module) { - var runtime = function (exports) { + function values(iterable) { + if (iterable) { + var iteratorMethod = iterable[iteratorSymbol]; - var Op = Object.prototype; - var hasOwn = Op.hasOwnProperty; - var undefined$1; // More compressible than void 0. - - var $Symbol = typeof Symbol === "function" ? Symbol : {}; - var iteratorSymbol = $Symbol.iterator || "@@iterator"; - var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator"; - var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; - - function define(obj, key, value) { - Object.defineProperty(obj, key, { - value: value, - enumerable: true, - configurable: true, - writable: true - }); - return obj[key]; - } - - try { - // IE 8 has a broken Object.defineProperty that only works on DOM objects. - define({}, ""); - } catch (err) { - define = function define(obj, key, value) { - return obj[key] = value; - }; - } - - function wrap(innerFn, outerFn, self, tryLocsList) { - // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator. - var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator; - var generator = Object.create(protoGenerator.prototype); - var context = new Context(tryLocsList || []); // The ._invoke method unifies the implementations of the .next, - // .throw, and .return methods. - - generator._invoke = makeInvokeMethod(innerFn, self, context); - return generator; - } - - exports.wrap = wrap; // Try/catch helper to minimize deoptimizations. Returns a completion - // record like context.tryEntries[i].completion. This interface could - // have been (and was previously) designed to take a closure to be - // invoked without arguments, but in all the cases we care about we - // already have an existing method we want to call, so there's no need - // to create a new function object. We can even get away with assuming - // the method takes exactly one argument, since that happens to be true - // in every case, so we don't have to touch the arguments object. The - // only additional allocation required is the completion record, which - // has a stable shape and so hopefully should be cheap to allocate. - - function tryCatch(fn, obj, arg) { - try { - return { - type: "normal", - arg: fn.call(obj, arg) - }; - } catch (err) { - return { - type: "throw", - arg: err - }; - } - } - - var GenStateSuspendedStart = "suspendedStart"; - var GenStateSuspendedYield = "suspendedYield"; - var GenStateExecuting = "executing"; - var GenStateCompleted = "completed"; // Returning this object from the innerFn has the same effect as - // breaking out of the dispatch switch statement. - - var ContinueSentinel = {}; // Dummy constructor functions that we use as the .constructor and - // .constructor.prototype properties for functions that return Generator - // objects. For full spec compliance, you may wish to configure your - // minifier not to mangle the names of these two functions. - - function Generator() {} - - function GeneratorFunction() {} - - function GeneratorFunctionPrototype() {} // This is a polyfill for %IteratorPrototype% for environments that - // don't natively support it. - - - var IteratorPrototype = {}; - - IteratorPrototype[iteratorSymbol] = function () { - return this; - }; - - var getProto = Object.getPrototypeOf; - var NativeIteratorPrototype = getProto && getProto(getProto(values([]))); - - if (NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) { - // This environment has a native %IteratorPrototype%; use it instead - // of the polyfill. - IteratorPrototype = NativeIteratorPrototype; - } - - var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype); - GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype; - GeneratorFunctionPrototype.constructor = GeneratorFunction; - GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"); // Helper for defining the .next, .throw, and .return methods of the - // Iterator interface in terms of a single ._invoke method. - - function defineIteratorMethods(prototype) { - ["next", "throw", "return"].forEach(function (method) { - define(prototype, method, function (arg) { - return this._invoke(method, arg); - }); - }); - } - - exports.isGeneratorFunction = function (genFun) { - var ctor = typeof genFun === "function" && genFun.constructor; - return ctor ? ctor === GeneratorFunction || // For the native GeneratorFunction constructor, the best we can - // do is to check its .name property. - (ctor.displayName || ctor.name) === "GeneratorFunction" : false; - }; - - exports.mark = function (genFun) { - if (Object.setPrototypeOf) { - Object.setPrototypeOf(genFun, GeneratorFunctionPrototype); - } else { - genFun.__proto__ = GeneratorFunctionPrototype; - define(genFun, toStringTagSymbol, "GeneratorFunction"); - } - - genFun.prototype = Object.create(Gp); - return genFun; - }; // Within the body of any async function, `await x` is transformed to - // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test - // `hasOwn.call(value, "__await")` to determine if the yielded value is - // meant to be awaited. - - - exports.awrap = function (arg) { - return { - __await: arg - }; - }; - - function AsyncIterator(generator, PromiseImpl) { - function invoke(method, arg, resolve, reject) { - var record = tryCatch(generator[method], generator, arg); - - if (record.type === "throw") { - reject(record.arg); - } else { - var result = record.arg; - var value = result.value; - - if (value && _typeof(value) === "object" && hasOwn.call(value, "__await")) { - return PromiseImpl.resolve(value.__await).then(function (value) { - invoke("next", value, resolve, reject); - }, function (err) { - invoke("throw", err, resolve, reject); - }); - } - - return PromiseImpl.resolve(value).then(function (unwrapped) { - // When a yielded Promise is resolved, its final value becomes - // the .value of the Promise<{value,done}> result for the - // current iteration. - result.value = unwrapped; - resolve(result); - }, function (error) { - // If a rejected Promise was yielded, throw the rejection back - // into the async generator function so it can be handled there. - return invoke("throw", error, resolve, reject); - }); - } - } - - var previousPromise; - - function enqueue(method, arg) { - function callInvokeWithMethodAndArg() { - return new PromiseImpl(function (resolve, reject) { - invoke(method, arg, resolve, reject); - }); - } - - return previousPromise = // If enqueue has been called before, then we want to wait until - // all previous Promises have been resolved before calling invoke, - // so that results are always delivered in the correct order. If - // enqueue has not been called before, then it is important to - // call invoke immediately, without waiting on a callback to fire, - // so that the async generator function has the opportunity to do - // any necessary setup in a predictable way. This predictability - // is why the Promise constructor synchronously invokes its - // executor callback, and why async functions synchronously - // execute code before the first await. Since we implement simple - // async functions in terms of async generators, it is especially - // important to get this right, even though it requires care. - previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, // Avoid propagating failures to Promises returned by later - // invocations of the iterator. - callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); - } // Define the unified helper method that is used to implement .next, - // .throw, and .return (see defineIteratorMethods). - - - this._invoke = enqueue; - } - - defineIteratorMethods(AsyncIterator.prototype); - - AsyncIterator.prototype[asyncIteratorSymbol] = function () { - return this; - }; - - exports.AsyncIterator = AsyncIterator; // Note that simple async functions are implemented on top of - // AsyncIterator objects; they just return a Promise for the value of - // the final result produced by the iterator. - - exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) { - if (PromiseImpl === void 0) PromiseImpl = Promise; - var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl); - return exports.isGeneratorFunction(outerFn) ? iter // If outerFn is a generator, return the full iterator. - : iter.next().then(function (result) { - return result.done ? result.value : iter.next(); - }); - }; - - function makeInvokeMethod(innerFn, self, context) { - var state = GenStateSuspendedStart; - return function invoke(method, arg) { - if (state === GenStateExecuting) { - throw new Error("Generator is already running"); - } - - if (state === GenStateCompleted) { - if (method === "throw") { - throw arg; - } // Be forgiving, per 25.3.3.3.3 of the spec: - // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume - - - return doneResult(); - } - - context.method = method; - context.arg = arg; - - while (true) { - var delegate = context.delegate; - - if (delegate) { - var delegateResult = maybeInvokeDelegate(delegate, context); - - if (delegateResult) { - if (delegateResult === ContinueSentinel) continue; - return delegateResult; - } - } - - if (context.method === "next") { - // Setting context._sent for legacy support of Babel's - // function.sent implementation. - context.sent = context._sent = context.arg; - } else if (context.method === "throw") { - if (state === GenStateSuspendedStart) { - state = GenStateCompleted; - throw context.arg; - } - - context.dispatchException(context.arg); - } else if (context.method === "return") { - context.abrupt("return", context.arg); - } - - state = GenStateExecuting; - var record = tryCatch(innerFn, self, context); - - if (record.type === "normal") { - // If an exception is thrown from innerFn, we leave state === - // GenStateExecuting and loop back for another invocation. - state = context.done ? GenStateCompleted : GenStateSuspendedYield; - - if (record.arg === ContinueSentinel) { - continue; - } - - return { - value: record.arg, - done: context.done - }; - } else if (record.type === "throw") { - state = GenStateCompleted; // Dispatch the exception by looping back around to the - // context.dispatchException(context.arg) call above. - - context.method = "throw"; - context.arg = record.arg; - } - } - }; - } // Call delegate.iterator[context.method](context.arg) and handle the - // result, either by returning a { value, done } result from the - // delegate iterator, or by modifying context.method and context.arg, - // setting context.delegate to null, and returning the ContinueSentinel. - - - function maybeInvokeDelegate(delegate, context) { - var method = delegate.iterator[context.method]; - - if (method === undefined$1) { - // A .throw or .return when the delegate iterator has no .throw - // method always terminates the yield* loop. - context.delegate = null; - - if (context.method === "throw") { - // Note: ["return"] must be used for ES3 parsing compatibility. - if (delegate.iterator["return"]) { - // If the delegate iterator has a return method, give it a - // chance to clean up. - context.method = "return"; - context.arg = undefined$1; - maybeInvokeDelegate(delegate, context); - - if (context.method === "throw") { - // If maybeInvokeDelegate(context) changed context.method from - // "return" to "throw", let that override the TypeError below. - return ContinueSentinel; - } - } - - context.method = "throw"; - context.arg = new TypeError("The iterator does not provide a 'throw' method"); - } - - return ContinueSentinel; - } - - var record = tryCatch(method, delegate.iterator, context.arg); - - if (record.type === "throw") { - context.method = "throw"; - context.arg = record.arg; - context.delegate = null; - return ContinueSentinel; - } - - var info = record.arg; - - if (!info) { - context.method = "throw"; - context.arg = new TypeError("iterator result is not an object"); - context.delegate = null; - return ContinueSentinel; - } - - if (info.done) { - // Assign the result of the finished delegate to the temporary - // variable specified by delegate.resultName (see delegateYield). - context[delegate.resultName] = info.value; // Resume execution at the desired location (see delegateYield). - - context.next = delegate.nextLoc; // If context.method was "throw" but the delegate handled the - // exception, let the outer generator proceed normally. If - // context.method was "next", forget context.arg since it has been - // "consumed" by the delegate iterator. If context.method was - // "return", allow the original .return call to continue in the - // outer generator. - - if (context.method !== "return") { - context.method = "next"; - context.arg = undefined$1; - } - } else { - // Re-yield the result returned by the delegate method. - return info; - } // The delegate iterator is finished, so forget it and continue with - // the outer generator. - - - context.delegate = null; - return ContinueSentinel; - } // Define Generator.prototype.{next,throw,return} in terms of the - // unified ._invoke helper method. - - - defineIteratorMethods(Gp); - define(Gp, toStringTagSymbol, "Generator"); // A Generator should always return itself as the iterator object when the - // @@iterator function is called on it. Some browsers' implementations of the - // iterator prototype chain incorrectly implement this, causing the Generator - // object to not be returned from this call. This ensures that doesn't happen. - // See https://github.com/facebook/regenerator/issues/274 for more details. - - Gp[iteratorSymbol] = function () { - return this; - }; - - Gp.toString = function () { - return "[object Generator]"; - }; - - function pushTryEntry(locs) { - var entry = { - tryLoc: locs[0] - }; - - if (1 in locs) { - entry.catchLoc = locs[1]; - } - - if (2 in locs) { - entry.finallyLoc = locs[2]; - entry.afterLoc = locs[3]; - } - - this.tryEntries.push(entry); - } - - function resetTryEntry(entry) { - var record = entry.completion || {}; - record.type = "normal"; - delete record.arg; - entry.completion = record; - } - - function Context(tryLocsList) { - // The root entry object (effectively a try statement without a catch - // or a finally block) gives us a place to store values thrown from - // locations where there is no enclosing try statement. - this.tryEntries = [{ - tryLoc: "root" - }]; - tryLocsList.forEach(pushTryEntry, this); - this.reset(true); - } - - exports.keys = function (object) { - var keys = []; - - for (var key in object) { - keys.push(key); - } - - keys.reverse(); // Rather than returning an object with a next method, we keep - // things simple and return the next function itself. - - return function next() { - while (keys.length) { - var key = keys.pop(); - - if (key in object) { - next.value = key; - next.done = false; - return next; - } - } // To avoid creating an additional object, we just hang the .value - // and .done properties off the next function object itself. This - // also ensures that the minifier will not anonymize the function. - - - next.done = true; - return next; - }; - }; - - function values(iterable) { - if (iterable) { - var iteratorMethod = iterable[iteratorSymbol]; - - if (iteratorMethod) { - return iteratorMethod.call(iterable); - } + if (iteratorMethod) { + return iteratorMethod.call(iterable); + } if (typeof iterable.next === "function") { return iterable; @@ -10147,14 +9626,19 @@ } catch (accidentalStrictMode) { // This module should not be running in strict mode, so the above // assignment should always work unless something is misconfigured. Just - // in case runtime.js accidentally runs in strict mode, we can escape + // in case runtime.js accidentally runs in strict mode, in modern engines + // we can explicitly access globalThis. In older engines we can escape // strict mode using a global Function call. This could conceivably fail // if a Content Security Policy forbids using Function, but in that case // the proper solution is to fix the accidental strict mode problem. If // you've misconfigured your bundler to force strict mode and applied a // CSP to forbid Function, and you're not willing to fix either of those // problems, please detail your unique predicament in a GitHub issue. - Function("r", "regeneratorRuntime = r")(runtime); + if ((typeof globalThis === "undefined" ? "undefined" : _typeof(globalThis)) === "object") { + globalThis.regeneratorRuntime = runtime; + } else { + Function("r", "regeneratorRuntime = r")(runtime); + } } })(runtime); @@ -10277,7 +9761,66 @@ var bisectRight = ascendingBisect.right; d3_bisector(number$1).center; - var $$w = _export; + var anObject$2 = anObject$n; + var iteratorClose = iteratorClose$2; + + // call something on iterator step with safe closing on error + var callWithSafeIterationClosing$1 = function (iterator, fn, value, ENTRIES) { + try { + return ENTRIES ? fn(anObject$2(value)[0], value[1]) : fn(value); + } catch (error) { + iteratorClose(iterator, 'throw', error); + } + }; + + var global$c = global$1m; + var bind$5 = functionBindContext; + var call$4 = functionCall; + var toObject$3 = toObject$j; + var callWithSafeIterationClosing = callWithSafeIterationClosing$1; + var isArrayIteratorMethod = isArrayIteratorMethod$3; + var isConstructor = isConstructor$4; + var lengthOfArrayLike$3 = lengthOfArrayLike$g; + var createProperty = createProperty$4; + var getIterator = getIterator$4; + var getIteratorMethod = getIteratorMethod$5; + + var Array$1 = global$c.Array; + + // `Array.from` method implementation + // https://tc39.es/ecma262/#sec-array.from + var arrayFrom$1 = function from(arrayLike /* , mapfn = undefined, thisArg = undefined */) { + var O = toObject$3(arrayLike); + var IS_CONSTRUCTOR = isConstructor(this); + var argumentsLength = arguments.length; + var mapfn = argumentsLength > 1 ? arguments[1] : undefined; + var mapping = mapfn !== undefined; + if (mapping) mapfn = bind$5(mapfn, argumentsLength > 2 ? arguments[2] : undefined); + var iteratorMethod = getIteratorMethod(O); + var index = 0; + var length, result, step, iterator, next, value; + // if the target is not iterable or it's an array with the default iterator - use a simple case + if (iteratorMethod && !(this == Array$1 && isArrayIteratorMethod(iteratorMethod))) { + iterator = getIterator(O, iteratorMethod); + next = iterator.next; + result = IS_CONSTRUCTOR ? new this() : []; + for (;!(step = call$4(next, iterator)).done; index++) { + value = mapping ? callWithSafeIterationClosing(iterator, mapfn, [step.value, index], true) : step.value; + createProperty(result, index, value); + } + } else { + length = lengthOfArrayLike$3(O); + result = IS_CONSTRUCTOR ? new this(length) : Array$1(length); + for (;length > index; index++) { + value = mapping ? mapfn(O[index], index) : O[index]; + createProperty(result, index, value); + } + } + result.length = index; + return result; + }; + + var $$D = _export; var from = arrayFrom$1; var checkCorrectnessOfIteration = checkCorrectnessOfIteration$4; @@ -10288,32 +9831,32 @@ // `Array.from` method // https://tc39.es/ecma262/#sec-array.from - $$w({ target: 'Array', stat: true, forced: INCORRECT_ITERATION }, { + $$D({ target: 'Array', stat: true, forced: INCORRECT_ITERATION }, { from: from }); - var $$v = _export; + var $$C = _export; var fill = arrayFill$1; - var addToUnscopables$3 = addToUnscopables$5; + var addToUnscopables$4 = addToUnscopables$6; // `Array.prototype.fill` method // https://tc39.es/ecma262/#sec-array.prototype.fill - $$v({ target: 'Array', proto: true }, { + $$C({ target: 'Array', proto: true }, { fill: fill }); // https://tc39.es/ecma262/#sec-array.prototype-@@unscopables - addToUnscopables$3('fill'); + addToUnscopables$4('fill'); - var $$u = _export; + var $$B = _export; var $some = arrayIteration.some; - var arrayMethodIsStrict$3 = arrayMethodIsStrict$8; + var arrayMethodIsStrict$4 = arrayMethodIsStrict$9; - var STRICT_METHOD$3 = arrayMethodIsStrict$3('some'); + var STRICT_METHOD$4 = arrayMethodIsStrict$4('some'); // `Array.prototype.some` method // https://tc39.es/ecma262/#sec-array.prototype.some - $$u({ target: 'Array', proto: true, forced: !STRICT_METHOD$3 }, { + $$B({ target: 'Array', proto: true, forced: !STRICT_METHOD$4 }, { some: function some(callbackfn /* , thisArg */) { return $some(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined); } @@ -10403,14 +9946,14 @@ return Adder; }(); - var $$t = _export; - var DESCRIPTORS$4 = descriptors; - var defineProperties = objectDefineProperties; + var $$A = _export; + var DESCRIPTORS$5 = descriptors; + var defineProperties$1 = objectDefineProperties; // `Object.defineProperties` method // https://tc39.es/ecma262/#sec-object.defineproperties - $$t({ target: 'Object', stat: true, forced: !DESCRIPTORS$4, sham: !DESCRIPTORS$4 }, { - defineProperties: defineProperties + $$A({ target: 'Object', stat: true, forced: !DESCRIPTORS$5, sham: !DESCRIPTORS$5 }, { + defineProperties: defineProperties$1 }); var collection = collection$2; @@ -10422,20 +9965,23 @@ return function Map() { return init(this, arguments.length ? arguments[0] : undefined); }; }, collectionStrong); - var $$s = _export; - var aFunction = aFunction$9; - var toObject$1 = toObject$i; - var toLength$4 = toLength$q; - var fails$b = fails$N; - var internalSort = arraySort; - var arrayMethodIsStrict$2 = arrayMethodIsStrict$8; + var $$z = _export; + var uncurryThis$f = functionUncurryThis; + var aCallable$1 = aCallable$a; + var toObject$2 = toObject$j; + var lengthOfArrayLike$2 = lengthOfArrayLike$g; + var toString$a = toString$k; + var fails$b = fails$S; + var internalSort = arraySort$1; + var arrayMethodIsStrict$3 = arrayMethodIsStrict$9; var FF = engineFfVersion; var IE_OR_EDGE = engineIsIeOrEdge; var V8 = engineV8Version; var WEBKIT = engineWebkitVersion; var test = []; - var nativeSort = test.sort; + var un$Sort = uncurryThis$f(test.sort); + var push$3 = uncurryThis$f(test.push); // IE8- var FAILS_ON_UNDEFINED = fails$b(function () { @@ -10446,7 +9992,7 @@ test.sort(null); }); // Old WebKit - var STRICT_METHOD$2 = arrayMethodIsStrict$2('sort'); + var STRICT_METHOD$3 = arrayMethodIsStrict$3('sort'); var STABLE_SORT = !fails$b(function () { // feature detection can be too slow, so check engines versions @@ -10483,36 +10029,37 @@ return result !== 'DGBEFHACIJK'; }); - var FORCED$5 = FAILS_ON_UNDEFINED || !FAILS_ON_NULL || !STRICT_METHOD$2 || !STABLE_SORT; + var FORCED$7 = FAILS_ON_UNDEFINED || !FAILS_ON_NULL || !STRICT_METHOD$3 || !STABLE_SORT; var getSortCompare = function (comparefn) { return function (x, y) { if (y === undefined) return -1; if (x === undefined) return 1; if (comparefn !== undefined) return +comparefn(x, y) || 0; - return String(x) > String(y) ? 1 : -1; + return toString$a(x) > toString$a(y) ? 1 : -1; }; }; // `Array.prototype.sort` method // https://tc39.es/ecma262/#sec-array.prototype.sort - $$s({ target: 'Array', proto: true, forced: FORCED$5 }, { + $$z({ target: 'Array', proto: true, forced: FORCED$7 }, { sort: function sort(comparefn) { - if (comparefn !== undefined) aFunction(comparefn); + if (comparefn !== undefined) aCallable$1(comparefn); - var array = toObject$1(this); + var array = toObject$2(this); - if (STABLE_SORT) return comparefn === undefined ? nativeSort.call(array) : nativeSort.call(array, comparefn); + if (STABLE_SORT) return comparefn === undefined ? un$Sort(array) : un$Sort(array, comparefn); var items = []; - var arrayLength = toLength$4(array.length); + var arrayLength = lengthOfArrayLike$2(array); var itemsLength, index; for (index = 0; index < arrayLength; index++) { - if (index in array) items.push(array[index]); + if (index in array) push$3(items, array[index]); } - items = internalSort(items, getSortCompare(comparefn)); + internalSort(items, getSortCompare(comparefn)); + itemsLength = items.length; index = 0; @@ -10812,7 +10359,7 @@ return x === y ? x !== 0 || 1 / x === 1 / y : x != x && y != y; }; - var $$r = _export; + var $$y = _export; // eslint-disable-next-line es/no-math-hypot -- required for testing var $hypot = Math.hypot; @@ -10825,7 +10372,7 @@ // `Math.hypot` method // https://tc39.es/ecma262/#sec-math.hypot - $$r({ target: 'Math', stat: true, forced: BUGGY }, { + $$y({ target: 'Math', stat: true, forced: BUGGY }, { // eslint-disable-next-line no-unused-vars -- required for `.length` hypot: function hypot(value1, value2) { var sum = 0; @@ -10856,12 +10403,12 @@ return (x = +x) == 0 || x != x ? x : x < 0 ? -1 : 1; }; - var $$q = _export; + var $$x = _export; var sign$1 = mathSign; // `Math.sign` method // https://tc39.es/ecma262/#sec-math.sign - $$q({ target: 'Math', stat: true }, { + $$x({ target: 'Math', stat: true }, { sign: sign$1 }); @@ -13325,36 +12872,37 @@ } }); - var $$p = _export; + var $$w = _export; var $every = arrayIteration.every; - var arrayMethodIsStrict$1 = arrayMethodIsStrict$8; + var arrayMethodIsStrict$2 = arrayMethodIsStrict$9; - var STRICT_METHOD$1 = arrayMethodIsStrict$1('every'); + var STRICT_METHOD$2 = arrayMethodIsStrict$2('every'); // `Array.prototype.every` method // https://tc39.es/ecma262/#sec-array.prototype.every - $$p({ target: 'Array', proto: true, forced: !STRICT_METHOD$1 }, { + $$w({ target: 'Array', proto: true, forced: !STRICT_METHOD$2 }, { every: function every(callbackfn /* , thisArg */) { return $every(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined); } }); - var $$o = _export; + var $$v = _export; var $reduce = arrayReduce.left; - var arrayMethodIsStrict = arrayMethodIsStrict$8; - var CHROME_VERSION = engineV8Version; - var IS_NODE = engineIsNode; + var arrayMethodIsStrict$1 = arrayMethodIsStrict$9; + var CHROME_VERSION$1 = engineV8Version; + var IS_NODE$1 = engineIsNode; - var STRICT_METHOD = arrayMethodIsStrict('reduce'); + var STRICT_METHOD$1 = arrayMethodIsStrict$1('reduce'); // Chrome 80-82 has a critical bug // https://bugs.chromium.org/p/chromium/issues/detail?id=1049982 - var CHROME_BUG = !IS_NODE && CHROME_VERSION > 79 && CHROME_VERSION < 83; + var CHROME_BUG$1 = !IS_NODE$1 && CHROME_VERSION$1 > 79 && CHROME_VERSION$1 < 83; // `Array.prototype.reduce` method // https://tc39.es/ecma262/#sec-array.prototype.reduce - $$o({ target: 'Array', proto: true, forced: !STRICT_METHOD || CHROME_BUG }, { + $$v({ target: 'Array', proto: true, forced: !STRICT_METHOD$1 || CHROME_BUG$1 }, { reduce: function reduce(callbackfn /* , initialValue */) { - return $reduce(this, callbackfn, arguments.length, arguments.length > 1 ? arguments[1] : undefined); + var length = arguments.length; + return $reduce(this, callbackfn, length, length > 1 ? arguments[1] : undefined); } }); @@ -14112,9 +13660,9 @@ return new Selection$1(subgroups, parents); } - var $$n = _export; + var $$u = _export; var $find = arrayIteration.find; - var addToUnscopables$2 = addToUnscopables$5; + var addToUnscopables$3 = addToUnscopables$6; var FIND = 'find'; var SKIPS_HOLES$1 = true; @@ -14124,14 +13672,14 @@ // `Array.prototype.find` method // https://tc39.es/ecma262/#sec-array.prototype.find - $$n({ target: 'Array', proto: true, forced: SKIPS_HOLES$1 }, { + $$u({ target: 'Array', proto: true, forced: SKIPS_HOLES$1 }, { find: function find(callbackfn /* , that = undefined */) { return $find(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined); } }); // https://tc39.es/ecma262/#sec-array.prototype-@@unscopables - addToUnscopables$2(FIND); + addToUnscopables$3(FIND); function matcher (selector) { return function () { @@ -14514,8 +14062,8 @@ } function defaultView (node) { - return node.ownerDocument && node.ownerDocument.defaultView || // node is a Node - node.document && node // node is a Window + return node.ownerDocument && node.ownerDocument.defaultView // node is a Node + || node.document && node // node is a Window || node.defaultView; // node is a Document } @@ -15343,28 +14891,38 @@ return drag; } - var DESCRIPTORS$3 = descriptors; - var global$3 = global$F; + var DESCRIPTORS$4 = descriptors; + var global$b = global$1m; + var uncurryThis$e = functionUncurryThis; var isForced$1 = isForced_1; var inheritIfRequired$1 = inheritIfRequired$4; - var createNonEnumerableProperty = createNonEnumerableProperty$e; + var createNonEnumerableProperty = createNonEnumerableProperty$b; var defineProperty$1 = objectDefineProperty.f; var getOwnPropertyNames$1 = objectGetOwnPropertyNames.f; + var isPrototypeOf$1 = objectIsPrototypeOf; var isRegExp$1 = isRegexp; - var getFlags = regexpFlags$1; + var toString$9 = toString$k; + var regExpFlags$1 = regexpFlags$1; var stickyHelpers = regexpStickyHelpers; - var redefine$2 = redefine$g.exports; - var fails$a = fails$N; - var has$1 = has$j; + var redefine$3 = redefine$h.exports; + var fails$a = fails$S; + var hasOwn$2 = hasOwnProperty_1; var enforceInternalState = internalState.enforce; var setSpecies = setSpecies$5; - var wellKnownSymbol$1 = wellKnownSymbol$s; + var wellKnownSymbol$1 = wellKnownSymbol$t; var UNSUPPORTED_DOT_ALL = regexpUnsupportedDotAll; var UNSUPPORTED_NCG = regexpUnsupportedNcg; var MATCH$1 = wellKnownSymbol$1('match'); - var NativeRegExp = global$3.RegExp; - var RegExpPrototype = NativeRegExp.prototype; + var NativeRegExp = global$b.RegExp; + var RegExpPrototype$1 = NativeRegExp.prototype; + var SyntaxError$1 = global$b.SyntaxError; + var getFlags = uncurryThis$e(regExpFlags$1); + var exec$2 = uncurryThis$e(RegExpPrototype$1.exec); + var charAt$1 = uncurryThis$e(''.charAt); + var replace$3 = uncurryThis$e(''.replace); + var stringIndexOf$1 = uncurryThis$e(''.indexOf); + var stringSlice$4 = uncurryThis$e(''.slice); // TODO: Use only propper RegExpIdentifierName var IS_NCG = /^\?<[^\s\d!#%&*+<=>@^][^\s!#%&*+<=>@^]*>/; var re1 = /a/g; @@ -15375,7 +14933,7 @@ var UNSUPPORTED_Y = stickyHelpers.UNSUPPORTED_Y; - var BASE_FORCED = DESCRIPTORS$3 && + var BASE_FORCED = DESCRIPTORS$4 && (!CORRECT_NEW || UNSUPPORTED_Y || UNSUPPORTED_DOT_ALL || UNSUPPORTED_NCG || fails$a(function () { re2[MATCH$1] = false; // RegExp constructor can alter flags and IsRegExp works correct with @@match @@ -15389,9 +14947,9 @@ var brackets = false; var chr; for (; index <= length; index++) { - chr = string.charAt(index); + chr = charAt$1(string, index); if (chr === '\\') { - result += chr + string.charAt(++index); + result += chr + charAt$1(string, ++index); continue; } if (!brackets && chr === '.') { @@ -15418,9 +14976,9 @@ var groupname = ''; var chr; for (; index <= length; index++) { - chr = string.charAt(index); + chr = charAt$1(string, index); if (chr === '\\') { - chr = chr + string.charAt(++index); + chr = chr + charAt$1(string, ++index); } else if (chr === ']') { brackets = false; } else if (!brackets) switch (true) { @@ -15428,7 +14986,7 @@ brackets = true; break; case chr === '(': - if (IS_NCG.test(string.slice(index + 1))) { + if (exec$2(IS_NCG, stringSlice$4(string, index + 1))) { index += 2; ncg = true; } @@ -15436,11 +14994,11 @@ groupid++; continue; case chr === '>' && ncg: - if (groupname === '' || has$1(names, groupname)) { - throw new SyntaxError('Invalid capture group name'); + if (groupname === '' || hasOwn$2(names, groupname)) { + throw new SyntaxError$1('Invalid capture group name'); } names[groupname] = true; - named.push([groupname, groupid]); + named[named.length] = [groupname, groupid]; ncg = false; groupname = ''; continue; @@ -15454,37 +15012,36 @@ // https://tc39.es/ecma262/#sec-regexp-constructor if (isForced$1('RegExp', BASE_FORCED)) { var RegExpWrapper = function RegExp(pattern, flags) { - var thisIsRegExp = this instanceof RegExpWrapper; + var thisIsRegExp = isPrototypeOf$1(RegExpPrototype$1, this); var patternIsRegExp = isRegExp$1(pattern); var flagsAreUndefined = flags === undefined; var groups = []; - var rawPattern, rawFlags, dotAll, sticky, handled, result, state; + var rawPattern = pattern; + var rawFlags, dotAll, sticky, handled, result, state; - if (!thisIsRegExp && patternIsRegExp && pattern.constructor === RegExpWrapper && flagsAreUndefined) { + if (!thisIsRegExp && patternIsRegExp && flagsAreUndefined && pattern.constructor === RegExpWrapper) { return pattern; } - if (CORRECT_NEW) { - if (patternIsRegExp && !flagsAreUndefined) pattern = pattern.source; - } else if (pattern instanceof RegExpWrapper) { - if (flagsAreUndefined) flags = getFlags.call(pattern); + if (patternIsRegExp || isPrototypeOf$1(RegExpPrototype$1, pattern)) { pattern = pattern.source; + if (flagsAreUndefined) flags = 'flags' in rawPattern ? rawPattern.flags : getFlags(rawPattern); } - pattern = pattern === undefined ? '' : String(pattern); - flags = flags === undefined ? '' : String(flags); + pattern = pattern === undefined ? '' : toString$9(pattern); + flags = flags === undefined ? '' : toString$9(flags); rawPattern = pattern; if (UNSUPPORTED_DOT_ALL && 'dotAll' in re1) { - dotAll = !!flags && flags.indexOf('s') > -1; - if (dotAll) flags = flags.replace(/s/g, ''); + dotAll = !!flags && stringIndexOf$1(flags, 's') > -1; + if (dotAll) flags = replace$3(flags, /s/g, ''); } rawFlags = flags; if (UNSUPPORTED_Y && 'sticky' in re1) { - sticky = !!flags && flags.indexOf('y') > -1; - if (sticky) flags = flags.replace(/y/g, ''); + sticky = !!flags && stringIndexOf$1(flags, 'y') > -1; + if (sticky) flags = replace$3(flags, /y/g, ''); } if (UNSUPPORTED_NCG) { @@ -15493,11 +15050,7 @@ groups = handled[1]; } - result = inheritIfRequired$1( - CORRECT_NEW ? new NativeRegExp(pattern, flags) : NativeRegExp(pattern, flags), - thisIsRegExp ? this : RegExpPrototype, - RegExpWrapper - ); + result = inheritIfRequired$1(NativeRegExp(pattern, flags), thisIsRegExp ? this : RegExpPrototype$1, RegExpWrapper); if (dotAll || sticky || groups.length) { state = enforceInternalState(result); @@ -15529,9 +15082,9 @@ proxy(keys$1[index$1++]); } - RegExpPrototype.constructor = RegExpWrapper; - RegExpWrapper.prototype = RegExpPrototype; - redefine$2(global$3, 'RegExp', RegExpWrapper); + RegExpPrototype$1.constructor = RegExpWrapper; + RegExpWrapper.prototype = RegExpPrototype$1; + redefine$3(global$b, 'RegExp', RegExpWrapper); } // https://tc39.es/ecma262/#sec-get-regexp-@@species @@ -16275,20 +15828,20 @@ }; } // General case. else { - var d1 = Math.sqrt(d2), - b0 = (w1 * w1 - w0 * w0 + rho4 * d2) / (2 * w0 * rho2 * d1), - b1 = (w1 * w1 - w0 * w0 - rho4 * d2) / (2 * w1 * rho2 * d1), - r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0), - r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1); - S = (r1 - r0) / rho; - - i = function i(t) { - var s = t * S, - coshr0 = cosh(r0), - u = w0 / (rho2 * d1) * (coshr0 * tanh(rho * s + r0) - sinh(r0)); - return [ux0 + u * dx, uy0 + u * dy, w0 * coshr0 / cosh(rho * s + r0)]; - }; - } + var d1 = Math.sqrt(d2), + b0 = (w1 * w1 - w0 * w0 + rho4 * d2) / (2 * w0 * rho2 * d1), + b1 = (w1 * w1 - w0 * w0 - rho4 * d2) / (2 * w1 * rho2 * d1), + r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0), + r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1); + S = (r1 - r0) / rho; + + i = function i(t) { + var s = t * S, + coshr0 = cosh(r0), + u = w0 / (rho2 * d1) * (coshr0 * tanh(rho * s + r0) - sinh(r0)); + return [ux0 + u * dx, uy0 + u * dy, w0 * coshr0 / cosh(rho * s + r0)]; + }; + } i.duration = S * 1000 * rho / Math.SQRT2; return i; @@ -16315,13 +15868,13 @@ return samples; } - var $$m = _export; - var bind$2 = functionBind; + var $$t = _export; + var bind$4 = functionBind; // `Function.prototype.bind` method // https://tc39.es/ecma262/#sec-function.prototype.bind - $$m({ target: 'Function', proto: true }, { - bind: bind$2 + $$t({ target: 'Function', proto: true }, { + bind: bind$4 }); var frame = 0, @@ -16472,7 +16025,7 @@ function schedule (node, name, id, index, group, timing) { var schedules = node.__transition; if (!schedules) node.__transition = {};else if (id in schedules) return; - create$3(node, id, { + create$2(node, id, { name: name, index: index, // For context during callback. @@ -16504,7 +16057,7 @@ return schedule; } - function create$3(node, id, self) { + function create$2(node, id, self) { var schedules = node.__transition, tween; // Initialize the self timer when the transition is created. // Note the actual delay is not known until the first callback! @@ -16539,11 +16092,11 @@ delete schedules[i]; } // Cancel any pre-empted transitions. else if (+i < id) { - o.state = ENDED; - o.timer.stop(); - o.on.call("cancel", node, node.__data__, o.index, o.group); - delete schedules[i]; - } + o.state = ENDED; + o.timer.stop(); + o.on.call("cancel", node, node.__data__, o.index, o.group); + delete schedules[i]; + } } // Defer the first tick to end of the current frame; see d3/d3#1576. // Note the transition may be canceled after start and before the first tick! // Note this must be scheduled before the start event; see d3/d3-transition#16! @@ -17534,10 +17087,10 @@ return function (t) { if (t === 1) t = b; // Avoid rounding error on end. else { - var l = i(t), - k = w / l[2]; - t = new Transform(k, p[0] - l[0] * k, p[1] - l[1] * k); - } + var l = i(t), + k = w / l[2]; + t = new Transform(k, p[0] - l[0] * k, p[1] - l[1] * k); + } g.zoom(null, t); }; }); @@ -17617,11 +17170,11 @@ clearTimeout(g.wheel); } // If this wheel event won’t trigger a transform change, ignore it. else if (t.k === k) return; // Otherwise, capture the mouse point and location at the start. - else { - g.mouse = [p, t.invert(p)]; - interrupt(this); - g.start(); - } + else { + g.mouse = [p, t.invert(p)]; + interrupt(this); + g.start(); + } noevent(event); g.wheel = setTimeout(wheelidled, wheelDelay); @@ -17994,10 +17547,57 @@ return score; } - var $$l = _export; + var call$3 = functionCall; + var fixRegExpWellKnownSymbolLogic$1 = fixRegexpWellKnownSymbolLogic; + var anObject$1 = anObject$n; + var toLength$3 = toLength$c; + var toString$8 = toString$k; + var requireObjectCoercible$7 = requireObjectCoercible$e; + var getMethod$1 = getMethod$7; + var advanceStringIndex = advanceStringIndex$3; + var regExpExec$1 = regexpExecAbstract; + + // @@match logic + fixRegExpWellKnownSymbolLogic$1('match', function (MATCH, nativeMatch, maybeCallNative) { + return [ + // `String.prototype.match` method + // https://tc39.es/ecma262/#sec-string.prototype.match + function match(regexp) { + var O = requireObjectCoercible$7(this); + var matcher = regexp == undefined ? undefined : getMethod$1(regexp, MATCH); + return matcher ? call$3(matcher, regexp, O) : new RegExp(regexp)[MATCH](toString$8(O)); + }, + // `RegExp.prototype[@@match]` method + // https://tc39.es/ecma262/#sec-regexp.prototype-@@match + function (string) { + var rx = anObject$1(this); + var S = toString$8(string); + var res = maybeCallNative(nativeMatch, rx, S); + + if (res.done) return res.value; + + if (!rx.global) return regExpExec$1(rx, S); + + var fullUnicode = rx.unicode; + rx.lastIndex = 0; + var A = []; + var n = 0; + var result; + while ((result = regExpExec$1(rx, S)) !== null) { + var matchStr = toString$8(result[0]); + A[n] = matchStr; + if (matchStr === '') rx.lastIndex = advanceStringIndex(S, toLength$3(rx.lastIndex), fullUnicode); + n++; + } + return n === 0 ? null : A; + } + ]; + }); + + var $$s = _export; var FREEZING = freezing; - var fails$9 = fails$N; - var isObject$4 = isObject$r; + var fails$9 = fails$S; + var isObject$4 = isObject$s; var onFreeze = internalMetadata.exports.onFreeze; // eslint-disable-next-line es/no-object-freeze -- safe @@ -18006,7 +17606,7 @@ // `Object.freeze` method // https://tc39.es/ecma262/#sec-object.freeze - $$l({ target: 'Object', stat: true, forced: FAILS_ON_PRIMITIVES, sham: !FREEZING }, { + $$s({ target: 'Object', stat: true, forced: FAILS_ON_PRIMITIVES, sham: !FREEZING }, { freeze: function freeze(it) { return $freeze && isObject$4(it) ? $freeze(onFreeze(it)) : it; } @@ -18156,49 +17756,65 @@ }, []); } - var DESCRIPTORS$2 = descriptors; - var global$2 = global$F; + var uncurryThis$d = functionUncurryThis; + + // `thisNumberValue` abstract operation + // https://tc39.es/ecma262/#sec-thisnumbervalue + var thisNumberValue$3 = uncurryThis$d(1.0.valueOf); + + var DESCRIPTORS$3 = descriptors; + var global$a = global$1m; + var uncurryThis$c = functionUncurryThis; var isForced = isForced_1; - var redefine$1 = redefine$g.exports; - var has = has$j; - var classof$1 = classofRaw$1; + var redefine$2 = redefine$h.exports; + var hasOwn$1 = hasOwnProperty_1; var inheritIfRequired = inheritIfRequired$4; - var toPrimitive$1 = toPrimitive$7; - var fails$8 = fails$N; - var create$2 = objectCreate; + var isPrototypeOf = objectIsPrototypeOf; + var isSymbol$1 = isSymbol$6; + var toPrimitive$1 = toPrimitive$3; + var fails$8 = fails$S; var getOwnPropertyNames = objectGetOwnPropertyNames.f; var getOwnPropertyDescriptor$2 = objectGetOwnPropertyDescriptor.f; var defineProperty = objectDefineProperty.f; + var thisNumberValue$2 = thisNumberValue$3; var trim$2 = stringTrim.trim; var NUMBER = 'Number'; - var NativeNumber = global$2[NUMBER]; + var NativeNumber = global$a[NUMBER]; var NumberPrototype = NativeNumber.prototype; - - // Opera ~12 has broken Object#toString - var BROKEN_CLASSOF = classof$1(create$2(NumberPrototype)) == NUMBER; + var TypeError$4 = global$a.TypeError; + var arraySlice$1 = uncurryThis$c(''.slice); + var charCodeAt$1 = uncurryThis$c(''.charCodeAt); + + // `ToNumeric` abstract operation + // https://tc39.es/ecma262/#sec-tonumeric + var toNumeric = function (value) { + var primValue = toPrimitive$1(value, 'number'); + return typeof primValue == 'bigint' ? primValue : toNumber$1(primValue); + }; // `ToNumber` abstract operation // https://tc39.es/ecma262/#sec-tonumber var toNumber$1 = function (argument) { - var it = toPrimitive$1(argument, false); + var it = toPrimitive$1(argument, 'number'); var first, third, radix, maxCode, digits, length, index, code; + if (isSymbol$1(it)) throw TypeError$4('Cannot convert a Symbol value to a number'); if (typeof it == 'string' && it.length > 2) { it = trim$2(it); - first = it.charCodeAt(0); + first = charCodeAt$1(it, 0); if (first === 43 || first === 45) { - third = it.charCodeAt(2); + third = charCodeAt$1(it, 2); if (third === 88 || third === 120) return NaN; // Number('+0x1') should be NaN, old V8 fix } else if (first === 48) { - switch (it.charCodeAt(1)) { + switch (charCodeAt$1(it, 1)) { case 66: case 98: radix = 2; maxCode = 49; break; // fast equal of /^0b[01]+$/i case 79: case 111: radix = 8; maxCode = 55; break; // fast equal of /^0o[0-7]+$/i default: return +it; } - digits = it.slice(2); + digits = arraySlice$1(it, 2); length = digits.length; for (index = 0; index < length; index++) { - code = digits.charCodeAt(index); + code = charCodeAt$1(digits, index); // parseInt parses a string to a first unavailable symbol // but ToNumber should return NaN if a string contains unavailable symbols if (code < 48 || code > maxCode) return NaN; @@ -18211,75 +17827,29 @@ // https://tc39.es/ecma262/#sec-number-constructor if (isForced(NUMBER, !NativeNumber(' 0o1') || !NativeNumber('0b1') || NativeNumber('+0x1'))) { var NumberWrapper = function Number(value) { - var it = arguments.length < 1 ? 0 : value; + var n = arguments.length < 1 ? 0 : NativeNumber(toNumeric(value)); var dummy = this; - return dummy instanceof NumberWrapper - // check on 1..constructor(foo) case - && (BROKEN_CLASSOF ? fails$8(function () { NumberPrototype.valueOf.call(dummy); }) : classof$1(dummy) != NUMBER) - ? inheritIfRequired(new NativeNumber(toNumber$1(it)), dummy, NumberWrapper) : toNumber$1(it); + // check on 1..constructor(foo) case + return isPrototypeOf(NumberPrototype, dummy) && fails$8(function () { thisNumberValue$2(dummy); }) + ? inheritIfRequired(Object(n), dummy, NumberWrapper) : n; }; - for (var keys = DESCRIPTORS$2 ? getOwnPropertyNames(NativeNumber) : ( + for (var keys = DESCRIPTORS$3 ? getOwnPropertyNames(NativeNumber) : ( // ES3: 'MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,' + // ES2015 (in case, if modules with ES2015 Number statics required before): - 'EPSILON,isFinite,isInteger,isNaN,isSafeInteger,MAX_SAFE_INTEGER,' + - 'MIN_SAFE_INTEGER,parseFloat,parseInt,isInteger,' + + 'EPSILON,MAX_SAFE_INTEGER,MIN_SAFE_INTEGER,isFinite,isInteger,isNaN,isSafeInteger,parseFloat,parseInt,' + // ESNext 'fromString,range' ).split(','), j$1 = 0, key; keys.length > j$1; j$1++) { - if (has(NativeNumber, key = keys[j$1]) && !has(NumberWrapper, key)) { + if (hasOwn$1(NativeNumber, key = keys[j$1]) && !hasOwn$1(NumberWrapper, key)) { defineProperty(NumberWrapper, key, getOwnPropertyDescriptor$2(NativeNumber, key)); } } NumberWrapper.prototype = NumberPrototype; NumberPrototype.constructor = NumberWrapper; - redefine$1(global$2, NUMBER, NumberWrapper); + redefine$2(global$a, NUMBER, NumberWrapper); } - var fixRegExpWellKnownSymbolLogic$1 = fixRegexpWellKnownSymbolLogic; - var anObject$1 = anObject$m; - var toLength$3 = toLength$q; - var requireObjectCoercible$7 = requireObjectCoercible$e; - var advanceStringIndex = advanceStringIndex$3; - var regExpExec$1 = regexpExecAbstract; - - // @@match logic - fixRegExpWellKnownSymbolLogic$1('match', function (MATCH, nativeMatch, maybeCallNative) { - return [ - // `String.prototype.match` method - // https://tc39.es/ecma262/#sec-string.prototype.match - function match(regexp) { - var O = requireObjectCoercible$7(this); - var matcher = regexp == undefined ? undefined : regexp[MATCH]; - return matcher !== undefined ? matcher.call(regexp, O) : new RegExp(regexp)[MATCH](String(O)); - }, - // `RegExp.prototype[@@match]` method - // https://tc39.es/ecma262/#sec-regexp.prototype-@@match - function (string) { - var res = maybeCallNative(nativeMatch, this, string); - if (res.done) return res.value; - - var rx = anObject$1(this); - var S = String(string); - - if (!rx.global) return regExpExec$1(rx, S); - - var fullUnicode = rx.unicode; - rx.lastIndex = 0; - var A = []; - var n = 0; - var result; - while ((result = regExpExec$1(rx, S)) !== null) { - var matchStr = String(result[0]); - A[n] = matchStr; - if (matchStr === '') rx.lastIndex = advanceStringIndex(S, toLength$3(rx.lastIndex), fullUnicode); - n++; - } - return n === 0 ? null : A; - } - ]; - }); - var diacritics = {}; var remove$6 = diacritics.remove = removeDiacritics; @@ -20660,8 +20230,8 @@ } else if (reference_1$1.tashkeel.indexOf(word[w]) > -1) { // tashkeel - add without changing state output += word[w]; - } else if (nextLetter === ' ' || // last Arabic letter in this word - reference_1$1.lineBreakers.indexOf(word[w]) > -1) { + } else if (nextLetter === ' ' // last Arabic letter in this word + || reference_1$1.lineBreakers.indexOf(word[w]) > -1) { // the current letter is known to break lines output += CharShaper_1$1.CharShaper(word[w], state === 'initial' ? 'isolated' : 'final'); state = 'initial'; @@ -20834,10 +20404,14 @@ return ret; } - var DESCRIPTORS$1 = descriptors; + var DESCRIPTORS$2 = descriptors; + var uncurryThis$b = functionUncurryThis; var objectKeys = objectKeys$4; - var toIndexedObject = toIndexedObject$b; - var propertyIsEnumerable = objectPropertyIsEnumerable.f; + var toIndexedObject = toIndexedObject$c; + var $propertyIsEnumerable = objectPropertyIsEnumerable.f; + + var propertyIsEnumerable = uncurryThis$b($propertyIsEnumerable); + var push$2 = uncurryThis$b([].push); // `Object.{ entries, values }` methods implementation var createMethod$1 = function (TO_ENTRIES) { @@ -20850,8 +20424,8 @@ var key; while (length > i) { key = keys[i++]; - if (!DESCRIPTORS$1 || propertyIsEnumerable.call(O, key)) { - result.push(TO_ENTRIES ? [key, O[key]] : O[key]); + if (!DESCRIPTORS$2 || propertyIsEnumerable(O, key)) { + push$2(result, TO_ENTRIES ? [key, O[key]] : O[key]); } } return result; @@ -20867,12 +20441,12 @@ values: createMethod$1(false) }; - var $$k = _export; + var $$r = _export; var $values = objectToArray.values; // `Object.values` method // https://tc39.es/ecma262/#sec-object.values - $$k({ target: 'Object', stat: true }, { + $$r({ target: 'Object', stat: true }, { values: function values(O) { return $values(O); } @@ -20900,7 +20474,9 @@ return delete s[k]; } }; - }(); // + }(); + + var _listeners = {}; // // corePreferences is an interface for persisting basic key-value strings // within and between iD sessions on the same site. // @@ -20911,10 +20487,16 @@ * @returns {boolean} true if the action succeeded */ - function corePreferences(k, v) { try { - if (arguments.length === 1) return _storage.getItem(k);else if (v === null) _storage.removeItem(k);else _storage.setItem(k, v); + if (v === undefined) return _storage.getItem(k);else if (v === null) _storage.removeItem(k);else _storage.setItem(k, v); + + if (_listeners[k]) { + _listeners[k].forEach(function (handler) { + return handler(v); + }); + } + return true; } catch (e) { /* eslint-disable no-console */ @@ -20926,7 +20508,14 @@ return false; } - } + } // adds an event listener which is triggered whenever + + + corePreferences.onChange = function (k, handler) { + _listeners[k] = _listeners[k] || []; + + _listeners[k].push(handler); + }; var vparse = {exports: {}}; @@ -20975,7 +20564,7 @@ var parseVersion = vparse.exports; var name = "iD"; - var version = "2.20.2"; + var version = "2.20.3"; var description = "A friendly editor for OpenStreetMap"; var main = "dist/iD.min.js"; var repository = "github:openstreetmap/iD"; @@ -20983,9 +20572,9 @@ var bugs = "https://github.com/openstreetmap/iD/issues"; var keywords = ["editor","openstreetmap"]; var license = "ISC"; - var scripts = {all:"npm-run-all -s clean build build:legacy dist",build:"npm-run-all -s build:css build:data build:dev","build:css":"node scripts/build_css.js","build:data":"shx mkdir -p dist/data && node scripts/build_data.js","build:dev":"rollup --config config/rollup.config.dev.js","build:legacy":"rollup --config config/rollup.config.legacy.js","build:stats":"rollup --config config/rollup.config.stats.js",clean:"shx rm -f dist/*.js dist/*.map dist/*.css dist/img/*.svg",dist:"npm-run-all -p dist:**","dist:mapillary":"shx mkdir -p dist/mapillary-js && shx cp -R node_modules/mapillary-js/dist/* dist/mapillary-js/","dist:pannellum":"shx mkdir -p dist/pannellum-streetside && shx cp -R node_modules/pannellum/build/* dist/pannellum-streetside/","dist:min:iD":"uglifyjs dist/iD.legacy.js --compress --mangle --output dist/iD.min.js","dist:svg:iD":"svg-sprite --symbol --symbol-dest . --shape-id-generator \"iD-%s\" --symbol-sprite dist/img/iD-sprite.svg \"svg/iD-sprite/**/*.svg\"","dist:svg:community":"svg-sprite --symbol --symbol-dest . --shape-id-generator \"community-%s\" --symbol-sprite dist/img/community-sprite.svg node_modules/osm-community-index/dist/img/*.svg","dist:svg:fa":"svg-sprite --symbol --symbol-dest . --symbol-sprite dist/img/fa-sprite.svg svg/fontawesome/*.svg","dist:svg:maki":"svg-sprite --symbol --symbol-dest . --shape-id-generator \"maki-%s\" --symbol-sprite dist/img/maki-sprite.svg node_modules/@mapbox/maki/icons/*.svg","dist:svg:mapillary:signs":"svg-sprite --symbol --symbol-dest . --symbol-sprite dist/img/mapillary-sprite.svg node_modules/mapillary_sprite_source/package_signs/*.svg","dist:svg:mapillary:objects":"svg-sprite --symbol --symbol-dest . --symbol-sprite dist/img/mapillary-object-sprite.svg node_modules/mapillary_sprite_source/package_objects/*.svg","dist:svg:temaki":"svg-sprite --symbol --symbol-dest . --shape-id-generator \"temaki-%s\" --symbol-sprite dist/img/temaki-sprite.svg node_modules/@ideditor/temaki/icons/*.svg",imagery:"node scripts/update_imagery.js",lint:"eslint scripts test/spec modules","lint:fix":"eslint scripts test/spec modules --fix",start:"npm-run-all -s build start:server",quickstart:"npm-run-all -s build:dev start:server","start:server":"node scripts/server.js",test:"npm-run-all -s lint build:css build:data build:legacy test:spec","test:spec":"phantomjs --web-security=no node_modules/mocha-phantomjs-core/mocha-phantomjs-core.js test/index.html spec",translations:"node scripts/update_locales.js"}; + var scripts = {all:"npm-run-all -s clean build build:legacy dist",build:"npm-run-all -s build:css build:data build:dev","build:css":"node scripts/build_css.js","build:data":"shx mkdir -p dist/data && node scripts/build_data.js","build:dev":"rollup --config config/rollup.config.dev.js","build:legacy":"rollup --config config/rollup.config.legacy.js","build:stats":"rollup --config config/rollup.config.stats.js",clean:"shx rm -f dist/*.js dist/*.map dist/*.css dist/img/*.svg",dist:"npm-run-all -p dist:**","dist:mapillary":"shx mkdir -p dist/mapillary-js && shx cp -R node_modules/mapillary-js/dist/* dist/mapillary-js/","dist:pannellum":"shx mkdir -p dist/pannellum-streetside && shx cp -R node_modules/pannellum/build/* dist/pannellum-streetside/","dist:min:iD":"uglifyjs dist/iD.legacy.js --compress --mangle --output dist/iD.min.js","dist:svg:iD":"svg-sprite --symbol --symbol-dest . --shape-id-generator \"iD-%s\" --symbol-sprite dist/img/iD-sprite.svg \"svg/iD-sprite/**/*.svg\"","dist:svg:community":"svg-sprite --symbol --symbol-dest . --shape-id-generator \"community-%s\" --symbol-sprite dist/img/community-sprite.svg node_modules/osm-community-index/dist/img/*.svg","dist:svg:fa":"svg-sprite --symbol --symbol-dest . --symbol-sprite dist/img/fa-sprite.svg svg/fontawesome/*.svg","dist:svg:maki":"svg-sprite --symbol --symbol-dest . --shape-id-generator \"maki-%s\" --symbol-sprite dist/img/maki-sprite.svg node_modules/@mapbox/maki/icons/*.svg","dist:svg:mapillary:signs":"svg-sprite --symbol --symbol-dest . --symbol-sprite dist/img/mapillary-sprite.svg node_modules/mapillary_sprite_source/package_signs/*.svg","dist:svg:mapillary:objects":"svg-sprite --symbol --symbol-dest . --symbol-sprite dist/img/mapillary-object-sprite.svg node_modules/mapillary_sprite_source/package_objects/*.svg","dist:svg:temaki":"svg-sprite --symbol --symbol-dest . --shape-id-generator \"temaki-%s\" --symbol-sprite dist/img/temaki-sprite.svg node_modules/@ideditor/temaki/icons/*.svg",imagery:"node scripts/update_imagery.js",lint:"eslint scripts test/spec modules","lint:fix":"eslint scripts test/spec modules --fix",start:"npm-run-all -s build start:server",quickstart:"npm-run-all -s build:dev start:server","start:server":"node scripts/server.js",test:"npm-run-all -s lint build test:spec","test:spec":"karma start karma.conf.js",translations:"node scripts/update_locales.js"}; var dependencies = {"@ideditor/country-coder":"~5.0.3","@ideditor/location-conflation":"~1.0.2","@mapbox/geojson-area":"^0.2.2","@mapbox/sexagesimal":"1.2.0","@mapbox/vector-tile":"^1.3.1","@tmcw/togeojson":"^4.5.0","@turf/bbox-clip":"^6.0.0","abortcontroller-polyfill":"^1.4.0","aes-js":"^3.1.2","alif-toolkit":"^1.2.9","core-js":"^3.6.5",diacritics:"1.3.0","fast-deep-equal":"~3.1.1","fast-json-stable-stringify":"2.1.0","lodash-es":"~4.17.15",marked:"~2.0.0","node-diff3":"2.1.0","osm-auth":"1.1.0",pannellum:"2.5.6",pbf:"^3.2.1","polygon-clipping":"~0.15.1",rbush:"3.0.1","whatwg-fetch":"^3.4.1","which-polygon":"2.2.0"}; - var devDependencies = {"@babel/core":"^7.11.6","@babel/preset-env":"^7.11.5","@fortawesome/fontawesome-svg-core":"^1.2.32","@fortawesome/free-brands-svg-icons":"~5.15.1","@fortawesome/free-regular-svg-icons":"~5.15.1","@fortawesome/free-solid-svg-icons":"~5.15.1","@ideditor/temaki":"~4.4.0","@mapbox/maki":"^6.0.0","@rollup/plugin-babel":"^5.2.1","@rollup/plugin-commonjs":"^21.0.0","@rollup/plugin-json":"^4.0.1","@rollup/plugin-node-resolve":"~13.0.5",autoprefixer:"^10.0.1",btoa:"^1.2.1",chai:"^4.1.0","cldr-core":"37.0.0","cldr-localenames-full":"37.0.0",colors:"^1.1.2","concat-files":"^0.1.1",d3:"~6.6.0","editor-layer-index":"github:osmlab/editor-layer-index#gh-pages",eslint:"^7.1.0",gaze:"^1.1.3",glob:"^7.1.0",happen:"^0.3.1","js-yaml":"^4.0.0","json-stringify-pretty-compact":"^3.0.0",mapillary_sprite_source:"^1.8.0","mapillary-js":"4.0.0",minimist:"^1.2.3",mocha:"^7.0.1","mocha-phantomjs-core":"^2.1.0","name-suggestion-index":"~6.0","node-fetch":"^2.6.1","npm-run-all":"^4.0.0","object-inspect":"1.10.3","osm-community-index":"~5.1.0","phantomjs-prebuilt":"~2.1.16",postcss:"^8.1.1","postcss-selector-prepend":"^0.5.0",rollup:"~2.52.8","rollup-plugin-includepaths":"~0.2.3","rollup-plugin-progress":"^1.1.1","rollup-plugin-visualizer":"~4.2.0",shelljs:"^0.8.0",shx:"^0.3.0",sinon:"7.5.0","sinon-chai":"^3.3.0",smash:"0.0","static-server":"^2.2.1","svg-sprite":"1.5.1","uglify-js":"~3.13.0",vparse:"~1.1.0"}; + var devDependencies = {"@babel/core":"^7.11.6","@babel/preset-env":"^7.11.5","@fortawesome/fontawesome-svg-core":"^1.2.32","@fortawesome/free-brands-svg-icons":"~5.15.1","@fortawesome/free-regular-svg-icons":"~5.15.1","@fortawesome/free-solid-svg-icons":"~5.15.1","@ideditor/temaki":"~5.0.0","@mapbox/maki":"^6.0.0","@rollup/plugin-babel":"^5.2.1","@rollup/plugin-commonjs":"^21.0.0","@rollup/plugin-json":"^4.0.1","@rollup/plugin-node-resolve":"~13.0.5",autoprefixer:"^10.0.1",btoa:"^1.2.1",chai:"^4.3.4","cldr-core":"37.0.0","cldr-localenames-full":"37.0.0",chalk:"^4.1.2","concat-files":"^0.1.1",d3:"~6.6.0","editor-layer-index":"github:osmlab/editor-layer-index#gh-pages",eslint:"^7.1.0","fetch-mock":"^9.11.0",gaze:"^1.1.3",glob:"^7.1.0",happen:"^0.3.2","js-yaml":"^4.0.0","json-stringify-pretty-compact":"^3.0.0",karma:"^6.3.5","karma-chrome-launcher":"^3.1.0","karma-coverage":"^2.0.3","karma-mocha":"^2.0.1","karma-remap-istanbul":"^0.6.0",mapillary_sprite_source:"^1.8.0","mapillary-js":"4.0.0",minimist:"^1.2.3",mocha:"^8.4.0","name-suggestion-index":"~6.0","node-fetch":"^2.6.1","npm-run-all":"^4.0.0","object-inspect":"1.10.3","osm-community-index":"~5.1.0",postcss:"^8.1.1","postcss-selector-prepend":"^0.5.0",rollup:"~2.52.8","rollup-plugin-includepaths":"~0.2.3","rollup-plugin-progress":"^1.1.1","rollup-plugin-visualizer":"~4.2.0",shelljs:"^0.8.0",shx:"^0.3.0",sinon:"^11.1.2","sinon-chai":"^3.7.0",smash:"0.0","static-server":"^2.2.1","svg-sprite":"1.5.1","uglify-js":"~3.13.0",vparse:"~1.1.0"}; var engines = {node:">=10"}; var browserslist = ["> 0.2%, last 6 major versions, Firefox ESR, IE 11, maintained node versions"]; var packageJSON = { @@ -21120,42 +20709,41 @@ return _this; } - var classof = classofRaw$1; - - // `thisNumberValue` abstract operation - // https://tc39.es/ecma262/#sec-thisnumbervalue - var thisNumberValue$2 = function (value) { - if (typeof value != 'number' && classof(value) != 'Number') { - throw TypeError('Incorrect invocation'); - } - return +value; - }; - - var toInteger$1 = toInteger$b; + var global$9 = global$1m; + var toIntegerOrInfinity$1 = toIntegerOrInfinity$b; + var toString$7 = toString$k; var requireObjectCoercible$6 = requireObjectCoercible$e; + var RangeError$5 = global$9.RangeError; + // `String.prototype.repeat` method implementation // https://tc39.es/ecma262/#sec-string.prototype.repeat var stringRepeat = function repeat(count) { - var str = String(requireObjectCoercible$6(this)); + var str = toString$7(requireObjectCoercible$6(this)); var result = ''; - var n = toInteger$1(count); - if (n < 0 || n == Infinity) throw RangeError('Wrong number of repetitions'); + var n = toIntegerOrInfinity$1(count); + if (n < 0 || n == Infinity) throw RangeError$5('Wrong number of repetitions'); for (;n > 0; (n >>>= 1) && (str += str)) if (n & 1) result += str; return result; }; - var $$j = _export; - var toInteger = toInteger$b; - var thisNumberValue$1 = thisNumberValue$2; - var repeat$2 = stringRepeat; - var fails$7 = fails$N; - - var nativeToFixed = 1.0.toFixed; - var floor = Math.floor; + var $$q = _export; + var global$8 = global$1m; + var uncurryThis$a = functionUncurryThis; + var toIntegerOrInfinity = toIntegerOrInfinity$b; + var thisNumberValue$1 = thisNumberValue$3; + var $repeat$1 = stringRepeat; + var fails$7 = fails$S; + + var RangeError$4 = global$8.RangeError; + var String$1 = global$8.String; + var floor$2 = Math.floor; + var repeat$2 = uncurryThis$a($repeat$1); + var stringSlice$3 = uncurryThis$a(''.slice); + var un$ToFixed = uncurryThis$a(1.0.toFixed); - var pow = function (x, n, acc) { - return n === 0 ? acc : n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc); + var pow$1 = function (x, n, acc) { + return n === 0 ? acc : n % 2 === 1 ? pow$1(x, n - 1, acc * x) : pow$1(x * x, n / 2, acc); }; var log = function (x) { @@ -21177,7 +20765,7 @@ while (++index < 6) { c2 += n * data[index]; data[index] = c2 % 1e7; - c2 = floor(c2 / 1e7); + c2 = floor$2(c2 / 1e7); } }; @@ -21186,7 +20774,7 @@ var c = 0; while (--index >= 0) { c += data[index]; - data[index] = floor(c / n); + data[index] = floor$2(c / n); c = (c % n) * 1e7; } }; @@ -21196,44 +20784,44 @@ var s = ''; while (--index >= 0) { if (s !== '' || index === 0 || data[index] !== 0) { - var t = String(data[index]); - s = s === '' ? t : s + repeat$2.call('0', 7 - t.length) + t; + var t = String$1(data[index]); + s = s === '' ? t : s + repeat$2('0', 7 - t.length) + t; } } return s; }; - var FORCED$4 = nativeToFixed && ( - 0.00008.toFixed(3) !== '0.000' || - 0.9.toFixed(0) !== '1' || - 1.255.toFixed(2) !== '1.25' || - 1000000000000000128.0.toFixed(0) !== '1000000000000000128' - ) || !fails$7(function () { + var FORCED$6 = fails$7(function () { + return un$ToFixed(0.00008, 3) !== '0.000' || + un$ToFixed(0.9, 0) !== '1' || + un$ToFixed(1.255, 2) !== '1.25' || + un$ToFixed(1000000000000000128.0, 0) !== '1000000000000000128'; + }) || !fails$7(function () { // V8 ~ Android 4.3- - nativeToFixed.call({}); + un$ToFixed({}); }); // `Number.prototype.toFixed` method // https://tc39.es/ecma262/#sec-number.prototype.tofixed - $$j({ target: 'Number', proto: true, forced: FORCED$4 }, { + $$q({ target: 'Number', proto: true, forced: FORCED$6 }, { toFixed: function toFixed(fractionDigits) { var number = thisNumberValue$1(this); - var fractDigits = toInteger(fractionDigits); + var fractDigits = toIntegerOrInfinity(fractionDigits); var data = [0, 0, 0, 0, 0, 0]; var sign = ''; var result = '0'; var e, z, j, k; - if (fractDigits < 0 || fractDigits > 20) throw RangeError('Incorrect fraction digits'); + if (fractDigits < 0 || fractDigits > 20) throw RangeError$4('Incorrect fraction digits'); // eslint-disable-next-line no-self-compare -- NaN check if (number != number) return 'NaN'; - if (number <= -1e21 || number >= 1e21) return String(number); + if (number <= -1e21 || number >= 1e21) return String$1(number); if (number < 0) { sign = '-'; number = -number; } if (number > 1e-21) { - e = log(number * pow(2, 69, 1)) - 69; - z = e < 0 ? number * pow(2, -e, 1) : number / pow(2, e, 1); + e = log(number * pow$1(2, 69, 1)) - 69; + z = e < 0 ? number * pow$1(2, -e, 1) : number / pow$1(2, e, 1); z *= 0x10000000000000; e = 52 - e; if (e > 0) { @@ -21243,7 +20831,7 @@ multiply(data, 1e7, 0); j -= 7; } - multiply(data, pow(10, j, 1), 0); + multiply(data, pow$1(10, j, 1), 0); j = e - 1; while (j >= 23) { divide(data, 1 << 23); @@ -21256,23 +20844,23 @@ } else { multiply(data, 0, z); multiply(data, 1 << -e, 0); - result = dataToString(data) + repeat$2.call('0', fractDigits); + result = dataToString(data) + repeat$2('0', fractDigits); } } if (fractDigits > 0) { k = result.length; result = sign + (k <= fractDigits - ? '0.' + repeat$2.call('0', fractDigits - k) + result - : result.slice(0, k - fractDigits) + '.' + result.slice(k - fractDigits)); + ? '0.' + repeat$2('0', fractDigits - k) + result + : stringSlice$3(result, 0, k - fractDigits) + '.' + stringSlice$3(result, k - fractDigits)); } else { result = sign + result; } return result; } }); - var global$1 = global$F; + var global$7 = global$1m; - var globalIsFinite = global$1.isFinite; + var globalIsFinite = global$7.isFinite; // `Number.isFinite` method // https://tc39.es/ecma262/#sec-number.isfinite @@ -21281,26 +20869,30 @@ return typeof it == 'number' && globalIsFinite(it); }; - var $$i = _export; + var $$p = _export; var numberIsFinite = numberIsFinite$1; // `Number.isFinite` method // https://tc39.es/ecma262/#sec-number.isfinite - $$i({ target: 'Number', stat: true }, { isFinite: numberIsFinite }); + $$p({ target: 'Number', stat: true }, { isFinite: numberIsFinite }); - var $$h = _export; + var $$o = _export; + var global$6 = global$1m; + var uncurryThis$9 = functionUncurryThis; var toAbsoluteIndex = toAbsoluteIndex$8; - var fromCharCode = String.fromCharCode; + var RangeError$3 = global$6.RangeError; + var fromCharCode$1 = String.fromCharCode; // eslint-disable-next-line es/no-string-fromcodepoint -- required for testing var $fromCodePoint = String.fromCodePoint; + var join$2 = uncurryThis$9([].join); // length should be 1, old FF problem var INCORRECT_LENGTH = !!$fromCodePoint && $fromCodePoint.length != 1; // `String.fromCodePoint` method // https://tc39.es/ecma262/#sec-string.fromcodepoint - $$h({ target: 'String', stat: true, forced: INCORRECT_LENGTH }, { + $$o({ target: 'String', stat: true, forced: INCORRECT_LENGTH }, { // eslint-disable-next-line no-unused-vars -- required for `.length` fromCodePoint: function fromCodePoint(x) { var elements = []; @@ -21309,19 +20901,21 @@ var code; while (length > i) { code = +arguments[i++]; - if (toAbsoluteIndex(code, 0x10FFFF) !== code) throw RangeError(code + ' is not a valid code point'); - elements.push(code < 0x10000 - ? fromCharCode(code) - : fromCharCode(((code -= 0x10000) >> 10) + 0xD800, code % 0x400 + 0xDC00) - ); - } return elements.join(''); + if (toAbsoluteIndex(code, 0x10FFFF) !== code) throw RangeError$3(code + ' is not a valid code point'); + elements[i] = code < 0x10000 + ? fromCharCode$1(code) + : fromCharCode$1(((code -= 0x10000) >> 10) + 0xD800, code % 0x400 + 0xDC00); + } return join$2(elements, ''); } }); + var call$2 = functionCall; var fixRegExpWellKnownSymbolLogic = fixRegexpWellKnownSymbolLogic; - var anObject = anObject$m; + var anObject = anObject$n; var requireObjectCoercible$5 = requireObjectCoercible$e; var sameValue = sameValue$1; + var toString$6 = toString$k; + var getMethod = getMethod$7; var regExpExec = regexpExecAbstract; // @@search logic @@ -21331,17 +20925,17 @@ // https://tc39.es/ecma262/#sec-string.prototype.search function search(regexp) { var O = requireObjectCoercible$5(this); - var searcher = regexp == undefined ? undefined : regexp[SEARCH]; - return searcher !== undefined ? searcher.call(regexp, O) : new RegExp(regexp)[SEARCH](String(O)); + var searcher = regexp == undefined ? undefined : getMethod(regexp, SEARCH); + return searcher ? call$2(searcher, regexp, O) : new RegExp(regexp)[SEARCH](toString$6(O)); }, // `RegExp.prototype[@@search]` method // https://tc39.es/ecma262/#sec-regexp.prototype-@@search function (string) { - var res = maybeCallNative(nativeSearch, this, string); - if (res.done) return res.value; - var rx = anObject(this); - var S = String(string); + var S = toString$6(string); + var res = maybeCallNative(nativeSearch, rx, S); + + if (res.done) return res.value; var previousLastIndex = rx.lastIndex; if (!sameValue(previousLastIndex, 0)) rx.lastIndex = 0; @@ -28352,20 +27946,20 @@ var inputValidation = {}; - var $$g = _export; + var $$n = _export; var $includes = arrayIncludes.includes; - var addToUnscopables$1 = addToUnscopables$5; + var addToUnscopables$2 = addToUnscopables$6; // `Array.prototype.includes` method // https://tc39.es/ecma262/#sec-array.prototype.includes - $$g({ target: 'Array', proto: true }, { + $$n({ target: 'Array', proto: true }, { includes: function includes(el /* , fromIndex = 0 */) { return $includes(this, el, arguments.length > 1 ? arguments[1] : undefined); } }); // https://tc39.es/ecma262/#sec-array.prototype-@@unscopables - addToUnscopables$1('includes'); + addToUnscopables$2('includes'); var validateCenter$1 = {}; @@ -28562,28 +28156,31 @@ return argument === null || argument === undefined; } - var $$f = _export; + var $$m = _export; // `Number.EPSILON` constant // https://tc39.es/ecma262/#sec-number.epsilon - $$f({ target: 'Number', stat: true }, { + $$m({ target: 'Number', stat: true }, { EPSILON: Math.pow(2, -52) }); + var uncurryThis$8 = functionUncurryThis; var requireObjectCoercible$4 = requireObjectCoercible$e; + var toString$5 = toString$k; var quot = /"/g; + var replace$2 = uncurryThis$8(''.replace); // `CreateHTML` abstract operation // https://tc39.es/ecma262/#sec-createhtml var createHtml = function (string, tag, attribute, value) { - var S = String(requireObjectCoercible$4(string)); + var S = toString$5(requireObjectCoercible$4(string)); var p1 = '<' + tag; - if (attribute !== '') p1 += ' ' + attribute + '="' + String(value).replace(quot, '"') + '"'; + if (attribute !== '') p1 += ' ' + attribute + '="' + replace$2(toString$5(value), quot, '"') + '"'; return p1 + '>' + S + ''; }; - var fails$6 = fails$N; + var fails$6 = fails$S; // check the existence of a method, lowercase // of a tag and escaping quotes in arguments @@ -28594,13 +28191,13 @@ }); }; - var $$e = _export; + var $$l = _export; var createHTML = createHtml; var forcedStringHTMLMethod = stringHtmlForced; // `String.prototype.link` method // https://tc39.es/ecma262/#sec-string.prototype.link - $$e({ target: 'String', proto: true, forced: forcedStringHTMLMethod('link') }, { + $$l({ target: 'String', proto: true, forced: forcedStringHTMLMethod('link') }, { link: function link(url) { return createHTML(this, 'a', 'href', url); } @@ -28720,7 +28317,7 @@ return node; } - function split(key, v, comparator) { + function split$2(key, v, comparator) { var left = null; var right = null; @@ -29193,7 +28790,7 @@ Tree.prototype.update = function (key, newKey, newData) { var comparator = this._comparator; - var _a = split(key, this._root, comparator), + var _a = split$2(key, this._root, comparator), left = _a.left, right = _a.right; @@ -29207,7 +28804,7 @@ }; Tree.prototype.split = function (key) { - return split(key, this._root, this._comparator); + return split$2(key, this._root, this._comparator); }; return Tree; @@ -31276,34 +30873,35 @@ var precision = geojsonPrecision.exports; - var $$d = _export; - var fails$5 = fails$N; - var toObject = toObject$i; - var toPrimitive = toPrimitive$7; + var $$k = _export; + var fails$5 = fails$S; + var toObject$1 = toObject$j; + var toPrimitive = toPrimitive$3; - var FORCED$3 = fails$5(function () { + var FORCED$5 = fails$5(function () { return new Date(NaN).toJSON() !== null || Date.prototype.toJSON.call({ toISOString: function () { return 1; } }) !== 1; }); // `Date.prototype.toJSON` method // https://tc39.es/ecma262/#sec-date.prototype.tojson - $$d({ target: 'Date', proto: true, forced: FORCED$3 }, { + $$k({ target: 'Date', proto: true, forced: FORCED$5 }, { // eslint-disable-next-line no-unused-vars -- required for `.length` toJSON: function toJSON(key) { - var O = toObject(this); - var pv = toPrimitive(O); + var O = toObject$1(this); + var pv = toPrimitive(O, 'number'); return typeof pv == 'number' && !isFinite(pv) ? null : O.toISOString(); } }); - var $$c = _export; + var $$j = _export; + var call$1 = functionCall; // `URL.prototype.toJSON` method // https://url.spec.whatwg.org/#dom-url-tojson - $$c({ target: 'URL', proto: true, enumerable: true }, { + $$j({ target: 'URL', proto: true, enumerable: true }, { toJSON: function toJSON() { - return URL.prototype.toString.call(this); + return call$1(URL.prototype.toString, this); } }); @@ -31879,11 +31477,11 @@ return aRank > bRank ? 1 : aRank < bRank ? -1 : a.id.localeCompare(b.id); } - var $$b = _export; + var $$i = _export; // `Number.MAX_SAFE_INTEGER` constant // https://tc39.es/ecma262/#sec-number.max_safe_integer - $$b({ target: 'Number', stat: true }, { + $$i({ target: 'Number', stat: true }, { MAX_SAFE_INTEGER: 0x1FFFFFFFFFFFFF }); @@ -32830,6 +32428,8 @@ // Like selection.property('value', ...), but avoids no-op value sets, // which can result in layout/repaint thrashing in some situations. + + /** @returns {string} */ function utilGetSetValue(selection, value) { function d3_selection_value(value) { function valueNull() { @@ -33904,9 +33504,9 @@ return _this; } - var $$a = _export; + var $$h = _export; var $findIndex = arrayIteration.findIndex; - var addToUnscopables = addToUnscopables$5; + var addToUnscopables$1 = addToUnscopables$6; var FIND_INDEX = 'findIndex'; var SKIPS_HOLES = true; @@ -33916,24 +33516,27 @@ // `Array.prototype.findIndex` method // https://tc39.es/ecma262/#sec-array.prototype.findindex - $$a({ target: 'Array', proto: true, forced: SKIPS_HOLES }, { + $$h({ target: 'Array', proto: true, forced: SKIPS_HOLES }, { findIndex: function findIndex(callbackfn /* , that = undefined */) { return $findIndex(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined); } }); // https://tc39.es/ecma262/#sec-array.prototype-@@unscopables - addToUnscopables(FIND_INDEX); + addToUnscopables$1(FIND_INDEX); + var global$5 = global$1m; var isRegExp = isRegexp; + var TypeError$3 = global$5.TypeError; + var notARegexp = function (it) { if (isRegExp(it)) { - throw TypeError("The method doesn't accept regular expressions"); + throw TypeError$3("The method doesn't accept regular expressions"); } return it; }; - var wellKnownSymbol = wellKnownSymbol$s; + var wellKnownSymbol = wellKnownSymbol$t; var MATCH = wellKnownSymbol('match'); @@ -33949,23809 +33552,30256 @@ } return false; }; - var $$9 = _export; + var $$g = _export; + var uncurryThis$7 = functionUncurryThis; var notARegExp$2 = notARegexp; var requireObjectCoercible$3 = requireObjectCoercible$e; + var toString$4 = toString$k; var correctIsRegExpLogic$2 = correctIsRegexpLogic; + var stringIndexOf = uncurryThis$7(''.indexOf); + // `String.prototype.includes` method // https://tc39.es/ecma262/#sec-string.prototype.includes - $$9({ target: 'String', proto: true, forced: !correctIsRegExpLogic$2('includes') }, { + $$g({ target: 'String', proto: true, forced: !correctIsRegExpLogic$2('includes') }, { includes: function includes(searchString /* , position = 0 */) { - return !!~String(requireObjectCoercible$3(this)) - .indexOf(notARegExp$2(searchString), arguments.length > 1 ? arguments[1] : undefined); + return !!~stringIndexOf( + toString$4(requireObjectCoercible$3(this)), + toString$4(notARegExp$2(searchString)), + arguments.length > 1 ? arguments[1] : undefined + ); } }); - var _mainLocalizer = coreLocalizer(); // singleton + /** Detect free variable `global` from Node.js. */ + var freeGlobal = (typeof global === "undefined" ? "undefined" : _typeof(global)) == 'object' && global && global.Object === Object && global; + /** Detect free variable `self`. */ - var _t = _mainLocalizer.t; - // coreLocalizer manages language and locale parameters including translated strings - // + var freeSelf = (typeof self === "undefined" ? "undefined" : _typeof(self)) == 'object' && self && self.Object === Object && self; + /** Used as a reference to the global object. */ - function coreLocalizer() { - var localizer = {}; - var _dataLanguages = {}; // `_dataLocales` is an object containing all _supported_ locale codes -> language info. - // * `rtl` - right-to-left or left-to-right text direction - // * `pct` - the percent of strings translated; 1 = 100%, full coverage - // - // { - // en: { rtl: false, pct: {…} }, - // de: { rtl: false, pct: {…} }, - // … - // } + var root = freeGlobal || freeSelf || Function('return this')(); - var _dataLocales = {}; // `localeStrings` is an object containing all _loaded_ locale codes -> string data. - // { - // en: { icons: {…}, toolbar: {…}, modes: {…}, operations: {…}, … }, - // de: { icons: {…}, toolbar: {…}, modes: {…}, operations: {…}, … }, - // … - // } + /** Built-in value references. */ - var _localeStrings = {}; // the current locale + var _Symbol = root.Symbol; - var _localeCode = 'en-US'; // `_localeCodes` must contain `_localeCode` first, optionally followed by fallbacks + /** Used for built-in method references. */ - var _localeCodes = ['en-US', 'en']; - var _languageCode = 'en'; - var _textDirection = 'ltr'; - var _usesMetric = false; - var _languageNames = {}; - var _scriptNames = {}; // getters for the current locale parameters + var objectProto$1 = Object.prototype; + /** Used to check objects for own properties. */ - localizer.localeCode = function () { - return _localeCode; - }; + var hasOwnProperty$2 = objectProto$1.hasOwnProperty; + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ - localizer.localeCodes = function () { - return _localeCodes; - }; + var nativeObjectToString$1 = objectProto$1.toString; + /** Built-in value references. */ - localizer.languageCode = function () { - return _languageCode; - }; + var symToStringTag$1 = _Symbol ? _Symbol.toStringTag : undefined; + /** + * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the raw `toStringTag`. + */ - localizer.textDirection = function () { - return _textDirection; - }; + function getRawTag(value) { + var isOwn = hasOwnProperty$2.call(value, symToStringTag$1), + tag = value[symToStringTag$1]; - localizer.usesMetric = function () { - return _usesMetric; - }; + try { + value[symToStringTag$1] = undefined; + var unmasked = true; + } catch (e) {} - localizer.languageNames = function () { - return _languageNames; - }; + var result = nativeObjectToString$1.call(value); - localizer.scriptNames = function () { - return _scriptNames; - }; // The client app may want to manually set the locale, regardless of the - // settings provided by the browser + if (unmasked) { + if (isOwn) { + value[symToStringTag$1] = tag; + } else { + delete value[symToStringTag$1]; + } + } + return result; + } - var _preferredLocaleCodes = []; + /** Used for built-in method references. */ + var objectProto = Object.prototype; + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ - localizer.preferredLocaleCodes = function (codes) { - if (!arguments.length) return _preferredLocaleCodes; + var nativeObjectToString = objectProto.toString; + /** + * Converts `value` to a string using `Object.prototype.toString`. + * + * @private + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + */ - if (typeof codes === 'string') { - // be generous and accept delimited strings as input - _preferredLocaleCodes = codes.split(/,|;| /gi).filter(Boolean); - } else { - _preferredLocaleCodes = codes; - } + function objectToString(value) { + return nativeObjectToString.call(value); + } - return localizer; - }; + /** `Object#toString` result references. */ - var _loadPromise; + var nullTag = '[object Null]', + undefinedTag = '[object Undefined]'; + /** Built-in value references. */ - localizer.ensureLoaded = function () { - if (_loadPromise) return _loadPromise; - var filesToFetch = ['languages', // load the list of languages - 'locales' // load the list of supported locales - ]; - var localeDirs = { - general: 'locales', - tagging: 'https://cdn.jsdelivr.net/npm/@openstreetmap/id-tagging-schema@3/dist/translations' - }; - var fileMap = _mainFileFetcher.fileMap(); + var symToStringTag = _Symbol ? _Symbol.toStringTag : undefined; + /** + * The base implementation of `getTag` without fallbacks for buggy environments. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ - for (var scopeId in localeDirs) { - var key = "locales_index_".concat(scopeId); + function baseGetTag(value) { + if (value == null) { + return value === undefined ? undefinedTag : nullTag; + } - if (!fileMap[key]) { - fileMap[key] = localeDirs[scopeId] + '/index.min.json'; - } + return symToStringTag && symToStringTag in Object(value) ? getRawTag(value) : objectToString(value); + } - filesToFetch.push(key); - } + /** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ + function isObjectLike(value) { + return value != null && _typeof(value) == 'object'; + } - return _loadPromise = Promise.all(filesToFetch.map(function (key) { - return _mainFileFetcher.get(key); - })).then(function (results) { - _dataLanguages = results[0]; - _dataLocales = results[1]; - var indexes = results.slice(2); + /** `Object#toString` result references. */ - var requestedLocales = (_preferredLocaleCodes || []).concat(utilDetect().browserLocales) // List of locales preferred by the browser in priority order. - .concat(['en']); // fallback to English since it's the only guaranteed complete language + var symbolTag = '[object Symbol]'; + /** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ + function isSymbol(value) { + return _typeof(value) == 'symbol' || isObjectLike(value) && baseGetTag(value) == symbolTag; + } - _localeCodes = localesToUseFrom(requestedLocales); - _localeCode = _localeCodes[0]; // Run iD in the highest-priority locale; the rest are fallbacks + /** + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ + function arrayMap(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length, + result = Array(length); - var loadStringsPromises = []; - indexes.forEach(function (index, i) { - // Will always return the index for `en` if nothing else - var fullCoverageIndex = _localeCodes.findIndex(function (locale) { - return index[locale] && index[locale].pct === 1; - }); // We only need to load locales up until we find one with full coverage + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; + } - _localeCodes.slice(0, fullCoverageIndex + 1).forEach(function (code) { - var scopeId = Object.keys(localeDirs)[i]; - var directory = Object.values(localeDirs)[i]; - if (index[code]) loadStringsPromises.push(localizer.loadLocale(code, scopeId, directory)); - }); - }); - return Promise.all(loadStringsPromises); - }).then(function () { - updateForCurrentLocale(); - })["catch"](function (err) { - return console.error(err); - }); // eslint-disable-line - }; // Returns the locales from `requestedLocales` supported by iD that we should use + /** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ + var isArray$1 = Array.isArray; + /** Used as references for various `Number` constants. */ - function localesToUseFrom(requestedLocales) { - var supportedLocales = _dataLocales; - var toUse = []; + var INFINITY = 1 / 0; + /** Used to convert symbols to primitives and strings. */ - for (var i in requestedLocales) { - var locale = requestedLocales[i]; - if (supportedLocales[locale]) toUse.push(locale); + var symbolProto = _Symbol ? _Symbol.prototype : undefined, + symbolToString = symbolProto ? symbolProto.toString : undefined; + /** + * The base implementation of `_.toString` which doesn't convert nullish + * values to empty strings. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ - if (locale.includes('-')) { - // Full locale ('es-ES'), add fallback to the base ('es') - var langPart = locale.split('-')[0]; - if (supportedLocales[langPart]) toUse.push(langPart); - } - } // remove duplicates + function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + if (isArray$1(value)) { + // Recursively convert values (susceptible to call stack limits). + return arrayMap(value, baseToString) + ''; + } - return utilArrayUniq(toUse); + if (isSymbol(value)) { + return symbolToString ? symbolToString.call(value) : ''; } - function updateForCurrentLocale() { - if (!_localeCode) return; - _languageCode = _localeCode.split('-')[0]; - var currentData = _dataLocales[_localeCode] || _dataLocales[_languageCode]; - var hash = utilStringQs(window.location.hash); + var result = value + ''; + return result == '0' && 1 / value == -INFINITY ? '-0' : result; + } - if (hash.rtl === 'true') { - _textDirection = 'rtl'; - } else if (hash.rtl === 'false') { - _textDirection = 'ltr'; - } else { - _textDirection = currentData && currentData.rtl ? 'rtl' : 'ltr'; - } + /** Used to match a single whitespace character. */ + var reWhitespace = /\s/; + /** + * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace + * character of `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the index of the last non-whitespace character. + */ - var locale = _localeCode; - if (locale.toLowerCase() === 'en-us') locale = 'en'; - _languageNames = _localeStrings.general[locale].languageNames; - _scriptNames = _localeStrings.general[locale].scriptNames; - _usesMetric = _localeCode.slice(-3).toLowerCase() !== '-us'; - } - /* Locales */ - // Returns a Promise to load the strings for the requested locale + function trimmedEndIndex(string) { + var index = string.length; + while (index-- && reWhitespace.test(string.charAt(index))) {} - localizer.loadLocale = function (locale, scopeId, directory) { - // US English is the default - if (locale.toLowerCase() === 'en-us') locale = 'en'; + return index; + } - if (_localeStrings[scopeId] && _localeStrings[scopeId][locale]) { - // already loaded - return Promise.resolve(locale); - } + /** Used to match leading whitespace. */ - var fileMap = _mainFileFetcher.fileMap(); - var key = "locale_".concat(scopeId, "_").concat(locale); + var reTrimStart = /^\s+/; + /** + * The base implementation of `_.trim`. + * + * @private + * @param {string} string The string to trim. + * @returns {string} Returns the trimmed string. + */ - if (!fileMap[key]) { - fileMap[key] = "".concat(directory, "/").concat(locale, ".min.json"); - } + function baseTrim(string) { + return string ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, '') : string; + } - return _mainFileFetcher.get(key).then(function (d) { - if (!_localeStrings[scopeId]) _localeStrings[scopeId] = {}; - _localeStrings[scopeId][locale] = d[locale]; - return locale; - }); - }; + /** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ + function isObject$2(value) { + var type = _typeof(value); - localizer.pluralRule = function (number) { - return pluralRule(number, _localeCode); - }; // Returns the plural rule for the given `number` with the given `localeCode`. - // One of: `zero`, `one`, `two`, `few`, `many`, `other` + return value != null && (type == 'object' || type == 'function'); + } + /** Used as references for various `Number` constants. */ - function pluralRule(number, localeCode) { - // modern browsers have this functionality built-in - var rules = 'Intl' in window && Intl.PluralRules && new Intl.PluralRules(localeCode); + var NAN = 0 / 0; + /** Used to detect bad signed hexadecimal string values. */ - if (rules) { - return rules.select(number); - } // fallback to basic one/other, as in English + var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; + /** Used to detect binary string values. */ + var reIsBinary = /^0b[01]+$/i; + /** Used to detect octal string values. */ - if (number === 1) return 'one'; - return 'other'; + var reIsOctal = /^0o[0-7]+$/i; + /** Built-in method references without a dependency on `root`. */ + + var freeParseInt = parseInt; + /** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3.2); + * // => 3.2 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3.2'); + * // => 3.2 + */ + + function toNumber(value) { + if (typeof value == 'number') { + return value; } - /** - * Try to find that string in `locale` or the current `_localeCode` matching - * the given `stringId`. If no string can be found in the requested locale, - * we'll recurse down all the `_localeCodes` until one is found. - * - * @param {string} stringId string identifier - * @param {object?} replacements token replacements and default string - * @param {string?} locale locale to use (defaults to currentLocale) - * @return {string?} localized string - */ + if (isSymbol(value)) { + return NAN; + } - localizer.tInfo = function (origStringId, replacements, locale) { - var stringId = origStringId.trim(); - var scopeId = 'general'; + if (isObject$2(value)) { + var other = typeof value.valueOf == 'function' ? value.valueOf() : value; + value = isObject$2(other) ? other + '' : other; + } - if (stringId[0] === '_') { - var split = stringId.split('.'); - scopeId = split[0].slice(1); - stringId = split.slice(1).join('.'); - } + if (typeof value != 'string') { + return value === 0 ? value : +value; + } - locale = locale || _localeCode; - var path = stringId.split('.').map(function (s) { - return s.replace(//g, '.'); - }).reverse(); - var stringsKey = locale; // US English is the default + value = baseTrim(value); + var isBinary = reIsBinary.test(value); + return isBinary || reIsOctal.test(value) ? freeParseInt(value.slice(2), isBinary ? 2 : 8) : reIsBadHex.test(value) ? NAN : +value; + } - if (stringsKey.toLowerCase() === 'en-us') stringsKey = 'en'; - var result = _localeStrings && _localeStrings[scopeId] && _localeStrings[scopeId][stringsKey]; + /** + * Converts `value` to a string. An empty string is returned for `null` + * and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ - while (result !== undefined && path.length) { - result = result[path.pop()]; - } + function toString$3(value) { + return value == null ? '' : baseToString(value); + } - if (result !== undefined) { - if (replacements) { - if (_typeof(result) === 'object' && Object.keys(result).length) { - // If plural forms are provided, dig one level deeper based on the - // first numeric token replacement provided. - var number = Object.values(replacements).find(function (value) { - return typeof value === 'number'; - }); + /** + * The base implementation of `_.propertyOf` without support for deep paths. + * + * @private + * @param {Object} object The object to query. + * @returns {Function} Returns the new accessor function. + */ + function basePropertyOf(object) { + return function (key) { + return object == null ? undefined : object[key]; + }; + } - if (number !== undefined) { - var rule = pluralRule(number, locale); + /** + * Gets the timestamp of the number of milliseconds that have elapsed since + * the Unix epoch (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Date + * @returns {number} Returns the timestamp. + * @example + * + * _.defer(function(stamp) { + * console.log(_.now() - stamp); + * }, _.now()); + * // => Logs the number of milliseconds it took for the deferred invocation. + */ - if (result[rule]) { - result = result[rule]; - } else { - // We're pretty sure this should be a plural but no string - // could be found for the given rule. Just pick the first - // string and hope it makes sense. - result = Object.values(result)[0]; - } - } - } + var now = function now() { + return root.Date.now(); + }; - if (typeof result === 'string') { - for (var key in replacements) { - var value = replacements[key]; + /** Error message constants. */ - if (typeof value === 'number') { - if (value.toLocaleString) { - // format numbers for the locale - value = value.toLocaleString(locale, { - style: 'decimal', - useGrouping: true, - minimumFractionDigits: 0 - }); - } else { - value = value.toString(); - } - } + var FUNC_ERROR_TEXT$1 = 'Expected a function'; + /* Built-in method references for those with the same name as other `lodash` methods. */ - var token = "{".concat(key, "}"); - var regex = new RegExp(token, 'g'); - result = result.replace(regex, value); - } - } - } + var nativeMax = Math.max, + nativeMin = Math.min; + /** + * Creates a debounced function that delays invoking `func` until after `wait` + * milliseconds have elapsed since the last time the debounced function was + * invoked. The debounced function comes with a `cancel` method to cancel + * delayed `func` invocations and a `flush` method to immediately invoke them. + * Provide `options` to indicate whether `func` should be invoked on the + * leading and/or trailing edge of the `wait` timeout. The `func` is invoked + * with the last arguments provided to the debounced function. Subsequent + * calls to the debounced function return the result of the last `func` + * invocation. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is + * invoked on the trailing edge of the timeout only if the debounced function + * is invoked more than once during the `wait` timeout. + * + * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred + * until to the next tick, similar to `setTimeout` with a timeout of `0`. + * + * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) + * for details over the differences between `_.debounce` and `_.throttle`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to debounce. + * @param {number} [wait=0] The number of milliseconds to delay. + * @param {Object} [options={}] The options object. + * @param {boolean} [options.leading=false] + * Specify invoking on the leading edge of the timeout. + * @param {number} [options.maxWait] + * The maximum time `func` is allowed to be delayed before it's invoked. + * @param {boolean} [options.trailing=true] + * Specify invoking on the trailing edge of the timeout. + * @returns {Function} Returns the new debounced function. + * @example + * + * // Avoid costly calculations while the window size is in flux. + * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); + * + * // Invoke `sendMail` when clicked, debouncing subsequent calls. + * jQuery(element).on('click', _.debounce(sendMail, 300, { + * 'leading': true, + * 'trailing': false + * })); + * + * // Ensure `batchLog` is invoked once after 1 second of debounced calls. + * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 }); + * var source = new EventSource('/stream'); + * jQuery(source).on('message', debounced); + * + * // Cancel the trailing debounced invocation. + * jQuery(window).on('popstate', debounced.cancel); + */ - if (typeof result === 'string') { - // found a localized string! - return { - text: result, - locale: locale - }; - } - } // no localized string found... - // attempt to fallback to a lower-priority language + function debounce(func, wait, options) { + var lastArgs, + lastThis, + maxWait, + result, + timerId, + lastCallTime, + lastInvokeTime = 0, + leading = false, + maxing = false, + trailing = true; + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT$1); + } - var index = _localeCodes.indexOf(locale); + wait = toNumber(wait) || 0; - if (index >= 0 && index < _localeCodes.length - 1) { - // eventually this will be 'en' or another locale with 100% coverage - var fallback = _localeCodes[index + 1]; - return localizer.tInfo(origStringId, replacements, fallback); - } + if (isObject$2(options)) { + leading = !!options.leading; + maxing = 'maxWait' in options; + maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait; + trailing = 'trailing' in options ? !!options.trailing : trailing; + } - if (replacements && 'default' in replacements) { - // Fallback to a default value if one is specified in `replacements` - return { - text: replacements["default"], - locale: null - }; - } + function invokeFunc(time) { + var args = lastArgs, + thisArg = lastThis; + lastArgs = lastThis = undefined; + lastInvokeTime = time; + result = func.apply(thisArg, args); + return result; + } - var missing = "Missing ".concat(locale, " translation: ").concat(origStringId); - if (typeof console !== 'undefined') console.error(missing); // eslint-disable-line + function leadingEdge(time) { + // Reset any `maxWait` timer. + lastInvokeTime = time; // Start the timer for the trailing edge. - return { - text: missing, - locale: 'en' - }; - }; + timerId = setTimeout(timerExpired, wait); // Invoke the leading edge. - localizer.hasTextForStringId = function (stringId) { - return !!localizer.tInfo(stringId, { - "default": 'nothing found' - }).locale; - }; // Returns only the localized text, discarding the locale info + return leading ? invokeFunc(time) : result; + } + function remainingWait(time) { + var timeSinceLastCall = time - lastCallTime, + timeSinceLastInvoke = time - lastInvokeTime, + timeWaiting = wait - timeSinceLastCall; + return maxing ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke) : timeWaiting; + } - localizer.t = function (stringId, replacements, locale) { - return localizer.tInfo(stringId, replacements, locale).text; - }; // Returns the localized text wrapped in an HTML element encoding the locale info + function shouldInvoke(time) { + var timeSinceLastCall = time - lastCallTime, + timeSinceLastInvoke = time - lastInvokeTime; // Either this is the first call, activity has stopped and we're at the + // trailing edge, the system time has gone backwards and we're treating + // it as the trailing edge, or we've hit the `maxWait` limit. + return lastCallTime === undefined || timeSinceLastCall >= wait || timeSinceLastCall < 0 || maxing && timeSinceLastInvoke >= maxWait; + } - localizer.t.html = function (stringId, replacements, locale) { - var info = localizer.tInfo(stringId, replacements, locale); // text may be empty or undefined if `replacements.default` is + function timerExpired() { + var time = now(); - return info.text ? localizer.htmlForLocalizedText(info.text, info.locale) : ''; - }; + if (shouldInvoke(time)) { + return trailingEdge(time); + } // Restart the timer. - localizer.htmlForLocalizedText = function (text, localeCode) { - return "").concat(text, ""); - }; - localizer.languageName = function (code, options) { - if (_languageNames[code]) { - // name in locale language - // e.g. "German" - return _languageNames[code]; - } // sometimes we only want the local name + timerId = setTimeout(timerExpired, remainingWait(time)); + } + function trailingEdge(time) { + timerId = undefined; // Only invoke if we have `lastArgs` which means `func` has been + // debounced at least once. - if (options && options.localOnly) return null; - var langInfo = _dataLanguages[code]; + if (trailing && lastArgs) { + return invokeFunc(time); + } - if (langInfo) { - if (langInfo.nativeName) { - // name in native language - // e.g. "Deutsch (de)" - return localizer.t('translate.language_and_code', { - language: langInfo.nativeName, - code: code - }); - } else if (langInfo.base && langInfo.script) { - var base = langInfo.base; // the code of the language this is based on + lastArgs = lastThis = undefined; + return result; + } - if (_languageNames[base]) { - // base language name in locale language - var scriptCode = langInfo.script; - var script = _scriptNames[scriptCode] || scriptCode; // e.g. "Serbian (Cyrillic)" + function cancel() { + if (timerId !== undefined) { + clearTimeout(timerId); + } - return localizer.t('translate.language_and_code', { - language: _languageNames[base], - code: script - }); - } else if (_dataLanguages[base] && _dataLanguages[base].nativeName) { - // e.g. "српски (sr-Cyrl)" - return localizer.t('translate.language_and_code', { - language: _dataLanguages[base].nativeName, - code: code - }); - } + lastInvokeTime = 0; + lastArgs = lastCallTime = lastThis = timerId = undefined; + } + + function flush() { + return timerId === undefined ? result : trailingEdge(now()); + } + + function debounced() { + var time = now(), + isInvoking = shouldInvoke(time); + lastArgs = arguments; + lastThis = this; + lastCallTime = time; + + if (isInvoking) { + if (timerId === undefined) { + return leadingEdge(lastCallTime); + } + + if (maxing) { + // Handle invocations in a tight loop. + clearTimeout(timerId); + timerId = setTimeout(timerExpired, wait); + return invokeFunc(lastCallTime); } } - return code; // if not found, use the code - }; + if (timerId === undefined) { + timerId = setTimeout(timerExpired, wait); + } - return localizer; + return result; + } + + debounced.cancel = cancel; + debounced.flush = flush; + return debounced; } - // `presetCollection` is a wrapper around an `Array` of presets `collection`, - // and decorated with some extra methods for searching and matching geometry - // + /** Used to map characters to HTML entities. */ - function presetCollection(collection) { - var MAXRESULTS = 50; - var _this = {}; - var _memo = {}; - _this.collection = collection; + var htmlEscapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''' + }; + /** + * Used by `_.escape` to convert characters to HTML entities. + * + * @private + * @param {string} chr The matched character to escape. + * @returns {string} Returns the escaped character. + */ - _this.item = function (id) { - if (_memo[id]) return _memo[id]; + var escapeHtmlChar = basePropertyOf(htmlEscapes); - var found = _this.collection.find(function (d) { - return d.id === id; - }); + /** Used to match HTML entities and HTML characters. */ - if (found) _memo[id] = found; - return found; - }; + var reUnescapedHtml = /[&<>"']/g, + reHasUnescapedHtml = RegExp(reUnescapedHtml.source); + /** + * Converts the characters "&", "<", ">", '"', and "'" in `string` to their + * corresponding HTML entities. + * + * **Note:** No other characters are escaped. To escape additional + * characters use a third-party library like [_he_](https://mths.be/he). + * + * Though the ">" character is escaped for symmetry, characters like + * ">" and "/" don't need escaping in HTML and have no special meaning + * unless they're part of a tag or unquoted attribute value. See + * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands) + * (under "semi-related fun fact") for more details. + * + * When working with HTML you should always + * [quote attribute values](http://wonko.com/post/html-escaping) to reduce + * XSS vectors. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escape('fred, barney, & pebbles'); + * // => 'fred, barney, & pebbles' + */ - _this.index = function (id) { - return _this.collection.findIndex(function (d) { - return d.id === id; - }); - }; + function escape$4(string) { + string = toString$3(string); + return string && reHasUnescapedHtml.test(string) ? string.replace(reUnescapedHtml, escapeHtmlChar) : string; + } - _this.matchGeometry = function (geometry) { - return presetCollection(_this.collection.filter(function (d) { - return d.matchGeometry(geometry); - })); - }; + /** Error message constants. */ - _this.matchAllGeometry = function (geometries) { - return presetCollection(_this.collection.filter(function (d) { - return d && d.matchAllGeometry(geometries); - })); - }; + var FUNC_ERROR_TEXT = 'Expected a function'; + /** + * Creates a throttled function that only invokes `func` at most once per + * every `wait` milliseconds. The throttled function comes with a `cancel` + * method to cancel delayed `func` invocations and a `flush` method to + * immediately invoke them. Provide `options` to indicate whether `func` + * should be invoked on the leading and/or trailing edge of the `wait` + * timeout. The `func` is invoked with the last arguments provided to the + * throttled function. Subsequent calls to the throttled function return the + * result of the last `func` invocation. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is + * invoked on the trailing edge of the timeout only if the throttled function + * is invoked more than once during the `wait` timeout. + * + * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred + * until to the next tick, similar to `setTimeout` with a timeout of `0`. + * + * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) + * for details over the differences between `_.throttle` and `_.debounce`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to throttle. + * @param {number} [wait=0] The number of milliseconds to throttle invocations to. + * @param {Object} [options={}] The options object. + * @param {boolean} [options.leading=true] + * Specify invoking on the leading edge of the timeout. + * @param {boolean} [options.trailing=true] + * Specify invoking on the trailing edge of the timeout. + * @returns {Function} Returns the new throttled function. + * @example + * + * // Avoid excessively updating the position while scrolling. + * jQuery(window).on('scroll', _.throttle(updatePosition, 100)); + * + * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes. + * var throttled = _.throttle(renewToken, 300000, { 'trailing': false }); + * jQuery(element).on('click', throttled); + * + * // Cancel the trailing throttled invocation. + * jQuery(window).on('popstate', throttled.cancel); + */ - _this.matchAnyGeometry = function (geometries) { - return presetCollection(_this.collection.filter(function (d) { - return geometries.some(function (geom) { - return d.matchGeometry(geom); - }); - })); - }; + function throttle(func, wait, options) { + var leading = true, + trailing = true; - _this.fallback = function (geometry) { - var id = geometry; - if (id === 'vertex') id = 'point'; - return _this.item(id); - }; + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } - _this.search = function (value, geometry, loc) { - if (!value) return _this; // don't remove diacritical characters since we're assuming the user is being intentional + if (isObject$2(options)) { + leading = 'leading' in options ? !!options.leading : leading; + trailing = 'trailing' in options ? !!options.trailing : trailing; + } - value = value.toLowerCase().trim(); // match at name beginning or just after a space (e.g. "office" -> match "Law Office") + return debounce(func, wait, { + 'leading': leading, + 'maxWait': wait, + 'trailing': trailing + }); + } - function leading(a) { - var index = a.indexOf(value); - return index === 0 || a[index - 1] === ' '; - } // match at name beginning only + var $$f = _export; + var lastIndexOf = arrayLastIndexOf; + // `Array.prototype.lastIndexOf` method + // https://tc39.es/ecma262/#sec-array.prototype.lastindexof + // eslint-disable-next-line es/no-array-prototype-lastindexof -- required for testing + $$f({ target: 'Array', proto: true, forced: lastIndexOf !== [].lastIndexOf }, { + lastIndexOf: lastIndexOf + }); - function leadingStrict(a) { - var index = a.indexOf(value); - return index === 0; - } + var global$4 = global$1m; + var isArray = isArray$8; + var lengthOfArrayLike$1 = lengthOfArrayLike$g; + var bind$3 = functionBindContext; - function sortPresets(nameProp) { - return function sortNames(a, b) { - var aCompare = a[nameProp](); - var bCompare = b[nameProp](); // priority if search string matches preset name exactly - #4325 + var TypeError$2 = global$4.TypeError; - if (value === aCompare) return -1; - if (value === bCompare) return 1; // priority for higher matchScore + // `FlattenIntoArray` abstract operation + // https://tc39.github.io/proposal-flatMap/#sec-FlattenIntoArray + var flattenIntoArray$1 = function (target, original, source, sourceLen, start, depth, mapper, thisArg) { + var targetIndex = start; + var sourceIndex = 0; + var mapFn = mapper ? bind$3(mapper, thisArg) : false; + var element, elementLen; - var i = b.originalScore - a.originalScore; - if (i !== 0) return i; // priority if search string appears earlier in preset name + while (sourceIndex < sourceLen) { + if (sourceIndex in source) { + element = mapFn ? mapFn(source[sourceIndex], sourceIndex, original) : source[sourceIndex]; - i = aCompare.indexOf(value) - bCompare.indexOf(value); - if (i !== 0) return i; // priority for shorter preset names + if (depth > 0 && isArray(element)) { + elementLen = lengthOfArrayLike$1(element); + targetIndex = flattenIntoArray$1(target, original, element, elementLen, targetIndex, depth - 1) - 1; + } else { + if (targetIndex >= 0x1FFFFFFFFFFFFF) throw TypeError$2('Exceed the acceptable array length'); + target[targetIndex] = element; + } - return aCompare.length - bCompare.length; - }; + targetIndex++; } + sourceIndex++; + } + return targetIndex; + }; - var pool = _this.collection; - - if (Array.isArray(loc)) { - var validLocations = _mainLocations.locationsAt(loc); - pool = pool.filter(function (a) { - return !a.locationSetID || validLocations[a.locationSetID]; - }); - } + var flattenIntoArray_1 = flattenIntoArray$1; - var searchable = pool.filter(function (a) { - return a.searchable !== false && a.suggestion !== true; - }); - var suggestions = pool.filter(function (a) { - return a.suggestion === true; - }); // matches value to preset.name + var $$e = _export; + var flattenIntoArray = flattenIntoArray_1; + var aCallable = aCallable$a; + var toObject = toObject$j; + var lengthOfArrayLike = lengthOfArrayLike$g; + var arraySpeciesCreate = arraySpeciesCreate$4; + + // `Array.prototype.flatMap` method + // https://tc39.es/ecma262/#sec-array.prototype.flatmap + $$e({ target: 'Array', proto: true }, { + flatMap: function flatMap(callbackfn /* , thisArg */) { + var O = toObject(this); + var sourceLen = lengthOfArrayLike(O); + var A; + aCallable(callbackfn); + A = arraySpeciesCreate(O, 0); + A.length = flattenIntoArray(A, O, O, sourceLen, 0, 1, callbackfn, arguments.length > 1 ? arguments[1] : undefined); + return A; + } + }); - var leadingNames = searchable.filter(function (a) { - return leading(a.searchName()); - }).sort(sortPresets('searchName')); // matches value to preset suggestion name + // this method was added to unscopables after implementation + // in popular engines, so it's moved to a separate module + var addToUnscopables = addToUnscopables$6; - var leadingSuggestions = suggestions.filter(function (a) { - return leadingStrict(a.searchName()); - }).sort(sortPresets('searchName')); - var leadingNamesStripped = searchable.filter(function (a) { - return leading(a.searchNameStripped()); - }).sort(sortPresets('searchNameStripped')); - var leadingSuggestionsStripped = suggestions.filter(function (a) { - return leadingStrict(a.searchNameStripped()); - }).sort(sortPresets('searchNameStripped')); // matches value to preset.terms values + // https://tc39.es/ecma262/#sec-array.prototype-@@unscopables + addToUnscopables('flatMap'); - var leadingTerms = searchable.filter(function (a) { - return (a.terms() || []).some(leading); - }); - var leadingSuggestionTerms = suggestions.filter(function (a) { - return (a.terms() || []).some(leading); - }); // matches value to preset.tags values + var $$d = _export; + var uncurryThis$6 = functionUncurryThis; + var getOwnPropertyDescriptor$1 = objectGetOwnPropertyDescriptor.f; + var toLength$2 = toLength$c; + var toString$2 = toString$k; + var notARegExp$1 = notARegexp; + var requireObjectCoercible$2 = requireObjectCoercible$e; + var correctIsRegExpLogic$1 = correctIsRegexpLogic; - var leadingTagValues = searchable.filter(function (a) { - return Object.values(a.tags || {}).filter(function (val) { - return val !== '*'; - }).some(leading); - }); // finds close matches to value in preset.name + // eslint-disable-next-line es/no-string-prototype-endswith -- safe + var un$EndsWith = uncurryThis$6(''.endsWith); + var slice$2 = uncurryThis$6(''.slice); + var min$1 = Math.min; - var similarName = searchable.map(function (a) { - return { - preset: a, - dist: utilEditDistance(value, a.searchName()) - }; - }).filter(function (a) { - return a.dist + Math.min(value.length - a.preset.searchName().length, 0) < 3; - }).sort(function (a, b) { - return a.dist - b.dist; - }).map(function (a) { - return a.preset; - }); // finds close matches to value to preset suggestion name + var CORRECT_IS_REGEXP_LOGIC$1 = correctIsRegExpLogic$1('endsWith'); + // https://github.com/zloirock/core-js/pull/702 + var MDN_POLYFILL_BUG$1 = !CORRECT_IS_REGEXP_LOGIC$1 && !!function () { + var descriptor = getOwnPropertyDescriptor$1(String.prototype, 'endsWith'); + return descriptor && !descriptor.writable; + }(); - var similarSuggestions = suggestions.map(function (a) { - return { - preset: a, - dist: utilEditDistance(value, a.searchName()) - }; - }).filter(function (a) { - return a.dist + Math.min(value.length - a.preset.searchName().length, 0) < 1; - }).sort(function (a, b) { - return a.dist - b.dist; - }).map(function (a) { - return a.preset; - }); // finds close matches to value in preset.terms + // `String.prototype.endsWith` method + // https://tc39.es/ecma262/#sec-string.prototype.endswith + $$d({ target: 'String', proto: true, forced: !MDN_POLYFILL_BUG$1 && !CORRECT_IS_REGEXP_LOGIC$1 }, { + endsWith: function endsWith(searchString /* , endPosition = @length */) { + var that = toString$2(requireObjectCoercible$2(this)); + notARegExp$1(searchString); + var endPosition = arguments.length > 1 ? arguments[1] : undefined; + var len = that.length; + var end = endPosition === undefined ? len : min$1(toLength$2(endPosition), len); + var search = toString$2(searchString); + return un$EndsWith + ? un$EndsWith(that, search, end) + : slice$2(that, end - search.length, end) === search; + } + }); - var similarTerms = searchable.filter(function (a) { - return (a.terms() || []).some(function (b) { - return utilEditDistance(value, b) + Math.min(value.length - b.length, 0) < 3; - }); - }); - var results = leadingNames.concat(leadingSuggestions, leadingNamesStripped, leadingSuggestionsStripped, leadingTerms, leadingSuggestionTerms, leadingTagValues, similarName, similarSuggestions, similarTerms).slice(0, MAXRESULTS - 1); + // https://github.com/tc39/proposal-string-pad-start-end + var uncurryThis$5 = functionUncurryThis; + var toLength$1 = toLength$c; + var toString$1 = toString$k; + var $repeat = stringRepeat; + var requireObjectCoercible$1 = requireObjectCoercible$e; - if (geometry) { - if (typeof geometry === 'string') { - results.push(_this.fallback(geometry)); - } else { - geometry.forEach(function (geom) { - return results.push(_this.fallback(geom)); - }); - } - } + var repeat$1 = uncurryThis$5($repeat); + var stringSlice$2 = uncurryThis$5(''.slice); + var ceil = Math.ceil; - return presetCollection(utilArrayUniq(results)); + // `String.prototype.{ padStart, padEnd }` methods implementation + var createMethod = function (IS_END) { + return function ($this, maxLength, fillString) { + var S = toString$1(requireObjectCoercible$1($this)); + var intMaxLength = toLength$1(maxLength); + var stringLength = S.length; + var fillStr = fillString === undefined ? ' ' : toString$1(fillString); + var fillLen, stringFiller; + if (intMaxLength <= stringLength || fillStr == '') return S; + fillLen = intMaxLength - stringLength; + stringFiller = repeat$1(fillStr, ceil(fillLen / fillStr.length)); + if (stringFiller.length > fillLen) stringFiller = stringSlice$2(stringFiller, 0, fillLen); + return IS_END ? S + stringFiller : stringFiller + S; }; + }; - return _this; - } - - // `presetCategory` builds a `presetCollection` of member presets, - // decorated with some extra methods for searching and matching geometry - // + var stringPad = { + // `String.prototype.padStart` method + // https://tc39.es/ecma262/#sec-string.prototype.padstart + start: createMethod(false), + // `String.prototype.padEnd` method + // https://tc39.es/ecma262/#sec-string.prototype.padend + end: createMethod(true) + }; - function presetCategory(categoryID, category, allPresets) { - var _this = Object.assign({}, category); // shallow copy + // https://github.com/zloirock/core-js/issues/280 + var userAgent = engineUserAgent; + var stringPadWebkitBug = /Version\/10(?:\.\d+){1,2}(?: [\w./]+)?(?: Mobile\/\w+)? Safari\//.test(userAgent); - var _searchName; // cache + var $$c = _export; + var $padEnd = stringPad.end; + var WEBKIT_BUG$1 = stringPadWebkitBug; + // `String.prototype.padEnd` method + // https://tc39.es/ecma262/#sec-string.prototype.padend + $$c({ target: 'String', proto: true, forced: WEBKIT_BUG$1 }, { + padEnd: function padEnd(maxLength /* , fillString = ' ' */) { + return $padEnd(this, maxLength, arguments.length > 1 ? arguments[1] : undefined); + } + }); - var _searchNameStripped; // cache + var $$b = _export; + var $padStart = stringPad.start; + var WEBKIT_BUG = stringPadWebkitBug; + // `String.prototype.padStart` method + // https://tc39.es/ecma262/#sec-string.prototype.padstart + $$b({ target: 'String', proto: true, forced: WEBKIT_BUG }, { + padStart: function padStart(maxLength /* , fillString = ' ' */) { + return $padStart(this, maxLength, arguments.length > 1 ? arguments[1] : undefined); + } + }); - _this.id = categoryID; - _this.members = presetCollection((category.members || []).map(function (presetID) { - return allPresets[presetID]; - }).filter(Boolean)); - _this.geometry = _this.members.collection.reduce(function (acc, preset) { - for (var i in preset.geometry) { - var geometry = preset.geometry[i]; + var $$a = _export; + var $reduceRight = arrayReduce.right; + var arrayMethodIsStrict = arrayMethodIsStrict$9; + var CHROME_VERSION = engineV8Version; + var IS_NODE = engineIsNode; - if (acc.indexOf(geometry) === -1) { - acc.push(geometry); - } - } + var STRICT_METHOD = arrayMethodIsStrict('reduceRight'); + // Chrome 80-82 has a critical bug + // https://bugs.chromium.org/p/chromium/issues/detail?id=1049982 + var CHROME_BUG = !IS_NODE && CHROME_VERSION > 79 && CHROME_VERSION < 83; - return acc; - }, []); + // `Array.prototype.reduceRight` method + // https://tc39.es/ecma262/#sec-array.prototype.reduceright + $$a({ target: 'Array', proto: true, forced: !STRICT_METHOD || CHROME_BUG }, { + reduceRight: function reduceRight(callbackfn /* , initialValue */) { + return $reduceRight(this, callbackfn, arguments.length, arguments.length > 1 ? arguments[1] : undefined); + } + }); - _this.matchGeometry = function (geom) { - return _this.geometry.indexOf(geom) >= 0; - }; + var $$9 = _export; + var repeat = stringRepeat; - _this.matchAllGeometry = function (geometries) { - return _this.members.collection.some(function (preset) { - return preset.matchAllGeometry(geometries); - }); - }; + // `String.prototype.repeat` method + // https://tc39.es/ecma262/#sec-string.prototype.repeat + $$9({ target: 'String', proto: true }, { + repeat: repeat + }); - _this.matchScore = function () { - return -1; - }; + var $$8 = _export; + var uncurryThis$4 = functionUncurryThis; + var getOwnPropertyDescriptor = objectGetOwnPropertyDescriptor.f; + var toLength = toLength$c; + var toString = toString$k; + var notARegExp = notARegexp; + var requireObjectCoercible = requireObjectCoercible$e; + var correctIsRegExpLogic = correctIsRegexpLogic; - _this.name = function () { - return _t("_tagging.presets.categories.".concat(categoryID, ".name"), { - 'default': categoryID - }); - }; + // eslint-disable-next-line es/no-string-prototype-startswith -- safe + var un$StartsWith = uncurryThis$4(''.startsWith); + var stringSlice$1 = uncurryThis$4(''.slice); + var min = Math.min; - _this.nameLabel = function () { - return _t.html("_tagging.presets.categories.".concat(categoryID, ".name"), { - 'default': categoryID - }); - }; + var CORRECT_IS_REGEXP_LOGIC = correctIsRegExpLogic('startsWith'); + // https://github.com/zloirock/core-js/pull/702 + var MDN_POLYFILL_BUG = !CORRECT_IS_REGEXP_LOGIC && !!function () { + var descriptor = getOwnPropertyDescriptor(String.prototype, 'startsWith'); + return descriptor && !descriptor.writable; + }(); - _this.terms = function () { - return []; - }; + // `String.prototype.startsWith` method + // https://tc39.es/ecma262/#sec-string.prototype.startswith + $$8({ target: 'String', proto: true, forced: !MDN_POLYFILL_BUG && !CORRECT_IS_REGEXP_LOGIC }, { + startsWith: function startsWith(searchString /* , position = 0 */) { + var that = toString(requireObjectCoercible(this)); + notARegExp(searchString); + var index = toLength(min(arguments.length > 1 ? arguments[1] : undefined, that.length)); + var search = toString(searchString); + return un$StartsWith + ? un$StartsWith(that, search, index) + : stringSlice$1(that, index, index + search.length) === search; + } + }); - _this.searchName = function () { - if (!_searchName) { - _searchName = (_this.suggestion ? _this.originalName : _this.name()).toLowerCase(); - } + var $$7 = _export; + var $trimEnd = stringTrim.end; + var forcedStringTrimMethod$1 = stringTrimForced; + + var FORCED$4 = forcedStringTrimMethod$1('trimEnd'); + + var trimEnd = FORCED$4 ? function trimEnd() { + return $trimEnd(this); + // eslint-disable-next-line es/no-string-prototype-trimstart-trimend -- safe + } : ''.trimEnd; + + // `String.prototype.{ trimEnd, trimRight }` methods + // https://tc39.es/ecma262/#sec-string.prototype.trimend + // https://tc39.es/ecma262/#String.prototype.trimright + $$7({ target: 'String', proto: true, name: 'trimEnd', forced: FORCED$4 }, { + trimEnd: trimEnd, + trimRight: trimEnd + }); - return _searchName; - }; + var $$6 = _export; + var $trimStart = stringTrim.start; + var forcedStringTrimMethod = stringTrimForced; - _this.searchNameStripped = function () { - if (!_searchNameStripped) { - _searchNameStripped = _this.searchName(); // split combined diacritical characters into their parts + var FORCED$3 = forcedStringTrimMethod('trimStart'); - if (_searchNameStripped.normalize) _searchNameStripped = _searchNameStripped.normalize('NFD'); // remove diacritics + var trimStart = FORCED$3 ? function trimStart() { + return $trimStart(this); + // eslint-disable-next-line es/no-string-prototype-trimstart-trimend -- safe + } : ''.trimStart; - _searchNameStripped = _searchNameStripped.replace(/[\u0300-\u036f]/g, ''); - } + // `String.prototype.{ trimStart, trimLeft }` methods + // https://tc39.es/ecma262/#sec-string.prototype.trimstart + // https://tc39.es/ecma262/#String.prototype.trimleft + $$6({ target: 'String', proto: true, name: 'trimStart', forced: FORCED$3 }, { + trimStart: trimStart, + trimLeft: trimStart + }); - return _searchNameStripped; - }; + var _mainLocalizer = coreLocalizer(); // singleton - return _this; - } - // `presetField` decorates a given `field` Object - // with some extra methods for searching and matching geometry + var _t = _mainLocalizer.t; + // coreLocalizer manages language and locale parameters including translated strings // - function presetField(fieldID, field) { - var _this = Object.assign({}, field); // shallow copy + function coreLocalizer() { + var localizer = {}; + var _dataLanguages = {}; // `_dataLocales` is an object containing all _supported_ locale codes -> language info. + // * `rtl` - right-to-left or left-to-right text direction + // * `pct` - the percent of strings translated; 1 = 100%, full coverage + // + // { + // en: { rtl: false, pct: {…} }, + // de: { rtl: false, pct: {…} }, + // … + // } + var _dataLocales = {}; // `localeStrings` is an object containing all _loaded_ locale codes -> string data. + // { + // en: { icons: {…}, toolbar: {…}, modes: {…}, operations: {…}, … }, + // de: { icons: {…}, toolbar: {…}, modes: {…}, operations: {…}, … }, + // … + // } - _this.id = fieldID; // for use in classes, element ids, css selectors + var _localeStrings = {}; // the current locale - _this.safeid = utilSafeClassName(fieldID); + var _localeCode = 'en-US'; // `_localeCodes` must contain `_localeCode` first, optionally followed by fallbacks - _this.matchGeometry = function (geom) { - return !_this.geometry || _this.geometry.indexOf(geom) !== -1; - }; + var _localeCodes = ['en-US', 'en']; + var _languageCode = 'en'; + var _textDirection = 'ltr'; + var _usesMetric = false; + var _languageNames = {}; + var _scriptNames = {}; // getters for the current locale parameters - _this.matchAllGeometry = function (geometries) { - return !_this.geometry || geometries.every(function (geom) { - return _this.geometry.indexOf(geom) !== -1; - }); + localizer.localeCode = function () { + return _localeCode; }; - _this.t = function (scope, options) { - return _t("_tagging.presets.fields.".concat(fieldID, ".").concat(scope), options); + localizer.localeCodes = function () { + return _localeCodes; }; - _this.t.html = function (scope, options) { - return _t.html("_tagging.presets.fields.".concat(fieldID, ".").concat(scope), options); + localizer.languageCode = function () { + return _languageCode; }; - _this.hasTextForStringId = function (scope) { - return _mainLocalizer.hasTextForStringId("_tagging.presets.fields.".concat(fieldID, ".").concat(scope)); + localizer.textDirection = function () { + return _textDirection; }; - _this.title = function () { - return _this.overrideLabel || _this.t('label', { - 'default': fieldID - }); + localizer.usesMetric = function () { + return _usesMetric; }; - _this.label = function () { - return _this.overrideLabel || _this.t.html('label', { - 'default': fieldID - }); + localizer.languageNames = function () { + return _languageNames; }; - var _placeholder = _this.placeholder; + localizer.scriptNames = function () { + return _scriptNames; + }; // The client app may want to manually set the locale, regardless of the + // settings provided by the browser - _this.placeholder = function () { - return _this.t('placeholder', { - 'default': _placeholder - }); - }; - _this.originalTerms = (_this.terms || []).join(); + var _preferredLocaleCodes = []; - _this.terms = function () { - return _this.t('terms', { - 'default': _this.originalTerms - }).toLowerCase().trim().split(/\s*,+\s*/); - }; + localizer.preferredLocaleCodes = function (codes) { + if (!arguments.length) return _preferredLocaleCodes; - _this.increment = _this.type === 'number' ? _this.increment || 1 : undefined; - return _this; - } + if (typeof codes === 'string') { + // be generous and accept delimited strings as input + _preferredLocaleCodes = codes.split(/,|;| /gi).filter(Boolean); + } else { + _preferredLocaleCodes = codes; + } - var $$8 = _export; - var lastIndexOf = arrayLastIndexOf; + return localizer; + }; - // `Array.prototype.lastIndexOf` method - // https://tc39.es/ecma262/#sec-array.prototype.lastindexof - // eslint-disable-next-line es/no-array-prototype-lastindexof -- required for testing - $$8({ target: 'Array', proto: true, forced: lastIndexOf !== [].lastIndexOf }, { - lastIndexOf: lastIndexOf - }); + var _loadPromise; - // `presetPreset` decorates a given `preset` Object - // with some extra methods for searching and matching geometry - // + localizer.ensureLoaded = function () { + if (_loadPromise) return _loadPromise; + var filesToFetch = ['languages', // load the list of languages + 'locales' // load the list of supported locales + ]; + var localeDirs = { + general: 'locales', + tagging: 'https://cdn.jsdelivr.net/npm/@openstreetmap/id-tagging-schema@3/dist/translations' + }; + var fileMap = _mainFileFetcher.fileMap(); - function presetPreset(presetID, preset, addable, allFields, allPresets) { - allFields = allFields || {}; - allPresets = allPresets || {}; + for (var scopeId in localeDirs) { + var key = "locales_index_".concat(scopeId); - var _this = Object.assign({}, preset); // shallow copy + if (!fileMap[key]) { + fileMap[key] = localeDirs[scopeId] + '/index.min.json'; + } + filesToFetch.push(key); + } - var _addable = addable || false; + return _loadPromise = Promise.all(filesToFetch.map(function (key) { + return _mainFileFetcher.get(key); + })).then(function (results) { + _dataLanguages = results[0]; + _dataLocales = results[1]; + var indexes = results.slice(2); - var _resolvedFields; // cache + var requestedLocales = (_preferredLocaleCodes || []).concat(utilDetect().browserLocales) // List of locales preferred by the browser in priority order. + .concat(['en']); // fallback to English since it's the only guaranteed complete language - var _resolvedMoreFields; // cache + _localeCodes = localesToUseFrom(requestedLocales); + _localeCode = _localeCodes[0]; // Run iD in the highest-priority locale; the rest are fallbacks + var loadStringsPromises = []; + indexes.forEach(function (index, i) { + // Will always return the index for `en` if nothing else + var fullCoverageIndex = _localeCodes.findIndex(function (locale) { + return index[locale] && index[locale].pct === 1; + }); // We only need to load locales up until we find one with full coverage - var _searchName; // cache + _localeCodes.slice(0, fullCoverageIndex + 1).forEach(function (code) { + var scopeId = Object.keys(localeDirs)[i]; + var directory = Object.values(localeDirs)[i]; + if (index[code]) loadStringsPromises.push(localizer.loadLocale(code, scopeId, directory)); + }); + }); + return Promise.all(loadStringsPromises); + }).then(function () { + updateForCurrentLocale(); + })["catch"](function (err) { + return console.error(err); + }); // eslint-disable-line + }; // Returns the locales from `requestedLocales` supported by iD that we should use - var _searchNameStripped; // cache + function localesToUseFrom(requestedLocales) { + var supportedLocales = _dataLocales; + var toUse = []; - _this.id = presetID; - _this.safeid = utilSafeClassName(presetID); // for use in css classes, selectors, element ids + for (var i in requestedLocales) { + var locale = requestedLocales[i]; + if (supportedLocales[locale]) toUse.push(locale); - _this.originalTerms = (_this.terms || []).join(); - _this.originalName = _this.name || ''; - _this.originalScore = _this.matchScore || 1; - _this.originalReference = _this.reference || {}; - _this.originalFields = _this.fields || []; - _this.originalMoreFields = _this.moreFields || []; - - _this.fields = function () { - return _resolvedFields || (_resolvedFields = resolve('fields')); - }; - - _this.moreFields = function () { - return _resolvedMoreFields || (_resolvedMoreFields = resolve('moreFields')); - }; + if (locale.includes('-')) { + // Full locale ('es-ES'), add fallback to the base ('es') + var langPart = locale.split('-')[0]; + if (supportedLocales[langPart]) toUse.push(langPart); + } + } // remove duplicates - _this.resetFields = function () { - return _resolvedFields = _resolvedMoreFields = null; - }; - _this.tags = _this.tags || {}; - _this.addTags = _this.addTags || _this.tags; - _this.removeTags = _this.removeTags || _this.addTags; - _this.geometry = _this.geometry || []; + return utilArrayUniq(toUse); + } - _this.matchGeometry = function (geom) { - return _this.geometry.indexOf(geom) >= 0; - }; + function updateForCurrentLocale() { + if (!_localeCode) return; + _languageCode = _localeCode.split('-')[0]; + var currentData = _dataLocales[_localeCode] || _dataLocales[_languageCode]; + var hash = utilStringQs(window.location.hash); - _this.matchAllGeometry = function (geoms) { - return geoms.every(_this.matchGeometry); - }; + if (hash.rtl === 'true') { + _textDirection = 'rtl'; + } else if (hash.rtl === 'false') { + _textDirection = 'ltr'; + } else { + _textDirection = currentData && currentData.rtl ? 'rtl' : 'ltr'; + } - _this.matchScore = function (entityTags) { - var tags = _this.tags; - var seen = {}; - var score = 0; // match on tags + var locale = _localeCode; + if (locale.toLowerCase() === 'en-us') locale = 'en'; + _languageNames = _localeStrings.general[locale].languageNames; + _scriptNames = _localeStrings.general[locale].scriptNames; + _usesMetric = _localeCode.slice(-3).toLowerCase() !== '-us'; + } + /* Locales */ + // Returns a Promise to load the strings for the requested locale - for (var k in tags) { - seen[k] = true; - if (entityTags[k] === tags[k]) { - score += _this.originalScore; - } else if (tags[k] === '*' && k in entityTags) { - score += _this.originalScore / 2; - } else { - return -1; - } - } // boost score for additional matches in addTags - #6802 + localizer.loadLocale = function (locale, scopeId, directory) { + // US English is the default + if (locale.toLowerCase() === 'en-us') locale = 'en'; + if (_localeStrings[scopeId] && _localeStrings[scopeId][locale]) { + // already loaded + return Promise.resolve(locale); + } - var addTags = _this.addTags; + var fileMap = _mainFileFetcher.fileMap(); + var key = "locale_".concat(scopeId, "_").concat(locale); - for (var _k in addTags) { - if (!seen[_k] && entityTags[_k] === addTags[_k]) { - score += _this.originalScore; - } + if (!fileMap[key]) { + fileMap[key] = "".concat(directory, "/").concat(locale, ".min.json"); } - return score; + return _mainFileFetcher.get(key).then(function (d) { + if (!_localeStrings[scopeId]) _localeStrings[scopeId] = {}; + _localeStrings[scopeId][locale] = d[locale]; + return locale; + }); }; - _this.t = function (scope, options) { - var textID = "_tagging.presets.presets.".concat(presetID, ".").concat(scope); - return _t(textID, options); - }; + localizer.pluralRule = function (number) { + return pluralRule(number, _localeCode); + }; // Returns the plural rule for the given `number` with the given `localeCode`. + // One of: `zero`, `one`, `two`, `few`, `many`, `other` - _this.t.html = function (scope, options) { - var textID = "_tagging.presets.presets.".concat(presetID, ".").concat(scope); - return _t.html(textID, options); - }; - _this.name = function () { - return _this.t('name', { - 'default': _this.originalName - }); - }; + function pluralRule(number, localeCode) { + // modern browsers have this functionality built-in + var rules = 'Intl' in window && Intl.PluralRules && new Intl.PluralRules(localeCode); - _this.nameLabel = function () { - return _this.t.html('name', { - 'default': _this.originalName - }); - }; + if (rules) { + return rules.select(number); + } // fallback to basic one/other, as in English - _this.subtitle = function () { - if (_this.suggestion) { - var path = presetID.split('/'); - path.pop(); // remove brand name - return _t('_tagging.presets.presets.' + path.join('/') + '.name'); - } + if (number === 1) return 'one'; + return 'other'; + } + /** + * Try to find that string in `locale` or the current `_localeCode` matching + * the given `stringId`. If no string can be found in the requested locale, + * we'll recurse down all the `_localeCodes` until one is found. + * + * @param {string} stringId string identifier + * @param {object?} replacements token replacements and default string + * @param {string?} locale locale to use (defaults to currentLocale) + * @return {string?} localized string + */ - return null; - }; - _this.subtitleLabel = function () { - if (_this.suggestion) { - var path = presetID.split('/'); - path.pop(); // remove brand name + localizer.tInfo = function (origStringId, replacements, locale) { + var stringId = origStringId.trim(); + var scopeId = 'general'; - return _t.html('_tagging.presets.presets.' + path.join('/') + '.name'); + if (stringId[0] === '_') { + var split = stringId.split('.'); + scopeId = split[0].slice(1); + stringId = split.slice(1).join('.'); } - return null; - }; + locale = locale || _localeCode; + var path = stringId.split('.').map(function (s) { + return s.replace(//g, '.'); + }).reverse(); + var stringsKey = locale; // US English is the default - _this.terms = function () { - return _this.t('terms', { - 'default': _this.originalTerms - }).toLowerCase().trim().split(/\s*,+\s*/); - }; + if (stringsKey.toLowerCase() === 'en-us') stringsKey = 'en'; + var result = _localeStrings && _localeStrings[scopeId] && _localeStrings[scopeId][stringsKey]; - _this.searchName = function () { - if (!_searchName) { - _searchName = (_this.suggestion ? _this.originalName : _this.name()).toLowerCase(); + while (result !== undefined && path.length) { + result = result[path.pop()]; } - return _searchName; - }; - - _this.searchNameStripped = function () { - if (!_searchNameStripped) { - _searchNameStripped = _this.searchName(); // split combined diacritical characters into their parts + if (result !== undefined) { + if (replacements) { + if (_typeof(result) === 'object' && Object.keys(result).length) { + // If plural forms are provided, dig one level deeper based on the + // first numeric token replacement provided. + var number = Object.values(replacements).find(function (value) { + return typeof value === 'number'; + }); - if (_searchNameStripped.normalize) _searchNameStripped = _searchNameStripped.normalize('NFD'); // remove diacritics + if (number !== undefined) { + var rule = pluralRule(number, locale); - _searchNameStripped = _searchNameStripped.replace(/[\u0300-\u036f]/g, ''); - } + if (result[rule]) { + result = result[rule]; + } else { + // We're pretty sure this should be a plural but no string + // could be found for the given rule. Just pick the first + // string and hope it makes sense. + result = Object.values(result)[0]; + } + } + } - return _searchNameStripped; - }; + if (typeof result === 'string') { + for (var key in replacements) { + var value = replacements[key]; - _this.isFallback = function () { - var tagCount = Object.keys(_this.tags).length; - return tagCount === 0 || tagCount === 1 && _this.tags.hasOwnProperty('area'); - }; + if (typeof value === 'number') { + if (value.toLocaleString) { + // format numbers for the locale + value = value.toLocaleString(locale, { + style: 'decimal', + useGrouping: true, + minimumFractionDigits: 0 + }); + } else { + value = value.toString(); + } + } - _this.addable = function (val) { - if (!arguments.length) return _addable; - _addable = val; - return _this; - }; + var token = "{".concat(key, "}"); + var regex = new RegExp(token, 'g'); + result = result.replace(regex, value); + } + } + } - _this.reference = function () { - // Lookup documentation on Wikidata... - var qid = _this.tags.wikidata || _this.tags['flag:wikidata'] || _this.tags['brand:wikidata'] || _this.tags['network:wikidata'] || _this.tags['operator:wikidata']; + if (typeof result === 'string') { + // found a localized string! + return { + text: result, + locale: locale + }; + } + } // no localized string found... + // attempt to fallback to a lower-priority language - if (qid) { - return { - qid: qid - }; - } // Lookup documentation on OSM Wikibase... + var index = _localeCodes.indexOf(locale); - var key = _this.originalReference.key || Object.keys(utilObjectOmit(_this.tags, 'name'))[0]; - var value = _this.originalReference.value || _this.tags[key]; + if (index >= 0 && index < _localeCodes.length - 1) { + // eventually this will be 'en' or another locale with 100% coverage + var fallback = _localeCodes[index + 1]; + return localizer.tInfo(origStringId, replacements, fallback); + } - if (value === '*') { - return { - key: key - }; - } else { + if (replacements && 'default' in replacements) { + // Fallback to a default value if one is specified in `replacements` return { - key: key, - value: value + text: replacements["default"], + locale: null }; } - }; - - _this.unsetTags = function (tags, geometry, ignoringKeys, skipFieldDefaults) { - // allow manually keeping some tags - var removeTags = ignoringKeys ? utilObjectOmit(_this.removeTags, ignoringKeys) : _this.removeTags; - tags = utilObjectOmit(tags, Object.keys(removeTags)); - if (geometry && !skipFieldDefaults) { - _this.fields().forEach(function (field) { - if (field.matchGeometry(geometry) && field.key && field["default"] === tags[field.key]) { - delete tags[field.key]; - } - }); - } + var missing = "Missing ".concat(locale, " translation: ").concat(origStringId); + if (typeof console !== 'undefined') console.error(missing); // eslint-disable-line - delete tags.area; - return tags; + return { + text: missing, + locale: 'en' + }; }; - _this.setTags = function (tags, geometry, skipFieldDefaults) { - var addTags = _this.addTags; - tags = Object.assign({}, tags); // shallow copy + localizer.hasTextForStringId = function (stringId) { + return !!localizer.tInfo(stringId, { + "default": 'nothing found' + }).locale; + }; // Returns only the localized text, discarding the locale info - for (var k in addTags) { - if (addTags[k] === '*') { - // if this tag is ancillary, don't override an existing value since any value is okay - if (_this.tags[k] || !tags[k] || tags[k] === 'no') { - tags[k] = 'yes'; - } - } else { - tags[k] = addTags[k]; - } - } // Add area=yes if necessary. - // This is necessary if the geometry is already an area (e.g. user drew an area) AND any of: - // 1. chosen preset could be either an area or a line (`barrier=city_wall`) - // 2. chosen preset doesn't have a key in osmAreaKeys (`railway=station`) + localizer.t = function (stringId, replacements, locale) { + return localizer.tInfo(stringId, replacements, locale).text; + }; // Returns the localized text wrapped in an HTML element encoding the locale info - if (!addTags.hasOwnProperty('area')) { - delete tags.area; + /** + * @deprecated This method is considered deprecated. Instead, use the direct DOM manipulating + * method `t.append`. + */ - if (geometry === 'area') { - var needsAreaTag = true; - if (_this.geometry.indexOf('line') === -1) { - for (var _k2 in addTags) { - if (_k2 in osmAreaKeys) { - needsAreaTag = false; - break; - } - } - } + localizer.t.html = function (stringId, replacements, locale) { + // replacement string might be html unsafe, so we need to escape it except if it is explicitly marked as html code + replacements = Object.assign({}, replacements); - if (needsAreaTag) { - tags.area = 'yes'; - } + for (var k in replacements) { + if (typeof replacements[k] === 'string') { + replacements[k] = escape$4(replacements[k]); } - } - if (geometry && !skipFieldDefaults) { - _this.fields().forEach(function (field) { - if (field.matchGeometry(geometry) && field.key && !tags[field.key] && field["default"]) { - tags[field.key] = field["default"]; - } - }); + if (_typeof(replacements[k]) === 'object' && typeof replacements[k].html === 'string') { + replacements[k] = replacements[k].html; + } } - return tags; - }; // For a preset without fields, use the fields of the parent preset. - // Replace {preset} placeholders with the fields of the specified presets. + var info = localizer.tInfo(stringId, replacements, locale); // text may be empty or undefined if `replacements.default` is + if (info.text) { + return "").concat(info.text, ""); + } else { + return ''; + } + }; // Adds localized text wrapped as an HTML span element with locale info to the DOM - function resolve(which) { - var fieldIDs = which === 'fields' ? _this.originalFields : _this.originalMoreFields; - var resolved = []; - fieldIDs.forEach(function (fieldID) { - var match = fieldID.match(/\{(.*)\}/); - if (match !== null) { - // a presetID wrapped in braces {} - resolved = resolved.concat(inheritFields(match[1], which)); - } else if (allFields[fieldID]) { - // a normal fieldID - resolved.push(allFields[fieldID]); - } else { - console.log("Cannot resolve \"".concat(fieldID, "\" found in ").concat(_this.id, ".").concat(which)); // eslint-disable-line no-console - } - }); // no fields resolved, so use the parent's if possible + localizer.t.append = function (stringId, replacements, locale) { + return function (selection) { + var info = localizer.tInfo(stringId, replacements, locale); + return selection.append('span').attr('class', 'localized-text').attr('lang', info.locale || 'und').text((replacements && replacements.prefix || '') + info.text + (replacements && replacements.suffix || '')); + }; + }; - if (!resolved.length) { - var endIndex = _this.id.lastIndexOf('/'); + localizer.languageName = function (code, options) { + if (_languageNames[code]) { + // name in locale language + // e.g. "German" + return _languageNames[code]; + } // sometimes we only want the local name - var parentID = endIndex && _this.id.substring(0, endIndex); - if (parentID) { - resolved = inheritFields(parentID, which); - } - } + if (options && options.localOnly) return null; + var langInfo = _dataLanguages[code]; - return utilArrayUniq(resolved); // returns an array of fields to inherit from the given presetID, if found + if (langInfo) { + if (langInfo.nativeName) { + // name in native language + // e.g. "Deutsch (de)" + return localizer.t('translate.language_and_code', { + language: langInfo.nativeName, + code: code + }); + } else if (langInfo.base && langInfo.script) { + var base = langInfo.base; // the code of the language this is based on - function inheritFields(presetID, which) { - var parent = allPresets[presetID]; - if (!parent) return []; + if (_languageNames[base]) { + // base language name in locale language + var scriptCode = langInfo.script; + var script = _scriptNames[scriptCode] || scriptCode; // e.g. "Serbian (Cyrillic)" - if (which === 'fields') { - return parent.fields().filter(shouldInherit); - } else if (which === 'moreFields') { - return parent.moreFields(); - } else { - return []; + return localizer.t('translate.language_and_code', { + language: _languageNames[base], + code: script + }); + } else if (_dataLanguages[base] && _dataLanguages[base].nativeName) { + // e.g. "српски (sr-Cyrl)" + return localizer.t('translate.language_and_code', { + language: _dataLanguages[base].nativeName, + code: code + }); + } } - } // Skip `fields` for the keys which define the preset. - // These are usually `typeCombo` fields like `shop=*` - - - function shouldInherit(f) { - if (f.key && _this.tags[f.key] !== undefined && // inherit anyway if multiple values are allowed or just a checkbox - f.type !== 'multiCombo' && f.type !== 'semiCombo' && f.type !== 'manyCombo' && f.type !== 'check') return false; - return true; } - } - return _this; + return code; // if not found, use the code + }; + + return localizer; } - var _mainPresetIndex = presetIndex(); // singleton - // `presetIndex` wraps a `presetCollection` - // with methods for loading new data and returning defaults + // `presetCollection` is a wrapper around an `Array` of presets `collection`, + // and decorated with some extra methods for searching and matching geometry // - function presetIndex() { - var dispatch = dispatch$8('favoritePreset', 'recentsChange'); - var MAXRECENTS = 30; // seed the preset lists with geometry fallbacks + function presetCollection(collection) { + var MAXRESULTS = 50; + var _this = {}; + var _memo = {}; + _this.collection = collection; - var POINT = presetPreset('point', { - name: 'Point', - tags: {}, - geometry: ['point', 'vertex'], - matchScore: 0.1 - }); - var LINE = presetPreset('line', { - name: 'Line', - tags: {}, - geometry: ['line'], - matchScore: 0.1 - }); - var AREA = presetPreset('area', { - name: 'Area', - tags: { - area: 'yes' - }, - geometry: ['area'], - matchScore: 0.1 - }); - var RELATION = presetPreset('relation', { - name: 'Relation', - tags: {}, - geometry: ['relation'], - matchScore: 0.1 - }); + _this.item = function (id) { + if (_memo[id]) return _memo[id]; - var _this = presetCollection([POINT, LINE, AREA, RELATION]); + var found = _this.collection.find(function (d) { + return d.id === id; + }); - var _presets = { - point: POINT, - line: LINE, - area: AREA, - relation: RELATION - }; - var _defaults = { - point: presetCollection([POINT]), - vertex: presetCollection([POINT]), - line: presetCollection([LINE]), - area: presetCollection([AREA]), - relation: presetCollection([RELATION]) + if (found) _memo[id] = found; + return found; }; - var _fields = {}; - var _categories = {}; - var _universal = []; - var _addablePresetIDs = null; // Set of preset IDs that the user can add - - var _recents; - var _favorites; // Index of presets by (geometry, tag key). + _this.index = function (id) { + return _this.collection.findIndex(function (d) { + return d.id === id; + }); + }; + _this.matchGeometry = function (geometry) { + return presetCollection(_this.collection.filter(function (d) { + return d.matchGeometry(geometry); + })); + }; - var _geometryIndex = { - point: {}, - vertex: {}, - line: {}, - area: {}, - relation: {} + _this.matchAllGeometry = function (geometries) { + return presetCollection(_this.collection.filter(function (d) { + return d && d.matchAllGeometry(geometries); + })); }; - var _loadPromise; - - _this.ensureLoaded = function () { - if (_loadPromise) return _loadPromise; - return _loadPromise = Promise.all([_mainFileFetcher.get('preset_categories'), _mainFileFetcher.get('preset_defaults'), _mainFileFetcher.get('preset_presets'), _mainFileFetcher.get('preset_fields')]).then(function (vals) { - _this.merge({ - categories: vals[0], - defaults: vals[1], - presets: vals[2], - fields: vals[3] + _this.matchAnyGeometry = function (geometries) { + return presetCollection(_this.collection.filter(function (d) { + return geometries.some(function (geom) { + return d.matchGeometry(geom); }); + })); + }; - osmSetAreaKeys(_this.areaKeys()); - osmSetPointTags(_this.pointTags()); - osmSetVertexTags(_this.vertexTags()); - }); - }; // `merge` accepts an object containing new preset data (all properties optional): - // { - // fields: {}, - // presets: {}, - // categories: {}, - // defaults: {}, - // featureCollection: {} - //} + _this.fallback = function (geometry) { + var id = geometry; + if (id === 'vertex') id = 'point'; + return _this.item(id); + }; + _this.search = function (value, geometry, loc) { + if (!value) return _this; // don't remove diacritical characters since we're assuming the user is being intentional - _this.merge = function (d) { - var newLocationSets = []; // Merge Fields + value = value.toLowerCase().trim(); // match at name beginning or just after a space (e.g. "office" -> match "Law Office") - if (d.fields) { - Object.keys(d.fields).forEach(function (fieldID) { - var f = d.fields[fieldID]; + function leading(a) { + var index = a.indexOf(value); + return index === 0 || a[index - 1] === ' '; + } // match at name beginning only - if (f) { - // add or replace - f = presetField(fieldID, f); - if (f.locationSet) newLocationSets.push(f); - _fields[fieldID] = f; - } else { - // remove - delete _fields[fieldID]; - } - }); - } // Merge Presets + function leadingStrict(a) { + var index = a.indexOf(value); + return index === 0; + } - if (d.presets) { - Object.keys(d.presets).forEach(function (presetID) { - var p = d.presets[presetID]; + function sortPresets(nameProp) { + return function sortNames(a, b) { + var aCompare = a[nameProp](); + var bCompare = b[nameProp](); // priority if search string matches preset name exactly - #4325 - if (p) { - // add or replace - var isAddable = !_addablePresetIDs || _addablePresetIDs.has(presetID); + if (value === aCompare) return -1; + if (value === bCompare) return 1; // priority for higher matchScore - p = presetPreset(presetID, p, isAddable, _fields, _presets); - if (p.locationSet) newLocationSets.push(p); - _presets[presetID] = p; - } else { - // remove (but not if it's a fallback) - var existing = _presets[presetID]; + var i = b.originalScore - a.originalScore; + if (i !== 0) return i; // priority if search string appears earlier in preset name - if (existing && !existing.isFallback()) { - delete _presets[presetID]; - } - } - }); - } // Merge Categories + i = aCompare.indexOf(value) - bCompare.indexOf(value); + if (i !== 0) return i; // priority for shorter preset names + return aCompare.length - bCompare.length; + }; + } - if (d.categories) { - Object.keys(d.categories).forEach(function (categoryID) { - var c = d.categories[categoryID]; + var pool = _this.collection; - if (c) { - // add or replace - c = presetCategory(categoryID, c, _presets); - if (c.locationSet) newLocationSets.push(c); - _categories[categoryID] = c; - } else { - // remove - delete _categories[categoryID]; - } + if (Array.isArray(loc)) { + var validLocations = _mainLocations.locationsAt(loc); + pool = pool.filter(function (a) { + return !a.locationSetID || validLocations[a.locationSetID]; }); - } // Rebuild _this.collection after changing presets and categories - - - _this.collection = Object.values(_presets).concat(Object.values(_categories)); // Merge Defaults + } - if (d.defaults) { - Object.keys(d.defaults).forEach(function (geometry) { - var def = d.defaults[geometry]; + var searchable = pool.filter(function (a) { + return a.searchable !== false && a.suggestion !== true; + }); + var suggestions = pool.filter(function (a) { + return a.suggestion === true; + }); // matches value to preset.name - if (Array.isArray(def)) { - // add or replace - _defaults[geometry] = presetCollection(def.map(function (id) { - return _presets[id] || _categories[id]; - }).filter(Boolean)); - } else { - // remove - delete _defaults[geometry]; - } - }); - } // Rebuild universal fields array + var leadingNames = searchable.filter(function (a) { + return leading(a.searchName()); + }).sort(sortPresets('searchName')); // matches value to preset suggestion name + var leadingSuggestions = suggestions.filter(function (a) { + return leadingStrict(a.searchName()); + }).sort(sortPresets('searchName')); + var leadingNamesStripped = searchable.filter(function (a) { + return leading(a.searchNameStripped()); + }).sort(sortPresets('searchNameStripped')); + var leadingSuggestionsStripped = suggestions.filter(function (a) { + return leadingStrict(a.searchNameStripped()); + }).sort(sortPresets('searchNameStripped')); // matches value to preset.terms values - _universal = Object.values(_fields).filter(function (field) { - return field.universal; - }); // Reset all the preset fields - they'll need to be resolved again + var leadingTerms = searchable.filter(function (a) { + return (a.terms() || []).some(leading); + }); + var leadingSuggestionTerms = suggestions.filter(function (a) { + return (a.terms() || []).some(leading); + }); // matches value to preset.tags values - Object.values(_presets).forEach(function (preset) { - return preset.resetFields(); - }); // Rebuild geometry index + var leadingTagValues = searchable.filter(function (a) { + return Object.values(a.tags || {}).filter(function (val) { + return val !== '*'; + }).some(leading); + }); // finds close matches to value in preset.name - _geometryIndex = { - point: {}, - vertex: {}, - line: {}, - area: {}, - relation: {} - }; + var similarName = searchable.map(function (a) { + return { + preset: a, + dist: utilEditDistance(value, a.searchName()) + }; + }).filter(function (a) { + return a.dist + Math.min(value.length - a.preset.searchName().length, 0) < 3; + }).sort(function (a, b) { + return a.dist - b.dist; + }).map(function (a) { + return a.preset; + }); // finds close matches to value to preset suggestion name - _this.collection.forEach(function (preset) { - (preset.geometry || []).forEach(function (geometry) { - var g = _geometryIndex[geometry]; + var similarSuggestions = suggestions.map(function (a) { + return { + preset: a, + dist: utilEditDistance(value, a.searchName()) + }; + }).filter(function (a) { + return a.dist + Math.min(value.length - a.preset.searchName().length, 0) < 1; + }).sort(function (a, b) { + return a.dist - b.dist; + }).map(function (a) { + return a.preset; + }); // finds close matches to value in preset.terms - for (var key in preset.tags) { - g[key] = g[key] || {}; - var value = preset.tags[key]; - (g[key][value] = g[key][value] || []).push(preset); - } + var similarTerms = searchable.filter(function (a) { + return (a.terms() || []).some(function (b) { + return utilEditDistance(value, b) + Math.min(value.length - b.length, 0) < 3; }); - }); // Merge Custom Features - - - if (d.featureCollection && Array.isArray(d.featureCollection.features)) { - _mainLocations.mergeCustomGeoJSON(d.featureCollection); - } // Resolve all locationSet features. - + }); + var results = leadingNames.concat(leadingSuggestions, leadingNamesStripped, leadingSuggestionsStripped, leadingTerms, leadingSuggestionTerms, leadingTagValues, similarName, similarSuggestions, similarTerms).slice(0, MAXRESULTS - 1); - if (newLocationSets.length) { - _mainLocations.mergeLocationSets(newLocationSets); + if (geometry) { + if (typeof geometry === 'string') { + results.push(_this.fallback(geometry)); + } else { + geometry.forEach(function (geom) { + return results.push(_this.fallback(geom)); + }); + } } - return _this; + return presetCollection(utilArrayUniq(results)); }; - _this.match = function (entity, resolver) { - return resolver["transient"](entity, 'presetMatch', function () { - var geometry = entity.geometry(resolver); // Treat entities on addr:interpolation lines as points, not vertices - #3241 + return _this; + } - if (geometry === 'vertex' && entity.isOnAddressLine(resolver)) { - geometry = 'point'; - } + // `presetCategory` builds a `presetCollection` of member presets, + // decorated with some extra methods for searching and matching geometry + // - var entityExtent = entity.extent(resolver); - return _this.matchTags(entity.tags, geometry, entityExtent.center()); - }); - }; + function presetCategory(categoryID, category, allPresets) { + var _this = Object.assign({}, category); // shallow copy - _this.matchTags = function (tags, geometry, loc) { - var keyIndex = _geometryIndex[geometry]; - var bestScore = -1; - var bestMatch; - var matchCandidates = []; - for (var k in tags) { - var indexMatches = []; - var valueIndex = keyIndex[k]; - if (!valueIndex) continue; - var keyValueMatches = valueIndex[tags[k]]; - if (keyValueMatches) indexMatches.push.apply(indexMatches, _toConsumableArray(keyValueMatches)); - var keyStarMatches = valueIndex['*']; - if (keyStarMatches) indexMatches.push.apply(indexMatches, _toConsumableArray(keyStarMatches)); - if (indexMatches.length === 0) continue; + var _searchName; // cache - for (var i = 0; i < indexMatches.length; i++) { - var candidate = indexMatches[i]; - var score = candidate.matchScore(tags); - if (score === -1) { - continue; - } + var _searchNameStripped; // cache - matchCandidates.push({ - score: score, - candidate: candidate - }); - if (score > bestScore) { - bestScore = score; - bestMatch = candidate; - } + _this.id = categoryID; + _this.members = presetCollection((category.members || []).map(function (presetID) { + return allPresets[presetID]; + }).filter(Boolean)); + _this.geometry = _this.members.collection.reduce(function (acc, preset) { + for (var i in preset.geometry) { + var geometry = preset.geometry[i]; + + if (acc.indexOf(geometry) === -1) { + acc.push(geometry); } } - if (bestMatch && bestMatch.locationSetID && bestMatch.locationSetID !== '+[Q2]' && Array.isArray(loc)) { - var validLocations = _mainLocations.locationsAt(loc); + return acc; + }, []); - if (!validLocations[bestMatch.locationSetID]) { - matchCandidates.sort(function (a, b) { - return a.score < b.score ? 1 : -1; - }); + _this.matchGeometry = function (geom) { + return _this.geometry.indexOf(geom) >= 0; + }; - for (var _i = 0; _i < matchCandidates.length; _i++) { - var candidateScore = matchCandidates[_i]; + _this.matchAllGeometry = function (geometries) { + return _this.members.collection.some(function (preset) { + return preset.matchAllGeometry(geometries); + }); + }; - if (!candidateScore.candidate.locationSetID || validLocations[candidateScore.candidate.locationSetID]) { - bestMatch = candidateScore.candidate; - bestScore = candidateScore.score; - break; - } - } - } - } // If any part of an address is present, allow fallback to "Address" preset - #4353 + _this.matchScore = function () { + return -1; + }; + _this.name = function () { + return _t("_tagging.presets.categories.".concat(categoryID, ".name"), { + 'default': categoryID + }); + }; - if (!bestMatch || bestMatch.isFallback()) { - for (var _k in tags) { - if (/^addr:/.test(_k) && keyIndex['addr:*'] && keyIndex['addr:*']['*']) { - bestMatch = keyIndex['addr:*']['*'][0]; - break; - } - } + _this.nameLabel = function () { + return _t.html("_tagging.presets.categories.".concat(categoryID, ".name"), { + 'default': categoryID + }); + }; + + _this.terms = function () { + return []; + }; + + _this.searchName = function () { + if (!_searchName) { + _searchName = (_this.suggestion ? _this.originalName : _this.name()).toLowerCase(); } - return bestMatch || _this.fallback(geometry); + return _searchName; }; - _this.allowsVertex = function (entity, resolver) { - if (entity.type !== 'node') return false; - if (Object.keys(entity.tags).length === 0) return true; - return resolver["transient"](entity, 'vertexMatch', function () { - // address lines allow vertices to act as standalone points - if (entity.isOnAddressLine(resolver)) return true; - var geometries = osmNodeGeometriesForTags(entity.tags); - if (geometries.vertex) return true; - if (geometries.point) return false; // allow vertices for unspecified points + _this.searchNameStripped = function () { + if (!_searchNameStripped) { + _searchNameStripped = _this.searchName(); // split combined diacritical characters into their parts - return true; - }); - }; // Because of the open nature of tagging, iD will never have a complete - // list of tags used in OSM, so we want it to have logic like "assume - // that a closed way with an amenity tag is an area, unless the amenity - // is one of these specific types". This function computes a structure - // that allows testing of such conditions, based on the presets designated - // as as supporting (or not supporting) the area geometry. - // - // The returned object L is a keeplist/discardlist of tags. A closed way - // with a tag (k, v) is considered to be an area if `k in L && !(v in L[k])` - // (see `Way#isArea()`). In other words, the keys of L form the keeplist, - // and the subkeys form the discardlist. + if (_searchNameStripped.normalize) _searchNameStripped = _searchNameStripped.normalize('NFD'); // remove diacritics + _searchNameStripped = _searchNameStripped.replace(/[\u0300-\u036f]/g, ''); + } - _this.areaKeys = function () { - // The ignore list is for keys that imply lines. (We always add `area=yes` for exceptions) - var ignore = ['barrier', 'highway', 'footway', 'railway', 'junction', 'type']; - var areaKeys = {}; // ignore name-suggestion-index and deprecated presets + return _searchNameStripped; + }; - var presets = _this.collection.filter(function (p) { - return !p.suggestion && !p.replacement; - }); // keeplist + return _this; + } + // `presetField` decorates a given `field` Object + // with some extra methods for searching and matching geometry + // - presets.forEach(function (p) { - var keys = p.tags && Object.keys(p.tags); - var key = keys && keys.length && keys[0]; // pick the first tag + function presetField(fieldID, field) { + var _this = Object.assign({}, field); // shallow copy - if (!key) return; - if (ignore.indexOf(key) !== -1) return; - if (p.geometry.indexOf('area') !== -1) { - // probably an area.. - areaKeys[key] = areaKeys[key] || {}; - } - }); // discardlist + _this.id = fieldID; // for use in classes, element ids, css selectors - presets.forEach(function (p) { - var key; + _this.safeid = utilSafeClassName(fieldID); - for (key in p.addTags) { - // examine all addTags to get a better sense of what can be tagged on lines - #6800 - var value = p.addTags[key]; + _this.matchGeometry = function (geom) { + return !_this.geometry || _this.geometry.indexOf(geom) !== -1; + }; - if (key in areaKeys && // probably an area... - p.geometry.indexOf('line') !== -1 && // but sometimes a line - value !== '*') { - areaKeys[key][value] = true; - } - } + _this.matchAllGeometry = function (geometries) { + return !_this.geometry || geometries.every(function (geom) { + return _this.geometry.indexOf(geom) !== -1; }); - return areaKeys; }; - _this.pointTags = function () { - return _this.collection.reduce(function (pointTags, d) { - // ignore name-suggestion-index, deprecated, and generic presets - if (d.suggestion || d.replacement || d.searchable === false) return pointTags; // only care about the primary tag - - var keys = d.tags && Object.keys(d.tags); - var key = keys && keys.length && keys[0]; // pick the first tag + _this.t = function (scope, options) { + return _t("_tagging.presets.fields.".concat(fieldID, ".").concat(scope), options); + }; - if (!key) return pointTags; // if this can be a point + _this.t.html = function (scope, options) { + return _t.html("_tagging.presets.fields.".concat(fieldID, ".").concat(scope), options); + }; - if (d.geometry.indexOf('point') !== -1) { - pointTags[key] = pointTags[key] || {}; - pointTags[key][d.tags[key]] = true; - } + _this.hasTextForStringId = function (scope) { + return _mainLocalizer.hasTextForStringId("_tagging.presets.fields.".concat(fieldID, ".").concat(scope)); + }; - return pointTags; - }, {}); + _this.title = function () { + return _this.overrideLabel || _this.t('label', { + 'default': fieldID + }); }; - _this.vertexTags = function () { - return _this.collection.reduce(function (vertexTags, d) { - // ignore name-suggestion-index, deprecated, and generic presets - if (d.suggestion || d.replacement || d.searchable === false) return vertexTags; // only care about the primary tag + _this.label = function () { + return _this.overrideLabel || _this.t.html('label', { + 'default': fieldID + }); + }; - var keys = d.tags && Object.keys(d.tags); - var key = keys && keys.length && keys[0]; // pick the first tag + var _placeholder = _this.placeholder; - if (!key) return vertexTags; // if this can be a vertex + _this.placeholder = function () { + return _this.t('placeholder', { + 'default': _placeholder + }); + }; - if (d.geometry.indexOf('vertex') !== -1) { - vertexTags[key] = vertexTags[key] || {}; - vertexTags[key][d.tags[key]] = true; - } + _this.originalTerms = (_this.terms || []).join(); - return vertexTags; - }, {}); + _this.terms = function () { + return _this.t('terms', { + 'default': _this.originalTerms + }).toLowerCase().trim().split(/\s*,+\s*/); }; - _this.field = function (id) { - return _fields[id]; - }; + _this.increment = _this.type === 'number' ? _this.increment || 1 : undefined; + return _this; + } - _this.universal = function () { - return _universal; - }; + // `presetPreset` decorates a given `preset` Object + // with some extra methods for searching and matching geometry + // - _this.defaults = function (geometry, n, startWithRecents, loc) { - var recents = []; + function presetPreset(presetID, preset, addable, allFields, allPresets) { + allFields = allFields || {}; + allPresets = allPresets || {}; - if (startWithRecents) { - recents = _this.recent().matchGeometry(geometry).collection.slice(0, 4); - } + var _this = Object.assign({}, preset); // shallow copy - var defaults; - if (_addablePresetIDs) { - defaults = Array.from(_addablePresetIDs).map(function (id) { - var preset = _this.item(id); + var _addable = addable || false; - if (preset && preset.matchGeometry(geometry)) return preset; - return null; - }).filter(Boolean); - } else { - defaults = _defaults[geometry].collection.concat(_this.fallback(geometry)); - } + var _resolvedFields; // cache - var result = presetCollection(utilArrayUniq(recents.concat(defaults)).slice(0, n - 1)); - if (Array.isArray(loc)) { - var validLocations = _mainLocations.locationsAt(loc); - result.collection = result.collection.filter(function (a) { - return !a.locationSetID || validLocations[a.locationSetID]; - }); - } + var _resolvedMoreFields; // cache - return result; - }; // pass a Set of addable preset ids + var _searchName; // cache - _this.addablePresetIDs = function (val) { - if (!arguments.length) return _addablePresetIDs; // accept and convert arrays - if (Array.isArray(val)) val = new Set(val); - _addablePresetIDs = val; + var _searchNameStripped; // cache - if (_addablePresetIDs) { - // reset all presets - _this.collection.forEach(function (p) { - // categories aren't addable - if (p.addable) p.addable(_addablePresetIDs.has(p.id)); - }); - } else { - _this.collection.forEach(function (p) { - if (p.addable) p.addable(true); - }); - } - return _this; + _this.id = presetID; + _this.safeid = utilSafeClassName(presetID); // for use in css classes, selectors, element ids + + _this.originalTerms = (_this.terms || []).join(); + _this.originalName = _this.name || ''; + _this.originalScore = _this.matchScore || 1; + _this.originalReference = _this.reference || {}; + _this.originalFields = _this.fields || []; + _this.originalMoreFields = _this.moreFields || []; + + _this.fields = function () { + return _resolvedFields || (_resolvedFields = resolve('fields')); }; - _this.recent = function () { - return presetCollection(utilArrayUniq(_this.getRecents().map(function (d) { - return d.preset; - }))); + _this.moreFields = function () { + return _resolvedMoreFields || (_resolvedMoreFields = resolve('moreFields')); }; - function RibbonItem(preset, source) { - var item = {}; - item.preset = preset; - item.source = source; + _this.resetFields = function () { + return _resolvedFields = _resolvedMoreFields = null; + }; - item.isFavorite = function () { - return item.source === 'favorite'; - }; + _this.tags = _this.tags || {}; + _this.addTags = _this.addTags || _this.tags; + _this.removeTags = _this.removeTags || _this.addTags; + _this.geometry = _this.geometry || []; - item.isRecent = function () { - return item.source === 'recent'; - }; + _this.matchGeometry = function (geom) { + return _this.geometry.indexOf(geom) >= 0; + }; - item.matches = function (preset) { - return item.preset.id === preset.id; - }; + _this.matchAllGeometry = function (geoms) { + return geoms.every(_this.matchGeometry); + }; - item.minified = function () { - return { - pID: item.preset.id - }; - }; + _this.matchScore = function (entityTags) { + var tags = _this.tags; + var seen = {}; + var score = 0; // match on tags - return item; - } + for (var k in tags) { + seen[k] = true; - function ribbonItemForMinified(d, source) { - if (d && d.pID) { - var preset = _this.item(d.pID); + if (entityTags[k] === tags[k]) { + score += _this.originalScore; + } else if (tags[k] === '*' && k in entityTags) { + score += _this.originalScore / 2; + } else { + return -1; + } + } // boost score for additional matches in addTags - #6802 - if (!preset) return null; - return RibbonItem(preset, source); - } - return null; - } + var addTags = _this.addTags; - _this.getGenericRibbonItems = function () { - return ['point', 'line', 'area'].map(function (id) { - return RibbonItem(_this.item(id), 'generic'); - }); + for (var _k in addTags) { + if (!seen[_k] && entityTags[_k] === addTags[_k]) { + score += _this.originalScore; + } + } + + return score; }; - _this.getAddable = function () { - if (!_addablePresetIDs) return []; - return _addablePresetIDs.map(function (id) { - var preset = _this.item(id); + _this.t = function (scope, options) { + var textID = "_tagging.presets.presets.".concat(presetID, ".").concat(scope); + return _t(textID, options); + }; - if (preset) return RibbonItem(preset, 'addable'); - return null; - }).filter(Boolean); + _this.t.html = function (scope, options) { + var textID = "_tagging.presets.presets.".concat(presetID, ".").concat(scope); + return _t.html(textID, options); }; - function setRecents(items) { - _recents = items; - var minifiedItems = items.map(function (d) { - return d.minified(); + _this.name = function () { + return _this.t('name', { + 'default': _this.originalName }); - corePreferences('preset_recents', JSON.stringify(minifiedItems)); - dispatch.call('recentsChange'); - } - - _this.getRecents = function () { - if (!_recents) { - // fetch from local storage - _recents = (JSON.parse(corePreferences('preset_recents')) || []).reduce(function (acc, d) { - var item = ribbonItemForMinified(d, 'recent'); - if (item && item.preset.addable()) acc.push(item); - return acc; - }, []); - } - - return _recents; }; - _this.addRecent = function (preset, besidePreset, after) { - var recents = _this.getRecents(); - - var beforeItem = _this.recentMatching(besidePreset); - - var toIndex = recents.indexOf(beforeItem); - if (after) toIndex += 1; - var newItem = RibbonItem(preset, 'recent'); - recents.splice(toIndex, 0, newItem); - setRecents(recents); + _this.nameLabel = function () { + return _this.t.html('name', { + 'default': _this.originalName + }); }; - _this.removeRecent = function (preset) { - var item = _this.recentMatching(preset); - - if (item) { - var items = _this.getRecents(); + _this.subtitle = function () { + if (_this.suggestion) { + var path = presetID.split('/'); + path.pop(); // remove brand name - items.splice(items.indexOf(item), 1); - setRecents(items); + return _t('_tagging.presets.presets.' + path.join('/') + '.name'); } + + return null; }; - _this.recentMatching = function (preset) { - var items = _this.getRecents(); + _this.subtitleLabel = function () { + if (_this.suggestion) { + var path = presetID.split('/'); + path.pop(); // remove brand name - for (var i in items) { - if (items[i].matches(preset)) { - return items[i]; - } + return _t.html('_tagging.presets.presets.' + path.join('/') + '.name'); } return null; }; - _this.moveItem = function (items, fromIndex, toIndex) { - if (fromIndex === toIndex || fromIndex < 0 || toIndex < 0 || fromIndex >= items.length || toIndex >= items.length) return null; - items.splice(toIndex, 0, items.splice(fromIndex, 1)[0]); - return items; + _this.terms = function () { + return _this.t('terms', { + 'default': _this.originalTerms + }).toLowerCase().trim().split(/\s*,+\s*/); }; - _this.moveRecent = function (item, beforeItem) { - var recents = _this.getRecents(); - - var fromIndex = recents.indexOf(item); - var toIndex = recents.indexOf(beforeItem); - - var items = _this.moveItem(recents, fromIndex, toIndex); + _this.searchName = function () { + if (!_searchName) { + _searchName = (_this.suggestion ? _this.originalName : _this.name()).toLowerCase(); + } - if (items) setRecents(items); + return _searchName; }; - _this.setMostRecent = function (preset) { - if (preset.searchable === false) return; - - var items = _this.getRecents(); - - var item = _this.recentMatching(preset); - - if (item) { - items.splice(items.indexOf(item), 1); - } else { - item = RibbonItem(preset, 'recent'); - } // remove the last recent (first in, first out) - + _this.searchNameStripped = function () { + if (!_searchNameStripped) { + _searchNameStripped = _this.searchName(); // split combined diacritical characters into their parts - while (items.length >= MAXRECENTS) { - items.pop(); - } // prepend array + if (_searchNameStripped.normalize) _searchNameStripped = _searchNameStripped.normalize('NFD'); // remove diacritics + _searchNameStripped = _searchNameStripped.replace(/[\u0300-\u036f]/g, ''); + } - items.unshift(item); - setRecents(items); + return _searchNameStripped; }; - function setFavorites(items) { - _favorites = items; - var minifiedItems = items.map(function (d) { - return d.minified(); - }); - corePreferences('preset_favorites', JSON.stringify(minifiedItems)); // call update - - dispatch.call('favoritePreset'); - } - - _this.addFavorite = function (preset, besidePreset, after) { - var favorites = _this.getFavorites(); - - var beforeItem = _this.favoriteMatching(besidePreset); + _this.isFallback = function () { + var tagCount = Object.keys(_this.tags).length; + return tagCount === 0 || tagCount === 1 && _this.tags.hasOwnProperty('area'); + }; - var toIndex = favorites.indexOf(beforeItem); - if (after) toIndex += 1; - var newItem = RibbonItem(preset, 'favorite'); - favorites.splice(toIndex, 0, newItem); - setFavorites(favorites); + _this.addable = function (val) { + if (!arguments.length) return _addable; + _addable = val; + return _this; }; - _this.toggleFavorite = function (preset) { - var favs = _this.getFavorites(); + _this.reference = function () { + // Lookup documentation on Wikidata... + var qid = _this.tags.wikidata || _this.tags['flag:wikidata'] || _this.tags['brand:wikidata'] || _this.tags['network:wikidata'] || _this.tags['operator:wikidata']; - var favorite = _this.favoriteMatching(preset); + if (qid) { + return { + qid: qid + }; + } // Lookup documentation on OSM Wikibase... - if (favorite) { - favs.splice(favs.indexOf(favorite), 1); - } else { - // only allow 10 favorites - if (favs.length === 10) { - // remove the last favorite (last in, first out) - favs.pop(); - } // append array + var key = _this.originalReference.key || Object.keys(utilObjectOmit(_this.tags, 'name'))[0]; + var value = _this.originalReference.value || _this.tags[key]; - favs.push(RibbonItem(preset, 'favorite')); + if (value === '*') { + return { + key: key + }; + } else { + return { + key: key, + value: value + }; } - - setFavorites(favs); }; - _this.removeFavorite = function (preset) { - var item = _this.favoriteMatching(preset); - - if (item) { - var items = _this.getFavorites(); + _this.unsetTags = function (tags, geometry, ignoringKeys, skipFieldDefaults) { + // allow manually keeping some tags + var removeTags = ignoringKeys ? utilObjectOmit(_this.removeTags, ignoringKeys) : _this.removeTags; + tags = utilObjectOmit(tags, Object.keys(removeTags)); - items.splice(items.indexOf(item), 1); - setFavorites(items); + if (geometry && !skipFieldDefaults) { + _this.fields().forEach(function (field) { + if (field.matchGeometry(geometry) && field.key && field["default"] === tags[field.key]) { + delete tags[field.key]; + } + }); } + + delete tags.area; + return tags; }; - _this.getFavorites = function () { - if (!_favorites) { - // fetch from local storage - var rawFavorites = JSON.parse(corePreferences('preset_favorites')); + _this.setTags = function (tags, geometry, skipFieldDefaults) { + var addTags = _this.addTags; + tags = Object.assign({}, tags); // shallow copy - if (!rawFavorites) { - rawFavorites = []; - corePreferences('preset_favorites', JSON.stringify(rawFavorites)); + for (var k in addTags) { + if (addTags[k] === '*') { + // if this tag is ancillary, don't override an existing value since any value is okay + if (_this.tags[k] || !tags[k] || tags[k] === 'no') { + tags[k] = 'yes'; + } + } else { + tags[k] = addTags[k]; } + } // Add area=yes if necessary. + // This is necessary if the geometry is already an area (e.g. user drew an area) AND any of: + // 1. chosen preset could be either an area or a line (`barrier=city_wall`) + // 2. chosen preset doesn't have a key in osmAreaKeys (`railway=station`) - _favorites = rawFavorites.reduce(function (output, d) { - var item = ribbonItemForMinified(d, 'favorite'); - if (item && item.preset.addable()) output.push(item); - return output; - }, []); - } - return _favorites; - }; + if (!addTags.hasOwnProperty('area')) { + delete tags.area; - _this.favoriteMatching = function (preset) { - var favs = _this.getFavorites(); + if (geometry === 'area') { + var needsAreaTag = true; - for (var index in favs) { - if (favs[index].matches(preset)) { - return favs[index]; + if (_this.geometry.indexOf('line') === -1) { + for (var _k2 in addTags) { + if (_k2 in osmAreaKeys) { + needsAreaTag = false; + break; + } + } + } + + if (needsAreaTag) { + tags.area = 'yes'; + } } } - return null; - }; + if (geometry && !skipFieldDefaults) { + _this.fields().forEach(function (field) { + if (field.matchGeometry(geometry) && field.key && !tags[field.key] && field["default"]) { + tags[field.key] = field["default"]; + } + }); + } - return utilRebind(_this, dispatch, 'on'); - } + return tags; + }; // For a preset without fields, use the fields of the parent preset. + // Replace {preset} placeholders with the fields of the specified presets. - function utilTagText(entity) { - var obj = entity && entity.tags || {}; - return Object.keys(obj).map(function (k) { - return k + '=' + obj[k]; - }).join(', '); - } - function utilTotalExtent(array, graph) { - var extent = geoExtent(); - var val, entity; - for (var i = 0; i < array.length; i++) { - val = array[i]; - entity = typeof val === 'string' ? graph.hasEntity(val) : val; + function resolve(which) { + var fieldIDs = which === 'fields' ? _this.originalFields : _this.originalMoreFields; + var resolved = []; + fieldIDs.forEach(function (fieldID) { + var match = fieldID.match(/\{(.*)\}/); - if (entity) { - extent._extend(entity.extent(graph)); - } - } + if (match !== null) { + // a presetID wrapped in braces {} + resolved = resolved.concat(inheritFields(match[1], which)); + } else if (allFields[fieldID]) { + // a normal fieldID + resolved.push(allFields[fieldID]); + } else { + console.log("Cannot resolve \"".concat(fieldID, "\" found in ").concat(_this.id, ".").concat(which)); // eslint-disable-line no-console + } + }); // no fields resolved, so use the parent's if possible - return extent; - } - function utilTagDiff(oldTags, newTags) { - var tagDiff = []; - var keys = utilArrayUnion(Object.keys(oldTags), Object.keys(newTags)).sort(); - keys.forEach(function (k) { - var oldVal = oldTags[k]; - var newVal = newTags[k]; + if (!resolved.length) { + var endIndex = _this.id.lastIndexOf('/'); - if ((oldVal || oldVal === '') && (newVal === undefined || newVal !== oldVal)) { - tagDiff.push({ - type: '-', - key: k, - oldVal: oldVal, - newVal: newVal, - display: '- ' + k + '=' + oldVal - }); - } + var parentID = endIndex && _this.id.substring(0, endIndex); - if ((newVal || newVal === '') && (oldVal === undefined || newVal !== oldVal)) { - tagDiff.push({ - type: '+', - key: k, - oldVal: oldVal, - newVal: newVal, - display: '+ ' + k + '=' + newVal - }); + if (parentID) { + resolved = inheritFields(parentID, which); + } } - }); - return tagDiff; - } - function utilEntitySelector(ids) { - return ids.length ? '.' + ids.join(',.') : 'nothing'; - } // returns an selector to select entity ids for: - // - entityIDs passed in - // - shallow descendant entityIDs for any of those entities that are relations - function utilEntityOrMemberSelector(ids, graph) { - var seen = new Set(ids); - ids.forEach(collectShallowDescendants); - return utilEntitySelector(Array.from(seen)); + return utilArrayUniq(resolved); // returns an array of fields to inherit from the given presetID, if found - function collectShallowDescendants(id) { - var entity = graph.hasEntity(id); - if (!entity || entity.type !== 'relation') return; - entity.members.map(function (member) { - return member.id; - }).forEach(function (id) { - seen.add(id); - }); - } - } // returns an selector to select entity ids for: - // - entityIDs passed in - // - deep descendant entityIDs for any of those entities that are relations + function inheritFields(presetID, which) { + var parent = allPresets[presetID]; + if (!parent) return []; - function utilEntityOrDeepMemberSelector(ids, graph) { - return utilEntitySelector(utilEntityAndDeepMemberIDs(ids, graph)); - } // returns an selector to select entity ids for: - // - entityIDs passed in - // - deep descendant entityIDs for any of those entities that are relations + if (which === 'fields') { + return parent.fields().filter(shouldInherit); + } else if (which === 'moreFields') { + return parent.moreFields(); + } else { + return []; + } + } // Skip `fields` for the keys which define the preset. + // These are usually `typeCombo` fields like `shop=*` - function utilEntityAndDeepMemberIDs(ids, graph) { - var seen = new Set(); - ids.forEach(collectDeepDescendants); - return Array.from(seen); - function collectDeepDescendants(id) { - if (seen.has(id)) return; - seen.add(id); - var entity = graph.hasEntity(id); - if (!entity || entity.type !== 'relation') return; - entity.members.map(function (member) { - return member.id; - }).forEach(collectDeepDescendants); // recurse + function shouldInherit(f) { + if (f.key && _this.tags[f.key] !== undefined && // inherit anyway if multiple values are allowed or just a checkbox + f.type !== 'multiCombo' && f.type !== 'semiCombo' && f.type !== 'manyCombo' && f.type !== 'check') return false; + return true; + } } - } // returns an selector to select entity ids for: - // - deep descendant entityIDs for any of those entities that are relations - function utilDeepMemberSelector(ids, graph, skipMultipolgonMembers) { - var idsSet = new Set(ids); - var seen = new Set(); - var returners = new Set(); - ids.forEach(collectDeepDescendants); - return utilEntitySelector(Array.from(returners)); + return _this; + } - function collectDeepDescendants(id) { - if (seen.has(id)) return; - seen.add(id); + var _mainPresetIndex = presetIndex(); // singleton + // `presetIndex` wraps a `presetCollection` + // with methods for loading new data and returning defaults + // - if (!idsSet.has(id)) { - returners.add(id); - } + function presetIndex() { + var dispatch = dispatch$8('favoritePreset', 'recentsChange'); + var MAXRECENTS = 30; // seed the preset lists with geometry fallbacks - var entity = graph.hasEntity(id); - if (!entity || entity.type !== 'relation') return; - if (skipMultipolgonMembers && entity.isMultipolygon()) return; - entity.members.map(function (member) { - return member.id; - }).forEach(collectDeepDescendants); // recurse - } - } // Adds or removes highlight styling for the specified entities - - function utilHighlightEntities(ids, highlighted, context) { - context.surface().selectAll(utilEntityOrDeepMemberSelector(ids, context.graph())).classed('highlighted', highlighted); - } // returns an Array that is the union of: - // - nodes for any nodeIDs passed in - // - child nodes of any wayIDs passed in - // - descendant member and child nodes of relationIDs passed in - - function utilGetAllNodes(ids, graph) { - var seen = new Set(); - var nodes = new Set(); - ids.forEach(collectNodes); - return Array.from(nodes); + var POINT = presetPreset('point', { + name: 'Point', + tags: {}, + geometry: ['point', 'vertex'], + matchScore: 0.1 + }); + var LINE = presetPreset('line', { + name: 'Line', + tags: {}, + geometry: ['line'], + matchScore: 0.1 + }); + var AREA = presetPreset('area', { + name: 'Area', + tags: { + area: 'yes' + }, + geometry: ['area'], + matchScore: 0.1 + }); + var RELATION = presetPreset('relation', { + name: 'Relation', + tags: {}, + geometry: ['relation'], + matchScore: 0.1 + }); - function collectNodes(id) { - if (seen.has(id)) return; - seen.add(id); - var entity = graph.hasEntity(id); - if (!entity) return; + var _this = presetCollection([POINT, LINE, AREA, RELATION]); - if (entity.type === 'node') { - nodes.add(entity); - } else if (entity.type === 'way') { - entity.nodes.forEach(collectNodes); - } else { - entity.members.map(function (member) { - return member.id; - }).forEach(collectNodes); // recurse - } - } - } - function utilDisplayName(entity) { - var localizedNameKey = 'name:' + _mainLocalizer.languageCode().toLowerCase(); - var name = entity.tags[localizedNameKey] || entity.tags.name || ''; - if (name) return name; - var tags = { - direction: entity.tags.direction, - from: entity.tags.from, - network: entity.tags.cycle_network || entity.tags.network, - ref: entity.tags.ref, - to: entity.tags.to, - via: entity.tags.via + var _presets = { + point: POINT, + line: LINE, + area: AREA, + relation: RELATION }; - var keyComponents = []; + var _defaults = { + point: presetCollection([POINT]), + vertex: presetCollection([POINT]), + line: presetCollection([LINE]), + area: presetCollection([AREA]), + relation: presetCollection([RELATION]) + }; + var _fields = {}; + var _categories = {}; + var _universal = []; + var _addablePresetIDs = null; // Set of preset IDs that the user can add - if (tags.network) { - keyComponents.push('network'); - } + var _recents; - if (tags.ref) { - keyComponents.push('ref'); - } // Routes may need more disambiguation based on direction or destination + var _favorites; // Index of presets by (geometry, tag key). - if (entity.tags.route) { - if (tags.direction) { - keyComponents.push('direction'); - } else if (tags.from && tags.to) { - keyComponents.push('from'); - keyComponents.push('to'); + var _geometryIndex = { + point: {}, + vertex: {}, + line: {}, + area: {}, + relation: {} + }; - if (tags.via) { - keyComponents.push('via'); - } - } - } + var _loadPromise; - if (keyComponents.length) { - name = _t('inspector.display_name.' + keyComponents.join('_'), tags); - } + _this.ensureLoaded = function () { + if (_loadPromise) return _loadPromise; + return _loadPromise = Promise.all([_mainFileFetcher.get('preset_categories'), _mainFileFetcher.get('preset_defaults'), _mainFileFetcher.get('preset_presets'), _mainFileFetcher.get('preset_fields')]).then(function (vals) { + _this.merge({ + categories: vals[0], + defaults: vals[1], + presets: vals[2], + fields: vals[3] + }); - return name; - } - function utilDisplayNameForPath(entity) { - var name = utilDisplayName(entity); - var isFirefox = utilDetect().browser.toLowerCase().indexOf('firefox') > -1; - var isNewChromium = Number(utilDetect().version.split('.')[0]) >= 96.0; + osmSetAreaKeys(_this.areaKeys()); + osmSetPointTags(_this.pointTags()); + osmSetVertexTags(_this.vertexTags()); + }); + }; // `merge` accepts an object containing new preset data (all properties optional): + // { + // fields: {}, + // presets: {}, + // categories: {}, + // defaults: {}, + // featureCollection: {} + //} - if (!isFirefox && !isNewChromium && name && rtlRegex.test(name)) { - name = fixRTLTextForSvg(name); - } - return name; - } - function utilDisplayType(id) { - return { - n: _t('inspector.node'), - w: _t('inspector.way'), - r: _t('inspector.relation') - }[id.charAt(0)]; - } // `utilDisplayLabel` - // Returns a string suitable for display - // By default returns something like name/ref, fallback to preset type, fallback to OSM type - // "Main Street" or "Tertiary Road" - // If `verbose=true`, include both preset name and feature name. - // "Tertiary Road Main Street" - // + _this.merge = function (d) { + var newLocationSets = []; // Merge Fields - function utilDisplayLabel(entity, graphOrGeometry, verbose) { - var result; - var displayName = utilDisplayName(entity); - var preset = typeof graphOrGeometry === 'string' ? _mainPresetIndex.matchTags(entity.tags, graphOrGeometry) : _mainPresetIndex.match(entity, graphOrGeometry); - var presetName = preset && (preset.suggestion ? preset.subtitle() : preset.name()); + if (d.fields) { + Object.keys(d.fields).forEach(function (fieldID) { + var f = d.fields[fieldID]; - if (verbose) { - result = [presetName, displayName].filter(Boolean).join(' '); - } else { - result = displayName || presetName; - } // Fallback to the OSM type (node/way/relation) + if (f) { + // add or replace + f = presetField(fieldID, f); + if (f.locationSet) newLocationSets.push(f); + _fields[fieldID] = f; + } else { + // remove + delete _fields[fieldID]; + } + }); + } // Merge Presets - return result || utilDisplayType(entity.id); - } - function utilEntityRoot(entityType) { - return { - node: 'n', - way: 'w', - relation: 'r' - }[entityType]; - } // Returns a single object containing the tags of all the given entities. - // Example: - // { - // highway: 'service', - // service: 'parking_aisle' - // } - // + - // { - // highway: 'service', - // service: 'driveway', - // width: '3' - // } - // = - // { - // highway: 'service', - // service: [ 'driveway', 'parking_aisle' ], - // width: [ '3', undefined ] - // } + if (d.presets) { + Object.keys(d.presets).forEach(function (presetID) { + var p = d.presets[presetID]; - function utilCombinedTags(entityIDs, graph) { - var tags = {}; - var tagCounts = {}; - var allKeys = new Set(); - var entities = entityIDs.map(function (entityID) { - return graph.hasEntity(entityID); - }).filter(Boolean); // gather the aggregate keys + if (p) { + // add or replace + var isAddable = !_addablePresetIDs || _addablePresetIDs.has(presetID); - entities.forEach(function (entity) { - var keys = Object.keys(entity.tags).filter(Boolean); - keys.forEach(function (key) { - allKeys.add(key); - }); - }); - entities.forEach(function (entity) { - allKeys.forEach(function (key) { - var value = entity.tags[key]; // purposely allow `undefined` + p = presetPreset(presetID, p, isAddable, _fields, _presets); + if (p.locationSet) newLocationSets.push(p); + _presets[presetID] = p; + } else { + // remove (but not if it's a fallback) + var existing = _presets[presetID]; - if (!tags.hasOwnProperty(key)) { - // first value, set as raw - tags[key] = value; - } else { - if (!Array.isArray(tags[key])) { - if (tags[key] !== value) { - // first alternate value, replace single value with array - tags[key] = [tags[key], value]; + if (existing && !existing.isFallback()) { + delete _presets[presetID]; } + } + }); + } // Merge Categories + + + if (d.categories) { + Object.keys(d.categories).forEach(function (categoryID) { + var c = d.categories[categoryID]; + + if (c) { + // add or replace + c = presetCategory(categoryID, c, _presets); + if (c.locationSet) newLocationSets.push(c); + _categories[categoryID] = c; } else { - // type is array - if (tags[key].indexOf(value) === -1) { - // subsequent alternate value, add to array - tags[key].push(value); - } + // remove + delete _categories[categoryID]; } - } + }); + } // Rebuild _this.collection after changing presets and categories - var tagHash = key + '=' + value; - if (!tagCounts[tagHash]) tagCounts[tagHash] = 0; - tagCounts[tagHash] += 1; - }); - }); - for (var key in tags) { - if (!Array.isArray(tags[key])) continue; // sort values by frequency then alphabetically + _this.collection = Object.values(_presets).concat(Object.values(_categories)); // Merge Defaults - tags[key] = tags[key].sort(function (val1, val2) { - var key = key; // capture + if (d.defaults) { + Object.keys(d.defaults).forEach(function (geometry) { + var def = d.defaults[geometry]; - var count2 = tagCounts[key + '=' + val2]; - var count1 = tagCounts[key + '=' + val1]; + if (Array.isArray(def)) { + // add or replace + _defaults[geometry] = presetCollection(def.map(function (id) { + return _presets[id] || _categories[id]; + }).filter(Boolean)); + } else { + // remove + delete _defaults[geometry]; + } + }); + } // Rebuild universal fields array - if (count2 !== count1) { - return count2 - count1; - } - if (val2 && val1) { - return val1.localeCompare(val2); - } + _universal = Object.values(_fields).filter(function (field) { + return field.universal; + }); // Reset all the preset fields - they'll need to be resolved again - return val1 ? 1 : -1; - }); - } + Object.values(_presets).forEach(function (preset) { + return preset.resetFields(); + }); // Rebuild geometry index - return tags; - } - function utilStringQs(str) { - var i = 0; // advance past any leading '?' or '#' characters + _geometryIndex = { + point: {}, + vertex: {}, + line: {}, + area: {}, + relation: {} + }; - while (i < str.length && (str[i] === '?' || str[i] === '#')) { - i++; - } + _this.collection.forEach(function (preset) { + (preset.geometry || []).forEach(function (geometry) { + var g = _geometryIndex[geometry]; - str = str.slice(i); - return str.split('&').reduce(function (obj, pair) { - var parts = pair.split('='); + for (var key in preset.tags) { + g[key] = g[key] || {}; + var value = preset.tags[key]; + (g[key][value] = g[key][value] || []).push(preset); + } + }); + }); // Merge Custom Features - if (parts.length === 2) { - obj[parts[0]] = null === parts[1] ? '' : decodeURIComponent(parts[1]); - } - return obj; - }, {}); - } - function utilQsString(obj, noencode) { - // encode everything except special characters used in certain hash parameters: - // "/" in map states, ":", ",", {" and "}" in background - function softEncode(s) { - return encodeURIComponent(s).replace(/(%2F|%3A|%2C|%7B|%7D)/g, decodeURIComponent); - } + if (d.featureCollection && Array.isArray(d.featureCollection.features)) { + _mainLocations.mergeCustomGeoJSON(d.featureCollection); + } // Resolve all locationSet features. - return Object.keys(obj).sort().map(function (key) { - return encodeURIComponent(key) + '=' + (noencode ? softEncode(obj[key]) : encodeURIComponent(obj[key])); - }).join('&'); - } - function utilPrefixDOMProperty(property) { - var prefixes = ['webkit', 'ms', 'moz', 'o']; - var i = -1; - var n = prefixes.length; - var s = document.body; - if (property in s) return property; - property = property.substr(0, 1).toUpperCase() + property.substr(1); - while (++i < n) { - if (prefixes[i] + property in s) { - return prefixes[i] + property; + if (newLocationSets.length) { + _mainLocations.mergeLocationSets(newLocationSets); } - } - return false; - } - function utilPrefixCSSProperty(property) { - var prefixes = ['webkit', 'ms', 'Moz', 'O']; - var i = -1; - var n = prefixes.length; - var s = document.body.style; + return _this; + }; - if (property.toLowerCase() in s) { - return property.toLowerCase(); - } + _this.match = function (entity, resolver) { + return resolver["transient"](entity, 'presetMatch', function () { + var geometry = entity.geometry(resolver); // Treat entities on addr:interpolation lines as points, not vertices - #3241 - while (++i < n) { - if (prefixes[i] + property in s) { - return '-' + prefixes[i].toLowerCase() + property.replace(/([A-Z])/g, '-$1').toLowerCase(); - } - } + if (geometry === 'vertex' && entity.isOnAddressLine(resolver)) { + geometry = 'point'; + } - return false; - } - var transformProperty; - function utilSetTransform(el, x, y, scale) { - var prop = transformProperty = transformProperty || utilPrefixCSSProperty('Transform'); - var translate = utilDetect().opera ? 'translate(' + x + 'px,' + y + 'px)' : 'translate3d(' + x + 'px,' + y + 'px,0)'; - return el.style(prop, translate + (scale ? ' scale(' + scale + ')' : '')); - } // Calculates Levenshtein distance between two strings - // see: https://en.wikipedia.org/wiki/Levenshtein_distance - // first converts the strings to lowercase and replaces diacritic marks with ascii equivalents. + var entityExtent = entity.extent(resolver); + return _this.matchTags(entity.tags, geometry, entityExtent.center()); + }); + }; - function utilEditDistance(a, b) { - a = remove$6(a.toLowerCase()); - b = remove$6(b.toLowerCase()); - if (a.length === 0) return b.length; - if (b.length === 0) return a.length; - var matrix = []; - var i, j; + _this.matchTags = function (tags, geometry, loc) { + var keyIndex = _geometryIndex[geometry]; + var bestScore = -1; + var bestMatch; + var matchCandidates = []; - for (i = 0; i <= b.length; i++) { - matrix[i] = [i]; - } + for (var k in tags) { + var indexMatches = []; + var valueIndex = keyIndex[k]; + if (!valueIndex) continue; + var keyValueMatches = valueIndex[tags[k]]; + if (keyValueMatches) indexMatches.push.apply(indexMatches, _toConsumableArray(keyValueMatches)); + var keyStarMatches = valueIndex['*']; + if (keyStarMatches) indexMatches.push.apply(indexMatches, _toConsumableArray(keyStarMatches)); + if (indexMatches.length === 0) continue; - for (j = 0; j <= a.length; j++) { - matrix[0][j] = j; - } + for (var i = 0; i < indexMatches.length; i++) { + var candidate = indexMatches[i]; + var score = candidate.matchScore(tags); - for (i = 1; i <= b.length; i++) { - for (j = 1; j <= a.length; j++) { - if (b.charAt(i - 1) === a.charAt(j - 1)) { - matrix[i][j] = matrix[i - 1][j - 1]; - } else { - matrix[i][j] = Math.min(matrix[i - 1][j - 1] + 1, // substitution - Math.min(matrix[i][j - 1] + 1, // insertion - matrix[i - 1][j] + 1)); // deletion + if (score === -1) { + continue; + } + + matchCandidates.push({ + score: score, + candidate: candidate + }); + + if (score > bestScore) { + bestScore = score; + bestMatch = candidate; + } } } - } - return matrix[b.length][a.length]; - } // a d3.mouse-alike which - // 1. Only works on HTML elements, not SVG - // 2. Does not cause style recalculation + if (bestMatch && bestMatch.locationSetID && bestMatch.locationSetID !== '+[Q2]' && Array.isArray(loc)) { + var validLocations = _mainLocations.locationsAt(loc); - function utilFastMouse(container) { - var rect = container.getBoundingClientRect(); - var rectLeft = rect.left; - var rectTop = rect.top; - var clientLeft = +container.clientLeft; - var clientTop = +container.clientTop; - return function (e) { - return [e.clientX - rectLeft - clientLeft, e.clientY - rectTop - clientTop]; - }; - } - function utilAsyncMap(inputs, func, callback) { - var remaining = inputs.length; - var results = []; - var errors = []; - inputs.forEach(function (d, i) { - func(d, function done(err, data) { - errors[i] = err; - results[i] = data; - remaining--; - if (!remaining) callback(errors, results); - }); - }); - } // wraps an index to an interval [0..length-1] + if (!validLocations[bestMatch.locationSetID]) { + matchCandidates.sort(function (a, b) { + return a.score < b.score ? 1 : -1; + }); - function utilWrap(index, length) { - if (index < 0) { - index += Math.ceil(-index / length) * length; - } + for (var _i = 0; _i < matchCandidates.length; _i++) { + var candidateScore = matchCandidates[_i]; - return index % length; - } - /** - * a replacement for functor - * - * @param {*} value any value - * @returns {Function} a function that returns that value or the value if it's a function - */ - - function utilFunctor(value) { - if (typeof value === 'function') return value; - return function () { - return value; - }; - } - function utilNoAuto(selection) { - var isText = selection.size() && selection.node().tagName.toLowerCase() === 'textarea'; - return selection // assign 'new-password' even for non-password fields to prevent browsers (Chrome) ignoring 'off' - .attr('autocomplete', 'new-password').attr('autocorrect', 'off').attr('autocapitalize', 'off').attr('spellcheck', isText ? 'true' : 'false'); - } // https://stackoverflow.com/questions/194846/is-there-any-kind-of-hash-code-function-in-javascript - // https://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-hashcode-method/ + if (!candidateScore.candidate.locationSetID || validLocations[candidateScore.candidate.locationSetID]) { + bestMatch = candidateScore.candidate; + bestScore = candidateScore.score; + break; + } + } + } + } // If any part of an address is present, allow fallback to "Address" preset - #4353 - function utilHashcode(str) { - var hash = 0; - if (str.length === 0) { - return hash; - } + if (!bestMatch || bestMatch.isFallback()) { + for (var _k in tags) { + if (/^addr:/.test(_k) && keyIndex['addr:*'] && keyIndex['addr:*']['*']) { + bestMatch = keyIndex['addr:*']['*'][0]; + break; + } + } + } - for (var i = 0; i < str.length; i++) { - var _char = str.charCodeAt(i); + return bestMatch || _this.fallback(geometry); + }; - hash = (hash << 5) - hash + _char; - hash = hash & hash; // Convert to 32bit integer - } + _this.allowsVertex = function (entity, resolver) { + if (entity.type !== 'node') return false; + if (Object.keys(entity.tags).length === 0) return true; + return resolver["transient"](entity, 'vertexMatch', function () { + // address lines allow vertices to act as standalone points + if (entity.isOnAddressLine(resolver)) return true; + var geometries = osmNodeGeometriesForTags(entity.tags); + if (geometries.vertex) return true; + if (geometries.point) return false; // allow vertices for unspecified points - return hash; - } // Returns version of `str` with all runs of special characters replaced by `_`; - // suitable for HTML ids, classes, selectors, etc. + return true; + }); + }; // Because of the open nature of tagging, iD will never have a complete + // list of tags used in OSM, so we want it to have logic like "assume + // that a closed way with an amenity tag is an area, unless the amenity + // is one of these specific types". This function computes a structure + // that allows testing of such conditions, based on the presets designated + // as as supporting (or not supporting) the area geometry. + // + // The returned object L is a keeplist/discardlist of tags. A closed way + // with a tag (k, v) is considered to be an area if `k in L && !(v in L[k])` + // (see `Way#isArea()`). In other words, the keys of L form the keeplist, + // and the subkeys form the discardlist. - function utilSafeClassName(str) { - return str.toLowerCase().replace(/[^a-z0-9]+/g, '_'); - } // Returns string based on `val` that is highly unlikely to collide with an id - // used previously or that's present elsewhere in the document. Useful for preventing - // browser-provided autofills or when embedding iD on pages with unknown elements. - function utilUniqueDomId(val) { - return 'ideditor-' + utilSafeClassName(val.toString()) + '-' + new Date().getTime().toString(); - } // Returns the length of `str` in unicode characters. This can be less than - // `String.length()` since a single unicode character can be composed of multiple - // JavaScript UTF-16 code units. + _this.areaKeys = function () { + // The ignore list is for keys that imply lines. (We always add `area=yes` for exceptions) + var ignore = ['barrier', 'highway', 'footway', 'railway', 'junction', 'type']; + var areaKeys = {}; // ignore name-suggestion-index and deprecated presets - function utilUnicodeCharsCount(str) { - // Native ES2015 implementations of `Array.from` split strings into unicode characters - return Array.from(str).length; - } // Returns a new string representing `str` cut from its start to `limit` length - // in unicode characters. Note that this runs the risk of splitting graphemes. + var presets = _this.collection.filter(function (p) { + return !p.suggestion && !p.replacement; + }); // keeplist - function utilUnicodeCharsTruncated(str, limit) { - return Array.from(str).slice(0, limit).join(''); - } - function osmEntity(attrs) { - // For prototypal inheritance. - if (this instanceof osmEntity) return; // Create the appropriate subtype. + presets.forEach(function (p) { + var keys = p.tags && Object.keys(p.tags); + var key = keys && keys.length && keys[0]; // pick the first tag - if (attrs && attrs.type) { - return osmEntity[attrs.type].apply(this, arguments); - } else if (attrs && attrs.id) { - return osmEntity[osmEntity.id.type(attrs.id)].apply(this, arguments); - } // Initialize a generic Entity (used only in tests). + if (!key) return; + if (ignore.indexOf(key) !== -1) return; + if (p.geometry.indexOf('area') !== -1) { + // probably an area.. + areaKeys[key] = areaKeys[key] || {}; + } + }); // discardlist - return new osmEntity().initialize(arguments); - } + presets.forEach(function (p) { + var key; - osmEntity.id = function (type) { - return osmEntity.id.fromOSM(type, osmEntity.id.next[type]--); - }; + for (key in p.addTags) { + // examine all addTags to get a better sense of what can be tagged on lines - #6800 + var value = p.addTags[key]; - osmEntity.id.next = { - changeset: -1, - node: -1, - way: -1, - relation: -1 - }; + if (key in areaKeys && // probably an area... + p.geometry.indexOf('line') !== -1 && // but sometimes a line + value !== '*') { + areaKeys[key][value] = true; + } + } + }); + return areaKeys; + }; - osmEntity.id.fromOSM = function (type, id) { - return type[0] + id; - }; + _this.pointTags = function () { + return _this.collection.reduce(function (pointTags, d) { + // ignore name-suggestion-index, deprecated, and generic presets + if (d.suggestion || d.replacement || d.searchable === false) return pointTags; // only care about the primary tag - osmEntity.id.toOSM = function (id) { - return id.slice(1); - }; + var keys = d.tags && Object.keys(d.tags); + var key = keys && keys.length && keys[0]; // pick the first tag - osmEntity.id.type = function (id) { - return { - 'c': 'changeset', - 'n': 'node', - 'w': 'way', - 'r': 'relation' - }[id[0]]; - }; // A function suitable for use as the second argument to d3.selection#data(). + if (!key) return pointTags; // if this can be a point + if (d.geometry.indexOf('point') !== -1) { + pointTags[key] = pointTags[key] || {}; + pointTags[key][d.tags[key]] = true; + } - osmEntity.key = function (entity) { - return entity.id + 'v' + (entity.v || 0); - }; + return pointTags; + }, {}); + }; - var _deprecatedTagValuesByKey; + _this.vertexTags = function () { + return _this.collection.reduce(function (vertexTags, d) { + // ignore name-suggestion-index, deprecated, and generic presets + if (d.suggestion || d.replacement || d.searchable === false) return vertexTags; // only care about the primary tag - osmEntity.deprecatedTagValuesByKey = function (dataDeprecated) { - if (!_deprecatedTagValuesByKey) { - _deprecatedTagValuesByKey = {}; - dataDeprecated.forEach(function (d) { - var oldKeys = Object.keys(d.old); + var keys = d.tags && Object.keys(d.tags); + var key = keys && keys.length && keys[0]; // pick the first tag - if (oldKeys.length === 1) { - var oldKey = oldKeys[0]; - var oldValue = d.old[oldKey]; + if (!key) return vertexTags; // if this can be a vertex - if (oldValue !== '*') { - if (!_deprecatedTagValuesByKey[oldKey]) { - _deprecatedTagValuesByKey[oldKey] = [oldValue]; - } else { - _deprecatedTagValuesByKey[oldKey].push(oldValue); - } - } + if (d.geometry.indexOf('vertex') !== -1) { + vertexTags[key] = vertexTags[key] || {}; + vertexTags[key][d.tags[key]] = true; } - }); - } - - return _deprecatedTagValuesByKey; - }; - osmEntity.prototype = { - tags: {}, - initialize: function initialize(sources) { - for (var i = 0; i < sources.length; ++i) { - var source = sources[i]; + return vertexTags; + }, {}); + }; - for (var prop in source) { - if (Object.prototype.hasOwnProperty.call(source, prop)) { - if (source[prop] === undefined) { - delete this[prop]; - } else { - this[prop] = source[prop]; - } - } - } - } + _this.field = function (id) { + return _fields[id]; + }; - if (!this.id && this.type) { - this.id = osmEntity.id(this.type); - } + _this.universal = function () { + return _universal; + }; - if (!this.hasOwnProperty('visible')) { - this.visible = true; - } + _this.defaults = function (geometry, n, startWithRecents, loc) { + var recents = []; - if (debug) { - Object.freeze(this); - Object.freeze(this.tags); - if (this.loc) Object.freeze(this.loc); - if (this.nodes) Object.freeze(this.nodes); - if (this.members) Object.freeze(this.members); + if (startWithRecents) { + recents = _this.recent().matchGeometry(geometry).collection.slice(0, 4); } - return this; - }, - copy: function copy(resolver, copies) { - if (copies[this.id]) return copies[this.id]; - var copy = osmEntity(this, { - id: undefined, - user: undefined, - version: undefined - }); - copies[this.id] = copy; - return copy; - }, - osmId: function osmId() { - return osmEntity.id.toOSM(this.id); - }, - isNew: function isNew() { - return this.osmId() < 0; - }, - update: function update(attrs) { - return osmEntity(this, attrs, { - v: 1 + (this.v || 0) - }); - }, - mergeTags: function mergeTags(tags) { - var merged = Object.assign({}, this.tags); // shallow copy - - var changed = false; + var defaults; - for (var k in tags) { - var t1 = merged[k]; - var t2 = tags[k]; + if (_addablePresetIDs) { + defaults = Array.from(_addablePresetIDs).map(function (id) { + var preset = _this.item(id); - if (!t1) { - changed = true; - merged[k] = t2; - } else if (t1 !== t2) { - changed = true; - merged[k] = utilUnicodeCharsTruncated(utilArrayUnion(t1.split(/;\s*/), t2.split(/;\s*/)).join(';'), 255 // avoid exceeding character limit; see also services/osm.js -> maxCharsForTagValue() - ); - } + if (preset && preset.matchGeometry(geometry)) return preset; + return null; + }).filter(Boolean); + } else { + defaults = _defaults[geometry].collection.concat(_this.fallback(geometry)); } - return changed ? this.update({ - tags: merged - }) : this; - }, - intersects: function intersects(extent, resolver) { - return this.extent(resolver).intersects(extent); - }, - hasNonGeometryTags: function hasNonGeometryTags() { - return Object.keys(this.tags).some(function (k) { - return k !== 'area'; - }); - }, - hasParentRelations: function hasParentRelations(resolver) { - return resolver.parentRelations(this).length > 0; - }, - hasInterestingTags: function hasInterestingTags() { - return Object.keys(this.tags).some(osmIsInterestingTag); - }, - isHighwayIntersection: function isHighwayIntersection() { - return false; - }, - isDegenerate: function isDegenerate() { - return true; - }, - deprecatedTags: function deprecatedTags(dataDeprecated) { - var tags = this.tags; // if there are no tags, none can be deprecated + var result = presetCollection(utilArrayUniq(recents.concat(defaults)).slice(0, n - 1)); - if (Object.keys(tags).length === 0) return []; - var deprecated = []; - dataDeprecated.forEach(function (d) { - var oldKeys = Object.keys(d.old); + if (Array.isArray(loc)) { + var validLocations = _mainLocations.locationsAt(loc); + result.collection = result.collection.filter(function (a) { + return !a.locationSetID || validLocations[a.locationSetID]; + }); + } - if (d.replace) { - var hasExistingValues = Object.keys(d.replace).some(function (replaceKey) { - if (!tags[replaceKey] || d.old[replaceKey]) return false; - var replaceValue = d.replace[replaceKey]; - if (replaceValue === '*') return false; - if (replaceValue === tags[replaceKey]) return false; - return true; - }); // don't flag deprecated tags if the upgrade path would overwrite existing data - #7843 + return result; + }; // pass a Set of addable preset ids - if (hasExistingValues) return; - } - var matchesDeprecatedTags = oldKeys.every(function (oldKey) { - if (!tags[oldKey]) return false; - if (d.old[oldKey] === '*') return true; - if (d.old[oldKey] === tags[oldKey]) return true; - var vals = tags[oldKey].split(';').filter(Boolean); + _this.addablePresetIDs = function (val) { + if (!arguments.length) return _addablePresetIDs; // accept and convert arrays - if (vals.length === 0) { - return false; - } else if (vals.length > 1) { - return vals.indexOf(d.old[oldKey]) !== -1; - } else { - if (tags[oldKey] === d.old[oldKey]) { - if (d.replace && d.old[oldKey] === d.replace[oldKey]) { - var replaceKeys = Object.keys(d.replace); - return !replaceKeys.every(function (replaceKey) { - return tags[replaceKey] === d.replace[replaceKey]; - }); - } else { - return true; - } - } - } + if (Array.isArray(val)) val = new Set(val); + _addablePresetIDs = val; - return false; + if (_addablePresetIDs) { + // reset all presets + _this.collection.forEach(function (p) { + // categories aren't addable + if (p.addable) p.addable(_addablePresetIDs.has(p.id)); + }); + } else { + _this.collection.forEach(function (p) { + if (p.addable) p.addable(true); }); + } - if (matchesDeprecatedTags) { - deprecated.push(d); - } - }); - return deprecated; - } - }; + return _this; + }; - function osmLanes(entity) { - if (entity.type !== 'way') return null; - if (!entity.tags.highway) return null; - var tags = entity.tags; - var isOneWay = entity.isOneWay(); - var laneCount = getLaneCount(tags, isOneWay); - var maxspeed = parseMaxspeed(tags); - var laneDirections = parseLaneDirections(tags, isOneWay, laneCount); - var forward = laneDirections.forward; - var backward = laneDirections.backward; - var bothways = laneDirections.bothways; // parse the piped string 'x|y|z' format + _this.recent = function () { + return presetCollection(utilArrayUniq(_this.getRecents().map(function (d) { + return d.preset; + }))); + }; - var turnLanes = {}; - turnLanes.unspecified = parseTurnLanes(tags['turn:lanes']); - turnLanes.forward = parseTurnLanes(tags['turn:lanes:forward']); - turnLanes.backward = parseTurnLanes(tags['turn:lanes:backward']); - var maxspeedLanes = {}; - maxspeedLanes.unspecified = parseMaxspeedLanes(tags['maxspeed:lanes'], maxspeed); - maxspeedLanes.forward = parseMaxspeedLanes(tags['maxspeed:lanes:forward'], maxspeed); - maxspeedLanes.backward = parseMaxspeedLanes(tags['maxspeed:lanes:backward'], maxspeed); - var psvLanes = {}; - psvLanes.unspecified = parseMiscLanes(tags['psv:lanes']); - psvLanes.forward = parseMiscLanes(tags['psv:lanes:forward']); - psvLanes.backward = parseMiscLanes(tags['psv:lanes:backward']); - var busLanes = {}; - busLanes.unspecified = parseMiscLanes(tags['bus:lanes']); - busLanes.forward = parseMiscLanes(tags['bus:lanes:forward']); - busLanes.backward = parseMiscLanes(tags['bus:lanes:backward']); - var taxiLanes = {}; - taxiLanes.unspecified = parseMiscLanes(tags['taxi:lanes']); - taxiLanes.forward = parseMiscLanes(tags['taxi:lanes:forward']); - taxiLanes.backward = parseMiscLanes(tags['taxi:lanes:backward']); - var hovLanes = {}; - hovLanes.unspecified = parseMiscLanes(tags['hov:lanes']); - hovLanes.forward = parseMiscLanes(tags['hov:lanes:forward']); - hovLanes.backward = parseMiscLanes(tags['hov:lanes:backward']); - var hgvLanes = {}; - hgvLanes.unspecified = parseMiscLanes(tags['hgv:lanes']); - hgvLanes.forward = parseMiscLanes(tags['hgv:lanes:forward']); - hgvLanes.backward = parseMiscLanes(tags['hgv:lanes:backward']); - var bicyclewayLanes = {}; - bicyclewayLanes.unspecified = parseBicycleWay(tags['bicycleway:lanes']); - bicyclewayLanes.forward = parseBicycleWay(tags['bicycleway:lanes:forward']); - bicyclewayLanes.backward = parseBicycleWay(tags['bicycleway:lanes:backward']); - var lanesObj = { - forward: [], - backward: [], - unspecified: [] - }; // map forward/backward/unspecified of each lane type to lanesObj + function RibbonItem(preset, source) { + var item = {}; + item.preset = preset; + item.source = source; - mapToLanesObj(lanesObj, turnLanes, 'turnLane'); - mapToLanesObj(lanesObj, maxspeedLanes, 'maxspeed'); - mapToLanesObj(lanesObj, psvLanes, 'psv'); - mapToLanesObj(lanesObj, busLanes, 'bus'); - mapToLanesObj(lanesObj, taxiLanes, 'taxi'); - mapToLanesObj(lanesObj, hovLanes, 'hov'); - mapToLanesObj(lanesObj, hgvLanes, 'hgv'); - mapToLanesObj(lanesObj, bicyclewayLanes, 'bicycleway'); - return { - metadata: { - count: laneCount, - oneway: isOneWay, - forward: forward, - backward: backward, - bothways: bothways, - turnLanes: turnLanes, - maxspeed: maxspeed, - maxspeedLanes: maxspeedLanes, - psvLanes: psvLanes, - busLanes: busLanes, - taxiLanes: taxiLanes, - hovLanes: hovLanes, - hgvLanes: hgvLanes, - bicyclewayLanes: bicyclewayLanes - }, - lanes: lanesObj - }; - } + item.isFavorite = function () { + return item.source === 'favorite'; + }; - function getLaneCount(tags, isOneWay) { - var count; + item.isRecent = function () { + return item.source === 'recent'; + }; - if (tags.lanes) { - count = parseInt(tags.lanes, 10); + item.matches = function (preset) { + return item.preset.id === preset.id; + }; - if (count > 0) { - return count; - } + item.minified = function () { + return { + pID: item.preset.id + }; + }; + + return item; } - switch (tags.highway) { - case 'trunk': - case 'motorway': - count = isOneWay ? 2 : 4; - break; + function ribbonItemForMinified(d, source) { + if (d && d.pID) { + var preset = _this.item(d.pID); - default: - count = isOneWay ? 1 : 2; - break; + if (!preset) return null; + return RibbonItem(preset, source); + } + + return null; } - return count; - } + _this.getGenericRibbonItems = function () { + return ['point', 'line', 'area'].map(function (id) { + return RibbonItem(_this.item(id), 'generic'); + }); + }; - function parseMaxspeed(tags) { - var maxspeed = tags.maxspeed; - if (!maxspeed) return; - var maxspeedRegex = /^([0-9][\.0-9]+?)(?:[ ]?(?:km\/h|kmh|kph|mph|knots))?$/; - if (!maxspeedRegex.test(maxspeed)) return; - return parseInt(maxspeed, 10); - } + _this.getAddable = function () { + if (!_addablePresetIDs) return []; + return _addablePresetIDs.map(function (id) { + var preset = _this.item(id); - function parseLaneDirections(tags, isOneWay, laneCount) { - var forward = parseInt(tags['lanes:forward'], 10); - var backward = parseInt(tags['lanes:backward'], 10); - var bothways = parseInt(tags['lanes:both_ways'], 10) > 0 ? 1 : 0; + if (preset) return RibbonItem(preset, 'addable'); + return null; + }).filter(Boolean); + }; - if (parseInt(tags.oneway, 10) === -1) { - forward = 0; - bothways = 0; - backward = laneCount; - } else if (isOneWay) { - forward = laneCount; - bothways = 0; - backward = 0; - } else if (isNaN(forward) && isNaN(backward)) { - backward = Math.floor((laneCount - bothways) / 2); - forward = laneCount - bothways - backward; - } else if (isNaN(forward)) { - if (backward > laneCount - bothways) { - backward = laneCount - bothways; + function setRecents(items) { + _recents = items; + var minifiedItems = items.map(function (d) { + return d.minified(); + }); + corePreferences('preset_recents', JSON.stringify(minifiedItems)); + dispatch.call('recentsChange'); + } + + _this.getRecents = function () { + if (!_recents) { + // fetch from local storage + _recents = (JSON.parse(corePreferences('preset_recents')) || []).reduce(function (acc, d) { + var item = ribbonItemForMinified(d, 'recent'); + if (item && item.preset.addable()) acc.push(item); + return acc; + }, []); } - forward = laneCount - bothways - backward; - } else if (isNaN(backward)) { - if (forward > laneCount - bothways) { - forward = laneCount - bothways; + return _recents; + }; + + _this.addRecent = function (preset, besidePreset, after) { + var recents = _this.getRecents(); + + var beforeItem = _this.recentMatching(besidePreset); + + var toIndex = recents.indexOf(beforeItem); + if (after) toIndex += 1; + var newItem = RibbonItem(preset, 'recent'); + recents.splice(toIndex, 0, newItem); + setRecents(recents); + }; + + _this.removeRecent = function (preset) { + var item = _this.recentMatching(preset); + + if (item) { + var items = _this.getRecents(); + + items.splice(items.indexOf(item), 1); + setRecents(items); } + }; - backward = laneCount - bothways - forward; - } + _this.recentMatching = function (preset) { + var items = _this.getRecents(); - return { - forward: forward, - backward: backward, - bothways: bothways + for (var i in items) { + if (items[i].matches(preset)) { + return items[i]; + } + } + + return null; }; - } - function parseTurnLanes(tag) { - if (!tag) return; - var validValues = ['left', 'slight_left', 'sharp_left', 'through', 'right', 'slight_right', 'sharp_right', 'reverse', 'merge_to_left', 'merge_to_right', 'none']; - return tag.split('|').map(function (s) { - if (s === '') s = 'none'; - return s.split(';').map(function (d) { - return validValues.indexOf(d) === -1 ? 'unknown' : d; - }); - }); - } + _this.moveItem = function (items, fromIndex, toIndex) { + if (fromIndex === toIndex || fromIndex < 0 || toIndex < 0 || fromIndex >= items.length || toIndex >= items.length) return null; + items.splice(toIndex, 0, items.splice(fromIndex, 1)[0]); + return items; + }; - function parseMaxspeedLanes(tag, maxspeed) { - if (!tag) return; - return tag.split('|').map(function (s) { - if (s === 'none') return s; - var m = parseInt(s, 10); - if (s === '' || m === maxspeed) return null; - return isNaN(m) ? 'unknown' : m; - }); - } + _this.moveRecent = function (item, beforeItem) { + var recents = _this.getRecents(); - function parseMiscLanes(tag) { - if (!tag) return; - var validValues = ['yes', 'no', 'designated']; - return tag.split('|').map(function (s) { - if (s === '') s = 'no'; - return validValues.indexOf(s) === -1 ? 'unknown' : s; - }); - } + var fromIndex = recents.indexOf(item); + var toIndex = recents.indexOf(beforeItem); - function parseBicycleWay(tag) { - if (!tag) return; - var validValues = ['yes', 'no', 'designated', 'lane']; - return tag.split('|').map(function (s) { - if (s === '') s = 'no'; - return validValues.indexOf(s) === -1 ? 'unknown' : s; - }); - } + var items = _this.moveItem(recents, fromIndex, toIndex); - function mapToLanesObj(lanesObj, data, key) { - if (data.forward) { - data.forward.forEach(function (l, i) { - if (!lanesObj.forward[i]) lanesObj.forward[i] = {}; - lanesObj.forward[i][key] = l; - }); - } + if (items) setRecents(items); + }; - if (data.backward) { - data.backward.forEach(function (l, i) { - if (!lanesObj.backward[i]) lanesObj.backward[i] = {}; - lanesObj.backward[i][key] = l; - }); - } + _this.setMostRecent = function (preset) { + if (preset.searchable === false) return; - if (data.unspecified) { - data.unspecified.forEach(function (l, i) { - if (!lanesObj.unspecified[i]) lanesObj.unspecified[i] = {}; - lanesObj.unspecified[i][key] = l; + var items = _this.getRecents(); + + var item = _this.recentMatching(preset); + + if (item) { + items.splice(items.indexOf(item), 1); + } else { + item = RibbonItem(preset, 'recent'); + } // remove the last recent (first in, first out) + + + while (items.length >= MAXRECENTS) { + items.pop(); + } // prepend array + + + items.unshift(item); + setRecents(items); + }; + + function setFavorites(items) { + _favorites = items; + var minifiedItems = items.map(function (d) { + return d.minified(); }); - } - } + corePreferences('preset_favorites', JSON.stringify(minifiedItems)); // call update - function osmWay() { - if (!(this instanceof osmWay)) { - return new osmWay().initialize(arguments); - } else if (arguments.length) { - this.initialize(arguments); + dispatch.call('favoritePreset'); } - } - osmEntity.way = osmWay; - osmWay.prototype = Object.create(osmEntity.prototype); - Object.assign(osmWay.prototype, { - type: 'way', - nodes: [], - copy: function copy(resolver, copies) { - if (copies[this.id]) return copies[this.id]; - var copy = osmEntity.prototype.copy.call(this, resolver, copies); - var nodes = this.nodes.map(function (id) { - return resolver.entity(id).copy(resolver, copies).id; - }); - copy = copy.update({ - nodes: nodes - }); - copies[this.id] = copy; - return copy; - }, - extent: function extent(resolver) { - return resolver["transient"](this, 'extent', function () { - var extent = geoExtent(); - for (var i = 0; i < this.nodes.length; i++) { - var node = resolver.hasEntity(this.nodes[i]); + _this.addFavorite = function (preset, besidePreset, after) { + var favorites = _this.getFavorites(); - if (node) { - extent._extend(node.extent()); - } - } + var beforeItem = _this.favoriteMatching(besidePreset); - return extent; - }); - }, - first: function first() { - return this.nodes[0]; - }, - last: function last() { - return this.nodes[this.nodes.length - 1]; - }, - contains: function contains(node) { - return this.nodes.indexOf(node) >= 0; - }, - affix: function affix(node) { - if (this.nodes[0] === node) return 'prefix'; - if (this.nodes[this.nodes.length - 1] === node) return 'suffix'; - }, - layer: function layer() { - // explicit layer tag, clamp between -10, 10.. - if (isFinite(this.tags.layer)) { - return Math.max(-10, Math.min(+this.tags.layer, 10)); - } // implied layer tag.. + var toIndex = favorites.indexOf(beforeItem); + if (after) toIndex += 1; + var newItem = RibbonItem(preset, 'favorite'); + favorites.splice(toIndex, 0, newItem); + setFavorites(favorites); + }; + _this.toggleFavorite = function (preset) { + var favs = _this.getFavorites(); - if (this.tags.covered === 'yes') return -1; - if (this.tags.location === 'overground') return 1; - if (this.tags.location === 'underground') return -1; - if (this.tags.location === 'underwater') return -10; - if (this.tags.power === 'line') return 10; - if (this.tags.power === 'minor_line') return 10; - if (this.tags.aerialway) return 10; - if (this.tags.bridge) return 1; - if (this.tags.cutting) return -1; - if (this.tags.tunnel) return -1; - if (this.tags.waterway) return -1; - if (this.tags.man_made === 'pipeline') return -10; - if (this.tags.boundary) return -10; - return 0; - }, - // the approximate width of the line based on its tags except its `width` tag - impliedLineWidthMeters: function impliedLineWidthMeters() { - var averageWidths = { - highway: { - // width is for single lane - motorway: 5, - motorway_link: 5, - trunk: 4.5, - trunk_link: 4.5, - primary: 4, - secondary: 4, - tertiary: 4, - primary_link: 4, - secondary_link: 4, - tertiary_link: 4, - unclassified: 4, - road: 4, - living_street: 4, - bus_guideway: 4, - pedestrian: 4, - residential: 3.5, - service: 3.5, - track: 3, - cycleway: 2.5, - bridleway: 2, - corridor: 2, - steps: 2, - path: 1.5, - footway: 1.5 - }, - railway: { - // width includes ties and rail bed, not just track gauge - rail: 2.5, - light_rail: 2.5, - tram: 2.5, - subway: 2.5, - monorail: 2.5, - funicular: 2.5, - disused: 2.5, - preserved: 2.5, - miniature: 1.5, - narrow_gauge: 1.5 - }, - waterway: { - river: 50, - canal: 25, - stream: 5, - tidal_channel: 5, - fish_pass: 2.5, - drain: 2.5, - ditch: 1.5 - } - }; + var favorite = _this.favoriteMatching(preset); - for (var key in averageWidths) { - if (this.tags[key] && averageWidths[key][this.tags[key]]) { - var width = averageWidths[key][this.tags[key]]; + if (favorite) { + favs.splice(favs.indexOf(favorite), 1); + } else { + // only allow 10 favorites + if (favs.length === 10) { + // remove the last favorite (last in, first out) + favs.pop(); + } // append array - if (key === 'highway') { - var laneCount = this.tags.lanes && parseInt(this.tags.lanes, 10); - if (!laneCount) laneCount = this.isOneWay() ? 1 : 2; - return width * laneCount; - } - return width; - } + favs.push(RibbonItem(preset, 'favorite')); } - return null; - }, - isOneWay: function isOneWay() { - // explicit oneway tag.. - var values = { - 'yes': true, - '1': true, - '-1': true, - 'reversible': true, - 'alternating': true, - 'no': false, - '0': false - }; + setFavorites(favs); + }; - if (values[this.tags.oneway] !== undefined) { - return values[this.tags.oneway]; - } // implied oneway tag.. + _this.removeFavorite = function (preset) { + var item = _this.favoriteMatching(preset); + if (item) { + var items = _this.getFavorites(); - for (var key in this.tags) { - if (key in osmOneWayTags && this.tags[key] in osmOneWayTags[key]) { - return true; + items.splice(items.indexOf(item), 1); + setFavorites(items); + } + }; + + _this.getFavorites = function () { + if (!_favorites) { + // fetch from local storage + var rawFavorites = JSON.parse(corePreferences('preset_favorites')); + + if (!rawFavorites) { + rawFavorites = []; + corePreferences('preset_favorites', JSON.stringify(rawFavorites)); } + + _favorites = rawFavorites.reduce(function (output, d) { + var item = ribbonItemForMinified(d, 'favorite'); + if (item && item.preset.addable()) output.push(item); + return output; + }, []); } - return false; - }, - // Some identifier for tag that implies that this way is "sided", - // i.e. the right side is the 'inside' (e.g. the right side of a - // natural=cliff is lower). - sidednessIdentifier: function sidednessIdentifier() { - for (var key in this.tags) { - var value = this.tags[key]; + return _favorites; + }; - if (key in osmRightSideIsInsideTags && value in osmRightSideIsInsideTags[key]) { - if (osmRightSideIsInsideTags[key][value] === true) { - return key; - } else { - // if the map's value is something other than a - // literal true, we should use it so we can - // special case some keys (e.g. natural=coastline - // is handled differently to other naturals). - return osmRightSideIsInsideTags[key][value]; - } + _this.favoriteMatching = function (preset) { + var favs = _this.getFavorites(); + + for (var index in favs) { + if (favs[index].matches(preset)) { + return favs[index]; } } return null; - }, - isSided: function isSided() { - if (this.tags.two_sided === 'yes') { - return false; - } + }; - return this.sidednessIdentifier() !== null; - }, - lanes: function lanes() { - return osmLanes(this); - }, - isClosed: function isClosed() { - return this.nodes.length > 1 && this.first() === this.last(); - }, - isConvex: function isConvex(resolver) { - if (!this.isClosed() || this.isDegenerate()) return null; - var nodes = utilArrayUniq(resolver.childNodes(this)); - var coords = nodes.map(function (n) { - return n.loc; - }); - var curr = 0; - var prev = 0; + return utilRebind(_this, dispatch, 'on'); + } - for (var i = 0; i < coords.length; i++) { - var o = coords[(i + 1) % coords.length]; - var a = coords[i]; - var b = coords[(i + 2) % coords.length]; - var res = geoVecCross(a, b, o); - curr = res > 0 ? 1 : res < 0 ? -1 : 0; + function utilTagText(entity) { + var obj = entity && entity.tags || {}; + return Object.keys(obj).map(function (k) { + return k + '=' + obj[k]; + }).join(', '); + } + function utilTotalExtent(array, graph) { + var extent = geoExtent(); + var val, entity; - if (curr === 0) { - continue; - } else if (prev && curr !== prev) { - return false; - } + for (var i = 0; i < array.length; i++) { + val = array[i]; + entity = typeof val === 'string' ? graph.hasEntity(val) : val; - prev = curr; + if (entity) { + extent._extend(entity.extent(graph)); } + } - return true; - }, - // returns an object with the tag that implies this is an area, if any - tagSuggestingArea: function tagSuggestingArea() { - return osmTagSuggestingArea(this.tags); - }, - isArea: function isArea() { - if (this.tags.area === 'yes') return true; - if (!this.isClosed() || this.tags.area === 'no') return false; - return this.tagSuggestingArea() !== null; - }, - isDegenerate: function isDegenerate() { - return new Set(this.nodes).size < (this.isArea() ? 3 : 2); - }, - areAdjacent: function areAdjacent(n1, n2) { - for (var i = 0; i < this.nodes.length; i++) { - if (this.nodes[i] === n1) { - if (this.nodes[i - 1] === n2) return true; - if (this.nodes[i + 1] === n2) return true; - } - } + return extent; + } + function utilTagDiff(oldTags, newTags) { + var tagDiff = []; + var keys = utilArrayUnion(Object.keys(oldTags), Object.keys(newTags)).sort(); + keys.forEach(function (k) { + var oldVal = oldTags[k]; + var newVal = newTags[k]; - return false; - }, - geometry: function geometry(graph) { - return graph["transient"](this, 'geometry', function () { - return this.isArea() ? 'area' : 'line'; - }); - }, - // returns an array of objects representing the segments between the nodes in this way - segments: function segments(graph) { - function segmentExtent(graph) { - var n1 = graph.hasEntity(this.nodes[0]); - var n2 = graph.hasEntity(this.nodes[1]); - return n1 && n2 && geoExtent([[Math.min(n1.loc[0], n2.loc[0]), Math.min(n1.loc[1], n2.loc[1])], [Math.max(n1.loc[0], n2.loc[0]), Math.max(n1.loc[1], n2.loc[1])]]); + if ((oldVal || oldVal === '') && (newVal === undefined || newVal !== oldVal)) { + tagDiff.push({ + type: '-', + key: k, + oldVal: oldVal, + newVal: newVal, + display: '- ' + k + '=' + oldVal + }); } - return graph["transient"](this, 'segments', function () { - var segments = []; + if ((newVal || newVal === '') && (oldVal === undefined || newVal !== oldVal)) { + tagDiff.push({ + type: '+', + key: k, + oldVal: oldVal, + newVal: newVal, + display: '+ ' + k + '=' + newVal + }); + } + }); + return tagDiff; + } + function utilEntitySelector(ids) { + return ids.length ? '.' + ids.join(',.') : 'nothing'; + } // returns an selector to select entity ids for: + // - entityIDs passed in + // - shallow descendant entityIDs for any of those entities that are relations - for (var i = 0; i < this.nodes.length - 1; i++) { - segments.push({ - id: this.id + '-' + i, - wayId: this.id, - index: i, - nodes: [this.nodes[i], this.nodes[i + 1]], - extent: segmentExtent - }); - } + function utilEntityOrMemberSelector(ids, graph) { + var seen = new Set(ids); + ids.forEach(collectShallowDescendants); + return utilEntitySelector(Array.from(seen)); - return segments; - }); - }, - // If this way is not closed, append the beginning node to the end of the nodelist to close it. - close: function close() { - if (this.isClosed() || !this.nodes.length) return this; - var nodes = this.nodes.slice(); - nodes = nodes.filter(noRepeatNodes); - nodes.push(nodes[0]); - return this.update({ - nodes: nodes + function collectShallowDescendants(id) { + var entity = graph.hasEntity(id); + if (!entity || entity.type !== 'relation') return; + entity.members.map(function (member) { + return member.id; + }).forEach(function (id) { + seen.add(id); }); - }, - // If this way is closed, remove any connector nodes from the end of the nodelist to unclose it. - unclose: function unclose() { - if (!this.isClosed()) return this; - var nodes = this.nodes.slice(); - var connector = this.first(); - var i = nodes.length - 1; // remove trailing connectors.. + } + } // returns an selector to select entity ids for: + // - entityIDs passed in + // - deep descendant entityIDs for any of those entities that are relations - while (i > 0 && nodes.length > 1 && nodes[i] === connector) { - nodes.splice(i, 1); - i = nodes.length - 1; - } + function utilEntityOrDeepMemberSelector(ids, graph) { + return utilEntitySelector(utilEntityAndDeepMemberIDs(ids, graph)); + } // returns an selector to select entity ids for: + // - entityIDs passed in + // - deep descendant entityIDs for any of those entities that are relations - nodes = nodes.filter(noRepeatNodes); - return this.update({ - nodes: nodes - }); - }, - // Adds a node (id) in front of the node which is currently at position index. - // If index is undefined, the node will be added to the end of the way for linear ways, - // or just before the final connecting node for circular ways. - // Consecutive duplicates are eliminated including existing ones. - // Circularity is always preserved when adding a node. - addNode: function addNode(id, index) { - var nodes = this.nodes.slice(); - var isClosed = this.isClosed(); - var max = isClosed ? nodes.length - 1 : nodes.length; + function utilEntityAndDeepMemberIDs(ids, graph) { + var seen = new Set(); + ids.forEach(collectDeepDescendants); + return Array.from(seen); - if (index === undefined) { - index = max; - } + function collectDeepDescendants(id) { + if (seen.has(id)) return; + seen.add(id); + var entity = graph.hasEntity(id); + if (!entity || entity.type !== 'relation') return; + entity.members.map(function (member) { + return member.id; + }).forEach(collectDeepDescendants); // recurse + } + } // returns an selector to select entity ids for: + // - deep descendant entityIDs for any of those entities that are relations - if (index < 0 || index > max) { - throw new RangeError('index ' + index + ' out of range 0..' + max); - } // If this is a closed way, remove all connector nodes except the first one - // (there may be duplicates) and adjust index if necessary.. + function utilDeepMemberSelector(ids, graph, skipMultipolgonMembers) { + var idsSet = new Set(ids); + var seen = new Set(); + var returners = new Set(); + ids.forEach(collectDeepDescendants); + return utilEntitySelector(Array.from(returners)); + function collectDeepDescendants(id) { + if (seen.has(id)) return; + seen.add(id); - if (isClosed) { - var connector = this.first(); // leading connectors.. + if (!idsSet.has(id)) { + returners.add(id); + } - var i = 1; + var entity = graph.hasEntity(id); + if (!entity || entity.type !== 'relation') return; + if (skipMultipolgonMembers && entity.isMultipolygon()) return; + entity.members.map(function (member) { + return member.id; + }).forEach(collectDeepDescendants); // recurse + } + } // Adds or removes highlight styling for the specified entities - while (i < nodes.length && nodes.length > 2 && nodes[i] === connector) { - nodes.splice(i, 1); - if (index > i) index--; - } // trailing connectors.. + function utilHighlightEntities(ids, highlighted, context) { + context.surface().selectAll(utilEntityOrDeepMemberSelector(ids, context.graph())).classed('highlighted', highlighted); + } // returns an Array that is the union of: + // - nodes for any nodeIDs passed in + // - child nodes of any wayIDs passed in + // - descendant member and child nodes of relationIDs passed in + function utilGetAllNodes(ids, graph) { + var seen = new Set(); + var nodes = new Set(); + ids.forEach(collectNodes); + return Array.from(nodes); - i = nodes.length - 1; + function collectNodes(id) { + if (seen.has(id)) return; + seen.add(id); + var entity = graph.hasEntity(id); + if (!entity) return; - while (i > 0 && nodes.length > 1 && nodes[i] === connector) { - nodes.splice(i, 1); - if (index > i) index--; - i = nodes.length - 1; - } + if (entity.type === 'node') { + nodes.add(entity); + } else if (entity.type === 'way') { + entity.nodes.forEach(collectNodes); + } else { + entity.members.map(function (member) { + return member.id; + }).forEach(collectNodes); // recurse } + } + } + function utilDisplayName(entity) { + var localizedNameKey = 'name:' + _mainLocalizer.languageCode().toLowerCase(); + var name = entity.tags[localizedNameKey] || entity.tags.name || ''; + if (name) return name; + var tags = { + direction: entity.tags.direction, + from: entity.tags.from, + network: entity.tags.cycle_network || entity.tags.network, + ref: entity.tags.ref, + to: entity.tags.to, + via: entity.tags.via + }; + var keyComponents = []; - nodes.splice(index, 0, id); - nodes = nodes.filter(noRepeatNodes); // If the way was closed before, append a connector node to keep it closed.. + if (tags.network) { + keyComponents.push('network'); + } - if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) { - nodes.push(nodes[0]); - } + if (tags.ref) { + keyComponents.push('ref'); + } // Routes may need more disambiguation based on direction or destination - return this.update({ - nodes: nodes - }); - }, - // Replaces the node which is currently at position index with the given node (id). - // Consecutive duplicates are eliminated including existing ones. - // Circularity is preserved when updating a node. - updateNode: function updateNode(id, index) { - var nodes = this.nodes.slice(); - var isClosed = this.isClosed(); - var max = nodes.length - 1; - if (index === undefined || index < 0 || index > max) { - throw new RangeError('index ' + index + ' out of range 0..' + max); - } // If this is a closed way, remove all connector nodes except the first one - // (there may be duplicates) and adjust index if necessary.. + if (entity.tags.route) { + if (tags.direction) { + keyComponents.push('direction'); + } else if (tags.from && tags.to) { + keyComponents.push('from'); + keyComponents.push('to'); + if (tags.via) { + keyComponents.push('via'); + } + } + } - if (isClosed) { - var connector = this.first(); // leading connectors.. + if (keyComponents.length) { + name = _t('inspector.display_name.' + keyComponents.join('_'), tags); + } - var i = 1; + return name; + } + function utilDisplayNameForPath(entity) { + var name = utilDisplayName(entity); + var isFirefox = utilDetect().browser.toLowerCase().indexOf('firefox') > -1; + var isNewChromium = Number(utilDetect().version.split('.')[0]) >= 96.0; - while (i < nodes.length && nodes.length > 2 && nodes[i] === connector) { - nodes.splice(i, 1); - if (index > i) index--; - } // trailing connectors.. + if (!isFirefox && !isNewChromium && name && rtlRegex.test(name)) { + name = fixRTLTextForSvg(name); + } + return name; + } + function utilDisplayType(id) { + return { + n: _t('inspector.node'), + w: _t('inspector.way'), + r: _t('inspector.relation') + }[id.charAt(0)]; + } // `utilDisplayLabel` + // Returns a string suitable for display + // By default returns something like name/ref, fallback to preset type, fallback to OSM type + // "Main Street" or "Tertiary Road" + // If `verbose=true`, include both preset name and feature name. + // "Tertiary Road Main Street" + // - i = nodes.length - 1; + function utilDisplayLabel(entity, graphOrGeometry, verbose) { + var result; + var displayName = utilDisplayName(entity); + var preset = typeof graphOrGeometry === 'string' ? _mainPresetIndex.matchTags(entity.tags, graphOrGeometry) : _mainPresetIndex.match(entity, graphOrGeometry); + var presetName = preset && (preset.suggestion ? preset.subtitle() : preset.name()); - while (i > 0 && nodes.length > 1 && nodes[i] === connector) { - nodes.splice(i, 1); - if (index === i) index = 0; // update leading connector instead + if (verbose) { + result = [presetName, displayName].filter(Boolean).join(' '); + } else { + result = displayName || presetName; + } // Fallback to the OSM type (node/way/relation) - i = nodes.length - 1; - } - } - nodes.splice(index, 1, id); - nodes = nodes.filter(noRepeatNodes); // If the way was closed before, append a connector node to keep it closed.. + return result || utilDisplayType(entity.id); + } + function utilEntityRoot(entityType) { + return { + node: 'n', + way: 'w', + relation: 'r' + }[entityType]; + } // Returns a single object containing the tags of all the given entities. + // Example: + // { + // highway: 'service', + // service: 'parking_aisle' + // } + // + + // { + // highway: 'service', + // service: 'driveway', + // width: '3' + // } + // = + // { + // highway: 'service', + // service: [ 'driveway', 'parking_aisle' ], + // width: [ '3', undefined ] + // } - if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) { - nodes.push(nodes[0]); - } + function utilCombinedTags(entityIDs, graph) { + var tags = {}; + var tagCounts = {}; + var allKeys = new Set(); + var entities = entityIDs.map(function (entityID) { + return graph.hasEntity(entityID); + }).filter(Boolean); // gather the aggregate keys - return this.update({ - nodes: nodes + entities.forEach(function (entity) { + var keys = Object.keys(entity.tags).filter(Boolean); + keys.forEach(function (key) { + allKeys.add(key); }); - }, - // Replaces each occurrence of node id needle with replacement. - // Consecutive duplicates are eliminated including existing ones. - // Circularity is preserved. - replaceNode: function replaceNode(needleID, replacementID) { - var nodes = this.nodes.slice(); - var isClosed = this.isClosed(); + }); + entities.forEach(function (entity) { + allKeys.forEach(function (key) { + var value = entity.tags[key]; // purposely allow `undefined` - for (var i = 0; i < nodes.length; i++) { - if (nodes[i] === needleID) { - nodes[i] = replacementID; + if (!tags.hasOwnProperty(key)) { + // first value, set as raw + tags[key] = value; + } else { + if (!Array.isArray(tags[key])) { + if (tags[key] !== value) { + // first alternate value, replace single value with array + tags[key] = [tags[key], value]; + } + } else { + // type is array + if (tags[key].indexOf(value) === -1) { + // subsequent alternate value, add to array + tags[key].push(value); + } + } } - } - - nodes = nodes.filter(noRepeatNodes); // If the way was closed before, append a connector node to keep it closed.. - - if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) { - nodes.push(nodes[0]); - } - - return this.update({ - nodes: nodes - }); - }, - // Removes each occurrence of node id. - // Consecutive duplicates are eliminated including existing ones. - // Circularity is preserved. - removeNode: function removeNode(id) { - var nodes = this.nodes.slice(); - var isClosed = this.isClosed(); - nodes = nodes.filter(function (node) { - return node !== id; - }).filter(noRepeatNodes); // If the way was closed before, append a connector node to keep it closed.. - - if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) { - nodes.push(nodes[0]); - } - return this.update({ - nodes: nodes + var tagHash = key + '=' + value; + if (!tagCounts[tagHash]) tagCounts[tagHash] = 0; + tagCounts[tagHash] += 1; }); - }, - asJXON: function asJXON(changeset_id) { - var r = { - way: { - '@id': this.osmId(), - '@version': this.version || 0, - nd: this.nodes.map(function (id) { - return { - keyAttributes: { - ref: osmEntity.id.toOSM(id) - } - }; - }, this), - tag: Object.keys(this.tags).map(function (k) { - return { - keyAttributes: { - k: k, - v: this.tags[k] - } - }; - }, this) - } - }; + }); - if (changeset_id) { - r.way['@changeset'] = changeset_id; - } + for (var key in tags) { + if (!Array.isArray(tags[key])) continue; // sort values by frequency then alphabetically - return r; - }, - asGeoJSON: function asGeoJSON(resolver) { - return resolver["transient"](this, 'GeoJSON', function () { - var coordinates = resolver.childNodes(this).map(function (n) { - return n.loc; - }); + tags[key] = tags[key].sort(function (val1, val2) { + var key = key; // capture - if (this.isArea() && this.isClosed()) { - return { - type: 'Polygon', - coordinates: [coordinates] - }; - } else { - return { - type: 'LineString', - coordinates: coordinates - }; - } - }); - }, - area: function area(resolver) { - return resolver["transient"](this, 'area', function () { - var nodes = resolver.childNodes(this); - var json = { - type: 'Polygon', - coordinates: [nodes.map(function (n) { - return n.loc; - })] - }; + var count2 = tagCounts[key + '=' + val2]; + var count1 = tagCounts[key + '=' + val1]; - if (!this.isClosed() && nodes.length) { - json.coordinates[0].push(nodes[0].loc); + if (count2 !== count1) { + return count2 - count1; } - var area = d3_geoArea(json); // Heuristic for detecting counterclockwise winding order. Assumes - // that OpenStreetMap polygons are not hemisphere-spanning. - - if (area > 2 * Math.PI) { - json.coordinates[0] = json.coordinates[0].reverse(); - area = d3_geoArea(json); + if (val2 && val1) { + return val1.localeCompare(val2); } - return isNaN(area) ? 0 : area; + return val1 ? 1 : -1; }); } - }); // Filter function to eliminate consecutive duplicates. - function noRepeatNodes(node, i, arr) { - return i === 0 || node !== arr[i - 1]; + return tags; } + function utilStringQs(str) { + var i = 0; // advance past any leading '?' or '#' characters - // - // 1. Relation tagged with `type=multipolygon` and no interesting tags. - // 2. One and only one member with the `outer` role. Must be a way with interesting tags. - // 3. No members without a role. - // - // Old multipolygons are no longer recommended but are still rendered as areas by iD. - - function osmOldMultipolygonOuterMemberOfRelation(entity, graph) { - if (entity.type !== 'relation' || !entity.isMultipolygon() || Object.keys(entity.tags).filter(osmIsInterestingTag).length > 1) { - return false; + while (i < str.length && (str[i] === '?' || str[i] === '#')) { + i++; } - var outerMember; - - for (var memberIndex in entity.members) { - var member = entity.members[memberIndex]; - - if (!member.role || member.role === 'outer') { - if (outerMember) return false; - if (member.type !== 'way') return false; - if (!graph.hasEntity(member.id)) return false; - outerMember = graph.entity(member.id); + str = str.slice(i); + return str.split('&').reduce(function (obj, pair) { + var parts = pair.split('='); - if (Object.keys(outerMember.tags).filter(osmIsInterestingTag).length === 0) { - return false; - } + if (parts.length === 2) { + obj[parts[0]] = null === parts[1] ? '' : decodeURIComponent(parts[1]); } + + return obj; + }, {}); + } + function utilQsString(obj, noencode) { + // encode everything except special characters used in certain hash parameters: + // "/" in map states, ":", ",", {" and "}" in background + function softEncode(s) { + return encodeURIComponent(s).replace(/(%2F|%3A|%2C|%7B|%7D)/g, decodeURIComponent); } - return outerMember; - } // For fixing up rendering of multipolygons with tags on the outer member. - // https://github.com/openstreetmap/iD/issues/613 + return Object.keys(obj).sort().map(function (key) { + return encodeURIComponent(key) + '=' + (noencode ? softEncode(obj[key]) : encodeURIComponent(obj[key])); + }).join('&'); + } + function utilPrefixDOMProperty(property) { + var prefixes = ['webkit', 'ms', 'moz', 'o']; + var i = -1; + var n = prefixes.length; + var s = document.body; + if (property in s) return property; + property = property.substr(0, 1).toUpperCase() + property.substr(1); - function osmIsOldMultipolygonOuterMember(entity, graph) { - if (entity.type !== 'way' || Object.keys(entity.tags).filter(osmIsInterestingTag).length === 0) { - return false; + while (++i < n) { + if (prefixes[i] + property in s) { + return prefixes[i] + property; + } } - var parents = graph.parentRelations(entity); - if (parents.length !== 1) return false; - var parent = parents[0]; + return false; + } + function utilPrefixCSSProperty(property) { + var prefixes = ['webkit', 'ms', 'Moz', 'O']; + var i = -1; + var n = prefixes.length; + var s = document.body.style; - if (!parent.isMultipolygon() || Object.keys(parent.tags).filter(osmIsInterestingTag).length > 1) { - return false; + if (property.toLowerCase() in s) { + return property.toLowerCase(); } - var members = parent.members, - member; - - for (var i = 0; i < members.length; i++) { - member = members[i]; - - if (member.id === entity.id && member.role && member.role !== 'outer') { - // Not outer member - return false; - } - - if (member.id !== entity.id && (!member.role || member.role === 'outer')) { - // Not a simple multipolygon - return false; + while (++i < n) { + if (prefixes[i] + property in s) { + return '-' + prefixes[i].toLowerCase() + property.replace(/([A-Z])/g, '-$1').toLowerCase(); } } - return parent; + return false; } - function osmOldMultipolygonOuterMember(entity, graph) { - if (entity.type !== 'way') return false; - var parents = graph.parentRelations(entity); - if (parents.length !== 1) return false; - var parent = parents[0]; - - if (!parent.isMultipolygon() || Object.keys(parent.tags).filter(osmIsInterestingTag).length > 1) { - return false; - } + var transformProperty; + function utilSetTransform(el, x, y, scale) { + var prop = transformProperty = transformProperty || utilPrefixCSSProperty('Transform'); + var translate = utilDetect().opera ? 'translate(' + x + 'px,' + y + 'px)' : 'translate3d(' + x + 'px,' + y + 'px,0)'; + return el.style(prop, translate + (scale ? ' scale(' + scale + ')' : '')); + } // Calculates Levenshtein distance between two strings + // see: https://en.wikipedia.org/wiki/Levenshtein_distance + // first converts the strings to lowercase and replaces diacritic marks with ascii equivalents. - var members = parent.members, - member, - outerMember; + function utilEditDistance(a, b) { + a = remove$6(a.toLowerCase()); + b = remove$6(b.toLowerCase()); + if (a.length === 0) return b.length; + if (b.length === 0) return a.length; + var matrix = []; + var i, j; - for (var i = 0; i < members.length; i++) { - member = members[i]; + for (i = 0; i <= b.length; i++) { + matrix[i] = [i]; + } - if (!member.role || member.role === 'outer') { - if (outerMember) return false; // Not a simple multipolygon + for (j = 0; j <= a.length; j++) { + matrix[0][j] = j; + } - outerMember = member; + for (i = 1; i <= b.length; i++) { + for (j = 1; j <= a.length; j++) { + if (b.charAt(i - 1) === a.charAt(j - 1)) { + matrix[i][j] = matrix[i - 1][j - 1]; + } else { + matrix[i][j] = Math.min(matrix[i - 1][j - 1] + 1, // substitution + Math.min(matrix[i][j - 1] + 1, // insertion + matrix[i - 1][j] + 1)); // deletion + } } } - if (!outerMember) return false; - var outerEntity = graph.hasEntity(outerMember.id); + return matrix[b.length][a.length]; + } // a d3.mouse-alike which + // 1. Only works on HTML elements, not SVG + // 2. Does not cause style recalculation - if (!outerEntity || !Object.keys(outerEntity.tags).filter(osmIsInterestingTag).length) { - return false; + function utilFastMouse(container) { + var rect = container.getBoundingClientRect(); + var rectLeft = rect.left; + var rectTop = rect.top; + var clientLeft = +container.clientLeft; + var clientTop = +container.clientTop; + return function (e) { + return [e.clientX - rectLeft - clientLeft, e.clientY - rectTop - clientTop]; + }; + } + function utilAsyncMap(inputs, func, callback) { + var remaining = inputs.length; + var results = []; + var errors = []; + inputs.forEach(function (d, i) { + func(d, function done(err, data) { + errors[i] = err; + results[i] = data; + remaining--; + if (!remaining) callback(errors, results); + }); + }); + } // wraps an index to an interval [0..length-1] + + function utilWrap(index, length) { + if (index < 0) { + index += Math.ceil(-index / length) * length; } - return outerEntity; - } // Join `toJoin` array into sequences of connecting ways. - // Segments which share identical start/end nodes will, as much as possible, - // be connected with each other. - // - // The return value is a nested array. Each constituent array contains elements - // of `toJoin` which have been determined to connect. - // - // Each consitituent array also has a `nodes` property whose value is an - // ordered array of member nodes, with appropriate order reversal and - // start/end coordinate de-duplication. - // - // Members of `toJoin` must have, at minimum, `type` and `id` properties. - // Thus either an array of `osmWay`s or a relation member array may be used. - // - // If an member is an `osmWay`, its tags and childnodes may be reversed via - // `actionReverse` in the output. - // - // The returned sequences array also has an `actions` array property, containing - // any reversal actions that should be applied to the graph, should the calling - // code attempt to actually join the given ways. - // - // Incomplete members (those for which `graph.hasEntity(element.id)` returns - // false) and non-way members are ignored. - // + return index % length; + } + /** + * a replacement for functor + * + * @param {*} value any value + * @returns {Function} a function that returns that value or the value if it's a function + */ - function osmJoinWays(toJoin, graph) { - function resolve(member) { - return graph.childNodes(graph.entity(member.id)); + function utilFunctor(value) { + if (typeof value === 'function') return value; + return function () { + return value; + }; + } + function utilNoAuto(selection) { + var isText = selection.size() && selection.node().tagName.toLowerCase() === 'textarea'; + return selection // assign 'new-password' even for non-password fields to prevent browsers (Chrome) ignoring 'off' + .attr('autocomplete', 'new-password').attr('autocorrect', 'off').attr('autocapitalize', 'off').attr('spellcheck', isText ? 'true' : 'false'); + } // https://stackoverflow.com/questions/194846/is-there-any-kind-of-hash-code-function-in-javascript + // https://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-hashcode-method/ + + function utilHashcode(str) { + var hash = 0; + + if (str.length === 0) { + return hash; } - function reverse(item) { - var action = actionReverse(item.id, { - reverseOneway: true - }); - sequences.actions.push(action); - return item instanceof osmWay ? action(graph).entity(item.id) : item; - } // make a copy containing only the items to join + for (var i = 0; i < str.length; i++) { + var _char = str.charCodeAt(i); + hash = (hash << 5) - hash + _char; + hash = hash & hash; // Convert to 32bit integer + } - toJoin = toJoin.filter(function (member) { - return member.type === 'way' && graph.hasEntity(member.id); - }); // Are the things we are joining relation members or `osmWays`? - // If `osmWays`, skip the "prefer a forward path" code below (see #4872) + return hash; + } // Returns version of `str` with all runs of special characters replaced by `_`; + // suitable for HTML ids, classes, selectors, etc. - var i; - var joinAsMembers = true; + function utilSafeClassName(str) { + return str.toLowerCase().replace(/[^a-z0-9]+/g, '_'); + } // Returns string based on `val` that is highly unlikely to collide with an id + // used previously or that's present elsewhere in the document. Useful for preventing + // browser-provided autofills or when embedding iD on pages with unknown elements. - for (i = 0; i < toJoin.length; i++) { - if (toJoin[i] instanceof osmWay) { - joinAsMembers = false; - break; - } - } + function utilUniqueDomId(val) { + return 'ideditor-' + utilSafeClassName(val.toString()) + '-' + new Date().getTime().toString(); + } // Returns the length of `str` in unicode characters. This can be less than + // `String.length()` since a single unicode character can be composed of multiple + // JavaScript UTF-16 code units. - var sequences = []; - sequences.actions = []; + function utilUnicodeCharsCount(str) { + // Native ES2015 implementations of `Array.from` split strings into unicode characters + return Array.from(str).length; + } // Returns a new string representing `str` cut from its start to `limit` length + // in unicode characters. Note that this runs the risk of splitting graphemes. - while (toJoin.length) { - // start a new sequence - var item = toJoin.shift(); - var currWays = [item]; - var currNodes = resolve(item).slice(); // add to it + function utilUnicodeCharsTruncated(str, limit) { + return Array.from(str).slice(0, limit).join(''); + } - while (toJoin.length) { - var start = currNodes[0]; - var end = currNodes[currNodes.length - 1]; - var fn = null; - var nodes = null; // Find the next way/member to join. + function toNumericID(id) { + var match = id.match(/^[cnwr](-?\d+)$/); - for (i = 0; i < toJoin.length; i++) { - item = toJoin[i]; - nodes = resolve(item); // (for member ordering only, not way ordering - see #4872) - // Strongly prefer to generate a forward path that preserves the order - // of the members array. For multipolygons and most relations, member - // order does not matter - but for routes, it does. (see #4589) - // If we started this sequence backwards (i.e. next member way attaches to - // the start node and not the end node), reverse the initial way before continuing. + if (match) { + return parseInt(match[1], 10); + } - if (joinAsMembers && currWays.length === 1 && nodes[0] !== end && nodes[nodes.length - 1] !== end && (nodes[nodes.length - 1] === start || nodes[0] === start)) { - currWays[0] = reverse(currWays[0]); - currNodes.reverse(); - start = currNodes[0]; - end = currNodes[currNodes.length - 1]; - } + return NaN; + } - if (nodes[0] === end) { - fn = currNodes.push; // join to end + function compareNumericIDs(left, right) { + if (isNaN(left) && isNaN(right)) return -1; + if (isNaN(left)) return 1; + if (isNaN(right)) return -1; + if (Math.sign(left) !== Math.sign(right)) return -Math.sign(left); + if (Math.sign(left) < 0) return Math.sign(right - left); + return Math.sign(left - right); + } // Returns -1 if the first parameter ID is older than the second, + // 1 if the second parameter is older, 0 if they are the same. + // If both IDs are test IDs, the function returns -1. - nodes = nodes.slice(1); - break; - } else if (nodes[nodes.length - 1] === end) { - fn = currNodes.push; // join to end - nodes = nodes.slice(0, -1).reverse(); - item = reverse(item); - break; - } else if (nodes[nodes.length - 1] === start) { - fn = currNodes.unshift; // join to beginning + function utilCompareIDs(left, right) { + return compareNumericIDs(toNumericID(left), toNumericID(right)); + } // Returns the chronologically oldest ID in the list. + // Database IDs (with positive numbers) before editor ones (with negative numbers). + // Among each category, the closest number to 0 is the oldest. + // Test IDs (any string that does not conform to OSM's ID scheme) are taken last. - nodes = nodes.slice(0, -1); - break; - } else if (nodes[0] === start) { - fn = currNodes.unshift; // join to beginning + function utilOldestID(ids) { + if (ids.length === 0) { + return undefined; + } - nodes = nodes.slice(1).reverse(); - item = reverse(item); - break; - } else { - fn = nodes = null; - } - } + var oldestIDIndex = 0; + var oldestID = toNumericID(ids[0]); - if (!nodes) { - // couldn't find a joinable way/member - break; - } + for (var i = 1; i < ids.length; i++) { + var num = toNumericID(ids[i]); - fn.apply(currWays, [item]); - fn.apply(currNodes, nodes); - toJoin.splice(i, 1); + if (compareNumericIDs(oldestID, num) === 1) { + oldestIDIndex = i; + oldestID = num; } - - currWays.nodes = currNodes; - sequences.push(currWays); } - return sequences; + return ids[oldestIDIndex]; } - function actionAddMember(relationId, member, memberIndex, insertPair) { - return function action(graph) { - var relation = graph.entity(relationId); // There are some special rules for Public Transport v2 routes. + function osmEntity(attrs) { + // For prototypal inheritance. + if (this instanceof osmEntity) return; // Create the appropriate subtype. - var isPTv2 = /stop|platform/.test(member.role); + if (attrs && attrs.type) { + return osmEntity[attrs.type].apply(this, arguments); + } else if (attrs && attrs.id) { + return osmEntity[osmEntity.id.type(attrs.id)].apply(this, arguments); + } // Initialize a generic Entity (used only in tests). - if ((isNaN(memberIndex) || insertPair) && member.type === 'way' && !isPTv2) { - // Try to perform sensible inserts based on how the ways join together - graph = addWayMember(relation, graph); - } else { - // see https://wiki.openstreetmap.org/wiki/Public_transport#Service_routes - // Stops and Platforms for PTv2 should be ordered first. - // hack: We do not currently have the ability to place them in the exactly correct order. - if (isPTv2 && isNaN(memberIndex)) { - memberIndex = 0; - } - graph = graph.replace(relation.addMember(member, memberIndex)); - } + return new osmEntity().initialize(arguments); + } - return graph; - }; // Add a way member into the relation "wherever it makes sense". - // In this situation we were not supplied a memberIndex. + osmEntity.id = function (type) { + return osmEntity.id.fromOSM(type, osmEntity.id.next[type]--); + }; - function addWayMember(relation, graph) { - var groups, tempWay, item, i, j, k; // remove PTv2 stops and platforms before doing anything. + osmEntity.id.next = { + changeset: -1, + node: -1, + way: -1, + relation: -1 + }; - var PTv2members = []; - var members = []; + osmEntity.id.fromOSM = function (type, id) { + return type[0] + id; + }; - for (i = 0; i < relation.members.length; i++) { - var m = relation.members[i]; + osmEntity.id.toOSM = function (id) { + var match = id.match(/^[cnwr](-?\d+)$/); - if (/stop|platform/.test(m.role)) { - PTv2members.push(m); - } else { - members.push(m); - } - } + if (match) { + return match[1]; + } - relation = relation.update({ - members: members - }); + return ''; + }; - if (insertPair) { - // We're adding a member that must stay paired with an existing member. - // (This feature is used by `actionSplit`) - // - // This is tricky because the members may exist multiple times in the - // member list, and with different A-B/B-A ordering and different roles. - // (e.g. a bus route that loops out and back - #4589). - // - // Replace the existing member with a temporary way, - // so that `osmJoinWays` can treat the pair like a single way. - tempWay = osmWay({ - id: 'wTemp', - nodes: insertPair.nodes - }); - graph = graph.replace(tempWay); - var tempMember = { - id: tempWay.id, - type: 'way', - role: member.role - }; - var tempRelation = relation.replaceMember({ - id: insertPair.originalID - }, tempMember, true); - groups = utilArrayGroupBy(tempRelation.members, 'type'); - groups.way = groups.way || []; - } else { - // Add the member anywhere, one time. Just push and let `osmJoinWays` decide where to put it. - groups = utilArrayGroupBy(relation.members, 'type'); - groups.way = groups.way || []; - groups.way.push(member); - } + osmEntity.id.type = function (id) { + return { + 'c': 'changeset', + 'n': 'node', + 'w': 'way', + 'r': 'relation' + }[id[0]]; + }; // A function suitable for use as the second argument to d3.selection#data(). - members = withIndex(groups.way); - var joined = osmJoinWays(members, graph); // `joined` might not contain all of the way members, - // But will contain only the completed (downloaded) members - for (i = 0; i < joined.length; i++) { - var segment = joined[i]; - var nodes = segment.nodes.slice(); - var startIndex = segment[0].index; // j = array index in `members` where this segment starts + osmEntity.key = function (entity) { + return entity.id + 'v' + (entity.v || 0); + }; - for (j = 0; j < members.length; j++) { - if (members[j].index === startIndex) { - break; - } - } // k = each member in segment + var _deprecatedTagValuesByKey; + osmEntity.deprecatedTagValuesByKey = function (dataDeprecated) { + if (!_deprecatedTagValuesByKey) { + _deprecatedTagValuesByKey = {}; + dataDeprecated.forEach(function (d) { + var oldKeys = Object.keys(d.old); - for (k = 0; k < segment.length; k++) { - item = segment[k]; - var way = graph.entity(item.id); // If this is a paired item, generate members in correct order and role + if (oldKeys.length === 1) { + var oldKey = oldKeys[0]; + var oldValue = d.old[oldKey]; - if (tempWay && item.id === tempWay.id) { - if (nodes[0].id === insertPair.nodes[0]) { - item.pair = [{ - id: insertPair.originalID, - type: 'way', - role: item.role - }, { - id: insertPair.insertedID, - type: 'way', - role: item.role - }]; + if (oldValue !== '*') { + if (!_deprecatedTagValuesByKey[oldKey]) { + _deprecatedTagValuesByKey[oldKey] = [oldValue]; } else { - item.pair = [{ - id: insertPair.insertedID, - type: 'way', - role: item.role - }, { - id: insertPair.originalID, - type: 'way', - role: item.role - }]; + _deprecatedTagValuesByKey[oldKey].push(oldValue); } - } // reorder `members` if necessary + } + } + }); + } + return _deprecatedTagValuesByKey; + }; - if (k > 0) { - if (j + k >= members.length || item.index !== members[j + k].index) { - moveMember(members, item.index, j + k); + osmEntity.prototype = { + tags: {}, + initialize: function initialize(sources) { + for (var i = 0; i < sources.length; ++i) { + var source = sources[i]; + + for (var prop in source) { + if (Object.prototype.hasOwnProperty.call(source, prop)) { + if (source[prop] === undefined) { + delete this[prop]; + } else { + this[prop] = source[prop]; } } - - nodes.splice(0, way.nodes.length - 1); } } - if (tempWay) { - graph = graph.remove(tempWay); - } // Final pass: skip dead items, split pairs, remove index properties + if (!this.id && this.type) { + this.id = osmEntity.id(this.type); + } + if (!this.hasOwnProperty('visible')) { + this.visible = true; + } - var wayMembers = []; + if (debug) { + Object.freeze(this); + Object.freeze(this.tags); + if (this.loc) Object.freeze(this.loc); + if (this.nodes) Object.freeze(this.nodes); + if (this.members) Object.freeze(this.members); + } - for (i = 0; i < members.length; i++) { - item = members[i]; - if (item.index === -1) continue; + return this; + }, + copy: function copy(resolver, copies) { + if (copies[this.id]) return copies[this.id]; + var copy = osmEntity(this, { + id: undefined, + user: undefined, + version: undefined + }); + copies[this.id] = copy; + return copy; + }, + osmId: function osmId() { + return osmEntity.id.toOSM(this.id); + }, + isNew: function isNew() { + var osmId = osmEntity.id.toOSM(this.id); + return osmId.length === 0 || osmId[0] === '-'; + }, + update: function update(attrs) { + return osmEntity(this, attrs, { + v: 1 + (this.v || 0) + }); + }, + mergeTags: function mergeTags(tags) { + var merged = Object.assign({}, this.tags); // shallow copy - if (item.pair) { - wayMembers.push(item.pair[0]); - wayMembers.push(item.pair[1]); - } else { - wayMembers.push(utilObjectOmit(item, ['index'])); - } - } // Put stops and platforms first, then nodes, ways, relations - // This is recommended for Public Transport v2 routes: - // see https://wiki.openstreetmap.org/wiki/Public_transport#Service_routes + var changed = false; + for (var k in tags) { + var t1 = merged[k]; + var t2 = tags[k]; - var newMembers = PTv2members.concat(groups.node || [], wayMembers, groups.relation || []); - return graph.replace(relation.update({ - members: newMembers - })); // `moveMember()` changes the `members` array in place by splicing - // the item with `.index = findIndex` to where it belongs, - // and marking the old position as "dead" with `.index = -1` - // - // j=5, k=0 jk - // segment 5 4 7 6 - // members 0 1 2 3 4 5 6 7 8 9 keep 5 in j+k - // - // j=5, k=1 j k - // segment 5 4 7 6 - // members 0 1 2 3 4 5 6 7 8 9 move 4 to j+k - // members 0 1 2 3 x 5 4 6 7 8 9 moved - // - // j=5, k=2 j k - // segment 5 4 7 6 - // members 0 1 2 3 x 5 4 6 7 8 9 move 7 to j+k - // members 0 1 2 3 x 5 4 7 6 x 8 9 moved - // - // j=5, k=3 j k - // segment 5 4 7 6 - // members 0 1 2 3 x 5 4 7 6 x 8 9 keep 6 in j+k - // + if (!t1) { + changed = true; + merged[k] = t2; + } else if (t1 !== t2) { + changed = true; + merged[k] = utilUnicodeCharsTruncated(utilArrayUnion(t1.split(/;\s*/), t2.split(/;\s*/)).join(';'), 255 // avoid exceeding character limit; see also services/osm.js -> maxCharsForTagValue() + ); + } + } - function moveMember(arr, findIndex, toIndex) { - var i; + return changed ? this.update({ + tags: merged + }) : this; + }, + intersects: function intersects(extent, resolver) { + return this.extent(resolver).intersects(extent); + }, + hasNonGeometryTags: function hasNonGeometryTags() { + return Object.keys(this.tags).some(function (k) { + return k !== 'area'; + }); + }, + hasParentRelations: function hasParentRelations(resolver) { + return resolver.parentRelations(this).length > 0; + }, + hasInterestingTags: function hasInterestingTags() { + return Object.keys(this.tags).some(osmIsInterestingTag); + }, + isHighwayIntersection: function isHighwayIntersection() { + return false; + }, + isDegenerate: function isDegenerate() { + return true; + }, + deprecatedTags: function deprecatedTags(dataDeprecated) { + var tags = this.tags; // if there are no tags, none can be deprecated - for (i = 0; i < arr.length; i++) { - if (arr[i].index === findIndex) { - break; - } + if (Object.keys(tags).length === 0) return []; + var deprecated = []; + dataDeprecated.forEach(function (d) { + var oldKeys = Object.keys(d.old); + + if (d.replace) { + var hasExistingValues = Object.keys(d.replace).some(function (replaceKey) { + if (!tags[replaceKey] || d.old[replaceKey]) return false; + var replaceValue = d.replace[replaceKey]; + if (replaceValue === '*') return false; + if (replaceValue === tags[replaceKey]) return false; + return true; + }); // don't flag deprecated tags if the upgrade path would overwrite existing data - #7843 + + if (hasExistingValues) return; } - var item = Object.assign({}, arr[i]); // shallow copy + var matchesDeprecatedTags = oldKeys.every(function (oldKey) { + if (!tags[oldKey]) return false; + if (d.old[oldKey] === '*') return true; + if (d.old[oldKey] === tags[oldKey]) return true; + var vals = tags[oldKey].split(';').filter(Boolean); - arr[i].index = -1; // mark as dead + if (vals.length === 0) { + return false; + } else if (vals.length > 1) { + return vals.indexOf(d.old[oldKey]) !== -1; + } else { + if (tags[oldKey] === d.old[oldKey]) { + if (d.replace && d.old[oldKey] === d.replace[oldKey]) { + var replaceKeys = Object.keys(d.replace); + return !replaceKeys.every(function (replaceKey) { + return tags[replaceKey] === d.replace[replaceKey]; + }); + } else { + return true; + } + } + } - item.index = toIndex; - arr.splice(toIndex, 0, item); - } // This is the same as `Relation.indexedMembers`, - // Except we don't want to index all the members, only the ways + return false; + }); + if (matchesDeprecatedTags) { + deprecated.push(d); + } + }); + return deprecated; + } + }; - function withIndex(arr) { - var result = new Array(arr.length); + function osmLanes(entity) { + if (entity.type !== 'way') return null; + if (!entity.tags.highway) return null; + var tags = entity.tags; + var isOneWay = entity.isOneWay(); + var laneCount = getLaneCount(tags, isOneWay); + var maxspeed = parseMaxspeed(tags); + var laneDirections = parseLaneDirections(tags, isOneWay, laneCount); + var forward = laneDirections.forward; + var backward = laneDirections.backward; + var bothways = laneDirections.bothways; // parse the piped string 'x|y|z' format - for (var i = 0; i < arr.length; i++) { - result[i] = Object.assign({}, arr[i]); // shallow copy + var turnLanes = {}; + turnLanes.unspecified = parseTurnLanes(tags['turn:lanes']); + turnLanes.forward = parseTurnLanes(tags['turn:lanes:forward']); + turnLanes.backward = parseTurnLanes(tags['turn:lanes:backward']); + var maxspeedLanes = {}; + maxspeedLanes.unspecified = parseMaxspeedLanes(tags['maxspeed:lanes'], maxspeed); + maxspeedLanes.forward = parseMaxspeedLanes(tags['maxspeed:lanes:forward'], maxspeed); + maxspeedLanes.backward = parseMaxspeedLanes(tags['maxspeed:lanes:backward'], maxspeed); + var psvLanes = {}; + psvLanes.unspecified = parseMiscLanes(tags['psv:lanes']); + psvLanes.forward = parseMiscLanes(tags['psv:lanes:forward']); + psvLanes.backward = parseMiscLanes(tags['psv:lanes:backward']); + var busLanes = {}; + busLanes.unspecified = parseMiscLanes(tags['bus:lanes']); + busLanes.forward = parseMiscLanes(tags['bus:lanes:forward']); + busLanes.backward = parseMiscLanes(tags['bus:lanes:backward']); + var taxiLanes = {}; + taxiLanes.unspecified = parseMiscLanes(tags['taxi:lanes']); + taxiLanes.forward = parseMiscLanes(tags['taxi:lanes:forward']); + taxiLanes.backward = parseMiscLanes(tags['taxi:lanes:backward']); + var hovLanes = {}; + hovLanes.unspecified = parseMiscLanes(tags['hov:lanes']); + hovLanes.forward = parseMiscLanes(tags['hov:lanes:forward']); + hovLanes.backward = parseMiscLanes(tags['hov:lanes:backward']); + var hgvLanes = {}; + hgvLanes.unspecified = parseMiscLanes(tags['hgv:lanes']); + hgvLanes.forward = parseMiscLanes(tags['hgv:lanes:forward']); + hgvLanes.backward = parseMiscLanes(tags['hgv:lanes:backward']); + var bicyclewayLanes = {}; + bicyclewayLanes.unspecified = parseBicycleWay(tags['bicycleway:lanes']); + bicyclewayLanes.forward = parseBicycleWay(tags['bicycleway:lanes:forward']); + bicyclewayLanes.backward = parseBicycleWay(tags['bicycleway:lanes:backward']); + var lanesObj = { + forward: [], + backward: [], + unspecified: [] + }; // map forward/backward/unspecified of each lane type to lanesObj - result[i].index = i; - } + mapToLanesObj(lanesObj, turnLanes, 'turnLane'); + mapToLanesObj(lanesObj, maxspeedLanes, 'maxspeed'); + mapToLanesObj(lanesObj, psvLanes, 'psv'); + mapToLanesObj(lanesObj, busLanes, 'bus'); + mapToLanesObj(lanesObj, taxiLanes, 'taxi'); + mapToLanesObj(lanesObj, hovLanes, 'hov'); + mapToLanesObj(lanesObj, hgvLanes, 'hgv'); + mapToLanesObj(lanesObj, bicyclewayLanes, 'bicycleway'); + return { + metadata: { + count: laneCount, + oneway: isOneWay, + forward: forward, + backward: backward, + bothways: bothways, + turnLanes: turnLanes, + maxspeed: maxspeed, + maxspeedLanes: maxspeedLanes, + psvLanes: psvLanes, + busLanes: busLanes, + taxiLanes: taxiLanes, + hovLanes: hovLanes, + hgvLanes: hgvLanes, + bicyclewayLanes: bicyclewayLanes + }, + lanes: lanesObj + }; + } - return result; + function getLaneCount(tags, isOneWay) { + var count; + + if (tags.lanes) { + count = parseInt(tags.lanes, 10); + + if (count > 0) { + return count; } } + + switch (tags.highway) { + case 'trunk': + case 'motorway': + count = isOneWay ? 2 : 4; + break; + + default: + count = isOneWay ? 1 : 2; + break; + } + + return count; } - function actionAddMidpoint(midpoint, node) { - return function (graph) { - graph = graph.replace(node.move(midpoint.loc)); - var parents = utilArrayIntersection(graph.parentWays(graph.entity(midpoint.edge[0])), graph.parentWays(graph.entity(midpoint.edge[1]))); - parents.forEach(function (way) { - for (var i = 0; i < way.nodes.length - 1; i++) { - if (geoEdgeEqual([way.nodes[i], way.nodes[i + 1]], midpoint.edge)) { - graph = graph.replace(graph.entity(way.id).addNode(node.id, i + 1)); // Add only one midpoint on doubled-back segments, - // turning them into self-intersections. + function parseMaxspeed(tags) { + var maxspeed = tags.maxspeed; + if (!maxspeed) return; + var maxspeedRegex = /^([0-9][\.0-9]+?)(?:[ ]?(?:km\/h|kmh|kph|mph|knots))?$/; + if (!maxspeedRegex.test(maxspeed)) return; + return parseInt(maxspeed, 10); + } - return; - } - } - }); - return graph; + function parseLaneDirections(tags, isOneWay, laneCount) { + var forward = parseInt(tags['lanes:forward'], 10); + var backward = parseInt(tags['lanes:backward'], 10); + var bothways = parseInt(tags['lanes:both_ways'], 10) > 0 ? 1 : 0; + + if (parseInt(tags.oneway, 10) === -1) { + forward = 0; + bothways = 0; + backward = laneCount; + } else if (isOneWay) { + forward = laneCount; + bothways = 0; + backward = 0; + } else if (isNaN(forward) && isNaN(backward)) { + backward = Math.floor((laneCount - bothways) / 2); + forward = laneCount - bothways - backward; + } else if (isNaN(forward)) { + if (backward > laneCount - bothways) { + backward = laneCount - bothways; + } + + forward = laneCount - bothways - backward; + } else if (isNaN(backward)) { + if (forward > laneCount - bothways) { + forward = laneCount - bothways; + } + + backward = laneCount - bothways - forward; + } + + return { + forward: forward, + backward: backward, + bothways: bothways }; } - // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/AddNodeToWayAction.as - function actionAddVertex(wayId, nodeId, index) { - return function (graph) { - return graph.replace(graph.entity(wayId).addNode(nodeId, index)); - }; + function parseTurnLanes(tag) { + if (!tag) return; + var validValues = ['left', 'slight_left', 'sharp_left', 'through', 'right', 'slight_right', 'sharp_right', 'reverse', 'merge_to_left', 'merge_to_right', 'none']; + return tag.split('|').map(function (s) { + if (s === '') s = 'none'; + return s.split(';').map(function (d) { + return validValues.indexOf(d) === -1 ? 'unknown' : d; + }); + }); } - function actionChangeMember(relationId, member, memberIndex) { - return function (graph) { - return graph.replace(graph.entity(relationId).updateMember(member, memberIndex)); - }; + function parseMaxspeedLanes(tag, maxspeed) { + if (!tag) return; + return tag.split('|').map(function (s) { + if (s === 'none') return s; + var m = parseInt(s, 10); + if (s === '' || m === maxspeed) return null; + return isNaN(m) ? 'unknown' : m; + }); } - function actionChangePreset(entityID, oldPreset, newPreset, skipFieldDefaults) { - return function action(graph) { - var entity = graph.entity(entityID); - var geometry = entity.geometry(graph); - var tags = entity.tags; // preserve tags that the new preset might care about, if any + function parseMiscLanes(tag) { + if (!tag) return; + var validValues = ['yes', 'no', 'designated']; + return tag.split('|').map(function (s) { + if (s === '') s = 'no'; + return validValues.indexOf(s) === -1 ? 'unknown' : s; + }); + } - if (oldPreset) tags = oldPreset.unsetTags(tags, geometry, newPreset && newPreset.addTags ? Object.keys(newPreset.addTags) : null); - if (newPreset) tags = newPreset.setTags(tags, geometry, skipFieldDefaults); - return graph.replace(entity.update({ - tags: tags - })); - }; + function parseBicycleWay(tag) { + if (!tag) return; + var validValues = ['yes', 'no', 'designated', 'lane']; + return tag.split('|').map(function (s) { + if (s === '') s = 'no'; + return validValues.indexOf(s) === -1 ? 'unknown' : s; + }); } - function actionChangeTags(entityId, tags) { - return function (graph) { - var entity = graph.entity(entityId); - return graph.replace(entity.update({ - tags: tags - })); - }; + function mapToLanesObj(lanesObj, data, key) { + if (data.forward) { + data.forward.forEach(function (l, i) { + if (!lanesObj.forward[i]) lanesObj.forward[i] = {}; + lanesObj.forward[i][key] = l; + }); + } + + if (data.backward) { + data.backward.forEach(function (l, i) { + if (!lanesObj.backward[i]) lanesObj.backward[i] = {}; + lanesObj.backward[i][key] = l; + }); + } + + if (data.unspecified) { + data.unspecified.forEach(function (l, i) { + if (!lanesObj.unspecified[i]) lanesObj.unspecified[i] = {}; + lanesObj.unspecified[i][key] = l; + }); + } } - function osmNode() { - if (!(this instanceof osmNode)) { - return new osmNode().initialize(arguments); + function osmWay() { + if (!(this instanceof osmWay)) { + return new osmWay().initialize(arguments); } else if (arguments.length) { this.initialize(arguments); } } - osmEntity.node = osmNode; - osmNode.prototype = Object.create(osmEntity.prototype); - Object.assign(osmNode.prototype, { - type: 'node', - loc: [9999, 9999], - extent: function extent() { - return new geoExtent(this.loc); - }, - geometry: function geometry(graph) { - return graph["transient"](this, 'geometry', function () { - return graph.isPoi(this) ? 'point' : 'vertex'; + osmEntity.way = osmWay; + osmWay.prototype = Object.create(osmEntity.prototype); + Object.assign(osmWay.prototype, { + type: 'way', + nodes: [], + copy: function copy(resolver, copies) { + if (copies[this.id]) return copies[this.id]; + var copy = osmEntity.prototype.copy.call(this, resolver, copies); + var nodes = this.nodes.map(function (id) { + return resolver.entity(id).copy(resolver, copies).id; + }); + copy = copy.update({ + nodes: nodes }); + copies[this.id] = copy; + return copy; }, - move: function move(loc) { - return this.update({ - loc: loc + extent: function extent(resolver) { + return resolver["transient"](this, 'extent', function () { + var extent = geoExtent(); + + for (var i = 0; i < this.nodes.length; i++) { + var node = resolver.hasEntity(this.nodes[i]); + + if (node) { + extent._extend(node.extent()); + } + } + + return extent; }); }, - isDegenerate: function isDegenerate() { - return !(Array.isArray(this.loc) && this.loc.length === 2 && this.loc[0] >= -180 && this.loc[0] <= 180 && this.loc[1] >= -90 && this.loc[1] <= 90); + first: function first() { + return this.nodes[0]; }, - // Inspect tags and geometry to determine which direction(s) this node/vertex points - directions: function directions(resolver, projection) { - var val; - var i; // which tag to use? + last: function last() { + return this.nodes[this.nodes.length - 1]; + }, + contains: function contains(node) { + return this.nodes.indexOf(node) >= 0; + }, + affix: function affix(node) { + if (this.nodes[0] === node) return 'prefix'; + if (this.nodes[this.nodes.length - 1] === node) return 'suffix'; + }, + layer: function layer() { + // explicit layer tag, clamp between -10, 10.. + if (isFinite(this.tags.layer)) { + return Math.max(-10, Math.min(+this.tags.layer, 10)); + } // implied layer tag.. - if (this.isHighwayIntersection(resolver) && (this.tags.stop || '').toLowerCase() === 'all') { - // all-way stop tag on a highway intersection - val = 'all'; - } else { - // generic direction tag - val = (this.tags.direction || '').toLowerCase(); // better suffix-style direction tag - var re = /:direction$/i; - var keys = Object.keys(this.tags); + if (this.tags.covered === 'yes') return -1; + if (this.tags.location === 'overground') return 1; + if (this.tags.location === 'underground') return -1; + if (this.tags.location === 'underwater') return -10; + if (this.tags.power === 'line') return 10; + if (this.tags.power === 'minor_line') return 10; + if (this.tags.aerialway) return 10; + if (this.tags.bridge) return 1; + if (this.tags.cutting) return -1; + if (this.tags.tunnel) return -1; + if (this.tags.waterway) return -1; + if (this.tags.man_made === 'pipeline') return -10; + if (this.tags.boundary) return -10; + return 0; + }, + // the approximate width of the line based on its tags except its `width` tag + impliedLineWidthMeters: function impliedLineWidthMeters() { + var averageWidths = { + highway: { + // width is for single lane + motorway: 5, + motorway_link: 5, + trunk: 4.5, + trunk_link: 4.5, + primary: 4, + secondary: 4, + tertiary: 4, + primary_link: 4, + secondary_link: 4, + tertiary_link: 4, + unclassified: 4, + road: 4, + living_street: 4, + bus_guideway: 4, + pedestrian: 4, + residential: 3.5, + service: 3.5, + track: 3, + cycleway: 2.5, + bridleway: 2, + corridor: 2, + steps: 2, + path: 1.5, + footway: 1.5 + }, + railway: { + // width includes ties and rail bed, not just track gauge + rail: 2.5, + light_rail: 2.5, + tram: 2.5, + subway: 2.5, + monorail: 2.5, + funicular: 2.5, + disused: 2.5, + preserved: 2.5, + miniature: 1.5, + narrow_gauge: 1.5 + }, + waterway: { + river: 50, + canal: 25, + stream: 5, + tidal_channel: 5, + fish_pass: 2.5, + drain: 2.5, + ditch: 1.5 + } + }; - for (i = 0; i < keys.length; i++) { - if (re.test(keys[i])) { - val = this.tags[keys[i]].toLowerCase(); - break; + for (var key in averageWidths) { + if (this.tags[key] && averageWidths[key][this.tags[key]]) { + var width = averageWidths[key][this.tags[key]]; + + if (key === 'highway') { + var laneCount = this.tags.lanes && parseInt(this.tags.lanes, 10); + if (!laneCount) laneCount = this.isOneWay() ? 1 : 2; + return width * laneCount; } + + return width; } } - if (val === '') return []; - var cardinal = { - north: 0, - n: 0, - northnortheast: 22, - nne: 22, - northeast: 45, - ne: 45, - eastnortheast: 67, - ene: 67, - east: 90, - e: 90, - eastsoutheast: 112, - ese: 112, - southeast: 135, - se: 135, - southsoutheast: 157, - sse: 157, - south: 180, - s: 180, - southsouthwest: 202, - ssw: 202, - southwest: 225, - sw: 225, - westsouthwest: 247, - wsw: 247, - west: 270, - w: 270, - westnorthwest: 292, - wnw: 292, - northwest: 315, - nw: 315, - northnorthwest: 337, - nnw: 337 + return null; + }, + isOneWay: function isOneWay() { + // explicit oneway tag.. + var values = { + 'yes': true, + '1': true, + '-1': true, + 'reversible': true, + 'alternating': true, + 'no': false, + '0': false }; - var values = val.split(';'); - var results = []; - values.forEach(function (v) { - // swap cardinal for numeric directions - if (cardinal[v] !== undefined) { - v = cardinal[v]; - } // numeric direction - just add to results - - if (v !== '' && !isNaN(+v)) { - results.push(+v); - return; - } // string direction - inspect parent ways + if (values[this.tags.oneway] !== undefined) { + return values[this.tags.oneway]; + } // implied oneway tag.. - var lookBackward = this.tags['traffic_sign:backward'] || v === 'backward' || v === 'both' || v === 'all'; - var lookForward = this.tags['traffic_sign:forward'] || v === 'forward' || v === 'both' || v === 'all'; - if (!lookForward && !lookBackward) return; - var nodeIds = {}; - resolver.parentWays(this).forEach(function (parent) { - var nodes = parent.nodes; + for (var key in this.tags) { + if (key in osmOneWayTags && this.tags[key] in osmOneWayTags[key]) { + return true; + } + } - for (i = 0; i < nodes.length; i++) { - if (nodes[i] === this.id) { - // match current entity - if (lookForward && i > 0) { - nodeIds[nodes[i - 1]] = true; // look back to prev node - } + return false; + }, + // Some identifier for tag that implies that this way is "sided", + // i.e. the right side is the 'inside' (e.g. the right side of a + // natural=cliff is lower). + sidednessIdentifier: function sidednessIdentifier() { + for (var key in this.tags) { + var value = this.tags[key]; - if (lookBackward && i < nodes.length - 1) { - nodeIds[nodes[i + 1]] = true; // look ahead to next node - } - } + if (key in osmRightSideIsInsideTags && value in osmRightSideIsInsideTags[key]) { + if (osmRightSideIsInsideTags[key][value] === true) { + return key; + } else { + // if the map's value is something other than a + // literal true, we should use it so we can + // special case some keys (e.g. natural=coastline + // is handled differently to other naturals). + return osmRightSideIsInsideTags[key][value]; } - }, this); - Object.keys(nodeIds).forEach(function (nodeId) { - // +90 because geoAngle returns angle from X axis, not Y (north) - results.push(geoAngle(this, resolver.entity(nodeId), projection) * (180 / Math.PI) + 90); - }, this); - }, this); - return utilArrayUniq(results); + } + } + + return null; }, - isCrossing: function isCrossing() { - return this.tags.highway === 'crossing' || this.tags.railway && this.tags.railway.indexOf('crossing') !== -1; + isSided: function isSided() { + if (this.tags.two_sided === 'yes') { + return false; + } + + return this.sidednessIdentifier() !== null; }, - isEndpoint: function isEndpoint(resolver) { - return resolver["transient"](this, 'isEndpoint', function () { - var id = this.id; - return resolver.parentWays(this).filter(function (parent) { - return !parent.isClosed() && !!parent.affix(id); - }).length > 0; - }); + lanes: function lanes() { + return osmLanes(this); }, - isConnected: function isConnected(resolver) { - return resolver["transient"](this, 'isConnected', function () { - var parents = resolver.parentWays(this); - - if (parents.length > 1) { - // vertex is connected to multiple parent ways - for (var i in parents) { - if (parents[i].geometry(resolver) === 'line' && parents[i].hasInterestingTags()) return true; - } - } else if (parents.length === 1) { - var way = parents[0]; - var nodes = way.nodes.slice(); - - if (way.isClosed()) { - nodes.pop(); - } // ignore connecting node if closed - // return true if vertex appears multiple times (way is self intersecting) + isClosed: function isClosed() { + return this.nodes.length > 1 && this.first() === this.last(); + }, + isConvex: function isConvex(resolver) { + if (!this.isClosed() || this.isDegenerate()) return null; + var nodes = utilArrayUniq(resolver.childNodes(this)); + var coords = nodes.map(function (n) { + return n.loc; + }); + var curr = 0; + var prev = 0; + for (var i = 0; i < coords.length; i++) { + var o = coords[(i + 1) % coords.length]; + var a = coords[i]; + var b = coords[(i + 2) % coords.length]; + var res = geoVecCross(a, b, o); + curr = res > 0 ? 1 : res < 0 ? -1 : 0; - return nodes.indexOf(this.id) !== nodes.lastIndexOf(this.id); + if (curr === 0) { + continue; + } else if (prev && curr !== prev) { + return false; } - return false; - }); - }, - parentIntersectionWays: function parentIntersectionWays(resolver) { - return resolver["transient"](this, 'parentIntersectionWays', function () { - return resolver.parentWays(this).filter(function (parent) { - return (parent.tags.highway || parent.tags.waterway || parent.tags.railway || parent.tags.aeroway) && parent.geometry(resolver) === 'line'; - }); - }); + prev = curr; + } + + return true; }, - isIntersection: function isIntersection(resolver) { - return this.parentIntersectionWays(resolver).length > 1; + // returns an object with the tag that implies this is an area, if any + tagSuggestingArea: function tagSuggestingArea() { + return osmTagSuggestingArea(this.tags); }, - isHighwayIntersection: function isHighwayIntersection(resolver) { - return resolver["transient"](this, 'isHighwayIntersection', function () { - return resolver.parentWays(this).filter(function (parent) { - return parent.tags.highway && parent.geometry(resolver) === 'line'; - }).length > 1; - }); + isArea: function isArea() { + if (this.tags.area === 'yes') return true; + if (!this.isClosed() || this.tags.area === 'no') return false; + return this.tagSuggestingArea() !== null; }, - isOnAddressLine: function isOnAddressLine(resolver) { - return resolver["transient"](this, 'isOnAddressLine', function () { - return resolver.parentWays(this).filter(function (parent) { - return parent.tags.hasOwnProperty('addr:interpolation') && parent.geometry(resolver) === 'line'; - }).length > 0; - }); + isDegenerate: function isDegenerate() { + return new Set(this.nodes).size < (this.isArea() ? 3 : 2); }, - asJXON: function asJXON(changeset_id) { - var r = { - node: { - '@id': this.osmId(), - '@lon': this.loc[0], - '@lat': this.loc[1], - '@version': this.version || 0, - tag: Object.keys(this.tags).map(function (k) { - return { - keyAttributes: { - k: k, - v: this.tags[k] - } - }; - }, this) + areAdjacent: function areAdjacent(n1, n2) { + for (var i = 0; i < this.nodes.length; i++) { + if (this.nodes[i] === n1) { + if (this.nodes[i - 1] === n2) return true; + if (this.nodes[i + 1] === n2) return true; } - }; - if (changeset_id) r.node['@changeset'] = changeset_id; - return r; + } + + return false; }, - asGeoJSON: function asGeoJSON() { - return { - type: 'Point', - coordinates: this.loc - }; - } - }); + geometry: function geometry(graph) { + return graph["transient"](this, 'geometry', function () { + return this.isArea() ? 'area' : 'line'; + }); + }, + // returns an array of objects representing the segments between the nodes in this way + segments: function segments(graph) { + function segmentExtent(graph) { + var n1 = graph.hasEntity(this.nodes[0]); + var n2 = graph.hasEntity(this.nodes[1]); + return n1 && n2 && geoExtent([[Math.min(n1.loc[0], n2.loc[0]), Math.min(n1.loc[1], n2.loc[1])], [Math.max(n1.loc[0], n2.loc[0]), Math.max(n1.loc[1], n2.loc[1])]]); + } - function actionCircularize(wayId, projection, maxAngle) { - maxAngle = (maxAngle || 20) * Math.PI / 180; + return graph["transient"](this, 'segments', function () { + var segments = []; - var action = function action(graph, t) { - if (t === null || !isFinite(t)) t = 1; - t = Math.min(Math.max(+t, 0), 1); - var way = graph.entity(wayId); - var origNodes = {}; - graph.childNodes(way).forEach(function (node) { - if (!origNodes[node.id]) origNodes[node.id] = node; + for (var i = 0; i < this.nodes.length - 1; i++) { + segments.push({ + id: this.id + '-' + i, + wayId: this.id, + index: i, + nodes: [this.nodes[i], this.nodes[i + 1]], + extent: segmentExtent + }); + } + + return segments; + }); + }, + // If this way is not closed, append the beginning node to the end of the nodelist to close it. + close: function close() { + if (this.isClosed() || !this.nodes.length) return this; + var nodes = this.nodes.slice(); + nodes = nodes.filter(noRepeatNodes); + nodes.push(nodes[0]); + return this.update({ + nodes: nodes }); + }, + // If this way is closed, remove any connector nodes from the end of the nodelist to unclose it. + unclose: function unclose() { + if (!this.isClosed()) return this; + var nodes = this.nodes.slice(); + var connector = this.first(); + var i = nodes.length - 1; // remove trailing connectors.. - if (!way.isConvex(graph)) { - graph = action.makeConvex(graph); + while (i > 0 && nodes.length > 1 && nodes[i] === connector) { + nodes.splice(i, 1); + i = nodes.length - 1; } - var nodes = utilArrayUniq(graph.childNodes(way)); - var keyNodes = nodes.filter(function (n) { - return graph.parentWays(n).length !== 1; - }); - var points = nodes.map(function (n) { - return projection(n.loc); - }); - var keyPoints = keyNodes.map(function (n) { - return projection(n.loc); - }); - var centroid = points.length === 2 ? geoVecInterp(points[0], points[1], 0.5) : d3_polygonCentroid(points); - var radius = d3_median(points, function (p) { - return geoVecLength(centroid, p); + nodes = nodes.filter(noRepeatNodes); + return this.update({ + nodes: nodes }); - var sign = d3_polygonArea(points) > 0 ? 1 : -1; - var ids, i, j, k; // we need at least two key nodes for the algorithm to work + }, + // Adds a node (id) in front of the node which is currently at position index. + // If index is undefined, the node will be added to the end of the way for linear ways, + // or just before the final connecting node for circular ways. + // Consecutive duplicates are eliminated including existing ones. + // Circularity is always preserved when adding a node. + addNode: function addNode(id, index) { + var nodes = this.nodes.slice(); + var isClosed = this.isClosed(); + var max = isClosed ? nodes.length - 1 : nodes.length; - if (!keyNodes.length) { - keyNodes = [nodes[0]]; - keyPoints = [points[0]]; + if (index === undefined) { + index = max; } - if (keyNodes.length === 1) { - var index = nodes.indexOf(keyNodes[0]); - var oppositeIndex = Math.floor((index + nodes.length / 2) % nodes.length); - keyNodes.push(nodes[oppositeIndex]); - keyPoints.push(points[oppositeIndex]); - } // key points and nodes are those connected to the ways, - // they are projected onto the circle, in between nodes are moved - // to constant intervals between key nodes, extra in between nodes are - // added if necessary. + if (index < 0 || index > max) { + throw new RangeError('index ' + index + ' out of range 0..' + max); + } // If this is a closed way, remove all connector nodes except the first one + // (there may be duplicates) and adjust index if necessary.. - for (i = 0; i < keyPoints.length; i++) { - var nextKeyNodeIndex = (i + 1) % keyNodes.length; - var startNode = keyNodes[i]; - var endNode = keyNodes[nextKeyNodeIndex]; - var startNodeIndex = nodes.indexOf(startNode); - var endNodeIndex = nodes.indexOf(endNode); - var numberNewPoints = -1; - var indexRange = endNodeIndex - startNodeIndex; - var nearNodes = {}; - var inBetweenNodes = []; - var startAngle, endAngle, totalAngle, eachAngle; - var angle, loc, node, origNode; + if (isClosed) { + var connector = this.first(); // leading connectors.. - if (indexRange < 0) { - indexRange += nodes.length; - } // position this key node + var i = 1; + while (i < nodes.length && nodes.length > 2 && nodes[i] === connector) { + nodes.splice(i, 1); + if (index > i) index--; + } // trailing connectors.. - var distance = geoVecLength(centroid, keyPoints[i]) || 1e-4; - keyPoints[i] = [centroid[0] + (keyPoints[i][0] - centroid[0]) / distance * radius, centroid[1] + (keyPoints[i][1] - centroid[1]) / distance * radius]; - loc = projection.invert(keyPoints[i]); - node = keyNodes[i]; - origNode = origNodes[node.id]; - node = node.move(geoVecInterp(origNode.loc, loc, t)); - graph = graph.replace(node); // figure out the between delta angle we want to match to - startAngle = Math.atan2(keyPoints[i][1] - centroid[1], keyPoints[i][0] - centroid[0]); - endAngle = Math.atan2(keyPoints[nextKeyNodeIndex][1] - centroid[1], keyPoints[nextKeyNodeIndex][0] - centroid[0]); - totalAngle = endAngle - startAngle; // detects looping around -pi/pi + i = nodes.length - 1; - if (totalAngle * sign > 0) { - totalAngle = -sign * (2 * Math.PI - Math.abs(totalAngle)); + while (i > 0 && nodes.length > 1 && nodes[i] === connector) { + nodes.splice(i, 1); + if (index > i) index--; + i = nodes.length - 1; } + } - do { - numberNewPoints++; - eachAngle = totalAngle / (indexRange + numberNewPoints); - } while (Math.abs(eachAngle) > maxAngle); // move existing nodes + nodes.splice(index, 0, id); + nodes = nodes.filter(noRepeatNodes); // If the way was closed before, append a connector node to keep it closed.. + if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) { + nodes.push(nodes[0]); + } - for (j = 1; j < indexRange; j++) { - angle = startAngle + j * eachAngle; - loc = projection.invert([centroid[0] + Math.cos(angle) * radius, centroid[1] + Math.sin(angle) * radius]); - node = nodes[(j + startNodeIndex) % nodes.length]; - origNode = origNodes[node.id]; - nearNodes[node.id] = angle; - node = node.move(geoVecInterp(origNode.loc, loc, t)); - graph = graph.replace(node); - } // add new in between nodes if necessary + return this.update({ + nodes: nodes + }); + }, + // Replaces the node which is currently at position index with the given node (id). + // Consecutive duplicates are eliminated including existing ones. + // Circularity is preserved when updating a node. + updateNode: function updateNode(id, index) { + var nodes = this.nodes.slice(); + var isClosed = this.isClosed(); + var max = nodes.length - 1; + if (index === undefined || index < 0 || index > max) { + throw new RangeError('index ' + index + ' out of range 0..' + max); + } // If this is a closed way, remove all connector nodes except the first one + // (there may be duplicates) and adjust index if necessary.. - for (j = 0; j < numberNewPoints; j++) { - angle = startAngle + (indexRange + j) * eachAngle; - loc = projection.invert([centroid[0] + Math.cos(angle) * radius, centroid[1] + Math.sin(angle) * radius]); // choose a nearnode to use as the original - var min = Infinity; + if (isClosed) { + var connector = this.first(); // leading connectors.. - for (var nodeId in nearNodes) { - var nearAngle = nearNodes[nodeId]; - var dist = Math.abs(nearAngle - angle); + var i = 1; - if (dist < min) { - min = dist; - origNode = origNodes[nodeId]; - } - } + while (i < nodes.length && nodes.length > 2 && nodes[i] === connector) { + nodes.splice(i, 1); + if (index > i) index--; + } // trailing connectors.. - node = osmNode({ - loc: geoVecInterp(origNode.loc, loc, t) - }); - graph = graph.replace(node); - nodes.splice(endNodeIndex + j, 0, node); - inBetweenNodes.push(node.id); - } // Check for other ways that share these keyNodes.. - // If keyNodes are adjacent in both ways, - // we can add inBetweenNodes to that shared way too.. + i = nodes.length - 1; - if (indexRange === 1 && inBetweenNodes.length) { - var startIndex1 = way.nodes.lastIndexOf(startNode.id); - var endIndex1 = way.nodes.lastIndexOf(endNode.id); - var wayDirection1 = endIndex1 - startIndex1; + while (i > 0 && nodes.length > 1 && nodes[i] === connector) { + nodes.splice(i, 1); + if (index === i) index = 0; // update leading connector instead - if (wayDirection1 < -1) { - wayDirection1 = 1; - } + i = nodes.length - 1; + } + } - var parentWays = graph.parentWays(keyNodes[i]); + nodes.splice(index, 1, id); + nodes = nodes.filter(noRepeatNodes); // If the way was closed before, append a connector node to keep it closed.. - for (j = 0; j < parentWays.length; j++) { - var sharedWay = parentWays[j]; - if (sharedWay === way) continue; + if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) { + nodes.push(nodes[0]); + } - if (sharedWay.areAdjacent(startNode.id, endNode.id)) { - var startIndex2 = sharedWay.nodes.lastIndexOf(startNode.id); - var endIndex2 = sharedWay.nodes.lastIndexOf(endNode.id); - var wayDirection2 = endIndex2 - startIndex2; - var insertAt = endIndex2; + return this.update({ + nodes: nodes + }); + }, + // Replaces each occurrence of node id needle with replacement. + // Consecutive duplicates are eliminated including existing ones. + // Circularity is preserved. + replaceNode: function replaceNode(needleID, replacementID) { + var nodes = this.nodes.slice(); + var isClosed = this.isClosed(); - if (wayDirection2 < -1) { - wayDirection2 = 1; - } + for (var i = 0; i < nodes.length; i++) { + if (nodes[i] === needleID) { + nodes[i] = replacementID; + } + } - if (wayDirection1 !== wayDirection2) { - inBetweenNodes.reverse(); - insertAt = startIndex2; - } + nodes = nodes.filter(noRepeatNodes); // If the way was closed before, append a connector node to keep it closed.. - for (k = 0; k < inBetweenNodes.length; k++) { - sharedWay = sharedWay.addNode(inBetweenNodes[k], insertAt + k); - } + if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) { + nodes.push(nodes[0]); + } - graph = graph.replace(sharedWay); - } - } - } - } // update the way to have all the new nodes + return this.update({ + nodes: nodes + }); + }, + // Removes each occurrence of node id. + // Consecutive duplicates are eliminated including existing ones. + // Circularity is preserved. + removeNode: function removeNode(id) { + var nodes = this.nodes.slice(); + var isClosed = this.isClosed(); + nodes = nodes.filter(function (node) { + return node !== id; + }).filter(noRepeatNodes); // If the way was closed before, append a connector node to keep it closed.. + if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) { + nodes.push(nodes[0]); + } - ids = nodes.map(function (n) { - return n.id; - }); - ids.push(ids[0]); - way = way.update({ - nodes: ids - }); - graph = graph.replace(way); - return graph; - }; - - action.makeConvex = function (graph) { - var way = graph.entity(wayId); - var nodes = utilArrayUniq(graph.childNodes(way)); - var points = nodes.map(function (n) { - return projection(n.loc); + return this.update({ + nodes: nodes }); - var sign = d3_polygonArea(points) > 0 ? 1 : -1; - var hull = d3_polygonHull(points); - var i, j; // D3 convex hulls go counterclockwise.. + }, + asJXON: function asJXON(changeset_id) { + var r = { + way: { + '@id': this.osmId(), + '@version': this.version || 0, + nd: this.nodes.map(function (id) { + return { + keyAttributes: { + ref: osmEntity.id.toOSM(id) + } + }; + }, this), + tag: Object.keys(this.tags).map(function (k) { + return { + keyAttributes: { + k: k, + v: this.tags[k] + } + }; + }, this) + } + }; - if (sign === -1) { - nodes.reverse(); - points.reverse(); + if (changeset_id) { + r.way['@changeset'] = changeset_id; } - for (i = 0; i < hull.length - 1; i++) { - var startIndex = points.indexOf(hull[i]); - var endIndex = points.indexOf(hull[i + 1]); - var indexRange = endIndex - startIndex; - - if (indexRange < 0) { - indexRange += nodes.length; - } // move interior nodes to the surface of the convex hull.. - + return r; + }, + asGeoJSON: function asGeoJSON(resolver) { + return resolver["transient"](this, 'GeoJSON', function () { + var coordinates = resolver.childNodes(this).map(function (n) { + return n.loc; + }); - for (j = 1; j < indexRange; j++) { - var point = geoVecInterp(hull[i], hull[i + 1], j / indexRange); - var node = nodes[(j + startIndex) % nodes.length].move(projection.invert(point)); - graph = graph.replace(node); + if (this.isArea() && this.isClosed()) { + return { + type: 'Polygon', + coordinates: [coordinates] + }; + } else { + return { + type: 'LineString', + coordinates: coordinates + }; } - } + }); + }, + area: function area(resolver) { + return resolver["transient"](this, 'area', function () { + var nodes = resolver.childNodes(this); + var json = { + type: 'Polygon', + coordinates: [nodes.map(function (n) { + return n.loc; + })] + }; - return graph; - }; + if (!this.isClosed() && nodes.length) { + json.coordinates[0].push(nodes[0].loc); + } - action.disabled = function (graph) { - if (!graph.entity(wayId).isClosed()) { - return 'not_closed'; - } //disable when already circular + var area = d3_geoArea(json); // Heuristic for detecting counterclockwise winding order. Assumes + // that OpenStreetMap polygons are not hemisphere-spanning. + if (area > 2 * Math.PI) { + json.coordinates[0] = json.coordinates[0].reverse(); + area = d3_geoArea(json); + } - var way = graph.entity(wayId); - var nodes = utilArrayUniq(graph.childNodes(way)); - var points = nodes.map(function (n) { - return projection(n.loc); + return isNaN(area) ? 0 : area; }); - var hull = d3_polygonHull(points); - var epsilonAngle = Math.PI / 180; - - if (hull.length !== points.length || hull.length < 3) { - return false; - } - - var centroid = d3_polygonCentroid(points); - var radius = geoVecLengthSquare(centroid, points[0]); - var i, actualPoint; // compare distances between centroid and points + } + }); // Filter function to eliminate consecutive duplicates. - for (i = 0; i < hull.length; i++) { - actualPoint = hull[i]; - var actualDist = geoVecLengthSquare(actualPoint, centroid); - var diff = Math.abs(actualDist - radius); //compare distances with epsilon-error (5%) + function noRepeatNodes(node, i, arr) { + return i === 0 || node !== arr[i - 1]; + } - if (diff > 0.05 * radius) { - return false; - } - } //check if central angles are smaller than maxAngle + // + // 1. Relation tagged with `type=multipolygon` and no interesting tags. + // 2. One and only one member with the `outer` role. Must be a way with interesting tags. + // 3. No members without a role. + // + // Old multipolygons are no longer recommended but are still rendered as areas by iD. + function osmOldMultipolygonOuterMemberOfRelation(entity, graph) { + if (entity.type !== 'relation' || !entity.isMultipolygon() || Object.keys(entity.tags).filter(osmIsInterestingTag).length > 1) { + return false; + } - for (i = 0; i < hull.length; i++) { - actualPoint = hull[i]; - var nextPoint = hull[(i + 1) % hull.length]; - var startAngle = Math.atan2(actualPoint[1] - centroid[1], actualPoint[0] - centroid[0]); - var endAngle = Math.atan2(nextPoint[1] - centroid[1], nextPoint[0] - centroid[0]); - var angle = endAngle - startAngle; + var outerMember; - if (angle < 0) { - angle = -angle; - } + for (var memberIndex in entity.members) { + var member = entity.members[memberIndex]; - if (angle > Math.PI) { - angle = 2 * Math.PI - angle; - } + if (!member.role || member.role === 'outer') { + if (outerMember) return false; + if (member.type !== 'way') return false; + if (!graph.hasEntity(member.id)) return false; + outerMember = graph.entity(member.id); - if (angle > maxAngle + epsilonAngle) { + if (Object.keys(outerMember.tags).filter(osmIsInterestingTag).length === 0) { return false; } } + } - return 'already_circular'; - }; - - action.transitionable = true; - return action; - } - - function actionDeleteWay(wayID) { - function canDeleteNode(node, graph) { - // don't delete nodes still attached to ways or relations - if (graph.parentWays(node).length || graph.parentRelations(node).length) return false; - var geometries = osmNodeGeometriesForTags(node.tags); // don't delete if this node can be a standalone point - - if (geometries.point) return false; // delete if this node only be a vertex - - if (geometries.vertex) return true; // iD doesn't know if this should be a point or vertex, - // so only delete if there are no interesting tags + return outerMember; + } // For fixing up rendering of multipolygons with tags on the outer member. + // https://github.com/openstreetmap/iD/issues/613 - return !node.hasInterestingTags(); + function osmIsOldMultipolygonOuterMember(entity, graph) { + if (entity.type !== 'way' || Object.keys(entity.tags).filter(osmIsInterestingTag).length === 0) { + return false; } - var action = function action(graph) { - var way = graph.entity(wayID); - graph.parentRelations(way).forEach(function (parent) { - parent = parent.removeMembersWithID(wayID); - graph = graph.replace(parent); + var parents = graph.parentRelations(entity); + if (parents.length !== 1) return false; + var parent = parents[0]; - if (parent.isDegenerate()) { - graph = actionDeleteRelation(parent.id)(graph); - } - }); - new Set(way.nodes).forEach(function (nodeID) { - graph = graph.replace(way.removeNode(nodeID)); - var node = graph.entity(nodeID); + if (!parent.isMultipolygon() || Object.keys(parent.tags).filter(osmIsInterestingTag).length > 1) { + return false; + } - if (canDeleteNode(node, graph)) { - graph = graph.remove(node); - } - }); - return graph.remove(way); - }; + var members = parent.members, + member; - return action; - } + for (var i = 0; i < members.length; i++) { + member = members[i]; - function actionDeleteMultiple(ids) { - var actions = { - way: actionDeleteWay, - node: actionDeleteNode, - relation: actionDeleteRelation - }; + if (member.id === entity.id && member.role && member.role !== 'outer') { + // Not outer member + return false; + } - var action = function action(graph) { - ids.forEach(function (id) { - if (graph.hasEntity(id)) { - // It may have been deleted already. - graph = actions[graph.entity(id).type](id)(graph); - } - }); - return graph; - }; + if (member.id !== entity.id && (!member.role || member.role === 'outer')) { + // Not a simple multipolygon + return false; + } + } - return action; + return parent; } + function osmOldMultipolygonOuterMember(entity, graph) { + if (entity.type !== 'way') return false; + var parents = graph.parentRelations(entity); + if (parents.length !== 1) return false; + var parent = parents[0]; - function actionDeleteRelation(relationID, allowUntaggedMembers) { - function canDeleteEntity(entity, graph) { - return !graph.parentWays(entity).length && !graph.parentRelations(entity).length && !entity.hasInterestingTags() && !allowUntaggedMembers; + if (!parent.isMultipolygon() || Object.keys(parent.tags).filter(osmIsInterestingTag).length > 1) { + return false; } - var action = function action(graph) { - var relation = graph.entity(relationID); - graph.parentRelations(relation).forEach(function (parent) { - parent = parent.removeMembersWithID(relationID); - graph = graph.replace(parent); - - if (parent.isDegenerate()) { - graph = actionDeleteRelation(parent.id)(graph); - } - }); - var memberIDs = utilArrayUniq(relation.members.map(function (m) { - return m.id; - })); - memberIDs.forEach(function (memberID) { - graph = graph.replace(relation.removeMembersWithID(memberID)); - var entity = graph.entity(memberID); - - if (canDeleteEntity(entity, graph)) { - graph = actionDeleteMultiple([memberID])(graph); - } - }); - return graph.remove(relation); - }; + var members = parent.members, + member, + outerMember; - return action; - } + for (var i = 0; i < members.length; i++) { + member = members[i]; - function actionDeleteNode(nodeId) { - var action = function action(graph) { - var node = graph.entity(nodeId); - graph.parentWays(node).forEach(function (parent) { - parent = parent.removeNode(nodeId); - graph = graph.replace(parent); + if (!member.role || member.role === 'outer') { + if (outerMember) return false; // Not a simple multipolygon - if (parent.isDegenerate()) { - graph = actionDeleteWay(parent.id)(graph); - } - }); - graph.parentRelations(node).forEach(function (parent) { - parent = parent.removeMembersWithID(nodeId); - graph = graph.replace(parent); + outerMember = member; + } + } - if (parent.isDegenerate()) { - graph = actionDeleteRelation(parent.id)(graph); - } - }); - return graph.remove(node); - }; + if (!outerMember) return false; + var outerEntity = graph.hasEntity(outerMember.id); - return action; - } + if (!outerEntity || !Object.keys(outerEntity.tags).filter(osmIsInterestingTag).length) { + return false; + } + return outerEntity; + } // Join `toJoin` array into sequences of connecting ways. + // Segments which share identical start/end nodes will, as much as possible, + // be connected with each other. // - // First choose a node to be the survivor, with preference given - // to an existing (not new) node. + // The return value is a nested array. Each constituent array contains elements + // of `toJoin` which have been determined to connect. // - // Tags and relation memberships of of non-surviving nodes are merged - // to the survivor. + // Each consitituent array also has a `nodes` property whose value is an + // ordered array of member nodes, with appropriate order reversal and + // start/end coordinate de-duplication. // - // This is the inverse of `iD.actionDisconnect`. + // Members of `toJoin` must have, at minimum, `type` and `id` properties. + // Thus either an array of `osmWay`s or a relation member array may be used. // - // Reference: - // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/MergeNodesAction.as - // https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/actions/MergeNodesAction.java + // If an member is an `osmWay`, its tags and childnodes may be reversed via + // `actionReverse` in the output. + // + // The returned sequences array also has an `actions` array property, containing + // any reversal actions that should be applied to the graph, should the calling + // code attempt to actually join the given ways. + // + // Incomplete members (those for which `graph.hasEntity(element.id)` returns + // false) and non-way members are ignored. // - function actionConnect(nodeIDs) { - var action = function action(graph) { - var survivor; - var node; - var parents; - var i, j; // Choose a survivor node, prefer an existing (not new) node - #4974 - - for (i = 0; i < nodeIDs.length; i++) { - survivor = graph.entity(nodeIDs[i]); - if (survivor.version) break; // found one - } // Replace all non-surviving nodes with the survivor and merge tags. - + function osmJoinWays(toJoin, graph) { + function resolve(member) { + return graph.childNodes(graph.entity(member.id)); + } - for (i = 0; i < nodeIDs.length; i++) { - node = graph.entity(nodeIDs[i]); - if (node.id === survivor.id) continue; - parents = graph.parentWays(node); + function reverse(item) { + var action = actionReverse(item.id, { + reverseOneway: true + }); + sequences.actions.push(action); + return item instanceof osmWay ? action(graph).entity(item.id) : item; + } // make a copy containing only the items to join - for (j = 0; j < parents.length; j++) { - graph = graph.replace(parents[j].replaceNode(node.id, survivor.id)); - } - parents = graph.parentRelations(node); + toJoin = toJoin.filter(function (member) { + return member.type === 'way' && graph.hasEntity(member.id); + }); // Are the things we are joining relation members or `osmWays`? + // If `osmWays`, skip the "prefer a forward path" code below (see #4872) - for (j = 0; j < parents.length; j++) { - graph = graph.replace(parents[j].replaceMember(node, survivor)); - } + var i; + var joinAsMembers = true; - survivor = survivor.mergeTags(node.tags); - graph = actionDeleteNode(node.id)(graph); + for (i = 0; i < toJoin.length; i++) { + if (toJoin[i] instanceof osmWay) { + joinAsMembers = false; + break; } + } - graph = graph.replace(survivor); // find and delete any degenerate ways created by connecting adjacent vertices - - parents = graph.parentWays(survivor); + var sequences = []; + sequences.actions = []; - for (i = 0; i < parents.length; i++) { - if (parents[i].isDegenerate()) { - graph = actionDeleteWay(parents[i].id)(graph); - } - } + while (toJoin.length) { + // start a new sequence + var item = toJoin.shift(); + var currWays = [item]; + var currNodes = resolve(item).slice(); // add to it - return graph; - }; + while (toJoin.length) { + var start = currNodes[0]; + var end = currNodes[currNodes.length - 1]; + var fn = null; + var nodes = null; // Find the next way/member to join. - action.disabled = function (graph) { - var seen = {}; - var restrictionIDs = []; - var survivor; - var node, way; - var relations, relation, role; - var i, j, k; // Choose a survivor node, prefer an existing (not new) node - #4974 + for (i = 0; i < toJoin.length; i++) { + item = toJoin[i]; + nodes = resolve(item); // (for member ordering only, not way ordering - see #4872) + // Strongly prefer to generate a forward path that preserves the order + // of the members array. For multipolygons and most relations, member + // order does not matter - but for routes, it does. (see #4589) + // If we started this sequence backwards (i.e. next member way attaches to + // the start node and not the end node), reverse the initial way before continuing. - for (i = 0; i < nodeIDs.length; i++) { - survivor = graph.entity(nodeIDs[i]); - if (survivor.version) break; // found one - } // 1. disable if the nodes being connected have conflicting relation roles + if (joinAsMembers && currWays.length === 1 && nodes[0] !== end && nodes[nodes.length - 1] !== end && (nodes[nodes.length - 1] === start || nodes[0] === start)) { + currWays[0] = reverse(currWays[0]); + currNodes.reverse(); + start = currNodes[0]; + end = currNodes[currNodes.length - 1]; + } + if (nodes[0] === end) { + fn = currNodes.push; // join to end - for (i = 0; i < nodeIDs.length; i++) { - node = graph.entity(nodeIDs[i]); - relations = graph.parentRelations(node); + nodes = nodes.slice(1); + break; + } else if (nodes[nodes.length - 1] === end) { + fn = currNodes.push; // join to end - for (j = 0; j < relations.length; j++) { - relation = relations[j]; - role = relation.memberById(node.id).role || ''; // if this node is a via node in a restriction, remember for later + nodes = nodes.slice(0, -1).reverse(); + item = reverse(item); + break; + } else if (nodes[nodes.length - 1] === start) { + fn = currNodes.unshift; // join to beginning - if (relation.hasFromViaTo()) { - restrictionIDs.push(relation.id); - } + nodes = nodes.slice(0, -1); + break; + } else if (nodes[0] === start) { + fn = currNodes.unshift; // join to beginning - if (seen[relation.id] !== undefined && seen[relation.id] !== role) { - return 'relation'; + nodes = nodes.slice(1).reverse(); + item = reverse(item); + break; } else { - seen[relation.id] = role; + fn = nodes = null; } } - } // gather restrictions for parent ways + if (!nodes) { + // couldn't find a joinable way/member + break; + } - for (i = 0; i < nodeIDs.length; i++) { - node = graph.entity(nodeIDs[i]); - var parents = graph.parentWays(node); + fn.apply(currWays, [item]); + fn.apply(currNodes, nodes); + toJoin.splice(i, 1); + } - for (j = 0; j < parents.length; j++) { - var parent = parents[j]; - relations = graph.parentRelations(parent); + currWays.nodes = currNodes; + sequences.push(currWays); + } - for (k = 0; k < relations.length; k++) { - relation = relations[k]; + return sequences; + } - if (relation.hasFromViaTo()) { - restrictionIDs.push(relation.id); - } - } + function actionAddMember(relationId, member, memberIndex, insertPair) { + return function action(graph) { + var relation = graph.entity(relationId); // There are some special rules for Public Transport v2 routes. + + var isPTv2 = /stop|platform/.test(member.role); + + if ((isNaN(memberIndex) || insertPair) && member.type === 'way' && !isPTv2) { + // Try to perform sensible inserts based on how the ways join together + graph = addWayMember(relation, graph); + } else { + // see https://wiki.openstreetmap.org/wiki/Public_transport#Service_routes + // Stops and Platforms for PTv2 should be ordered first. + // hack: We do not currently have the ability to place them in the exactly correct order. + if (isPTv2 && isNaN(memberIndex)) { + memberIndex = 0; } - } // test restrictions + graph = graph.replace(relation.addMember(member, memberIndex)); + } - restrictionIDs = utilArrayUniq(restrictionIDs); + return graph; + }; // Add a way member into the relation "wherever it makes sense". + // In this situation we were not supplied a memberIndex. - for (i = 0; i < restrictionIDs.length; i++) { - relation = graph.entity(restrictionIDs[i]); - if (!relation.isComplete(graph)) continue; - var memberWays = relation.members.filter(function (m) { - return m.type === 'way'; - }).map(function (m) { - return graph.entity(m.id); - }); - memberWays = utilArrayUniq(memberWays); - var f = relation.memberByRole('from'); - var t = relation.memberByRole('to'); - var isUturn = f.id === t.id; // 2a. disable if connection would damage a restriction - // (a key node is a node at the junction of ways) + function addWayMember(relation, graph) { + var groups, tempWay, insertPairIsReversed, item, i, j, k; // remove PTv2 stops and platforms before doing anything. - var nodes = { - from: [], - via: [], - to: [], - keyfrom: [], - keyto: [] - }; + var PTv2members = []; + var members = []; - for (j = 0; j < relation.members.length; j++) { - collectNodes(relation.members[j], nodes); - } + for (i = 0; i < relation.members.length; i++) { + var m = relation.members[i]; - nodes.keyfrom = utilArrayUniq(nodes.keyfrom.filter(hasDuplicates)); - nodes.keyto = utilArrayUniq(nodes.keyto.filter(hasDuplicates)); - var filter = keyNodeFilter(nodes.keyfrom, nodes.keyto); - nodes.from = nodes.from.filter(filter); - nodes.via = nodes.via.filter(filter); - nodes.to = nodes.to.filter(filter); - var connectFrom = false; - var connectVia = false; - var connectTo = false; - var connectKeyFrom = false; - var connectKeyTo = false; + if (/stop|platform/.test(m.role)) { + PTv2members.push(m); + } else { + members.push(m); + } + } - for (j = 0; j < nodeIDs.length; j++) { - var n = nodeIDs[j]; + relation = relation.update({ + members: members + }); - if (nodes.from.indexOf(n) !== -1) { - connectFrom = true; - } + if (insertPair) { + // We're adding a member that must stay paired with an existing member. + // (This feature is used by `actionSplit`) + // + // This is tricky because the members may exist multiple times in the + // member list, and with different A-B/B-A ordering and different roles. + // (e.g. a bus route that loops out and back - #4589). + // + // Replace the existing member with a temporary way, + // so that `osmJoinWays` can treat the pair like a single way. + tempWay = osmWay({ + id: 'wTemp', + nodes: insertPair.nodes + }); + graph = graph.replace(tempWay); + var tempMember = { + id: tempWay.id, + type: 'way', + role: member.role + }; + var tempRelation = relation.replaceMember({ + id: insertPair.originalID + }, tempMember, true); + groups = utilArrayGroupBy(tempRelation.members, 'type'); + groups.way = groups.way || []; // Insert pair is reversed if the inserted way comes before the original one. + // (Except when they form a loop.) - if (nodes.via.indexOf(n) !== -1) { - connectVia = true; - } + var originalWay = graph.entity(insertPair.originalID); + var insertedWay = graph.entity(insertPair.insertedID); + insertPairIsReversed = originalWay.nodes.length > 0 && insertedWay.nodes.length > 0 && insertedWay.nodes[insertedWay.nodes.length - 1] === originalWay.nodes[0] && originalWay.nodes[originalWay.nodes.length - 1] !== insertedWay.nodes[0]; + } else { + // Add the member anywhere, one time. Just push and let `osmJoinWays` decide where to put it. + groups = utilArrayGroupBy(relation.members, 'type'); + groups.way = groups.way || []; + groups.way.push(member); + } - if (nodes.to.indexOf(n) !== -1) { - connectTo = true; - } + members = withIndex(groups.way); + var joined = osmJoinWays(members, graph); // `joined` might not contain all of the way members, + // But will contain only the completed (downloaded) members - if (nodes.keyfrom.indexOf(n) !== -1) { - connectKeyFrom = true; - } + for (i = 0; i < joined.length; i++) { + var segment = joined[i]; + var nodes = segment.nodes.slice(); + var startIndex = segment[0].index; // j = array index in `members` where this segment starts - if (nodes.keyto.indexOf(n) !== -1) { - connectKeyTo = true; + for (j = 0; j < members.length; j++) { + if (members[j].index === startIndex) { + break; } - } - - if (connectFrom && connectTo && !isUturn) { - return 'restriction'; - } - - if (connectFrom && connectVia) { - return 'restriction'; - } - - if (connectTo && connectVia) { - return 'restriction'; - } // connecting to a key node - - // if both nodes are on a member way (i.e. part of the turn restriction), - // the connecting node must be adjacent to the key node. - + } // k = each member in segment - if (connectKeyFrom || connectKeyTo) { - if (nodeIDs.length !== 2) { - return 'restriction'; - } - var n0 = null; - var n1 = null; + for (k = 0; k < segment.length; k++) { + item = segment[k]; + var way = graph.entity(item.id); // If this is a paired item, generate members in correct order and role - for (j = 0; j < memberWays.length; j++) { - way = memberWays[j]; + if (tempWay && item.id === tempWay.id) { + var reverse = nodes[0].id !== insertPair.nodes[0] ^ insertPairIsReversed; - if (way.contains(nodeIDs[0])) { - n0 = nodeIDs[0]; + if (reverse) { + item.pair = [{ + id: insertPair.insertedID, + type: 'way', + role: item.role + }, { + id: insertPair.originalID, + type: 'way', + role: item.role + }]; + } else { + item.pair = [{ + id: insertPair.originalID, + type: 'way', + role: item.role + }, { + id: insertPair.insertedID, + type: 'way', + role: item.role + }]; } + } // reorder `members` if necessary - if (way.contains(nodeIDs[1])) { - n1 = nodeIDs[1]; + + if (k > 0) { + if (j + k >= members.length || item.index !== members[j + k].index) { + moveMember(members, item.index, j + k); } } - if (n0 && n1) { - // both nodes are part of the restriction - var ok = false; + nodes.splice(0, way.nodes.length - 1); + } + } - for (j = 0; j < memberWays.length; j++) { - way = memberWays[j]; + if (tempWay) { + graph = graph.remove(tempWay); + } // Final pass: skip dead items, split pairs, remove index properties - if (way.areAdjacent(n0, n1)) { - ok = true; - break; - } - } - if (!ok) { - return 'restriction'; - } - } - } // 2b. disable if nodes being connected will destroy a member way in a restriction - // (to test, make a copy and try actually connecting the nodes) + var wayMembers = []; + for (i = 0; i < members.length; i++) { + item = members[i]; + if (item.index === -1) continue; - for (j = 0; j < memberWays.length; j++) { - way = memberWays[j].update({}); // make copy + if (item.pair) { + wayMembers.push(item.pair[0]); + wayMembers.push(item.pair[1]); + } else { + wayMembers.push(utilObjectOmit(item, ['index'])); + } + } // Put stops and platforms first, then nodes, ways, relations + // This is recommended for Public Transport v2 routes: + // see https://wiki.openstreetmap.org/wiki/Public_transport#Service_routes - for (k = 0; k < nodeIDs.length; k++) { - if (nodeIDs[k] === survivor.id) continue; - if (way.areAdjacent(nodeIDs[k], survivor.id)) { - way = way.removeNode(nodeIDs[k]); - } else { - way = way.replaceNode(nodeIDs[k], survivor.id); - } - } + var newMembers = PTv2members.concat(groups.node || [], wayMembers, groups.relation || []); + return graph.replace(relation.update({ + members: newMembers + })); // `moveMember()` changes the `members` array in place by splicing + // the item with `.index = findIndex` to where it belongs, + // and marking the old position as "dead" with `.index = -1` + // + // j=5, k=0 jk + // segment 5 4 7 6 + // members 0 1 2 3 4 5 6 7 8 9 keep 5 in j+k + // + // j=5, k=1 j k + // segment 5 4 7 6 + // members 0 1 2 3 4 5 6 7 8 9 move 4 to j+k + // members 0 1 2 3 x 5 4 6 7 8 9 moved + // + // j=5, k=2 j k + // segment 5 4 7 6 + // members 0 1 2 3 x 5 4 6 7 8 9 move 7 to j+k + // members 0 1 2 3 x 5 4 7 6 x 8 9 moved + // + // j=5, k=3 j k + // segment 5 4 7 6 + // members 0 1 2 3 x 5 4 7 6 x 8 9 keep 6 in j+k + // - if (way.isDegenerate()) { - return 'restriction'; + function moveMember(arr, findIndex, toIndex) { + var i; + + for (i = 0; i < arr.length; i++) { + if (arr[i].index === findIndex) { + break; } } - } - - return false; // if a key node appears multiple times (indexOf !== lastIndexOf) it's a FROM-VIA or TO-VIA junction - - function hasDuplicates(n, i, arr) { - return arr.indexOf(n) !== arr.lastIndexOf(n); - } - function keyNodeFilter(froms, tos) { - return function (n) { - return froms.indexOf(n) === -1 && tos.indexOf(n) === -1; - }; - } + var item = Object.assign({}, arr[i]); // shallow copy - function collectNodes(member, collection) { - var entity = graph.hasEntity(member.id); - if (!entity) return; - var role = member.role || ''; + arr[i].index = -1; // mark as dead - if (!collection[role]) { - collection[role] = []; - } + item.index = toIndex; + arr.splice(toIndex, 0, item); + } // This is the same as `Relation.indexedMembers`, + // Except we don't want to index all the members, only the ways - if (member.type === 'node') { - collection[role].push(member.id); - if (role === 'via') { - collection.keyfrom.push(member.id); - collection.keyto.push(member.id); - } - } else if (member.type === 'way') { - collection[role].push.apply(collection[role], entity.nodes); + function withIndex(arr) { + var result = new Array(arr.length); - if (role === 'from' || role === 'via') { - collection.keyfrom.push(entity.first()); - collection.keyfrom.push(entity.last()); - } + for (var i = 0; i < arr.length; i++) { + result[i] = Object.assign({}, arr[i]); // shallow copy - if (role === 'to' || role === 'via') { - collection.keyto.push(entity.first()); - collection.keyto.push(entity.last()); - } + result[i].index = i; } - } - }; - return action; + return result; + } + } } - function actionCopyEntities(ids, fromGraph) { - var _copies = {}; + function actionAddMidpoint(midpoint, node) { + return function (graph) { + graph = graph.replace(node.move(midpoint.loc)); + var parents = utilArrayIntersection(graph.parentWays(graph.entity(midpoint.edge[0])), graph.parentWays(graph.entity(midpoint.edge[1]))); + parents.forEach(function (way) { + for (var i = 0; i < way.nodes.length - 1; i++) { + if (geoEdgeEqual([way.nodes[i], way.nodes[i + 1]], midpoint.edge)) { + graph = graph.replace(graph.entity(way.id).addNode(node.id, i + 1)); // Add only one midpoint on doubled-back segments, + // turning them into self-intersections. - var action = function action(graph) { - ids.forEach(function (id) { - fromGraph.entity(id).copy(fromGraph, _copies); + return; + } + } }); - - for (var id in _copies) { - graph = graph.replace(_copies[id]); - } - return graph; }; + } - action.copies = function () { - return _copies; + // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/AddNodeToWayAction.as + function actionAddVertex(wayId, nodeId, index) { + return function (graph) { + return graph.replace(graph.entity(wayId).addNode(nodeId, index)); }; - - return action; } - function actionDeleteMember(relationId, memberIndex) { + function actionChangeMember(relationId, member, memberIndex) { return function (graph) { - var relation = graph.entity(relationId).removeMember(memberIndex); - graph = graph.replace(relation); + return graph.replace(graph.entity(relationId).updateMember(member, memberIndex)); + }; + } - if (relation.isDegenerate()) { - graph = actionDeleteRelation(relation.id)(graph); - } + function actionChangePreset(entityID, oldPreset, newPreset, skipFieldDefaults) { + return function action(graph) { + var entity = graph.entity(entityID); + var geometry = entity.geometry(graph); + var tags = entity.tags; // preserve tags that the new preset might care about, if any - return graph; + if (oldPreset) tags = oldPreset.unsetTags(tags, geometry, newPreset && newPreset.addTags ? Object.keys(newPreset.addTags) : null); + if (newPreset) tags = newPreset.setTags(tags, geometry, skipFieldDefaults); + return graph.replace(entity.update({ + tags: tags + })); }; } - function actionDiscardTags(difference, discardTags) { - discardTags = discardTags || {}; + function actionChangeTags(entityId, tags) { return function (graph) { - difference.modified().forEach(checkTags); - difference.created().forEach(checkTags); - return graph; + var entity = graph.entity(entityId); + return graph.replace(entity.update({ + tags: tags + })); + }; + } - function checkTags(entity) { - var keys = Object.keys(entity.tags); - var didDiscard = false; - var tags = {}; + function osmNode() { + if (!(this instanceof osmNode)) { + return new osmNode().initialize(arguments); + } else if (arguments.length) { + this.initialize(arguments); + } + } + osmEntity.node = osmNode; + osmNode.prototype = Object.create(osmEntity.prototype); + Object.assign(osmNode.prototype, { + type: 'node', + loc: [9999, 9999], + extent: function extent() { + return new geoExtent(this.loc); + }, + geometry: function geometry(graph) { + return graph["transient"](this, 'geometry', function () { + return graph.isPoi(this) ? 'point' : 'vertex'; + }); + }, + move: function move(loc) { + return this.update({ + loc: loc + }); + }, + isDegenerate: function isDegenerate() { + return !(Array.isArray(this.loc) && this.loc.length === 2 && this.loc[0] >= -180 && this.loc[0] <= 180 && this.loc[1] >= -90 && this.loc[1] <= 90); + }, + // Inspect tags and geometry to determine which direction(s) this node/vertex points + directions: function directions(resolver, projection) { + var val; + var i; // which tag to use? - for (var i = 0; i < keys.length; i++) { - var k = keys[i]; + if (this.isHighwayIntersection(resolver) && (this.tags.stop || '').toLowerCase() === 'all') { + // all-way stop tag on a highway intersection + val = 'all'; + } else { + // generic direction tag + val = (this.tags.direction || '').toLowerCase(); // better suffix-style direction tag - if (discardTags[k] || !entity.tags[k]) { - didDiscard = true; - } else { - tags[k] = entity.tags[k]; - } - } + var re = /:direction$/i; + var keys = Object.keys(this.tags); - if (didDiscard) { - graph = graph.replace(entity.update({ - tags: tags - })); + for (i = 0; i < keys.length; i++) { + if (re.test(keys[i])) { + val = this.tags[keys[i]].toLowerCase(); + break; + } } } - }; - } - // - // Optionally, disconnect only the given ways. - // - // For testing convenience, accepts an ID to assign to the (first) new node. - // Normally, this will be undefined and the way will automatically - // be assigned a new ID. - // - // This is the inverse of `iD.actionConnect`. - // - // Reference: - // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/UnjoinNodeAction.as - // https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/actions/UnGlueAction.java - // + if (val === '') return []; + var cardinal = { + north: 0, + n: 0, + northnortheast: 22, + nne: 22, + northeast: 45, + ne: 45, + eastnortheast: 67, + ene: 67, + east: 90, + e: 90, + eastsoutheast: 112, + ese: 112, + southeast: 135, + se: 135, + southsoutheast: 157, + sse: 157, + south: 180, + s: 180, + southsouthwest: 202, + ssw: 202, + southwest: 225, + sw: 225, + westsouthwest: 247, + wsw: 247, + west: 270, + w: 270, + westnorthwest: 292, + wnw: 292, + northwest: 315, + nw: 315, + northnorthwest: 337, + nnw: 337 + }; + var values = val.split(';'); + var results = []; + values.forEach(function (v) { + // swap cardinal for numeric directions + if (cardinal[v] !== undefined) { + v = cardinal[v]; + } // numeric direction - just add to results - function actionDisconnect(nodeId, newNodeId) { - var wayIds; - var action = function action(graph) { - var node = graph.entity(nodeId); - var connections = action.connections(graph); - connections.forEach(function (connection) { - var way = graph.entity(connection.wayID); - var newNode = osmNode({ - id: newNodeId, - loc: node.loc, - tags: node.tags - }); - graph = graph.replace(newNode); + if (v !== '' && !isNaN(+v)) { + results.push(+v); + return; + } // string direction - inspect parent ways - if (connection.index === 0 && way.isArea()) { - // replace shared node with shared node.. - graph = graph.replace(way.replaceNode(way.nodes[0], newNode.id)); - } else if (way.isClosed() && connection.index === way.nodes.length - 1) { - // replace closing node with new new node.. - graph = graph.replace(way.unclose().addNode(newNode.id)); - } else { - // replace shared node with multiple new nodes.. - graph = graph.replace(way.updateNode(newNode.id, connection.index)); - } - }); - return graph; - }; - action.connections = function (graph) { - var candidates = []; - var keeping = false; - var parentWays = graph.parentWays(graph.entity(nodeId)); - var way, waynode; + var lookBackward = this.tags['traffic_sign:backward'] || v === 'backward' || v === 'both' || v === 'all'; + var lookForward = this.tags['traffic_sign:forward'] || v === 'forward' || v === 'both' || v === 'all'; + if (!lookForward && !lookBackward) return; + var nodeIds = {}; + resolver.parentWays(this).forEach(function (parent) { + var nodes = parent.nodes; - for (var i = 0; i < parentWays.length; i++) { - way = parentWays[i]; - - if (wayIds && wayIds.indexOf(way.id) === -1) { - keeping = true; - continue; - } - - if (way.isArea() && way.nodes[0] === nodeId) { - candidates.push({ - wayID: way.id, - index: 0 - }); - } else { - for (var j = 0; j < way.nodes.length; j++) { - waynode = way.nodes[j]; - - if (waynode === nodeId) { - if (way.isClosed() && parentWays.length > 1 && wayIds && wayIds.indexOf(way.id) !== -1 && j === way.nodes.length - 1) { - continue; + for (i = 0; i < nodes.length; i++) { + if (nodes[i] === this.id) { + // match current entity + if (lookForward && i > 0) { + nodeIds[nodes[i - 1]] = true; // look back to prev node } - candidates.push({ - wayID: way.id, - index: j - }); + if (lookBackward && i < nodes.length - 1) { + nodeIds[nodes[i + 1]] = true; // look ahead to next node + } } } - } - } - - return keeping ? candidates : candidates.slice(1); - }; + }, this); + Object.keys(nodeIds).forEach(function (nodeId) { + // +90 because geoAngle returns angle from X axis, not Y (north) + results.push(geoAngle(this, resolver.entity(nodeId), projection) * (180 / Math.PI) + 90); + }, this); + }, this); + return utilArrayUniq(results); + }, + isCrossing: function isCrossing() { + return this.tags.highway === 'crossing' || this.tags.railway && this.tags.railway.indexOf('crossing') !== -1; + }, + isEndpoint: function isEndpoint(resolver) { + return resolver["transient"](this, 'isEndpoint', function () { + var id = this.id; + return resolver.parentWays(this).filter(function (parent) { + return !parent.isClosed() && !!parent.affix(id); + }).length > 0; + }); + }, + isConnected: function isConnected(resolver) { + return resolver["transient"](this, 'isConnected', function () { + var parents = resolver.parentWays(this); - action.disabled = function (graph) { - var connections = action.connections(graph); - if (connections.length === 0) return 'not_connected'; - var parentWays = graph.parentWays(graph.entity(nodeId)); - var seenRelationIds = {}; - var sharedRelation; - parentWays.forEach(function (way) { - var relations = graph.parentRelations(way); - relations.forEach(function (relation) { - if (relation.id in seenRelationIds) { - if (wayIds) { - if (wayIds.indexOf(way.id) !== -1 || wayIds.indexOf(seenRelationIds[relation.id]) !== -1) { - sharedRelation = relation; - } - } else { - sharedRelation = relation; - } - } else { - seenRelationIds[relation.id] = way.id; + if (parents.length > 1) { + // vertex is connected to multiple parent ways + for (var i in parents) { + if (parents[i].geometry(resolver) === 'line' && parents[i].hasInterestingTags()) return true; } + } else if (parents.length === 1) { + var way = parents[0]; + var nodes = way.nodes.slice(); + + if (way.isClosed()) { + nodes.pop(); + } // ignore connecting node if closed + // return true if vertex appears multiple times (way is self intersecting) + + + return nodes.indexOf(this.id) !== nodes.lastIndexOf(this.id); + } + + return false; + }); + }, + parentIntersectionWays: function parentIntersectionWays(resolver) { + return resolver["transient"](this, 'parentIntersectionWays', function () { + return resolver.parentWays(this).filter(function (parent) { + return (parent.tags.highway || parent.tags.waterway || parent.tags.railway || parent.tags.aeroway) && parent.geometry(resolver) === 'line'; }); }); - if (sharedRelation) return 'relation'; - }; + }, + isIntersection: function isIntersection(resolver) { + return this.parentIntersectionWays(resolver).length > 1; + }, + isHighwayIntersection: function isHighwayIntersection(resolver) { + return resolver["transient"](this, 'isHighwayIntersection', function () { + return resolver.parentWays(this).filter(function (parent) { + return parent.tags.highway && parent.geometry(resolver) === 'line'; + }).length > 1; + }); + }, + isOnAddressLine: function isOnAddressLine(resolver) { + return resolver["transient"](this, 'isOnAddressLine', function () { + return resolver.parentWays(this).filter(function (parent) { + return parent.tags.hasOwnProperty('addr:interpolation') && parent.geometry(resolver) === 'line'; + }).length > 0; + }); + }, + asJXON: function asJXON(changeset_id) { + var r = { + node: { + '@id': this.osmId(), + '@lon': this.loc[0], + '@lat': this.loc[1], + '@version': this.version || 0, + tag: Object.keys(this.tags).map(function (k) { + return { + keyAttributes: { + k: k, + v: this.tags[k] + } + }; + }, this) + } + }; + if (changeset_id) r.node['@changeset'] = changeset_id; + return r; + }, + asGeoJSON: function asGeoJSON() { + return { + type: 'Point', + coordinates: this.loc + }; + } + }); - action.limitWays = function (val) { - if (!arguments.length) return wayIds; - wayIds = val; - return action; - }; + function actionCircularize(wayId, projection, maxAngle) { + maxAngle = (maxAngle || 20) * Math.PI / 180; - return action; - } + var action = function action(graph, t) { + if (t === null || !isFinite(t)) t = 1; + t = Math.min(Math.max(+t, 0), 1); + var way = graph.entity(wayId); + var origNodes = {}; + graph.childNodes(way).forEach(function (node) { + if (!origNodes[node.id]) origNodes[node.id] = node; + }); - function actionExtract(entityID, projection) { - var extractedNodeID; + if (!way.isConvex(graph)) { + graph = action.makeConvex(graph); + } - var action = function action(graph) { - var entity = graph.entity(entityID); + var nodes = utilArrayUniq(graph.childNodes(way)); + var keyNodes = nodes.filter(function (n) { + return graph.parentWays(n).length !== 1; + }); + var points = nodes.map(function (n) { + return projection(n.loc); + }); + var keyPoints = keyNodes.map(function (n) { + return projection(n.loc); + }); + var centroid = points.length === 2 ? geoVecInterp(points[0], points[1], 0.5) : d3_polygonCentroid(points); + var radius = d3_median(points, function (p) { + return geoVecLength(centroid, p); + }); + var sign = d3_polygonArea(points) > 0 ? 1 : -1; + var ids, i, j, k; // we need at least two key nodes for the algorithm to work - if (entity.type === 'node') { - return extractFromNode(entity, graph); + if (!keyNodes.length) { + keyNodes = [nodes[0]]; + keyPoints = [points[0]]; } - return extractFromWayOrRelation(entity, graph); - }; + if (keyNodes.length === 1) { + var index = nodes.indexOf(keyNodes[0]); + var oppositeIndex = Math.floor((index + nodes.length / 2) % nodes.length); + keyNodes.push(nodes[oppositeIndex]); + keyPoints.push(points[oppositeIndex]); + } // key points and nodes are those connected to the ways, + // they are projected onto the circle, in between nodes are moved + // to constant intervals between key nodes, extra in between nodes are + // added if necessary. - function extractFromNode(node, graph) { - extractedNodeID = node.id; // Create a new node to replace the one we will detach - var replacement = osmNode({ - loc: node.loc - }); - graph = graph.replace(replacement); // Process each way in turn, updating the graph as we go + for (i = 0; i < keyPoints.length; i++) { + var nextKeyNodeIndex = (i + 1) % keyNodes.length; + var startNode = keyNodes[i]; + var endNode = keyNodes[nextKeyNodeIndex]; + var startNodeIndex = nodes.indexOf(startNode); + var endNodeIndex = nodes.indexOf(endNode); + var numberNewPoints = -1; + var indexRange = endNodeIndex - startNodeIndex; + var nearNodes = {}; + var inBetweenNodes = []; + var startAngle, endAngle, totalAngle, eachAngle; + var angle, loc, node, origNode; - graph = graph.parentWays(node).reduce(function (accGraph, parentWay) { - return accGraph.replace(parentWay.replaceNode(entityID, replacement.id)); - }, graph); // Process any relations too + if (indexRange < 0) { + indexRange += nodes.length; + } // position this key node - return graph.parentRelations(node).reduce(function (accGraph, parentRel) { - return accGraph.replace(parentRel.replaceMember(node, replacement)); - }, graph); - } - function extractFromWayOrRelation(entity, graph) { - var fromGeometry = entity.geometry(graph); - var keysToCopyAndRetain = ['source', 'wheelchair']; - var keysToRetain = ['area']; - var buildingKeysToRetain = ['architect', 'building', 'height', 'layer']; - var extractedLoc = d3_geoPath(projection).centroid(entity.asGeoJSON(graph)); - extractedLoc = extractedLoc && projection.invert(extractedLoc); + var distance = geoVecLength(centroid, keyPoints[i]) || 1e-4; + keyPoints[i] = [centroid[0] + (keyPoints[i][0] - centroid[0]) / distance * radius, centroid[1] + (keyPoints[i][1] - centroid[1]) / distance * radius]; + loc = projection.invert(keyPoints[i]); + node = keyNodes[i]; + origNode = origNodes[node.id]; + node = node.move(geoVecInterp(origNode.loc, loc, t)); + graph = graph.replace(node); // figure out the between delta angle we want to match to - if (!extractedLoc || !isFinite(extractedLoc[0]) || !isFinite(extractedLoc[1])) { - extractedLoc = entity.extent(graph).center(); - } + startAngle = Math.atan2(keyPoints[i][1] - centroid[1], keyPoints[i][0] - centroid[0]); + endAngle = Math.atan2(keyPoints[nextKeyNodeIndex][1] - centroid[1], keyPoints[nextKeyNodeIndex][0] - centroid[0]); + totalAngle = endAngle - startAngle; // detects looping around -pi/pi - var indoorAreaValues = { - area: true, - corridor: true, - elevator: true, - level: true, - room: true - }; - var isBuilding = entity.tags.building && entity.tags.building !== 'no' || entity.tags['building:part'] && entity.tags['building:part'] !== 'no'; - var isIndoorArea = fromGeometry === 'area' && entity.tags.indoor && indoorAreaValues[entity.tags.indoor]; - var entityTags = Object.assign({}, entity.tags); // shallow copy + if (totalAngle * sign > 0) { + totalAngle = -sign * (2 * Math.PI - Math.abs(totalAngle)); + } - var pointTags = {}; + do { + numberNewPoints++; + eachAngle = totalAngle / (indexRange + numberNewPoints); + } while (Math.abs(eachAngle) > maxAngle); // move existing nodes - for (var key in entityTags) { - if (entity.type === 'relation' && key === 'type') { - continue; - } - if (keysToRetain.indexOf(key) !== -1) { - continue; - } + for (j = 1; j < indexRange; j++) { + angle = startAngle + j * eachAngle; + loc = projection.invert([centroid[0] + Math.cos(angle) * radius, centroid[1] + Math.sin(angle) * radius]); + node = nodes[(j + startNodeIndex) % nodes.length]; + origNode = origNodes[node.id]; + nearNodes[node.id] = angle; + node = node.move(geoVecInterp(origNode.loc, loc, t)); + graph = graph.replace(node); + } // add new in between nodes if necessary - if (isBuilding) { - // don't transfer building-related tags - if (buildingKeysToRetain.indexOf(key) !== -1 || key.match(/^building:.{1,}/) || key.match(/^roof:.{1,}/)) continue; - } // leave `indoor` tag on the area + for (j = 0; j < numberNewPoints; j++) { + angle = startAngle + (indexRange + j) * eachAngle; + loc = projection.invert([centroid[0] + Math.cos(angle) * radius, centroid[1] + Math.sin(angle) * radius]); // choose a nearnode to use as the original - if (isIndoorArea && key === 'indoor') { - continue; - } // copy the tag from the entity to the point + var min = Infinity; + for (var nodeId in nearNodes) { + var nearAngle = nearNodes[nodeId]; + var dist = Math.abs(nearAngle - angle); - pointTags[key] = entityTags[key]; // leave addresses and some other tags so they're on both features + if (dist < min) { + min = dist; + origNode = origNodes[nodeId]; + } + } - if (keysToCopyAndRetain.indexOf(key) !== -1 || key.match(/^addr:.{1,}/)) { - continue; - } else if (isIndoorArea && key === 'level') { - // leave `level` on both features - continue; - } // remove the tag from the entity + node = osmNode({ + loc: geoVecInterp(origNode.loc, loc, t) + }); + graph = graph.replace(node); + nodes.splice(endNodeIndex + j, 0, node); + inBetweenNodes.push(node.id); + } // Check for other ways that share these keyNodes.. + // If keyNodes are adjacent in both ways, + // we can add inBetweenNodes to that shared way too.. - delete entityTags[key]; - } + if (indexRange === 1 && inBetweenNodes.length) { + var startIndex1 = way.nodes.lastIndexOf(startNode.id); + var endIndex1 = way.nodes.lastIndexOf(endNode.id); + var wayDirection1 = endIndex1 - startIndex1; - if (!isBuilding && !isIndoorArea && fromGeometry === 'area') { - // ensure that areas keep area geometry - entityTags.area = 'yes'; - } + if (wayDirection1 < -1) { + wayDirection1 = 1; + } - var replacement = osmNode({ - loc: extractedLoc, - tags: pointTags - }); - graph = graph.replace(replacement); - extractedNodeID = replacement.id; - return graph.replace(entity.update({ - tags: entityTags - })); - } + var parentWays = graph.parentWays(keyNodes[i]); - action.getExtractedNodeID = function () { - return extractedNodeID; - }; + for (j = 0; j < parentWays.length; j++) { + var sharedWay = parentWays[j]; + if (sharedWay === way) continue; - return action; - } + if (sharedWay.areAdjacent(startNode.id, endNode.id)) { + var startIndex2 = sharedWay.nodes.lastIndexOf(startNode.id); + var endIndex2 = sharedWay.nodes.lastIndexOf(endNode.id); + var wayDirection2 = endIndex2 - startIndex2; + var insertAt = endIndex2; - // - // This is the inverse of `iD.actionSplit`. - // - // Reference: - // https://github.com/systemed/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/MergeWaysAction.as - // https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/actions/CombineWayAction.java - // + if (wayDirection2 < -1) { + wayDirection2 = 1; + } - function actionJoin(ids) { - function groupEntitiesByGeometry(graph) { - var entities = ids.map(function (id) { - return graph.entity(id); - }); - return Object.assign({ - line: [] - }, utilArrayGroupBy(entities, function (entity) { - return entity.geometry(graph); - })); - } + if (wayDirection1 !== wayDirection2) { + inBetweenNodes.reverse(); + insertAt = startIndex2; + } - var action = function action(graph) { - var ways = ids.map(graph.entity, graph); // if any of the ways are sided (e.g. coastline, cliff, kerb) - // sort them first so they establish the overall order - #6033 + for (k = 0; k < inBetweenNodes.length; k++) { + sharedWay = sharedWay.addNode(inBetweenNodes[k], insertAt + k); + } - ways.sort(function (a, b) { - var aSided = a.isSided(); - var bSided = b.isSided(); - return aSided && !bSided ? -1 : bSided && !aSided ? 1 : 0; - }); // Prefer to keep an existing way. - // if there are multiple existing ways, keep the oldest one - // the oldest way is determined by the ID of the way + graph = graph.replace(sharedWay); + } + } + } + } // update the way to have all the new nodes - var survivorID = (ways.filter(function (way) { - return !way.isNew(); - }).sort(function (a, b) { - return +a.osmId() - +b.osmId(); - })[0] || ways[0]).id; - var sequences = osmJoinWays(ways, graph); - var joined = sequences[0]; // We might need to reverse some of these ways before joining them. #4688 - // `joined.actions` property will contain any actions we need to apply. - graph = sequences.actions.reduce(function (g, action) { - return action(g); - }, graph); - var survivor = graph.entity(survivorID); - survivor = survivor.update({ - nodes: joined.nodes.map(function (n) { - return n.id; - }) + ids = nodes.map(function (n) { + return n.id; }); - graph = graph.replace(survivor); - joined.forEach(function (way) { - if (way.id === survivorID) return; - graph.parentRelations(way).forEach(function (parent) { - graph = graph.replace(parent.replaceMember(way, survivor)); - }); - survivor = survivor.mergeTags(way.tags); - graph = graph.replace(survivor); - graph = actionDeleteWay(way.id)(graph); - }); // Finds if the join created a single-member multipolygon, - // and if so turns it into a basic area instead - - function checkForSimpleMultipolygon() { - if (!survivor.isClosed()) return; - var multipolygons = graph.parentMultipolygons(survivor).filter(function (multipolygon) { - // find multipolygons where the survivor is the only member - return multipolygon.members.length === 1; - }); // skip if this is the single member of multiple multipolygons + ids.push(ids[0]); + way = way.update({ + nodes: ids + }); + graph = graph.replace(way); + return graph; + }; - if (multipolygons.length !== 1) return; - var multipolygon = multipolygons[0]; + action.makeConvex = function (graph) { + var way = graph.entity(wayId); + var nodes = utilArrayUniq(graph.childNodes(way)); + var points = nodes.map(function (n) { + return projection(n.loc); + }); + var sign = d3_polygonArea(points) > 0 ? 1 : -1; + var hull = d3_polygonHull(points); + var i, j; // D3 convex hulls go counterclockwise.. - for (var key in survivor.tags) { - if (multipolygon.tags[key] && // don't collapse if tags cannot be cleanly merged - multipolygon.tags[key] !== survivor.tags[key]) return; - } + if (sign === -1) { + nodes.reverse(); + points.reverse(); + } - survivor = survivor.mergeTags(multipolygon.tags); - graph = graph.replace(survivor); - graph = actionDeleteRelation(multipolygon.id, true - /* allow untagged members */ - )(graph); - var tags = Object.assign({}, survivor.tags); + for (i = 0; i < hull.length - 1; i++) { + var startIndex = points.indexOf(hull[i]); + var endIndex = points.indexOf(hull[i + 1]); + var indexRange = endIndex - startIndex; - if (survivor.geometry(graph) !== 'area') { - // ensure the feature persists as an area - tags.area = 'yes'; - } + if (indexRange < 0) { + indexRange += nodes.length; + } // move interior nodes to the surface of the convex hull.. - delete tags.type; // remove type=multipolygon - survivor = survivor.update({ - tags: tags - }); - graph = graph.replace(survivor); + for (j = 1; j < indexRange; j++) { + var point = geoVecInterp(hull[i], hull[i + 1], j / indexRange); + var node = nodes[(j + startIndex) % nodes.length].move(projection.invert(point)); + graph = graph.replace(node); + } } - checkForSimpleMultipolygon(); return graph; - }; // Returns the number of nodes the resultant way is expected to have - - - action.resultingWayNodesLength = function (graph) { - return ids.reduce(function (count, id) { - return count + graph.entity(id).nodes.length; - }, 0) - ids.length - 1; }; action.disabled = function (graph) { - var geometries = groupEntitiesByGeometry(graph); + if (!graph.entity(wayId).isClosed()) { + return 'not_closed'; + } //disable when already circular - if (ids.length < 2 || ids.length !== geometries.line.length) { - return 'not_eligible'; - } - var joined = osmJoinWays(ids.map(graph.entity, graph), graph); + var way = graph.entity(wayId); + var nodes = utilArrayUniq(graph.childNodes(way)); + var points = nodes.map(function (n) { + return projection(n.loc); + }); + var hull = d3_polygonHull(points); + var epsilonAngle = Math.PI / 180; - if (joined.length > 1) { - return 'not_adjacent'; + if (hull.length !== points.length || hull.length < 3) { + return false; } - var i; // All joined ways must belong to the same set of (non-restriction) relations. - // Restriction relations have different logic, below, which allows some cases - // this prohibits, and prohibits some cases this allows. - - var sortedParentRelations = function sortedParentRelations(id) { - return graph.parentRelations(graph.entity(id)).filter(function (rel) { - return !rel.isRestriction() && !rel.isConnectivity(); - }).sort(function (a, b) { - return a.id - b.id; - }); - }; - - var relsA = sortedParentRelations(ids[0]); + var centroid = d3_polygonCentroid(points); + var radius = geoVecLengthSquare(centroid, points[0]); + var i, actualPoint; // compare distances between centroid and points - for (i = 1; i < ids.length; i++) { - var relsB = sortedParentRelations(ids[i]); + for (i = 0; i < hull.length; i++) { + actualPoint = hull[i]; + var actualDist = geoVecLengthSquare(actualPoint, centroid); + var diff = Math.abs(actualDist - radius); //compare distances with epsilon-error (5%) - if (!utilArrayIdentical(relsA, relsB)) { - return 'conflicting_relations'; + if (diff > 0.05 * radius) { + return false; } - } // Loop through all combinations of path-pairs - // to check potential intersections between all pairs - + } //check if central angles are smaller than maxAngle - for (i = 0; i < ids.length - 1; i++) { - for (var j = i + 1; j < ids.length; j++) { - var path1 = graph.childNodes(graph.entity(ids[i])).map(function (e) { - return e.loc; - }); - var path2 = graph.childNodes(graph.entity(ids[j])).map(function (e) { - return e.loc; - }); - var intersections = geoPathIntersections(path1, path2); // Check if intersections are just nodes lying on top of - // each other/the line, as opposed to crossing it - var common = utilArrayIntersection(joined[0].nodes.map(function (n) { - return n.loc.toString(); - }), intersections.map(function (n) { - return n.toString(); - })); + for (i = 0; i < hull.length; i++) { + actualPoint = hull[i]; + var nextPoint = hull[(i + 1) % hull.length]; + var startAngle = Math.atan2(actualPoint[1] - centroid[1], actualPoint[0] - centroid[0]); + var endAngle = Math.atan2(nextPoint[1] - centroid[1], nextPoint[0] - centroid[0]); + var angle = endAngle - startAngle; - if (common.length !== intersections.length) { - return 'paths_intersect'; - } + if (angle < 0) { + angle = -angle; } - } - - var nodeIds = joined[0].nodes.map(function (n) { - return n.id; - }).slice(1, -1); - var relation; - var tags = {}; - var conflicting = false; - joined[0].forEach(function (way) { - var parents = graph.parentRelations(way); - parents.forEach(function (parent) { - if ((parent.isRestriction() || parent.isConnectivity()) && parent.members.some(function (m) { - return nodeIds.indexOf(m.id) >= 0; - })) { - relation = parent; - } - }); - for (var k in way.tags) { - if (!(k in tags)) { - tags[k] = way.tags[k]; - } else if (tags[k] && osmIsInterestingTag(k) && tags[k] !== way.tags[k]) { - conflicting = true; - } + if (angle > Math.PI) { + angle = 2 * Math.PI - angle; } - }); - if (relation) { - return relation.isRestriction() ? 'restriction' : 'connectivity'; + if (angle > maxAngle + epsilonAngle) { + return false; + } } - if (conflicting) { - return 'conflicting_tags'; - } + return 'already_circular'; }; + action.transitionable = true; return action; } - function actionMerge(ids) { - function groupEntitiesByGeometry(graph) { - var entities = ids.map(function (id) { - return graph.entity(id); - }); - return Object.assign({ - point: [], - area: [], - line: [], - relation: [] - }, utilArrayGroupBy(entities, function (entity) { - return entity.geometry(graph); - })); + function actionDeleteWay(wayID) { + function canDeleteNode(node, graph) { + // don't delete nodes still attached to ways or relations + if (graph.parentWays(node).length || graph.parentRelations(node).length) return false; + var geometries = osmNodeGeometriesForTags(node.tags); // don't delete if this node can be a standalone point + + if (geometries.point) return false; // delete if this node only be a vertex + + if (geometries.vertex) return true; // iD doesn't know if this should be a point or vertex, + // so only delete if there are no interesting tags + + return !node.hasInterestingTags(); } var action = function action(graph) { - var geometries = groupEntitiesByGeometry(graph); - var target = geometries.area[0] || geometries.line[0]; - var points = geometries.point; - points.forEach(function (point) { - target = target.mergeTags(point.tags); - graph = graph.replace(target); - graph.parentRelations(point).forEach(function (parent) { - graph = graph.replace(parent.replaceMember(point, target)); - }); - var nodes = utilArrayUniq(graph.childNodes(target)); - var removeNode = point; + var way = graph.entity(wayID); + graph.parentRelations(way).forEach(function (parent) { + parent = parent.removeMembersWithID(wayID); + graph = graph.replace(parent); - for (var i = 0; i < nodes.length; i++) { - var node = nodes[i]; + if (parent.isDegenerate()) { + graph = actionDeleteRelation(parent.id)(graph); + } + }); + new Set(way.nodes).forEach(function (nodeID) { + graph = graph.replace(way.removeNode(nodeID)); + var node = graph.entity(nodeID); - if (graph.parentWays(node).length > 1 || graph.parentRelations(node).length || node.hasInterestingTags()) { - continue; - } // Found an uninteresting child node on the target way. - // Move orig point into its place to preserve point's history. #3683 + if (canDeleteNode(node, graph)) { + graph = graph.remove(node); + } + }); + return graph.remove(way); + }; + return action; + } - graph = graph.replace(point.update({ - tags: {}, - loc: node.loc - })); - target = target.replaceNode(node.id, point.id); - graph = graph.replace(target); - removeNode = node; - break; - } + function actionDeleteMultiple(ids) { + var actions = { + way: actionDeleteWay, + node: actionDeleteNode, + relation: actionDeleteRelation + }; - graph = graph.remove(removeNode); + var action = function action(graph) { + ids.forEach(function (id) { + if (graph.hasEntity(id)) { + // It may have been deleted already. + graph = actions[graph.entity(id).type](id)(graph); + } }); + return graph; + }; - if (target.tags.area === 'yes') { - var tags = Object.assign({}, target.tags); // shallow copy + return action; + } - delete tags.area; + function actionDeleteRelation(relationID, allowUntaggedMembers) { + function canDeleteEntity(entity, graph) { + return !graph.parentWays(entity).length && !graph.parentRelations(entity).length && !entity.hasInterestingTags() && !allowUntaggedMembers; + } - if (osmTagSuggestingArea(tags)) { - // remove the `area` tag if area geometry is now implied - #3851 - target = target.update({ - tags: tags - }); - graph = graph.replace(target); + var action = function action(graph) { + var relation = graph.entity(relationID); + graph.parentRelations(relation).forEach(function (parent) { + parent = parent.removeMembersWithID(relationID); + graph = graph.replace(parent); + + if (parent.isDegenerate()) { + graph = actionDeleteRelation(parent.id)(graph); } - } + }); + var memberIDs = utilArrayUniq(relation.members.map(function (m) { + return m.id; + })); + memberIDs.forEach(function (memberID) { + graph = graph.replace(relation.removeMembersWithID(memberID)); + var entity = graph.entity(memberID); - return graph; + if (canDeleteEntity(entity, graph)) { + graph = actionDeleteMultiple([memberID])(graph); + } + }); + return graph.remove(relation); }; - action.disabled = function (graph) { - var geometries = groupEntitiesByGeometry(graph); + return action; + } - if (geometries.point.length === 0 || geometries.area.length + geometries.line.length !== 1 || geometries.relation.length !== 0) { - return 'not_eligible'; - } + function actionDeleteNode(nodeId) { + var action = function action(graph) { + var node = graph.entity(nodeId); + graph.parentWays(node).forEach(function (parent) { + parent = parent.removeNode(nodeId); + graph = graph.replace(parent); + + if (parent.isDegenerate()) { + graph = actionDeleteWay(parent.id)(graph); + } + }); + graph.parentRelations(node).forEach(function (parent) { + parent = parent.removeMembersWithID(nodeId); + graph = graph.replace(parent); + + if (parent.isDegenerate()) { + graph = actionDeleteRelation(parent.id)(graph); + } + }); + return graph.remove(node); }; return action; } // - // 1. move all the nodes to a common location - // 2. `actionConnect` them + // First choose a node to be the survivor, with preference given + // to the oldest existing (not new) and "interesting" node. + // + // Tags and relation memberships of of non-surviving nodes are merged + // to the survivor. + // + // This is the inverse of `iD.actionDisconnect`. + // + // Reference: + // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/MergeNodesAction.as + // https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/actions/MergeNodesAction.java + // - function actionMergeNodes(nodeIDs, loc) { - // If there is a single "interesting" node, use that as the location. - // Otherwise return the average location of all the nodes. - function chooseLoc(graph) { - if (!nodeIDs.length) return null; - var sum = [0, 0]; - var interestingCount = 0; - var interestingLoc; + function actionConnect(nodeIDs) { + var action = function action(graph) { + var survivor; + var node; + var parents; + var i, j; // Select the node with the ID passed as parameter if it is in the list, + // otherwise select the node with the oldest ID as the survivor, or the + // last one if there are only new nodes. - for (var i = 0; i < nodeIDs.length; i++) { - var node = graph.entity(nodeIDs[i]); + nodeIDs.reverse(); + var interestingIDs = []; + + for (i = 0; i < nodeIDs.length; i++) { + node = graph.entity(nodeIDs[i]); if (node.hasInterestingTags()) { - interestingLoc = ++interestingCount === 1 ? node.loc : null; + if (!node.isNew()) { + interestingIDs.push(node.id); + } } - - sum = geoVecAdd(sum, node.loc); } - return interestingLoc || geoVecScale(sum, 1 / nodeIDs.length); - } + survivor = graph.entity(utilOldestID(interestingIDs.length > 0 ? interestingIDs : nodeIDs)); // Replace all non-surviving nodes with the survivor and merge tags. - var action = function action(graph) { - if (nodeIDs.length < 2) return graph; - var toLoc = loc; + for (i = 0; i < nodeIDs.length; i++) { + node = graph.entity(nodeIDs[i]); + if (node.id === survivor.id) continue; + parents = graph.parentWays(node); - if (!toLoc) { - toLoc = chooseLoc(graph); + for (j = 0; j < parents.length; j++) { + graph = graph.replace(parents[j].replaceNode(node.id, survivor.id)); + } + + parents = graph.parentRelations(node); + + for (j = 0; j < parents.length; j++) { + graph = graph.replace(parents[j].replaceMember(node, survivor)); + } + + survivor = survivor.mergeTags(node.tags); + graph = actionDeleteNode(node.id)(graph); } - for (var i = 0; i < nodeIDs.length; i++) { - var node = graph.entity(nodeIDs[i]); + graph = graph.replace(survivor); // find and delete any degenerate ways created by connecting adjacent vertices - if (node.loc !== toLoc) { - graph = graph.replace(node.move(toLoc)); + parents = graph.parentWays(survivor); + + for (i = 0; i < parents.length; i++) { + if (parents[i].isDegenerate()) { + graph = actionDeleteWay(parents[i].id)(graph); } } - return actionConnect(nodeIDs)(graph); + return graph; }; action.disabled = function (graph) { - if (nodeIDs.length < 2) return 'not_eligible'; + var seen = {}; + var restrictionIDs = []; + var survivor; + var node, way; + var relations, relation, role; + var i, j, k; // Select the node with the oldest ID as the survivor. - for (var i = 0; i < nodeIDs.length; i++) { - var entity = graph.entity(nodeIDs[i]); - if (entity.type !== 'node') return 'not_eligible'; - } + survivor = graph.entity(utilOldestID(nodeIDs)); // 1. disable if the nodes being connected have conflicting relation roles - return actionConnect(nodeIDs).disabled(graph); - }; + for (i = 0; i < nodeIDs.length; i++) { + node = graph.entity(nodeIDs[i]); + relations = graph.parentRelations(node); - return action; - } + for (j = 0; j < relations.length; j++) { + relation = relations[j]; + role = relation.memberById(node.id).role || ''; // if this node is a via node in a restriction, remember for later - function osmChangeset() { - if (!(this instanceof osmChangeset)) { - return new osmChangeset().initialize(arguments); - } else if (arguments.length) { - this.initialize(arguments); - } - } - osmEntity.changeset = osmChangeset; - osmChangeset.prototype = Object.create(osmEntity.prototype); - Object.assign(osmChangeset.prototype, { - type: 'changeset', - extent: function extent() { - return new geoExtent(); - }, - geometry: function geometry() { - return 'changeset'; - }, - asJXON: function asJXON() { - return { - osm: { - changeset: { - tag: Object.keys(this.tags).map(function (k) { - return { - '@k': k, - '@v': this.tags[k] - }; - }, this), - '@version': 0.6, - '@generator': 'iD' + if (relation.hasFromViaTo()) { + restrictionIDs.push(relation.id); + } + + if (seen[relation.id] !== undefined && seen[relation.id] !== role) { + return 'relation'; + } else { + seen[relation.id] = role; } } - }; - }, - // Generate [osmChange](http://wiki.openstreetmap.org/wiki/OsmChange) - // XML. Returns a string. - osmChangeJXON: function osmChangeJXON(changes) { - var changeset_id = this.id; + } // gather restrictions for parent ways - function nest(x, order) { - var groups = {}; - for (var i = 0; i < x.length; i++) { - var tagName = Object.keys(x[i])[0]; - if (!groups[tagName]) groups[tagName] = []; - groups[tagName].push(x[i][tagName]); + for (i = 0; i < nodeIDs.length; i++) { + node = graph.entity(nodeIDs[i]); + var parents = graph.parentWays(node); + + for (j = 0; j < parents.length; j++) { + var parent = parents[j]; + relations = graph.parentRelations(parent); + + for (k = 0; k < relations.length; k++) { + relation = relations[k]; + + if (relation.hasFromViaTo()) { + restrictionIDs.push(relation.id); + } + } } + } // test restrictions - var ordered = {}; - order.forEach(function (o) { - if (groups[o]) ordered[o] = groups[o]; - }); - return ordered; - } // sort relations in a changeset by dependencies + restrictionIDs = utilArrayUniq(restrictionIDs); - function sort(changes) { - // find a referenced relation in the current changeset - function resolve(item) { - return relations.find(function (relation) { - return item.keyAttributes.type === 'relation' && item.keyAttributes.ref === relation['@id']; - }); - } // a new item is an item that has not been already processed + for (i = 0; i < restrictionIDs.length; i++) { + relation = graph.entity(restrictionIDs[i]); + if (!relation.isComplete(graph)) continue; + var memberWays = relation.members.filter(function (m) { + return m.type === 'way'; + }).map(function (m) { + return graph.entity(m.id); + }); + memberWays = utilArrayUniq(memberWays); + var f = relation.memberByRole('from'); + var t = relation.memberByRole('to'); + var isUturn = f.id === t.id; // 2a. disable if connection would damage a restriction + // (a key node is a node at the junction of ways) + var nodes = { + from: [], + via: [], + to: [], + keyfrom: [], + keyto: [] + }; - function isNew(item) { - return !sorted[item['@id']] && !processing.find(function (proc) { - return proc['@id'] === item['@id']; - }); + for (j = 0; j < relation.members.length; j++) { + collectNodes(relation.members[j], nodes); } - var processing = []; - var sorted = {}; - var relations = changes.relation; - if (!relations) return changes; + nodes.keyfrom = utilArrayUniq(nodes.keyfrom.filter(hasDuplicates)); + nodes.keyto = utilArrayUniq(nodes.keyto.filter(hasDuplicates)); + var filter = keyNodeFilter(nodes.keyfrom, nodes.keyto); + nodes.from = nodes.from.filter(filter); + nodes.via = nodes.via.filter(filter); + nodes.to = nodes.to.filter(filter); + var connectFrom = false; + var connectVia = false; + var connectTo = false; + var connectKeyFrom = false; + var connectKeyTo = false; - for (var i = 0; i < relations.length; i++) { - var relation = relations[i]; // skip relation if already sorted + for (j = 0; j < nodeIDs.length; j++) { + var n = nodeIDs[j]; - if (!sorted[relation['@id']]) { - processing.push(relation); + if (nodes.from.indexOf(n) !== -1) { + connectFrom = true; } - while (processing.length > 0) { - var next = processing[0], - deps = next.member.map(resolve).filter(Boolean).filter(isNew); + if (nodes.via.indexOf(n) !== -1) { + connectVia = true; + } - if (deps.length === 0) { - sorted[next['@id']] = next; - processing.shift(); - } else { - processing = deps.concat(processing); - } + if (nodes.to.indexOf(n) !== -1) { + connectTo = true; } - } - changes.relation = Object.values(sorted); - return changes; - } + if (nodes.keyfrom.indexOf(n) !== -1) { + connectKeyFrom = true; + } - function rep(entity) { - return entity.asJXON(changeset_id); - } + if (nodes.keyto.indexOf(n) !== -1) { + connectKeyTo = true; + } + } - return { - osmChange: { - '@version': 0.6, - '@generator': 'iD', - 'create': sort(nest(changes.created.map(rep), ['node', 'way', 'relation'])), - 'modify': nest(changes.modified.map(rep), ['node', 'way', 'relation']), - 'delete': Object.assign(nest(changes.deleted.map(rep), ['relation', 'way', 'node']), { - '@if-unused': true - }) + if (connectFrom && connectTo && !isUturn) { + return 'restriction'; } - }; - }, - asGeoJSON: function asGeoJSON() { - return {}; - } - }); - function osmNote() { - if (!(this instanceof osmNote)) { - return new osmNote().initialize(arguments); - } else if (arguments.length) { - this.initialize(arguments); - } - } + if (connectFrom && connectVia) { + return 'restriction'; + } - osmNote.id = function () { - return osmNote.id.next--; - }; + if (connectTo && connectVia) { + return 'restriction'; + } // connecting to a key node - + // if both nodes are on a member way (i.e. part of the turn restriction), + // the connecting node must be adjacent to the key node. - osmNote.id.next = -1; - Object.assign(osmNote.prototype, { - type: 'note', - initialize: function initialize(sources) { - for (var i = 0; i < sources.length; ++i) { - var source = sources[i]; - for (var prop in source) { - if (Object.prototype.hasOwnProperty.call(source, prop)) { - if (source[prop] === undefined) { - delete this[prop]; - } else { - this[prop] = source[prop]; - } + if (connectKeyFrom || connectKeyTo) { + if (nodeIDs.length !== 2) { + return 'restriction'; } - } - } - if (!this.id) { - this.id = osmNote.id().toString(); - } - - return this; - }, - extent: function extent() { - return new geoExtent(this.loc); - }, - update: function update(attrs) { - return osmNote(this, attrs); // {v: 1 + (this.v || 0)} - }, - isNew: function isNew() { - return this.id < 0; - }, - move: function move(loc) { - return this.update({ - loc: loc - }); - } - }); + var n0 = null; + var n1 = null; - function osmRelation() { - if (!(this instanceof osmRelation)) { - return new osmRelation().initialize(arguments); - } else if (arguments.length) { - this.initialize(arguments); - } - } - osmEntity.relation = osmRelation; - osmRelation.prototype = Object.create(osmEntity.prototype); + for (j = 0; j < memberWays.length; j++) { + way = memberWays[j]; - osmRelation.creationOrder = function (a, b) { - var aId = parseInt(osmEntity.id.toOSM(a.id), 10); - var bId = parseInt(osmEntity.id.toOSM(b.id), 10); - if (aId < 0 || bId < 0) return aId - bId; - return bId - aId; - }; + if (way.contains(nodeIDs[0])) { + n0 = nodeIDs[0]; + } - Object.assign(osmRelation.prototype, { - type: 'relation', - members: [], - copy: function copy(resolver, copies) { - if (copies[this.id]) return copies[this.id]; - var copy = osmEntity.prototype.copy.call(this, resolver, copies); - var members = this.members.map(function (member) { - return Object.assign({}, member, { - id: resolver.entity(member.id).copy(resolver, copies).id - }); - }); - copy = copy.update({ - members: members - }); - copies[this.id] = copy; - return copy; - }, - extent: function extent(resolver, memo) { - return resolver["transient"](this, 'extent', function () { - if (memo && memo[this.id]) return geoExtent(); - memo = memo || {}; - memo[this.id] = true; - var extent = geoExtent(); + if (way.contains(nodeIDs[1])) { + n1 = nodeIDs[1]; + } + } - for (var i = 0; i < this.members.length; i++) { - var member = resolver.hasEntity(this.members[i].id); + if (n0 && n1) { + // both nodes are part of the restriction + var ok = false; - if (member) { - extent._extend(member.extent(resolver, memo)); - } - } + for (j = 0; j < memberWays.length; j++) { + way = memberWays[j]; - return extent; - }); - }, - geometry: function geometry(graph) { - return graph["transient"](this, 'geometry', function () { - return this.isMultipolygon() ? 'area' : 'relation'; - }); - }, - isDegenerate: function isDegenerate() { - return this.members.length === 0; - }, - // Return an array of members, each extended with an 'index' property whose value - // is the member index. - indexedMembers: function indexedMembers() { - var result = new Array(this.members.length); + if (way.areAdjacent(n0, n1)) { + ok = true; + break; + } + } - for (var i = 0; i < this.members.length; i++) { - result[i] = Object.assign({}, this.members[i], { - index: i - }); - } + if (!ok) { + return 'restriction'; + } + } + } // 2b. disable if nodes being connected will destroy a member way in a restriction + // (to test, make a copy and try actually connecting the nodes) - return result; - }, - // Return the first member with the given role. A copy of the member object - // is returned, extended with an 'index' property whose value is the member index. - memberByRole: function memberByRole(role) { - for (var i = 0; i < this.members.length; i++) { - if (this.members[i].role === role) { - return Object.assign({}, this.members[i], { - index: i - }); - } - } - }, - // Same as memberByRole, but returns all members with the given role - membersByRole: function membersByRole(role) { - var result = []; - for (var i = 0; i < this.members.length; i++) { - if (this.members[i].role === role) { - result.push(Object.assign({}, this.members[i], { - index: i - })); - } - } + for (j = 0; j < memberWays.length; j++) { + way = memberWays[j].update({}); // make copy - return result; - }, - // Return the first member with the given id. A copy of the member object - // is returned, extended with an 'index' property whose value is the member index. - memberById: function memberById(id) { - for (var i = 0; i < this.members.length; i++) { - if (this.members[i].id === id) { - return Object.assign({}, this.members[i], { - index: i - }); - } - } - }, - // Return the first member with the given id and role. A copy of the member object - // is returned, extended with an 'index' property whose value is the member index. - memberByIdAndRole: function memberByIdAndRole(id, role) { - for (var i = 0; i < this.members.length; i++) { - if (this.members[i].id === id && this.members[i].role === role) { - return Object.assign({}, this.members[i], { - index: i - }); - } - } - }, - addMember: function addMember(member, index) { - var members = this.members.slice(); - members.splice(index === undefined ? members.length : index, 0, member); - return this.update({ - members: members - }); - }, - updateMember: function updateMember(member, index) { - var members = this.members.slice(); - members.splice(index, 1, Object.assign({}, members[index], member)); - return this.update({ - members: members - }); - }, - removeMember: function removeMember(index) { - var members = this.members.slice(); - members.splice(index, 1); - return this.update({ - members: members - }); - }, - removeMembersWithID: function removeMembersWithID(id) { - var members = this.members.filter(function (m) { - return m.id !== id; - }); - return this.update({ - members: members - }); - }, - moveMember: function moveMember(fromIndex, toIndex) { - var members = this.members.slice(); - members.splice(toIndex, 0, members.splice(fromIndex, 1)[0]); - return this.update({ - members: members - }); - }, - // Wherever a member appears with id `needle.id`, replace it with a member - // with id `replacement.id`, type `replacement.type`, and the original role, - // By default, adding a duplicate member (by id and role) is prevented. - // Return an updated relation. - replaceMember: function replaceMember(needle, replacement, keepDuplicates) { - if (!this.memberById(needle.id)) return this; - var members = []; + for (k = 0; k < nodeIDs.length; k++) { + if (nodeIDs[k] === survivor.id) continue; - for (var i = 0; i < this.members.length; i++) { - var member = this.members[i]; + if (way.areAdjacent(nodeIDs[k], survivor.id)) { + way = way.removeNode(nodeIDs[k]); + } else { + way = way.replaceNode(nodeIDs[k], survivor.id); + } + } - if (member.id !== needle.id) { - members.push(member); - } else if (keepDuplicates || !this.memberByIdAndRole(replacement.id, member.role)) { - members.push({ - id: replacement.id, - type: replacement.type, - role: member.role - }); + if (way.isDegenerate()) { + return 'restriction'; + } } } - return this.update({ - members: members - }); - }, - asJXON: function asJXON(changeset_id) { - var r = { - relation: { - '@id': this.osmId(), - '@version': this.version || 0, - member: this.members.map(function (member) { - return { - keyAttributes: { - type: member.type, - role: member.role, - ref: osmEntity.id.toOSM(member.id) - } - }; - }, this), - tag: Object.keys(this.tags).map(function (k) { - return { - keyAttributes: { - k: k, - v: this.tags[k] - } - }; - }, this) - } - }; + return false; // if a key node appears multiple times (indexOf !== lastIndexOf) it's a FROM-VIA or TO-VIA junction - if (changeset_id) { - r.relation['@changeset'] = changeset_id; + function hasDuplicates(n, i, arr) { + return arr.indexOf(n) !== arr.lastIndexOf(n); } - return r; - }, - asGeoJSON: function asGeoJSON(resolver) { - return resolver["transient"](this, 'GeoJSON', function () { - if (this.isMultipolygon()) { - return { - type: 'MultiPolygon', - coordinates: this.multipolygon(resolver) - }; - } else { - return { - type: 'FeatureCollection', - properties: this.tags, - features: this.members.map(function (member) { - return Object.assign({ - role: member.role - }, resolver.entity(member.id).asGeoJSON(resolver)); - }) - }; - } - }); - }, - area: function area(resolver) { - return resolver["transient"](this, 'area', function () { - return d3_geoArea(this.asGeoJSON(resolver)); - }); - }, - isMultipolygon: function isMultipolygon() { - return this.tags.type === 'multipolygon'; - }, - isComplete: function isComplete(resolver) { - for (var i = 0; i < this.members.length; i++) { - if (!resolver.hasEntity(this.members[i].id)) { - return false; - } + function keyNodeFilter(froms, tos) { + return function (n) { + return froms.indexOf(n) === -1 && tos.indexOf(n) === -1; + }; } - return true; - }, - hasFromViaTo: function hasFromViaTo() { - return this.members.some(function (m) { - return m.role === 'from'; - }) && this.members.some(function (m) { - return m.role === 'via'; - }) && this.members.some(function (m) { - return m.role === 'to'; - }); - }, - isRestriction: function isRestriction() { - return !!(this.tags.type && this.tags.type.match(/^restriction:?/)); - }, - isValidRestriction: function isValidRestriction() { - if (!this.isRestriction()) return false; - var froms = this.members.filter(function (m) { - return m.role === 'from'; - }); - var vias = this.members.filter(function (m) { - return m.role === 'via'; - }); - var tos = this.members.filter(function (m) { - return m.role === 'to'; - }); - if (froms.length !== 1 && this.tags.restriction !== 'no_entry') return false; - if (froms.some(function (m) { - return m.type !== 'way'; - })) return false; - if (tos.length !== 1 && this.tags.restriction !== 'no_exit') return false; - if (tos.some(function (m) { - return m.type !== 'way'; - })) return false; - if (vias.length === 0) return false; - if (vias.length > 1 && vias.some(function (m) { - return m.type !== 'way'; - })) return false; - return true; - }, - isConnectivity: function isConnectivity() { - return !!(this.tags.type && this.tags.type.match(/^connectivity:?/)); - }, - // Returns an array [A0, ... An], each Ai being an array of node arrays [Nds0, ... Ndsm], - // where Nds0 is an outer ring and subsequent Ndsi's (if any i > 0) being inner rings. - // - // This corresponds to the structure needed for rendering a multipolygon path using a - // `evenodd` fill rule, as well as the structure of a GeoJSON MultiPolygon geometry. - // - // In the case of invalid geometries, this function will still return a result which - // includes the nodes of all way members, but some Nds may be unclosed and some inner - // rings not matched with the intended outer ring. - // - multipolygon: function multipolygon(resolver) { - var outers = this.members.filter(function (m) { - return 'outer' === (m.role || 'outer'); - }); - var inners = this.members.filter(function (m) { - return 'inner' === m.role; - }); - outers = osmJoinWays(outers, resolver); - inners = osmJoinWays(inners, resolver); + function collectNodes(member, collection) { + var entity = graph.hasEntity(member.id); + if (!entity) return; + var role = member.role || ''; - var sequenceToLineString = function sequenceToLineString(sequence) { - if (sequence.nodes.length > 2 && sequence.nodes[0] !== sequence.nodes[sequence.nodes.length - 1]) { - // close unclosed parts to ensure correct area rendering - #2945 - sequence.nodes.push(sequence.nodes[0]); + if (!collection[role]) { + collection[role] = []; } - return sequence.nodes.map(function (node) { - return node.loc; - }); - }; - - outers = outers.map(sequenceToLineString); - inners = inners.map(sequenceToLineString); - var result = outers.map(function (o) { - // Heuristic for detecting counterclockwise winding order. Assumes - // that OpenStreetMap polygons are not hemisphere-spanning. - return [d3_geoArea({ - type: 'Polygon', - coordinates: [o] - }) > 2 * Math.PI ? o.reverse() : o]; - }); - - function findOuter(inner) { - var o, outer; - - for (o = 0; o < outers.length; o++) { - outer = outers[o]; + if (member.type === 'node') { + collection[role].push(member.id); - if (geoPolygonContainsPolygon(outer, inner)) { - return o; + if (role === 'via') { + collection.keyfrom.push(member.id); + collection.keyto.push(member.id); } - } + } else if (member.type === 'way') { + collection[role].push.apply(collection[role], entity.nodes); - for (o = 0; o < outers.length; o++) { - outer = outers[o]; + if (role === 'from' || role === 'via') { + collection.keyfrom.push(entity.first()); + collection.keyfrom.push(entity.last()); + } - if (geoPolygonIntersectsPolygon(outer, inner, false)) { - return o; + if (role === 'to' || role === 'via') { + collection.keyto.push(entity.first()); + collection.keyto.push(entity.last()); } } } + }; - for (var i = 0; i < inners.length; i++) { - var inner = inners[i]; + return action; + } - if (d3_geoArea({ - type: 'Polygon', - coordinates: [inner] - }) < 2 * Math.PI) { - inner = inner.reverse(); - } + function actionCopyEntities(ids, fromGraph) { + var _copies = {}; - var o = findOuter(inners[i]); + var action = function action(graph) { + ids.forEach(function (id) { + fromGraph.entity(id).copy(fromGraph, _copies); + }); - if (o !== undefined) { - result[o].push(inners[i]); - } else { - result.push([inners[i]]); // Invalid geometry - } + for (var id in _copies) { + graph = graph.replace(_copies[id]); } - return result; - } - }); + return graph; + }; - var QAItem = /*#__PURE__*/function () { - function QAItem(loc, service, itemType, id, props) { - _classCallCheck$1(this, QAItem); + action.copies = function () { + return _copies; + }; - // Store required properties - this.loc = loc; - this.service = service.title; - this.itemType = itemType; // All issues must have an ID for selection, use generic if none specified + return action; + } - this.id = id ? id : "".concat(QAItem.id()); - this.update(props); // Some QA services have marker icons to differentiate issues + function actionDeleteMember(relationId, memberIndex) { + return function (graph) { + var relation = graph.entity(relationId).removeMember(memberIndex); + graph = graph.replace(relation); - if (service && typeof service.getIcon === 'function') { - this.icon = service.getIcon(itemType); + if (relation.isDegenerate()) { + graph = actionDeleteRelation(relation.id)(graph); } - } - _createClass$1(QAItem, [{ - key: "update", - value: function update(props) { - var _this = this; + return graph; + }; + } - // You can't override this initial information - var loc = this.loc, - service = this.service, - itemType = this.itemType, - id = this.id; - Object.keys(props).forEach(function (prop) { - return _this[prop] = props[prop]; - }); - this.loc = loc; - this.service = service; - this.itemType = itemType; - this.id = id; - return this; - } // Generic handling for newly created QAItems + function actionDiscardTags(difference, discardTags) { + discardTags = discardTags || {}; + return function (graph) { + difference.modified().forEach(checkTags); + difference.created().forEach(checkTags); + return graph; - }], [{ - key: "id", - value: function id() { - return this.nextId--; - } - }]); + function checkTags(entity) { + var keys = Object.keys(entity.tags); + var didDiscard = false; + var tags = {}; - return QAItem; - }(); - QAItem.nextId = -1; + for (var i = 0; i < keys.length; i++) { + var k = keys[i]; + + if (discardTags[k] || !entity.tags[k]) { + didDiscard = true; + } else { + tags[k] = entity.tags[k]; + } + } + + if (didDiscard) { + graph = graph.replace(entity.update({ + tags: tags + })); + } + } + }; + } // - // Optionally, split only the given ways, if multiple ways share - // the given node. - // - // This is the inverse of `iD.actionJoin`. + // Optionally, disconnect only the given ways. // - // For testing convenience, accepts an ID to assign to the new way. + // For testing convenience, accepts an ID to assign to the (first) new node. // Normally, this will be undefined and the way will automatically // be assigned a new ID. // + // This is the inverse of `iD.actionConnect`. + // // Reference: - // https://github.com/systemed/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/SplitWayAction.as + // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/UnjoinNodeAction.as + // https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/actions/UnGlueAction.java // - function actionSplit(nodeIds, newWayIds) { - // accept single ID for backwards-compatiblity - if (typeof nodeIds === 'string') nodeIds = [nodeIds]; - - var _wayIDs; // the strategy for picking which way will have a new version and which way is newly created - - - var _keepHistoryOn = 'longest'; // 'longest', 'first' - // The IDs of the ways actually created by running this action - - var _createdWayIDs = []; - - function dist(graph, nA, nB) { - var locA = graph.entity(nA).loc; - var locB = graph.entity(nB).loc; - var epsilon = 1e-6; - return locA && locB ? geoSphericalDistance(locA, locB) : epsilon; - } // If the way is closed, we need to search for a partner node - // to split the way at. - // - // The following looks for a node that is both far away from - // the initial node in terms of way segment length and nearby - // in terms of beeline-distance. This assures that areas get - // split on the most "natural" points (independent of the number - // of nodes). - // For example: bone-shaped areas get split across their waist - // line, circles across the diameter. - - - function splitArea(nodes, idxA, graph) { - var lengths = new Array(nodes.length); - var length; - var i; - var best = 0; - var idxB; - - function wrap(index) { - return utilWrap(index, nodes.length); - } // calculate lengths - - - length = 0; - - for (i = wrap(idxA + 1); i !== idxA; i = wrap(i + 1)) { - length += dist(graph, nodes[i], nodes[wrap(i - 1)]); - lengths[i] = length; - } - - length = 0; + function actionDisconnect(nodeId, newNodeId) { + var wayIds; + var disconnectableRelationTypes = { + 'associatedStreet': true, + 'enforcement': true, + 'site': true + }; - for (i = wrap(idxA - 1); i !== idxA; i = wrap(i - 1)) { - length += dist(graph, nodes[i], nodes[wrap(i + 1)]); + var action = function action(graph) { + var node = graph.entity(nodeId); + var connections = action.connections(graph); + connections.forEach(function (connection) { + var way = graph.entity(connection.wayID); + var newNode = osmNode({ + id: newNodeId, + loc: node.loc, + tags: node.tags + }); + graph = graph.replace(newNode); - if (length < lengths[i]) { - lengths[i] = length; + if (connection.index === 0 && way.isArea()) { + // replace shared node with shared node.. + graph = graph.replace(way.replaceNode(way.nodes[0], newNode.id)); + } else if (way.isClosed() && connection.index === way.nodes.length - 1) { + // replace closing node with new new node.. + graph = graph.replace(way.unclose().addNode(newNode.id)); + } else { + // replace shared node with multiple new nodes.. + graph = graph.replace(way.updateNode(newNode.id, connection.index)); } - } // determine best opposite node to split + }); + return graph; + }; + action.connections = function (graph) { + var candidates = []; + var keeping = false; + var parentWays = graph.parentWays(graph.entity(nodeId)); + var way, waynode; - for (i = 0; i < nodes.length; i++) { - var cost = lengths[i] / dist(graph, nodes[idxA], nodes[i]); + for (var i = 0; i < parentWays.length; i++) { + way = parentWays[i]; - if (cost > best) { - idxB = i; - best = cost; + if (wayIds && wayIds.indexOf(way.id) === -1) { + keeping = true; + continue; } - } - - return idxB; - } - - function totalLengthBetweenNodes(graph, nodes) { - var totalLength = 0; - - for (var i = 0; i < nodes.length - 1; i++) { - totalLength += dist(graph, nodes[i], nodes[i + 1]); - } - - return totalLength; - } - - function split(graph, nodeId, wayA, newWayId) { - var wayB = osmWay({ - id: newWayId, - tags: wayA.tags - }); // `wayB` is the NEW way - - var origNodes = wayA.nodes.slice(); - var nodesA; - var nodesB; - var isArea = wayA.isArea(); - var isOuter = osmIsOldMultipolygonOuterMember(wayA, graph); - - if (wayA.isClosed()) { - var nodes = wayA.nodes.slice(0, -1); - var idxA = nodes.indexOf(nodeId); - var idxB = splitArea(nodes, idxA, graph); - if (idxB < idxA) { - nodesA = nodes.slice(idxA).concat(nodes.slice(0, idxB + 1)); - nodesB = nodes.slice(idxB, idxA + 1); + if (way.isArea() && way.nodes[0] === nodeId) { + candidates.push({ + wayID: way.id, + index: 0 + }); } else { - nodesA = nodes.slice(idxA, idxB + 1); - nodesB = nodes.slice(idxB).concat(nodes.slice(0, idxA + 1)); - } - } else { - var idx = wayA.nodes.indexOf(nodeId, 1); - nodesA = wayA.nodes.slice(0, idx + 1); - nodesB = wayA.nodes.slice(idx); - } - - var lengthA = totalLengthBetweenNodes(graph, nodesA); - var lengthB = totalLengthBetweenNodes(graph, nodesB); - - if (_keepHistoryOn === 'longest' && lengthB > lengthA) { - // keep the history on the longer way, regardless of the node count - wayA = wayA.update({ - nodes: nodesB - }); - wayB = wayB.update({ - nodes: nodesA - }); - var temp = lengthA; - lengthA = lengthB; - lengthB = temp; - } else { - wayA = wayA.update({ - nodes: nodesA - }); - wayB = wayB.update({ - nodes: nodesB - }); - } + for (var j = 0; j < way.nodes.length; j++) { + waynode = way.nodes[j]; - if (wayA.tags.step_count) { - // divide up the the step count proportionally between the two ways - var stepCount = parseFloat(wayA.tags.step_count); + if (waynode === nodeId) { + if (way.isClosed() && parentWays.length > 1 && wayIds && wayIds.indexOf(way.id) !== -1 && j === way.nodes.length - 1) { + continue; + } - if (stepCount && // ensure a number - isFinite(stepCount) && // ensure positive - stepCount > 0 && // ensure integer - Math.round(stepCount) === stepCount) { - var tagsA = Object.assign({}, wayA.tags); - var tagsB = Object.assign({}, wayB.tags); - var ratioA = lengthA / (lengthA + lengthB); - var countA = Math.round(stepCount * ratioA); - tagsA.step_count = countA.toString(); - tagsB.step_count = (stepCount - countA).toString(); - wayA = wayA.update({ - tags: tagsA - }); - wayB = wayB.update({ - tags: tagsB - }); + candidates.push({ + wayID: way.id, + index: j + }); + } + } } } - graph = graph.replace(wayA); - graph = graph.replace(wayB); - graph.parentRelations(wayA).forEach(function (relation) { - var member; // Turn restrictions - make sure: - // 1. Splitting a FROM/TO way - only `wayA` OR `wayB` remains in relation - // (whichever one is connected to the VIA node/ways) - // 2. Splitting a VIA way - `wayB` remains in relation as a VIA way - - if (relation.hasFromViaTo()) { - var f = relation.memberByRole('from'); - var v = relation.membersByRole('via'); - var t = relation.memberByRole('to'); - var i; // 1. split a FROM/TO - - if (f.id === wayA.id || t.id === wayA.id) { - var keepB = false; - - if (v.length === 1 && v[0].type === 'node') { - // check via node - keepB = wayB.contains(v[0].id); - } else { - // check via way(s) - for (i = 0; i < v.length; i++) { - if (v[i].type === 'way') { - var wayVia = graph.hasEntity(v[i].id); + return keeping ? candidates : candidates.slice(1); + }; - if (wayVia && utilArrayIntersection(wayB.nodes, wayVia.nodes).length) { - keepB = true; - break; - } - } + action.disabled = function (graph) { + var connections = action.connections(graph); + if (connections.length === 0) return 'not_connected'; + var parentWays = graph.parentWays(graph.entity(nodeId)); + var seenRelationIds = {}; + var sharedRelation; + parentWays.forEach(function (way) { + var relations = graph.parentRelations(way); + relations.filter(function (relation) { + return !disconnectableRelationTypes[relation.tags.type]; + }).forEach(function (relation) { + if (relation.id in seenRelationIds) { + if (wayIds) { + if (wayIds.indexOf(way.id) !== -1 || wayIds.indexOf(seenRelationIds[relation.id]) !== -1) { + sharedRelation = relation; } + } else { + sharedRelation = relation; } - - if (keepB) { - relation = relation.replaceMember(wayA, wayB); - graph = graph.replace(relation); - } // 2. split a VIA - } else { - for (i = 0; i < v.length; i++) { - if (v[i].type === 'way' && v[i].id === wayA.id) { - member = { - id: wayB.id, - type: 'way', - role: 'via' - }; - graph = actionAddMember(relation.id, member, v[i].index + 1)(graph); - break; - } - } - } // All other relations (Routes, Multipolygons, etc): - // 1. Both `wayA` and `wayB` remain in the relation - // 2. But must be inserted as a pair (see `actionAddMember` for details) - - } else { - if (relation === isOuter) { - graph = graph.replace(relation.mergeTags(wayA.tags)); - graph = graph.replace(wayA.update({ - tags: {} - })); - graph = graph.replace(wayB.update({ - tags: {} - })); + seenRelationIds[relation.id] = way.id; } - - member = { - id: wayB.id, - type: 'way', - role: relation.memberById(wayA.id).role - }; - var insertPair = { - originalID: wayA.id, - insertedID: wayB.id, - nodes: origNodes - }; - graph = actionAddMember(relation.id, member, undefined, insertPair)(graph); - } + }); }); + if (sharedRelation) return 'relation'; + }; - if (!isOuter && isArea) { - var multipolygon = osmRelation({ - tags: Object.assign({}, wayA.tags, { - type: 'multipolygon' - }), - members: [{ - id: wayA.id, - role: 'outer', - type: 'way' - }, { - id: wayB.id, - role: 'outer', - type: 'way' - }] - }); - graph = graph.replace(multipolygon); - graph = graph.replace(wayA.update({ - tags: {} - })); - graph = graph.replace(wayB.update({ - tags: {} - })); - } + action.limitWays = function (val) { + if (!arguments.length) return wayIds; + wayIds = val; + return action; + }; - _createdWayIDs.push(wayB.id); + return action; + } - return graph; - } + function actionExtract(entityID, projection) { + var extractedNodeID; var action = function action(graph) { - _createdWayIDs = []; - var newWayIndex = 0; - - for (var i = 0; i < nodeIds.length; i++) { - var nodeId = nodeIds[i]; - var candidates = action.waysForNode(nodeId, graph); + var entity = graph.entity(entityID); - for (var j = 0; j < candidates.length; j++) { - graph = split(graph, nodeId, candidates[j], newWayIds && newWayIds[newWayIndex]); - newWayIndex += 1; - } + if (entity.type === 'node') { + return extractFromNode(entity, graph); } - return graph; + return extractFromWayOrRelation(entity, graph); }; - action.getCreatedWayIDs = function () { - return _createdWayIDs; - }; + function extractFromNode(node, graph) { + extractedNodeID = node.id; // Create a new node to replace the one we will detach - action.waysForNode = function (nodeId, graph) { - var node = graph.entity(nodeId); - var splittableParents = graph.parentWays(node).filter(isSplittable); + var replacement = osmNode({ + loc: node.loc + }); + graph = graph.replace(replacement); // Process each way in turn, updating the graph as we go - if (!_wayIDs) { - // If the ways to split aren't specified, only split the lines. - // If there are no lines to split, split the areas. - var hasLine = splittableParents.some(function (parent) { - return parent.geometry(graph) === 'line'; - }); + graph = graph.parentWays(node).reduce(function (accGraph, parentWay) { + return accGraph.replace(parentWay.replaceNode(entityID, replacement.id)); + }, graph); // Process any relations too - if (hasLine) { - return splittableParents.filter(function (parent) { - return parent.geometry(graph) === 'line'; - }); - } + return graph.parentRelations(node).reduce(function (accGraph, parentRel) { + return accGraph.replace(parentRel.replaceMember(node, replacement)); + }, graph); + } + + function extractFromWayOrRelation(entity, graph) { + var fromGeometry = entity.geometry(graph); + var keysToCopyAndRetain = ['source', 'wheelchair']; + var keysToRetain = ['area']; + var buildingKeysToRetain = ['architect', 'building', 'height', 'layer']; + var extractedLoc = d3_geoPath(projection).centroid(entity.asGeoJSON(graph)); + extractedLoc = extractedLoc && projection.invert(extractedLoc); + + if (!extractedLoc || !isFinite(extractedLoc[0]) || !isFinite(extractedLoc[1])) { + extractedLoc = entity.extent(graph).center(); } - return splittableParents; + var indoorAreaValues = { + area: true, + corridor: true, + elevator: true, + level: true, + room: true + }; + var isBuilding = entity.tags.building && entity.tags.building !== 'no' || entity.tags['building:part'] && entity.tags['building:part'] !== 'no'; + var isIndoorArea = fromGeometry === 'area' && entity.tags.indoor && indoorAreaValues[entity.tags.indoor]; + var entityTags = Object.assign({}, entity.tags); // shallow copy - function isSplittable(parent) { - // If the ways to split are specified, ignore everything else. - if (_wayIDs && _wayIDs.indexOf(parent.id) === -1) return false; // We can fake splitting closed ways at their endpoints... + var pointTags = {}; - if (parent.isClosed()) return true; // otherwise, we can't split nodes at their endpoints. + for (var key in entityTags) { + if (entity.type === 'relation' && key === 'type') { + continue; + } - for (var i = 1; i < parent.nodes.length - 1; i++) { - if (parent.nodes[i] === nodeId) return true; + if (keysToRetain.indexOf(key) !== -1) { + continue; } - return false; - } - }; + if (isBuilding) { + // don't transfer building-related tags + if (buildingKeysToRetain.indexOf(key) !== -1 || key.match(/^building:.{1,}/) || key.match(/^roof:.{1,}/)) continue; + } // leave `indoor` tag on the area - action.ways = function (graph) { - return utilArrayUniq([].concat.apply([], nodeIds.map(function (nodeId) { - return action.waysForNode(nodeId, graph); - }))); - }; - action.disabled = function (graph) { - for (var i = 0; i < nodeIds.length; i++) { - var nodeId = nodeIds[i]; - var candidates = action.waysForNode(nodeId, graph); + if (isIndoorArea && key === 'indoor') { + continue; + } // copy the tag from the entity to the point - if (candidates.length === 0 || _wayIDs && _wayIDs.length !== candidates.length) { - return 'not_eligible'; - } + + pointTags[key] = entityTags[key]; // leave addresses and some other tags so they're on both features + + if (keysToCopyAndRetain.indexOf(key) !== -1 || key.match(/^addr:.{1,}/)) { + continue; + } else if (isIndoorArea && key === 'level') { + // leave `level` on both features + continue; + } // remove the tag from the entity + + + delete entityTags[key]; } - }; - action.limitWays = function (val) { - if (!arguments.length) return _wayIDs; - _wayIDs = val; - return action; - }; + if (!isBuilding && !isIndoorArea && fromGeometry === 'area') { + // ensure that areas keep area geometry + entityTags.area = 'yes'; + } - action.keepHistoryOn = function (val) { - if (!arguments.length) return _keepHistoryOn; - _keepHistoryOn = val; - return action; + var replacement = osmNode({ + loc: extractedLoc, + tags: pointTags + }); + graph = graph.replace(replacement); + extractedNodeID = replacement.id; + return graph.replace(entity.update({ + tags: entityTags + })); + } + + action.getExtractedNodeID = function () { + return extractedNodeID; }; return action; } - function coreGraph(other, mutable) { - if (!(this instanceof coreGraph)) return new coreGraph(other, mutable); + // + // This is the inverse of `iD.actionSplit`. + // + // Reference: + // https://github.com/systemed/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/MergeWaysAction.as + // https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/actions/CombineWayAction.java + // - if (other instanceof coreGraph) { - var base = other.base(); - this.entities = Object.assign(Object.create(base.entities), other.entities); - this._parentWays = Object.assign(Object.create(base.parentWays), other._parentWays); - this._parentRels = Object.assign(Object.create(base.parentRels), other._parentRels); - } else { - this.entities = Object.create({}); - this._parentWays = Object.create({}); - this._parentRels = Object.create({}); - this.rebase(other || [], [this]); + function actionJoin(ids) { + function groupEntitiesByGeometry(graph) { + var entities = ids.map(function (id) { + return graph.entity(id); + }); + return Object.assign({ + line: [] + }, utilArrayGroupBy(entities, function (entity) { + return entity.geometry(graph); + })); } - this.transients = {}; - this._childNodes = {}; - this.frozen = !mutable; - } - coreGraph.prototype = { - hasEntity: function hasEntity(id) { - return this.entities[id]; - }, - entity: function entity(id) { - var entity = this.entities[id]; //https://github.com/openstreetmap/iD/issues/3973#issuecomment-307052376 + var action = function action(graph) { + var ways = ids.map(graph.entity, graph); // Prefer to keep an existing way. + // if there are multiple existing ways, keep the oldest one + // the oldest way is determined by the ID of the way. - if (!entity) { - entity = this.entities.__proto__[id]; // eslint-disable-line no-proto - } + var survivorID = utilOldestID(ways.map(function (way) { + return way.id; + })); // if any of the ways are sided (e.g. coastline, cliff, kerb) + // sort them first so they establish the overall order - #6033 - if (!entity) { - throw new Error('entity ' + id + ' not found'); - } + ways.sort(function (a, b) { + var aSided = a.isSided(); + var bSided = b.isSided(); + return aSided && !bSided ? -1 : bSided && !aSided ? 1 : 0; + }); + var sequences = osmJoinWays(ways, graph); + var joined = sequences[0]; // We might need to reverse some of these ways before joining them. #4688 + // `joined.actions` property will contain any actions we need to apply. - return entity; - }, - geometry: function geometry(id) { - return this.entity(id).geometry(this); - }, - "transient": function transient(entity, key, fn) { - var id = entity.id; - var transients = this.transients[id] || (this.transients[id] = {}); + graph = sequences.actions.reduce(function (g, action) { + return action(g); + }, graph); + var survivor = graph.entity(survivorID); + survivor = survivor.update({ + nodes: joined.nodes.map(function (n) { + return n.id; + }) + }); + graph = graph.replace(survivor); + joined.forEach(function (way) { + if (way.id === survivorID) return; + graph.parentRelations(way).forEach(function (parent) { + graph = graph.replace(parent.replaceMember(way, survivor)); + }); + survivor = survivor.mergeTags(way.tags); + graph = graph.replace(survivor); + graph = actionDeleteWay(way.id)(graph); + }); // Finds if the join created a single-member multipolygon, + // and if so turns it into a basic area instead - if (transients[key] !== undefined) { - return transients[key]; - } + function checkForSimpleMultipolygon() { + if (!survivor.isClosed()) return; + var multipolygons = graph.parentMultipolygons(survivor).filter(function (multipolygon) { + // find multipolygons where the survivor is the only member + return multipolygon.members.length === 1; + }); // skip if this is the single member of multiple multipolygons - transients[key] = fn.call(entity); - return transients[key]; - }, - parentWays: function parentWays(entity) { - var parents = this._parentWays[entity.id]; - var result = []; + if (multipolygons.length !== 1) return; + var multipolygon = multipolygons[0]; - if (parents) { - parents.forEach(function (id) { - result.push(this.entity(id)); - }, this); - } + for (var key in survivor.tags) { + if (multipolygon.tags[key] && // don't collapse if tags cannot be cleanly merged + multipolygon.tags[key] !== survivor.tags[key]) return; + } - return result; - }, - isPoi: function isPoi(entity) { - var parents = this._parentWays[entity.id]; - return !parents || parents.size === 0; - }, - isShared: function isShared(entity) { - var parents = this._parentWays[entity.id]; - return parents && parents.size > 1; - }, - parentRelations: function parentRelations(entity) { - var parents = this._parentRels[entity.id]; - var result = []; + survivor = survivor.mergeTags(multipolygon.tags); + graph = graph.replace(survivor); + graph = actionDeleteRelation(multipolygon.id, true + /* allow untagged members */ + )(graph); + var tags = Object.assign({}, survivor.tags); - if (parents) { - parents.forEach(function (id) { - result.push(this.entity(id)); - }, this); - } + if (survivor.geometry(graph) !== 'area') { + // ensure the feature persists as an area + tags.area = 'yes'; + } - return result; - }, - parentMultipolygons: function parentMultipolygons(entity) { - return this.parentRelations(entity).filter(function (relation) { - return relation.isMultipolygon(); - }); - }, - childNodes: function childNodes(entity) { - if (this._childNodes[entity.id]) return this._childNodes[entity.id]; - if (!entity.nodes) return []; - var nodes = []; + delete tags.type; // remove type=multipolygon - for (var i = 0; i < entity.nodes.length; i++) { - nodes[i] = this.entity(entity.nodes[i]); + survivor = survivor.update({ + tags: tags + }); + graph = graph.replace(survivor); } - this._childNodes[entity.id] = nodes; - return this._childNodes[entity.id]; - }, - base: function base() { - return { - 'entities': Object.getPrototypeOf(this.entities), - 'parentWays': Object.getPrototypeOf(this._parentWays), - 'parentRels': Object.getPrototypeOf(this._parentRels) - }; - }, - // Unlike other graph methods, rebase mutates in place. This is because it - // is used only during the history operation that merges newly downloaded - // data into each state. To external consumers, it should appear as if the - // graph always contained the newly downloaded data. - rebase: function rebase(entities, stack, force) { - var base = this.base(); - var i, j, k, id; - for (i = 0; i < entities.length; i++) { - var entity = entities[i]; - if (!entity.visible || !force && base.entities[entity.id]) continue; // Merging data into the base graph + checkForSimpleMultipolygon(); + return graph; + }; // Returns the number of nodes the resultant way is expected to have - base.entities[entity.id] = entity; - this._updateCalculated(undefined, entity, base.parentWays, base.parentRels); // Restore provisionally-deleted nodes that are discovered to have an extant parent + action.resultingWayNodesLength = function (graph) { + return ids.reduce(function (count, id) { + return count + graph.entity(id).nodes.length; + }, 0) - ids.length - 1; + }; + action.disabled = function (graph) { + var geometries = groupEntitiesByGeometry(graph); - if (entity.type === 'way') { - for (j = 0; j < entity.nodes.length; j++) { - id = entity.nodes[j]; + if (ids.length < 2 || ids.length !== geometries.line.length) { + return 'not_eligible'; + } - for (k = 1; k < stack.length; k++) { - var ents = stack[k].entities; + var joined = osmJoinWays(ids.map(graph.entity, graph), graph); - if (ents.hasOwnProperty(id) && ents[id] === undefined) { - delete ents[id]; - } - } - } - } + if (joined.length > 1) { + return 'not_adjacent'; } - for (i = 0; i < stack.length; i++) { - stack[i]._updateRebased(); - } - }, - _updateRebased: function _updateRebased() { - var base = this.base(); - Object.keys(this._parentWays).forEach(function (child) { - if (base.parentWays[child]) { - base.parentWays[child].forEach(function (id) { - if (!this.entities.hasOwnProperty(id)) { - this._parentWays[child].add(id); - } - }, this); - } - }, this); - Object.keys(this._parentRels).forEach(function (child) { - if (base.parentRels[child]) { - base.parentRels[child].forEach(function (id) { - if (!this.entities.hasOwnProperty(id)) { - this._parentRels[child].add(id); - } - }, this); - } - }, this); - this.transients = {}; // this._childNodes is not updated, under the assumption that - // ways are always downloaded with their child nodes. - }, - // Updates calculated properties (parentWays, parentRels) for the specified change - _updateCalculated: function _updateCalculated(oldentity, entity, parentWays, parentRels) { - parentWays = parentWays || this._parentWays; - parentRels = parentRels || this._parentRels; - var type = entity && entity.type || oldentity && oldentity.type; - var removed, added, i; + var i; // All joined ways must belong to the same set of (non-restriction) relations. + // Restriction relations have different logic, below, which allows some cases + // this prohibits, and prohibits some cases this allows. - if (type === 'way') { - // Update parentWays - if (oldentity && entity) { - removed = utilArrayDifference(oldentity.nodes, entity.nodes); - added = utilArrayDifference(entity.nodes, oldentity.nodes); - } else if (oldentity) { - removed = oldentity.nodes; - added = []; - } else if (entity) { - removed = []; - added = entity.nodes; - } + var sortedParentRelations = function sortedParentRelations(id) { + return graph.parentRelations(graph.entity(id)).filter(function (rel) { + return !rel.isRestriction() && !rel.isConnectivity(); + }).sort(function (a, b) { + return a.id - b.id; + }); + }; - for (i = 0; i < removed.length; i++) { - // make a copy of prototype property, store as own property, and update.. - parentWays[removed[i]] = new Set(parentWays[removed[i]]); - parentWays[removed[i]]["delete"](oldentity.id); - } + var relsA = sortedParentRelations(ids[0]); - for (i = 0; i < added.length; i++) { - // make a copy of prototype property, store as own property, and update.. - parentWays[added[i]] = new Set(parentWays[added[i]]); - parentWays[added[i]].add(entity.id); - } - } else if (type === 'relation') { - // Update parentRels - // diff only on the IDs since the same entity can be a member multiple times with different roles - var oldentityMemberIDs = oldentity ? oldentity.members.map(function (m) { - return m.id; - }) : []; - var entityMemberIDs = entity ? entity.members.map(function (m) { - return m.id; - }) : []; + for (i = 1; i < ids.length; i++) { + var relsB = sortedParentRelations(ids[i]); - if (oldentity && entity) { - removed = utilArrayDifference(oldentityMemberIDs, entityMemberIDs); - added = utilArrayDifference(entityMemberIDs, oldentityMemberIDs); - } else if (oldentity) { - removed = oldentityMemberIDs; - added = []; - } else if (entity) { - removed = []; - added = entityMemberIDs; + if (!utilArrayIdentical(relsA, relsB)) { + return 'conflicting_relations'; } + } // Loop through all combinations of path-pairs + // to check potential intersections between all pairs - for (i = 0; i < removed.length; i++) { - // make a copy of prototype property, store as own property, and update.. - parentRels[removed[i]] = new Set(parentRels[removed[i]]); - parentRels[removed[i]]["delete"](oldentity.id); - } - for (i = 0; i < added.length; i++) { - // make a copy of prototype property, store as own property, and update.. - parentRels[added[i]] = new Set(parentRels[added[i]]); - parentRels[added[i]].add(entity.id); + for (i = 0; i < ids.length - 1; i++) { + for (var j = i + 1; j < ids.length; j++) { + var path1 = graph.childNodes(graph.entity(ids[i])).map(function (e) { + return e.loc; + }); + var path2 = graph.childNodes(graph.entity(ids[j])).map(function (e) { + return e.loc; + }); + var intersections = geoPathIntersections(path1, path2); // Check if intersections are just nodes lying on top of + // each other/the line, as opposed to crossing it + + var common = utilArrayIntersection(joined[0].nodes.map(function (n) { + return n.loc.toString(); + }), intersections.map(function (n) { + return n.toString(); + })); + + if (common.length !== intersections.length) { + return 'paths_intersect'; + } } } - }, - replace: function replace(entity) { - if (this.entities[entity.id] === entity) return this; - return this.update(function () { - this._updateCalculated(this.entities[entity.id], entity); - this.entities[entity.id] = entity; - }); - }, - remove: function remove(entity) { - return this.update(function () { - this._updateCalculated(entity, undefined); - - this.entities[entity.id] = undefined; - }); - }, - revert: function revert(id) { - var baseEntity = this.base().entities[id]; - var headEntity = this.entities[id]; - if (headEntity === baseEntity) return this; - return this.update(function () { - this._updateCalculated(headEntity, baseEntity); + var nodeIds = joined[0].nodes.map(function (n) { + return n.id; + }).slice(1, -1); + var relation; + var tags = {}; + var conflicting = false; + joined[0].forEach(function (way) { + var parents = graph.parentRelations(way); + parents.forEach(function (parent) { + if ((parent.isRestriction() || parent.isConnectivity()) && parent.members.some(function (m) { + return nodeIds.indexOf(m.id) >= 0; + })) { + relation = parent; + } + }); - delete this.entities[id]; + for (var k in way.tags) { + if (!(k in tags)) { + tags[k] = way.tags[k]; + } else if (tags[k] && osmIsInterestingTag(k) && tags[k] !== way.tags[k]) { + conflicting = true; + } + } }); - }, - update: function update() { - var graph = this.frozen ? coreGraph(this, true) : this; - for (var i = 0; i < arguments.length; i++) { - arguments[i].call(graph, graph); + if (relation) { + return relation.isRestriction() ? 'restriction' : 'connectivity'; } - if (this.frozen) graph.frozen = true; - return graph; - }, - // Obliterates any existing entities - load: function load(entities) { - var base = this.base(); - this.entities = Object.create(base.entities); - - for (var i in entities) { - this.entities[i] = entities[i]; - - this._updateCalculated(base.entities[i], this.entities[i]); + if (conflicting) { + return 'conflicting_tags'; } + }; - return this; - } - }; - - function osmTurn(turn) { - if (!(this instanceof osmTurn)) { - return new osmTurn(turn); - } - - Object.assign(this, turn); + return action; } - function osmIntersection(graph, startVertexId, maxDistance) { - maxDistance = maxDistance || 30; // in meters - - var vgraph = coreGraph(); // virtual graph - var i, j, k; - - function memberOfRestriction(entity) { - return graph.parentRelations(entity).some(function (r) { - return r.isRestriction(); + function actionMerge(ids) { + function groupEntitiesByGeometry(graph) { + var entities = ids.map(function (id) { + return graph.entity(id); }); + return Object.assign({ + point: [], + area: [], + line: [], + relation: [] + }, utilArrayGroupBy(entities, function (entity) { + return entity.geometry(graph); + })); } - function isRoad(way) { - if (way.isArea() || way.isDegenerate()) return false; - var roads = { - 'motorway': true, - 'motorway_link': true, - 'trunk': true, - 'trunk_link': true, - 'primary': true, - 'primary_link': true, - 'secondary': true, - 'secondary_link': true, - 'tertiary': true, - 'tertiary_link': true, - 'residential': true, - 'unclassified': true, - 'living_street': true, - 'service': true, - 'road': true, - 'track': true - }; - return roads[way.tags.highway]; - } + var action = function action(graph) { + var geometries = groupEntitiesByGeometry(graph); + var target = geometries.area[0] || geometries.line[0]; + var points = geometries.point; + points.forEach(function (point) { + target = target.mergeTags(point.tags); + graph = graph.replace(target); + graph.parentRelations(point).forEach(function (parent) { + graph = graph.replace(parent.replaceMember(point, target)); + }); + var nodes = utilArrayUniq(graph.childNodes(target)); + var removeNode = point; - var startNode = graph.entity(startVertexId); - var checkVertices = [startNode]; - var checkWays; - var vertices = []; - var vertexIds = []; - var vertex; - var ways = []; - var wayIds = []; - var way; - var nodes = []; - var node; - var parents = []; - var parent; // `actions` will store whatever actions must be performed to satisfy - // preconditions for adding a turn restriction to this intersection. - // - Remove any existing degenerate turn restrictions (missing from/to, etc) - // - Reverse oneways so that they are drawn in the forward direction - // - Split ways on key vertices + if (!point.isNew()) { + // Try to preserve the original point if it already has + // an ID in the database. + var inserted = false; - var actions = []; // STEP 1: walk the graph outwards from starting vertex to search - // for more key vertices and ways to include in the intersection.. + var canBeReplaced = function canBeReplaced(node) { + return !(graph.parentWays(node).length > 1 || graph.parentRelations(node).length); + }; - while (checkVertices.length) { - vertex = checkVertices.pop(); // check this vertex for parent ways that are roads + var replaceNode = function replaceNode(node) { + graph = graph.replace(point.update({ + tags: node.tags, + loc: node.loc + })); + target = target.replaceNode(node.id, point.id); + graph = graph.replace(target); + removeNode = node; + inserted = true; + }; - checkWays = graph.parentWays(vertex); - var hasWays = false; + var i; + var node; // First, try to replace a new child node on the target way. - for (i = 0; i < checkWays.length; i++) { - way = checkWays[i]; - if (!isRoad(way) && !memberOfRestriction(way)) continue; - ways.push(way); // it's a road, or it's already in a turn restriction + for (i = 0; i < nodes.length; i++) { + node = nodes[i]; - hasWays = true; // check the way's children for more key vertices + if (canBeReplaced(node) && node.isNew()) { + replaceNode(node); + break; + } + } - nodes = utilArrayUniq(graph.childNodes(way)); + if (!inserted && point.hasInterestingTags()) { + // No new child node found, try to find an existing, but + // uninteresting child node instead. + for (i = 0; i < nodes.length; i++) { + node = nodes[i]; - for (j = 0; j < nodes.length; j++) { - node = nodes[j]; - if (node === vertex) continue; // same thing + if (canBeReplaced(node) && !node.hasInterestingTags()) { + replaceNode(node); + break; + } + } - if (vertices.indexOf(node) !== -1) continue; // seen it already + if (!inserted) { + // Still not inserted, try to find an existing, interesting, + // but more recent child node. + for (i = 0; i < nodes.length; i++) { + node = nodes[i]; - if (geoSphericalDistance(node.loc, startNode.loc) > maxDistance) continue; // too far from start - // a key vertex will have parents that are also roads + if (canBeReplaced(node) && utilCompareIDs(point.id, node.id) < 0) { + replaceNode(node); + break; + } + } + } // If the point still hasn't been inserted, we give up. + // There are more interesting or older nodes on the way. - var hasParents = false; - parents = graph.parentWays(node); + } + } - for (k = 0; k < parents.length; k++) { - parent = parents[k]; - if (parent === way) continue; // same thing + graph = graph.remove(removeNode); + }); - if (ways.indexOf(parent) !== -1) continue; // seen it already + if (target.tags.area === 'yes') { + var tags = Object.assign({}, target.tags); // shallow copy - if (!isRoad(parent)) continue; // not a road + delete tags.area; - hasParents = true; - break; - } - - if (hasParents) { - checkVertices.push(node); - } + if (osmTagSuggestingArea(tags)) { + // remove the `area` tag if area geometry is now implied - #3851 + target = target.update({ + tags: tags + }); + graph = graph.replace(target); } } - if (hasWays) { - vertices.push(vertex); + return graph; + }; + + action.disabled = function (graph) { + var geometries = groupEntitiesByGeometry(graph); + + if (geometries.point.length === 0 || geometries.area.length + geometries.line.length !== 1 || geometries.relation.length !== 0) { + return 'not_eligible'; } - } + }; - vertices = utilArrayUniq(vertices); - ways = utilArrayUniq(ways); // STEP 2: Build a virtual graph containing only the entities in the intersection.. - // Everything done after this step should act on the virtual graph - // Any actions that must be performed later to the main graph go in `actions` array + return action; + } - ways.forEach(function (way) { - graph.childNodes(way).forEach(function (node) { - vgraph = vgraph.replace(node); - }); - vgraph = vgraph.replace(way); - graph.parentRelations(way).forEach(function (relation) { - if (relation.isRestriction()) { - if (relation.isValidRestriction(graph)) { - vgraph = vgraph.replace(relation); - } else if (relation.isComplete(graph)) { - actions.push(actionDeleteRelation(relation.id)); - } - } - }); - }); // STEP 3: Force all oneways to be drawn in the forward direction + // + // 1. move all the nodes to a common location + // 2. `actionConnect` them - ways.forEach(function (w) { - var way = vgraph.entity(w.id); + function actionMergeNodes(nodeIDs, loc) { + // If there is a single "interesting" node, use that as the location. + // Otherwise return the average location of all the nodes. + function chooseLoc(graph) { + if (!nodeIDs.length) return null; + var sum = [0, 0]; + var interestingCount = 0; + var interestingLoc; - if (way.tags.oneway === '-1') { - var action = actionReverse(way.id, { - reverseOneway: true - }); - actions.push(action); - vgraph = action(vgraph); - } - }); // STEP 4: Split ways on key vertices + for (var i = 0; i < nodeIDs.length; i++) { + var node = graph.entity(nodeIDs[i]); - var origCount = osmEntity.id.next.way; - vertices.forEach(function (v) { - // This is an odd way to do it, but we need to find all the ways that - // will be split here, then split them one at a time to ensure that these - // actions can be replayed on the main graph exactly in the same order. - // (It is unintuitive, but the order of ways returned from graph.parentWays() - // is arbitrary, depending on how the main graph and vgraph were built) - var splitAll = actionSplit([v.id]).keepHistoryOn('first'); + if (node.hasInterestingTags()) { + interestingLoc = ++interestingCount === 1 ? node.loc : null; + } - if (!splitAll.disabled(vgraph)) { - splitAll.ways(vgraph).forEach(function (way) { - var splitOne = actionSplit([v.id]).limitWays([way.id]).keepHistoryOn('first'); - actions.push(splitOne); - vgraph = splitOne(vgraph); - }); + sum = geoVecAdd(sum, node.loc); } - }); // In here is where we should also split the intersection at nearby junction. - // for https://github.com/mapbox/iD-internal/issues/31 - // nearbyVertices.forEach(function(v) { - // }); - // Reasons why we reset the way id count here: - // 1. Continuity with way ids created by the splits so that we can replay - // these actions later if the user decides to create a turn restriction - // 2. Avoids churning way ids just by hovering over a vertex - // and displaying the turn restriction editor - osmEntity.id.next.way = origCount; // STEP 5: Update arrays to point to vgraph entities + return interestingLoc || geoVecScale(sum, 1 / nodeIDs.length); + } - vertexIds = vertices.map(function (v) { - return v.id; - }); - vertices = []; - ways = []; - vertexIds.forEach(function (id) { - var vertex = vgraph.entity(id); - var parents = vgraph.parentWays(vertex); - vertices.push(vertex); - ways = ways.concat(parents); - }); - vertices = utilArrayUniq(vertices); - ways = utilArrayUniq(ways); - vertexIds = vertices.map(function (v) { - return v.id; - }); - wayIds = ways.map(function (w) { - return w.id; - }); // STEP 6: Update the ways with some metadata that will be useful for - // walking the intersection graph later and rendering turn arrows. + var action = function action(graph) { + if (nodeIDs.length < 2) return graph; + var toLoc = loc; - function withMetadata(way, vertexIds) { - var __oneWay = way.isOneWay(); // which affixes are key vertices? + if (!toLoc) { + toLoc = chooseLoc(graph); + } + for (var i = 0; i < nodeIDs.length; i++) { + var node = graph.entity(nodeIDs[i]); - var __first = vertexIds.indexOf(way.first()) !== -1; + if (node.loc !== toLoc) { + graph = graph.replace(node.move(toLoc)); + } + } - var __last = vertexIds.indexOf(way.last()) !== -1; // what roles is this way eligible for? + return actionConnect(nodeIDs)(graph); + }; + action.disabled = function (graph) { + if (nodeIDs.length < 2) return 'not_eligible'; - var __via = __first && __last; + for (var i = 0; i < nodeIDs.length; i++) { + var entity = graph.entity(nodeIDs[i]); + if (entity.type !== 'node') return 'not_eligible'; + } - var __from = __first && !__oneWay || __last; + return actionConnect(nodeIDs).disabled(graph); + }; - var __to = __first || __last && !__oneWay; + return action; + } - return way.update({ - __first: __first, - __last: __last, - __from: __from, - __via: __via, - __to: __to, - __oneWay: __oneWay - }); + function osmChangeset() { + if (!(this instanceof osmChangeset)) { + return new osmChangeset().initialize(arguments); + } else if (arguments.length) { + this.initialize(arguments); } + } + osmEntity.changeset = osmChangeset; + osmChangeset.prototype = Object.create(osmEntity.prototype); + Object.assign(osmChangeset.prototype, { + type: 'changeset', + extent: function extent() { + return new geoExtent(); + }, + geometry: function geometry() { + return 'changeset'; + }, + asJXON: function asJXON() { + return { + osm: { + changeset: { + tag: Object.keys(this.tags).map(function (k) { + return { + '@k': k, + '@v': this.tags[k] + }; + }, this), + '@version': 0.6, + '@generator': 'iD' + } + } + }; + }, + // Generate [osmChange](http://wiki.openstreetmap.org/wiki/OsmChange) + // XML. Returns a string. + osmChangeJXON: function osmChangeJXON(changes) { + var changeset_id = this.id; - ways = []; - wayIds.forEach(function (id) { - var way = withMetadata(vgraph.entity(id), vertexIds); - vgraph = vgraph.replace(way); - ways.push(way); - }); // STEP 7: Simplify - This is an iterative process where we: - // 1. Find trivial vertices with only 2 parents - // 2. trim off the leaf way from those vertices and remove from vgraph + function nest(x, order) { + var groups = {}; - var keepGoing; - var removeWayIds = []; - var removeVertexIds = []; + for (var i = 0; i < x.length; i++) { + var tagName = Object.keys(x[i])[0]; + if (!groups[tagName]) groups[tagName] = []; + groups[tagName].push(x[i][tagName]); + } - do { - keepGoing = false; - checkVertices = vertexIds.slice(); + var ordered = {}; + order.forEach(function (o) { + if (groups[o]) ordered[o] = groups[o]; + }); + return ordered; + } // sort relations in a changeset by dependencies - for (i = 0; i < checkVertices.length; i++) { - var vertexId = checkVertices[i]; - vertex = vgraph.hasEntity(vertexId); - if (!vertex) { - if (vertexIds.indexOf(vertexId) !== -1) { - vertexIds.splice(vertexIds.indexOf(vertexId), 1); // stop checking this one - } + function sort(changes) { + // find a referenced relation in the current changeset + function resolve(item) { + return relations.find(function (relation) { + return item.keyAttributes.type === 'relation' && item.keyAttributes.ref === relation['@id']; + }); + } // a new item is an item that has not been already processed - removeVertexIds.push(vertexId); - continue; + + function isNew(item) { + return !sorted[item['@id']] && !processing.find(function (proc) { + return proc['@id'] === item['@id']; + }); } - parents = vgraph.parentWays(vertex); + var processing = []; + var sorted = {}; + var relations = changes.relation; + if (!relations) return changes; - if (parents.length < 3) { - if (vertexIds.indexOf(vertexId) !== -1) { - vertexIds.splice(vertexIds.indexOf(vertexId), 1); // stop checking this one + for (var i = 0; i < relations.length; i++) { + var relation = relations[i]; // skip relation if already sorted + + if (!sorted[relation['@id']]) { + processing.push(relation); } - } - if (parents.length === 2) { - // vertex with 2 parents is trivial - var a = parents[0]; - var b = parents[1]; - var aIsLeaf = a && !a.__via; - var bIsLeaf = b && !b.__via; - var leaf, survivor; + while (processing.length > 0) { + var next = processing[0], + deps = next.member.map(resolve).filter(Boolean).filter(isNew); - if (aIsLeaf && !bIsLeaf) { - leaf = a; - survivor = b; - } else if (!aIsLeaf && bIsLeaf) { - leaf = b; - survivor = a; + if (deps.length === 0) { + sorted[next['@id']] = next; + processing.shift(); + } else { + processing = deps.concat(processing); + } } + } - if (leaf && survivor) { - survivor = withMetadata(survivor, vertexIds); // update survivor way + changes.relation = Object.values(sorted); + return changes; + } - vgraph = vgraph.replace(survivor).remove(leaf); // update graph + function rep(entity) { + return entity.asJXON(changeset_id); + } - removeWayIds.push(leaf.id); - keepGoing = true; - } + return { + osmChange: { + '@version': 0.6, + '@generator': 'iD', + 'create': sort(nest(changes.created.map(rep), ['node', 'way', 'relation'])), + 'modify': nest(changes.modified.map(rep), ['node', 'way', 'relation']), + 'delete': Object.assign(nest(changes.deleted.map(rep), ['relation', 'way', 'node']), { + '@if-unused': true + }) } + }; + }, + asGeoJSON: function asGeoJSON() { + return {}; + } + }); - parents = vgraph.parentWays(vertex); + function osmNote() { + if (!(this instanceof osmNote)) { + return new osmNote().initialize(arguments); + } else if (arguments.length) { + this.initialize(arguments); + } + } - if (parents.length < 2) { - // vertex is no longer a key vertex - if (vertexIds.indexOf(vertexId) !== -1) { - vertexIds.splice(vertexIds.indexOf(vertexId), 1); // stop checking this one - } + osmNote.id = function () { + return osmNote.id.next--; + }; - removeVertexIds.push(vertexId); - keepGoing = true; - } + osmNote.id.next = -1; + Object.assign(osmNote.prototype, { + type: 'note', + initialize: function initialize(sources) { + for (var i = 0; i < sources.length; ++i) { + var source = sources[i]; - if (parents.length < 1) { - // vertex is no longer attached to anything - vgraph = vgraph.remove(vertex); + for (var prop in source) { + if (Object.prototype.hasOwnProperty.call(source, prop)) { + if (source[prop] === undefined) { + delete this[prop]; + } else { + this[prop] = source[prop]; + } + } } } - } while (keepGoing); - - vertices = vertices.filter(function (vertex) { - return removeVertexIds.indexOf(vertex.id) === -1; - }).map(function (vertex) { - return vgraph.entity(vertex.id); - }); - ways = ways.filter(function (way) { - return removeWayIds.indexOf(way.id) === -1; - }).map(function (way) { - return vgraph.entity(way.id); - }); // OK! Here is our intersection.. - var intersection = { - graph: vgraph, - actions: actions, - vertices: vertices, - ways: ways - }; // Get all the valid turns through this intersection given a starting way id. - // This operates on the virtual graph for everything. - // - // Basically, walk through all possible paths from starting way, - // honoring the existing turn restrictions as we go (watch out for loops!) - // - // For each path found, generate and return a `osmTurn` datastructure. - // + if (!this.id) { + this.id = osmNote.id().toString(); + } - intersection.turns = function (fromWayId, maxViaWay) { - if (!fromWayId) return []; - if (!maxViaWay) maxViaWay = 0; - var vgraph = intersection.graph; - var keyVertexIds = intersection.vertices.map(function (v) { - return v.id; + return this; + }, + extent: function extent() { + return new geoExtent(this.loc); + }, + update: function update(attrs) { + return osmNote(this, attrs); // {v: 1 + (this.v || 0)} + }, + isNew: function isNew() { + return this.id < 0; + }, + move: function move(loc) { + return this.update({ + loc: loc }); - var start = vgraph.entity(fromWayId); - if (!start || !(start.__from || start.__via)) return []; // maxViaWay=0 from-*-to (0 vias) - // maxViaWay=1 from-*-via-*-to (1 via max) - // maxViaWay=2 from-*-via-*-via-*-to (2 vias max) - - var maxPathLength = maxViaWay * 2 + 3; - var turns = []; - step(start); - return turns; // traverse the intersection graph and find all the valid paths - - function step(entity, currPath, currRestrictions, matchedRestriction) { - currPath = (currPath || []).slice(); // shallow copy + } + }); - if (currPath.length >= maxPathLength) return; - currPath.push(entity.id); - currRestrictions = (currRestrictions || []).slice(); // shallow copy + function osmRelation() { + if (!(this instanceof osmRelation)) { + return new osmRelation().initialize(arguments); + } else if (arguments.length) { + this.initialize(arguments); + } + } + osmEntity.relation = osmRelation; + osmRelation.prototype = Object.create(osmEntity.prototype); - var i, j; + osmRelation.creationOrder = function (a, b) { + var aId = parseInt(osmEntity.id.toOSM(a.id), 10); + var bId = parseInt(osmEntity.id.toOSM(b.id), 10); + if (aId < 0 || bId < 0) return aId - bId; + return bId - aId; + }; - if (entity.type === 'node') { - var parents = vgraph.parentWays(entity); - var nextWays = []; // which ways can we step into? + Object.assign(osmRelation.prototype, { + type: 'relation', + members: [], + copy: function copy(resolver, copies) { + if (copies[this.id]) return copies[this.id]; + var copy = osmEntity.prototype.copy.call(this, resolver, copies); + var members = this.members.map(function (member) { + return Object.assign({}, member, { + id: resolver.entity(member.id).copy(resolver, copies).id + }); + }); + copy = copy.update({ + members: members + }); + copies[this.id] = copy; + return copy; + }, + extent: function extent(resolver, memo) { + return resolver["transient"](this, 'extent', function () { + if (memo && memo[this.id]) return geoExtent(); + memo = memo || {}; + memo[this.id] = true; + var extent = geoExtent(); - for (i = 0; i < parents.length; i++) { - var way = parents[i]; // if next way is a oneway incoming to this vertex, skip + for (var i = 0; i < this.members.length; i++) { + var member = resolver.hasEntity(this.members[i].id); - if (way.__oneWay && way.nodes[0] !== entity.id) continue; // if we have seen it before (allowing for an initial u-turn), skip + if (member) { + extent._extend(member.extent(resolver, memo)); + } + } - if (currPath.indexOf(way.id) !== -1 && currPath.length >= 3) continue; // Check all "current" restrictions (where we've already walked the `FROM`) + return extent; + }); + }, + geometry: function geometry(graph) { + return graph["transient"](this, 'geometry', function () { + return this.isMultipolygon() ? 'area' : 'relation'; + }); + }, + isDegenerate: function isDegenerate() { + return this.members.length === 0; + }, + // Return an array of members, each extended with an 'index' property whose value + // is the member index. + indexedMembers: function indexedMembers() { + var result = new Array(this.members.length); - var restrict = null; + for (var i = 0; i < this.members.length; i++) { + result[i] = Object.assign({}, this.members[i], { + index: i + }); + } - for (j = 0; j < currRestrictions.length; j++) { - var restriction = currRestrictions[j]; - var f = restriction.memberByRole('from'); - var v = restriction.membersByRole('via'); - var t = restriction.memberByRole('to'); - var isOnly = /^only_/.test(restriction.tags.restriction); // Does the current path match this turn restriction? + return result; + }, + // Return the first member with the given role. A copy of the member object + // is returned, extended with an 'index' property whose value is the member index. + memberByRole: function memberByRole(role) { + for (var i = 0; i < this.members.length; i++) { + if (this.members[i].role === role) { + return Object.assign({}, this.members[i], { + index: i + }); + } + } + }, + // Same as memberByRole, but returns all members with the given role + membersByRole: function membersByRole(role) { + var result = []; - var matchesFrom = f.id === fromWayId; - var matchesViaTo = false; - var isAlongOnlyPath = false; + for (var i = 0; i < this.members.length; i++) { + if (this.members[i].role === role) { + result.push(Object.assign({}, this.members[i], { + index: i + })); + } + } - if (t.id === way.id) { - // match TO - if (v.length === 1 && v[0].type === 'node') { - // match VIA node - matchesViaTo = v[0].id === entity.id && (matchesFrom && currPath.length === 2 || !matchesFrom && currPath.length > 2); - } else { - // match all VIA ways - var pathVias = []; - - for (k = 2; k < currPath.length; k += 2) { - // k = 2 skips FROM - pathVias.push(currPath[k]); // (path goes way-node-way...) - } + return result; + }, + // Return the first member with the given id. A copy of the member object + // is returned, extended with an 'index' property whose value is the member index. + memberById: function memberById(id) { + for (var i = 0; i < this.members.length; i++) { + if (this.members[i].id === id) { + return Object.assign({}, this.members[i], { + index: i + }); + } + } + }, + // Return the first member with the given id and role. A copy of the member object + // is returned, extended with an 'index' property whose value is the member index. + memberByIdAndRole: function memberByIdAndRole(id, role) { + for (var i = 0; i < this.members.length; i++) { + if (this.members[i].id === id && this.members[i].role === role) { + return Object.assign({}, this.members[i], { + index: i + }); + } + } + }, + addMember: function addMember(member, index) { + var members = this.members.slice(); + members.splice(index === undefined ? members.length : index, 0, member); + return this.update({ + members: members + }); + }, + updateMember: function updateMember(member, index) { + var members = this.members.slice(); + members.splice(index, 1, Object.assign({}, members[index], member)); + return this.update({ + members: members + }); + }, + removeMember: function removeMember(index) { + var members = this.members.slice(); + members.splice(index, 1); + return this.update({ + members: members + }); + }, + removeMembersWithID: function removeMembersWithID(id) { + var members = this.members.filter(function (m) { + return m.id !== id; + }); + return this.update({ + members: members + }); + }, + moveMember: function moveMember(fromIndex, toIndex) { + var members = this.members.slice(); + members.splice(toIndex, 0, members.splice(fromIndex, 1)[0]); + return this.update({ + members: members + }); + }, + // Wherever a member appears with id `needle.id`, replace it with a member + // with id `replacement.id`, type `replacement.type`, and the original role, + // By default, adding a duplicate member (by id and role) is prevented. + // Return an updated relation. + replaceMember: function replaceMember(needle, replacement, keepDuplicates) { + if (!this.memberById(needle.id)) return this; + var members = []; - var restrictionVias = []; + for (var i = 0; i < this.members.length; i++) { + var member = this.members[i]; - for (k = 0; k < v.length; k++) { - if (v[k].type === 'way') { - restrictionVias.push(v[k].id); - } - } + if (member.id !== needle.id) { + members.push(member); + } else if (keepDuplicates || !this.memberByIdAndRole(replacement.id, member.role)) { + members.push({ + id: replacement.id, + type: replacement.type, + role: member.role + }); + } + } - var diff = utilArrayDifference(pathVias, restrictionVias); - matchesViaTo = !diff.length; - } - } else if (isOnly) { - for (k = 0; k < v.length; k++) { - // way doesn't match TO, but is one of the via ways along the path of an "only" - if (v[k].type === 'way' && v[k].id === way.id) { - isAlongOnlyPath = true; - break; - } - } + return this.update({ + members: members + }); + }, + asJXON: function asJXON(changeset_id) { + var r = { + relation: { + '@id': this.osmId(), + '@version': this.version || 0, + member: this.members.map(function (member) { + return { + keyAttributes: { + type: member.type, + role: member.role, + ref: osmEntity.id.toOSM(member.id) } + }; + }, this), + tag: Object.keys(this.tags).map(function (k) { + return { + keyAttributes: { + k: k, + v: this.tags[k] + } + }; + }, this) + } + }; - if (matchesViaTo) { - if (isOnly) { - restrict = { - id: restriction.id, - direct: matchesFrom, - from: f.id, - only: true, - end: true - }; - } else { - restrict = { - id: restriction.id, - direct: matchesFrom, - from: f.id, - no: true, - end: true - }; - } - } else { - // indirect - caused by a different nearby restriction - if (isAlongOnlyPath) { - restrict = { - id: restriction.id, - direct: false, - from: f.id, - only: true, - end: false - }; - } else if (isOnly) { - restrict = { - id: restriction.id, - direct: false, - from: f.id, - no: true, - end: true - }; - } - } // stop looking if we find a "direct" restriction (matching FROM, VIA, TO) - - - if (restrict && restrict.direct) break; - } - - nextWays.push({ - way: way, - restrict: restrict - }); - } + if (changeset_id) { + r.relation['@changeset'] = changeset_id; + } - nextWays.forEach(function (nextWay) { - step(nextWay.way, currPath, currRestrictions, nextWay.restrict); - }); + return r; + }, + asGeoJSON: function asGeoJSON(resolver) { + return resolver["transient"](this, 'GeoJSON', function () { + if (this.isMultipolygon()) { + return { + type: 'MultiPolygon', + coordinates: this.multipolygon(resolver) + }; } else { - // entity.type === 'way' - if (currPath.length >= 3) { - // this is a "complete" path.. - var turnPath = currPath.slice(); // shallow copy - // an indirect restriction - only include the partial path (starting at FROM) - - if (matchedRestriction && matchedRestriction.direct === false) { - for (i = 0; i < turnPath.length; i++) { - if (turnPath[i] === matchedRestriction.from) { - turnPath = turnPath.slice(i); - break; - } - } - } - - var turn = pathToTurn(turnPath); + return { + type: 'FeatureCollection', + properties: this.tags, + features: this.members.map(function (member) { + return Object.assign({ + role: member.role + }, resolver.entity(member.id).asGeoJSON(resolver)); + }) + }; + } + }); + }, + area: function area(resolver) { + return resolver["transient"](this, 'area', function () { + return d3_geoArea(this.asGeoJSON(resolver)); + }); + }, + isMultipolygon: function isMultipolygon() { + return this.tags.type === 'multipolygon'; + }, + isComplete: function isComplete(resolver) { + for (var i = 0; i < this.members.length; i++) { + if (!resolver.hasEntity(this.members[i].id)) { + return false; + } + } - if (turn) { - if (matchedRestriction) { - turn.restrictionID = matchedRestriction.id; - turn.no = matchedRestriction.no; - turn.only = matchedRestriction.only; - turn.direct = matchedRestriction.direct; - } + return true; + }, + hasFromViaTo: function hasFromViaTo() { + return this.members.some(function (m) { + return m.role === 'from'; + }) && this.members.some(function (m) { + return m.role === 'via'; + }) && this.members.some(function (m) { + return m.role === 'to'; + }); + }, + isRestriction: function isRestriction() { + return !!(this.tags.type && this.tags.type.match(/^restriction:?/)); + }, + isValidRestriction: function isValidRestriction() { + if (!this.isRestriction()) return false; + var froms = this.members.filter(function (m) { + return m.role === 'from'; + }); + var vias = this.members.filter(function (m) { + return m.role === 'via'; + }); + var tos = this.members.filter(function (m) { + return m.role === 'to'; + }); + if (froms.length !== 1 && this.tags.restriction !== 'no_entry') return false; + if (froms.some(function (m) { + return m.type !== 'way'; + })) return false; + if (tos.length !== 1 && this.tags.restriction !== 'no_exit') return false; + if (tos.some(function (m) { + return m.type !== 'way'; + })) return false; + if (vias.length === 0) return false; + if (vias.length > 1 && vias.some(function (m) { + return m.type !== 'way'; + })) return false; + return true; + }, + isConnectivity: function isConnectivity() { + return !!(this.tags.type && this.tags.type.match(/^connectivity:?/)); + }, + // Returns an array [A0, ... An], each Ai being an array of node arrays [Nds0, ... Ndsm], + // where Nds0 is an outer ring and subsequent Ndsi's (if any i > 0) being inner rings. + // + // This corresponds to the structure needed for rendering a multipolygon path using a + // `evenodd` fill rule, as well as the structure of a GeoJSON MultiPolygon geometry. + // + // In the case of invalid geometries, this function will still return a result which + // includes the nodes of all way members, but some Nds may be unclosed and some inner + // rings not matched with the intended outer ring. + // + multipolygon: function multipolygon(resolver) { + var outers = this.members.filter(function (m) { + return 'outer' === (m.role || 'outer'); + }); + var inners = this.members.filter(function (m) { + return 'inner' === m.role; + }); + outers = osmJoinWays(outers, resolver); + inners = osmJoinWays(inners, resolver); - turns.push(osmTurn(turn)); - } + var sequenceToLineString = function sequenceToLineString(sequence) { + if (sequence.nodes.length > 2 && sequence.nodes[0] !== sequence.nodes[sequence.nodes.length - 1]) { + // close unclosed parts to ensure correct area rendering - #2945 + sequence.nodes.push(sequence.nodes[0]); + } - if (currPath[0] === currPath[2]) return; // if we made a u-turn - stop here - } + return sequence.nodes.map(function (node) { + return node.loc; + }); + }; - if (matchedRestriction && matchedRestriction.end) return; // don't advance any further - // which nodes can we step into? + outers = outers.map(sequenceToLineString); + inners = inners.map(sequenceToLineString); + var result = outers.map(function (o) { + // Heuristic for detecting counterclockwise winding order. Assumes + // that OpenStreetMap polygons are not hemisphere-spanning. + return [d3_geoArea({ + type: 'Polygon', + coordinates: [o] + }) > 2 * Math.PI ? o.reverse() : o]; + }); - var n1 = vgraph.entity(entity.first()); - var n2 = vgraph.entity(entity.last()); - var dist = geoSphericalDistance(n1.loc, n2.loc); - var nextNodes = []; + function findOuter(inner) { + var o, outer; - if (currPath.length > 1) { - if (dist > maxDistance) return; // the next node is too far + for (o = 0; o < outers.length; o++) { + outer = outers[o]; - if (!entity.__via) return; // this way is a leaf / can't be a via + if (geoPolygonContainsPolygon(outer, inner)) { + return o; } + } - if (!entity.__oneWay && // bidirectional.. - keyVertexIds.indexOf(n1.id) !== -1 && // key vertex.. - currPath.indexOf(n1.id) === -1) { - // haven't seen it yet.. - nextNodes.push(n1); // can advance to first node - } + for (o = 0; o < outers.length; o++) { + outer = outers[o]; - if (keyVertexIds.indexOf(n2.id) !== -1 && // key vertex.. - currPath.indexOf(n2.id) === -1) { - // haven't seen it yet.. - nextNodes.push(n2); // can advance to last node + if (geoPolygonIntersectsPolygon(outer, inner, false)) { + return o; } - - nextNodes.forEach(function (nextNode) { - // gather restrictions FROM this way - var fromRestrictions = vgraph.parentRelations(entity).filter(function (r) { - if (!r.isRestriction()) return false; - var f = r.memberByRole('from'); - if (!f || f.id !== entity.id) return false; - var isOnly = /^only_/.test(r.tags.restriction); - if (!isOnly) return true; // `only_` restrictions only matter along the direction of the VIA - #4849 - - var isOnlyVia = false; - var v = r.membersByRole('via'); - - if (v.length === 1 && v[0].type === 'node') { - // via node - isOnlyVia = v[0].id === nextNode.id; - } else { - // via way(s) - for (var i = 0; i < v.length; i++) { - if (v[i].type !== 'way') continue; - var viaWay = vgraph.entity(v[i].id); - - if (viaWay.first() === nextNode.id || viaWay.last() === nextNode.id) { - isOnlyVia = true; - break; - } - } - } - - return isOnlyVia; - }); - step(nextNode, currPath, currRestrictions.concat(fromRestrictions), false); - }); } - } // assumes path is alternating way-node-way of odd length - - - function pathToTurn(path) { - if (path.length < 3) return; - var fromWayId, fromNodeId, fromVertexId; - var toWayId, toNodeId, toVertexId; - var viaWayIds, viaNodeId, isUturn; - fromWayId = path[0]; - toWayId = path[path.length - 1]; + } - if (path.length === 3 && fromWayId === toWayId) { - // u turn - var way = vgraph.entity(fromWayId); - if (way.__oneWay) return null; - isUturn = true; - viaNodeId = fromVertexId = toVertexId = path[1]; - fromNodeId = toNodeId = adjacentNode(fromWayId, viaNodeId); - } else { - isUturn = false; - fromVertexId = path[1]; - fromNodeId = adjacentNode(fromWayId, fromVertexId); - toVertexId = path[path.length - 2]; - toNodeId = adjacentNode(toWayId, toVertexId); + for (var i = 0; i < inners.length; i++) { + var inner = inners[i]; - if (path.length === 3) { - viaNodeId = path[1]; - } else { - viaWayIds = path.filter(function (entityId) { - return entityId[0] === 'w'; - }); - viaWayIds = viaWayIds.slice(1, viaWayIds.length - 1); // remove first, last - } + if (d3_geoArea({ + type: 'Polygon', + coordinates: [inner] + }) < 2 * Math.PI) { + inner = inner.reverse(); } - return { - key: path.join('_'), - path: path, - from: { - node: fromNodeId, - way: fromWayId, - vertex: fromVertexId - }, - via: { - node: viaNodeId, - ways: viaWayIds - }, - to: { - node: toNodeId, - way: toWayId, - vertex: toVertexId - }, - u: isUturn - }; + var o = findOuter(inners[i]); - function adjacentNode(wayId, affixId) { - var nodes = vgraph.entity(wayId).nodes; - return affixId === nodes[0] ? nodes[1] : nodes[nodes.length - 2]; + if (o !== undefined) { + result[o].push(inners[i]); + } else { + result.push([inners[i]]); // Invalid geometry } } - }; - - return intersection; - } - function osmInferRestriction(graph, turn, projection) { - var fromWay = graph.entity(turn.from.way); - var fromNode = graph.entity(turn.from.node); - var fromVertex = graph.entity(turn.from.vertex); - var toWay = graph.entity(turn.to.way); - var toNode = graph.entity(turn.to.node); - var toVertex = graph.entity(turn.to.vertex); - var fromOneWay = fromWay.tags.oneway === 'yes'; - var toOneWay = toWay.tags.oneway === 'yes'; - var angle = (geoAngle(fromVertex, fromNode, projection) - geoAngle(toVertex, toNode, projection)) * 180 / Math.PI; - - while (angle < 0) { - angle += 360; - } - if (fromNode === toNode) { - return 'no_u_turn'; + return result; } + }); - if ((angle < 23 || angle > 336) && fromOneWay && toOneWay) { - return 'no_u_turn'; // wider tolerance for u-turn if both ways are oneway - } + var QAItem = /*#__PURE__*/function () { + function QAItem(loc, service, itemType, id, props) { + _classCallCheck$1(this, QAItem); - if ((angle < 40 || angle > 319) && fromOneWay && toOneWay && turn.from.vertex !== turn.to.vertex) { - return 'no_u_turn'; // even wider tolerance for u-turn if there is a via way (from !== to) - } + // Store required properties + this.loc = loc; + this.service = service.title; + this.itemType = itemType; // All issues must have an ID for selection, use generic if none specified - if (angle < 158) { - return 'no_right_turn'; - } + this.id = id ? id : "".concat(QAItem.id()); + this.update(props); // Some QA services have marker icons to differentiate issues - if (angle > 202) { - return 'no_left_turn'; + if (service && typeof service.getIcon === 'function') { + this.icon = service.getIcon(itemType); + } } - return 'no_straight_on'; - } + _createClass$1(QAItem, [{ + key: "update", + value: function update(props) { + var _this = this; - function actionMergePolygon(ids, newRelationId) { - function groupEntities(graph) { - var entities = ids.map(function (id) { - return graph.entity(id); - }); - var geometryGroups = utilArrayGroupBy(entities, function (entity) { - if (entity.type === 'way' && entity.isClosed()) { - return 'closedWay'; - } else if (entity.type === 'relation' && entity.isMultipolygon()) { - return 'multipolygon'; - } else { - return 'other'; - } - }); - return Object.assign({ - closedWay: [], - multipolygon: [], - other: [] - }, geometryGroups); - } + // You can't override this initial information + var loc = this.loc, + service = this.service, + itemType = this.itemType, + id = this.id; + Object.keys(props).forEach(function (prop) { + return _this[prop] = props[prop]; + }); + this.loc = loc; + this.service = service; + this.itemType = itemType; + this.id = id; + return this; + } // Generic handling for newly created QAItems - var action = function action(graph) { - var entities = groupEntities(graph); // An array representing all the polygons that are part of the multipolygon. - // - // Each element is itself an array of objects with an id property, and has a - // locs property which is an array of the locations forming the polygon. + }], [{ + key: "id", + value: function id() { + return this.nextId--; + } + }]); - var polygons = entities.multipolygon.reduce(function (polygons, m) { - return polygons.concat(osmJoinWays(m.members, graph)); - }, []).concat(entities.closedWay.map(function (d) { - var member = [{ - id: d.id - }]; - member.nodes = graph.childNodes(d); - return member; - })); // contained is an array of arrays of boolean values, - // where contained[j][k] is true iff the jth way is - // contained by the kth way. + return QAItem; + }(); + QAItem.nextId = -1; - var contained = polygons.map(function (w, i) { - return polygons.map(function (d, n) { - if (i === n) return null; - return geoPolygonContainsPolygon(d.nodes.map(function (n) { - return n.loc; - }), w.nodes.map(function (n) { - return n.loc; - })); - }); - }); // Sort all polygons as either outer or inner ways + // + // Optionally, split only the given ways, if multiple ways share + // the given node. + // + // This is the inverse of `iD.actionJoin`. + // + // For testing convenience, accepts an ID to assign to the new way. + // Normally, this will be undefined and the way will automatically + // be assigned a new ID. + // + // Reference: + // https://github.com/systemed/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/SplitWayAction.as + // - var members = []; - var outer = true; + function actionSplit(nodeIds, newWayIds) { + // accept single ID for backwards-compatiblity + if (typeof nodeIds === 'string') nodeIds = [nodeIds]; - while (polygons.length) { - extractUncontained(polygons); - polygons = polygons.filter(isContained); - contained = contained.filter(isContained).map(filterContained); - } + var _wayIDs; // the strategy for picking which way will have a new version and which way is newly created - function isContained(d, i) { - return contained[i].some(function (val) { - return val; - }); - } - function filterContained(d) { - return d.filter(isContained); - } + var _keepHistoryOn = 'longest'; // 'longest', 'first' + // The IDs of the ways actually created by running this action - function extractUncontained(polygons) { - polygons.forEach(function (d, i) { - if (!isContained(d, i)) { - d.forEach(function (member) { - members.push({ - type: 'way', - id: member.id, - role: outer ? 'outer' : 'inner' - }); - }); - } - }); - outer = !outer; - } // Move all tags to one relation + var _createdWayIDs = []; + + function dist(graph, nA, nB) { + var locA = graph.entity(nA).loc; + var locB = graph.entity(nB).loc; + var epsilon = 1e-6; + return locA && locB ? geoSphericalDistance(locA, locB) : epsilon; + } // If the way is closed, we need to search for a partner node + // to split the way at. + // + // The following looks for a node that is both far away from + // the initial node in terms of way segment length and nearby + // in terms of beeline-distance. This assures that areas get + // split on the most "natural" points (independent of the number + // of nodes). + // For example: bone-shaped areas get split across their waist + // line, circles across the diameter. - var relation = entities.multipolygon[0] || osmRelation({ - id: newRelationId, - tags: { - type: 'multipolygon' - } - }); - entities.multipolygon.slice(1).forEach(function (m) { - relation = relation.mergeTags(m.tags); - graph = graph.remove(m); - }); - entities.closedWay.forEach(function (way) { - function isThisOuter(m) { - return m.id === way.id && m.role !== 'inner'; - } + function splitArea(nodes, idxA, graph) { + var lengths = new Array(nodes.length); + var length; + var i; + var best = 0; + var idxB; - if (members.some(isThisOuter)) { - relation = relation.mergeTags(way.tags); - graph = graph.replace(way.update({ - tags: {} - })); - } - }); - return graph.replace(relation.update({ - members: members, - tags: utilObjectOmit(relation.tags, ['area']) - })); - }; + function wrap(index) { + return utilWrap(index, nodes.length); + } // calculate lengths - action.disabled = function (graph) { - var entities = groupEntities(graph); - if (entities.other.length > 0 || entities.closedWay.length + entities.multipolygon.length < 2) { - return 'not_eligible'; - } + length = 0; - if (!entities.multipolygon.every(function (r) { - return r.isComplete(graph); - })) { - return 'incomplete_relation'; + for (i = wrap(idxA + 1); i !== idxA; i = wrap(i + 1)) { + length += dist(graph, nodes[i], nodes[wrap(i - 1)]); + lengths[i] = length; } - if (!entities.multipolygon.length) { - var sharedMultipolygons = []; - entities.closedWay.forEach(function (way, i) { - if (i === 0) { - sharedMultipolygons = graph.parentMultipolygons(way); - } else { - sharedMultipolygons = utilArrayIntersection(sharedMultipolygons, graph.parentMultipolygons(way)); - } - }); - sharedMultipolygons = sharedMultipolygons.filter(function (relation) { - return relation.members.length === entities.closedWay.length; - }); + length = 0; - if (sharedMultipolygons.length) { - // don't create a new multipolygon if it'd be redundant - return 'not_eligible'; + for (i = wrap(idxA - 1); i !== idxA; i = wrap(i - 1)) { + length += dist(graph, nodes[i], nodes[wrap(i + 1)]); + + if (length < lengths[i]) { + lengths[i] = length; + } + } // determine best opposite node to split + + + for (i = 0; i < nodes.length; i++) { + var cost = lengths[i] / dist(graph, nodes[idxA], nodes[i]); + + if (cost > best) { + idxB = i; + best = cost; } - } else if (entities.closedWay.some(function (way) { - return utilArrayIntersection(graph.parentMultipolygons(way), entities.multipolygon).length; - })) { - // don't add a way to a multipolygon again if it's already a member - return 'not_eligible'; } - }; - return action; - } + return idxB; + } - var DESCRIPTORS = descriptors; - var objectDefinePropertyModule = objectDefineProperty; - var regExpFlags = regexpFlags$1; - var fails$4 = fails$N; + function totalLengthBetweenNodes(graph, nodes) { + var totalLength = 0; - var FORCED$2 = DESCRIPTORS && fails$4(function () { - // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe - return Object.getOwnPropertyDescriptor(RegExp.prototype, 'flags').get.call({ dotAll: true, sticky: true }) !== 'sy'; - }); + for (var i = 0; i < nodes.length - 1; i++) { + totalLength += dist(graph, nodes[i], nodes[i + 1]); + } - // `RegExp.prototype.flags` getter - // https://tc39.es/ecma262/#sec-get-regexp.prototype.flags - if (FORCED$2) objectDefinePropertyModule.f(RegExp.prototype, 'flags', { - configurable: true, - get: regExpFlags - }); + return totalLength; + } - var fastDeepEqual = function equal(a, b) { - if (a === b) return true; + function split(graph, nodeId, wayA, newWayId) { + var wayB = osmWay({ + id: newWayId, + tags: wayA.tags + }); // `wayB` is the NEW way - if (a && b && _typeof(a) == 'object' && _typeof(b) == 'object') { - if (a.constructor !== b.constructor) return false; - var length, i, keys; + var origNodes = wayA.nodes.slice(); + var nodesA; + var nodesB; + var isArea = wayA.isArea(); + var isOuter = osmIsOldMultipolygonOuterMember(wayA, graph); - if (Array.isArray(a)) { - length = a.length; - if (length != b.length) return false; + if (wayA.isClosed()) { + var nodes = wayA.nodes.slice(0, -1); + var idxA = nodes.indexOf(nodeId); + var idxB = splitArea(nodes, idxA, graph); - for (i = length; i-- !== 0;) { - if (!equal(a[i], b[i])) return false; + if (idxB < idxA) { + nodesA = nodes.slice(idxA).concat(nodes.slice(0, idxB + 1)); + nodesB = nodes.slice(idxB, idxA + 1); + } else { + nodesA = nodes.slice(idxA, idxB + 1); + nodesB = nodes.slice(idxB).concat(nodes.slice(0, idxA + 1)); } - - return true; + } else { + var idx = wayA.nodes.indexOf(nodeId, 1); + nodesA = wayA.nodes.slice(0, idx + 1); + nodesB = wayA.nodes.slice(idx); } - if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags; - if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf(); - if (a.toString !== Object.prototype.toString) return a.toString() === b.toString(); - keys = Object.keys(a); - length = keys.length; - if (length !== Object.keys(b).length) return false; + var lengthA = totalLengthBetweenNodes(graph, nodesA); + var lengthB = totalLengthBetweenNodes(graph, nodesB); - for (i = length; i-- !== 0;) { - if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false; + if (_keepHistoryOn === 'longest' && lengthB > lengthA) { + // keep the history on the longer way, regardless of the node count + wayA = wayA.update({ + nodes: nodesB + }); + wayB = wayB.update({ + nodes: nodesA + }); + var temp = lengthA; + lengthA = lengthB; + lengthB = temp; + } else { + wayA = wayA.update({ + nodes: nodesA + }); + wayB = wayB.update({ + nodes: nodesB + }); } - for (i = length; i-- !== 0;) { - var key = keys[i]; - if (!equal(a[key], b[key])) return false; + if (wayA.tags.step_count) { + // divide up the the step count proportionally between the two ways + var stepCount = parseFloat(wayA.tags.step_count); + + if (stepCount && // ensure a number + isFinite(stepCount) && // ensure positive + stepCount > 0 && // ensure integer + Math.round(stepCount) === stepCount) { + var tagsA = Object.assign({}, wayA.tags); + var tagsB = Object.assign({}, wayB.tags); + var ratioA = lengthA / (lengthA + lengthB); + var countA = Math.round(stepCount * ratioA); + tagsA.step_count = countA.toString(); + tagsB.step_count = (stepCount - countA).toString(); + wayA = wayA.update({ + tags: tagsA + }); + wayB = wayB.update({ + tags: tagsB + }); + } } - return true; - } // true if both NaN, false otherwise + graph = graph.replace(wayA); + graph = graph.replace(wayB); + graph.parentRelations(wayA).forEach(function (relation) { + var member; // Turn restrictions - make sure: + // 1. Splitting a FROM/TO way - only `wayA` OR `wayB` remains in relation + // (whichever one is connected to the VIA node/ways) + // 2. Splitting a VIA way - `wayB` remains in relation as a VIA way + if (relation.hasFromViaTo()) { + var f = relation.memberByRole('from'); + var v = relation.membersByRole('via'); + var t = relation.memberByRole('to'); + var i; // 1. split a FROM/TO - return a !== a && b !== b; - }; + if (f.id === wayA.id || t.id === wayA.id) { + var keepB = false; - // J. W. Hunt and M. D. McIlroy, An algorithm for differential buffer - // comparison, Bell Telephone Laboratories CSTR #41 (1976) - // http://www.cs.dartmouth.edu/~doug/ - // https://en.wikipedia.org/wiki/Longest_common_subsequence_problem - // - // Expects two arrays, finds longest common sequence + if (v.length === 1 && v[0].type === 'node') { + // check via node + keepB = wayB.contains(v[0].id); + } else { + // check via way(s) + for (i = 0; i < v.length; i++) { + if (v[i].type === 'way') { + var wayVia = graph.hasEntity(v[i].id); - function LCS(buffer1, buffer2) { - var equivalenceClasses = {}; + if (wayVia && utilArrayIntersection(wayB.nodes, wayVia.nodes).length) { + keepB = true; + break; + } + } + } + } - for (var j = 0; j < buffer2.length; j++) { - var item = buffer2[j]; + if (keepB) { + relation = relation.replaceMember(wayA, wayB); + graph = graph.replace(relation); + } // 2. split a VIA - if (equivalenceClasses[item]) { - equivalenceClasses[item].push(j); - } else { - equivalenceClasses[item] = [j]; - } - } + } else { + for (i = 0; i < v.length; i++) { + if (v[i].type === 'way' && v[i].id === wayA.id) { + member = { + id: wayB.id, + type: 'way', + role: 'via' + }; + graph = actionAddMember(relation.id, member, v[i].index + 1)(graph); + break; + } + } + } // All other relations (Routes, Multipolygons, etc): + // 1. Both `wayA` and `wayB` remain in the relation + // 2. But must be inserted as a pair (see `actionAddMember` for details) - var NULLRESULT = { - buffer1index: -1, - buffer2index: -1, - chain: null - }; - var candidates = [NULLRESULT]; + } else { + if (relation === isOuter) { + graph = graph.replace(relation.mergeTags(wayA.tags)); + graph = graph.replace(wayA.update({ + tags: {} + })); + graph = graph.replace(wayB.update({ + tags: {} + })); + } - for (var i = 0; i < buffer1.length; i++) { - var _item = buffer1[i]; - var buffer2indices = equivalenceClasses[_item] || []; - var r = 0; - var c = candidates[0]; + member = { + id: wayB.id, + type: 'way', + role: relation.memberById(wayA.id).role + }; + var insertPair = { + originalID: wayA.id, + insertedID: wayB.id, + nodes: origNodes + }; + graph = actionAddMember(relation.id, member, undefined, insertPair)(graph); + } + }); - for (var jx = 0; jx < buffer2indices.length; jx++) { - var _j = buffer2indices[jx]; - var s = void 0; + if (!isOuter && isArea) { + var multipolygon = osmRelation({ + tags: Object.assign({}, wayA.tags, { + type: 'multipolygon' + }), + members: [{ + id: wayA.id, + role: 'outer', + type: 'way' + }, { + id: wayB.id, + role: 'outer', + type: 'way' + }] + }); + graph = graph.replace(multipolygon); + graph = graph.replace(wayA.update({ + tags: {} + })); + graph = graph.replace(wayB.update({ + tags: {} + })); + } - for (s = r; s < candidates.length; s++) { - if (candidates[s].buffer2index < _j && (s === candidates.length - 1 || candidates[s + 1].buffer2index > _j)) { - break; - } - } + _createdWayIDs.push(wayB.id); - if (s < candidates.length) { - var newCandidate = { - buffer1index: i, - buffer2index: _j, - chain: candidates[s] - }; + return graph; + } - if (r === candidates.length) { - candidates.push(c); - } else { - candidates[r] = c; - } + var action = function action(graph) { + _createdWayIDs = []; + var newWayIndex = 0; - r = s + 1; - c = newCandidate; + for (var i = 0; i < nodeIds.length; i++) { + var nodeId = nodeIds[i]; + var candidates = action.waysForNode(nodeId, graph); - if (r === candidates.length) { - break; // no point in examining further (j)s - } + for (var j = 0; j < candidates.length; j++) { + graph = split(graph, nodeId, candidates[j], newWayIds && newWayIds[newWayIndex]); + newWayIndex += 1; } } - candidates[r] = c; - } // At this point, we know the LCS: it's in the reverse of the - // linked-list through .chain of candidates[candidates.length - 1]. + return graph; + }; + action.getCreatedWayIDs = function () { + return _createdWayIDs; + }; - return candidates[candidates.length - 1]; - } // We apply the LCS to build a 'comm'-style picture of the - // offsets and lengths of mismatched chunks in the input - // buffers. This is used by diff3MergeRegions. + action.waysForNode = function (nodeId, graph) { + var node = graph.entity(nodeId); + var splittableParents = graph.parentWays(node).filter(isSplittable); + if (!_wayIDs) { + // If the ways to split aren't specified, only split the lines. + // If there are no lines to split, split the areas. + var hasLine = splittableParents.some(function (parent) { + return parent.geometry(graph) === 'line'; + }); - function diffIndices(buffer1, buffer2) { - var lcs = LCS(buffer1, buffer2); - var result = []; - var tail1 = buffer1.length; - var tail2 = buffer2.length; + if (hasLine) { + return splittableParents.filter(function (parent) { + return parent.geometry(graph) === 'line'; + }); + } + } - for (var candidate = lcs; candidate !== null; candidate = candidate.chain) { - var mismatchLength1 = tail1 - candidate.buffer1index - 1; - var mismatchLength2 = tail2 - candidate.buffer2index - 1; - tail1 = candidate.buffer1index; - tail2 = candidate.buffer2index; - - if (mismatchLength1 || mismatchLength2) { - result.push({ - buffer1: [tail1 + 1, mismatchLength1], - buffer1Content: buffer1.slice(tail1 + 1, tail1 + 1 + mismatchLength1), - buffer2: [tail2 + 1, mismatchLength2], - buffer2Content: buffer2.slice(tail2 + 1, tail2 + 1 + mismatchLength2) - }); - } - } - - result.reverse(); - return result; - } // We apply the LCS to build a JSON representation of a - // independently derived from O, returns a fairly complicated - // internal representation of merge decisions it's taken. The - // interested reader may wish to consult - // - // Sanjeev Khanna, Keshav Kunal, and Benjamin C. Pierce. - // 'A Formal Investigation of ' In Arvind and Prasad, - // editors, Foundations of Software Technology and Theoretical - // Computer Science (FSTTCS), December 2007. - // - // (http://www.cis.upenn.edu/~bcpierce/papers/diff3-short.pdf) - // - - - function diff3MergeRegions(a, o, b) { - // "hunks" are array subsets where `a` or `b` are different from `o` - // https://www.gnu.org/software/diffutils/manual/html_node/diff3-Hunks.html - var hunks = []; + return splittableParents; - function addHunk(h, ab) { - hunks.push({ - ab: ab, - oStart: h.buffer1[0], - oLength: h.buffer1[1], - // length of o to remove - abStart: h.buffer2[0], - abLength: h.buffer2[1] // length of a/b to insert - // abContent: (ab === 'a' ? a : b).slice(h.buffer2[0], h.buffer2[0] + h.buffer2[1]) + function isSplittable(parent) { + // If the ways to split are specified, ignore everything else. + if (_wayIDs && _wayIDs.indexOf(parent.id) === -1) return false; // We can fake splitting closed ways at their endpoints... - }); - } + if (parent.isClosed()) return true; // otherwise, we can't split nodes at their endpoints. - diffIndices(o, a).forEach(function (item) { - return addHunk(item, 'a'); - }); - diffIndices(o, b).forEach(function (item) { - return addHunk(item, 'b'); - }); - hunks.sort(function (x, y) { - return x.oStart - y.oStart; - }); - var results = []; - var currOffset = 0; + for (var i = 1; i < parent.nodes.length - 1; i++) { + if (parent.nodes[i] === nodeId) return true; + } - function advanceTo(endOffset) { - if (endOffset > currOffset) { - results.push({ - stable: true, - buffer: 'o', - bufferStart: currOffset, - bufferLength: endOffset - currOffset, - bufferContent: o.slice(currOffset, endOffset) - }); - currOffset = endOffset; + return false; } - } - - while (hunks.length) { - var hunk = hunks.shift(); - var regionStart = hunk.oStart; - var regionEnd = hunk.oStart + hunk.oLength; - var regionHunks = [hunk]; - advanceTo(regionStart); // Try to pull next overlapping hunk into this region - - while (hunks.length) { - var nextHunk = hunks[0]; - var nextHunkStart = nextHunk.oStart; - if (nextHunkStart > regionEnd) break; // no overlap + }; - regionEnd = Math.max(regionEnd, nextHunkStart + nextHunk.oLength); - regionHunks.push(hunks.shift()); - } + action.ways = function (graph) { + return utilArrayUniq([].concat.apply([], nodeIds.map(function (nodeId) { + return action.waysForNode(nodeId, graph); + }))); + }; - if (regionHunks.length === 1) { - // Only one hunk touches this region, meaning that there is no conflict here. - // Either `a` or `b` is inserting into a region of `o` unchanged by the other. - if (hunk.abLength > 0) { - var buffer = hunk.ab === 'a' ? a : b; - results.push({ - stable: true, - buffer: hunk.ab, - bufferStart: hunk.abStart, - bufferLength: hunk.abLength, - bufferContent: buffer.slice(hunk.abStart, hunk.abStart + hunk.abLength) - }); - } - } else { - // A true a/b conflict. Determine the bounds involved from `a`, `o`, and `b`. - // Effectively merge all the `a` hunks into one giant hunk, then do the - // same for the `b` hunks; then, correct for skew in the regions of `o` - // that each side changed, and report appropriate spans for the three sides. - var bounds = { - a: [a.length, -1, o.length, -1], - b: [b.length, -1, o.length, -1] - }; + action.disabled = function (graph) { + for (var i = 0; i < nodeIds.length; i++) { + var nodeId = nodeIds[i]; + var candidates = action.waysForNode(nodeId, graph); - while (regionHunks.length) { - hunk = regionHunks.shift(); - var oStart = hunk.oStart; - var oEnd = oStart + hunk.oLength; - var abStart = hunk.abStart; - var abEnd = abStart + hunk.abLength; - var _b = bounds[hunk.ab]; - _b[0] = Math.min(abStart, _b[0]); - _b[1] = Math.max(abEnd, _b[1]); - _b[2] = Math.min(oStart, _b[2]); - _b[3] = Math.max(oEnd, _b[3]); + if (candidates.length === 0 || _wayIDs && _wayIDs.length !== candidates.length) { + return 'not_eligible'; } - - var aStart = bounds.a[0] + (regionStart - bounds.a[2]); - var aEnd = bounds.a[1] + (regionEnd - bounds.a[3]); - var bStart = bounds.b[0] + (regionStart - bounds.b[2]); - var bEnd = bounds.b[1] + (regionEnd - bounds.b[3]); - var result = { - stable: false, - aStart: aStart, - aLength: aEnd - aStart, - aContent: a.slice(aStart, aEnd), - oStart: regionStart, - oLength: regionEnd - regionStart, - oContent: o.slice(regionStart, regionEnd), - bStart: bStart, - bLength: bEnd - bStart, - bContent: b.slice(bStart, bEnd) - }; - results.push(result); } - - currOffset = regionEnd; - } - - advanceTo(o.length); - return results; - } // Applies the output of diff3MergeRegions to actually - // construct the merged buffer; the returned result alternates - // between 'ok' and 'conflict' blocks. - // A "false conflict" is where `a` and `b` both change the same from `o` - - - function diff3Merge(a, o, b, options) { - var defaults = { - excludeFalseConflicts: true, - stringSeparator: /\s+/ }; - options = Object.assign(defaults, options); - var aString = typeof a === 'string'; - var oString = typeof o === 'string'; - var bString = typeof b === 'string'; - if (aString) a = a.split(options.stringSeparator); - if (oString) o = o.split(options.stringSeparator); - if (bString) b = b.split(options.stringSeparator); - var results = []; - var regions = diff3MergeRegions(a, o, b); - var okBuffer = []; - function flushOk() { - if (okBuffer.length) { - results.push({ - ok: okBuffer - }); - } + action.limitWays = function (val) { + if (!arguments.length) return _wayIDs; + _wayIDs = val; + return action; + }; - okBuffer = []; - } + action.keepHistoryOn = function (val) { + if (!arguments.length) return _keepHistoryOn; + _keepHistoryOn = val; + return action; + }; - function isFalseConflict(a, b) { - if (a.length !== b.length) return false; + return action; + } - for (var i = 0; i < a.length; i++) { - if (a[i] !== b[i]) return false; - } + function coreGraph(other, mutable) { + if (!(this instanceof coreGraph)) return new coreGraph(other, mutable); - return true; + if (other instanceof coreGraph) { + var base = other.base(); + this.entities = Object.assign(Object.create(base.entities), other.entities); + this._parentWays = Object.assign(Object.create(base.parentWays), other._parentWays); + this._parentRels = Object.assign(Object.create(base.parentRels), other._parentRels); + } else { + this.entities = Object.create({}); + this._parentWays = Object.create({}); + this._parentRels = Object.create({}); + this.rebase(other || [], [this]); } - regions.forEach(function (region) { - if (region.stable) { - var _okBuffer; + this.transients = {}; + this._childNodes = {}; + this.frozen = !mutable; + } + coreGraph.prototype = { + hasEntity: function hasEntity(id) { + return this.entities[id]; + }, + entity: function entity(id) { + var entity = this.entities[id]; //https://github.com/openstreetmap/iD/issues/3973#issuecomment-307052376 - (_okBuffer = okBuffer).push.apply(_okBuffer, _toConsumableArray(region.bufferContent)); - } else { - if (options.excludeFalseConflicts && isFalseConflict(region.aContent, region.bContent)) { - var _okBuffer2; + if (!entity) { + entity = this.entities.__proto__[id]; // eslint-disable-line no-proto + } - (_okBuffer2 = okBuffer).push.apply(_okBuffer2, _toConsumableArray(region.aContent)); - } else { - flushOk(); - results.push({ - conflict: { - a: region.aContent, - aIndex: region.aStart, - o: region.oContent, - oIndex: region.oStart, - b: region.bContent, - bIndex: region.bStart - } - }); - } + if (!entity) { + throw new Error('entity ' + id + ' not found'); } - }); - flushOk(); - return results; - } - function actionMergeRemoteChanges(id, localGraph, remoteGraph, discardTags, formatUser) { - discardTags = discardTags || {}; - var _option = 'safe'; // 'safe', 'force_local', 'force_remote' + return entity; + }, + geometry: function geometry(id) { + return this.entity(id).geometry(this); + }, + "transient": function transient(entity, key, fn) { + var id = entity.id; + var transients = this.transients[id] || (this.transients[id] = {}); - var _conflicts = []; + if (transients[key] !== undefined) { + return transients[key]; + } - function user(d) { - return typeof formatUser === 'function' ? formatUser(d) : d; - } + transients[key] = fn.call(entity); + return transients[key]; + }, + parentWays: function parentWays(entity) { + var parents = this._parentWays[entity.id]; + var result = []; - function mergeLocation(remote, target) { - function pointEqual(a, b) { - var epsilon = 1e-6; - return Math.abs(a[0] - b[0]) < epsilon && Math.abs(a[1] - b[1]) < epsilon; + if (parents) { + parents.forEach(function (id) { + result.push(this.entity(id)); + }, this); } - if (_option === 'force_local' || pointEqual(target.loc, remote.loc)) { - return target; - } + return result; + }, + isPoi: function isPoi(entity) { + var parents = this._parentWays[entity.id]; + return !parents || parents.size === 0; + }, + isShared: function isShared(entity) { + var parents = this._parentWays[entity.id]; + return parents && parents.size > 1; + }, + parentRelations: function parentRelations(entity) { + var parents = this._parentRels[entity.id]; + var result = []; - if (_option === 'force_remote') { - return target.update({ - loc: remote.loc - }); + if (parents) { + parents.forEach(function (id) { + result.push(this.entity(id)); + }, this); } - _conflicts.push(_t('merge_remote_changes.conflict.location', { - user: user(remote.user) - })); - - return target; - } + return result; + }, + parentMultipolygons: function parentMultipolygons(entity) { + return this.parentRelations(entity).filter(function (relation) { + return relation.isMultipolygon(); + }); + }, + childNodes: function childNodes(entity) { + if (this._childNodes[entity.id]) return this._childNodes[entity.id]; + if (!entity.nodes) return []; + var nodes = []; - function mergeNodes(base, remote, target) { - if (_option === 'force_local' || fastDeepEqual(target.nodes, remote.nodes)) { - return target; + for (var i = 0; i < entity.nodes.length; i++) { + nodes[i] = this.entity(entity.nodes[i]); } + this._childNodes[entity.id] = nodes; + return this._childNodes[entity.id]; + }, + base: function base() { + return { + 'entities': Object.getPrototypeOf(this.entities), + 'parentWays': Object.getPrototypeOf(this._parentWays), + 'parentRels': Object.getPrototypeOf(this._parentRels) + }; + }, + // Unlike other graph methods, rebase mutates in place. This is because it + // is used only during the history operation that merges newly downloaded + // data into each state. To external consumers, it should appear as if the + // graph always contained the newly downloaded data. + rebase: function rebase(entities, stack, force) { + var base = this.base(); + var i, j, k, id; - if (_option === 'force_remote') { - return target.update({ - nodes: remote.nodes - }); - } + for (i = 0; i < entities.length; i++) { + var entity = entities[i]; + if (!entity.visible || !force && base.entities[entity.id]) continue; // Merging data into the base graph - var ccount = _conflicts.length; - var o = base.nodes || []; - var a = target.nodes || []; - var b = remote.nodes || []; - var nodes = []; - var hunks = diff3Merge(a, o, b, { - excludeFalseConflicts: true - }); + base.entities[entity.id] = entity; - for (var i = 0; i < hunks.length; i++) { - var hunk = hunks[i]; + this._updateCalculated(undefined, entity, base.parentWays, base.parentRels); // Restore provisionally-deleted nodes that are discovered to have an extant parent - if (hunk.ok) { - nodes.push.apply(nodes, hunk.ok); - } else { - // for all conflicts, we can assume c.a !== c.b - // because `diff3Merge` called with `true` option to exclude false conflicts.. - var c = hunk.conflict; - if (fastDeepEqual(c.o, c.a)) { - // only changed remotely - nodes.push.apply(nodes, c.b); - } else if (fastDeepEqual(c.o, c.b)) { - // only changed locally - nodes.push.apply(nodes, c.a); - } else { - // changed both locally and remotely - _conflicts.push(_t('merge_remote_changes.conflict.nodelist', { - user: user(remote.user) - })); + if (entity.type === 'way') { + for (j = 0; j < entity.nodes.length; j++) { + id = entity.nodes[j]; - break; + for (k = 1; k < stack.length; k++) { + var ents = stack[k].entities; + + if (ents.hasOwnProperty(id) && ents[id] === undefined) { + delete ents[id]; + } + } } } } - return _conflicts.length === ccount ? target.update({ - nodes: nodes - }) : target; - } - - function mergeChildren(targetWay, children, updates, graph) { - function isUsed(node, targetWay) { - var hasInterestingParent = graph.parentWays(node).some(function (way) { - return way.id !== targetWay.id; - }); - return node.hasInterestingTags() || hasInterestingParent || graph.parentRelations(node).length > 0; + for (i = 0; i < stack.length; i++) { + stack[i]._updateRebased(); } + }, + _updateRebased: function _updateRebased() { + var base = this.base(); + Object.keys(this._parentWays).forEach(function (child) { + if (base.parentWays[child]) { + base.parentWays[child].forEach(function (id) { + if (!this.entities.hasOwnProperty(id)) { + this._parentWays[child].add(id); + } + }, this); + } + }, this); + Object.keys(this._parentRels).forEach(function (child) { + if (base.parentRels[child]) { + base.parentRels[child].forEach(function (id) { + if (!this.entities.hasOwnProperty(id)) { + this._parentRels[child].add(id); + } + }, this); + } + }, this); + this.transients = {}; // this._childNodes is not updated, under the assumption that + // ways are always downloaded with their child nodes. + }, + // Updates calculated properties (parentWays, parentRels) for the specified change + _updateCalculated: function _updateCalculated(oldentity, entity, parentWays, parentRels) { + parentWays = parentWays || this._parentWays; + parentRels = parentRels || this._parentRels; + var type = entity && entity.type || oldentity && oldentity.type; + var removed, added, i; - var ccount = _conflicts.length; + if (type === 'way') { + // Update parentWays + if (oldentity && entity) { + removed = utilArrayDifference(oldentity.nodes, entity.nodes); + added = utilArrayDifference(entity.nodes, oldentity.nodes); + } else if (oldentity) { + removed = oldentity.nodes; + added = []; + } else if (entity) { + removed = []; + added = entity.nodes; + } - for (var i = 0; i < children.length; i++) { - var id = children[i]; - var node = graph.hasEntity(id); // remove unused childNodes.. + for (i = 0; i < removed.length; i++) { + // make a copy of prototype property, store as own property, and update.. + parentWays[removed[i]] = new Set(parentWays[removed[i]]); + parentWays[removed[i]]["delete"](oldentity.id); + } - if (targetWay.nodes.indexOf(id) === -1) { - if (node && !isUsed(node, targetWay)) { - updates.removeIds.push(id); - } + for (i = 0; i < added.length; i++) { + // make a copy of prototype property, store as own property, and update.. + parentWays[added[i]] = new Set(parentWays[added[i]]); + parentWays[added[i]].add(entity.id); + } + } else if (type === 'relation') { + // Update parentRels + // diff only on the IDs since the same entity can be a member multiple times with different roles + var oldentityMemberIDs = oldentity ? oldentity.members.map(function (m) { + return m.id; + }) : []; + var entityMemberIDs = entity ? entity.members.map(function (m) { + return m.id; + }) : []; - continue; - } // restore used childNodes.. + if (oldentity && entity) { + removed = utilArrayDifference(oldentityMemberIDs, entityMemberIDs); + added = utilArrayDifference(entityMemberIDs, oldentityMemberIDs); + } else if (oldentity) { + removed = oldentityMemberIDs; + added = []; + } else if (entity) { + removed = []; + added = entityMemberIDs; + } + for (i = 0; i < removed.length; i++) { + // make a copy of prototype property, store as own property, and update.. + parentRels[removed[i]] = new Set(parentRels[removed[i]]); + parentRels[removed[i]]["delete"](oldentity.id); + } - var local = localGraph.hasEntity(id); - var remote = remoteGraph.hasEntity(id); - var target; + for (i = 0; i < added.length; i++) { + // make a copy of prototype property, store as own property, and update.. + parentRels[added[i]] = new Set(parentRels[added[i]]); + parentRels[added[i]].add(entity.id); + } + } + }, + replace: function replace(entity) { + if (this.entities[entity.id] === entity) return this; + return this.update(function () { + this._updateCalculated(this.entities[entity.id], entity); - if (_option === 'force_remote' && remote && remote.visible) { - updates.replacements.push(remote); - } else if (_option === 'force_local' && local) { - target = osmEntity(local); - - if (remote) { - target = target.update({ - version: remote.version - }); - } + this.entities[entity.id] = entity; + }); + }, + remove: function remove(entity) { + return this.update(function () { + this._updateCalculated(entity, undefined); - updates.replacements.push(target); - } else if (_option === 'safe' && local && remote && local.version !== remote.version) { - target = osmEntity(local, { - version: remote.version - }); + this.entities[entity.id] = undefined; + }); + }, + revert: function revert(id) { + var baseEntity = this.base().entities[id]; + var headEntity = this.entities[id]; + if (headEntity === baseEntity) return this; + return this.update(function () { + this._updateCalculated(headEntity, baseEntity); - if (remote.visible) { - target = mergeLocation(remote, target); - } else { - _conflicts.push(_t('merge_remote_changes.conflict.deleted', { - user: user(remote.user) - })); - } + delete this.entities[id]; + }); + }, + update: function update() { + var graph = this.frozen ? coreGraph(this, true) : this; - if (_conflicts.length !== ccount) break; - updates.replacements.push(target); - } + for (var i = 0; i < arguments.length; i++) { + arguments[i].call(graph, graph); } - return targetWay; - } + if (this.frozen) graph.frozen = true; + return graph; + }, + // Obliterates any existing entities + load: function load(entities) { + var base = this.base(); + this.entities = Object.create(base.entities); - function updateChildren(updates, graph) { - for (var i = 0; i < updates.replacements.length; i++) { - graph = graph.replace(updates.replacements[i]); - } + for (var i in entities) { + this.entities[i] = entities[i]; - if (updates.removeIds.length) { - graph = actionDeleteMultiple(updates.removeIds)(graph); + this._updateCalculated(base.entities[i], this.entities[i]); } - return graph; + return this; } + }; - function mergeMembers(remote, target) { - if (_option === 'force_local' || fastDeepEqual(target.members, remote.members)) { - return target; - } + function osmTurn(turn) { + if (!(this instanceof osmTurn)) { + return new osmTurn(turn); + } - if (_option === 'force_remote') { - return target.update({ - members: remote.members - }); - } + Object.assign(this, turn); + } + function osmIntersection(graph, startVertexId, maxDistance) { + maxDistance = maxDistance || 30; // in meters - _conflicts.push(_t('merge_remote_changes.conflict.memberlist', { - user: user(remote.user) - })); + var vgraph = coreGraph(); // virtual graph - return target; + var i, j, k; + + function memberOfRestriction(entity) { + return graph.parentRelations(entity).some(function (r) { + return r.isRestriction(); + }); } - function mergeTags(base, remote, target) { - if (_option === 'force_local' || fastDeepEqual(target.tags, remote.tags)) { - return target; - } + function isRoad(way) { + if (way.isArea() || way.isDegenerate()) return false; + var roads = { + 'motorway': true, + 'motorway_link': true, + 'trunk': true, + 'trunk_link': true, + 'primary': true, + 'primary_link': true, + 'secondary': true, + 'secondary_link': true, + 'tertiary': true, + 'tertiary_link': true, + 'residential': true, + 'unclassified': true, + 'living_street': true, + 'service': true, + 'road': true, + 'track': true + }; + return roads[way.tags.highway]; + } - if (_option === 'force_remote') { - return target.update({ - tags: remote.tags - }); - } + var startNode = graph.entity(startVertexId); + var checkVertices = [startNode]; + var checkWays; + var vertices = []; + var vertexIds = []; + var vertex; + var ways = []; + var wayIds = []; + var way; + var nodes = []; + var node; + var parents = []; + var parent; // `actions` will store whatever actions must be performed to satisfy + // preconditions for adding a turn restriction to this intersection. + // - Remove any existing degenerate turn restrictions (missing from/to, etc) + // - Reverse oneways so that they are drawn in the forward direction + // - Split ways on key vertices - var ccount = _conflicts.length; - var o = base.tags || {}; - var a = target.tags || {}; - var b = remote.tags || {}; - var keys = utilArrayUnion(utilArrayUnion(Object.keys(o), Object.keys(a)), Object.keys(b)).filter(function (k) { - return !discardTags[k]; - }); - var tags = Object.assign({}, a); // shallow copy + var actions = []; // STEP 1: walk the graph outwards from starting vertex to search + // for more key vertices and ways to include in the intersection.. - var changed = false; + while (checkVertices.length) { + vertex = checkVertices.pop(); // check this vertex for parent ways that are roads - for (var i = 0; i < keys.length; i++) { - var k = keys[i]; + checkWays = graph.parentWays(vertex); + var hasWays = false; - if (o[k] !== b[k] && a[k] !== b[k]) { - // changed remotely.. - if (o[k] !== a[k]) { - // changed locally.. - _conflicts.push(_t('merge_remote_changes.conflict.tags', { - tag: k, - local: a[k], - remote: b[k], - user: user(remote.user) - })); - } else { - // unchanged locally, accept remote change.. - if (b.hasOwnProperty(k)) { - tags[k] = b[k]; - } else { - delete tags[k]; - } + for (i = 0; i < checkWays.length; i++) { + way = checkWays[i]; + if (!isRoad(way) && !memberOfRestriction(way)) continue; + ways.push(way); // it's a road, or it's already in a turn restriction - changed = true; - } - } - } + hasWays = true; // check the way's children for more key vertices - return changed && _conflicts.length === ccount ? target.update({ - tags: tags - }) : target; - } // `graph.base()` is the common ancestor of the two graphs. - // `localGraph` contains user's edits up to saving - // `remoteGraph` contains remote edits to modified nodes - // `graph` must be a descendent of `localGraph` and may include - // some conflict resolution actions performed on it. - // - // --- ... --- `localGraph` -- ... -- `graph` - // / - // `graph.base()` --- ... --- `remoteGraph` - // + nodes = utilArrayUniq(graph.childNodes(way)); + for (j = 0; j < nodes.length; j++) { + node = nodes[j]; + if (node === vertex) continue; // same thing - var action = function action(graph) { - var updates = { - replacements: [], - removeIds: [] - }; - var base = graph.base().entities[id]; - var local = localGraph.entity(id); - var remote = remoteGraph.entity(id); - var target = osmEntity(local, { - version: remote.version - }); // delete/undelete + if (vertices.indexOf(node) !== -1) continue; // seen it already - if (!remote.visible) { - if (_option === 'force_remote') { - return actionDeleteMultiple([id])(graph); - } else if (_option === 'force_local') { - if (target.type === 'way') { - target = mergeChildren(target, utilArrayUniq(local.nodes), updates, graph); - graph = updateChildren(updates, graph); + if (geoSphericalDistance(node.loc, startNode.loc) > maxDistance) continue; // too far from start + // a key vertex will have parents that are also roads + + var hasParents = false; + parents = graph.parentWays(node); + + for (k = 0; k < parents.length; k++) { + parent = parents[k]; + if (parent === way) continue; // same thing + + if (ways.indexOf(parent) !== -1) continue; // seen it already + + if (!isRoad(parent)) continue; // not a road + + hasParents = true; + break; } - return graph.replace(target); - } else { - _conflicts.push(_t('merge_remote_changes.conflict.deleted', { - user: user(remote.user) - })); + if (hasParents) { + checkVertices.push(node); + } + } + } - return graph; // do nothing + if (hasWays) { + vertices.push(vertex); + } + } + + vertices = utilArrayUniq(vertices); + ways = utilArrayUniq(ways); // STEP 2: Build a virtual graph containing only the entities in the intersection.. + // Everything done after this step should act on the virtual graph + // Any actions that must be performed later to the main graph go in `actions` array + + ways.forEach(function (way) { + graph.childNodes(way).forEach(function (node) { + vgraph = vgraph.replace(node); + }); + vgraph = vgraph.replace(way); + graph.parentRelations(way).forEach(function (relation) { + if (relation.isRestriction()) { + if (relation.isValidRestriction(graph)) { + vgraph = vgraph.replace(relation); + } else if (relation.isComplete(graph)) { + actions.push(actionDeleteRelation(relation.id)); + } } - } // merge + }); + }); // STEP 3: Force all oneways to be drawn in the forward direction + ways.forEach(function (w) { + var way = vgraph.entity(w.id); - if (target.type === 'node') { - target = mergeLocation(remote, target); - } else if (target.type === 'way') { - // pull in any child nodes that may not be present locally.. - graph.rebase(remoteGraph.childNodes(remote), [graph], false); - target = mergeNodes(base, remote, target); - target = mergeChildren(target, utilArrayUnion(local.nodes, remote.nodes), updates, graph); - } else if (target.type === 'relation') { - target = mergeMembers(remote, target); + if (way.tags.oneway === '-1') { + var action = actionReverse(way.id, { + reverseOneway: true + }); + actions.push(action); + vgraph = action(vgraph); } + }); // STEP 4: Split ways on key vertices - target = mergeTags(base, remote, target); + var origCount = osmEntity.id.next.way; + vertices.forEach(function (v) { + // This is an odd way to do it, but we need to find all the ways that + // will be split here, then split them one at a time to ensure that these + // actions can be replayed on the main graph exactly in the same order. + // (It is unintuitive, but the order of ways returned from graph.parentWays() + // is arbitrary, depending on how the main graph and vgraph were built) + var splitAll = actionSplit([v.id]).keepHistoryOn('first'); - if (!_conflicts.length) { - graph = updateChildren(updates, graph).replace(target); + if (!splitAll.disabled(vgraph)) { + splitAll.ways(vgraph).forEach(function (way) { + var splitOne = actionSplit([v.id]).limitWays([way.id]).keepHistoryOn('first'); + actions.push(splitOne); + vgraph = splitOne(vgraph); + }); } + }); // In here is where we should also split the intersection at nearby junction. + // for https://github.com/mapbox/iD-internal/issues/31 + // nearbyVertices.forEach(function(v) { + // }); + // Reasons why we reset the way id count here: + // 1. Continuity with way ids created by the splits so that we can replay + // these actions later if the user decides to create a turn restriction + // 2. Avoids churning way ids just by hovering over a vertex + // and displaying the turn restriction editor - return graph; - }; + osmEntity.id.next.way = origCount; // STEP 5: Update arrays to point to vgraph entities - action.withOption = function (opt) { - _option = opt; - return action; - }; + vertexIds = vertices.map(function (v) { + return v.id; + }); + vertices = []; + ways = []; + vertexIds.forEach(function (id) { + var vertex = vgraph.entity(id); + var parents = vgraph.parentWays(vertex); + vertices.push(vertex); + ways = ways.concat(parents); + }); + vertices = utilArrayUniq(vertices); + ways = utilArrayUniq(ways); + vertexIds = vertices.map(function (v) { + return v.id; + }); + wayIds = ways.map(function (w) { + return w.id; + }); // STEP 6: Update the ways with some metadata that will be useful for + // walking the intersection graph later and rendering turn arrows. - action.conflicts = function () { - return _conflicts; - }; + function withMetadata(way, vertexIds) { + var __oneWay = way.isOneWay(); // which affixes are key vertices? - return action; - } - // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/MoveNodeAction.as + var __first = vertexIds.indexOf(way.first()) !== -1; - function actionMove(moveIDs, tryDelta, projection, cache) { - var _delta = tryDelta; + var __last = vertexIds.indexOf(way.last()) !== -1; // what roles is this way eligible for? - function setupCache(graph) { - function canMove(nodeID) { - // Allow movement of any node that is in the selectedIDs list.. - if (moveIDs.indexOf(nodeID) !== -1) return true; // Allow movement of a vertex where 2 ways meet.. - var parents = graph.parentWays(graph.entity(nodeID)); - if (parents.length < 3) return true; // Restrict movement of a vertex where >2 ways meet, unless all parentWays are moving too.. + var __via = __first && __last; - var parentsMoving = parents.every(function (way) { - return cache.moving[way.id]; - }); - if (!parentsMoving) delete cache.moving[nodeID]; - return parentsMoving; - } + var __from = __first && !__oneWay || __last; - function cacheEntities(ids) { - for (var i = 0; i < ids.length; i++) { - var id = ids[i]; - if (cache.moving[id]) continue; - cache.moving[id] = true; - var entity = graph.hasEntity(id); - if (!entity) continue; + var __to = __first || __last && !__oneWay; - if (entity.type === 'node') { - cache.nodes.push(id); - cache.startLoc[id] = entity.loc; - } else if (entity.type === 'way') { - cache.ways.push(id); - cacheEntities(entity.nodes); - } else { - cacheEntities(entity.members.map(function (member) { - return member.id; - })); + return way.update({ + __first: __first, + __last: __last, + __from: __from, + __via: __via, + __to: __to, + __oneWay: __oneWay + }); + } + + ways = []; + wayIds.forEach(function (id) { + var way = withMetadata(vgraph.entity(id), vertexIds); + vgraph = vgraph.replace(way); + ways.push(way); + }); // STEP 7: Simplify - This is an iterative process where we: + // 1. Find trivial vertices with only 2 parents + // 2. trim off the leaf way from those vertices and remove from vgraph + + var keepGoing; + var removeWayIds = []; + var removeVertexIds = []; + + do { + keepGoing = false; + checkVertices = vertexIds.slice(); + + for (i = 0; i < checkVertices.length; i++) { + var vertexId = checkVertices[i]; + vertex = vgraph.hasEntity(vertexId); + + if (!vertex) { + if (vertexIds.indexOf(vertexId) !== -1) { + vertexIds.splice(vertexIds.indexOf(vertexId), 1); // stop checking this one } + + removeVertexIds.push(vertexId); + continue; } - } - function cacheIntersections(ids) { - function isEndpoint(way, id) { - return !way.isClosed() && !!way.affix(id); + parents = vgraph.parentWays(vertex); + + if (parents.length < 3) { + if (vertexIds.indexOf(vertexId) !== -1) { + vertexIds.splice(vertexIds.indexOf(vertexId), 1); // stop checking this one + } } - for (var i = 0; i < ids.length; i++) { - var id = ids[i]; // consider only intersections with 1 moved and 1 unmoved way. + if (parents.length === 2) { + // vertex with 2 parents is trivial + var a = parents[0]; + var b = parents[1]; + var aIsLeaf = a && !a.__via; + var bIsLeaf = b && !b.__via; + var leaf, survivor; - var childNodes = graph.childNodes(graph.entity(id)); + if (aIsLeaf && !bIsLeaf) { + leaf = a; + survivor = b; + } else if (!aIsLeaf && bIsLeaf) { + leaf = b; + survivor = a; + } - for (var j = 0; j < childNodes.length; j++) { - var node = childNodes[j]; - var parents = graph.parentWays(node); - if (parents.length !== 2) continue; - var moved = graph.entity(id); - var unmoved = null; + if (leaf && survivor) { + survivor = withMetadata(survivor, vertexIds); // update survivor way - for (var k = 0; k < parents.length; k++) { - var way = parents[k]; + vgraph = vgraph.replace(survivor).remove(leaf); // update graph - if (!cache.moving[way.id]) { - unmoved = way; - break; - } - } + removeWayIds.push(leaf.id); + keepGoing = true; + } + } - if (!unmoved) continue; // exclude ways that are overly connected.. + parents = vgraph.parentWays(vertex); - if (utilArrayIntersection(moved.nodes, unmoved.nodes).length > 2) continue; - if (moved.isArea() || unmoved.isArea()) continue; - cache.intersections.push({ - nodeId: node.id, - movedId: moved.id, - unmovedId: unmoved.id, - movedIsEP: isEndpoint(moved, node.id), - unmovedIsEP: isEndpoint(unmoved, node.id) - }); + if (parents.length < 2) { + // vertex is no longer a key vertex + if (vertexIds.indexOf(vertexId) !== -1) { + vertexIds.splice(vertexIds.indexOf(vertexId), 1); // stop checking this one } + + removeVertexIds.push(vertexId); + keepGoing = true; } - } - if (!cache) { - cache = {}; + if (parents.length < 1) { + // vertex is no longer attached to anything + vgraph = vgraph.remove(vertex); + } } + } while (keepGoing); - if (!cache.ok) { - cache.moving = {}; - cache.intersections = []; - cache.replacedVertex = {}; - cache.startLoc = {}; - cache.nodes = []; - cache.ways = []; - cacheEntities(moveIDs); - cacheIntersections(cache.ways); - cache.nodes = cache.nodes.filter(canMove); - cache.ok = true; - } - } // Place a vertex where the moved vertex used to be, to preserve way shape.. - // - // Start: - // b ---- e - // / \ - // / \ - // / \ - // a c - // - // * node '*' added to preserve shape - // / \ - // / b ---- e way `b,e` moved here: - // / \ - // a c + vertices = vertices.filter(function (vertex) { + return removeVertexIds.indexOf(vertex.id) === -1; + }).map(function (vertex) { + return vgraph.entity(vertex.id); + }); + ways = ways.filter(function (way) { + return removeWayIds.indexOf(way.id) === -1; + }).map(function (way) { + return vgraph.entity(way.id); + }); // OK! Here is our intersection.. + + var intersection = { + graph: vgraph, + actions: actions, + vertices: vertices, + ways: ways + }; // Get all the valid turns through this intersection given a starting way id. + // This operates on the virtual graph for everything. + // + // Basically, walk through all possible paths from starting way, + // honoring the existing turn restrictions as we go (watch out for loops!) // + // For each path found, generate and return a `osmTurn` datastructure. // + intersection.turns = function (fromWayId, maxViaWay) { + if (!fromWayId) return []; + if (!maxViaWay) maxViaWay = 0; + var vgraph = intersection.graph; + var keyVertexIds = intersection.vertices.map(function (v) { + return v.id; + }); + var start = vgraph.entity(fromWayId); + if (!start || !(start.__from || start.__via)) return []; // maxViaWay=0 from-*-to (0 vias) + // maxViaWay=1 from-*-via-*-to (1 via max) + // maxViaWay=2 from-*-via-*-via-*-to (2 vias max) - function replaceMovedVertex(nodeId, wayId, graph, delta) { - var way = graph.entity(wayId); - var moved = graph.entity(nodeId); - var movedIndex = way.nodes.indexOf(nodeId); - var len, prevIndex, nextIndex; + var maxPathLength = maxViaWay * 2 + 3; + var turns = []; + step(start); + return turns; // traverse the intersection graph and find all the valid paths - if (way.isClosed()) { - len = way.nodes.length - 1; - prevIndex = (movedIndex + len - 1) % len; - nextIndex = (movedIndex + len + 1) % len; - } else { - len = way.nodes.length; - prevIndex = movedIndex - 1; - nextIndex = movedIndex + 1; - } + function step(entity, currPath, currRestrictions, matchedRestriction) { + currPath = (currPath || []).slice(); // shallow copy - var prev = graph.hasEntity(way.nodes[prevIndex]); - var next = graph.hasEntity(way.nodes[nextIndex]); // Don't add orig vertex at endpoint.. + if (currPath.length >= maxPathLength) return; + currPath.push(entity.id); + currRestrictions = (currRestrictions || []).slice(); // shallow copy - if (!prev || !next) return graph; - var key = wayId + '_' + nodeId; - var orig = cache.replacedVertex[key]; + var i, j; - if (!orig) { - orig = osmNode(); - cache.replacedVertex[key] = orig; - cache.startLoc[orig.id] = cache.startLoc[nodeId]; - } + if (entity.type === 'node') { + var parents = vgraph.parentWays(entity); + var nextWays = []; // which ways can we step into? - var start, end; + for (i = 0; i < parents.length; i++) { + var way = parents[i]; // if next way is a oneway incoming to this vertex, skip - if (delta) { - start = projection(cache.startLoc[nodeId]); - end = projection.invert(geoVecAdd(start, delta)); - } else { - end = cache.startLoc[nodeId]; - } + if (way.__oneWay && way.nodes[0] !== entity.id) continue; // if we have seen it before (allowing for an initial u-turn), skip - orig = orig.move(end); - var angle = Math.abs(geoAngle(orig, prev, projection) - geoAngle(orig, next, projection)) * 180 / Math.PI; // Don't add orig vertex if it would just make a straight line.. + if (currPath.indexOf(way.id) !== -1 && currPath.length >= 3) continue; // Check all "current" restrictions (where we've already walked the `FROM`) - if (angle > 175 && angle < 185) return graph; // moving forward or backward along way? + var restrict = null; - var p1 = [prev.loc, orig.loc, moved.loc, next.loc].map(projection); - var p2 = [prev.loc, moved.loc, orig.loc, next.loc].map(projection); - var d1 = geoPathLength(p1); - var d2 = geoPathLength(p2); - var insertAt = d1 <= d2 ? movedIndex : nextIndex; // moving around closed loop? + for (j = 0; j < currRestrictions.length; j++) { + var restriction = currRestrictions[j]; + var f = restriction.memberByRole('from'); + var v = restriction.membersByRole('via'); + var t = restriction.memberByRole('to'); + var isOnly = /^only_/.test(restriction.tags.restriction); // Does the current path match this turn restriction? - if (way.isClosed() && insertAt === 0) insertAt = len; - way = way.addNode(orig.id, insertAt); - return graph.replace(orig).replace(way); - } // Remove duplicate vertex that might have been added by - // replaceMovedVertex. This is done after the unzorro checks. + var matchesFrom = f.id === fromWayId; + var matchesViaTo = false; + var isAlongOnlyPath = false; + if (t.id === way.id) { + // match TO + if (v.length === 1 && v[0].type === 'node') { + // match VIA node + matchesViaTo = v[0].id === entity.id && (matchesFrom && currPath.length === 2 || !matchesFrom && currPath.length > 2); + } else { + // match all VIA ways + var pathVias = []; - function removeDuplicateVertices(wayId, graph) { - var way = graph.entity(wayId); - var epsilon = 1e-6; - var prev, curr; + for (k = 2; k < currPath.length; k += 2) { + // k = 2 skips FROM + pathVias.push(currPath[k]); // (path goes way-node-way...) + } - function isInteresting(node, graph) { - return graph.parentWays(node).length > 1 || graph.parentRelations(node).length || node.hasInterestingTags(); - } + var restrictionVias = []; - for (var i = 0; i < way.nodes.length; i++) { - curr = graph.entity(way.nodes[i]); + for (k = 0; k < v.length; k++) { + if (v[k].type === 'way') { + restrictionVias.push(v[k].id); + } + } - if (prev && curr && geoVecEqual(prev.loc, curr.loc, epsilon)) { - if (!isInteresting(prev, graph)) { - way = way.removeNode(prev.id); - graph = graph.replace(way).remove(prev); - } else if (!isInteresting(curr, graph)) { - way = way.removeNode(curr.id); - graph = graph.replace(way).remove(curr); - } - } + var diff = utilArrayDifference(pathVias, restrictionVias); + matchesViaTo = !diff.length; + } + } else if (isOnly) { + for (k = 0; k < v.length; k++) { + // way doesn't match TO, but is one of the via ways along the path of an "only" + if (v[k].type === 'way' && v[k].id === way.id) { + isAlongOnlyPath = true; + break; + } + } + } - prev = curr; - } + if (matchesViaTo) { + if (isOnly) { + restrict = { + id: restriction.id, + direct: matchesFrom, + from: f.id, + only: true, + end: true + }; + } else { + restrict = { + id: restriction.id, + direct: matchesFrom, + from: f.id, + no: true, + end: true + }; + } + } else { + // indirect - caused by a different nearby restriction + if (isAlongOnlyPath) { + restrict = { + id: restriction.id, + direct: false, + from: f.id, + only: true, + end: false + }; + } else if (isOnly) { + restrict = { + id: restriction.id, + direct: false, + from: f.id, + no: true, + end: true + }; + } + } // stop looking if we find a "direct" restriction (matching FROM, VIA, TO) - return graph; - } // Reorder nodes around intersections that have moved.. - // - // Start: way1.nodes: b,e (moving) - // a - b - c ----- d way2.nodes: a,b,c,d (static) - // | vertex: b - // e isEP1: true, isEP2, false - // - // way1 `b,e` moved here: - // a ----- c = b - d - // | - // e - // - // reorder nodes way1.nodes: b,e - // a ----- c - b - d way2.nodes: a,c,b,d - // | - // e - // + if (restrict && restrict.direct) break; + } - function unZorroIntersection(intersection, graph) { - var vertex = graph.entity(intersection.nodeId); - var way1 = graph.entity(intersection.movedId); - var way2 = graph.entity(intersection.unmovedId); - var isEP1 = intersection.movedIsEP; - var isEP2 = intersection.unmovedIsEP; // don't move the vertex if it is the endpoint of both ways. + nextWays.push({ + way: way, + restrict: restrict + }); + } - if (isEP1 && isEP2) return graph; - var nodes1 = graph.childNodes(way1).filter(function (n) { - return n !== vertex; - }); - var nodes2 = graph.childNodes(way2).filter(function (n) { - return n !== vertex; - }); - if (way1.isClosed() && way1.first() === vertex.id) nodes1.push(nodes1[0]); - if (way2.isClosed() && way2.first() === vertex.id) nodes2.push(nodes2[0]); - var edge1 = !isEP1 && geoChooseEdge(nodes1, projection(vertex.loc), projection); - var edge2 = !isEP2 && geoChooseEdge(nodes2, projection(vertex.loc), projection); - var loc; // snap vertex to nearest edge (or some point between them).. + nextWays.forEach(function (nextWay) { + step(nextWay.way, currPath, currRestrictions, nextWay.restrict); + }); + } else { + // entity.type === 'way' + if (currPath.length >= 3) { + // this is a "complete" path.. + var turnPath = currPath.slice(); // shallow copy + // an indirect restriction - only include the partial path (starting at FROM) - if (!isEP1 && !isEP2) { - var epsilon = 1e-6, - maxIter = 10; + if (matchedRestriction && matchedRestriction.direct === false) { + for (i = 0; i < turnPath.length; i++) { + if (turnPath[i] === matchedRestriction.from) { + turnPath = turnPath.slice(i); + break; + } + } + } - for (var i = 0; i < maxIter; i++) { - loc = geoVecInterp(edge1.loc, edge2.loc, 0.5); - edge1 = geoChooseEdge(nodes1, projection(loc), projection); - edge2 = geoChooseEdge(nodes2, projection(loc), projection); - if (Math.abs(edge1.distance - edge2.distance) < epsilon) break; - } - } else if (!isEP1) { - loc = edge1.loc; - } else { - loc = edge2.loc; - } + var turn = pathToTurn(turnPath); - graph = graph.replace(vertex.move(loc)); // if zorro happened, reorder nodes.. + if (turn) { + if (matchedRestriction) { + turn.restrictionID = matchedRestriction.id; + turn.no = matchedRestriction.no; + turn.only = matchedRestriction.only; + turn.direct = matchedRestriction.direct; + } - if (!isEP1 && edge1.index !== way1.nodes.indexOf(vertex.id)) { - way1 = way1.removeNode(vertex.id).addNode(vertex.id, edge1.index); - graph = graph.replace(way1); - } + turns.push(osmTurn(turn)); + } - if (!isEP2 && edge2.index !== way2.nodes.indexOf(vertex.id)) { - way2 = way2.removeNode(vertex.id).addNode(vertex.id, edge2.index); - graph = graph.replace(way2); - } + if (currPath[0] === currPath[2]) return; // if we made a u-turn - stop here + } - return graph; - } + if (matchedRestriction && matchedRestriction.end) return; // don't advance any further + // which nodes can we step into? - function cleanupIntersections(graph) { - for (var i = 0; i < cache.intersections.length; i++) { - var obj = cache.intersections[i]; - graph = replaceMovedVertex(obj.nodeId, obj.movedId, graph, _delta); - graph = replaceMovedVertex(obj.nodeId, obj.unmovedId, graph, null); - graph = unZorroIntersection(obj, graph); - graph = removeDuplicateVertices(obj.movedId, graph); - graph = removeDuplicateVertices(obj.unmovedId, graph); - } + var n1 = vgraph.entity(entity.first()); + var n2 = vgraph.entity(entity.last()); + var dist = geoSphericalDistance(n1.loc, n2.loc); + var nextNodes = []; - return graph; - } // check if moving way endpoint can cross an unmoved way, if so limit delta.. + if (currPath.length > 1) { + if (dist > maxDistance) return; // the next node is too far + if (!entity.__via) return; // this way is a leaf / can't be a via + } - function limitDelta(graph) { - function moveNode(loc) { - return geoVecAdd(projection(loc), _delta); - } + if (!entity.__oneWay && // bidirectional.. + keyVertexIds.indexOf(n1.id) !== -1 && // key vertex.. + currPath.indexOf(n1.id) === -1) { + // haven't seen it yet.. + nextNodes.push(n1); // can advance to first node + } - for (var i = 0; i < cache.intersections.length; i++) { - var obj = cache.intersections[i]; // Don't limit movement if this is vertex joins 2 endpoints.. + if (keyVertexIds.indexOf(n2.id) !== -1 && // key vertex.. + currPath.indexOf(n2.id) === -1) { + // haven't seen it yet.. + nextNodes.push(n2); // can advance to last node + } - if (obj.movedIsEP && obj.unmovedIsEP) continue; // Don't limit movement if this vertex is not an endpoint anyway.. + nextNodes.forEach(function (nextNode) { + // gather restrictions FROM this way + var fromRestrictions = vgraph.parentRelations(entity).filter(function (r) { + if (!r.isRestriction()) return false; + var f = r.memberByRole('from'); + if (!f || f.id !== entity.id) return false; + var isOnly = /^only_/.test(r.tags.restriction); + if (!isOnly) return true; // `only_` restrictions only matter along the direction of the VIA - #4849 - if (!obj.movedIsEP) continue; - var node = graph.entity(obj.nodeId); - var start = projection(node.loc); - var end = geoVecAdd(start, _delta); - var movedNodes = graph.childNodes(graph.entity(obj.movedId)); - var movedPath = movedNodes.map(function (n) { - return moveNode(n.loc); - }); - var unmovedNodes = graph.childNodes(graph.entity(obj.unmovedId)); - var unmovedPath = unmovedNodes.map(function (n) { - return projection(n.loc); - }); - var hits = geoPathIntersections(movedPath, unmovedPath); + var isOnlyVia = false; + var v = r.membersByRole('via'); - for (var j = 0; i < hits.length; i++) { - if (geoVecEqual(hits[j], end)) continue; - var edge = geoChooseEdge(unmovedNodes, end, projection); - _delta = geoVecSubtract(projection(edge.loc), start); + if (v.length === 1 && v[0].type === 'node') { + // via node + isOnlyVia = v[0].id === nextNode.id; + } else { + // via way(s) + for (var i = 0; i < v.length; i++) { + if (v[i].type !== 'way') continue; + var viaWay = vgraph.entity(v[i].id); + + if (viaWay.first() === nextNode.id || viaWay.last() === nextNode.id) { + isOnlyVia = true; + break; + } + } + } + + return isOnlyVia; + }); + step(nextNode, currPath, currRestrictions.concat(fromRestrictions), false); + }); } - } - } + } // assumes path is alternating way-node-way of odd length - var action = function action(graph) { - if (_delta[0] === 0 && _delta[1] === 0) return graph; - setupCache(graph); - if (cache.intersections.length) { - limitDelta(graph); - } + function pathToTurn(path) { + if (path.length < 3) return; + var fromWayId, fromNodeId, fromVertexId; + var toWayId, toNodeId, toVertexId; + var viaWayIds, viaNodeId, isUturn; + fromWayId = path[0]; + toWayId = path[path.length - 1]; - for (var i = 0; i < cache.nodes.length; i++) { - var node = graph.entity(cache.nodes[i]); - var start = projection(node.loc); - var end = geoVecAdd(start, _delta); - graph = graph.replace(node.move(projection.invert(end))); - } + if (path.length === 3 && fromWayId === toWayId) { + // u turn + var way = vgraph.entity(fromWayId); + if (way.__oneWay) return null; + isUturn = true; + viaNodeId = fromVertexId = toVertexId = path[1]; + fromNodeId = toNodeId = adjacentNode(fromWayId, viaNodeId); + } else { + isUturn = false; + fromVertexId = path[1]; + fromNodeId = adjacentNode(fromWayId, fromVertexId); + toVertexId = path[path.length - 2]; + toNodeId = adjacentNode(toWayId, toVertexId); - if (cache.intersections.length) { - graph = cleanupIntersections(graph); - } + if (path.length === 3) { + viaNodeId = path[1]; + } else { + viaWayIds = path.filter(function (entityId) { + return entityId[0] === 'w'; + }); + viaWayIds = viaWayIds.slice(1, viaWayIds.length - 1); // remove first, last + } + } - return graph; - }; + return { + key: path.join('_'), + path: path, + from: { + node: fromNodeId, + way: fromWayId, + vertex: fromVertexId + }, + via: { + node: viaNodeId, + ways: viaWayIds + }, + to: { + node: toNodeId, + way: toWayId, + vertex: toVertexId + }, + u: isUturn + }; - action.delta = function () { - return _delta; + function adjacentNode(wayId, affixId) { + var nodes = vgraph.entity(wayId).nodes; + return affixId === nodes[0] ? nodes[1] : nodes[nodes.length - 2]; + } + } }; - return action; + return intersection; } + function osmInferRestriction(graph, turn, projection) { + var fromWay = graph.entity(turn.from.way); + var fromNode = graph.entity(turn.from.node); + var fromVertex = graph.entity(turn.from.vertex); + var toWay = graph.entity(turn.to.way); + var toNode = graph.entity(turn.to.node); + var toVertex = graph.entity(turn.to.vertex); + var fromOneWay = fromWay.tags.oneway === 'yes'; + var toOneWay = toWay.tags.oneway === 'yes'; + var angle = (geoAngle(fromVertex, fromNode, projection) - geoAngle(toVertex, toNode, projection)) * 180 / Math.PI; - function actionMoveMember(relationId, fromIndex, toIndex) { - return function (graph) { - return graph.replace(graph.entity(relationId).moveMember(fromIndex, toIndex)); - }; - } + while (angle < 0) { + angle += 360; + } - function actionMoveNode(nodeID, toLoc) { - var action = function action(graph, t) { - if (t === null || !isFinite(t)) t = 1; - t = Math.min(Math.max(+t, 0), 1); - var node = graph.entity(nodeID); - return graph.replace(node.move(geoVecInterp(node.loc, toLoc, t))); - }; + if (fromNode === toNode) { + return 'no_u_turn'; + } - action.transitionable = true; - return action; - } + if ((angle < 23 || angle > 336) && fromOneWay && toOneWay) { + return 'no_u_turn'; // wider tolerance for u-turn if both ways are oneway + } - function actionNoop() { - return function (graph) { - return graph; - }; - } + if ((angle < 40 || angle > 319) && fromOneWay && toOneWay && turn.from.vertex !== turn.to.vertex) { + return 'no_u_turn'; // even wider tolerance for u-turn if there is a via way (from !== to) + } - function actionOrthogonalize(wayID, projection, vertexID, degThresh, ep) { - var epsilon = ep || 1e-4; - var threshold = degThresh || 13; // degrees within right or straight to alter - // We test normalized dot products so we can compare as cos(angle) + if (angle < 158) { + return 'no_right_turn'; + } - var lowerThreshold = Math.cos((90 - threshold) * Math.PI / 180); - var upperThreshold = Math.cos(threshold * Math.PI / 180); + if (angle > 202) { + return 'no_left_turn'; + } - var action = function action(graph, t) { - if (t === null || !isFinite(t)) t = 1; - t = Math.min(Math.max(+t, 0), 1); - var way = graph.entity(wayID); - way = way.removeNode(''); // sanity check - remove any consecutive duplicates + return 'no_straight_on'; + } - if (way.tags.nonsquare) { - var tags = Object.assign({}, way.tags); // since we're squaring, remove indication that this is physically unsquare + function actionMergePolygon(ids, newRelationId) { + function groupEntities(graph) { + var entities = ids.map(function (id) { + return graph.entity(id); + }); + var geometryGroups = utilArrayGroupBy(entities, function (entity) { + if (entity.type === 'way' && entity.isClosed()) { + return 'closedWay'; + } else if (entity.type === 'relation' && entity.isMultipolygon()) { + return 'multipolygon'; + } else { + return 'other'; + } + }); + return Object.assign({ + closedWay: [], + multipolygon: [], + other: [] + }, geometryGroups); + } - delete tags.nonsquare; - way = way.update({ - tags: tags + var action = function action(graph) { + var entities = groupEntities(graph); // An array representing all the polygons that are part of the multipolygon. + // + // Each element is itself an array of objects with an id property, and has a + // locs property which is an array of the locations forming the polygon. + + var polygons = entities.multipolygon.reduce(function (polygons, m) { + return polygons.concat(osmJoinWays(m.members, graph)); + }, []).concat(entities.closedWay.map(function (d) { + var member = [{ + id: d.id + }]; + member.nodes = graph.childNodes(d); + return member; + })); // contained is an array of arrays of boolean values, + // where contained[j][k] is true iff the jth way is + // contained by the kth way. + + var contained = polygons.map(function (w, i) { + return polygons.map(function (d, n) { + if (i === n) return null; + return geoPolygonContainsPolygon(d.nodes.map(function (n) { + return n.loc; + }), w.nodes.map(function (n) { + return n.loc; + })); }); + }); // Sort all polygons as either outer or inner ways + + var members = []; + var outer = true; + + while (polygons.length) { + extractUncontained(polygons); + polygons = polygons.filter(isContained); + contained = contained.filter(isContained).map(filterContained); } - graph = graph.replace(way); - var isClosed = way.isClosed(); - var nodes = graph.childNodes(way).slice(); // shallow copy + function isContained(d, i) { + return contained[i].some(function (val) { + return val; + }); + } - if (isClosed) nodes.pop(); + function filterContained(d) { + return d.filter(isContained); + } - if (vertexID !== undefined) { - nodes = nodeSubset(nodes, vertexID, isClosed); - if (nodes.length !== 3) return graph; - } // note: all geometry functions here use the unclosed node/point/coord list + function extractUncontained(polygons) { + polygons.forEach(function (d, i) { + if (!isContained(d, i)) { + d.forEach(function (member) { + members.push({ + type: 'way', + id: member.id, + role: outer ? 'outer' : 'inner' + }); + }); + } + }); + outer = !outer; + } // Move all tags to one relation. + // Keep the oldest multipolygon alive if it exists. - var nodeCount = {}; - var points = []; - var corner = { - i: 0, - dotp: 1 - }; - var node, point, loc, score, motions, i, j; + var relation; - for (i = 0; i < nodes.length; i++) { - node = nodes[i]; - nodeCount[node.id] = (nodeCount[node.id] || 0) + 1; - points.push({ - id: node.id, - coord: projection(node.loc) + if (entities.multipolygon.length > 0) { + var oldestID = utilOldestID(entities.multipolygon.map(function (entity) { + return entity.id; + })); + relation = entities.multipolygon.find(function (entity) { + return entity.id === oldestID; + }); + } else { + relation = osmRelation({ + id: newRelationId, + tags: { + type: 'multipolygon' + } }); } - if (points.length === 3) { - // move only one vertex for right triangle - for (i = 0; i < 1000; i++) { - motions = points.map(calcMotion); - points[corner.i].coord = geoVecAdd(points[corner.i].coord, motions[corner.i]); - score = corner.dotp; + entities.multipolygon.forEach(function (m) { + if (m.id !== relation.id) { + relation = relation.mergeTags(m.tags); + graph = graph.remove(m); + } + }); + entities.closedWay.forEach(function (way) { + function isThisOuter(m) { + return m.id === way.id && m.role !== 'inner'; + } - if (score < epsilon) { - break; - } + if (members.some(isThisOuter)) { + relation = relation.mergeTags(way.tags); + graph = graph.replace(way.update({ + tags: {} + })); } + }); + return graph.replace(relation.update({ + members: members, + tags: utilObjectOmit(relation.tags, ['area']) + })); + }; - node = graph.entity(nodes[corner.i].id); - loc = projection.invert(points[corner.i].coord); - graph = graph.replace(node.move(geoVecInterp(node.loc, loc, t))); - } else { - var straights = []; - var simplified = []; // Remove points from nearly straight sections.. - // This produces a simplified shape to orthogonalize + action.disabled = function (graph) { + var entities = groupEntities(graph); - for (i = 0; i < points.length; i++) { - point = points[i]; - var dotp = 0; + if (entities.other.length > 0 || entities.closedWay.length + entities.multipolygon.length < 2) { + return 'not_eligible'; + } - if (isClosed || i > 0 && i < points.length - 1) { - var a = points[(i - 1 + points.length) % points.length]; - var b = points[(i + 1) % points.length]; - dotp = Math.abs(geoOrthoNormalizedDotProduct(a.coord, b.coord, point.coord)); - } + if (!entities.multipolygon.every(function (r) { + return r.isComplete(graph); + })) { + return 'incomplete_relation'; + } - if (dotp > upperThreshold) { - straights.push(point); + if (!entities.multipolygon.length) { + var sharedMultipolygons = []; + entities.closedWay.forEach(function (way, i) { + if (i === 0) { + sharedMultipolygons = graph.parentMultipolygons(way); } else { - simplified.push(point); + sharedMultipolygons = utilArrayIntersection(sharedMultipolygons, graph.parentMultipolygons(way)); } - } // Orthogonalize the simplified shape + }); + sharedMultipolygons = sharedMultipolygons.filter(function (relation) { + return relation.members.length === entities.closedWay.length; + }); + if (sharedMultipolygons.length) { + // don't create a new multipolygon if it'd be redundant + return 'not_eligible'; + } + } else if (entities.closedWay.some(function (way) { + return utilArrayIntersection(graph.parentMultipolygons(way), entities.multipolygon).length; + })) { + // don't add a way to a multipolygon again if it's already a member + return 'not_eligible'; + } + }; - var bestPoints = clonePoints(simplified); - var originalPoints = clonePoints(simplified); - score = Infinity; + return action; + } - for (i = 0; i < 1000; i++) { - motions = simplified.map(calcMotion); + var DESCRIPTORS$1 = descriptors; + var objectDefinePropertyModule = objectDefineProperty; + var regExpFlags = regexpFlags$1; + var fails$4 = fails$S; - for (j = 0; j < motions.length; j++) { - simplified[j].coord = geoVecAdd(simplified[j].coord, motions[j]); - } + var RegExpPrototype = RegExp.prototype; - var newScore = geoOrthoCalcScore(simplified, isClosed, epsilon, threshold); + var FORCED$2 = DESCRIPTORS$1 && fails$4(function () { + // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe + return Object.getOwnPropertyDescriptor(RegExpPrototype, 'flags').get.call({ dotAll: true, sticky: true }) !== 'sy'; + }); - if (newScore < score) { - bestPoints = clonePoints(simplified); - score = newScore; - } + // `RegExp.prototype.flags` getter + // https://tc39.es/ecma262/#sec-get-regexp.prototype.flags + if (FORCED$2) objectDefinePropertyModule.f(RegExpPrototype, 'flags', { + configurable: true, + get: regExpFlags + }); - if (score < epsilon) { - break; - } + var fastDeepEqual = function equal(a, b) { + if (a === b) return true; + + if (a && b && _typeof(a) == 'object' && _typeof(b) == 'object') { + if (a.constructor !== b.constructor) return false; + var length, i, keys; + + if (Array.isArray(a)) { + length = a.length; + if (length != b.length) return false; + + for (i = length; i-- !== 0;) { + if (!equal(a[i], b[i])) return false; } - var bestCoords = bestPoints.map(function (p) { - return p.coord; - }); - if (isClosed) bestCoords.push(bestCoords[0]); // move the nodes that should move + return true; + } - for (i = 0; i < bestPoints.length; i++) { - point = bestPoints[i]; + if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags; + if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf(); + if (a.toString !== Object.prototype.toString) return a.toString() === b.toString(); + keys = Object.keys(a); + length = keys.length; + if (length !== Object.keys(b).length) return false; - if (!geoVecEqual(originalPoints[i].coord, point.coord)) { - node = graph.entity(point.id); - loc = projection.invert(point.coord); - graph = graph.replace(node.move(geoVecInterp(node.loc, loc, t))); - } - } // move the nodes along straight segments + for (i = length; i-- !== 0;) { + if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false; + } + + for (i = length; i-- !== 0;) { + var key = keys[i]; + if (!equal(a[key], b[key])) return false; + } + return true; + } // true if both NaN, false otherwise - for (i = 0; i < straights.length; i++) { - point = straights[i]; - if (nodeCount[point.id] > 1) continue; // skip self-intersections - node = graph.entity(point.id); + return a !== a && b !== b; + }; - if (t === 1 && graph.parentWays(node).length === 1 && graph.parentRelations(node).length === 0 && !node.hasInterestingTags()) { - // remove uninteresting points.. - graph = actionDeleteNode(node.id)(graph); - } else { - // move interesting points to the nearest edge.. - var choice = geoVecProject(point.coord, bestCoords); + // J. W. Hunt and M. D. McIlroy, An algorithm for differential buffer + // comparison, Bell Telephone Laboratories CSTR #41 (1976) + // http://www.cs.dartmouth.edu/~doug/ + // https://en.wikipedia.org/wiki/Longest_common_subsequence_problem + // + // Expects two arrays, finds longest common sequence - if (choice) { - loc = projection.invert(choice.target); - graph = graph.replace(node.move(geoVecInterp(node.loc, loc, t))); - } - } - } - } + function LCS(buffer1, buffer2) { + var equivalenceClasses = {}; - return graph; + for (var j = 0; j < buffer2.length; j++) { + var item = buffer2[j]; - function clonePoints(array) { - return array.map(function (p) { - return { - id: p.id, - coord: [p.coord[0], p.coord[1]] - }; - }); + if (equivalenceClasses[item]) { + equivalenceClasses[item].push(j); + } else { + equivalenceClasses[item] = [j]; } + } - function calcMotion(point, i, array) { - // don't try to move the endpoints of a non-closed way. - if (!isClosed && (i === 0 || i === array.length - 1)) return [0, 0]; // don't try to move a node that appears more than once (self intersection) + var NULLRESULT = { + buffer1index: -1, + buffer2index: -1, + chain: null + }; + var candidates = [NULLRESULT]; - if (nodeCount[array[i].id] > 1) return [0, 0]; - var a = array[(i - 1 + array.length) % array.length].coord; - var origin = point.coord; - var b = array[(i + 1) % array.length].coord; - var p = geoVecSubtract(a, origin); - var q = geoVecSubtract(b, origin); - var scale = 2 * Math.min(geoVecLength(p), geoVecLength(q)); - p = geoVecNormalize(p); - q = geoVecNormalize(q); - var dotp = p[0] * q[0] + p[1] * q[1]; - var val = Math.abs(dotp); + for (var i = 0; i < buffer1.length; i++) { + var _item = buffer1[i]; + var buffer2indices = equivalenceClasses[_item] || []; + var r = 0; + var c = candidates[0]; - if (val < lowerThreshold) { - // nearly orthogonal - corner.i = i; - corner.dotp = val; - var vec = geoVecNormalize(geoVecAdd(p, q)); - return geoVecScale(vec, 0.1 * dotp * scale); + for (var jx = 0; jx < buffer2indices.length; jx++) { + var _j = buffer2indices[jx]; + var s = void 0; + + for (s = r; s < candidates.length; s++) { + if (candidates[s].buffer2index < _j && (s === candidates.length - 1 || candidates[s + 1].buffer2index > _j)) { + break; + } } - return [0, 0]; // do nothing - } - }; // if we are only orthogonalizing one vertex, - // get that vertex and the previous and next + if (s < candidates.length) { + var newCandidate = { + buffer1index: i, + buffer2index: _j, + chain: candidates[s] + }; + if (r === candidates.length) { + candidates.push(c); + } else { + candidates[r] = c; + } - function nodeSubset(nodes, vertexID, isClosed) { - var first = isClosed ? 0 : 1; - var last = isClosed ? nodes.length : nodes.length - 1; + r = s + 1; + c = newCandidate; - for (var i = first; i < last; i++) { - if (nodes[i].id === vertexID) { - return [nodes[(i - 1 + nodes.length) % nodes.length], nodes[i], nodes[(i + 1) % nodes.length]]; + if (r === candidates.length) { + break; // no point in examining further (j)s + } } } - return []; - } + candidates[r] = c; + } // At this point, we know the LCS: it's in the reverse of the + // linked-list through .chain of candidates[candidates.length - 1]. - action.disabled = function (graph) { - var way = graph.entity(wayID); - way = way.removeNode(''); // sanity check - remove any consecutive duplicates - graph = graph.replace(way); - var isClosed = way.isClosed(); - var nodes = graph.childNodes(way).slice(); // shallow copy + return candidates[candidates.length - 1]; + } // We apply the LCS to build a 'comm'-style picture of the + // offsets and lengths of mismatched chunks in the input + // buffers. This is used by diff3MergeRegions. - if (isClosed) nodes.pop(); - var allowStraightAngles = false; - if (vertexID !== undefined) { - allowStraightAngles = true; - nodes = nodeSubset(nodes, vertexID, isClosed); - if (nodes.length !== 3) return 'end_vertex'; - } + function diffIndices(buffer1, buffer2) { + var lcs = LCS(buffer1, buffer2); + var result = []; + var tail1 = buffer1.length; + var tail2 = buffer2.length; - var coords = nodes.map(function (n) { - return projection(n.loc); - }); - var score = geoOrthoCanOrthogonalize(coords, isClosed, epsilon, threshold, allowStraightAngles); + for (var candidate = lcs; candidate !== null; candidate = candidate.chain) { + var mismatchLength1 = tail1 - candidate.buffer1index - 1; + var mismatchLength2 = tail2 - candidate.buffer2index - 1; + tail1 = candidate.buffer1index; + tail2 = candidate.buffer2index; - if (score === null) { - return 'not_squarish'; - } else if (score === 0) { - return 'square_enough'; - } else { - return false; + if (mismatchLength1 || mismatchLength2) { + result.push({ + buffer1: [tail1 + 1, mismatchLength1], + buffer1Content: buffer1.slice(tail1 + 1, tail1 + 1 + mismatchLength1), + buffer2: [tail2 + 1, mismatchLength2], + buffer2Content: buffer2.slice(tail2 + 1, tail2 + 1 + mismatchLength2) + }); } - }; - - action.transitionable = true; - return action; - } + } + result.reverse(); + return result; + } // We apply the LCS to build a JSON representation of a + // independently derived from O, returns a fairly complicated + // internal representation of merge decisions it's taken. The + // interested reader may wish to consult // - // `turn` must be an `osmTurn` object - // see osm/intersection.js, pathToTurn() - // - // This specifies a restriction of type `restriction` when traveling from - // `turn.from.way` toward `turn.to.way` via `turn.via.node` OR `turn.via.ways`. - // (The action does not check that these entities form a valid intersection.) - // - // From, to, and via ways should be split before calling this action. - // (old versions of the code would split the ways here, but we no longer do it) + // Sanjeev Khanna, Keshav Kunal, and Benjamin C. Pierce. + // 'A Formal Investigation of ' In Arvind and Prasad, + // editors, Foundations of Software Technology and Theoretical + // Computer Science (FSTTCS), December 2007. // - // For testing convenience, accepts a restrictionID to assign to the new - // relation. Normally, this will be undefined and the relation will - // automatically be assigned a new ID. + // (http://www.cis.upenn.edu/~bcpierce/papers/diff3-short.pdf) // - function actionRestrictTurn(turn, restrictionType, restrictionID) { - return function (graph) { - var fromWay = graph.entity(turn.from.way); - var toWay = graph.entity(turn.to.way); - var viaNode = turn.via.node && graph.entity(turn.via.node); - var viaWays = turn.via.ways && turn.via.ways.map(function (id) { - return graph.entity(id); - }); - var members = []; - members.push({ - id: fromWay.id, - type: 'way', - role: 'from' + + function diff3MergeRegions(a, o, b) { + // "hunks" are array subsets where `a` or `b` are different from `o` + // https://www.gnu.org/software/diffutils/manual/html_node/diff3-Hunks.html + var hunks = []; + + function addHunk(h, ab) { + hunks.push({ + ab: ab, + oStart: h.buffer1[0], + oLength: h.buffer1[1], + // length of o to remove + abStart: h.buffer2[0], + abLength: h.buffer2[1] // length of a/b to insert + // abContent: (ab === 'a' ? a : b).slice(h.buffer2[0], h.buffer2[0] + h.buffer2[1]) + }); + } - if (viaNode) { - members.push({ - id: viaNode.id, - type: 'node', - role: 'via' - }); - } else if (viaWays) { - viaWays.forEach(function (viaWay) { - members.push({ - id: viaWay.id, - type: 'way', - role: 'via' - }); + diffIndices(o, a).forEach(function (item) { + return addHunk(item, 'a'); + }); + diffIndices(o, b).forEach(function (item) { + return addHunk(item, 'b'); + }); + hunks.sort(function (x, y) { + return x.oStart - y.oStart; + }); + var results = []; + var currOffset = 0; + + function advanceTo(endOffset) { + if (endOffset > currOffset) { + results.push({ + stable: true, + buffer: 'o', + bufferStart: currOffset, + bufferLength: endOffset - currOffset, + bufferContent: o.slice(currOffset, endOffset) }); + currOffset = endOffset; } + } - members.push({ - id: toWay.id, - type: 'way', - role: 'to' - }); - return graph.replace(osmRelation({ - id: restrictionID, - tags: { - type: 'restriction', - restriction: restrictionType - }, - members: members - })); - }; - } + while (hunks.length) { + var hunk = hunks.shift(); + var regionStart = hunk.oStart; + var regionEnd = hunk.oStart + hunk.oLength; + var regionHunks = [hunk]; + advanceTo(regionStart); // Try to pull next overlapping hunk into this region - function actionRevert(id) { - var action = function action(graph) { - var entity = graph.hasEntity(id), - base = graph.base().entities[id]; + while (hunks.length) { + var nextHunk = hunks[0]; + var nextHunkStart = nextHunk.oStart; + if (nextHunkStart > regionEnd) break; // no overlap - if (entity && !base) { - // entity will be removed.. - if (entity.type === 'node') { - graph.parentWays(entity).forEach(function (parent) { - parent = parent.removeNode(id); - graph = graph.replace(parent); + regionEnd = Math.max(regionEnd, nextHunkStart + nextHunk.oLength); + regionHunks.push(hunks.shift()); + } - if (parent.isDegenerate()) { - graph = actionDeleteWay(parent.id)(graph); - } + if (regionHunks.length === 1) { + // Only one hunk touches this region, meaning that there is no conflict here. + // Either `a` or `b` is inserting into a region of `o` unchanged by the other. + if (hunk.abLength > 0) { + var buffer = hunk.ab === 'a' ? a : b; + results.push({ + stable: true, + buffer: hunk.ab, + bufferStart: hunk.abStart, + bufferLength: hunk.abLength, + bufferContent: buffer.slice(hunk.abStart, hunk.abStart + hunk.abLength) }); } + } else { + // A true a/b conflict. Determine the bounds involved from `a`, `o`, and `b`. + // Effectively merge all the `a` hunks into one giant hunk, then do the + // same for the `b` hunks; then, correct for skew in the regions of `o` + // that each side changed, and report appropriate spans for the three sides. + var bounds = { + a: [a.length, -1, o.length, -1], + b: [b.length, -1, o.length, -1] + }; - graph.parentRelations(entity).forEach(function (parent) { - parent = parent.removeMembersWithID(id); - graph = graph.replace(parent); + while (regionHunks.length) { + hunk = regionHunks.shift(); + var oStart = hunk.oStart; + var oEnd = oStart + hunk.oLength; + var abStart = hunk.abStart; + var abEnd = abStart + hunk.abLength; + var _b = bounds[hunk.ab]; + _b[0] = Math.min(abStart, _b[0]); + _b[1] = Math.max(abEnd, _b[1]); + _b[2] = Math.min(oStart, _b[2]); + _b[3] = Math.max(oEnd, _b[3]); + } - if (parent.isDegenerate()) { - graph = actionDeleteRelation(parent.id)(graph); - } - }); + var aStart = bounds.a[0] + (regionStart - bounds.a[2]); + var aEnd = bounds.a[1] + (regionEnd - bounds.a[3]); + var bStart = bounds.b[0] + (regionStart - bounds.b[2]); + var bEnd = bounds.b[1] + (regionEnd - bounds.b[3]); + var result = { + stable: false, + aStart: aStart, + aLength: aEnd - aStart, + aContent: a.slice(aStart, aEnd), + oStart: regionStart, + oLength: regionEnd - regionStart, + oContent: o.slice(regionStart, regionEnd), + bStart: bStart, + bLength: bEnd - bStart, + bContent: b.slice(bStart, bEnd) + }; + results.push(result); } - return graph.revert(id); - }; + currOffset = regionEnd; + } - return action; - } + advanceTo(o.length); + return results; + } // Applies the output of diff3MergeRegions to actually + // construct the merged buffer; the returned result alternates + // between 'ok' and 'conflict' blocks. + // A "false conflict" is where `a` and `b` both change the same from `o` - function actionRotate(rotateIds, pivot, angle, projection) { - var action = function action(graph) { - return graph.update(function (graph) { - utilGetAllNodes(rotateIds, graph).forEach(function (node) { - var point = geoRotate([projection(node.loc)], angle, pivot)[0]; - graph = graph.replace(node.move(projection.invert(point))); - }); - }); - }; - return action; - } + function diff3Merge(a, o, b, options) { + var defaults = { + excludeFalseConflicts: true, + stringSeparator: /\s+/ + }; + options = Object.assign(defaults, options); + var aString = typeof a === 'string'; + var oString = typeof o === 'string'; + var bString = typeof b === 'string'; + if (aString) a = a.split(options.stringSeparator); + if (oString) o = o.split(options.stringSeparator); + if (bString) b = b.split(options.stringSeparator); + var results = []; + var regions = diff3MergeRegions(a, o, b); + var okBuffer = []; - function actionScale(ids, pivotLoc, scaleFactor, projection) { - return function (graph) { - return graph.update(function (graph) { - var point, radial; - utilGetAllNodes(ids, graph).forEach(function (node) { - point = projection(node.loc); - radial = [point[0] - pivotLoc[0], point[1] - pivotLoc[1]]; - point = [pivotLoc[0] + scaleFactor * radial[0], pivotLoc[1] + scaleFactor * radial[1]]; - graph = graph.replace(node.move(projection.invert(point))); + function flushOk() { + if (okBuffer.length) { + results.push({ + ok: okBuffer }); - }); - }; - } + } - /* Align nodes along their common axis */ + okBuffer = []; + } - function actionStraightenNodes(nodeIDs, projection) { - function positionAlongWay(a, o, b) { - return geoVecDot(a, b, o) / geoVecDot(b, b, o); - } // returns the endpoints of the long axis of symmetry of the `points` bounding rect + function isFalseConflict(a, b) { + if (a.length !== b.length) return false; + for (var i = 0; i < a.length; i++) { + if (a[i] !== b[i]) return false; + } - function getEndpoints(points) { - var ssr = geoGetSmallestSurroundingRectangle(points); // Choose line pq = axis of symmetry. - // The shape's surrounding rectangle has 2 axes of symmetry. - // Snap points to the long axis + return true; + } - var p1 = [(ssr.poly[0][0] + ssr.poly[1][0]) / 2, (ssr.poly[0][1] + ssr.poly[1][1]) / 2]; - var q1 = [(ssr.poly[2][0] + ssr.poly[3][0]) / 2, (ssr.poly[2][1] + ssr.poly[3][1]) / 2]; - var p2 = [(ssr.poly[3][0] + ssr.poly[4][0]) / 2, (ssr.poly[3][1] + ssr.poly[4][1]) / 2]; - var q2 = [(ssr.poly[1][0] + ssr.poly[2][0]) / 2, (ssr.poly[1][1] + ssr.poly[2][1]) / 2]; - var isLong = geoVecLength(p1, q1) > geoVecLength(p2, q2); + regions.forEach(function (region) { + if (region.stable) { + var _okBuffer; - if (isLong) { - return [p1, q1]; + (_okBuffer = okBuffer).push.apply(_okBuffer, _toConsumableArray(region.bufferContent)); + } else { + if (options.excludeFalseConflicts && isFalseConflict(region.aContent, region.bContent)) { + var _okBuffer2; + + (_okBuffer2 = okBuffer).push.apply(_okBuffer2, _toConsumableArray(region.aContent)); + } else { + flushOk(); + results.push({ + conflict: { + a: region.aContent, + aIndex: region.aStart, + o: region.oContent, + oIndex: region.oStart, + b: region.bContent, + bIndex: region.bStart + } + }); + } } + }); + flushOk(); + return results; + } - return [p2, q2]; - } + var lodash = {exports: {}}; - var action = function action(graph, t) { - if (t === null || !isFinite(t)) t = 1; - t = Math.min(Math.max(+t, 0), 1); - var nodes = nodeIDs.map(function (id) { - return graph.entity(id); - }); - var points = nodes.map(function (n) { - return projection(n.loc); - }); - var endpoints = getEndpoints(points); - var startPoint = endpoints[0]; - var endPoint = endpoints[1]; // Move points onto the line connecting the endpoints + (function (module, exports) { + (function () { + /** Used as a safe reference for `undefined` in pre-ES5 environments. */ + var undefined$1; + /** Used as the semantic version number. */ + + var VERSION = '4.17.21'; + /** Used as the size to enable large array optimizations. */ + + var LARGE_ARRAY_SIZE = 200; + /** Error message constants. */ + + var CORE_ERROR_TEXT = 'Unsupported core-js use. Try https://npms.io/search?q=ponyfill.', + FUNC_ERROR_TEXT = 'Expected a function', + INVALID_TEMPL_VAR_ERROR_TEXT = 'Invalid `variable` option passed into `_.template`'; + /** Used to stand-in for `undefined` hash values. */ + + var HASH_UNDEFINED = '__lodash_hash_undefined__'; + /** Used as the maximum memoize cache size. */ + + var MAX_MEMOIZE_SIZE = 500; + /** Used as the internal argument placeholder. */ + + var PLACEHOLDER = '__lodash_placeholder__'; + /** Used to compose bitmasks for cloning. */ + + var CLONE_DEEP_FLAG = 1, + CLONE_FLAT_FLAG = 2, + CLONE_SYMBOLS_FLAG = 4; + /** Used to compose bitmasks for value comparisons. */ + + var COMPARE_PARTIAL_FLAG = 1, + COMPARE_UNORDERED_FLAG = 2; + /** Used to compose bitmasks for function metadata. */ + + var WRAP_BIND_FLAG = 1, + WRAP_BIND_KEY_FLAG = 2, + WRAP_CURRY_BOUND_FLAG = 4, + WRAP_CURRY_FLAG = 8, + WRAP_CURRY_RIGHT_FLAG = 16, + WRAP_PARTIAL_FLAG = 32, + WRAP_PARTIAL_RIGHT_FLAG = 64, + WRAP_ARY_FLAG = 128, + WRAP_REARG_FLAG = 256, + WRAP_FLIP_FLAG = 512; + /** Used as default options for `_.truncate`. */ + + var DEFAULT_TRUNC_LENGTH = 30, + DEFAULT_TRUNC_OMISSION = '...'; + /** Used to detect hot functions by number of calls within a span of milliseconds. */ + + var HOT_COUNT = 800, + HOT_SPAN = 16; + /** Used to indicate the type of lazy iteratees. */ + + var LAZY_FILTER_FLAG = 1, + LAZY_MAP_FLAG = 2, + LAZY_WHILE_FLAG = 3; + /** Used as references for various `Number` constants. */ + + var INFINITY = 1 / 0, + MAX_SAFE_INTEGER = 9007199254740991, + MAX_INTEGER = 1.7976931348623157e+308, + NAN = 0 / 0; + /** Used as references for the maximum length and index of an array. */ + + var MAX_ARRAY_LENGTH = 4294967295, + MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1, + HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1; + /** Used to associate wrap methods with their bit flags. */ + + var wrapFlags = [['ary', WRAP_ARY_FLAG], ['bind', WRAP_BIND_FLAG], ['bindKey', WRAP_BIND_KEY_FLAG], ['curry', WRAP_CURRY_FLAG], ['curryRight', WRAP_CURRY_RIGHT_FLAG], ['flip', WRAP_FLIP_FLAG], ['partial', WRAP_PARTIAL_FLAG], ['partialRight', WRAP_PARTIAL_RIGHT_FLAG], ['rearg', WRAP_REARG_FLAG]]; + /** `Object#toString` result references. */ + + var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + asyncTag = '[object AsyncFunction]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + domExcTag = '[object DOMException]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + mapTag = '[object Map]', + numberTag = '[object Number]', + nullTag = '[object Null]', + objectTag = '[object Object]', + promiseTag = '[object Promise]', + proxyTag = '[object Proxy]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]', + undefinedTag = '[object Undefined]', + weakMapTag = '[object WeakMap]', + weakSetTag = '[object WeakSet]'; + var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + /** Used to match empty string literals in compiled template source. */ + + var reEmptyStringLeading = /\b__p \+= '';/g, + reEmptyStringMiddle = /\b(__p \+=) '' \+/g, + reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; + /** Used to match HTML entities and HTML characters. */ + + var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g, + reUnescapedHtml = /[&<>"']/g, + reHasEscapedHtml = RegExp(reEscapedHtml.source), + reHasUnescapedHtml = RegExp(reUnescapedHtml.source); + /** Used to match template delimiters. */ + + var reEscape = /<%-([\s\S]+?)%>/g, + reEvaluate = /<%([\s\S]+?)%>/g, + reInterpolate = /<%=([\s\S]+?)%>/g; + /** Used to match property names within property paths. */ + + var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/, + rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + /** + * Used to match `RegExp` + * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). + */ - for (var i = 0; i < points.length; i++) { - var node = nodes[i]; - var point = points[i]; - var u = positionAlongWay(point, startPoint, endPoint); - var point2 = geoVecInterp(startPoint, endPoint, u); - var loc2 = projection.invert(point2); - graph = graph.replace(node.move(geoVecInterp(node.loc, loc2, t))); - } + var reRegExpChar = /[\\^$.*+?()[\]{}|]/g, + reHasRegExpChar = RegExp(reRegExpChar.source); + /** Used to match leading whitespace. */ - return graph; - }; + var reTrimStart = /^\s+/; + /** Used to match a single whitespace character. */ - action.disabled = function (graph) { - var nodes = nodeIDs.map(function (id) { - return graph.entity(id); - }); - var points = nodes.map(function (n) { - return projection(n.loc); - }); - var endpoints = getEndpoints(points); - var startPoint = endpoints[0]; - var endPoint = endpoints[1]; - var maxDistance = 0; + var reWhitespace = /\s/; + /** Used to match wrap detail comments. */ - for (var i = 0; i < points.length; i++) { - var point = points[i]; - var u = positionAlongWay(point, startPoint, endPoint); - var p = geoVecInterp(startPoint, endPoint, u); - var dist = geoVecLength(p, point); + var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/, + reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/, + reSplitDetails = /,? & /; + /** Used to match words composed of alphanumeric characters. */ - if (!isNaN(dist) && dist > maxDistance) { - maxDistance = dist; - } - } + var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g; + /** + * Used to validate the `validate` option in `_.template` variable. + * + * Forbids characters which could potentially change the meaning of the function argument definition: + * - "()," (modification of function parameters) + * - "=" (default value) + * - "[]{}" (destructuring of function parameters) + * - "/" (beginning of a comment) + * - whitespace + */ - if (maxDistance < 0.0001) { - return 'straight_enough'; - } - }; + var reForbiddenIdentifierChars = /[()=,{}\[\]\/\s]/; + /** Used to match backslashes in property paths. */ - action.transitionable = true; - return action; - } + var reEscapeChar = /\\(\\)?/g; + /** + * Used to match + * [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components). + */ - /* - * Based on https://github.com/openstreetmap/potlatch2/net/systemeD/potlatch2/tools/Straighten.as - */ + var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; + /** Used to match `RegExp` flags from their coerced string values. */ + + var reFlags = /\w*$/; + /** Used to detect bad signed hexadecimal string values. */ + + var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; + /** Used to detect binary string values. */ + + var reIsBinary = /^0b[01]+$/i; + /** Used to detect host constructors (Safari). */ + + var reIsHostCtor = /^\[object .+?Constructor\]$/; + /** Used to detect octal string values. */ + + var reIsOctal = /^0o[0-7]+$/i; + /** Used to detect unsigned integer values. */ + + var reIsUint = /^(?:0|[1-9]\d*)$/; + /** Used to match Latin Unicode letters (excluding mathematical operators). */ + + var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g; + /** Used to ensure capturing order of template delimiters. */ + + var reNoMatch = /($^)/; + /** Used to match unescaped characters in compiled string literals. */ + + var reUnescapedString = /['\n\r\u2028\u2029\\]/g; + /** Used to compose unicode character classes. */ + + var rsAstralRange = "\\ud800-\\udfff", + rsComboMarksRange = "\\u0300-\\u036f", + reComboHalfMarksRange = "\\ufe20-\\ufe2f", + rsComboSymbolsRange = "\\u20d0-\\u20ff", + rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, + rsDingbatRange = "\\u2700-\\u27bf", + rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff', + rsMathOpRange = '\\xac\\xb1\\xd7\\xf7', + rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf', + rsPunctuationRange = "\\u2000-\\u206f", + rsSpaceRange = " \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000", + rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde', + rsVarRange = "\\ufe0e\\ufe0f", + rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange; + /** Used to compose unicode capture groups. */ + + var rsApos = "['\u2019]", + rsAstral = '[' + rsAstralRange + ']', + rsBreak = '[' + rsBreakRange + ']', + rsCombo = '[' + rsComboRange + ']', + rsDigits = '\\d+', + rsDingbat = '[' + rsDingbatRange + ']', + rsLower = '[' + rsLowerRange + ']', + rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']', + rsFitz = "\\ud83c[\\udffb-\\udfff]", + rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', + rsNonAstral = '[^' + rsAstralRange + ']', + rsRegional = "(?:\\ud83c[\\udde6-\\uddff]){2}", + rsSurrPair = "[\\ud800-\\udbff][\\udc00-\\udfff]", + rsUpper = '[' + rsUpperRange + ']', + rsZWJ = "\\u200d"; + /** Used to compose unicode regexes. */ + + var rsMiscLower = '(?:' + rsLower + '|' + rsMisc + ')', + rsMiscUpper = '(?:' + rsUpper + '|' + rsMisc + ')', + rsOptContrLower = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?', + rsOptContrUpper = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?', + reOptMod = rsModifier + '?', + rsOptVar = '[' + rsVarRange + ']?', + rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', + rsOrdLower = '\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])', + rsOrdUpper = '\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])', + rsSeq = rsOptVar + reOptMod + rsOptJoin, + rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq, + rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; + /** Used to match apostrophes. */ + + var reApos = RegExp(rsApos, 'g'); + /** + * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and + * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols). + */ - function actionStraightenWay(selectedIDs, projection) { - function positionAlongWay(a, o, b) { - return geoVecDot(a, b, o) / geoVecDot(b, b, o); - } // Return all selected ways as a continuous, ordered array of nodes + var reComboMark = RegExp(rsCombo, 'g'); + /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ + + var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); + /** Used to match complex or compound words. */ + + var reUnicodeWord = RegExp([rsUpper + '?' + rsLower + '+' + rsOptContrLower + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')', rsMiscUpper + '+' + rsOptContrUpper + '(?=' + [rsBreak, rsUpper + rsMiscLower, '$'].join('|') + ')', rsUpper + '?' + rsMiscLower + '+' + rsOptContrLower, rsUpper + '+' + rsOptContrUpper, rsOrdUpper, rsOrdLower, rsDigits, rsEmoji].join('|'), 'g'); + /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ + + var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']'); + /** Used to detect strings that need a more robust regexp to match words. */ + + var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/; + /** Used to assign default `context` object properties. */ + + var contextProps = ['Array', 'Buffer', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array', 'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object', 'Promise', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array', 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap', '_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout']; + /** Used to make template sourceURLs easier to identify. */ + + var templateCounter = -1; + /** Used to identify `toStringTag` values of typed arrays. */ + + var typedArrayTags = {}; + typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = typedArrayTags[uint32Tag] = true; + typedArrayTags[argsTag] = typedArrayTags[arrayTag] = typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = typedArrayTags[errorTag] = typedArrayTags[funcTag] = typedArrayTags[mapTag] = typedArrayTags[numberTag] = typedArrayTags[objectTag] = typedArrayTags[regexpTag] = typedArrayTags[setTag] = typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false; + /** Used to identify `toStringTag` values supported by `_.clone`. */ + + var cloneableTags = {}; + cloneableTags[argsTag] = cloneableTags[arrayTag] = cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] = cloneableTags[boolTag] = cloneableTags[dateTag] = cloneableTags[float32Tag] = cloneableTags[float64Tag] = cloneableTags[int8Tag] = cloneableTags[int16Tag] = cloneableTags[int32Tag] = cloneableTags[mapTag] = cloneableTags[numberTag] = cloneableTags[objectTag] = cloneableTags[regexpTag] = cloneableTags[setTag] = cloneableTags[stringTag] = cloneableTags[symbolTag] = cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; + cloneableTags[errorTag] = cloneableTags[funcTag] = cloneableTags[weakMapTag] = false; + /** Used to map Latin Unicode letters to basic Latin letters. */ + + var deburredLetters = { + // Latin-1 Supplement block. + '\xc0': 'A', + '\xc1': 'A', + '\xc2': 'A', + '\xc3': 'A', + '\xc4': 'A', + '\xc5': 'A', + '\xe0': 'a', + '\xe1': 'a', + '\xe2': 'a', + '\xe3': 'a', + '\xe4': 'a', + '\xe5': 'a', + '\xc7': 'C', + '\xe7': 'c', + '\xd0': 'D', + '\xf0': 'd', + '\xc8': 'E', + '\xc9': 'E', + '\xca': 'E', + '\xcb': 'E', + '\xe8': 'e', + '\xe9': 'e', + '\xea': 'e', + '\xeb': 'e', + '\xcc': 'I', + '\xcd': 'I', + '\xce': 'I', + '\xcf': 'I', + '\xec': 'i', + '\xed': 'i', + '\xee': 'i', + '\xef': 'i', + '\xd1': 'N', + '\xf1': 'n', + '\xd2': 'O', + '\xd3': 'O', + '\xd4': 'O', + '\xd5': 'O', + '\xd6': 'O', + '\xd8': 'O', + '\xf2': 'o', + '\xf3': 'o', + '\xf4': 'o', + '\xf5': 'o', + '\xf6': 'o', + '\xf8': 'o', + '\xd9': 'U', + '\xda': 'U', + '\xdb': 'U', + '\xdc': 'U', + '\xf9': 'u', + '\xfa': 'u', + '\xfb': 'u', + '\xfc': 'u', + '\xdd': 'Y', + '\xfd': 'y', + '\xff': 'y', + '\xc6': 'Ae', + '\xe6': 'ae', + '\xde': 'Th', + '\xfe': 'th', + '\xdf': 'ss', + // Latin Extended-A block. + "\u0100": 'A', + "\u0102": 'A', + "\u0104": 'A', + "\u0101": 'a', + "\u0103": 'a', + "\u0105": 'a', + "\u0106": 'C', + "\u0108": 'C', + "\u010A": 'C', + "\u010C": 'C', + "\u0107": 'c', + "\u0109": 'c', + "\u010B": 'c', + "\u010D": 'c', + "\u010E": 'D', + "\u0110": 'D', + "\u010F": 'd', + "\u0111": 'd', + "\u0112": 'E', + "\u0114": 'E', + "\u0116": 'E', + "\u0118": 'E', + "\u011A": 'E', + "\u0113": 'e', + "\u0115": 'e', + "\u0117": 'e', + "\u0119": 'e', + "\u011B": 'e', + "\u011C": 'G', + "\u011E": 'G', + "\u0120": 'G', + "\u0122": 'G', + "\u011D": 'g', + "\u011F": 'g', + "\u0121": 'g', + "\u0123": 'g', + "\u0124": 'H', + "\u0126": 'H', + "\u0125": 'h', + "\u0127": 'h', + "\u0128": 'I', + "\u012A": 'I', + "\u012C": 'I', + "\u012E": 'I', + "\u0130": 'I', + "\u0129": 'i', + "\u012B": 'i', + "\u012D": 'i', + "\u012F": 'i', + "\u0131": 'i', + "\u0134": 'J', + "\u0135": 'j', + "\u0136": 'K', + "\u0137": 'k', + "\u0138": 'k', + "\u0139": 'L', + "\u013B": 'L', + "\u013D": 'L', + "\u013F": 'L', + "\u0141": 'L', + "\u013A": 'l', + "\u013C": 'l', + "\u013E": 'l', + "\u0140": 'l', + "\u0142": 'l', + "\u0143": 'N', + "\u0145": 'N', + "\u0147": 'N', + "\u014A": 'N', + "\u0144": 'n', + "\u0146": 'n', + "\u0148": 'n', + "\u014B": 'n', + "\u014C": 'O', + "\u014E": 'O', + "\u0150": 'O', + "\u014D": 'o', + "\u014F": 'o', + "\u0151": 'o', + "\u0154": 'R', + "\u0156": 'R', + "\u0158": 'R', + "\u0155": 'r', + "\u0157": 'r', + "\u0159": 'r', + "\u015A": 'S', + "\u015C": 'S', + "\u015E": 'S', + "\u0160": 'S', + "\u015B": 's', + "\u015D": 's', + "\u015F": 's', + "\u0161": 's', + "\u0162": 'T', + "\u0164": 'T', + "\u0166": 'T', + "\u0163": 't', + "\u0165": 't', + "\u0167": 't', + "\u0168": 'U', + "\u016A": 'U', + "\u016C": 'U', + "\u016E": 'U', + "\u0170": 'U', + "\u0172": 'U', + "\u0169": 'u', + "\u016B": 'u', + "\u016D": 'u', + "\u016F": 'u', + "\u0171": 'u', + "\u0173": 'u', + "\u0174": 'W', + "\u0175": 'w', + "\u0176": 'Y', + "\u0177": 'y', + "\u0178": 'Y', + "\u0179": 'Z', + "\u017B": 'Z', + "\u017D": 'Z', + "\u017A": 'z', + "\u017C": 'z', + "\u017E": 'z', + "\u0132": 'IJ', + "\u0133": 'ij', + "\u0152": 'Oe', + "\u0153": 'oe', + "\u0149": "'n", + "\u017F": 's' + }; + /** Used to map characters to HTML entities. */ + + var htmlEscapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''' + }; + /** Used to map HTML entities to characters. */ + + var htmlUnescapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + ''': "'" + }; + /** Used to escape characters for inclusion in compiled string literals. */ + + var stringEscapes = { + '\\': '\\', + "'": "'", + '\n': 'n', + '\r': 'r', + "\u2028": 'u2028', + "\u2029": 'u2029' + }; + /** Built-in method references without a dependency on `root`. */ + var freeParseFloat = parseFloat, + freeParseInt = parseInt; + /** Detect free variable `global` from Node.js. */ - function allNodes(graph) { - var nodes = []; - var startNodes = []; - var endNodes = []; - var remainingWays = []; - var selectedWays = selectedIDs.filter(function (w) { - return graph.entity(w).type === 'way'; - }); - var selectedNodes = selectedIDs.filter(function (n) { - return graph.entity(n).type === 'node'; - }); + var freeGlobal = _typeof(commonjsGlobal) == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal; + /** Detect free variable `self`. */ - for (var i = 0; i < selectedWays.length; i++) { - var way = graph.entity(selectedWays[i]); - nodes = way.nodes.slice(0); - remainingWays.push(nodes); - startNodes.push(nodes[0]); - endNodes.push(nodes[nodes.length - 1]); - } // Remove duplicate end/startNodes (duplicate nodes cannot be at the line end, - // and need to be removed so currNode difference calculation below works) - // i.e. ["n-1", "n-1", "n-2"] => ["n-2"] + var freeSelf = (typeof self === "undefined" ? "undefined" : _typeof(self)) == 'object' && self && self.Object === Object && self; + /** Used as a reference to the global object. */ + var root = freeGlobal || freeSelf || Function('return this')(); + /** Detect free variable `exports`. */ - startNodes = startNodes.filter(function (n) { - return startNodes.indexOf(n) === startNodes.lastIndexOf(n); - }); - endNodes = endNodes.filter(function (n) { - return endNodes.indexOf(n) === endNodes.lastIndexOf(n); - }); // Choose the initial endpoint to start from + var freeExports = exports && !exports.nodeType && exports; + /** Detect free variable `module`. */ - var currNode = utilArrayDifference(startNodes, endNodes).concat(utilArrayDifference(endNodes, startNodes))[0]; - var nextWay = []; - nodes = []; // Create nested function outside of loop to avoid "function in loop" lint error + var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module; + /** Detect the popular CommonJS extension `module.exports`. */ - var getNextWay = function getNextWay(currNode, remainingWays) { - return remainingWays.filter(function (way) { - return way[0] === currNode || way[way.length - 1] === currNode; - })[0]; - }; // Add nodes to end of nodes array, until all ways are added + var moduleExports = freeModule && freeModule.exports === freeExports; + /** Detect free variable `process` from Node.js. */ + var freeProcess = moduleExports && freeGlobal.process; + /** Used to access faster Node.js helpers. */ - while (remainingWays.length) { - nextWay = getNextWay(currNode, remainingWays); - remainingWays = utilArrayDifference(remainingWays, [nextWay]); + var nodeUtil = function () { + try { + // Use `util.types` for Node.js 10+. + var types = freeModule && freeModule.require && freeModule.require('util').types; - if (nextWay[0] !== currNode) { - nextWay.reverse(); - } + if (types) { + return types; + } // Legacy `process.binding('util')` for Node.js < 10. - nodes = nodes.concat(nextWay); - currNode = nodes[nodes.length - 1]; - } // If user selected 2 nodes to straighten between, then slice nodes array to those nodes + return freeProcess && freeProcess.binding && freeProcess.binding('util'); + } catch (e) {} + }(); + /* Node.js helper references. */ - if (selectedNodes.length === 2) { - var startNodeIdx = nodes.indexOf(selectedNodes[0]); - var endNodeIdx = nodes.indexOf(selectedNodes[1]); - var sortedStartEnd = [startNodeIdx, endNodeIdx]; - sortedStartEnd.sort(function (a, b) { - return a - b; - }); - nodes = nodes.slice(sortedStartEnd[0], sortedStartEnd[1] + 1); - } - return nodes.map(function (n) { - return graph.entity(n); - }); - } + var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer, + nodeIsDate = nodeUtil && nodeUtil.isDate, + nodeIsMap = nodeUtil && nodeUtil.isMap, + nodeIsRegExp = nodeUtil && nodeUtil.isRegExp, + nodeIsSet = nodeUtil && nodeUtil.isSet, + nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray; + /*--------------------------------------------------------------------------*/ - function shouldKeepNode(node, graph) { - return graph.parentWays(node).length > 1 || graph.parentRelations(node).length || node.hasInterestingTags(); - } + /** + * A faster alternative to `Function#apply`, this function invokes `func` + * with the `this` binding of `thisArg` and the arguments of `args`. + * + * @private + * @param {Function} func The function to invoke. + * @param {*} thisArg The `this` binding of `func`. + * @param {Array} args The arguments to invoke `func` with. + * @returns {*} Returns the result of `func`. + */ - var action = function action(graph, t) { - if (t === null || !isFinite(t)) t = 1; - t = Math.min(Math.max(+t, 0), 1); - var nodes = allNodes(graph); - var points = nodes.map(function (n) { - return projection(n.loc); - }); - var startPoint = points[0]; - var endPoint = points[points.length - 1]; - var toDelete = []; - var i; + function apply(func, thisArg, args) { + switch (args.length) { + case 0: + return func.call(thisArg); - for (i = 1; i < points.length - 1; i++) { - var node = nodes[i]; - var point = points[i]; + case 1: + return func.call(thisArg, args[0]); - if (t < 1 || shouldKeepNode(node, graph)) { - var u = positionAlongWay(point, startPoint, endPoint); - var p = geoVecInterp(startPoint, endPoint, u); - var loc2 = projection.invert(p); - graph = graph.replace(node.move(geoVecInterp(node.loc, loc2, t))); - } else { - // safe to delete - if (toDelete.indexOf(node) === -1) { - toDelete.push(node); - } + case 2: + return func.call(thisArg, args[0], args[1]); + + case 3: + return func.call(thisArg, args[0], args[1], args[2]); } - } - for (i = 0; i < toDelete.length; i++) { - graph = actionDeleteNode(toDelete[i].id)(graph); + return func.apply(thisArg, args); } + /** + * A specialized version of `baseAggregator` for arrays. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} setter The function to set `accumulator` values. + * @param {Function} iteratee The iteratee to transform keys. + * @param {Object} accumulator The initial aggregated object. + * @returns {Function} Returns `accumulator`. + */ - return graph; - }; - action.disabled = function (graph) { - // check way isn't too bendy - var nodes = allNodes(graph); - var points = nodes.map(function (n) { - return projection(n.loc); - }); - var startPoint = points[0]; - var endPoint = points[points.length - 1]; - var threshold = 0.2 * geoVecLength(startPoint, endPoint); - var i; + function arrayAggregator(array, setter, iteratee, accumulator) { + var index = -1, + length = array == null ? 0 : array.length; - if (threshold === 0) { - return 'too_bendy'; + while (++index < length) { + var value = array[index]; + setter(accumulator, value, iteratee(value), array); + } + + return accumulator; } + /** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ - var maxDistance = 0; - for (i = 1; i < points.length - 1; i++) { - var point = points[i]; - var u = positionAlongWay(point, startPoint, endPoint); - var p = geoVecInterp(startPoint, endPoint, u); - var dist = geoVecLength(p, point); // to bendy if point is off by 20% of total start/end distance in projected space + function arrayEach(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length; - if (isNaN(dist) || dist > threshold) { - return 'too_bendy'; - } else if (dist > maxDistance) { - maxDistance = dist; + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } } + + return array; } + /** + * A specialized version of `_.forEachRight` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ - var keepingAllNodes = nodes.every(function (node, i) { - return i === 0 || i === nodes.length - 1 || shouldKeepNode(node, graph); - }); - if (maxDistance < 0.0001 && // Allow straightening even if already straight in order to remove extraneous nodes - keepingAllNodes) { - return 'straight_enough'; - } - }; + function arrayEachRight(array, iteratee) { + var length = array == null ? 0 : array.length; - action.transitionable = true; - return action; - } + while (length--) { + if (iteratee(array[length], length, array) === false) { + break; + } + } - // - // `turn` must be an `osmTurn` object with a `restrictionID` property. - // see osm/intersection.js, pathToTurn() - // + return array; + } + /** + * A specialized version of `_.every` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false`. + */ - function actionUnrestrictTurn(turn) { - return function (graph) { - return actionDeleteRelation(turn.restrictionID)(graph); - }; - } - /* Reflect the given area around its axis of symmetry */ + function arrayEvery(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length; - function actionReflect(reflectIds, projection) { - var _useLongAxis = true; + while (++index < length) { + if (!predicate(array[index], index, array)) { + return false; + } + } - var action = function action(graph, t) { - if (t === null || !isFinite(t)) t = 1; - t = Math.min(Math.max(+t, 0), 1); - var nodes = utilGetAllNodes(reflectIds, graph); - var points = nodes.map(function (n) { - return projection(n.loc); - }); - var ssr = geoGetSmallestSurroundingRectangle(points); // Choose line pq = axis of symmetry. - // The shape's surrounding rectangle has 2 axes of symmetry. - // Reflect across the longer axis by default. + return true; + } + /** + * A specialized version of `_.filter` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ - var p1 = [(ssr.poly[0][0] + ssr.poly[1][0]) / 2, (ssr.poly[0][1] + ssr.poly[1][1]) / 2]; - var q1 = [(ssr.poly[2][0] + ssr.poly[3][0]) / 2, (ssr.poly[2][1] + ssr.poly[3][1]) / 2]; - var p2 = [(ssr.poly[3][0] + ssr.poly[4][0]) / 2, (ssr.poly[3][1] + ssr.poly[4][1]) / 2]; - var q2 = [(ssr.poly[1][0] + ssr.poly[2][0]) / 2, (ssr.poly[1][1] + ssr.poly[2][1]) / 2]; - var p, q; - var isLong = geoVecLength(p1, q1) > geoVecLength(p2, q2); - if (_useLongAxis && isLong || !_useLongAxis && !isLong) { - p = p1; - q = q1; - } else { - p = p2; - q = q2; - } // reflect c across pq - // http://math.stackexchange.com/questions/65503/point-reflection-over-a-line + function arrayFilter(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length, + resIndex = 0, + result = []; + while (++index < length) { + var value = array[index]; - var dx = q[0] - p[0]; - var dy = q[1] - p[1]; - var a = (dx * dx - dy * dy) / (dx * dx + dy * dy); - var b = 2 * dx * dy / (dx * dx + dy * dy); + if (predicate(value, index, array)) { + result[resIndex++] = value; + } + } - for (var i = 0; i < nodes.length; i++) { - var node = nodes[i]; - var c = projection(node.loc); - var c2 = [a * (c[0] - p[0]) + b * (c[1] - p[1]) + p[0], b * (c[0] - p[0]) - a * (c[1] - p[1]) + p[1]]; - var loc2 = projection.invert(c2); - node = node.move(geoVecInterp(node.loc, loc2, t)); - graph = graph.replace(node); + return result; } + /** + * A specialized version of `_.includes` for arrays without support for + * specifying an index to search from. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ - return graph; - }; - action.useLongAxis = function (val) { - if (!arguments.length) return _useLongAxis; - _useLongAxis = val; - return action; - }; + function arrayIncludes(array, value) { + var length = array == null ? 0 : array.length; + return !!length && baseIndexOf(array, value, 0) > -1; + } + /** + * This function is like `arrayIncludes` except that it accepts a comparator. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @param {Function} comparator The comparator invoked per element. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ - action.transitionable = true; - return action; - } - function actionUpgradeTags(entityId, oldTags, replaceTags) { - return function (graph) { - var entity = graph.entity(entityId); - var tags = Object.assign({}, entity.tags); // shallow copy + function arrayIncludesWith(array, value, comparator) { + var index = -1, + length = array == null ? 0 : array.length; - var transferValue; - var semiIndex; + while (++index < length) { + if (comparator(value, array[index])) { + return true; + } + } - for (var oldTagKey in oldTags) { - if (!(oldTagKey in tags)) continue; // wildcard match + return false; + } + /** + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ - if (oldTags[oldTagKey] === '*') { - // note the value since we might need to transfer it - transferValue = tags[oldTagKey]; - delete tags[oldTagKey]; // exact match - } else if (oldTags[oldTagKey] === tags[oldTagKey]) { - delete tags[oldTagKey]; // match is within semicolon-delimited values - } else { - var vals = tags[oldTagKey].split(';').filter(Boolean); - var oldIndex = vals.indexOf(oldTags[oldTagKey]); - if (vals.length === 1 || oldIndex === -1) { - delete tags[oldTagKey]; - } else { - if (replaceTags && replaceTags[oldTagKey]) { - // replacing a value within a semicolon-delimited value, note the index - semiIndex = oldIndex; - } + function arrayMap(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length, + result = Array(length); - vals.splice(oldIndex, 1); - tags[oldTagKey] = vals.join(';'); - } + while (++index < length) { + result[index] = iteratee(array[index], index, array); } + + return result; } + /** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ - if (replaceTags) { - for (var replaceKey in replaceTags) { - var replaceValue = replaceTags[replaceKey]; - if (replaceValue === '*') { - if (tags[replaceKey] && tags[replaceKey] !== 'no') { - // allow any pre-existing value except `no` (troll tag) - continue; - } else { - // otherwise assume `yes` is okay - tags[replaceKey] = 'yes'; - } - } else if (replaceValue === '$1') { - tags[replaceKey] = transferValue; - } else { - if (tags[replaceKey] && oldTags[replaceKey] && semiIndex !== undefined) { - // don't override preexisting values - var existingVals = tags[replaceKey].split(';').filter(Boolean); + function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; - if (existingVals.indexOf(replaceValue) === -1) { - existingVals.splice(semiIndex, 0, replaceValue); - tags[replaceKey] = existingVals.join(';'); - } - } else { - tags[replaceKey] = replaceValue; - } - } + while (++index < length) { + array[offset + index] = values[index]; } - } - - return graph.replace(entity.update({ - tags: tags - })); - }; - } - function behaviorEdit(context) { - function behavior() { - context.map().minzoom(context.minEditableZoom()); - } + return array; + } + /** + * A specialized version of `_.reduce` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the first element of `array` as + * the initial value. + * @returns {*} Returns the accumulated value. + */ - behavior.off = function () { - context.map().minzoom(0); - }; - return behavior; - } + function arrayReduce(array, iteratee, accumulator, initAccum) { + var index = -1, + length = array == null ? 0 : array.length; - /* - The hover behavior adds the `.hover` class on pointerover to all elements to which - the identical datum is bound, and removes it on pointerout. + if (initAccum && length) { + accumulator = array[++index]; + } - The :hover pseudo-class is insufficient for iD's purposes because a datum's visual - representation may consist of several elements scattered throughout the DOM hierarchy. - Only one of these elements can have the :hover pseudo-class, but all of them will - have the .hover class. - */ + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } - function behaviorHover(context) { - var dispatch = dispatch$8('hover'); + return accumulator; + } + /** + * A specialized version of `_.reduceRight` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the last element of `array` as + * the initial value. + * @returns {*} Returns the accumulated value. + */ - var _selection = select(null); - var _newNodeId = null; - var _initialNodeID = null; + function arrayReduceRight(array, iteratee, accumulator, initAccum) { + var length = array == null ? 0 : array.length; - var _altDisables; + if (initAccum && length) { + accumulator = array[--length]; + } - var _ignoreVertex; + while (length--) { + accumulator = iteratee(accumulator, array[length], length, array); + } - var _targets = []; // use pointer events on supported platforms; fallback to mouse events + return accumulator; + } + /** + * A specialized version of `_.some` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ - var _pointerPrefix = 'PointerEvent' in window ? 'pointer' : 'mouse'; - function keydown(d3_event) { - if (_altDisables && d3_event.keyCode === utilKeybinding.modifierCodes.alt) { - _selection.selectAll('.hover').classed('hover-suppressed', true).classed('hover', false); + function arraySome(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length; - _selection.classed('hover-disabled', true); + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } - dispatch.call('hover', this, null); + return false; } - } + /** + * Gets the size of an ASCII `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ - function keyup(d3_event) { - if (_altDisables && d3_event.keyCode === utilKeybinding.modifierCodes.alt) { - _selection.selectAll('.hover-suppressed').classed('hover-suppressed', false).classed('hover', true); - _selection.classed('hover-disabled', false); + var asciiSize = baseProperty('length'); + /** + * Converts an ASCII `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ - dispatch.call('hover', this, _targets); + function asciiToArray(string) { + return string.split(''); } - } + /** + * Splits an ASCII `string` into an array of its words. + * + * @private + * @param {string} The string to inspect. + * @returns {Array} Returns the words of `string`. + */ - function behavior(selection) { - _selection = selection; - _targets = []; - if (_initialNodeID) { - _newNodeId = _initialNodeID; - _initialNodeID = null; - } else { - _newNodeId = null; + function asciiWords(string) { + return string.match(reAsciiWord) || []; } + /** + * The base implementation of methods like `_.findKey` and `_.findLastKey`, + * without support for iteratee shorthands, which iterates over `collection` + * using `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the found element or its key, else `undefined`. + */ - _selection.on(_pointerPrefix + 'over.hover', pointerover).on(_pointerPrefix + 'out.hover', pointerout) // treat pointerdown as pointerover for touch devices - .on(_pointerPrefix + 'down.hover', pointerover); - select(window).on(_pointerPrefix + 'up.hover pointercancel.hover', pointerout, true).on('keydown.hover', keydown).on('keyup.hover', keyup); + function baseFindKey(collection, predicate, eachFunc) { + var result; + eachFunc(collection, function (value, key, collection) { + if (predicate(value, key, collection)) { + result = key; + return false; + } + }); + return result; + } + /** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {number} fromIndex The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ - function eventTarget(d3_event) { - var datum = d3_event.target && d3_event.target.__data__; - if (_typeof(datum) !== 'object') return null; - if (!(datum instanceof osmEntity) && datum.properties && datum.properties.entity instanceof osmEntity) { - return datum.properties.entity; + function baseFindIndex(array, predicate, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 1 : -1); + + while (fromRight ? index-- : ++index < length) { + if (predicate(array[index], index, array)) { + return index; + } } - return datum; + return -1; } + /** + * The base implementation of `_.indexOf` without `fromIndex` bounds checks. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ - function pointerover(d3_event) { - // ignore mouse hovers with buttons pressed unless dragging - if (context.mode().id.indexOf('drag') === -1 && (!d3_event.pointerType || d3_event.pointerType === 'mouse') && d3_event.buttons) return; - var target = eventTarget(d3_event); - - if (target && _targets.indexOf(target) === -1) { - _targets.push(target); - updateHover(d3_event, _targets); - } + function baseIndexOf(array, value, fromIndex) { + return value === value ? strictIndexOf(array, value, fromIndex) : baseFindIndex(array, baseIsNaN, fromIndex); } + /** + * This function is like `baseIndexOf` except that it accepts a comparator. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @param {Function} comparator The comparator invoked per element. + * @returns {number} Returns the index of the matched value, else `-1`. + */ - function pointerout(d3_event) { - var target = eventTarget(d3_event); - - var index = _targets.indexOf(target); - if (index !== -1) { - _targets.splice(index); + function baseIndexOfWith(array, value, fromIndex, comparator) { + var index = fromIndex - 1, + length = array.length; - updateHover(d3_event, _targets); + while (++index < length) { + if (comparator(array[index], value)) { + return index; + } } - } - function allowsVertex(d) { - return d.geometry(context.graph()) === 'vertex' || _mainPresetIndex.allowsVertex(d, context.graph()); + return -1; } + /** + * The base implementation of `_.isNaN` without support for number objects. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + */ - function modeAllowsHover(target) { - var mode = context.mode(); - if (mode.id === 'add-point') { - return mode.preset.matchGeometry('vertex') || target.type !== 'way' && target.geometry(context.graph()) !== 'vertex'; - } + function baseIsNaN(value) { + return value !== value; + } + /** + * The base implementation of `_.mean` and `_.meanBy` without support for + * iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {number} Returns the mean. + */ - return true; + + function baseMean(array, iteratee) { + var length = array == null ? 0 : array.length; + return length ? baseSum(array, iteratee) / length : NAN; } + /** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new accessor function. + */ - function updateHover(d3_event, targets) { - _selection.selectAll('.hover').classed('hover', false); - _selection.selectAll('.hover-suppressed').classed('hover-suppressed', false); + function baseProperty(key) { + return function (object) { + return object == null ? undefined$1 : object[key]; + }; + } + /** + * The base implementation of `_.propertyOf` without support for deep paths. + * + * @private + * @param {Object} object The object to query. + * @returns {Function} Returns the new accessor function. + */ - var mode = context.mode(); - if (!_newNodeId && (mode.id === 'draw-line' || mode.id === 'draw-area')) { - var node = targets.find(function (target) { - return target instanceof osmEntity && target.type === 'node'; - }); - _newNodeId = node && node.id; - } + function basePropertyOf(object) { + return function (key) { + return object == null ? undefined$1 : object[key]; + }; + } + /** + * The base implementation of `_.reduce` and `_.reduceRight`, without support + * for iteratee shorthands, which iterates over `collection` using `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} accumulator The initial value. + * @param {boolean} initAccum Specify using the first or last element of + * `collection` as the initial value. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the accumulated value. + */ - targets = targets.filter(function (datum) { - if (datum instanceof osmEntity) { - // If drawing a way, don't hover on a node that was just placed. #3974 - return datum.id !== _newNodeId && (datum.type !== 'node' || !_ignoreVertex || allowsVertex(datum)) && modeAllowsHover(datum); - } - return true; + function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) { + eachFunc(collection, function (value, index, collection) { + accumulator = initAccum ? (initAccum = false, value) : iteratee(accumulator, value, index, collection); }); - var selector = ''; + return accumulator; + } + /** + * The base implementation of `_.sortBy` which uses `comparer` to define the + * sort order of `array` and replaces criteria objects with their corresponding + * values. + * + * @private + * @param {Array} array The array to sort. + * @param {Function} comparer The function to define sort order. + * @returns {Array} Returns `array`. + */ - for (var i in targets) { - var datum = targets[i]; // What are we hovering over? - if (datum.__featurehash__) { - // hovering custom data - selector += ', .data' + datum.__featurehash__; - } else if (datum instanceof QAItem) { - selector += ', .' + datum.service + '.itemId-' + datum.id; - } else if (datum instanceof osmNote) { - selector += ', .note-' + datum.id; - } else if (datum instanceof osmEntity) { - selector += ', .' + datum.id; + function baseSortBy(array, comparer) { + var length = array.length; + array.sort(comparer); - if (datum.type === 'relation') { - for (var j in datum.members) { - selector += ', .' + datum.members[j].id; - } - } - } + while (length--) { + array[length] = array[length].value; } - var suppressed = _altDisables && d3_event && d3_event.altKey; + return array; + } + /** + * The base implementation of `_.sum` and `_.sumBy` without support for + * iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {number} Returns the sum. + */ - if (selector.trim().length) { - // remove the first comma - selector = selector.slice(1); - _selection.selectAll(selector).classed(suppressed ? 'hover-suppressed' : 'hover', true); + function baseSum(array, iteratee) { + var result, + index = -1, + length = array.length; + + while (++index < length) { + var current = iteratee(array[index]); + + if (current !== undefined$1) { + result = result === undefined$1 ? current : result + current; + } } - dispatch.call('hover', this, !suppressed && targets); + return result; } - } + /** + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. + * + * @private + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. + */ - behavior.off = function (selection) { - selection.selectAll('.hover').classed('hover', false); - selection.selectAll('.hover-suppressed').classed('hover-suppressed', false); - selection.classed('hover-disabled', false); - selection.on(_pointerPrefix + 'over.hover', null).on(_pointerPrefix + 'out.hover', null).on(_pointerPrefix + 'down.hover', null); - select(window).on(_pointerPrefix + 'up.hover pointercancel.hover', null, true).on('keydown.hover', null).on('keyup.hover', null); - }; - behavior.altDisables = function (val) { - if (!arguments.length) return _altDisables; - _altDisables = val; - return behavior; - }; + function baseTimes(n, iteratee) { + var index = -1, + result = Array(n); - behavior.ignoreVertex = function (val) { - if (!arguments.length) return _ignoreVertex; - _ignoreVertex = val; - return behavior; - }; + while (++index < n) { + result[index] = iteratee(index); + } - behavior.initialNodeID = function (nodeId) { - _initialNodeID = nodeId; - return behavior; - }; + return result; + } + /** + * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array + * of key-value pairs for `object` corresponding to the property names of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the key-value pairs. + */ - return utilRebind(behavior, dispatch, 'on'); - } - var _disableSpace = false; - var _lastSpace = null; - function behaviorDraw(context) { - var dispatch = dispatch$8('move', 'down', 'downcancel', 'click', 'clickWay', 'clickNode', 'undo', 'cancel', 'finish'); - var keybinding = utilKeybinding('draw'); + function baseToPairs(object, props) { + return arrayMap(props, function (key) { + return [key, object[key]]; + }); + } + /** + * The base implementation of `_.trim`. + * + * @private + * @param {string} string The string to trim. + * @returns {string} Returns the trimmed string. + */ - var _hover = behaviorHover(context).altDisables(true).ignoreVertex(true).on('hover', context.ui().sidebar.hover); - var _edit = behaviorEdit(context); + function baseTrim(string) { + return string ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, '') : string; + } + /** + * The base implementation of `_.unary` without support for storing metadata. + * + * @private + * @param {Function} func The function to cap arguments for. + * @returns {Function} Returns the new capped function. + */ - var _closeTolerance = 4; - var _tolerance = 12; - var _mouseLeave = false; - var _lastMouse = null; - var _lastPointerUpEvent; + function baseUnary(func) { + return function (value) { + return func(value); + }; + } + /** + * The base implementation of `_.values` and `_.valuesIn` which creates an + * array of `object` property values corresponding to the property names + * of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the array of property values. + */ - var _downPointer; // use pointer events on supported platforms; fallback to mouse events + function baseValues(object, props) { + return arrayMap(props, function (key) { + return object[key]; + }); + } + /** + * Checks if a `cache` value for `key` exists. + * + * @private + * @param {Object} cache The cache to query. + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ - var _pointerPrefix = 'PointerEvent' in window ? 'pointer' : 'mouse'; // related code - // - `mode/drag_node.js` `datum()` + function cacheHas(cache, key) { + return cache.has(key); + } + /** + * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol + * that is not found in the character symbols. + * + * @private + * @param {Array} strSymbols The string symbols to inspect. + * @param {Array} chrSymbols The character symbols to find. + * @returns {number} Returns the index of the first unmatched string symbol. + */ - function datum(d3_event) { - var mode = context.mode(); - var isNote = mode && mode.id.indexOf('note') !== -1; - if (d3_event.altKey || isNote) return {}; - var element; - if (d3_event.type === 'keydown') { - element = _lastMouse && _lastMouse.target; - } else { - element = d3_event.target; - } // When drawing, snap only to touch targets.. - // (this excludes area fills and active drawing elements) + function charsStartIndex(strSymbols, chrSymbols) { + var index = -1, + length = strSymbols.length; + while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} - var d = element.__data__; - return d && d.properties && d.properties.target ? d : {}; - } + return index; + } + /** + * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol + * that is not found in the character symbols. + * + * @private + * @param {Array} strSymbols The string symbols to inspect. + * @param {Array} chrSymbols The character symbols to find. + * @returns {number} Returns the index of the last unmatched string symbol. + */ - function pointerdown(d3_event) { - if (_downPointer) return; - var pointerLocGetter = utilFastMouse(this); - _downPointer = { - id: d3_event.pointerId || 'mouse', - pointerLocGetter: pointerLocGetter, - downTime: +new Date(), - downLoc: pointerLocGetter(d3_event) - }; - dispatch.call('down', this, d3_event, datum(d3_event)); - } - function pointerup(d3_event) { - if (!_downPointer || _downPointer.id !== (d3_event.pointerId || 'mouse')) return; - var downPointer = _downPointer; - _downPointer = null; - _lastPointerUpEvent = d3_event; - if (downPointer.isCancelled) return; - var t2 = +new Date(); - var p2 = downPointer.pointerLocGetter(d3_event); - var dist = geoVecLength(downPointer.downLoc, p2); + function charsEndIndex(strSymbols, chrSymbols) { + var index = strSymbols.length; - if (dist < _closeTolerance || dist < _tolerance && t2 - downPointer.downTime < 500) { - // Prevent a quick second click - select(window).on('click.draw-block', function () { - d3_event.stopPropagation(); - }, true); - context.map().dblclickZoomEnable(false); - window.setTimeout(function () { - context.map().dblclickZoomEnable(true); - select(window).on('click.draw-block', null); - }, 500); - click(d3_event, p2); + while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} + + return index; } - } + /** + * Gets the number of `placeholder` occurrences in `array`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} placeholder The placeholder to search for. + * @returns {number} Returns the placeholder count. + */ - function pointermove(d3_event) { - if (_downPointer && _downPointer.id === (d3_event.pointerId || 'mouse') && !_downPointer.isCancelled) { - var p2 = _downPointer.pointerLocGetter(d3_event); - var dist = geoVecLength(_downPointer.downLoc, p2); + function countHolders(array, placeholder) { + var length = array.length, + result = 0; - if (dist >= _closeTolerance) { - _downPointer.isCancelled = true; - dispatch.call('downcancel', this); + while (length--) { + if (array[length] === placeholder) { + ++result; + } } + + return result; } + /** + * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A + * letters to basic Latin letters. + * + * @private + * @param {string} letter The matched letter to deburr. + * @returns {string} Returns the deburred letter. + */ - if (d3_event.pointerType && d3_event.pointerType !== 'mouse' || d3_event.buttons || _downPointer) return; // HACK: Mobile Safari likes to send one or more `mouse` type pointermove - // events immediately after non-mouse pointerup events; detect and ignore them. - if (_lastPointerUpEvent && _lastPointerUpEvent.pointerType !== 'mouse' && d3_event.timeStamp - _lastPointerUpEvent.timeStamp < 100) return; - _lastMouse = d3_event; - dispatch.call('move', this, d3_event, datum(d3_event)); - } + var deburrLetter = basePropertyOf(deburredLetters); + /** + * Used by `_.escape` to convert characters to HTML entities. + * + * @private + * @param {string} chr The matched character to escape. + * @returns {string} Returns the escaped character. + */ - function pointercancel(d3_event) { - if (_downPointer && _downPointer.id === (d3_event.pointerId || 'mouse')) { - if (!_downPointer.isCancelled) { - dispatch.call('downcancel', this); - } + var escapeHtmlChar = basePropertyOf(htmlEscapes); + /** + * Used by `_.template` to escape characters for inclusion in compiled string literals. + * + * @private + * @param {string} chr The matched character to escape. + * @returns {string} Returns the escaped character. + */ - _downPointer = null; + function escapeStringChar(chr) { + return '\\' + stringEscapes[chr]; } - } + /** + * Gets the value at `key` of `object`. + * + * @private + * @param {Object} [object] The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ - function mouseenter() { - _mouseLeave = false; - } - function mouseleave() { - _mouseLeave = true; - } + function getValue(object, key) { + return object == null ? undefined$1 : object[key]; + } + /** + * Checks if `string` contains Unicode symbols. + * + * @private + * @param {string} string The string to inspect. + * @returns {boolean} Returns `true` if a symbol is found, else `false`. + */ - function allowsVertex(d) { - return d.geometry(context.graph()) === 'vertex' || _mainPresetIndex.allowsVertex(d, context.graph()); - } // related code - // - `mode/drag_node.js` `doMove()` - // - `behavior/draw.js` `click()` - // - `behavior/draw_way.js` `move()` + function hasUnicode(string) { + return reHasUnicode.test(string); + } + /** + * Checks if `string` contains a word composed of Unicode symbols. + * + * @private + * @param {string} string The string to inspect. + * @returns {boolean} Returns `true` if a word is found, else `false`. + */ - function click(d3_event, loc) { - var d = datum(d3_event); - var target = d && d.properties && d.properties.entity; - var mode = context.mode(); - if (target && target.type === 'node' && allowsVertex(target)) { - // Snap to a node - dispatch.call('clickNode', this, target, d); - return; - } else if (target && target.type === 'way' && (mode.id !== 'add-point' || mode.preset.matchGeometry('vertex'))) { - // Snap to a way - var choice = geoChooseEdge(context.graph().childNodes(target), loc, context.projection, context.activeID()); + function hasUnicodeWord(string) { + return reHasUnicodeWord.test(string); + } + /** + * Converts `iterator` to an array. + * + * @private + * @param {Object} iterator The iterator to convert. + * @returns {Array} Returns the converted array. + */ - if (choice) { - var edge = [target.nodes[choice.index - 1], target.nodes[choice.index]]; - dispatch.call('clickWay', this, choice.loc, edge, d); - return; + + function iteratorToArray(iterator) { + var data, + result = []; + + while (!(data = iterator.next()).done) { + result.push(data.value); } - } else if (mode.id !== 'add-point' || mode.preset.matchGeometry('point')) { - var locLatLng = context.projection.invert(loc); - dispatch.call('click', this, locLatLng, d); + + return result; } - } // treat a spacebar press like a click + /** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ - function space(d3_event) { - d3_event.preventDefault(); - d3_event.stopPropagation(); - var currSpace = context.map().mouse(); + function mapToArray(map) { + var index = -1, + result = Array(map.size); + map.forEach(function (value, key) { + result[++index] = [key, value]; + }); + return result; + } + /** + * Creates a unary function that invokes `func` with its argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ - if (_disableSpace && _lastSpace) { - var dist = geoVecLength(_lastSpace, currSpace); - if (dist > _tolerance) { - _disableSpace = false; - } + function overArg(func, transform) { + return function (arg) { + return func(transform(arg)); + }; } + /** + * Replaces all `placeholder` elements in `array` with an internal placeholder + * and returns an array of their indexes. + * + * @private + * @param {Array} array The array to modify. + * @param {*} placeholder The placeholder to replace. + * @returns {Array} Returns the new array of placeholder indexes. + */ - if (_disableSpace || _mouseLeave || !_lastMouse) return; // user must move mouse or release space bar to allow another click - _lastSpace = currSpace; - _disableSpace = true; - select(window).on('keyup.space-block', function () { - d3_event.preventDefault(); - d3_event.stopPropagation(); - _disableSpace = false; - select(window).on('keyup.space-block', null); - }); // get the current mouse position + function replaceHolders(array, placeholder) { + var index = -1, + length = array.length, + resIndex = 0, + result = []; - var loc = context.map().mouse() || // or the map center if the mouse has never entered the map - context.projection(context.map().center()); - click(d3_event, loc); - } + while (++index < length) { + var value = array[index]; - function backspace(d3_event) { - d3_event.preventDefault(); - dispatch.call('undo'); - } - - function del(d3_event) { - d3_event.preventDefault(); - dispatch.call('cancel'); - } + if (value === placeholder || value === PLACEHOLDER) { + array[index] = PLACEHOLDER; + result[resIndex++] = index; + } + } - function ret(d3_event) { - d3_event.preventDefault(); - dispatch.call('finish'); - } + return result; + } + /** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ - function behavior(selection) { - context.install(_hover); - context.install(_edit); - _downPointer = null; - keybinding.on('⌫', backspace).on('⌦', del).on('⎋', ret).on('↩', ret).on('space', space).on('⌥space', space); - selection.on('mouseenter.draw', mouseenter).on('mouseleave.draw', mouseleave).on(_pointerPrefix + 'down.draw', pointerdown).on(_pointerPrefix + 'move.draw', pointermove); - select(window).on(_pointerPrefix + 'up.draw', pointerup, true).on('pointercancel.draw', pointercancel, true); - select(document).call(keybinding); - return behavior; - } - behavior.off = function (selection) { - context.ui().sidebar.hover.cancel(); - context.uninstall(_hover); - context.uninstall(_edit); - selection.on('mouseenter.draw', null).on('mouseleave.draw', null).on(_pointerPrefix + 'down.draw', null).on(_pointerPrefix + 'move.draw', null); - select(window).on(_pointerPrefix + 'up.draw', null).on('pointercancel.draw', null); // note: keyup.space-block, click.draw-block should remain + function setToArray(set) { + var index = -1, + result = Array(set.size); + set.forEach(function (value) { + result[++index] = value; + }); + return result; + } + /** + * Converts `set` to its value-value pairs. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the value-value pairs. + */ - select(document).call(keybinding.unbind); - }; - behavior.hover = function () { - return _hover; - }; + function setToPairs(set) { + var index = -1, + result = Array(set.size); + set.forEach(function (value) { + result[++index] = [value, value]; + }); + return result; + } + /** + * A specialized version of `_.indexOf` which performs strict equality + * comparisons of values, i.e. `===`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ - return utilRebind(behavior, dispatch, 'on'); - } - function initRange(domain, range) { - switch (arguments.length) { - case 0: - break; + function strictIndexOf(array, value, fromIndex) { + var index = fromIndex - 1, + length = array.length; - case 1: - this.range(domain); - break; + while (++index < length) { + if (array[index] === value) { + return index; + } + } - default: - this.range(range).domain(domain); - break; - } + return -1; + } + /** + * A specialized version of `_.lastIndexOf` which performs strict equality + * comparisons of values, i.e. `===`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ - return this; - } - function constants(x) { - return function () { - return x; - }; - } + function strictLastIndexOf(array, value, fromIndex) { + var index = fromIndex + 1; - function number(x) { - return +x; - } + while (index--) { + if (array[index] === value) { + return index; + } + } - var unit = [0, 1]; - function identity$1(x) { - return x; - } + return index; + } + /** + * Gets the number of symbols in `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the string size. + */ - function normalize(a, b) { - return (b -= a = +a) ? function (x) { - return (x - a) / b; - } : constants(isNaN(b) ? NaN : 0.5); - } - function clamper(a, b) { - var t; - if (a > b) t = a, a = b, b = t; - return function (x) { - return Math.max(a, Math.min(b, x)); - }; - } // normalize(a, b)(x) takes a domain value x in [a,b] and returns the corresponding parameter t in [0,1]. - // interpolate(a, b)(t) takes a parameter t in [0,1] and returns the corresponding range value x in [a,b]. + function stringSize(string) { + return hasUnicode(string) ? unicodeSize(string) : asciiSize(string); + } + /** + * Converts `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ - function bimap(domain, range, interpolate) { - var d0 = domain[0], - d1 = domain[1], - r0 = range[0], - r1 = range[1]; - if (d1 < d0) d0 = normalize(d1, d0), r0 = interpolate(r1, r0);else d0 = normalize(d0, d1), r0 = interpolate(r0, r1); - return function (x) { - return r0(d0(x)); - }; - } + function stringToArray(string) { + return hasUnicode(string) ? unicodeToArray(string) : asciiToArray(string); + } + /** + * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace + * character of `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the index of the last non-whitespace character. + */ - function polymap(domain, range, interpolate) { - var j = Math.min(domain.length, range.length) - 1, - d = new Array(j), - r = new Array(j), - i = -1; // Reverse descending domains. - if (domain[j] < domain[0]) { - domain = domain.slice().reverse(); - range = range.slice().reverse(); - } + function trimmedEndIndex(string) { + var index = string.length; - while (++i < j) { - d[i] = normalize(domain[i], domain[i + 1]); - r[i] = interpolate(range[i], range[i + 1]); - } + while (index-- && reWhitespace.test(string.charAt(index))) {} - return function (x) { - var i = bisectRight(domain, x, 1, j) - 1; - return r[i](d[i](x)); - }; - } + return index; + } + /** + * Used by `_.unescape` to convert HTML entities to characters. + * + * @private + * @param {string} chr The matched character to unescape. + * @returns {string} Returns the unescaped character. + */ - function copy(source, target) { - return target.domain(source.domain()).range(source.range()).interpolate(source.interpolate()).clamp(source.clamp()).unknown(source.unknown()); - } - function transformer() { - var domain = unit, - range = unit, - interpolate = interpolate$1, - transform, - untransform, - unknown, - clamp = identity$1, - piecewise, - output, - input; - function rescale() { - var n = Math.min(domain.length, range.length); - if (clamp !== identity$1) clamp = clamper(domain[0], domain[n - 1]); - piecewise = n > 2 ? polymap : bimap; - output = input = null; - return scale; - } + var unescapeHtmlChar = basePropertyOf(htmlUnescapes); + /** + * Gets the size of a Unicode `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ - function scale(x) { - return x == null || isNaN(x = +x) ? unknown : (output || (output = piecewise(domain.map(transform), range, interpolate)))(transform(clamp(x))); - } + function unicodeSize(string) { + var result = reUnicode.lastIndex = 0; - scale.invert = function (y) { - return clamp(untransform((input || (input = piecewise(range, domain.map(transform), d3_interpolateNumber)))(y))); - }; + while (reUnicode.test(string)) { + ++result; + } - scale.domain = function (_) { - return arguments.length ? (domain = Array.from(_, number), rescale()) : domain.slice(); - }; + return result; + } + /** + * Converts a Unicode `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ - scale.range = function (_) { - return arguments.length ? (range = Array.from(_), rescale()) : range.slice(); - }; - scale.rangeRound = function (_) { - return range = Array.from(_), interpolate = interpolateRound, rescale(); - }; + function unicodeToArray(string) { + return string.match(reUnicode) || []; + } + /** + * Splits a Unicode `string` into an array of its words. + * + * @private + * @param {string} The string to inspect. + * @returns {Array} Returns the words of `string`. + */ - scale.clamp = function (_) { - return arguments.length ? (clamp = _ ? true : identity$1, rescale()) : clamp !== identity$1; - }; - scale.interpolate = function (_) { - return arguments.length ? (interpolate = _, rescale()) : interpolate; - }; + function unicodeWords(string) { + return string.match(reUnicodeWord) || []; + } + /*--------------------------------------------------------------------------*/ - scale.unknown = function (_) { - return arguments.length ? (unknown = _, scale) : unknown; - }; + /** + * Create a new pristine `lodash` function using the `context` object. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category Util + * @param {Object} [context=root] The context object. + * @returns {Function} Returns a new `lodash` function. + * @example + * + * _.mixin({ 'foo': _.constant('foo') }); + * + * var lodash = _.runInContext(); + * lodash.mixin({ 'bar': lodash.constant('bar') }); + * + * _.isFunction(_.foo); + * // => true + * _.isFunction(_.bar); + * // => false + * + * lodash.isFunction(lodash.foo); + * // => false + * lodash.isFunction(lodash.bar); + * // => true + * + * // Create a suped-up `defer` in Node.js. + * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer; + */ - return function (t, u) { - transform = t, untransform = u; - return rescale(); - }; - } - function continuous() { - return transformer()(identity$1, identity$1); - } - function formatDecimal (x) { - return Math.abs(x = Math.round(x)) >= 1e21 ? x.toLocaleString("en").replace(/,/g, "") : x.toString(10); - } // Computes the decimal coefficient and exponent of the specified number x with - // significant digits p, where x is positive and p is in [1, 21] or undefined. - // For example, formatDecimalParts(1.23) returns ["123", 0]. + var runInContext = function runInContext(context) { + context = context == null ? root : _.defaults(root.Object(), context, _.pick(root, contextProps)); + /** Built-in constructor references. */ - function formatDecimalParts(x, p) { - if ((i = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf("e")) < 0) return null; // NaN, ±Infinity + var Array = context.Array, + Date = context.Date, + Error = context.Error, + Function = context.Function, + Math = context.Math, + Object = context.Object, + RegExp = context.RegExp, + String = context.String, + TypeError = context.TypeError; + /** Used for built-in method references. */ - var i, - coefficient = x.slice(0, i); // The string returned by toExponential either has the form \d\.\d+e[-+]\d+ - // (e.g., 1.2e+3) or the form \de[-+]\d+ (e.g., 1e+3). + var arrayProto = Array.prototype, + funcProto = Function.prototype, + objectProto = Object.prototype; + /** Used to detect overreaching core-js shims. */ - return [coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coefficient, +x.slice(i + 1)]; - } + var coreJsData = context['__core-js_shared__']; + /** Used to resolve the decompiled source of functions. */ - function exponent (x) { - return x = formatDecimalParts(Math.abs(x)), x ? x[1] : NaN; - } + var funcToString = funcProto.toString; + /** Used to check objects for own properties. */ - function formatGroup (grouping, thousands) { - return function (value, width) { - var i = value.length, - t = [], - j = 0, - g = grouping[0], - length = 0; + var hasOwnProperty = objectProto.hasOwnProperty; + /** Used to generate unique IDs. */ - while (i > 0 && g > 0) { - if (length + g + 1 > width) g = Math.max(1, width - length); - t.push(value.substring(i -= g, i + g)); - if ((length += g + 1) > width) break; - g = grouping[j = (j + 1) % grouping.length]; - } + var idCounter = 0; + /** Used to detect methods masquerading as native. */ - return t.reverse().join(thousands); - }; - } + var maskSrcKey = function () { + var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); + return uid ? 'Symbol(src)_1.' + uid : ''; + }(); + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ - function formatNumerals (numerals) { - return function (value) { - return value.replace(/[0-9]/g, function (i) { - return numerals[+i]; - }); - }; - } - // [[fill]align][sign][symbol][0][width][,][.precision][~][type] - var re = /^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i; - function formatSpecifier(specifier) { - if (!(match = re.exec(specifier))) throw new Error("invalid format: " + specifier); - var match; - return new FormatSpecifier({ - fill: match[1], - align: match[2], - sign: match[3], - symbol: match[4], - zero: match[5], - width: match[6], - comma: match[7], - precision: match[8] && match[8].slice(1), - trim: match[9], - type: match[10] - }); - } - formatSpecifier.prototype = FormatSpecifier.prototype; // instanceof + var nativeObjectToString = objectProto.toString; + /** Used to infer the `Object` constructor. */ - function FormatSpecifier(specifier) { - this.fill = specifier.fill === undefined ? " " : specifier.fill + ""; - this.align = specifier.align === undefined ? ">" : specifier.align + ""; - this.sign = specifier.sign === undefined ? "-" : specifier.sign + ""; - this.symbol = specifier.symbol === undefined ? "" : specifier.symbol + ""; - this.zero = !!specifier.zero; - this.width = specifier.width === undefined ? undefined : +specifier.width; - this.comma = !!specifier.comma; - this.precision = specifier.precision === undefined ? undefined : +specifier.precision; - this.trim = !!specifier.trim; - this.type = specifier.type === undefined ? "" : specifier.type + ""; - } + var objectCtorString = funcToString.call(Object); + /** Used to restore the original `_` reference in `_.noConflict`. */ - FormatSpecifier.prototype.toString = function () { - return this.fill + this.align + this.sign + this.symbol + (this.zero ? "0" : "") + (this.width === undefined ? "" : Math.max(1, this.width | 0)) + (this.comma ? "," : "") + (this.precision === undefined ? "" : "." + Math.max(0, this.precision | 0)) + (this.trim ? "~" : "") + this.type; - }; + var oldDash = root._; + /** Used to detect if a method is native. */ - // Trims insignificant zeros, e.g., replaces 1.2000k with 1.2k. - function formatTrim (s) { - out: for (var n = s.length, i = 1, i0 = -1, i1; i < n; ++i) { - switch (s[i]) { - case ".": - i0 = i1 = i; - break; + var reIsNative = RegExp('^' + funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&').replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'); + /** Built-in value references. */ - case "0": - if (i0 === 0) i0 = i; - i1 = i; - break; + var Buffer = moduleExports ? context.Buffer : undefined$1, + _Symbol = context.Symbol, + Uint8Array = context.Uint8Array, + allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined$1, + getPrototype = overArg(Object.getPrototypeOf, Object), + objectCreate = Object.create, + propertyIsEnumerable = objectProto.propertyIsEnumerable, + splice = arrayProto.splice, + spreadableSymbol = _Symbol ? _Symbol.isConcatSpreadable : undefined$1, + symIterator = _Symbol ? _Symbol.iterator : undefined$1, + symToStringTag = _Symbol ? _Symbol.toStringTag : undefined$1; - default: - if (!+s[i]) break out; - if (i0 > 0) i0 = 0; - break; - } - } + var defineProperty = function () { + try { + var func = getNative(Object, 'defineProperty'); + func({}, '', {}); + return func; + } catch (e) {} + }(); + /** Mocked built-ins. */ + + + var ctxClearTimeout = context.clearTimeout !== root.clearTimeout && context.clearTimeout, + ctxNow = Date && Date.now !== root.Date.now && Date.now, + ctxSetTimeout = context.setTimeout !== root.setTimeout && context.setTimeout; + /* Built-in method references for those with the same name as other `lodash` methods. */ + + var nativeCeil = Math.ceil, + nativeFloor = Math.floor, + nativeGetSymbols = Object.getOwnPropertySymbols, + nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined$1, + nativeIsFinite = context.isFinite, + nativeJoin = arrayProto.join, + nativeKeys = overArg(Object.keys, Object), + nativeMax = Math.max, + nativeMin = Math.min, + nativeNow = Date.now, + nativeParseInt = context.parseInt, + nativeRandom = Math.random, + nativeReverse = arrayProto.reverse; + /* Built-in method references that are verified to be native. */ + + var DataView = getNative(context, 'DataView'), + Map = getNative(context, 'Map'), + Promise = getNative(context, 'Promise'), + Set = getNative(context, 'Set'), + WeakMap = getNative(context, 'WeakMap'), + nativeCreate = getNative(Object, 'create'); + /** Used to store function metadata. */ + + var metaMap = WeakMap && new WeakMap(); + /** Used to lookup unminified function names. */ + + var realNames = {}; + /** Used to detect maps, sets, and weakmaps. */ + + var dataViewCtorString = toSource(DataView), + mapCtorString = toSource(Map), + promiseCtorString = toSource(Promise), + setCtorString = toSource(Set), + weakMapCtorString = toSource(WeakMap); + /** Used to convert symbols to primitives and strings. */ + + var symbolProto = _Symbol ? _Symbol.prototype : undefined$1, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined$1, + symbolToString = symbolProto ? symbolProto.toString : undefined$1; + /*------------------------------------------------------------------------*/ - return i0 > 0 ? s.slice(0, i0) + s.slice(i1 + 1) : s; - } + /** + * Creates a `lodash` object which wraps `value` to enable implicit method + * chain sequences. Methods that operate on and return arrays, collections, + * and functions can be chained together. Methods that retrieve a single value + * or may return a primitive value will automatically end the chain sequence + * and return the unwrapped value. Otherwise, the value must be unwrapped + * with `_#value`. + * + * Explicit chain sequences, which must be unwrapped with `_#value`, may be + * enabled using `_.chain`. + * + * The execution of chained methods is lazy, that is, it's deferred until + * `_#value` is implicitly or explicitly called. + * + * Lazy evaluation allows several methods to support shortcut fusion. + * Shortcut fusion is an optimization to merge iteratee calls; this avoids + * the creation of intermediate arrays and can greatly reduce the number of + * iteratee executions. Sections of a chain sequence qualify for shortcut + * fusion if the section is applied to an array and iteratees accept only + * one argument. The heuristic for whether a section qualifies for shortcut + * fusion is subject to change. + * + * Chaining is supported in custom builds as long as the `_#value` method is + * directly or indirectly included in the build. + * + * In addition to lodash methods, wrappers have `Array` and `String` methods. + * + * The wrapper `Array` methods are: + * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift` + * + * The wrapper `String` methods are: + * `replace` and `split` + * + * The wrapper methods that support shortcut fusion are: + * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`, + * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`, + * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray` + * + * The chainable wrapper methods are: + * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`, + * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`, + * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, + * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, + * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`, + * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`, + * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`, + * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`, + * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`, + * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`, + * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`, + * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`, + * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`, + * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`, + * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`, + * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`, + * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`, + * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`, + * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`, + * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`, + * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`, + * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`, + * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`, + * `zipObject`, `zipObjectDeep`, and `zipWith` + * + * The wrapper methods that are **not** chainable by default are: + * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`, + * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`, + * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`, + * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`, + * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`, + * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`, + * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`, + * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`, + * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`, + * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`, + * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`, + * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`, + * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`, + * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`, + * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`, + * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`, + * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, + * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`, + * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`, + * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`, + * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`, + * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`, + * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`, + * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`, + * `upperFirst`, `value`, and `words` + * + * @name _ + * @constructor + * @category Seq + * @param {*} value The value to wrap in a `lodash` instance. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * function square(n) { + * return n * n; + * } + * + * var wrapped = _([1, 2, 3]); + * + * // Returns an unwrapped value. + * wrapped.reduce(_.add); + * // => 6 + * + * // Returns a wrapped value. + * var squares = wrapped.map(square); + * + * _.isArray(squares); + * // => false + * + * _.isArray(squares.value()); + * // => true + */ - var $$7 = _export; - var fails$3 = fails$N; - var thisNumberValue = thisNumberValue$2; + function lodash(value) { + if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) { + if (value instanceof LodashWrapper) { + return value; + } - var nativeToPrecision = 1.0.toPrecision; + if (hasOwnProperty.call(value, '__wrapped__')) { + return wrapperClone(value); + } + } - var FORCED$1 = fails$3(function () { - // IE7- - return nativeToPrecision.call(1, undefined) !== '1'; - }) || !fails$3(function () { - // V8 ~ Android 4.3- - nativeToPrecision.call({}); - }); + return new LodashWrapper(value); + } + /** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} proto The object to inherit from. + * @returns {Object} Returns the new object. + */ - // `Number.prototype.toPrecision` method - // https://tc39.es/ecma262/#sec-number.prototype.toprecision - $$7({ target: 'Number', proto: true, forced: FORCED$1 }, { - toPrecision: function toPrecision(precision) { - return precision === undefined - ? nativeToPrecision.call(thisNumberValue(this)) - : nativeToPrecision.call(thisNumberValue(this), precision); - } - }); - var prefixExponent; - function formatPrefixAuto (x, p) { - var d = formatDecimalParts(x, p); - if (!d) return x + ""; - var coefficient = d[0], - exponent = d[1], - i = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1, - n = coefficient.length; - return i === n ? coefficient : i > n ? coefficient + new Array(i - n + 1).join("0") : i > 0 ? coefficient.slice(0, i) + "." + coefficient.slice(i) : "0." + new Array(1 - i).join("0") + formatDecimalParts(x, Math.max(0, p + i - 1))[0]; // less than 1y! - } + var baseCreate = function () { + function object() {} - function formatRounded (x, p) { - var d = formatDecimalParts(x, p); - if (!d) return x + ""; - var coefficient = d[0], - exponent = d[1]; - return exponent < 0 ? "0." + new Array(-exponent).join("0") + coefficient : coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + "." + coefficient.slice(exponent + 1) : coefficient + new Array(exponent - coefficient.length + 2).join("0"); - } + return function (proto) { + if (!isObject(proto)) { + return {}; + } - var formatTypes = { - "%": function _(x, p) { - return (x * 100).toFixed(p); - }, - "b": function b(x) { - return Math.round(x).toString(2); - }, - "c": function c(x) { - return x + ""; - }, - "d": formatDecimal, - "e": function e(x, p) { - return x.toExponential(p); - }, - "f": function f(x, p) { - return x.toFixed(p); - }, - "g": function g(x, p) { - return x.toPrecision(p); - }, - "o": function o(x) { - return Math.round(x).toString(8); - }, - "p": function p(x, _p) { - return formatRounded(x * 100, _p); - }, - "r": formatRounded, - "s": formatPrefixAuto, - "X": function X(x) { - return Math.round(x).toString(16).toUpperCase(); - }, - "x": function x(_x) { - return Math.round(_x).toString(16); - } - }; + if (objectCreate) { + return objectCreate(proto); + } - function identity (x) { - return x; - } + object.prototype = proto; + var result = new object(); + object.prototype = undefined$1; + return result; + }; + }(); + /** + * The function whose prototype chain sequence wrappers inherit from. + * + * @private + */ - var map$1 = Array.prototype.map, - prefixes = ["y", "z", "a", "f", "p", "n", "µ", "m", "", "k", "M", "G", "T", "P", "E", "Z", "Y"]; - function formatLocale (locale) { - var group = locale.grouping === undefined || locale.thousands === undefined ? identity : formatGroup(map$1.call(locale.grouping, Number), locale.thousands + ""), - currencyPrefix = locale.currency === undefined ? "" : locale.currency[0] + "", - currencySuffix = locale.currency === undefined ? "" : locale.currency[1] + "", - decimal = locale.decimal === undefined ? "." : locale.decimal + "", - numerals = locale.numerals === undefined ? identity : formatNumerals(map$1.call(locale.numerals, String)), - percent = locale.percent === undefined ? "%" : locale.percent + "", - minus = locale.minus === undefined ? "−" : locale.minus + "", - nan = locale.nan === undefined ? "NaN" : locale.nan + ""; - function newFormat(specifier) { - specifier = formatSpecifier(specifier); - var fill = specifier.fill, - align = specifier.align, - sign = specifier.sign, - symbol = specifier.symbol, - zero = specifier.zero, - width = specifier.width, - comma = specifier.comma, - precision = specifier.precision, - trim = specifier.trim, - type = specifier.type; // The "n" type is an alias for ",g". + function baseLodash() {// No operation performed. + } + /** + * The base constructor for creating `lodash` wrapper objects. + * + * @private + * @param {*} value The value to wrap. + * @param {boolean} [chainAll] Enable explicit method chain sequences. + */ - if (type === "n") comma = true, type = "g"; // The "" type, and any invalid type, is an alias for ".12~g". - else if (!formatTypes[type]) precision === undefined && (precision = 12), trim = true, type = "g"; // If zero fill is specified, padding goes after sign and before digits. - if (zero || fill === "0" && align === "=") zero = true, fill = "0", align = "="; // Compute the prefix and suffix. - // For SI-prefix, the suffix is lazily computed. + function LodashWrapper(value, chainAll) { + this.__wrapped__ = value; + this.__actions__ = []; + this.__chain__ = !!chainAll; + this.__index__ = 0; + this.__values__ = undefined$1; + } + /** + * By default, the template delimiters used by lodash are like those in + * embedded Ruby (ERB) as well as ES2015 template strings. Change the + * following template settings to use alternative delimiters. + * + * @static + * @memberOf _ + * @type {Object} + */ - var prefix = symbol === "$" ? currencyPrefix : symbol === "#" && /[boxX]/.test(type) ? "0" + type.toLowerCase() : "", - suffix = symbol === "$" ? currencySuffix : /[%p]/.test(type) ? percent : ""; // What format function should we use? - // Is this an integer type? - // Can this type generate exponential notation? - var formatType = formatTypes[type], - maybeSuffix = /[defgprs%]/.test(type); // Set the default precision if not specified, - // or clamp the specified precision to the supported range. - // For significant precision, it must be in [1, 21]. - // For fixed precision, it must be in [0, 20]. + lodash.templateSettings = { + /** + * Used to detect `data` property values to be HTML-escaped. + * + * @memberOf _.templateSettings + * @type {RegExp} + */ + 'escape': reEscape, - precision = precision === undefined ? 6 : /[gprs]/.test(type) ? Math.max(1, Math.min(21, precision)) : Math.max(0, Math.min(20, precision)); + /** + * Used to detect code to be evaluated. + * + * @memberOf _.templateSettings + * @type {RegExp} + */ + 'evaluate': reEvaluate, - function format(value) { - var valuePrefix = prefix, - valueSuffix = suffix, - i, - n, - c; + /** + * Used to detect `data` property values to inject. + * + * @memberOf _.templateSettings + * @type {RegExp} + */ + 'interpolate': reInterpolate, - if (type === "c") { - valueSuffix = formatType(value) + valueSuffix; - value = ""; - } else { - value = +value; // Determine the sign. -0 is not less than 0, but 1 / -0 is! + /** + * Used to reference the data object in the template text. + * + * @memberOf _.templateSettings + * @type {string} + */ + 'variable': '', - var valueNegative = value < 0 || 1 / value < 0; // Perform the initial formatting. + /** + * Used to import variables into the compiled template. + * + * @memberOf _.templateSettings + * @type {Object} + */ + 'imports': { + /** + * A reference to the `lodash` function. + * + * @memberOf _.templateSettings.imports + * @type {Function} + */ + '_': lodash + } + }; // Ensure wrappers are instances of `baseLodash`. + + lodash.prototype = baseLodash.prototype; + lodash.prototype.constructor = lodash; + LodashWrapper.prototype = baseCreate(baseLodash.prototype); + LodashWrapper.prototype.constructor = LodashWrapper; + /*------------------------------------------------------------------------*/ - value = isNaN(value) ? nan : formatType(Math.abs(value), precision); // Trim insignificant zeros. + /** + * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation. + * + * @private + * @constructor + * @param {*} value The value to wrap. + */ - if (trim) value = formatTrim(value); // If a negative value rounds to zero after formatting, and no explicit positive sign is requested, hide the sign. + function LazyWrapper(value) { + this.__wrapped__ = value; + this.__actions__ = []; + this.__dir__ = 1; + this.__filtered__ = false; + this.__iteratees__ = []; + this.__takeCount__ = MAX_ARRAY_LENGTH; + this.__views__ = []; + } + /** + * Creates a clone of the lazy wrapper object. + * + * @private + * @name clone + * @memberOf LazyWrapper + * @returns {Object} Returns the cloned `LazyWrapper` object. + */ - if (valueNegative && +value === 0 && sign !== "+") valueNegative = false; // Compute the prefix and suffix. - valuePrefix = (valueNegative ? sign === "(" ? sign : minus : sign === "-" || sign === "(" ? "" : sign) + valuePrefix; - valueSuffix = (type === "s" ? prefixes[8 + prefixExponent / 3] : "") + valueSuffix + (valueNegative && sign === "(" ? ")" : ""); // Break the formatted value into the integer “value” part that can be - // grouped, and fractional or exponential “suffix” part that is not. + function lazyClone() { + var result = new LazyWrapper(this.__wrapped__); + result.__actions__ = copyArray(this.__actions__); + result.__dir__ = this.__dir__; + result.__filtered__ = this.__filtered__; + result.__iteratees__ = copyArray(this.__iteratees__); + result.__takeCount__ = this.__takeCount__; + result.__views__ = copyArray(this.__views__); + return result; + } + /** + * Reverses the direction of lazy iteration. + * + * @private + * @name reverse + * @memberOf LazyWrapper + * @returns {Object} Returns the new reversed `LazyWrapper` object. + */ - if (maybeSuffix) { - i = -1, n = value.length; - while (++i < n) { - if (c = value.charCodeAt(i), 48 > c || c > 57) { - valueSuffix = (c === 46 ? decimal + value.slice(i + 1) : value.slice(i)) + valueSuffix; - value = value.slice(0, i); - break; - } - } + function lazyReverse() { + if (this.__filtered__) { + var result = new LazyWrapper(this); + result.__dir__ = -1; + result.__filtered__ = true; + } else { + result = this.clone(); + result.__dir__ *= -1; } - } // If the fill character is not "0", grouping is applied before padding. - - - if (comma && !zero) value = group(value, Infinity); // Compute the padding. - var length = valuePrefix.length + value.length + valueSuffix.length, - padding = length < width ? new Array(width - length + 1).join(fill) : ""; // If the fill character is "0", grouping is applied after padding. + return result; + } + /** + * Extracts the unwrapped value from its lazy wrapper. + * + * @private + * @name value + * @memberOf LazyWrapper + * @returns {*} Returns the unwrapped value. + */ - if (comma && zero) value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = ""; // Reconstruct the final output based on the desired alignment. - switch (align) { - case "<": - value = valuePrefix + value + valueSuffix + padding; - break; + function lazyValue() { + var array = this.__wrapped__.value(), + dir = this.__dir__, + isArr = isArray(array), + isRight = dir < 0, + arrLength = isArr ? array.length : 0, + view = getView(0, arrLength, this.__views__), + start = view.start, + end = view.end, + length = end - start, + index = isRight ? end : start - 1, + iteratees = this.__iteratees__, + iterLength = iteratees.length, + resIndex = 0, + takeCount = nativeMin(length, this.__takeCount__); - case "=": - value = valuePrefix + padding + value + valueSuffix; - break; + if (!isArr || !isRight && arrLength == length && takeCount == length) { + return baseWrapperValue(array, this.__actions__); + } - case "^": - value = padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length); - break; + var result = []; - default: - value = padding + valuePrefix + value + valueSuffix; - break; - } + outer: while (length-- && resIndex < takeCount) { + index += dir; + var iterIndex = -1, + value = array[index]; + + while (++iterIndex < iterLength) { + var data = iteratees[iterIndex], + iteratee = data.iteratee, + type = data.type, + computed = iteratee(value); + + if (type == LAZY_MAP_FLAG) { + value = computed; + } else if (!computed) { + if (type == LAZY_FILTER_FLAG) { + continue outer; + } else { + break outer; + } + } + } - return numerals(value); - } + result[resIndex++] = value; + } - format.toString = function () { - return specifier + ""; - }; + return result; + } // Ensure `LazyWrapper` is an instance of `baseLodash`. - return format; - } - function formatPrefix(specifier, value) { - var f = newFormat((specifier = formatSpecifier(specifier), specifier.type = "f", specifier)), - e = Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3, - k = Math.pow(10, -e), - prefix = prefixes[8 + e / 3]; - return function (value) { - return f(k * value) + prefix; - }; - } + LazyWrapper.prototype = baseCreate(baseLodash.prototype); + LazyWrapper.prototype.constructor = LazyWrapper; + /*------------------------------------------------------------------------*/ - return { - format: newFormat, - formatPrefix: formatPrefix - }; - } + /** + * Creates a hash object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ - var locale; - var format$1; - var formatPrefix; - defaultLocale({ - thousands: ",", - grouping: [3], - currency: ["$", ""] - }); - function defaultLocale(definition) { - locale = formatLocale(definition); - format$1 = locale.format; - formatPrefix = locale.formatPrefix; - return locale; - } + function Hash(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + this.clear(); - function precisionFixed (step) { - return Math.max(0, -exponent(Math.abs(step))); - } + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + /** + * Removes all key-value entries from the hash. + * + * @private + * @name clear + * @memberOf Hash + */ - function precisionPrefix (step, value) { - return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3 - exponent(Math.abs(step))); - } - function precisionRound (step, max) { - step = Math.abs(step), max = Math.abs(max) - step; - return Math.max(0, exponent(max) - exponent(step)) + 1; - } + function hashClear() { + this.__data__ = nativeCreate ? nativeCreate(null) : {}; + this.size = 0; + } + /** + * Removes `key` and its value from the hash. + * + * @private + * @name delete + * @memberOf Hash + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ - function tickFormat(start, stop, count, specifier) { - var step = tickStep(start, stop, count), - precision; - specifier = formatSpecifier(specifier == null ? ",f" : specifier); - switch (specifier.type) { - case "s": - { - var value = Math.max(Math.abs(start), Math.abs(stop)); - if (specifier.precision == null && !isNaN(precision = precisionPrefix(step, value))) specifier.precision = precision; - return formatPrefix(specifier, value); + function hashDelete(key) { + var result = this.has(key) && delete this.__data__[key]; + this.size -= result ? 1 : 0; + return result; } + /** + * Gets the hash value for `key`. + * + * @private + * @name get + * @memberOf Hash + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ - case "": - case "e": - case "g": - case "p": - case "r": - { - if (specifier.precision == null && !isNaN(precision = precisionRound(step, Math.max(Math.abs(start), Math.abs(stop))))) specifier.precision = precision - (specifier.type === "e"); - break; + + function hashGet(key) { + var data = this.__data__; + + if (nativeCreate) { + var result = data[key]; + return result === HASH_UNDEFINED ? undefined$1 : result; + } + + return hasOwnProperty.call(data, key) ? data[key] : undefined$1; } + /** + * Checks if a hash value for `key` exists. + * + * @private + * @name has + * @memberOf Hash + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ - case "f": - case "%": - { - if (specifier.precision == null && !isNaN(precision = precisionFixed(step))) specifier.precision = precision - (specifier.type === "%") * 2; - break; + + function hashHas(key) { + var data = this.__data__; + return nativeCreate ? data[key] !== undefined$1 : hasOwnProperty.call(data, key); } - } + /** + * Sets the hash `key` to `value`. + * + * @private + * @name set + * @memberOf Hash + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the hash instance. + */ - return format$1(specifier); - } - function linearish(scale) { - var domain = scale.domain; + function hashSet(key, value) { + var data = this.__data__; + this.size += this.has(key) ? 0 : 1; + data[key] = nativeCreate && value === undefined$1 ? HASH_UNDEFINED : value; + return this; + } // Add methods to `Hash`. - scale.ticks = function (count) { - var d = domain(); - return ticks(d[0], d[d.length - 1], count == null ? 10 : count); - }; - scale.tickFormat = function (count, specifier) { - var d = domain(); - return tickFormat(d[0], d[d.length - 1], count == null ? 10 : count, specifier); - }; + Hash.prototype.clear = hashClear; + Hash.prototype['delete'] = hashDelete; + Hash.prototype.get = hashGet; + Hash.prototype.has = hashHas; + Hash.prototype.set = hashSet; + /*------------------------------------------------------------------------*/ - scale.nice = function (count) { - if (count == null) count = 10; - var d = domain(); - var i0 = 0; - var i1 = d.length - 1; - var start = d[i0]; - var stop = d[i1]; - var prestep; - var step; - var maxIter = 10; + /** + * Creates an list cache object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ - if (stop < start) { - step = start, start = stop, stop = step; - step = i0, i0 = i1, i1 = step; - } + function ListCache(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + this.clear(); - while (maxIter-- > 0) { - step = tickIncrement(start, stop, count); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + /** + * Removes all key-value entries from the list cache. + * + * @private + * @name clear + * @memberOf ListCache + */ - if (step === prestep) { - d[i0] = start; - d[i1] = stop; - return domain(d); - } else if (step > 0) { - start = Math.floor(start / step) * step; - stop = Math.ceil(stop / step) * step; - } else if (step < 0) { - start = Math.ceil(start * step) / step; - stop = Math.floor(stop * step) / step; - } else { - break; + + function listCacheClear() { + this.__data__ = []; + this.size = 0; } + /** + * Removes `key` and its value from the list cache. + * + * @private + * @name delete + * @memberOf ListCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ - prestep = step; - } - return scale; - }; + function listCacheDelete(key) { + var data = this.__data__, + index = assocIndexOf(data, key); - return scale; - } - function linear() { - var scale = continuous(); + if (index < 0) { + return false; + } - scale.copy = function () { - return copy(scale, linear()); - }; + var lastIndex = data.length - 1; - initRange.apply(scale, arguments); - return linearish(scale); - } + if (index == lastIndex) { + data.pop(); + } else { + splice.call(data, index, 1); + } - // eslint-disable-next-line es/no-math-expm1 -- safe - var $expm1 = Math.expm1; - var exp$1 = Math.exp; + --this.size; + return true; + } + /** + * Gets the list cache value for `key`. + * + * @private + * @name get + * @memberOf ListCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ - // `Math.expm1` method implementation - // https://tc39.es/ecma262/#sec-math.expm1 - var mathExpm1 = (!$expm1 - // Old FF bug - || $expm1(10) > 22025.465794806719 || $expm1(10) < 22025.4657948067165168 - // Tor Browser bug - || $expm1(-2e-17) != -2e-17 - ) ? function expm1(x) { - return (x = +x) == 0 ? x : x > -1e-6 && x < 1e-6 ? x + x * x / 2 : exp$1(x) - 1; - } : $expm1; - function quantize() { - var x0 = 0, - x1 = 1, - n = 1, - domain = [0.5], - range = [0, 1], - unknown; + function listCacheGet(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + return index < 0 ? undefined$1 : data[index][1]; + } + /** + * Checks if a list cache value for `key` exists. + * + * @private + * @name has + * @memberOf ListCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ - function scale(x) { - return x != null && x <= x ? range[bisectRight(domain, x, 0, n)] : unknown; - } - function rescale() { - var i = -1; - domain = new Array(n); + function listCacheHas(key) { + return assocIndexOf(this.__data__, key) > -1; + } + /** + * Sets the list cache `key` to `value`. + * + * @private + * @name set + * @memberOf ListCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the list cache instance. + */ - while (++i < n) { - domain[i] = ((i + 1) * x1 - (i - n) * x0) / (n + 1); - } - return scale; - } + function listCacheSet(key, value) { + var data = this.__data__, + index = assocIndexOf(data, key); - scale.domain = function (_) { - var _ref, _ref2; + if (index < 0) { + ++this.size; + data.push([key, value]); + } else { + data[index][1] = value; + } - return arguments.length ? ((_ref = _, _ref2 = _slicedToArray(_ref, 2), x0 = _ref2[0], x1 = _ref2[1], _ref), x0 = +x0, x1 = +x1, rescale()) : [x0, x1]; - }; + return this; + } // Add methods to `ListCache`. - scale.range = function (_) { - return arguments.length ? (n = (range = Array.from(_)).length - 1, rescale()) : range.slice(); - }; - scale.invertExtent = function (y) { - var i = range.indexOf(y); - return i < 0 ? [NaN, NaN] : i < 1 ? [x0, domain[0]] : i >= n ? [domain[n - 1], x1] : [domain[i - 1], domain[i]]; - }; + ListCache.prototype.clear = listCacheClear; + ListCache.prototype['delete'] = listCacheDelete; + ListCache.prototype.get = listCacheGet; + ListCache.prototype.has = listCacheHas; + ListCache.prototype.set = listCacheSet; + /*------------------------------------------------------------------------*/ - scale.unknown = function (_) { - return arguments.length ? (unknown = _, scale) : scale; - }; + /** + * Creates a map cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ - scale.thresholds = function () { - return domain.slice(); - }; + function MapCache(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + this.clear(); - scale.copy = function () { - return quantize().domain([x0, x1]).range(range).unknown(unknown); - }; + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + /** + * Removes all key-value entries from the map. + * + * @private + * @name clear + * @memberOf MapCache + */ - return initRange.apply(linearish(scale), arguments); - } - // https://github.com/tc39/proposal-string-pad-start-end - var toLength$2 = toLength$q; - var repeat$1 = stringRepeat; - var requireObjectCoercible$2 = requireObjectCoercible$e; + function mapCacheClear() { + this.size = 0; + this.__data__ = { + 'hash': new Hash(), + 'map': new (Map || ListCache)(), + 'string': new Hash() + }; + } + /** + * Removes `key` and its value from the map. + * + * @private + * @name delete + * @memberOf MapCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ - var ceil = Math.ceil; - // `String.prototype.{ padStart, padEnd }` methods implementation - var createMethod = function (IS_END) { - return function ($this, maxLength, fillString) { - var S = String(requireObjectCoercible$2($this)); - var stringLength = S.length; - var fillStr = fillString === undefined ? ' ' : String(fillString); - var intMaxLength = toLength$2(maxLength); - var fillLen, stringFiller; - if (intMaxLength <= stringLength || fillStr == '') return S; - fillLen = intMaxLength - stringLength; - stringFiller = repeat$1.call(fillStr, ceil(fillLen / fillStr.length)); - if (stringFiller.length > fillLen) stringFiller = stringFiller.slice(0, fillLen); - return IS_END ? S + stringFiller : stringFiller + S; - }; - }; + function mapCacheDelete(key) { + var result = getMapData(this, key)['delete'](key); + this.size -= result ? 1 : 0; + return result; + } + /** + * Gets the map value for `key`. + * + * @private + * @name get + * @memberOf MapCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ - var stringPad = { - // `String.prototype.padStart` method - // https://tc39.es/ecma262/#sec-string.prototype.padstart - start: createMethod(false), - // `String.prototype.padEnd` method - // https://tc39.es/ecma262/#sec-string.prototype.padend - end: createMethod(true) - }; - var fails$2 = fails$N; - var padStart = stringPad.start; + function mapCacheGet(key) { + return getMapData(this, key).get(key); + } + /** + * Checks if a map value for `key` exists. + * + * @private + * @name has + * @memberOf MapCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ - var abs$1 = Math.abs; - var DatePrototype = Date.prototype; - var getTime = DatePrototype.getTime; - var nativeDateToISOString = DatePrototype.toISOString; - // `Date.prototype.toISOString` method implementation - // https://tc39.es/ecma262/#sec-date.prototype.toisostring - // PhantomJS / old WebKit fails here: - var dateToIsoString = (fails$2(function () { - return nativeDateToISOString.call(new Date(-5e13 - 1)) != '0385-07-25T07:06:39.999Z'; - }) || !fails$2(function () { - nativeDateToISOString.call(new Date(NaN)); - })) ? function toISOString() { - if (!isFinite(getTime.call(this))) throw RangeError('Invalid time value'); - var date = this; - var year = date.getUTCFullYear(); - var milliseconds = date.getUTCMilliseconds(); - var sign = year < 0 ? '-' : year > 9999 ? '+' : ''; - return sign + padStart(abs$1(year), sign ? 6 : 4, 0) + - '-' + padStart(date.getUTCMonth() + 1, 2, 0) + - '-' + padStart(date.getUTCDate(), 2, 0) + - 'T' + padStart(date.getUTCHours(), 2, 0) + - ':' + padStart(date.getUTCMinutes(), 2, 0) + - ':' + padStart(date.getUTCSeconds(), 2, 0) + - '.' + padStart(milliseconds, 3, 0) + - 'Z'; - } : nativeDateToISOString; + function mapCacheHas(key) { + return getMapData(this, key).has(key); + } + /** + * Sets the map `key` to `value`. + * + * @private + * @name set + * @memberOf MapCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the map cache instance. + */ - var $$6 = _export; - var toISOString = dateToIsoString; - // `Date.prototype.toISOString` method - // https://tc39.es/ecma262/#sec-date.prototype.toisostring - // PhantomJS / old WebKit has a broken implementations - $$6({ target: 'Date', proto: true, forced: Date.prototype.toISOString !== toISOString }, { - toISOString: toISOString - }); + function mapCacheSet(key, value) { + var data = getMapData(this, key), + size = data.size; + data.set(key, value); + this.size += data.size == size ? 0 : 1; + return this; + } // Add methods to `MapCache`. - function behaviorBreathe() { - var duration = 800; - var steps = 4; - var selector = '.selected.shadow, .selected .shadow'; - var _selected = select(null); + MapCache.prototype.clear = mapCacheClear; + MapCache.prototype['delete'] = mapCacheDelete; + MapCache.prototype.get = mapCacheGet; + MapCache.prototype.has = mapCacheHas; + MapCache.prototype.set = mapCacheSet; + /*------------------------------------------------------------------------*/ - var _classed = ''; - var _params = {}; - var _done = false; + /** + * + * Creates an array cache object to store unique values. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ - var _timer; + function SetCache(values) { + var index = -1, + length = values == null ? 0 : values.length; + this.__data__ = new MapCache(); - function ratchetyInterpolator(a, b, steps, units) { - a = parseFloat(a); - b = parseFloat(b); - var sample = quantize().domain([0, 1]).range(d3_quantize(d3_interpolateNumber(a, b), steps)); - return function (t) { - return String(sample(t)) + (units || ''); - }; - } + while (++index < length) { + this.add(values[index]); + } + } + /** + * Adds `value` to the array cache. + * + * @private + * @name add + * @memberOf SetCache + * @alias push + * @param {*} value The value to cache. + * @returns {Object} Returns the cache instance. + */ - function reset(selection) { - selection.style('stroke-opacity', null).style('stroke-width', null).style('fill-opacity', null).style('r', null); - } - function setAnimationParams(transition, fromTo) { - var toFrom = fromTo === 'from' ? 'to' : 'from'; - transition.styleTween('stroke-opacity', function (d) { - return ratchetyInterpolator(_params[d.id][toFrom].opacity, _params[d.id][fromTo].opacity, steps); - }).styleTween('stroke-width', function (d) { - return ratchetyInterpolator(_params[d.id][toFrom].width, _params[d.id][fromTo].width, steps, 'px'); - }).styleTween('fill-opacity', function (d) { - return ratchetyInterpolator(_params[d.id][toFrom].opacity, _params[d.id][fromTo].opacity, steps); - }).styleTween('r', function (d) { - return ratchetyInterpolator(_params[d.id][toFrom].width, _params[d.id][fromTo].width, steps, 'px'); - }); - } + function setCacheAdd(value) { + this.__data__.set(value, HASH_UNDEFINED); - function calcAnimationParams(selection) { - selection.call(reset).each(function (d) { - var s = select(this); - var tag = s.node().tagName; - var p = { - 'from': {}, - 'to': {} - }; - var opacity; - var width; // determine base opacity and width + return this; + } + /** + * Checks if `value` is in the array cache. + * + * @private + * @name has + * @memberOf SetCache + * @param {*} value The value to search for. + * @returns {number} Returns `true` if `value` is found, else `false`. + */ - if (tag === 'circle') { - opacity = parseFloat(s.style('fill-opacity') || 0.5); - width = parseFloat(s.style('r') || 15.5); - } else { - opacity = parseFloat(s.style('stroke-opacity') || 0.7); - width = parseFloat(s.style('stroke-width') || 10); - } // calculate from/to interpolation params.. + function setCacheHas(value) { + return this.__data__.has(value); + } // Add methods to `SetCache`. - p.tag = tag; - p.from.opacity = opacity * 0.6; - p.to.opacity = opacity * 1.25; - p.from.width = width * 0.7; - p.to.width = width * (tag === 'circle' ? 1.5 : 1); - _params[d.id] = p; - }); - } - function run(surface, fromTo) { - var toFrom = fromTo === 'from' ? 'to' : 'from'; - var currSelected = surface.selectAll(selector); - var currClassed = surface.attr('class'); + SetCache.prototype.add = SetCache.prototype.push = setCacheAdd; + SetCache.prototype.has = setCacheHas; + /*------------------------------------------------------------------------*/ - if (_done || currSelected.empty()) { - _selected.call(reset); + /** + * Creates a stack cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ - _selected = select(null); - return; - } + function Stack(entries) { + var data = this.__data__ = new ListCache(entries); + this.size = data.size; + } + /** + * Removes all key-value entries from the stack. + * + * @private + * @name clear + * @memberOf Stack + */ - if (!fastDeepEqual(currSelected.data(), _selected.data()) || currClassed !== _classed) { - _selected.call(reset); - _classed = currClassed; - _selected = currSelected.call(calcAnimationParams); - } + function stackClear() { + this.__data__ = new ListCache(); + this.size = 0; + } + /** + * Removes `key` and its value from the stack. + * + * @private + * @name delete + * @memberOf Stack + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ - var didCallNextRun = false; - _selected.transition().duration(duration).call(setAnimationParams, fromTo).on('end', function () { - // `end` event is called for each selected element, but we want - // it to run only once - if (!didCallNextRun) { - surface.call(run, toFrom); - didCallNextRun = true; - } // if entity was deselected, remove breathe styling + function stackDelete(key) { + var data = this.__data__, + result = data['delete'](key); + this.size = data.size; + return result; + } + /** + * Gets the stack value for `key`. + * + * @private + * @name get + * @memberOf Stack + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ - if (!select(this).classed('selected')) { - reset(select(this)); + function stackGet(key) { + return this.__data__.get(key); } - }); - } + /** + * Checks if a stack value for `key` exists. + * + * @private + * @name has + * @memberOf Stack + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ - function behavior(surface) { - _done = false; - _timer = timer(function () { - // wait for elements to actually become selected - if (surface.selectAll(selector).empty()) { - return false; + + function stackHas(key) { + return this.__data__.has(key); } + /** + * Sets the stack `key` to `value`. + * + * @private + * @name set + * @memberOf Stack + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the stack cache instance. + */ - surface.call(run, 'from'); - _timer.stop(); + function stackSet(key, value) { + var data = this.__data__; - return true; - }, 20); - } + if (data instanceof ListCache) { + var pairs = data.__data__; - behavior.restartIfNeeded = function (surface) { - if (_selected.empty()) { - surface.call(run, 'from'); + if (!Map || pairs.length < LARGE_ARRAY_SIZE - 1) { + pairs.push([key, value]); + this.size = ++data.size; + return this; + } - if (_timer) { - _timer.stop(); - } - } - }; + data = this.__data__ = new MapCache(pairs); + } - behavior.off = function () { - _done = true; + data.set(key, value); + this.size = data.size; + return this; + } // Add methods to `Stack`. - if (_timer) { - _timer.stop(); - } - _selected.interrupt().call(reset); - }; + Stack.prototype.clear = stackClear; + Stack.prototype['delete'] = stackDelete; + Stack.prototype.get = stackGet; + Stack.prototype.has = stackHas; + Stack.prototype.set = stackSet; + /*------------------------------------------------------------------------*/ - return behavior; - } + /** + * Creates an array of the enumerable property names of the array-like `value`. + * + * @private + * @param {*} value The value to query. + * @param {boolean} inherited Specify returning inherited property names. + * @returns {Array} Returns the array of property names. + */ - /* Creates a keybinding behavior for an operation */ - function behaviorOperation(context) { - var _operation; + function arrayLikeKeys(value, inherited) { + var isArr = isArray(value), + isArg = !isArr && isArguments(value), + isBuff = !isArr && !isArg && isBuffer(value), + isType = !isArr && !isArg && !isBuff && isTypedArray(value), + skipIndexes = isArr || isArg || isBuff || isType, + result = skipIndexes ? baseTimes(value.length, String) : [], + length = result.length; + + for (var key in value) { + if ((inherited || hasOwnProperty.call(value, key)) && !(skipIndexes && ( // Safari 9 has enumerable `arguments.length` in strict mode. + key == 'length' || // Node.js 0.10 has enumerable non-index properties on buffers. + isBuff && (key == 'offset' || key == 'parent') || // PhantomJS 2 has enumerable non-index properties on typed arrays. + isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset') || // Skip index properties. + isIndex(key, length)))) { + result.push(key); + } + } - function keypress(d3_event) { - // prevent operations during low zoom selection - if (!context.map().withinEditableZoom()) return; - if (_operation.availableForKeypress && !_operation.availableForKeypress()) return; - d3_event.preventDefault(); + return result; + } + /** + * A specialized version of `_.sample` for arrays. + * + * @private + * @param {Array} array The array to sample. + * @returns {*} Returns the random element. + */ - var disabled = _operation.disabled(); - if (disabled) { - context.ui().flash.duration(4000).iconName('#iD-operation-' + _operation.id).iconClass('operation disabled').label(_operation.tooltip)(); - } else { - context.ui().flash.duration(2000).iconName('#iD-operation-' + _operation.id).iconClass('operation').label(_operation.annotation() || _operation.title)(); - if (_operation.point) _operation.point(null); - - _operation(); - } - } + function arraySample(array) { + var length = array.length; + return length ? array[baseRandom(0, length - 1)] : undefined$1; + } + /** + * A specialized version of `_.sampleSize` for arrays. + * + * @private + * @param {Array} array The array to sample. + * @param {number} n The number of elements to sample. + * @returns {Array} Returns the random elements. + */ - function behavior() { - if (_operation && _operation.available()) { - context.keybinding().on(_operation.keys, keypress); - } - return behavior; - } + function arraySampleSize(array, n) { + return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length)); + } + /** + * A specialized version of `_.shuffle` for arrays. + * + * @private + * @param {Array} array The array to shuffle. + * @returns {Array} Returns the new shuffled array. + */ - behavior.off = function () { - context.keybinding().off(_operation.keys); - }; - behavior.which = function (_) { - if (!arguments.length) return _operation; - _operation = _; - return behavior; - }; + function arrayShuffle(array) { + return shuffleSelf(copyArray(array)); + } + /** + * This function is like `assignValue` except that it doesn't assign + * `undefined` values. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ - return behavior; - } - function operationCircularize(context, selectedIDs) { - var _extent; + function assignMergeValue(object, key, value) { + if (value !== undefined$1 && !eq(object[key], value) || value === undefined$1 && !(key in object)) { + baseAssignValue(object, key, value); + } + } + /** + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ - var _actions = selectedIDs.map(getAction).filter(Boolean); - var _amount = _actions.length === 1 ? 'single' : 'multiple'; + function assignValue(object, key, value) { + var objValue = object[key]; - var _coords = utilGetAllNodes(selectedIDs, context.graph()).map(function (n) { - return n.loc; - }); + if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || value === undefined$1 && !(key in object)) { + baseAssignValue(object, key, value); + } + } + /** + * Gets the index at which the `key` is found in `array` of key-value pairs. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} key The key to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + */ - function getAction(entityID) { - var entity = context.entity(entityID); - if (entity.type !== 'way' || new Set(entity.nodes).size <= 1) return null; - if (!_extent) { - _extent = entity.extent(context.graph()); - } else { - _extent = _extent.extend(entity.extent(context.graph())); - } + function assocIndexOf(array, key) { + var length = array.length; - return actionCircularize(entityID, context.projection); - } + while (length--) { + if (eq(array[length][0], key)) { + return length; + } + } - var operation = function operation() { - if (!_actions.length) return; + return -1; + } + /** + * Aggregates elements of `collection` on `accumulator` with keys transformed + * by `iteratee` and values set by `setter`. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} setter The function to set `accumulator` values. + * @param {Function} iteratee The iteratee to transform keys. + * @param {Object} accumulator The initial aggregated object. + * @returns {Function} Returns `accumulator`. + */ - var combinedAction = function combinedAction(graph, t) { - _actions.forEach(function (action) { - if (!action.disabled(graph)) { - graph = action(graph, t); - } - }); - return graph; - }; + function baseAggregator(collection, setter, iteratee, accumulator) { + baseEach(collection, function (value, key, collection) { + setter(accumulator, value, iteratee(value), collection); + }); + return accumulator; + } + /** + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ - combinedAction.transitionable = true; - context.perform(combinedAction, operation.annotation()); - window.setTimeout(function () { - context.validator().validate(); - }, 300); // after any transition - }; - operation.available = function () { - return _actions.length && selectedIDs.length === _actions.length; - }; // don't cache this because the visible extent could change + function baseAssign(object, source) { + return object && copyObject(source, keys(source), object); + } + /** + * The base implementation of `_.assignIn` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ - operation.disabled = function () { - if (!_actions.length) return ''; + function baseAssignIn(object, source) { + return object && copyObject(source, keysIn(source), object); + } + /** + * The base implementation of `assignValue` and `assignMergeValue` without + * value checks. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ - var actionDisableds = _actions.map(function (action) { - return action.disabled(context.graph()); - }).filter(Boolean); - if (actionDisableds.length === _actions.length) { - // none of the features can be circularized - if (new Set(actionDisableds).size > 1) { - return 'multiple_blockers'; + function baseAssignValue(object, key, value) { + if (key == '__proto__' && defineProperty) { + defineProperty(object, key, { + 'configurable': true, + 'enumerable': true, + 'value': value, + 'writable': true + }); + } else { + object[key] = value; + } } + /** + * The base implementation of `_.at` without support for individual paths. + * + * @private + * @param {Object} object The object to iterate over. + * @param {string[]} paths The property paths to pick. + * @returns {Array} Returns the picked elements. + */ - return actionDisableds[0]; - } else if (_extent.percentContainedIn(context.map().extent()) < 0.8) { - return 'too_large'; - } else if (someMissing()) { - return 'not_downloaded'; - } else if (selectedIDs.some(context.hasHiddenConnections)) { - return 'connected_to_hidden'; - } - return false; + function baseAt(object, paths) { + var index = -1, + length = paths.length, + result = Array(length), + skip = object == null; - function someMissing() { - if (context.inIntro()) return false; - var osm = context.connection(); + while (++index < length) { + result[index] = skip ? undefined$1 : get(object, paths[index]); + } - if (osm) { - var missing = _coords.filter(function (loc) { - return !osm.isDataLoaded(loc); - }); + return result; + } + /** + * The base implementation of `_.clamp` which doesn't coerce arguments. + * + * @private + * @param {number} number The number to clamp. + * @param {number} [lower] The lower bound. + * @param {number} upper The upper bound. + * @returns {number} Returns the clamped number. + */ - if (missing.length) { - missing.forEach(function (loc) { - context.loadTileAtLoc(loc); - }); - return true; + + function baseClamp(number, lower, upper) { + if (number === number) { + if (upper !== undefined$1) { + number = number <= upper ? number : upper; + } + + if (lower !== undefined$1) { + number = number >= lower ? number : lower; + } } + + return number; } + /** + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} bitmask The bitmask flags. + * 1 - Deep clone + * 2 - Flatten inherited properties + * 4 - Clone symbols + * @param {Function} [customizer] The function to customize cloning. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. + * @returns {*} Returns the cloned value. + */ - return false; - } - }; - operation.tooltip = function () { - var disable = operation.disabled(); - return disable ? _t('operations.circularize.' + disable + '.' + _amount) : _t('operations.circularize.description.' + _amount); - }; + function baseClone(value, bitmask, customizer, key, object, stack) { + var result, + isDeep = bitmask & CLONE_DEEP_FLAG, + isFlat = bitmask & CLONE_FLAT_FLAG, + isFull = bitmask & CLONE_SYMBOLS_FLAG; - operation.annotation = function () { - return _t('operations.circularize.annotation.feature', { - n: _actions.length - }); - }; + if (customizer) { + result = object ? customizer(value, key, object, stack) : customizer(value); + } - operation.id = 'circularize'; - operation.keys = [_t('operations.circularize.key')]; - operation.title = _t('operations.circularize.title'); - operation.behavior = behaviorOperation(context).which(operation); - return operation; - } + if (result !== undefined$1) { + return result; + } - // For example, ⌘Z -> Ctrl+Z + if (!isObject(value)) { + return value; + } - var uiCmd = function uiCmd(code) { - var detected = utilDetect(); + var isArr = isArray(value); - if (detected.os === 'mac') { - return code; - } + if (isArr) { + result = initCloneArray(value); - if (detected.os === 'win') { - if (code === '⌘⇧Z') return 'Ctrl+Y'; - } + if (!isDeep) { + return copyArray(value, result); + } + } else { + var tag = getTag(value), + isFunc = tag == funcTag || tag == genTag; - var result = '', - replacements = { - '⌘': 'Ctrl', - '⇧': 'Shift', - '⌥': 'Alt', - '⌫': 'Backspace', - '⌦': 'Delete' - }; + if (isBuffer(value)) { + return cloneBuffer(value, isDeep); + } - for (var i = 0; i < code.length; i++) { - if (code[i] in replacements) { - result += replacements[code[i]] + (i < code.length - 1 ? '+' : ''); - } else { - result += code[i]; - } - } + if (tag == objectTag || tag == argsTag || isFunc && !object) { + result = isFlat || isFunc ? {} : initCloneObject(value); - return result; - }; // return a display-focused string for a given keyboard code + if (!isDeep) { + return isFlat ? copySymbolsIn(value, baseAssignIn(result, value)) : copySymbols(value, baseAssign(result, value)); + } + } else { + if (!cloneableTags[tag]) { + return object ? value : {}; + } - uiCmd.display = function (code) { - if (code.length !== 1) return code; - var detected = utilDetect(); - var mac = detected.os === 'mac'; - var replacements = { - '⌘': mac ? '⌘ ' + _t('shortcuts.key.cmd') : _t('shortcuts.key.ctrl'), - '⇧': mac ? '⇧ ' + _t('shortcuts.key.shift') : _t('shortcuts.key.shift'), - '⌥': mac ? '⌥ ' + _t('shortcuts.key.option') : _t('shortcuts.key.alt'), - '⌃': mac ? '⌃ ' + _t('shortcuts.key.ctrl') : _t('shortcuts.key.ctrl'), - '⌫': mac ? '⌫ ' + _t('shortcuts.key.delete') : _t('shortcuts.key.backspace'), - '⌦': mac ? '⌦ ' + _t('shortcuts.key.del') : _t('shortcuts.key.del'), - '↖': mac ? '↖ ' + _t('shortcuts.key.pgup') : _t('shortcuts.key.pgup'), - '↘': mac ? '↘ ' + _t('shortcuts.key.pgdn') : _t('shortcuts.key.pgdn'), - '⇞': mac ? '⇞ ' + _t('shortcuts.key.home') : _t('shortcuts.key.home'), - '⇟': mac ? '⇟ ' + _t('shortcuts.key.end') : _t('shortcuts.key.end'), - '↵': mac ? '⏎ ' + _t('shortcuts.key.return') : _t('shortcuts.key.enter'), - '⎋': mac ? '⎋ ' + _t('shortcuts.key.esc') : _t('shortcuts.key.esc'), - '☰': mac ? '☰ ' + _t('shortcuts.key.menu') : _t('shortcuts.key.menu') - }; - return replacements[code] || code; - }; + result = initCloneByTag(value, tag, isDeep); + } + } // Check for circular references and return its corresponding clone. - function operationDelete(context, selectedIDs) { - var multi = selectedIDs.length === 1 ? 'single' : 'multiple'; - var action = actionDeleteMultiple(selectedIDs); - var nodes = utilGetAllNodes(selectedIDs, context.graph()); - var coords = nodes.map(function (n) { - return n.loc; - }); - var extent = utilTotalExtent(selectedIDs, context.graph()); - var operation = function operation() { - var nextSelectedID; - var nextSelectedLoc; + stack || (stack = new Stack()); + var stacked = stack.get(value); - if (selectedIDs.length === 1) { - var id = selectedIDs[0]; - var entity = context.entity(id); - var geometry = entity.geometry(context.graph()); - var parents = context.graph().parentWays(entity); - var parent = parents[0]; // Select the next closest node in the way. + if (stacked) { + return stacked; + } - if (geometry === 'vertex') { - var nodes = parent.nodes; - var i = nodes.indexOf(id); + stack.set(value, result); - if (i === 0) { - i++; - } else if (i === nodes.length - 1) { - i--; - } else { - var a = geoSphericalDistance(entity.loc, context.entity(nodes[i - 1]).loc); - var b = geoSphericalDistance(entity.loc, context.entity(nodes[i + 1]).loc); - i = a < b ? i - 1 : i + 1; + if (isSet(value)) { + value.forEach(function (subValue) { + result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack)); + }); + } else if (isMap(value)) { + value.forEach(function (subValue, key) { + result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); } - nextSelectedID = nodes[i]; - nextSelectedLoc = context.entity(nextSelectedID).loc; + var keysFunc = isFull ? isFlat ? getAllKeysIn : getAllKeys : isFlat ? keysIn : keys; + var props = isArr ? undefined$1 : keysFunc(value); + arrayEach(props || value, function (subValue, key) { + if (props) { + key = subValue; + subValue = value[key]; + } // Recursively populate clone (susceptible to call stack limits). + + + assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + return result; } - } + /** + * The base implementation of `_.conforms` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property predicates to conform to. + * @returns {Function} Returns the new spec function. + */ - context.perform(action, operation.annotation()); - context.validator().validate(); - if (nextSelectedID && nextSelectedLoc) { - if (context.hasEntity(nextSelectedID)) { - context.enter(modeSelect(context, [nextSelectedID]).follow(true)); - } else { - context.map().centerEase(nextSelectedLoc); - context.enter(modeBrowse(context)); + function baseConforms(source) { + var props = keys(source); + return function (object) { + return baseConformsTo(object, source, props); + }; } - } else { - context.enter(modeBrowse(context)); - } - }; + /** + * The base implementation of `_.conformsTo` which accepts `props` to check. + * + * @private + * @param {Object} object The object to inspect. + * @param {Object} source The object of property predicates to conform to. + * @returns {boolean} Returns `true` if `object` conforms, else `false`. + */ - operation.available = function () { - return true; - }; - operation.disabled = function () { - if (extent.percentContainedIn(context.map().extent()) < 0.8) { - return 'too_large'; - } else if (someMissing()) { - return 'not_downloaded'; - } else if (selectedIDs.some(context.hasHiddenConnections)) { - return 'connected_to_hidden'; - } else if (selectedIDs.some(protectedMember)) { - return 'part_of_relation'; - } else if (selectedIDs.some(incompleteRelation)) { - return 'incomplete_relation'; - } else if (selectedIDs.some(hasWikidataTag)) { - return 'has_wikidata_tag'; - } + function baseConformsTo(object, source, props) { + var length = props.length; - return false; + if (object == null) { + return !length; + } - function someMissing() { - if (context.inIntro()) return false; - var osm = context.connection(); + object = Object(object); - if (osm) { - var missing = coords.filter(function (loc) { - return !osm.isDataLoaded(loc); - }); + while (length--) { + var key = props[length], + predicate = source[key], + value = object[key]; - if (missing.length) { - missing.forEach(function (loc) { - context.loadTileAtLoc(loc); - }); - return true; + if (value === undefined$1 && !(key in object) || !predicate(value)) { + return false; + } } + + return true; } + /** + * The base implementation of `_.delay` and `_.defer` which accepts `args` + * to provide to `func`. + * + * @private + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @param {Array} args The arguments to provide to `func`. + * @returns {number|Object} Returns the timer id or timeout object. + */ - return false; - } - function hasWikidataTag(id) { - var entity = context.entity(id); - return entity.tags.wikidata && entity.tags.wikidata.trim().length > 0; - } + function baseDelay(func, wait, args) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } - function incompleteRelation(id) { - var entity = context.entity(id); - return entity.type === 'relation' && !entity.isComplete(context.graph()); - } + return setTimeout(function () { + func.apply(undefined$1, args); + }, wait); + } + /** + * The base implementation of methods like `_.difference` without support + * for excluding multiple arrays or iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Array} values The values to exclude. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of filtered values. + */ - function protectedMember(id) { - var entity = context.entity(id); - if (entity.type !== 'way') return false; - var parents = context.graph().parentRelations(entity); - for (var i = 0; i < parents.length; i++) { - var parent = parents[i]; - var type = parent.tags.type; - var role = parent.memberById(id).role || 'outer'; + function baseDifference(array, values, iteratee, comparator) { + var index = -1, + includes = arrayIncludes, + isCommon = true, + length = array.length, + result = [], + valuesLength = values.length; - if (type === 'route' || type === 'boundary' || type === 'multipolygon' && role === 'outer') { - return true; + if (!length) { + return result; } - } - return false; - } - }; + if (iteratee) { + values = arrayMap(values, baseUnary(iteratee)); + } - operation.tooltip = function () { - var disable = operation.disabled(); - return disable ? _t('operations.delete.' + disable + '.' + multi) : _t('operations.delete.description.' + multi); - }; + if (comparator) { + includes = arrayIncludesWith; + isCommon = false; + } else if (values.length >= LARGE_ARRAY_SIZE) { + includes = cacheHas; + isCommon = false; + values = new SetCache(values); + } - operation.annotation = function () { - return selectedIDs.length === 1 ? _t('operations.delete.annotation.' + context.graph().geometry(selectedIDs[0])) : _t('operations.delete.annotation.feature', { - n: selectedIDs.length - }); - }; + outer: while (++index < length) { + var value = array[index], + computed = iteratee == null ? value : iteratee(value); + value = comparator || value !== 0 ? value : 0; - operation.id = 'delete'; - operation.keys = [uiCmd('⌘⌫'), uiCmd('⌘⌦'), uiCmd('⌦')]; - operation.title = _t('operations.delete.title'); - operation.behavior = behaviorOperation(context).which(operation); - return operation; - } + if (isCommon && computed === computed) { + var valuesIndex = valuesLength; - function operationOrthogonalize(context, selectedIDs) { - var _extent; + while (valuesIndex--) { + if (values[valuesIndex] === computed) { + continue outer; + } + } - var _type; + result.push(value); + } else if (!includes(values, computed, comparator)) { + result.push(value); + } + } - var _actions = selectedIDs.map(chooseAction).filter(Boolean); + return result; + } + /** + * The base implementation of `_.forEach` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + */ - var _amount = _actions.length === 1 ? 'single' : 'multiple'; - var _coords = utilGetAllNodes(selectedIDs, context.graph()).map(function (n) { - return n.loc; - }); + var baseEach = createBaseEach(baseForOwn); + /** + * The base implementation of `_.forEachRight` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + */ - function chooseAction(entityID) { - var entity = context.entity(entityID); - var geometry = entity.geometry(context.graph()); + var baseEachRight = createBaseEach(baseForOwnRight, true); + /** + * The base implementation of `_.every` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false` + */ - if (!_extent) { - _extent = entity.extent(context.graph()); - } else { - _extent = _extent.extend(entity.extent(context.graph())); - } // square a line/area + function baseEvery(collection, predicate) { + var result = true; + baseEach(collection, function (value, index, collection) { + result = !!predicate(value, index, collection); + return result; + }); + return result; + } + /** + * The base implementation of methods like `_.max` and `_.min` which accepts a + * `comparator` to determine the extremum value. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The iteratee invoked per iteration. + * @param {Function} comparator The comparator used to compare values. + * @returns {*} Returns the extremum value. + */ - if (entity.type === 'way' && new Set(entity.nodes).size > 2) { - if (_type && _type !== 'feature') return null; - _type = 'feature'; - return actionOrthogonalize(entityID, context.projection); // square a single vertex - } else if (geometry === 'vertex') { - if (_type && _type !== 'corner') return null; - _type = 'corner'; - var graph = context.graph(); - var parents = graph.parentWays(entity); + function baseExtremum(array, iteratee, comparator) { + var index = -1, + length = array.length; - if (parents.length === 1) { - var way = parents[0]; + while (++index < length) { + var value = array[index], + current = iteratee(value); - if (way.nodes.indexOf(entityID) !== -1) { - return actionOrthogonalize(way.id, context.projection, entityID); + if (current != null && (computed === undefined$1 ? current === current && !isSymbol(current) : comparator(current, computed))) { + var computed = current, + result = value; + } } + + return result; } - } + /** + * The base implementation of `_.fill` without an iteratee call guard. + * + * @private + * @param {Array} array The array to fill. + * @param {*} value The value to fill `array` with. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns `array`. + */ - return null; - } - var operation = function operation() { - if (!_actions.length) return; + function baseFill(array, value, start, end) { + var length = array.length; + start = toInteger(start); - var combinedAction = function combinedAction(graph, t) { - _actions.forEach(function (action) { - if (!action.disabled(graph)) { - graph = action(graph, t); + if (start < 0) { + start = -start > length ? 0 : length + start; } - }); - return graph; - }; + end = end === undefined$1 || end > length ? length : toInteger(end); - combinedAction.transitionable = true; - context.perform(combinedAction, operation.annotation()); - window.setTimeout(function () { - context.validator().validate(); - }, 300); // after any transition - }; + if (end < 0) { + end += length; + } - operation.available = function () { - return _actions.length && selectedIDs.length === _actions.length; - }; // don't cache this because the visible extent could change + end = start > end ? 0 : toLength(end); + while (start < end) { + array[start++] = value; + } - operation.disabled = function () { - if (!_actions.length) return ''; + return array; + } + /** + * The base implementation of `_.filter` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ - var actionDisableds = _actions.map(function (action) { - return action.disabled(context.graph()); - }).filter(Boolean); - if (actionDisableds.length === _actions.length) { - // none of the features can be squared - if (new Set(actionDisableds).size > 1) { - return 'multiple_blockers'; + function baseFilter(collection, predicate) { + var result = []; + baseEach(collection, function (value, index, collection) { + if (predicate(value, index, collection)) { + result.push(value); + } + }); + return result; } + /** + * The base implementation of `_.flatten` with support for restricting flattening. + * + * @private + * @param {Array} array The array to flatten. + * @param {number} depth The maximum recursion depth. + * @param {boolean} [predicate=isFlattenable] The function invoked per iteration. + * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks. + * @param {Array} [result=[]] The initial result value. + * @returns {Array} Returns the new flattened array. + */ - return actionDisableds[0]; - } else if (_extent && _extent.percentContainedIn(context.map().extent()) < 0.8) { - return 'too_large'; - } else if (someMissing()) { - return 'not_downloaded'; - } else if (selectedIDs.some(context.hasHiddenConnections)) { - return 'connected_to_hidden'; - } - - return false; - function someMissing() { - if (context.inIntro()) return false; - var osm = context.connection(); + function baseFlatten(array, depth, predicate, isStrict, result) { + var index = -1, + length = array.length; + predicate || (predicate = isFlattenable); + result || (result = []); - if (osm) { - var missing = _coords.filter(function (loc) { - return !osm.isDataLoaded(loc); - }); + while (++index < length) { + var value = array[index]; - if (missing.length) { - missing.forEach(function (loc) { - context.loadTileAtLoc(loc); - }); - return true; + if (depth > 0 && predicate(value)) { + if (depth > 1) { + // Recursively flatten arrays (susceptible to call stack limits). + baseFlatten(value, depth - 1, predicate, isStrict, result); + } else { + arrayPush(result, value); + } + } else if (!isStrict) { + result[result.length] = value; + } } + + return result; } + /** + * The base implementation of `baseForOwn` which iterates over `object` + * properties returned by `keysFunc` and invokes `iteratee` for each property. + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ - return false; - } - }; - operation.tooltip = function () { - var disable = operation.disabled(); - return disable ? _t('operations.orthogonalize.' + disable + '.' + _amount) : _t('operations.orthogonalize.description.' + _type + '.' + _amount); - }; + var baseFor = createBaseFor(); + /** + * This function is like `baseFor` except that it iterates over properties + * in the opposite order. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ - operation.annotation = function () { - return _t('operations.orthogonalize.annotation.' + _type, { - n: _actions.length - }); - }; - - operation.id = 'orthogonalize'; - operation.keys = [_t('operations.orthogonalize.key')]; - operation.title = _t('operations.orthogonalize.title'); - operation.behavior = behaviorOperation(context).which(operation); - return operation; - } - - function operationReflectShort(context, selectedIDs) { - return operationReflect(context, selectedIDs, 'short'); - } - function operationReflectLong(context, selectedIDs) { - return operationReflect(context, selectedIDs, 'long'); - } - function operationReflect(context, selectedIDs, axis) { - axis = axis || 'long'; - var multi = selectedIDs.length === 1 ? 'single' : 'multiple'; - var nodes = utilGetAllNodes(selectedIDs, context.graph()); - var coords = nodes.map(function (n) { - return n.loc; - }); - var extent = utilTotalExtent(selectedIDs, context.graph()); + var baseForRight = createBaseFor(true); + /** + * The base implementation of `_.forOwn` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ - var operation = function operation() { - var action = actionReflect(selectedIDs, context.projection).useLongAxis(Boolean(axis === 'long')); - context.perform(action, operation.annotation()); - window.setTimeout(function () { - context.validator().validate(); - }, 300); // after any transition - }; + function baseForOwn(object, iteratee) { + return object && baseFor(object, iteratee, keys); + } + /** + * The base implementation of `_.forOwnRight` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ - operation.available = function () { - return nodes.length >= 3; - }; // don't cache this because the visible extent could change + function baseForOwnRight(object, iteratee) { + return object && baseForRight(object, iteratee, keys); + } + /** + * The base implementation of `_.functions` which creates an array of + * `object` function property names filtered from `props`. + * + * @private + * @param {Object} object The object to inspect. + * @param {Array} props The property names to filter. + * @returns {Array} Returns the function names. + */ - operation.disabled = function () { - if (extent.percentContainedIn(context.map().extent()) < 0.8) { - return 'too_large'; - } else if (someMissing()) { - return 'not_downloaded'; - } else if (selectedIDs.some(context.hasHiddenConnections)) { - return 'connected_to_hidden'; - } else if (selectedIDs.some(incompleteRelation)) { - return 'incomplete_relation'; - } - return false; + function baseFunctions(object, props) { + return arrayFilter(props, function (key) { + return isFunction(object[key]); + }); + } + /** + * The base implementation of `_.get` without support for default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @returns {*} Returns the resolved value. + */ - function someMissing() { - if (context.inIntro()) return false; - var osm = context.connection(); - if (osm) { - var missing = coords.filter(function (loc) { - return !osm.isDataLoaded(loc); - }); + function baseGet(object, path) { + path = castPath(path, object); + var index = 0, + length = path.length; - if (missing.length) { - missing.forEach(function (loc) { - context.loadTileAtLoc(loc); - }); - return true; + while (object != null && index < length) { + object = object[toKey(path[index++])]; } + + return index && index == length ? object : undefined$1; } + /** + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. + */ - return false; - } - function incompleteRelation(id) { - var entity = context.entity(id); - return entity.type === 'relation' && !entity.isComplete(context.graph()); - } - }; + function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return isArray(object) ? result : arrayPush(result, symbolsFunc(object)); + } + /** + * The base implementation of `getTag` without fallbacks for buggy environments. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ - operation.tooltip = function () { - var disable = operation.disabled(); - return disable ? _t('operations.reflect.' + disable + '.' + multi) : _t('operations.reflect.description.' + axis + '.' + multi); - }; - operation.annotation = function () { - return _t('operations.reflect.annotation.' + axis + '.feature', { - n: selectedIDs.length - }); - }; + function baseGetTag(value) { + if (value == null) { + return value === undefined$1 ? undefinedTag : nullTag; + } - operation.id = 'reflect-' + axis; - operation.keys = [_t('operations.reflect.key.' + axis)]; - operation.title = _t('operations.reflect.title.' + axis); - operation.behavior = behaviorOperation(context).which(operation); - return operation; - } + return symToStringTag && symToStringTag in Object(value) ? getRawTag(value) : objectToString(value); + } + /** + * The base implementation of `_.gt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than `other`, + * else `false`. + */ - function operationMove(context, selectedIDs) { - var multi = selectedIDs.length === 1 ? 'single' : 'multiple'; - var nodes = utilGetAllNodes(selectedIDs, context.graph()); - var coords = nodes.map(function (n) { - return n.loc; - }); - var extent = utilTotalExtent(selectedIDs, context.graph()); - var operation = function operation() { - context.enter(modeMove(context, selectedIDs)); - }; + function baseGt(value, other) { + return value > other; + } + /** + * The base implementation of `_.has` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ - operation.available = function () { - return selectedIDs.length > 0; - }; - operation.disabled = function () { - if (extent.percentContainedIn(context.map().extent()) < 0.8) { - return 'too_large'; - } else if (someMissing()) { - return 'not_downloaded'; - } else if (selectedIDs.some(context.hasHiddenConnections)) { - return 'connected_to_hidden'; - } else if (selectedIDs.some(incompleteRelation)) { - return 'incomplete_relation'; - } + function baseHas(object, key) { + return object != null && hasOwnProperty.call(object, key); + } + /** + * The base implementation of `_.hasIn` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ - return false; - function someMissing() { - if (context.inIntro()) return false; - var osm = context.connection(); + function baseHasIn(object, key) { + return object != null && key in Object(object); + } + /** + * The base implementation of `_.inRange` which doesn't coerce arguments. + * + * @private + * @param {number} number The number to check. + * @param {number} start The start of the range. + * @param {number} end The end of the range. + * @returns {boolean} Returns `true` if `number` is in the range, else `false`. + */ - if (osm) { - var missing = coords.filter(function (loc) { - return !osm.isDataLoaded(loc); - }); - if (missing.length) { - missing.forEach(function (loc) { - context.loadTileAtLoc(loc); - }); - return true; - } + function baseInRange(number, start, end) { + return number >= nativeMin(start, end) && number < nativeMax(start, end); } + /** + * The base implementation of methods like `_.intersection`, without support + * for iteratee shorthands, that accepts an array of arrays to inspect. + * + * @private + * @param {Array} arrays The arrays to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of shared values. + */ - return false; - } - function incompleteRelation(id) { - var entity = context.entity(id); - return entity.type === 'relation' && !entity.isComplete(context.graph()); - } - }; + function baseIntersection(arrays, iteratee, comparator) { + var includes = comparator ? arrayIncludesWith : arrayIncludes, + length = arrays[0].length, + othLength = arrays.length, + othIndex = othLength, + caches = Array(othLength), + maxLength = Infinity, + result = []; - operation.tooltip = function () { - var disable = operation.disabled(); - return disable ? _t('operations.move.' + disable + '.' + multi) : _t('operations.move.description.' + multi); - }; + while (othIndex--) { + var array = arrays[othIndex]; - operation.annotation = function () { - return selectedIDs.length === 1 ? _t('operations.move.annotation.' + context.graph().geometry(selectedIDs[0])) : _t('operations.move.annotation.feature', { - n: selectedIDs.length - }); - }; + if (othIndex && iteratee) { + array = arrayMap(array, baseUnary(iteratee)); + } - operation.id = 'move'; - operation.keys = [_t('operations.move.key')]; - operation.title = _t('operations.move.title'); - operation.behavior = behaviorOperation(context).which(operation); - operation.mouseOnly = true; - return operation; - } + maxLength = nativeMin(array.length, maxLength); + caches[othIndex] = !comparator && (iteratee || length >= 120 && array.length >= 120) ? new SetCache(othIndex && array) : undefined$1; + } - function modeRotate(context, entityIDs) { - var _tolerancePx = 4; // see also behaviorDrag, behaviorSelect, modeMove + array = arrays[0]; + var index = -1, + seen = caches[0]; - var mode = { - id: 'rotate', - button: 'browse' - }; - var keybinding = utilKeybinding('rotate'); - var behaviors = [behaviorEdit(context), operationCircularize(context, entityIDs).behavior, operationDelete(context, entityIDs).behavior, operationMove(context, entityIDs).behavior, operationOrthogonalize(context, entityIDs).behavior, operationReflectLong(context, entityIDs).behavior, operationReflectShort(context, entityIDs).behavior]; - var annotation = entityIDs.length === 1 ? _t('operations.rotate.annotation.' + context.graph().geometry(entityIDs[0])) : _t('operations.rotate.annotation.feature', { - n: entityIDs.length - }); + outer: while (++index < length && result.length < maxLength) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + value = comparator || value !== 0 ? value : 0; - var _prevGraph; + if (!(seen ? cacheHas(seen, computed) : includes(result, computed, comparator))) { + othIndex = othLength; - var _prevAngle; + while (--othIndex) { + var cache = caches[othIndex]; - var _prevTransform; + if (!(cache ? cacheHas(cache, computed) : includes(arrays[othIndex], computed, comparator))) { + continue outer; + } + } - var _pivot; // use pointer events on supported platforms; fallback to mouse events + if (seen) { + seen.push(computed); + } + result.push(value); + } + } - var _pointerPrefix = 'PointerEvent' in window ? 'pointer' : 'mouse'; + return result; + } + /** + * The base implementation of `_.invert` and `_.invertBy` which inverts + * `object` with values transformed by `iteratee` and set by `setter`. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} setter The function to set `accumulator` values. + * @param {Function} iteratee The iteratee to transform values. + * @param {Object} accumulator The initial inverted object. + * @returns {Function} Returns `accumulator`. + */ - function doRotate(d3_event) { - var fn; - if (context.graph() !== _prevGraph) { - fn = context.perform; - } else { - fn = context.replace; - } // projection changed, recalculate _pivot + function baseInverter(object, setter, iteratee, accumulator) { + baseForOwn(object, function (value, key, object) { + setter(accumulator, iteratee(value), key, object); + }); + return accumulator; + } + /** + * The base implementation of `_.invoke` without support for individual + * method arguments. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the method to invoke. + * @param {Array} args The arguments to invoke the method with. + * @returns {*} Returns the result of the invoked method. + */ - var projection = context.projection; - var currTransform = projection.transform(); + function baseInvoke(object, path, args) { + path = castPath(path, object); + object = parent(object, path); + var func = object == null ? object : object[toKey(last(path))]; + return func == null ? undefined$1 : apply(func, object, args); + } + /** + * The base implementation of `_.isArguments`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + */ - if (!_prevTransform || currTransform.k !== _prevTransform.k || currTransform.x !== _prevTransform.x || currTransform.y !== _prevTransform.y) { - var nodes = utilGetAllNodes(entityIDs, context.graph()); - var points = nodes.map(function (n) { - return projection(n.loc); - }); - _pivot = getPivot(points); - _prevAngle = undefined; - } - var currMouse = context.map().mouse(d3_event); - var currAngle = Math.atan2(currMouse[1] - _pivot[1], currMouse[0] - _pivot[0]); - if (typeof _prevAngle === 'undefined') _prevAngle = currAngle; - var delta = currAngle - _prevAngle; - fn(actionRotate(entityIDs, _pivot, delta, projection)); - _prevTransform = currTransform; - _prevAngle = currAngle; - _prevGraph = context.graph(); - } + function baseIsArguments(value) { + return isObjectLike(value) && baseGetTag(value) == argsTag; + } + /** + * The base implementation of `_.isArrayBuffer` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`. + */ - function getPivot(points) { - var _pivot; - if (points.length === 1) { - _pivot = points[0]; - } else if (points.length === 2) { - _pivot = geoVecInterp(points[0], points[1], 0.5); - } else { - var polygonHull = d3_polygonHull(points); + function baseIsArrayBuffer(value) { + return isObjectLike(value) && baseGetTag(value) == arrayBufferTag; + } + /** + * The base implementation of `_.isDate` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a date object, else `false`. + */ - if (polygonHull.length === 2) { - _pivot = geoVecInterp(points[0], points[1], 0.5); - } else { - _pivot = d3_polygonCentroid(d3_polygonHull(points)); + + function baseIsDate(value) { + return isObjectLike(value) && baseGetTag(value) == dateTag; } - } + /** + * The base implementation of `_.isEqual` which supports partial comparisons + * and tracks traversed objects. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {boolean} bitmask The bitmask flags. + * 1 - Unordered comparison + * 2 - Partial comparison + * @param {Function} [customizer] The function to customize comparisons. + * @param {Object} [stack] Tracks traversed `value` and `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ - return _pivot; - } - function finish(d3_event) { - d3_event.stopPropagation(); - context.replace(actionNoop(), annotation); - context.enter(modeSelect(context, entityIDs)); - } + function baseIsEqual(value, other, bitmask, customizer, stack) { + if (value === other) { + return true; + } - function cancel() { - if (_prevGraph) context.pop(); // remove the rotate + if (value == null || other == null || !isObjectLike(value) && !isObjectLike(other)) { + return value !== value && other !== other; + } - context.enter(modeSelect(context, entityIDs)); - } + return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); + } + /** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} [stack] Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ - function undone() { - context.enter(modeBrowse(context)); - } - mode.enter = function () { - _prevGraph = null; - context.features().forceVisible(entityIDs); - behaviors.forEach(context.install); - var downEvent; - context.surface().on(_pointerPrefix + 'down.modeRotate', function (d3_event) { - downEvent = d3_event; - }); - select(window).on(_pointerPrefix + 'move.modeRotate', doRotate, true).on(_pointerPrefix + 'up.modeRotate', function (d3_event) { - if (!downEvent) return; - var mapNode = context.container().select('.main-map').node(); - var pointGetter = utilFastMouse(mapNode); - var p1 = pointGetter(downEvent); - var p2 = pointGetter(d3_event); - var dist = geoVecLength(p1, p2); - if (dist <= _tolerancePx) finish(d3_event); - downEvent = null; - }, true); - context.history().on('undone.modeRotate', undone); - keybinding.on('⎋', cancel).on('↩', finish); - select(document).call(keybinding); - }; + function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { + var objIsArr = isArray(object), + othIsArr = isArray(other), + objTag = objIsArr ? arrayTag : getTag(object), + othTag = othIsArr ? arrayTag : getTag(other); + objTag = objTag == argsTag ? objectTag : objTag; + othTag = othTag == argsTag ? objectTag : othTag; + var objIsObj = objTag == objectTag, + othIsObj = othTag == objectTag, + isSameTag = objTag == othTag; - mode.exit = function () { - behaviors.forEach(context.uninstall); - context.surface().on(_pointerPrefix + 'down.modeRotate', null); - select(window).on(_pointerPrefix + 'move.modeRotate', null, true).on(_pointerPrefix + 'up.modeRotate', null, true); - context.history().on('undone.modeRotate', null); - select(document).call(keybinding.unbind); - context.features().forceVisible([]); - }; + if (isSameTag && isBuffer(object)) { + if (!isBuffer(other)) { + return false; + } - mode.selectedIDs = function () { - if (!arguments.length) return entityIDs; // no assign + objIsArr = true; + objIsObj = false; + } - return mode; - }; + if (isSameTag && !objIsObj) { + stack || (stack = new Stack()); + return objIsArr || isTypedArray(object) ? equalArrays(object, other, bitmask, customizer, equalFunc, stack) : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); + } - return mode; - } + if (!(bitmask & COMPARE_PARTIAL_FLAG)) { + var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), + othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); - function operationRotate(context, selectedIDs) { - var multi = selectedIDs.length === 1 ? 'single' : 'multiple'; - var nodes = utilGetAllNodes(selectedIDs, context.graph()); - var coords = nodes.map(function (n) { - return n.loc; - }); - var extent = utilTotalExtent(selectedIDs, context.graph()); + if (objIsWrapped || othIsWrapped) { + var objUnwrapped = objIsWrapped ? object.value() : object, + othUnwrapped = othIsWrapped ? other.value() : other; + stack || (stack = new Stack()); + return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); + } + } - var operation = function operation() { - context.enter(modeRotate(context, selectedIDs)); - }; + if (!isSameTag) { + return false; + } - operation.available = function () { - return nodes.length >= 2; - }; + stack || (stack = new Stack()); + return equalObjects(object, other, bitmask, customizer, equalFunc, stack); + } + /** + * The base implementation of `_.isMap` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + */ - operation.disabled = function () { - if (extent.percentContainedIn(context.map().extent()) < 0.8) { - return 'too_large'; - } else if (someMissing()) { - return 'not_downloaded'; - } else if (selectedIDs.some(context.hasHiddenConnections)) { - return 'connected_to_hidden'; - } else if (selectedIDs.some(incompleteRelation)) { - return 'incomplete_relation'; - } - return false; + function baseIsMap(value) { + return isObjectLike(value) && getTag(value) == mapTag; + } + /** + * The base implementation of `_.isMatch` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Array} matchData The property names, values, and compare flags to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ - function someMissing() { - if (context.inIntro()) return false; - var osm = context.connection(); - if (osm) { - var missing = coords.filter(function (loc) { - return !osm.isDataLoaded(loc); - }); + function baseIsMatch(object, source, matchData, customizer) { + var index = matchData.length, + length = index, + noCustomizer = !customizer; - if (missing.length) { - missing.forEach(function (loc) { - context.loadTileAtLoc(loc); - }); - return true; + if (object == null) { + return !length; } - } - return false; - } + object = Object(object); - function incompleteRelation(id) { - var entity = context.entity(id); - return entity.type === 'relation' && !entity.isComplete(context.graph()); - } - }; + while (index--) { + var data = matchData[index]; - operation.tooltip = function () { - var disable = operation.disabled(); - return disable ? _t('operations.rotate.' + disable + '.' + multi) : _t('operations.rotate.description.' + multi); - }; + if (noCustomizer && data[2] ? data[1] !== object[data[0]] : !(data[0] in object)) { + return false; + } + } - operation.annotation = function () { - return selectedIDs.length === 1 ? _t('operations.rotate.annotation.' + context.graph().geometry(selectedIDs[0])) : _t('operations.rotate.annotation.feature', { - n: selectedIDs.length - }); - }; + while (++index < length) { + data = matchData[index]; + var key = data[0], + objValue = object[key], + srcValue = data[1]; - operation.id = 'rotate'; - operation.keys = [_t('operations.rotate.key')]; - operation.title = _t('operations.rotate.title'); - operation.behavior = behaviorOperation(context).which(operation); - operation.mouseOnly = true; - return operation; - } + if (noCustomizer && data[2]) { + if (objValue === undefined$1 && !(key in object)) { + return false; + } + } else { + var stack = new Stack(); - function modeMove(context, entityIDs, baseGraph) { - var _tolerancePx = 4; // see also behaviorDrag, behaviorSelect, modeRotate + if (customizer) { + var result = customizer(objValue, srcValue, key, object, source, stack); + } - var mode = { - id: 'move', - button: 'browse' - }; - var keybinding = utilKeybinding('move'); - var behaviors = [behaviorEdit(context), operationCircularize(context, entityIDs).behavior, operationDelete(context, entityIDs).behavior, operationOrthogonalize(context, entityIDs).behavior, operationReflectLong(context, entityIDs).behavior, operationReflectShort(context, entityIDs).behavior, operationRotate(context, entityIDs).behavior]; - var annotation = entityIDs.length === 1 ? _t('operations.move.annotation.' + context.graph().geometry(entityIDs[0])) : _t('operations.move.annotation.feature', { - n: entityIDs.length - }); + if (!(result === undefined$1 ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack) : result)) { + return false; + } + } + } - var _prevGraph; + return true; + } + /** + * The base implementation of `_.isNative` without bad shim checks. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + */ - var _cache; - var _origin; + function baseIsNative(value) { + if (!isObject(value) || isMasked(value)) { + return false; + } - var _nudgeInterval; // use pointer events on supported platforms; fallback to mouse events + var pattern = isFunction(value) ? reIsNative : reIsHostCtor; + return pattern.test(toSource(value)); + } + /** + * The base implementation of `_.isRegExp` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a regexp, else `false`. + */ - var _pointerPrefix = 'PointerEvent' in window ? 'pointer' : 'mouse'; + function baseIsRegExp(value) { + return isObjectLike(value) && baseGetTag(value) == regexpTag; + } + /** + * The base implementation of `_.isSet` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + */ - function doMove(nudge) { - nudge = nudge || [0, 0]; - var fn; - if (_prevGraph !== context.graph()) { - _cache = {}; - _origin = context.map().mouseCoordinates(); - fn = context.perform; - } else { - fn = context.overwrite; - } + function baseIsSet(value) { + return isObjectLike(value) && getTag(value) == setTag; + } + /** + * The base implementation of `_.isTypedArray` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. + */ - var currMouse = context.map().mouse(); - var origMouse = context.projection(_origin); - var delta = geoVecSubtract(geoVecSubtract(currMouse, origMouse), nudge); - fn(actionMove(entityIDs, delta, context.projection, _cache)); - _prevGraph = context.graph(); - } - function startNudge(nudge) { - if (_nudgeInterval) window.clearInterval(_nudgeInterval); - _nudgeInterval = window.setInterval(function () { - context.map().pan(nudge); - doMove(nudge); - }, 50); - } + function baseIsTypedArray(value) { + return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[baseGetTag(value)]; + } + /** + * The base implementation of `_.iteratee`. + * + * @private + * @param {*} [value=_.identity] The value to convert to an iteratee. + * @returns {Function} Returns the iteratee. + */ - function stopNudge() { - if (_nudgeInterval) { - window.clearInterval(_nudgeInterval); - _nudgeInterval = null; - } - } - function move() { - doMove(); - var nudge = geoViewportEdge(context.map().mouse(), context.map().dimensions()); + function baseIteratee(value) { + // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. + // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. + if (typeof value == 'function') { + return value; + } - if (nudge) { - startNudge(nudge); - } else { - stopNudge(); - } - } + if (value == null) { + return identity; + } - function finish(d3_event) { - d3_event.stopPropagation(); - context.replace(actionNoop(), annotation); - context.enter(modeSelect(context, entityIDs)); - stopNudge(); - } + if (_typeof(value) == 'object') { + return isArray(value) ? baseMatchesProperty(value[0], value[1]) : baseMatches(value); + } - function cancel() { - if (baseGraph) { - while (context.graph() !== baseGraph) { - context.pop(); - } // reset to baseGraph + return property(value); + } + /** + * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ - context.enter(modeBrowse(context)); - } else { - if (_prevGraph) context.pop(); // remove the move - - context.enter(modeSelect(context, entityIDs)); - } - - stopNudge(); - } + function baseKeys(object) { + if (!isPrototype(object)) { + return nativeKeys(object); + } - function undone() { - context.enter(modeBrowse(context)); - } + var result = []; - mode.enter = function () { - _origin = context.map().mouseCoordinates(); - _prevGraph = null; - _cache = {}; - context.features().forceVisible(entityIDs); - behaviors.forEach(context.install); - var downEvent; - context.surface().on(_pointerPrefix + 'down.modeMove', function (d3_event) { - downEvent = d3_event; - }); - select(window).on(_pointerPrefix + 'move.modeMove', move, true).on(_pointerPrefix + 'up.modeMove', function (d3_event) { - if (!downEvent) return; - var mapNode = context.container().select('.main-map').node(); - var pointGetter = utilFastMouse(mapNode); - var p1 = pointGetter(downEvent); - var p2 = pointGetter(d3_event); - var dist = geoVecLength(p1, p2); - if (dist <= _tolerancePx) finish(d3_event); - downEvent = null; - }, true); - context.history().on('undone.modeMove', undone); - keybinding.on('⎋', cancel).on('↩', finish); - select(document).call(keybinding); - }; + for (var key in Object(object)) { + if (hasOwnProperty.call(object, key) && key != 'constructor') { + result.push(key); + } + } - mode.exit = function () { - stopNudge(); - behaviors.forEach(function (behavior) { - context.uninstall(behavior); - }); - context.surface().on(_pointerPrefix + 'down.modeMove', null); - select(window).on(_pointerPrefix + 'move.modeMove', null, true).on(_pointerPrefix + 'up.modeMove', null, true); - context.history().on('undone.modeMove', null); - select(document).call(keybinding.unbind); - context.features().forceVisible([]); - }; + return result; + } + /** + * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ - mode.selectedIDs = function () { - if (!arguments.length) return entityIDs; // no assign - return mode; - }; + function baseKeysIn(object) { + if (!isObject(object)) { + return nativeKeysIn(object); + } - return mode; - } + var isProto = isPrototype(object), + result = []; - function behaviorPaste(context) { - function doPaste(d3_event) { - // prevent paste during low zoom selection - if (!context.map().withinEditableZoom()) return; - d3_event.preventDefault(); - var baseGraph = context.graph(); - var mouse = context.map().mouse(); - var projection = context.projection; - var viewport = geoExtent(projection.clipExtent()).polygon(); - if (!geoPointInPolygon(mouse, viewport)) return; - var oldIDs = context.copyIDs(); - if (!oldIDs.length) return; - var extent = geoExtent(); - var oldGraph = context.copyGraph(); - var newIDs = []; - var action = actionCopyEntities(oldIDs, oldGraph); - context.perform(action); - var copies = action.copies(); - var originals = new Set(); - Object.values(copies).forEach(function (entity) { - originals.add(entity.id); - }); + for (var key in object) { + if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { + result.push(key); + } + } - for (var id in copies) { - var oldEntity = oldGraph.entity(id); - var newEntity = copies[id]; + return result; + } + /** + * The base implementation of `_.lt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than `other`, + * else `false`. + */ - extent._extend(oldEntity.extent(oldGraph)); // Exclude child nodes from newIDs if their parent way was also copied. + function baseLt(value, other) { + return value < other; + } + /** + * The base implementation of `_.map` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ - var parents = context.graph().parentWays(newEntity); - var parentCopied = parents.some(function (parent) { - return originals.has(parent.id); - }); - if (!parentCopied) { - newIDs.push(newEntity.id); + function baseMap(collection, iteratee) { + var index = -1, + result = isArrayLike(collection) ? Array(collection.length) : []; + baseEach(collection, function (value, key, collection) { + result[++index] = iteratee(value, key, collection); + }); + return result; } - } // Put pasted objects where mouse pointer is.. + /** + * The base implementation of `_.matches` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new spec function. + */ - var copyPoint = context.copyLonLat() && projection(context.copyLonLat()) || projection(extent.center()); - var delta = geoVecSubtract(mouse, copyPoint); - context.perform(actionMove(newIDs, delta, projection)); - context.enter(modeMove(context, newIDs, baseGraph)); - } + function baseMatches(source) { + var matchData = getMatchData(source); - function behavior() { - context.keybinding().on(uiCmd('⌘V'), doPaste); - return behavior; - } + if (matchData.length == 1 && matchData[0][2]) { + return matchesStrictComparable(matchData[0][0], matchData[0][1]); + } - behavior.off = function () { - context.keybinding().off(uiCmd('⌘V')); - }; + return function (object) { + return object === source || baseIsMatch(object, source, matchData); + }; + } + /** + * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. + * + * @private + * @param {string} path The path of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ - return behavior; - } - var $$5 = _export; - var repeat = stringRepeat; + function baseMatchesProperty(path, srcValue) { + if (isKey(path) && isStrictComparable(srcValue)) { + return matchesStrictComparable(toKey(path), srcValue); + } - // `String.prototype.repeat` method - // https://tc39.es/ecma262/#sec-string.prototype.repeat - $$5({ target: 'String', proto: true }, { - repeat: repeat - }); + return function (object) { + var objValue = get(object, path); + return objValue === undefined$1 && objValue === srcValue ? hasIn(object, path) : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG); + }; + } + /** + * The base implementation of `_.merge` without support for multiple sources. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {number} srcIndex The index of `source`. + * @param {Function} [customizer] The function to customize merged values. + * @param {Object} [stack] Tracks traversed source values and their merged + * counterparts. + */ - /* - `behaviorDrag` is like `d3_behavior.drag`, with the following differences: - * The `origin` function is expected to return an [x, y] tuple rather than an - {x, y} object. - * The events are `start`, `move`, and `end`. - (https://github.com/mbostock/d3/issues/563) - * The `start` event is not dispatched until the first cursor movement occurs. - (https://github.com/mbostock/d3/pull/368) - * The `move` event has a `point` and `delta` [x, y] tuple properties rather - than `x`, `y`, `dx`, and `dy` properties. - * The `end` event is not dispatched if no movement occurs. - * An `off` function is available that unbinds the drag's internal event handlers. - */ + function baseMerge(object, source, srcIndex, customizer, stack) { + if (object === source) { + return; + } - function behaviorDrag() { - var dispatch = dispatch$8('start', 'move', 'end'); // see also behaviorSelect + baseFor(source, function (srcValue, key) { + stack || (stack = new Stack()); - var _tolerancePx = 1; // keep this low to facilitate pixel-perfect micromapping + if (isObject(srcValue)) { + baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack); + } else { + var newValue = customizer ? customizer(safeGet(object, key), srcValue, key + '', object, source, stack) : undefined$1; - var _penTolerancePx = 4; // styluses can be touchy so require greater movement - #1981 + if (newValue === undefined$1) { + newValue = srcValue; + } - var _origin = null; - var _selector = ''; + assignMergeValue(object, key, newValue); + } + }, keysIn); + } + /** + * A specialized version of `baseMerge` for arrays and objects which performs + * deep merges and tracks traversed objects enabling objects with circular + * references to be merged. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {string} key The key of the value to merge. + * @param {number} srcIndex The index of `source`. + * @param {Function} mergeFunc The function to merge values. + * @param {Function} [customizer] The function to customize assigned values. + * @param {Object} [stack] Tracks traversed source values and their merged + * counterparts. + */ - var _targetNode; - var _targetEntity; + function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) { + var objValue = safeGet(object, key), + srcValue = safeGet(source, key), + stacked = stack.get(srcValue); - var _surface; + if (stacked) { + assignMergeValue(object, key, stacked); + return; + } - var _pointerId; // use pointer events on supported platforms; fallback to mouse events + var newValue = customizer ? customizer(objValue, srcValue, key + '', object, source, stack) : undefined$1; + var isCommon = newValue === undefined$1; + + if (isCommon) { + var isArr = isArray(srcValue), + isBuff = !isArr && isBuffer(srcValue), + isTyped = !isArr && !isBuff && isTypedArray(srcValue); + newValue = srcValue; + + if (isArr || isBuff || isTyped) { + if (isArray(objValue)) { + newValue = objValue; + } else if (isArrayLikeObject(objValue)) { + newValue = copyArray(objValue); + } else if (isBuff) { + isCommon = false; + newValue = cloneBuffer(srcValue, true); + } else if (isTyped) { + isCommon = false; + newValue = cloneTypedArray(srcValue, true); + } else { + newValue = []; + } + } else if (isPlainObject(srcValue) || isArguments(srcValue)) { + newValue = objValue; + if (isArguments(objValue)) { + newValue = toPlainObject(objValue); + } else if (!isObject(objValue) || isFunction(objValue)) { + newValue = initCloneObject(srcValue); + } + } else { + isCommon = false; + } + } - var _pointerPrefix = 'PointerEvent' in window ? 'pointer' : 'mouse'; + if (isCommon) { + // Recursively merge objects and arrays (susceptible to call stack limits). + stack.set(srcValue, newValue); + mergeFunc(newValue, srcValue, srcIndex, customizer, stack); + stack['delete'](srcValue); + } - var d3_event_userSelectProperty = utilPrefixCSSProperty('UserSelect'); + assignMergeValue(object, key, newValue); + } + /** + * The base implementation of `_.nth` which doesn't coerce arguments. + * + * @private + * @param {Array} array The array to query. + * @param {number} n The index of the element to return. + * @returns {*} Returns the nth element of `array`. + */ - var d3_event_userSelectSuppress = function d3_event_userSelectSuppress() { - var selection$1 = selection(); - var select = selection$1.style(d3_event_userSelectProperty); - selection$1.style(d3_event_userSelectProperty, 'none'); - return function () { - selection$1.style(d3_event_userSelectProperty, select); - }; - }; - function pointerdown(d3_event) { - if (_pointerId) return; - _pointerId = d3_event.pointerId || 'mouse'; - _targetNode = this; // only force reflow once per drag + function baseNth(array, n) { + var length = array.length; - var pointerLocGetter = utilFastMouse(_surface || _targetNode.parentNode); - var offset; - var startOrigin = pointerLocGetter(d3_event); - var started = false; - var selectEnable = d3_event_userSelectSuppress(); - select(window).on(_pointerPrefix + 'move.drag', pointermove).on(_pointerPrefix + 'up.drag pointercancel.drag', pointerup, true); + if (!length) { + return; + } - if (_origin) { - offset = _origin.call(_targetNode, _targetEntity); - offset = [offset[0] - startOrigin[0], offset[1] - startOrigin[1]]; - } else { - offset = [0, 0]; - } + n += n < 0 ? length : 0; + return isIndex(n, length) ? array[n] : undefined$1; + } + /** + * The base implementation of `_.orderBy` without param guards. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {string[]} orders The sort orders of `iteratees`. + * @returns {Array} Returns the new sorted array. + */ - d3_event.stopPropagation(); - function pointermove(d3_event) { - if (_pointerId !== (d3_event.pointerId || 'mouse')) return; - var p = pointerLocGetter(d3_event); + function baseOrderBy(collection, iteratees, orders) { + if (iteratees.length) { + iteratees = arrayMap(iteratees, function (iteratee) { + if (isArray(iteratee)) { + return function (value) { + return baseGet(value, iteratee.length === 1 ? iteratee[0] : iteratee); + }; + } - if (!started) { - var dist = geoVecLength(startOrigin, p); - var tolerance = d3_event.pointerType === 'pen' ? _penTolerancePx : _tolerancePx; // don't start until the drag has actually moved somewhat + return iteratee; + }); + } else { + iteratees = [identity]; + } - if (dist < tolerance) return; - started = true; - dispatch.call('start', this, d3_event, _targetEntity); // Don't send a `move` event in the same cycle as `start` since dragging - // a midpoint will convert the target to a node. - } else { - startOrigin = p; - d3_event.stopPropagation(); - d3_event.preventDefault(); - var dx = p[0] - startOrigin[0]; - var dy = p[1] - startOrigin[1]; - dispatch.call('move', this, d3_event, _targetEntity, [p[0] + offset[0], p[1] + offset[1]], [dx, dy]); + var index = -1; + iteratees = arrayMap(iteratees, baseUnary(getIteratee())); + var result = baseMap(collection, function (value, key, collection) { + var criteria = arrayMap(iteratees, function (iteratee) { + return iteratee(value); + }); + return { + 'criteria': criteria, + 'index': ++index, + 'value': value + }; + }); + return baseSortBy(result, function (object, other) { + return compareMultiple(object, other, orders); + }); } - } + /** + * The base implementation of `_.pick` without support for individual + * property identifiers. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @returns {Object} Returns the new object. + */ - function pointerup(d3_event) { - if (_pointerId !== (d3_event.pointerId || 'mouse')) return; - _pointerId = null; - if (started) { - dispatch.call('end', this, d3_event, _targetEntity); - d3_event.preventDefault(); + function basePick(object, paths) { + return basePickBy(object, paths, function (value, path) { + return hasIn(object, path); + }); } + /** + * The base implementation of `_.pickBy` without support for iteratee shorthands. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @param {Function} predicate The function invoked per property. + * @returns {Object} Returns the new object. + */ - select(window).on(_pointerPrefix + 'move.drag', null).on(_pointerPrefix + 'up.drag pointercancel.drag', null); - selectEnable(); - } - } - - function behavior(selection) { - var matchesSelector = utilPrefixDOMProperty('matchesSelector'); - var delegate = pointerdown; - if (_selector) { - delegate = function delegate(d3_event) { - var root = this; - var target = d3_event.target; + function basePickBy(object, paths, predicate) { + var index = -1, + length = paths.length, + result = {}; - for (; target && target !== root; target = target.parentNode) { - var datum = target.__data__; - _targetEntity = datum instanceof osmNote ? datum : datum && datum.properties && datum.properties.entity; + while (++index < length) { + var path = paths[index], + value = baseGet(object, path); - if (_targetEntity && target[matchesSelector](_selector)) { - return pointerdown.call(target, d3_event); + if (predicate(value, path)) { + baseSet(result, castPath(path, object), value); } } - }; - } - selection.on(_pointerPrefix + 'down.drag' + _selector, delegate); - } + return result; + } + /** + * A specialized version of `baseProperty` which supports deep paths. + * + * @private + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + */ - behavior.off = function (selection) { - selection.on(_pointerPrefix + 'down.drag' + _selector, null); - }; - behavior.selector = function (_) { - if (!arguments.length) return _selector; - _selector = _; - return behavior; - }; + function basePropertyDeep(path) { + return function (object) { + return baseGet(object, path); + }; + } + /** + * The base implementation of `_.pullAllBy` without support for iteratee + * shorthands. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to remove. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns `array`. + */ - behavior.origin = function (_) { - if (!arguments.length) return _origin; - _origin = _; - return behavior; - }; - behavior.cancel = function () { - select(window).on(_pointerPrefix + 'move.drag', null).on(_pointerPrefix + 'up.drag pointercancel.drag', null); - return behavior; - }; + function basePullAll(array, values, iteratee, comparator) { + var indexOf = comparator ? baseIndexOfWith : baseIndexOf, + index = -1, + length = values.length, + seen = array; - behavior.targetNode = function (_) { - if (!arguments.length) return _targetNode; - _targetNode = _; - return behavior; - }; + if (array === values) { + values = copyArray(values); + } - behavior.targetEntity = function (_) { - if (!arguments.length) return _targetEntity; - _targetEntity = _; - return behavior; - }; + if (iteratee) { + seen = arrayMap(array, baseUnary(iteratee)); + } - behavior.surface = function (_) { - if (!arguments.length) return _surface; - _surface = _; - return behavior; - }; + while (++index < length) { + var fromIndex = 0, + value = values[index], + computed = iteratee ? iteratee(value) : value; - return utilRebind(behavior, dispatch, 'on'); - } + while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) { + if (seen !== array) { + splice.call(seen, fromIndex, 1); + } - function modeDragNode(context) { - var mode = { - id: 'drag-node', - button: 'browse' - }; - var hover = behaviorHover(context).altDisables(true).on('hover', context.ui().sidebar.hover); - var edit = behaviorEdit(context); + splice.call(array, fromIndex, 1); + } + } - var _nudgeInterval; + return array; + } + /** + * The base implementation of `_.pullAt` without support for individual + * indexes or capturing the removed elements. + * + * @private + * @param {Array} array The array to modify. + * @param {number[]} indexes The indexes of elements to remove. + * @returns {Array} Returns `array`. + */ - var _restoreSelectedIDs = []; - var _wasMidpoint = false; - var _isCancelled = false; - var _activeEntity; + function basePullAt(array, indexes) { + var length = array ? indexes.length : 0, + lastIndex = length - 1; - var _startLoc; + while (length--) { + var index = indexes[length]; - var _lastLoc; + if (length == lastIndex || index !== previous) { + var previous = index; - function startNudge(d3_event, entity, nudge) { - if (_nudgeInterval) window.clearInterval(_nudgeInterval); - _nudgeInterval = window.setInterval(function () { - context.map().pan(nudge); - doMove(d3_event, entity, nudge); - }, 50); - } + if (isIndex(index)) { + splice.call(array, index, 1); + } else { + baseUnset(array, index); + } + } + } - function stopNudge() { - if (_nudgeInterval) { - window.clearInterval(_nudgeInterval); - _nudgeInterval = null; - } - } + return array; + } + /** + * The base implementation of `_.random` without support for returning + * floating-point numbers. + * + * @private + * @param {number} lower The lower bound. + * @param {number} upper The upper bound. + * @returns {number} Returns the random number. + */ - function moveAnnotation(entity) { - return _t('operations.move.annotation.' + entity.geometry(context.graph())); - } - function connectAnnotation(nodeEntity, targetEntity) { - var nodeGeometry = nodeEntity.geometry(context.graph()); - var targetGeometry = targetEntity.geometry(context.graph()); + function baseRandom(lower, upper) { + return lower + nativeFloor(nativeRandom() * (upper - lower + 1)); + } + /** + * The base implementation of `_.range` and `_.rangeRight` which doesn't + * coerce arguments. + * + * @private + * @param {number} start The start of the range. + * @param {number} end The end of the range. + * @param {number} step The value to increment or decrement by. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the range of numbers. + */ - if (nodeGeometry === 'vertex' && targetGeometry === 'vertex') { - var nodeParentWayIDs = context.graph().parentWays(nodeEntity); - var targetParentWayIDs = context.graph().parentWays(targetEntity); - var sharedParentWays = utilArrayIntersection(nodeParentWayIDs, targetParentWayIDs); // if both vertices are part of the same way - if (sharedParentWays.length !== 0) { - // if the nodes are next to each other, they are merged - if (sharedParentWays[0].areAdjacent(nodeEntity.id, targetEntity.id)) { - return _t('operations.connect.annotation.from_vertex.to_adjacent_vertex'); + function baseRange(start, end, step, fromRight) { + var index = -1, + length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), + result = Array(length); + + while (length--) { + result[fromRight ? length : ++index] = start; + start += step; } - return _t('operations.connect.annotation.from_vertex.to_sibling_vertex'); + return result; } - } + /** + * The base implementation of `_.repeat` which doesn't coerce arguments. + * + * @private + * @param {string} string The string to repeat. + * @param {number} n The number of times to repeat the string. + * @returns {string} Returns the repeated string. + */ - return _t('operations.connect.annotation.from_' + nodeGeometry + '.to_' + targetGeometry); - } - function shouldSnapToNode(target) { - if (!_activeEntity) return false; - return _activeEntity.geometry(context.graph()) !== 'vertex' || target.geometry(context.graph()) === 'vertex' || _mainPresetIndex.allowsVertex(target, context.graph()); - } + function baseRepeat(string, n) { + var result = ''; - function origin(entity) { - return context.projection(entity.loc); - } + if (!string || n < 1 || n > MAX_SAFE_INTEGER) { + return result; + } // Leverage the exponentiation by squaring algorithm for a faster repeat. + // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details. - function keydown(d3_event) { - if (d3_event.keyCode === utilKeybinding.modifierCodes.alt) { - if (context.surface().classed('nope')) { - context.surface().classed('nope-suppressed', true); - } - context.surface().classed('nope', false).classed('nope-disabled', true); - } - } + do { + if (n % 2) { + result += string; + } - function keyup(d3_event) { - if (d3_event.keyCode === utilKeybinding.modifierCodes.alt) { - if (context.surface().classed('nope-suppressed')) { - context.surface().classed('nope', true); + n = nativeFloor(n / 2); + + if (n) { + string += string; + } + } while (n); + + return result; } + /** + * The base implementation of `_.rest` which doesn't validate or coerce arguments. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @returns {Function} Returns the new function. + */ - context.surface().classed('nope-suppressed', false).classed('nope-disabled', false); - } - } - function start(d3_event, entity) { - _wasMidpoint = entity.type === 'midpoint'; - var hasHidden = context.features().hasHiddenConnections(entity, context.graph()); - _isCancelled = !context.editable() || d3_event.shiftKey || hasHidden; + function baseRest(func, start) { + return setToString(overRest(func, start, identity), func + ''); + } + /** + * The base implementation of `_.sample`. + * + * @private + * @param {Array|Object} collection The collection to sample. + * @returns {*} Returns the random element. + */ - if (_isCancelled) { - if (hasHidden) { - context.ui().flash.duration(4000).iconName('#iD-icon-no').label(_t('modes.drag_node.connected_to_hidden'))(); + + function baseSample(collection) { + return arraySample(values(collection)); } + /** + * The base implementation of `_.sampleSize` without param guards. + * + * @private + * @param {Array|Object} collection The collection to sample. + * @param {number} n The number of elements to sample. + * @returns {Array} Returns the random elements. + */ - return drag.cancel(); - } - if (_wasMidpoint) { - var midpoint = entity; - entity = osmNode(); - context.perform(actionAddMidpoint(midpoint, entity)); - entity = context.entity(entity.id); // get post-action entity + function baseSampleSize(collection, n) { + var array = values(collection); + return shuffleSelf(array, baseClamp(n, 0, array.length)); + } + /** + * The base implementation of `_.set`. + * + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. + */ - var vertex = context.surface().selectAll('.' + entity.id); - drag.targetNode(vertex.node()).targetEntity(entity); - } else { - context.perform(actionNoop()); - } - _activeEntity = entity; - _startLoc = entity.loc; - hover.ignoreVertex(entity.geometry(context.graph()) === 'vertex'); - context.surface().selectAll('.' + _activeEntity.id).classed('active', true); - context.enter(mode); - } // related code - // - `behavior/draw.js` `datum()` + function baseSet(object, path, value, customizer) { + if (!isObject(object)) { + return object; + } + path = castPath(path, object); + var index = -1, + length = path.length, + lastIndex = length - 1, + nested = object; - function datum(d3_event) { - if (!d3_event || d3_event.altKey) { - return {}; - } else { - // When dragging, snap only to touch targets.. - // (this excludes area fills and active drawing elements) - var d = d3_event.target.__data__; - return d && d.properties && d.properties.target ? d : {}; - } - } + while (nested != null && ++index < length) { + var key = toKey(path[index]), + newValue = value; - function doMove(d3_event, entity, nudge) { - nudge = nudge || [0, 0]; - var currPoint = d3_event && d3_event.point || context.projection(_lastLoc); - var currMouse = geoVecSubtract(currPoint, nudge); - var loc = context.projection.invert(currMouse); - var target, edge; + if (key === '__proto__' || key === 'constructor' || key === 'prototype') { + return object; + } - if (!_nudgeInterval) { - // If not nudging at the edge of the viewport, try to snap.. - // related code - // - `mode/drag_node.js` `doMove()` - // - `behavior/draw.js` `click()` - // - `behavior/draw_way.js` `move()` - var d = datum(d3_event); - target = d && d.properties && d.properties.entity; - var targetLoc = target && target.loc; - var targetNodes = d && d.properties && d.properties.nodes; + if (index != lastIndex) { + var objValue = nested[key]; + newValue = customizer ? customizer(objValue, key, nested) : undefined$1; - if (targetLoc) { - // snap to node/vertex - a point target with `.loc` - if (shouldSnapToNode(target)) { - loc = targetLoc; - } - } else if (targetNodes) { - // snap to way - a line target with `.nodes` - edge = geoChooseEdge(targetNodes, context.map().mouse(), context.projection, end.id); + if (newValue === undefined$1) { + newValue = isObject(objValue) ? objValue : isIndex(path[index + 1]) ? [] : {}; + } + } - if (edge) { - loc = edge.loc; + assignValue(nested, key, newValue); + nested = nested[key]; } - } - } - - context.replace(actionMoveNode(entity.id, loc)); // Below here: validations - var isInvalid = false; // Check if this connection to `target` could cause relations to break.. - - if (target) { - isInvalid = hasRelationConflict(entity, target, edge, context.graph()); - } // Check if this drag causes the geometry to break.. + return object; + } + /** + * The base implementation of `setData` without support for hot loop shorting. + * + * @private + * @param {Function} func The function to associate metadata with. + * @param {*} data The metadata. + * @returns {Function} Returns `func`. + */ - if (!isInvalid) { - isInvalid = hasInvalidGeometry(entity, context.graph()); - } + var baseSetData = !metaMap ? identity : function (func, data) { + metaMap.set(func, data); + return func; + }; + /** + * The base implementation of `setToString` without support for hot loop shorting. + * + * @private + * @param {Function} func The function to modify. + * @param {Function} string The `toString` result. + * @returns {Function} Returns `func`. + */ - var nope = context.surface().classed('nope'); + var baseSetToString = !defineProperty ? identity : function (func, string) { + return defineProperty(func, 'toString', { + 'configurable': true, + 'enumerable': false, + 'value': constant(string), + 'writable': true + }); + }; + /** + * The base implementation of `_.shuffle`. + * + * @private + * @param {Array|Object} collection The collection to shuffle. + * @returns {Array} Returns the new shuffled array. + */ - if (isInvalid === 'relation' || isInvalid === 'restriction') { - if (!nope) { - // about to nope - show hint - context.ui().flash.duration(4000).iconName('#iD-icon-no').label(_t('operations.connect.' + isInvalid, { - relation: _mainPresetIndex.item('type/restriction').name() - }))(); - } - } else if (isInvalid) { - var errorID = isInvalid === 'line' ? 'lines' : 'areas'; - context.ui().flash.duration(3000).iconName('#iD-icon-no').label(_t('self_intersection.error.' + errorID))(); - } else { - if (nope) { - // about to un-nope, remove hint - context.ui().flash.duration(1).label('')(); + function baseShuffle(collection) { + return shuffleSelf(values(collection)); } - } - - var nopeDisabled = context.surface().classed('nope-disabled'); + /** + * The base implementation of `_.slice` without an iteratee call guard. + * + * @private + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ - if (nopeDisabled) { - context.surface().classed('nope', false).classed('nope-suppressed', isInvalid); - } else { - context.surface().classed('nope', isInvalid).classed('nope-suppressed', false); - } - _lastLoc = loc; - } // Uses `actionConnect.disabled()` to know whether this connection is ok.. + function baseSlice(array, start, end) { + var index = -1, + length = array.length; + if (start < 0) { + start = -start > length ? 0 : length + start; + } - function hasRelationConflict(entity, target, edge, graph) { - var testGraph = graph.update(); // copy - // if snapping to way - add midpoint there and consider that the target.. + end = end > length ? length : end; - if (edge) { - var midpoint = osmNode(); - var action = actionAddMidpoint({ - loc: edge.loc, - edge: [target.nodes[edge.index - 1], target.nodes[edge.index]] - }, midpoint); - testGraph = action(testGraph); - target = midpoint; - } // can we connect to it? + if (end < 0) { + end += length; + } + length = start > end ? 0 : end - start >>> 0; + start >>>= 0; + var result = Array(length); - var ids = [entity.id, target.id]; - return actionConnect(ids).disabled(testGraph); - } + while (++index < length) { + result[index] = array[index + start]; + } - function hasInvalidGeometry(entity, graph) { - var parents = graph.parentWays(entity); - var i, j, k; + return result; + } + /** + * The base implementation of `_.some` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ - for (i = 0; i < parents.length; i++) { - var parent = parents[i]; - var nodes = []; - var activeIndex = null; // which multipolygon ring contains node being dragged - // test any parent multipolygons for valid geometry - var relations = graph.parentRelations(parent); + function baseSome(collection, predicate) { + var result; + baseEach(collection, function (value, index, collection) { + result = predicate(value, index, collection); + return !result; + }); + return !!result; + } + /** + * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which + * performs a binary search of `array` to determine the index at which `value` + * should be inserted into `array` in order to maintain its sort order. + * + * @private + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {boolean} [retHighest] Specify returning the highest qualified index. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + */ - for (j = 0; j < relations.length; j++) { - if (!relations[j].isMultipolygon()) continue; - var rings = osmJoinWays(relations[j].members, graph); // find active ring and test it for self intersections - for (k = 0; k < rings.length; k++) { - nodes = rings[k].nodes; + function baseSortedIndex(array, value, retHighest) { + var low = 0, + high = array == null ? low : array.length; - if (nodes.find(function (n) { - return n.id === entity.id; - })) { - activeIndex = k; + if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) { + while (low < high) { + var mid = low + high >>> 1, + computed = array[mid]; - if (geoHasSelfIntersections(nodes, entity.id)) { - return 'multipolygonMember'; + if (computed !== null && !isSymbol(computed) && (retHighest ? computed <= value : computed < value)) { + low = mid + 1; + } else { + high = mid; } } - rings[k].coords = nodes.map(function (n) { - return n.loc; - }); - } // test active ring for intersections with other rings in the multipolygon + return high; + } + + return baseSortedIndexBy(array, value, identity, retHighest); + } + /** + * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy` + * which invokes `iteratee` for `value` and each element of `array` to compute + * their sort ranking. The iteratee is invoked with one argument; (value). + * + * @private + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function} iteratee The iteratee invoked per element. + * @param {boolean} [retHighest] Specify returning the highest qualified index. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + */ - for (k = 0; k < rings.length; k++) { - if (k === activeIndex) continue; // make sure active ring doesn't cross passive rings + function baseSortedIndexBy(array, value, iteratee, retHighest) { + var low = 0, + high = array == null ? 0 : array.length; - if (geoHasLineIntersections(rings[activeIndex].nodes, rings[k].nodes, entity.id)) { - return 'multipolygonRing'; + if (high === 0) { + return 0; + } + + value = iteratee(value); + var valIsNaN = value !== value, + valIsNull = value === null, + valIsSymbol = isSymbol(value), + valIsUndefined = value === undefined$1; + + while (low < high) { + var mid = nativeFloor((low + high) / 2), + computed = iteratee(array[mid]), + othIsDefined = computed !== undefined$1, + othIsNull = computed === null, + othIsReflexive = computed === computed, + othIsSymbol = isSymbol(computed); + + if (valIsNaN) { + var setLow = retHighest || othIsReflexive; + } else if (valIsUndefined) { + setLow = othIsReflexive && (retHighest || othIsDefined); + } else if (valIsNull) { + setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull); + } else if (valIsSymbol) { + setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol); + } else if (othIsNull || othIsSymbol) { + setLow = false; + } else { + setLow = retHighest ? computed <= value : computed < value; + } + + if (setLow) { + low = mid + 1; + } else { + high = mid; } } - } // If we still haven't tested this node's parent way for self-intersections. - // (because it's not a member of a multipolygon), test it now. + return nativeMin(high, MAX_ARRAY_INDEX); + } + /** + * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without + * support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @returns {Array} Returns the new duplicate free array. + */ - if (activeIndex === null) { - nodes = parent.nodes.map(function (nodeID) { - return graph.entity(nodeID); - }); - if (nodes.length && geoHasSelfIntersections(nodes, entity.id)) { - return parent.geometry(graph); + function baseSortedUniq(array, iteratee) { + var index = -1, + length = array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + if (!index || !eq(computed, seen)) { + var seen = computed; + result[resIndex++] = value === 0 ? 0 : value; + } } + + return result; } - } + /** + * The base implementation of `_.toNumber` which doesn't ensure correct + * conversions of binary, hexadecimal, or octal string values. + * + * @private + * @param {*} value The value to process. + * @returns {number} Returns the number. + */ - return false; - } - function move(d3_event, entity, point) { - if (_isCancelled) return; - d3_event.stopPropagation(); - context.surface().classed('nope-disabled', d3_event.altKey); - _lastLoc = context.projection.invert(point); - doMove(d3_event, entity); - var nudge = geoViewportEdge(point, context.map().dimensions()); + function baseToNumber(value) { + if (typeof value == 'number') { + return value; + } - if (nudge) { - startNudge(d3_event, entity, nudge); - } else { - stopNudge(); - } - } + if (isSymbol(value)) { + return NAN; + } - function end(d3_event, entity) { - if (_isCancelled) return; - var wasPoint = entity.geometry(context.graph()) === 'point'; - var d = datum(d3_event); - var nope = d && d.properties && d.properties.nope || context.surface().classed('nope'); - var target = d && d.properties && d.properties.entity; // entity to snap to + return +value; + } + /** + * The base implementation of `_.toString` which doesn't convert nullish + * values to empty strings. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ - if (nope) { - // bounce back - context.perform(_actionBounceBack(entity.id, _startLoc)); - } else if (target && target.type === 'way') { - var choice = geoChooseEdge(context.graph().childNodes(target), context.map().mouse(), context.projection, entity.id); - context.replace(actionAddMidpoint({ - loc: choice.loc, - edge: [target.nodes[choice.index - 1], target.nodes[choice.index]] - }, entity), connectAnnotation(entity, target)); - } else if (target && target.type === 'node' && shouldSnapToNode(target)) { - context.replace(actionConnect([target.id, entity.id]), connectAnnotation(entity, target)); - } else if (_wasMidpoint) { - context.replace(actionNoop(), _t('operations.add.annotation.vertex')); - } else { - context.replace(actionNoop(), moveAnnotation(entity)); - } - if (wasPoint) { - context.enter(modeSelect(context, [entity.id])); - } else { - var reselection = _restoreSelectedIDs.filter(function (id) { - return context.graph().hasEntity(id); - }); + function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } - if (reselection.length) { - context.enter(modeSelect(context, reselection)); - } else { - context.enter(modeBrowse(context)); - } - } - } + if (isArray(value)) { + // Recursively convert values (susceptible to call stack limits). + return arrayMap(value, baseToString) + ''; + } - function _actionBounceBack(nodeID, toLoc) { - var moveNode = actionMoveNode(nodeID, toLoc); + if (isSymbol(value)) { + return symbolToString ? symbolToString.call(value) : ''; + } - var action = function action(graph, t) { - // last time through, pop off the bounceback perform. - // it will then overwrite the initial perform with a moveNode that does nothing - if (t === 1) context.pop(); - return moveNode(graph, t); - }; + var result = value + ''; + return result == '0' && 1 / value == -INFINITY ? '-0' : result; + } + /** + * The base implementation of `_.uniqBy` without support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new duplicate free array. + */ - action.transitionable = true; - return action; - } - function cancel() { - drag.cancel(); - context.enter(modeBrowse(context)); - } + function baseUniq(array, iteratee, comparator) { + var index = -1, + includes = arrayIncludes, + length = array.length, + isCommon = true, + result = [], + seen = result; - var drag = behaviorDrag().selector('.layer-touch.points .target').surface(context.container().select('.main-map').node()).origin(origin).on('start', start).on('move', move).on('end', end); + if (comparator) { + isCommon = false; + includes = arrayIncludesWith; + } else if (length >= LARGE_ARRAY_SIZE) { + var set = iteratee ? null : createSet(array); - mode.enter = function () { - context.install(hover); - context.install(edit); - select(window).on('keydown.dragNode', keydown).on('keyup.dragNode', keyup); - context.history().on('undone.drag-node', cancel); - }; + if (set) { + return setToArray(set); + } - mode.exit = function () { - context.ui().sidebar.hover.cancel(); - context.uninstall(hover); - context.uninstall(edit); - select(window).on('keydown.dragNode', null).on('keyup.dragNode', null); - context.history().on('undone.drag-node', null); - _activeEntity = null; - context.surface().classed('nope', false).classed('nope-suppressed', false).classed('nope-disabled', false).selectAll('.active').classed('active', false); - stopNudge(); - }; + isCommon = false; + includes = cacheHas; + seen = new SetCache(); + } else { + seen = iteratee ? [] : result; + } - mode.selectedIDs = function () { - if (!arguments.length) return _activeEntity ? [_activeEntity.id] : []; // no assign + outer: while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + value = comparator || value !== 0 ? value : 0; - return mode; - }; + if (isCommon && computed === computed) { + var seenIndex = seen.length; - mode.activeID = function () { - if (!arguments.length) return _activeEntity && _activeEntity.id; // no assign + while (seenIndex--) { + if (seen[seenIndex] === computed) { + continue outer; + } + } - return mode; - }; + if (iteratee) { + seen.push(computed); + } - mode.restoreSelectedIDs = function (_) { - if (!arguments.length) return _restoreSelectedIDs; - _restoreSelectedIDs = _; - return mode; - }; + result.push(value); + } else if (!includes(seen, computed, comparator)) { + if (seen !== result) { + seen.push(computed); + } - mode.behavior = drag; - return mode; - } + result.push(value); + } + } - var $$4 = _export; - var NativePromise = nativePromiseConstructor; - var fails$1 = fails$N; - var getBuiltIn = getBuiltIn$9; - var speciesConstructor = speciesConstructor$8; - var promiseResolve = promiseResolve$2; - var redefine = redefine$g.exports; + return result; + } + /** + * The base implementation of `_.unset`. + * + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The property path to unset. + * @returns {boolean} Returns `true` if the property is deleted, else `false`. + */ - // Safari bug https://bugs.webkit.org/show_bug.cgi?id=200829 - var NON_GENERIC = !!NativePromise && fails$1(function () { - NativePromise.prototype['finally'].call({ then: function () { /* empty */ } }, function () { /* empty */ }); - }); - // `Promise.prototype.finally` method - // https://tc39.es/ecma262/#sec-promise.prototype.finally - $$4({ target: 'Promise', proto: true, real: true, forced: NON_GENERIC }, { - 'finally': function (onFinally) { - var C = speciesConstructor(this, getBuiltIn('Promise')); - var isFunction = typeof onFinally == 'function'; - return this.then( - isFunction ? function (x) { - return promiseResolve(C, onFinally()).then(function () { return x; }); - } : onFinally, - isFunction ? function (e) { - return promiseResolve(C, onFinally()).then(function () { throw e; }); - } : onFinally - ); - } - }); + function baseUnset(object, path) { + path = castPath(path, object); + object = parent(object, path); + return object == null || delete object[toKey(last(path))]; + } + /** + * The base implementation of `_.update`. + * + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to update. + * @param {Function} updater The function to produce the updated value. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. + */ - // makes sure that native promise-based APIs `Promise#finally` properly works with patched `Promise#then` - if (typeof NativePromise == 'function') { - var method = getBuiltIn('Promise').prototype['finally']; - if (NativePromise.prototype['finally'] !== method) { - redefine(NativePromise.prototype, 'finally', method, { unsafe: true }); - } - } - function quickselect(arr, k, left, right, compare) { - quickselectStep(arr, k, left || 0, right || arr.length - 1, compare || defaultCompare); - } + function baseUpdate(object, path, updater, customizer) { + return baseSet(object, path, updater(baseGet(object, path)), customizer); + } + /** + * The base implementation of methods like `_.dropWhile` and `_.takeWhile` + * without support for iteratee shorthands. + * + * @private + * @param {Array} array The array to query. + * @param {Function} predicate The function invoked per iteration. + * @param {boolean} [isDrop] Specify dropping elements instead of taking them. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the slice of `array`. + */ - function quickselectStep(arr, k, left, right, compare) { - while (right > left) { - if (right - left > 600) { - var n = right - left + 1; - var m = k - left + 1; - var z = Math.log(n); - var s = 0.5 * Math.exp(2 * z / 3); - var sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1); - var newLeft = Math.max(left, Math.floor(k - m * s / n + sd)); - var newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd)); - quickselectStep(arr, k, newLeft, newRight, compare); - } - var t = arr[k]; - var i = left; - var j = right; - swap(arr, left, k); - if (compare(arr[right], t) > 0) swap(arr, left, right); + function baseWhile(array, predicate, isDrop, fromRight) { + var length = array.length, + index = fromRight ? length : -1; - while (i < j) { - swap(arr, i, j); - i++; - j--; + while ((fromRight ? index-- : ++index < length) && predicate(array[index], index, array)) {} - while (compare(arr[i], t) < 0) { - i++; + return isDrop ? baseSlice(array, fromRight ? 0 : index, fromRight ? index + 1 : length) : baseSlice(array, fromRight ? index + 1 : 0, fromRight ? length : index); } + /** + * The base implementation of `wrapperValue` which returns the result of + * performing a sequence of actions on the unwrapped `value`, where each + * successive action is supplied the return value of the previous. + * + * @private + * @param {*} value The unwrapped value. + * @param {Array} actions Actions to perform to resolve the unwrapped value. + * @returns {*} Returns the resolved value. + */ - while (compare(arr[j], t) > 0) { - j--; - } - } - if (compare(arr[left], t) === 0) swap(arr, left, j);else { - j++; - swap(arr, j, right); - } - if (j <= k) left = j + 1; - if (k <= j) right = j - 1; - } - } + function baseWrapperValue(value, actions) { + var result = value; - function swap(arr, i, j) { - var tmp = arr[i]; - arr[i] = arr[j]; - arr[j] = tmp; - } + if (result instanceof LazyWrapper) { + result = result.value(); + } - function defaultCompare(a, b) { - return a < b ? -1 : a > b ? 1 : 0; - } + return arrayReduce(actions, function (result, action) { + return action.func.apply(action.thisArg, arrayPush([result], action.args)); + }, result); + } + /** + * The base implementation of methods like `_.xor`, without support for + * iteratee shorthands, that accepts an array of arrays to inspect. + * + * @private + * @param {Array} arrays The arrays to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of values. + */ - var RBush = /*#__PURE__*/function () { - function RBush() { - var maxEntries = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 9; - _classCallCheck$1(this, RBush); + function baseXor(arrays, iteratee, comparator) { + var length = arrays.length; - // max entries in a node is 9 by default; min node fill is 40% for best performance - this._maxEntries = Math.max(4, maxEntries); - this._minEntries = Math.max(2, Math.ceil(this._maxEntries * 0.4)); - this.clear(); - } + if (length < 2) { + return length ? baseUniq(arrays[0]) : []; + } - _createClass$1(RBush, [{ - key: "all", - value: function all() { - return this._all(this.data, []); - } - }, { - key: "search", - value: function search(bbox) { - var node = this.data; - var result = []; - if (!intersects(bbox, node)) return result; - var toBBox = this.toBBox; - var nodesToSearch = []; + var index = -1, + result = Array(length); - while (node) { - for (var i = 0; i < node.children.length; i++) { - var child = node.children[i]; - var childBBox = node.leaf ? toBBox(child) : child; + while (++index < length) { + var array = arrays[index], + othIndex = -1; - if (intersects(bbox, childBBox)) { - if (node.leaf) result.push(child);else if (contains(bbox, childBBox)) this._all(child, result);else nodesToSearch.push(child); + while (++othIndex < length) { + if (othIndex != index) { + result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator); + } } } - node = nodesToSearch.pop(); + return baseUniq(baseFlatten(result, 1), iteratee, comparator); } + /** + * This base implementation of `_.zipObject` which assigns values using `assignFunc`. + * + * @private + * @param {Array} props The property identifiers. + * @param {Array} values The property values. + * @param {Function} assignFunc The function to assign values. + * @returns {Object} Returns the new object. + */ - return result; - } - }, { - key: "collides", - value: function collides(bbox) { - var node = this.data; - if (!intersects(bbox, node)) return false; - var nodesToSearch = []; - while (node) { - for (var i = 0; i < node.children.length; i++) { - var child = node.children[i]; - var childBBox = node.leaf ? this.toBBox(child) : child; + function baseZipObject(props, values, assignFunc) { + var index = -1, + length = props.length, + valsLength = values.length, + result = {}; - if (intersects(bbox, childBBox)) { - if (node.leaf || contains(bbox, childBBox)) return true; - nodesToSearch.push(child); - } + while (++index < length) { + var value = index < valsLength ? values[index] : undefined$1; + assignFunc(result, props[index], value); } - node = nodesToSearch.pop(); + return result; } + /** + * Casts `value` to an empty array if it's not an array like object. + * + * @private + * @param {*} value The value to inspect. + * @returns {Array|Object} Returns the cast array-like object. + */ - return false; - } - }, { - key: "load", - value: function load(data) { - if (!(data && data.length)) return this; - - if (data.length < this._minEntries) { - for (var i = 0; i < data.length; i++) { - this.insert(data[i]); - } - return this; - } // recursively build the tree with the given data from scratch using OMT algorithm + function castArrayLikeObject(value) { + return isArrayLikeObject(value) ? value : []; + } + /** + * Casts `value` to `identity` if it's not a function. + * + * @private + * @param {*} value The value to inspect. + * @returns {Function} Returns cast function. + */ - var node = this._build(data.slice(), 0, data.length - 1, 0); + function castFunction(value) { + return typeof value == 'function' ? value : identity; + } + /** + * Casts `value` to a path array if it's not one. + * + * @private + * @param {*} value The value to inspect. + * @param {Object} [object] The object to query keys on. + * @returns {Array} Returns the cast property path array. + */ - if (!this.data.children.length) { - // save as is if tree is empty - this.data = node; - } else if (this.data.height === node.height) { - // split root if trees have the same height - this._splitRoot(this.data, node); - } else { - if (this.data.height < node.height) { - // swap trees if inserted one is bigger - var tmpNode = this.data; - this.data = node; - node = tmpNode; - } // insert the small tree into the large tree at appropriate level + function castPath(value, object) { + if (isArray(value)) { + return value; + } - this._insert(node, this.data.height - node.height - 1, true); + return isKey(value, object) ? [value] : stringToPath(toString(value)); } + /** + * A `baseRest` alias which can be replaced with `identity` by module + * replacement plugins. + * + * @private + * @type {Function} + * @param {Function} func The function to apply a rest parameter to. + * @returns {Function} Returns the new function. + */ - return this; - } - }, { - key: "insert", - value: function insert(item) { - if (item) this._insert(item, this.data.height - 1); - return this; - } - }, { - key: "clear", - value: function clear() { - this.data = createNode([]); - return this; - } - }, { - key: "remove", - value: function remove(item, equalsFn) { - if (!item) return this; - var node = this.data; - var bbox = this.toBBox(item); - var path = []; - var indexes = []; - var i, parent, goingUp; // depth-first iterative tree traversal - while (node || path.length) { - if (!node) { - // go up - node = path.pop(); - parent = path[path.length - 1]; - i = indexes.pop(); - goingUp = true; - } + var castRest = baseRest; + /** + * Casts `array` to a slice if it's needed. + * + * @private + * @param {Array} array The array to inspect. + * @param {number} start The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the cast slice. + */ - if (node.leaf) { - // check current node - var index = findItem(item, node.children, equalsFn); + function castSlice(array, start, end) { + var length = array.length; + end = end === undefined$1 ? length : end; + return !start && end >= length ? array : baseSlice(array, start, end); + } + /** + * A simple wrapper around the global [`clearTimeout`](https://mdn.io/clearTimeout). + * + * @private + * @param {number|Object} id The timer id or timeout object of the timer to clear. + */ - if (index !== -1) { - // item found, remove the item and condense tree upwards - node.children.splice(index, 1); - path.push(node); - this._condense(path); + var clearTimeout = ctxClearTimeout || function (id) { + return root.clearTimeout(id); + }; + /** + * Creates a clone of `buffer`. + * + * @private + * @param {Buffer} buffer The buffer to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Buffer} Returns the cloned buffer. + */ - return this; - } + + function cloneBuffer(buffer, isDeep) { + if (isDeep) { + return buffer.slice(); } - if (!goingUp && !node.leaf && contains(node, bbox)) { - // go down - path.push(node); - indexes.push(i); - i = 0; - parent = node; - node = node.children[0]; - } else if (parent) { - // go right - i++; - node = parent.children[i]; - goingUp = false; - } else node = null; // nothing found + var length = buffer.length, + result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length); + buffer.copy(result); + return result; + } + /** + * Creates a clone of `arrayBuffer`. + * + * @private + * @param {ArrayBuffer} arrayBuffer The array buffer to clone. + * @returns {ArrayBuffer} Returns the cloned array buffer. + */ + + function cloneArrayBuffer(arrayBuffer) { + var result = new arrayBuffer.constructor(arrayBuffer.byteLength); + new Uint8Array(result).set(new Uint8Array(arrayBuffer)); + return result; } + /** + * Creates a clone of `dataView`. + * + * @private + * @param {Object} dataView The data view to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned data view. + */ - return this; - } - }, { - key: "toBBox", - value: function toBBox(item) { - return item; - } - }, { - key: "compareMinX", - value: function compareMinX(a, b) { - return a.minX - b.minX; - } - }, { - key: "compareMinY", - value: function compareMinY(a, b) { - return a.minY - b.minY; - } - }, { - key: "toJSON", - value: function toJSON() { - return this.data; - } - }, { - key: "fromJSON", - value: function fromJSON(data) { - this.data = data; - return this; - } - }, { - key: "_all", - value: function _all(node, result) { - var nodesToSearch = []; - while (node) { - if (node.leaf) result.push.apply(result, _toConsumableArray(node.children));else nodesToSearch.push.apply(nodesToSearch, _toConsumableArray(node.children)); - node = nodesToSearch.pop(); + function cloneDataView(dataView, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer; + return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); } + /** + * Creates a clone of `regexp`. + * + * @private + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. + */ - return result; - } - }, { - key: "_build", - value: function _build(items, left, right, height) { - var N = right - left + 1; - var M = this._maxEntries; - var node; - if (N <= M) { - // reached leaf level; return leaf - node = createNode(items.slice(left, right + 1)); - calcBBox(node, this.toBBox); - return node; + function cloneRegExp(regexp) { + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); + result.lastIndex = regexp.lastIndex; + return result; } + /** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ - if (!height) { - // target height of the bulk-loaded tree - height = Math.ceil(Math.log(N) / Math.log(M)); // target number of root entries to maximize storage utilization - M = Math.ceil(N / Math.pow(M, height - 1)); + function cloneSymbol(symbol) { + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; } + /** + * Creates a clone of `typedArray`. + * + * @private + * @param {Object} typedArray The typed array to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned typed array. + */ - node = createNode([]); - node.leaf = false; - node.height = height; // split the items into M mostly square tiles - var N2 = Math.ceil(N / M); - var N1 = N2 * Math.ceil(Math.sqrt(M)); - multiSelect(items, left, right, N1, this.compareMinX); + function cloneTypedArray(typedArray, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; + return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); + } + /** + * Compares values to sort them in ascending order. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {number} Returns the sort order indicator for `value`. + */ - for (var i = left; i <= right; i += N1) { - var right2 = Math.min(i + N1 - 1, right); - multiSelect(items, i, right2, N2, this.compareMinY); - for (var j = i; j <= right2; j += N2) { - var right3 = Math.min(j + N2 - 1, right2); // pack each entry recursively + function compareAscending(value, other) { + if (value !== other) { + var valIsDefined = value !== undefined$1, + valIsNull = value === null, + valIsReflexive = value === value, + valIsSymbol = isSymbol(value); + var othIsDefined = other !== undefined$1, + othIsNull = other === null, + othIsReflexive = other === other, + othIsSymbol = isSymbol(other); - node.children.push(this._build(items, j, right3, height - 1)); + if (!othIsNull && !othIsSymbol && !valIsSymbol && value > other || valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol || valIsNull && othIsDefined && othIsReflexive || !valIsDefined && othIsReflexive || !valIsReflexive) { + return 1; + } + + if (!valIsNull && !valIsSymbol && !othIsSymbol && value < other || othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol || othIsNull && valIsDefined && valIsReflexive || !othIsDefined && valIsReflexive || !othIsReflexive) { + return -1; + } } + + return 0; } + /** + * Used by `_.orderBy` to compare multiple properties of a value to another + * and stable sort them. + * + * If `orders` is unspecified, all values are sorted in ascending order. Otherwise, + * specify an order of "desc" for descending or "asc" for ascending sort order + * of corresponding values. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {boolean[]|string[]} orders The order to sort by for each property. + * @returns {number} Returns the sort order indicator for `object`. + */ - calcBBox(node, this.toBBox); - return node; - } - }, { - key: "_chooseSubtree", - value: function _chooseSubtree(bbox, node, level, path) { - while (true) { - path.push(node); - if (node.leaf || path.length - 1 === level) break; - var minArea = Infinity; - var minEnlargement = Infinity; - var targetNode = void 0; - for (var i = 0; i < node.children.length; i++) { - var child = node.children[i]; - var area = bboxArea(child); - var enlargement = enlargedArea(bbox, child) - area; // choose entry with the least area enlargement + function compareMultiple(object, other, orders) { + var index = -1, + objCriteria = object.criteria, + othCriteria = other.criteria, + length = objCriteria.length, + ordersLength = orders.length; - if (enlargement < minEnlargement) { - minEnlargement = enlargement; - minArea = area < minArea ? area : minArea; - targetNode = child; - } else if (enlargement === minEnlargement) { - // otherwise choose one with the smallest area - if (area < minArea) { - minArea = area; - targetNode = child; + while (++index < length) { + var result = compareAscending(objCriteria[index], othCriteria[index]); + + if (result) { + if (index >= ordersLength) { + return result; } - } - } - node = targetNode || node.children[0]; - } + var order = orders[index]; + return result * (order == 'desc' ? -1 : 1); + } + } // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications + // that causes it, under certain circumstances, to provide the same value for + // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 + // for more details. + // + // This also ensures a stable sort in V8 and other engines. + // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details. - return node; - } - }, { - key: "_insert", - value: function _insert(item, level, isNode) { - var bbox = isNode ? item : this.toBBox(item); - var insertPath = []; // find the best node for accommodating the item, saving all nodes along the path too - var node = this._chooseSubtree(bbox, this.data, level, insertPath); // put the item into the node + return object.index - other.index; + } + /** + * Creates an array that is the composition of partially applied arguments, + * placeholders, and provided arguments into a single array of arguments. + * + * @private + * @param {Array} args The provided arguments. + * @param {Array} partials The arguments to prepend to those provided. + * @param {Array} holders The `partials` placeholder indexes. + * @params {boolean} [isCurried] Specify composing for a curried function. + * @returns {Array} Returns the new array of composed arguments. + */ - node.children.push(item); - extend$1(node, bbox); // split on node overflow; propagate upwards if necessary + function composeArgs(args, partials, holders, isCurried) { + var argsIndex = -1, + argsLength = args.length, + holdersLength = holders.length, + leftIndex = -1, + leftLength = partials.length, + rangeLength = nativeMax(argsLength - holdersLength, 0), + result = Array(leftLength + rangeLength), + isUncurried = !isCurried; - while (level >= 0) { - if (insertPath[level].children.length > this._maxEntries) { - this._split(insertPath, level); + while (++leftIndex < leftLength) { + result[leftIndex] = partials[leftIndex]; + } - level--; - } else break; - } // adjust bboxes along the insertion path + while (++argsIndex < holdersLength) { + if (isUncurried || argsIndex < argsLength) { + result[holders[argsIndex]] = args[argsIndex]; + } + } + while (rangeLength--) { + result[leftIndex++] = args[argsIndex++]; + } - this._adjustParentBBoxes(bbox, insertPath, level); - } // split overflowed node into two + return result; + } + /** + * This function is like `composeArgs` except that the arguments composition + * is tailored for `_.partialRight`. + * + * @private + * @param {Array} args The provided arguments. + * @param {Array} partials The arguments to append to those provided. + * @param {Array} holders The `partials` placeholder indexes. + * @params {boolean} [isCurried] Specify composing for a curried function. + * @returns {Array} Returns the new array of composed arguments. + */ - }, { - key: "_split", - value: function _split(insertPath, level) { - var node = insertPath[level]; - var M = node.children.length; - var m = this._minEntries; - this._chooseSplitAxis(node, m, M); + function composeArgsRight(args, partials, holders, isCurried) { + var argsIndex = -1, + argsLength = args.length, + holdersIndex = -1, + holdersLength = holders.length, + rightIndex = -1, + rightLength = partials.length, + rangeLength = nativeMax(argsLength - holdersLength, 0), + result = Array(rangeLength + rightLength), + isUncurried = !isCurried; - var splitIndex = this._chooseSplitIndex(node, m, M); + while (++argsIndex < rangeLength) { + result[argsIndex] = args[argsIndex]; + } - var newNode = createNode(node.children.splice(splitIndex, node.children.length - splitIndex)); - newNode.height = node.height; - newNode.leaf = node.leaf; - calcBBox(node, this.toBBox); - calcBBox(newNode, this.toBBox); - if (level) insertPath[level - 1].children.push(newNode);else this._splitRoot(node, newNode); - } - }, { - key: "_splitRoot", - value: function _splitRoot(node, newNode) { - // split root node - this.data = createNode([node, newNode]); - this.data.height = node.height + 1; - this.data.leaf = false; - calcBBox(this.data, this.toBBox); - } - }, { - key: "_chooseSplitIndex", - value: function _chooseSplitIndex(node, m, M) { - var index; - var minOverlap = Infinity; - var minArea = Infinity; + var offset = argsIndex; - for (var i = m; i <= M - m; i++) { - var bbox1 = distBBox(node, 0, i, this.toBBox); - var bbox2 = distBBox(node, i, M, this.toBBox); - var overlap = intersectionArea(bbox1, bbox2); - var area = bboxArea(bbox1) + bboxArea(bbox2); // choose distribution with minimum overlap + while (++rightIndex < rightLength) { + result[offset + rightIndex] = partials[rightIndex]; + } - if (overlap < minOverlap) { - minOverlap = overlap; - index = i; - minArea = area < minArea ? area : minArea; - } else if (overlap === minOverlap) { - // otherwise choose distribution with minimum area - if (area < minArea) { - minArea = area; - index = i; + while (++holdersIndex < holdersLength) { + if (isUncurried || argsIndex < argsLength) { + result[offset + holders[holdersIndex]] = args[argsIndex++]; } } + + return result; } + /** + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ - return index || M - m; - } // sorts node children by the best axis for split - }, { - key: "_chooseSplitAxis", - value: function _chooseSplitAxis(node, m, M) { - var compareMinX = node.leaf ? this.compareMinX : compareNodeMinX; - var compareMinY = node.leaf ? this.compareMinY : compareNodeMinY; + function copyArray(source, array) { + var index = -1, + length = source.length; + array || (array = Array(length)); - var xMargin = this._allDistMargin(node, m, M, compareMinX); + while (++index < length) { + array[index] = source[index]; + } - var yMargin = this._allDistMargin(node, m, M, compareMinY); // if total distributions margin value is minimal for x, sort by minX, - // otherwise it's already sorted by minY + return array; + } + /** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property identifiers to copy. + * @param {Object} [object={}] The object to copy properties to. + * @param {Function} [customizer] The function to customize copied values. + * @returns {Object} Returns `object`. + */ - if (xMargin < yMargin) node.children.sort(compareMinX); - } // total margin of all possible split distributions where each node is at least m full + function copyObject(source, props, object, customizer) { + var isNew = !object; + object || (object = {}); + var index = -1, + length = props.length; - }, { - key: "_allDistMargin", - value: function _allDistMargin(node, m, M, compare) { - node.children.sort(compare); - var toBBox = this.toBBox; - var leftBBox = distBBox(node, 0, m, toBBox); - var rightBBox = distBBox(node, M - m, M, toBBox); - var margin = bboxMargin(leftBBox) + bboxMargin(rightBBox); + while (++index < length) { + var key = props[index]; + var newValue = customizer ? customizer(object[key], source[key], key, object, source) : undefined$1; - for (var i = m; i < M - m; i++) { - var child = node.children[i]; - extend$1(leftBBox, node.leaf ? toBBox(child) : child); - margin += bboxMargin(leftBBox); - } + if (newValue === undefined$1) { + newValue = source[key]; + } - for (var _i = M - m - 1; _i >= m; _i--) { - var _child = node.children[_i]; - extend$1(rightBBox, node.leaf ? toBBox(_child) : _child); - margin += bboxMargin(rightBBox); + if (isNew) { + baseAssignValue(object, key, newValue); + } else { + assignValue(object, key, newValue); + } + } + + return object; } + /** + * Copies own symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ - return margin; - } - }, { - key: "_adjustParentBBoxes", - value: function _adjustParentBBoxes(bbox, path, level) { - // adjust bboxes along the given tree path - for (var i = level; i >= 0; i--) { - extend$1(path[i], bbox); + + function copySymbols(source, object) { + return copyObject(source, getSymbols(source), object); } - } - }, { - key: "_condense", - value: function _condense(path) { - // go through the path, removing empty nodes and updating bboxes - for (var i = path.length - 1, siblings; i >= 0; i--) { - if (path[i].children.length === 0) { - if (i > 0) { - siblings = path[i - 1].children; - siblings.splice(siblings.indexOf(path[i]), 1); - } else this.clear(); - } else calcBBox(path[i], this.toBBox); + /** + * Copies own and inherited symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ + + + function copySymbolsIn(source, object) { + return copyObject(source, getSymbolsIn(source), object); } - } - }]); + /** + * Creates a function like `_.groupBy`. + * + * @private + * @param {Function} setter The function to set accumulator values. + * @param {Function} [initializer] The accumulator object initializer. + * @returns {Function} Returns the new aggregator function. + */ - return RBush; - }(); - function findItem(item, items, equalsFn) { - if (!equalsFn) return items.indexOf(item); + function createAggregator(setter, initializer) { + return function (collection, iteratee) { + var func = isArray(collection) ? arrayAggregator : baseAggregator, + accumulator = initializer ? initializer() : {}; + return func(collection, setter, getIteratee(iteratee, 2), accumulator); + }; + } + /** + * Creates a function like `_.assign`. + * + * @private + * @param {Function} assigner The function to assign values. + * @returns {Function} Returns the new assigner function. + */ - for (var i = 0; i < items.length; i++) { - if (equalsFn(item, items[i])) return i; - } - return -1; - } // calculate node's bbox from bboxes of its children + function createAssigner(assigner) { + return baseRest(function (object, sources) { + var index = -1, + length = sources.length, + customizer = length > 1 ? sources[length - 1] : undefined$1, + guard = length > 2 ? sources[2] : undefined$1; + customizer = assigner.length > 3 && typeof customizer == 'function' ? (length--, customizer) : undefined$1; + if (guard && isIterateeCall(sources[0], sources[1], guard)) { + customizer = length < 3 ? undefined$1 : customizer; + length = 1; + } - function calcBBox(node, toBBox) { - distBBox(node, 0, node.children.length, toBBox, node); - } // min bounding rectangle of node children from k to p-1 + object = Object(object); + while (++index < length) { + var source = sources[index]; - function distBBox(node, k, p, toBBox, destNode) { - if (!destNode) destNode = createNode(null); - destNode.minX = Infinity; - destNode.minY = Infinity; - destNode.maxX = -Infinity; - destNode.maxY = -Infinity; + if (source) { + assigner(object, source, index, customizer); + } + } - for (var i = k; i < p; i++) { - var child = node.children[i]; - extend$1(destNode, node.leaf ? toBBox(child) : child); - } + return object; + }); + } + /** + * Creates a `baseEach` or `baseEachRight` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ - return destNode; - } - function extend$1(a, b) { - a.minX = Math.min(a.minX, b.minX); - a.minY = Math.min(a.minY, b.minY); - a.maxX = Math.max(a.maxX, b.maxX); - a.maxY = Math.max(a.maxY, b.maxY); - return a; - } + function createBaseEach(eachFunc, fromRight) { + return function (collection, iteratee) { + if (collection == null) { + return collection; + } - function compareNodeMinX(a, b) { - return a.minX - b.minX; - } + if (!isArrayLike(collection)) { + return eachFunc(collection, iteratee); + } - function compareNodeMinY(a, b) { - return a.minY - b.minY; - } + var length = collection.length, + index = fromRight ? length : -1, + iterable = Object(collection); - function bboxArea(a) { - return (a.maxX - a.minX) * (a.maxY - a.minY); - } + while (fromRight ? index-- : ++index < length) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } + } - function bboxMargin(a) { - return a.maxX - a.minX + (a.maxY - a.minY); - } + return collection; + }; + } + /** + * Creates a base function for methods like `_.forIn` and `_.forOwn`. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ - function enlargedArea(a, b) { - return (Math.max(b.maxX, a.maxX) - Math.min(b.minX, a.minX)) * (Math.max(b.maxY, a.maxY) - Math.min(b.minY, a.minY)); - } - function intersectionArea(a, b) { - var minX = Math.max(a.minX, b.minX); - var minY = Math.max(a.minY, b.minY); - var maxX = Math.min(a.maxX, b.maxX); - var maxY = Math.min(a.maxY, b.maxY); - return Math.max(0, maxX - minX) * Math.max(0, maxY - minY); - } + function createBaseFor(fromRight) { + return function (object, iteratee, keysFunc) { + var index = -1, + iterable = Object(object), + props = keysFunc(object), + length = props.length; - function contains(a, b) { - return a.minX <= b.minX && a.minY <= b.minY && b.maxX <= a.maxX && b.maxY <= a.maxY; - } + while (length--) { + var key = props[fromRight ? length : ++index]; - function intersects(a, b) { - return b.minX <= a.maxX && b.minY <= a.maxY && b.maxX >= a.minX && b.maxY >= a.minY; - } + if (iteratee(iterable[key], key, iterable) === false) { + break; + } + } - function createNode(children) { - return { - children: children, - height: 1, - leaf: true, - minX: Infinity, - minY: Infinity, - maxX: -Infinity, - maxY: -Infinity - }; - } // sort an array so that items come in groups of n unsorted items, with groups sorted between each other; - // combines selection algorithm with binary divide & conquer approach + return object; + }; + } + /** + * Creates a function that wraps `func` to invoke it with the optional `this` + * binding of `thisArg`. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask flags. See `createWrap` for more details. + * @param {*} [thisArg] The `this` binding of `func`. + * @returns {Function} Returns the new wrapped function. + */ - function multiSelect(arr, left, right, n, compare) { - var stack = [left, right]; + function createBind(func, bitmask, thisArg) { + var isBind = bitmask & WRAP_BIND_FLAG, + Ctor = createCtor(func); - while (stack.length) { - right = stack.pop(); - left = stack.pop(); - if (right - left <= n) continue; - var mid = left + Math.ceil((right - left) / n / 2) * n; - quickselect(arr, mid, left, right, compare); - stack.push(left, mid, mid, right); - } - } + function wrapper() { + var fn = this && this !== root && this instanceof wrapper ? Ctor : func; + return fn.apply(isBind ? thisArg : this, arguments); + } - function responseText(response) { - if (!response.ok) throw new Error(response.status + " " + response.statusText); - return response.text(); - } + return wrapper; + } + /** + * Creates a function like `_.lowerFirst`. + * + * @private + * @param {string} methodName The name of the `String` case method to use. + * @returns {Function} Returns the new case function. + */ - function d3_text (input, init) { - return fetch(input, init).then(responseText); - } - function responseJson(response) { - if (!response.ok) throw new Error(response.status + " " + response.statusText); - if (response.status === 204 || response.status === 205) return; - return response.json(); - } + function createCaseFirst(methodName) { + return function (string) { + string = toString(string); + var strSymbols = hasUnicode(string) ? stringToArray(string) : undefined$1; + var chr = strSymbols ? strSymbols[0] : string.charAt(0); + var trailing = strSymbols ? castSlice(strSymbols, 1).join('') : string.slice(1); + return chr[methodName]() + trailing; + }; + } + /** + * Creates a function like `_.camelCase`. + * + * @private + * @param {Function} callback The function to combine each word. + * @returns {Function} Returns the new compounder function. + */ - function d3_json (input, init) { - return fetch(input, init).then(responseJson); - } - function parser(type) { - return function (input, init) { - return d3_text(input, init).then(function (text) { - return new DOMParser().parseFromString(text, type); - }); - }; - } + function createCompounder(callback) { + return function (string) { + return arrayReduce(words(deburr(string).replace(reApos, '')), callback, ''); + }; + } + /** + * Creates a function that produces an instance of `Ctor` regardless of + * whether it was invoked as part of a `new` expression or by `call` or `apply`. + * + * @private + * @param {Function} Ctor The constructor to wrap. + * @returns {Function} Returns the new wrapped function. + */ - var d3_xml = parser("application/xml"); - var svg = parser("image/svg+xml"); - var tiler$6 = utilTiler(); - var dispatch$7 = dispatch$8('loaded'); - var _tileZoom$3 = 14; - var _krUrlRoot = 'https://www.keepright.at'; - var _krData = { - errorTypes: {}, - localizeStrings: {} - }; // This gets reassigned if reset + function createCtor(Ctor) { + return function () { + // Use a `switch` statement to work with class constructors. See + // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist + // for more details. + var args = arguments; - var _cache$2; + switch (args.length) { + case 0: + return new Ctor(); - var _krRuleset = [// no 20 - multiple node on same spot - these are mostly boundaries overlapping roads - 30, 40, 50, 60, 70, 90, 100, 110, 120, 130, 150, 160, 170, 180, 190, 191, 192, 193, 194, 195, 196, 197, 198, 200, 201, 202, 203, 204, 205, 206, 207, 208, 210, 220, 230, 231, 232, 270, 280, 281, 282, 283, 284, 285, 290, 291, 292, 293, 294, 295, 296, 297, 298, 300, 310, 311, 312, 313, 320, 350, 360, 370, 380, 390, 400, 401, 402, 410, 411, 412, 413]; + case 1: + return new Ctor(args[0]); - function abortRequest$6(controller) { - if (controller) { - controller.abort(); - } - } + case 2: + return new Ctor(args[0], args[1]); - function abortUnwantedRequests$3(cache, tiles) { - Object.keys(cache.inflightTile).forEach(function (k) { - var wanted = tiles.find(function (tile) { - return k === tile.id; - }); + case 3: + return new Ctor(args[0], args[1], args[2]); - if (!wanted) { - abortRequest$6(cache.inflightTile[k]); - delete cache.inflightTile[k]; - } - }); - } + case 4: + return new Ctor(args[0], args[1], args[2], args[3]); - function encodeIssueRtree$2(d) { - return { - minX: d.loc[0], - minY: d.loc[1], - maxX: d.loc[0], - maxY: d.loc[1], - data: d - }; - } // Replace or remove QAItem from rtree + case 5: + return new Ctor(args[0], args[1], args[2], args[3], args[4]); + case 6: + return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]); - function updateRtree$3(item, replace) { - _cache$2.rtree.remove(item, function (a, b) { - return a.data.id === b.data.id; - }); + case 7: + return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); + } - if (replace) { - _cache$2.rtree.insert(item); - } - } + var thisBinding = baseCreate(Ctor.prototype), + result = Ctor.apply(thisBinding, args); // Mimic the constructor's `return` behavior. + // See https://es5.github.io/#x13.2.2 for more details. - function tokenReplacements(d) { - if (!(d instanceof QAItem)) return; - var htmlRegex = new RegExp(/<\/[a-z][\s\S]*>/); - var replacements = {}; - var issueTemplate = _krData.errorTypes[d.whichType]; + return isObject(result) ? result : thisBinding; + }; + } + /** + * Creates a function that wraps `func` to enable currying. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask flags. See `createWrap` for more details. + * @param {number} arity The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ - if (!issueTemplate) { - /* eslint-disable no-console */ - console.log('No Template: ', d.whichType); - console.log(' ', d.description); - /* eslint-enable no-console */ - return; - } // some descriptions are just fixed text + function createCurry(func, bitmask, arity) { + var Ctor = createCtor(func); + function wrapper() { + var length = arguments.length, + args = Array(length), + index = length, + placeholder = getHolder(wrapper); - if (!issueTemplate.regex) return; // regex pattern should match description with variable details captured + while (index--) { + args[index] = arguments[index]; + } - var errorRegex = new RegExp(issueTemplate.regex, 'i'); - var errorMatch = errorRegex.exec(d.description); + var holders = length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder ? [] : replaceHolders(args, placeholder); + length -= holders.length; - if (!errorMatch) { - /* eslint-disable no-console */ - console.log('Unmatched: ', d.whichType); - console.log(' ', d.description); - console.log(' ', errorRegex); - /* eslint-enable no-console */ + if (length < arity) { + return createRecurry(func, bitmask, createHybrid, wrapper.placeholder, undefined$1, args, holders, undefined$1, undefined$1, arity - length); + } - return; - } + var fn = this && this !== root && this instanceof wrapper ? Ctor : func; + return apply(fn, this, args); + } - for (var i = 1; i < errorMatch.length; i++) { - // skip first - var capture = errorMatch[i]; - var idType = void 0; - idType = 'IDs' in issueTemplate ? issueTemplate.IDs[i - 1] : ''; + return wrapper; + } + /** + * Creates a `_.find` or `_.findLast` function. + * + * @private + * @param {Function} findIndexFunc The function to find the collection index. + * @returns {Function} Returns the new find function. + */ - if (idType && capture) { - // link IDs if present in the capture - capture = parseError(capture, idType); - } else if (htmlRegex.test(capture)) { - // escape any html in non-IDs - capture = '\\' + capture + '\\'; - } else { - var compare = capture.toLowerCase(); - if (_krData.localizeStrings[compare]) { - // some replacement strings can be localized - capture = _t('QA.keepRight.error_parts.' + _krData.localizeStrings[compare]); + function createFind(findIndexFunc) { + return function (collection, predicate, fromIndex) { + var iterable = Object(collection); + + if (!isArrayLike(collection)) { + var iteratee = getIteratee(predicate, 3); + collection = keys(collection); + + predicate = function predicate(key) { + return iteratee(iterable[key], key, iterable); + }; + } + + var index = findIndexFunc(collection, predicate, fromIndex); + return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined$1; + }; } - } + /** + * Creates a `_.flow` or `_.flowRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new flow function. + */ - replacements['var' + i] = capture; - } - return replacements; - } + function createFlow(fromRight) { + return flatRest(function (funcs) { + var length = funcs.length, + index = length, + prereq = LodashWrapper.prototype.thru; - function parseError(capture, idType) { - var compare = capture.toLowerCase(); + if (fromRight) { + funcs.reverse(); + } - if (_krData.localizeStrings[compare]) { - // some replacement strings can be localized - capture = _t('QA.keepRight.error_parts.' + _krData.localizeStrings[compare]); - } + while (index--) { + var func = funcs[index]; - switch (idType) { - // link a string like "this node" - case 'this': - capture = linkErrorObject(capture); - break; + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } - case 'url': - capture = linkURL(capture); - break; - // link an entity ID + if (prereq && !wrapper && getFuncName(func) == 'wrapper') { + var wrapper = new LodashWrapper([], true); + } + } - case 'n': - case 'w': - case 'r': - capture = linkEntity(idType + capture); - break; - // some errors have more complex ID lists/variance + index = wrapper ? index : length; - case '20': - capture = parse20(capture); - break; + while (++index < length) { + func = funcs[index]; + var funcName = getFuncName(func), + data = funcName == 'wrapper' ? getData(func) : undefined$1; - case '211': - capture = parse211(capture); - break; + if (data && isLaziable(data[0]) && data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) && !data[4].length && data[9] == 1) { + wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]); + } else { + wrapper = func.length == 1 && isLaziable(func) ? wrapper[funcName]() : wrapper.thru(func); + } + } - case '231': - capture = parse231(capture); - break; + return function () { + var args = arguments, + value = args[0]; - case '294': - capture = parse294(capture); - break; + if (wrapper && args.length == 1 && isArray(value)) { + return wrapper.plant(value).value(); + } - case '370': - capture = parse370(capture); - break; - } + var index = 0, + result = length ? funcs[index].apply(this, args) : value; - return capture; + while (++index < length) { + result = funcs[index].call(this, result); + } - function linkErrorObject(d) { - return "".concat(d, ""); - } + return result; + }; + }); + } + /** + * Creates a function that wraps `func` to invoke it with optional `this` + * binding of `thisArg`, partial application, and currying. + * + * @private + * @param {Function|string} func The function or method name to wrap. + * @param {number} bitmask The bitmask flags. See `createWrap` for more details. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to prepend to those provided to + * the new function. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [partialsRight] The arguments to append to those provided + * to the new function. + * @param {Array} [holdersRight] The `partialsRight` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ - function linkEntity(d) { - return "".concat(d, ""); - } - function linkURL(d) { - return "").concat(d, ""); - } // arbitrary node list of form: #ID, #ID, #ID... + function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) { + var isAry = bitmask & WRAP_ARY_FLAG, + isBind = bitmask & WRAP_BIND_FLAG, + isBindKey = bitmask & WRAP_BIND_KEY_FLAG, + isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG), + isFlip = bitmask & WRAP_FLIP_FLAG, + Ctor = isBindKey ? undefined$1 : createCtor(func); + function wrapper() { + var length = arguments.length, + args = Array(length), + index = length; - function parse211(capture) { - var newList = []; - var items = capture.split(', '); - items.forEach(function (item) { - // ID has # at the front - var id = linkEntity('n' + item.slice(1)); - newList.push(id); - }); - return newList.join(', '); - } // arbitrary way list of form: #ID(layer),#ID(layer),#ID(layer)... + while (index--) { + args[index] = arguments[index]; + } + if (isCurried) { + var placeholder = getHolder(wrapper), + holdersCount = countHolders(args, placeholder); + } - function parse231(capture) { - var newList = []; // unfortunately 'layer' can itself contain commas, so we split on '),' + if (partials) { + args = composeArgs(args, partials, holders, isCurried); + } - var items = capture.split('),'); - items.forEach(function (item) { - var match = item.match(/\#(\d+)\((.+)\)?/); + if (partialsRight) { + args = composeArgsRight(args, partialsRight, holdersRight, isCurried); + } - if (match !== null && match.length > 2) { - newList.push(linkEntity('w' + match[1]) + ' ' + _t('QA.keepRight.errorTypes.231.layer', { - layer: match[2] - })); - } - }); - return newList.join(', '); - } // arbitrary node/relation list of form: from node #ID,to relation #ID,to node #ID... + length -= holdersCount; + if (isCurried && length < arity) { + var newHolders = replaceHolders(args, placeholder); + return createRecurry(func, bitmask, createHybrid, wrapper.placeholder, thisArg, args, newHolders, argPos, ary, arity - length); + } - function parse294(capture) { - var newList = []; - var items = capture.split(','); - items.forEach(function (item) { - // item of form "from/to node/relation #ID" - item = item.split(' '); // to/from role is more clear in quotes + var thisBinding = isBind ? thisArg : this, + fn = isBindKey ? thisBinding[func] : func; + length = args.length; - var role = "\"".concat(item[0], "\""); // first letter of node/relation provides the type + if (argPos) { + args = reorder(args, argPos); + } else if (isFlip && length > 1) { + args.reverse(); + } - var idType = item[1].slice(0, 1); // ID has # at the front + if (isAry && ary < length) { + args.length = ary; + } - var id = item[2].slice(1); - id = linkEntity(idType + id); - newList.push("".concat(role, " ").concat(item[1], " ").concat(id)); - }); - return newList.join(', '); - } // may or may not include the string "(including the name 'name')" + if (this && this !== root && this instanceof wrapper) { + fn = Ctor || createCtor(fn); + } + return fn.apply(thisBinding, args); + } - function parse370(capture) { - if (!capture) return ''; - var match = capture.match(/\(including the name (\'.+\')\)/); + return wrapper; + } + /** + * Creates a function like `_.invertBy`. + * + * @private + * @param {Function} setter The function to set accumulator values. + * @param {Function} toIteratee The function to resolve iteratees. + * @returns {Function} Returns the new inverter function. + */ - if (match && match.length) { - return _t('QA.keepRight.errorTypes.370.including_the_name', { - name: match[1] - }); - } - return ''; - } // arbitrary node list of form: #ID,#ID,#ID... + function createInverter(setter, toIteratee) { + return function (object, iteratee) { + return baseInverter(object, setter, toIteratee(iteratee), {}); + }; + } + /** + * Creates a function that performs a mathematical operation on two values. + * + * @private + * @param {Function} operator The function to perform the operation. + * @param {number} [defaultValue] The value used for `undefined` arguments. + * @returns {Function} Returns the new mathematical operation function. + */ - function parse20(capture) { - var newList = []; - var items = capture.split(','); - items.forEach(function (item) { - // ID has # at the front - var id = linkEntity('n' + item.slice(1)); - newList.push(id); - }); - return newList.join(', '); - } - } + function createMathOperation(operator, defaultValue) { + return function (value, other) { + var result; - var serviceKeepRight = { - title: 'keepRight', - init: function init() { - _mainFileFetcher.get('keepRight').then(function (d) { - return _krData = d; - }); + if (value === undefined$1 && other === undefined$1) { + return defaultValue; + } - if (!_cache$2) { - this.reset(); - } + if (value !== undefined$1) { + result = value; + } - this.event = utilRebind(this, dispatch$7, 'on'); - }, - reset: function reset() { - if (_cache$2) { - Object.values(_cache$2.inflightTile).forEach(abortRequest$6); - } + if (other !== undefined$1) { + if (result === undefined$1) { + return other; + } - _cache$2 = { - data: {}, - loadedTile: {}, - inflightTile: {}, - inflightPost: {}, - closed: {}, - rtree: new RBush() - }; - }, - // KeepRight API: http://osm.mueschelsoft.de/keepright/interfacing.php - loadIssues: function loadIssues(projection) { - var _this = this; + if (typeof value == 'string' || typeof other == 'string') { + value = baseToString(value); + other = baseToString(other); + } else { + value = baseToNumber(value); + other = baseToNumber(other); + } - var options = { - format: 'geojson', - ch: _krRuleset - }; // determine the needed tiles to cover the view + result = operator(value, other); + } - var tiles = tiler$6.zoomExtent([_tileZoom$3, _tileZoom$3]).getTiles(projection); // abort inflight requests that are no longer needed + return result; + }; + } + /** + * Creates a function like `_.over`. + * + * @private + * @param {Function} arrayFunc The function to iterate over iteratees. + * @returns {Function} Returns the new over function. + */ - abortUnwantedRequests$3(_cache$2, tiles); // issue new requests.. - tiles.forEach(function (tile) { - if (_cache$2.loadedTile[tile.id] || _cache$2.inflightTile[tile.id]) return; + function createOver(arrayFunc) { + return flatRest(function (iteratees) { + iteratees = arrayMap(iteratees, baseUnary(getIteratee())); + return baseRest(function (args) { + var thisArg = this; + return arrayFunc(iteratees, function (iteratee) { + return apply(iteratee, thisArg, args); + }); + }); + }); + } + /** + * Creates the padding for `string` based on `length`. The `chars` string + * is truncated if the number of characters exceeds `length`. + * + * @private + * @param {number} length The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padding for `string`. + */ - var _tile$extent$rectangl = tile.extent.rectangle(), - _tile$extent$rectangl2 = _slicedToArray(_tile$extent$rectangl, 4), - left = _tile$extent$rectangl2[0], - top = _tile$extent$rectangl2[1], - right = _tile$extent$rectangl2[2], - bottom = _tile$extent$rectangl2[3]; - var params = Object.assign({}, options, { - left: left, - bottom: bottom, - right: right, - top: top - }); - var url = "".concat(_krUrlRoot, "/export.php?") + utilQsString(params); - var controller = new AbortController(); - _cache$2.inflightTile[tile.id] = controller; - d3_json(url, { - signal: controller.signal - }).then(function (data) { - delete _cache$2.inflightTile[tile.id]; - _cache$2.loadedTile[tile.id] = true; + function createPadding(length, chars) { + chars = chars === undefined$1 ? ' ' : baseToString(chars); + var charsLength = chars.length; - if (!data || !data.features || !data.features.length) { - throw new Error('No Data'); + if (charsLength < 2) { + return charsLength ? baseRepeat(chars, length) : chars; } - data.features.forEach(function (feature) { - var _feature$properties = feature.properties, - itemType = _feature$properties.error_type, - id = _feature$properties.error_id, - _feature$properties$c = _feature$properties.comment, - comment = _feature$properties$c === void 0 ? null : _feature$properties$c, - objectId = _feature$properties.object_id, - objectType = _feature$properties.object_type, - schema = _feature$properties.schema, - title = _feature$properties.title; - var loc = feature.geometry.coordinates, - _feature$properties$d = feature.properties.description, - description = _feature$properties$d === void 0 ? '' : _feature$properties$d; // if there is a parent, save its error type e.g.: - // Error 191 = "highway-highway" - // Error 190 = "intersections without junctions" (parent) + var result = baseRepeat(chars, nativeCeil(length / stringSize(chars))); + return hasUnicode(chars) ? castSlice(stringToArray(result), 0, length).join('') : result.slice(0, length); + } + /** + * Creates a function that wraps `func` to invoke it with the `this` binding + * of `thisArg` and `partials` prepended to the arguments it receives. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask flags. See `createWrap` for more details. + * @param {*} thisArg The `this` binding of `func`. + * @param {Array} partials The arguments to prepend to those provided to + * the new function. + * @returns {Function} Returns the new wrapped function. + */ - var issueTemplate = _krData.errorTypes[itemType]; - var parentIssueType = (Math.floor(itemType / 10) * 10).toString(); // try to handle error type directly, fallback to parent error type. - var whichType = issueTemplate ? itemType : parentIssueType; - var whichTemplate = _krData.errorTypes[whichType]; // Rewrite a few of the errors at this point.. - // This is done to make them easier to linkify and translate. + function createPartial(func, bitmask, thisArg, partials) { + var isBind = bitmask & WRAP_BIND_FLAG, + Ctor = createCtor(func); - switch (whichType) { - case '170': - description = "This feature has a FIXME tag: ".concat(description); - break; + function wrapper() { + var argsIndex = -1, + argsLength = arguments.length, + leftIndex = -1, + leftLength = partials.length, + args = Array(leftLength + argsLength), + fn = this && this !== root && this instanceof wrapper ? Ctor : func; - case '292': - case '293': - description = description.replace('A turn-', 'This turn-'); - break; + while (++leftIndex < leftLength) { + args[leftIndex] = partials[leftIndex]; + } - case '294': - case '295': - case '296': - case '297': - case '298': - description = "This turn-restriction~".concat(description); - break; + while (argsLength--) { + args[leftIndex++] = arguments[++argsIndex]; + } - case '300': - description = 'This highway is missing a maxspeed tag'; - break; + return apply(fn, isBind ? thisArg : this, args); + } - case '411': - case '412': - case '413': - description = "This feature~".concat(description); - break; - } // move markers slightly so it doesn't obscure the geometry, - // then move markers away from other coincident markers + return wrapper; + } + /** + * Creates a `_.range` or `_.rangeRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new range function. + */ - var coincident = false; + function createRange(fromRight) { + return function (start, end, step) { + if (step && typeof step != 'number' && isIterateeCall(start, end, step)) { + end = step = undefined$1; + } // Ensure the sign of `-0` is preserved. - do { - // first time, move marker up. after that, move marker right. - var delta = coincident ? [0.00001, 0] : [0, 0.00001]; - loc = geoVecAdd(loc, delta); - var bbox = geoExtent(loc).bbox(); - coincident = _cache$2.rtree.search(bbox).length; - } while (coincident); - var d = new QAItem(loc, _this, itemType, id, { - comment: comment, - description: description, - whichType: whichType, - parentIssueType: parentIssueType, - severity: whichTemplate.severity || 'error', - objectId: objectId, - objectType: objectType, - schema: schema, - title: title - }); - d.replacements = tokenReplacements(d); - _cache$2.data[id] = d; + start = toFinite(start); - _cache$2.rtree.insert(encodeIssueRtree$2(d)); - }); - dispatch$7.call('loaded'); - })["catch"](function () { - delete _cache$2.inflightTile[tile.id]; - _cache$2.loadedTile[tile.id] = true; - }); - }); - }, - postUpdate: function postUpdate(d, callback) { - var _this2 = this; + if (end === undefined$1) { + end = start; + start = 0; + } else { + end = toFinite(end); + } - if (_cache$2.inflightPost[d.id]) { - return callback({ - message: 'Error update already inflight', - status: -2 - }, d); - } + step = step === undefined$1 ? start < end ? 1 : -1 : toFinite(step); + return baseRange(start, end, step, fromRight); + }; + } + /** + * Creates a function that performs a relational operation on two values. + * + * @private + * @param {Function} operator The function to perform the operation. + * @returns {Function} Returns the new relational operation function. + */ - var params = { - schema: d.schema, - id: d.id - }; - if (d.newStatus) { - params.st = d.newStatus; - } + function createRelationalOperation(operator) { + return function (value, other) { + if (!(typeof value == 'string' && typeof other == 'string')) { + value = toNumber(value); + other = toNumber(other); + } - if (d.newComment !== undefined) { - params.co = d.newComment; - } // NOTE: This throws a CORS err, but it seems successful. - // We don't care too much about the response, so this is fine. + return operator(value, other); + }; + } + /** + * Creates a function that wraps `func` to continue currying. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask flags. See `createWrap` for more details. + * @param {Function} wrapFunc The function to create the `func` wrapper. + * @param {*} placeholder The placeholder value. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to prepend to those provided to + * the new function. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ - var url = "".concat(_krUrlRoot, "/comment.php?") + utilQsString(params); - var controller = new AbortController(); - _cache$2.inflightPost[d.id] = controller; // Since this is expected to throw an error just continue as if it worked - // (worst case scenario the request truly fails and issue will show up if iD restarts) + function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) { + var isCurry = bitmask & WRAP_CURRY_FLAG, + newHolders = isCurry ? holders : undefined$1, + newHoldersRight = isCurry ? undefined$1 : holders, + newPartials = isCurry ? partials : undefined$1, + newPartialsRight = isCurry ? undefined$1 : partials; + bitmask |= isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG; + bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG); - d3_json(url, { - signal: controller.signal - })["finally"](function () { - delete _cache$2.inflightPost[d.id]; + if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) { + bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG); + } - if (d.newStatus === 'ignore') { - // ignore permanently (false positive) - _this2.removeItem(d); - } else if (d.newStatus === 'ignore_t') { - // ignore temporarily (error fixed) - _this2.removeItem(d); + var newData = [func, bitmask, thisArg, newPartials, newHolders, newPartialsRight, newHoldersRight, argPos, ary, arity]; + var result = wrapFunc.apply(undefined$1, newData); - _cache$2.closed["".concat(d.schema, ":").concat(d.id)] = true; - } else { - d = _this2.replaceItem(d.update({ - comment: d.newComment, - newComment: undefined, - newState: undefined - })); + if (isLaziable(func)) { + setData(result, newData); + } + + result.placeholder = placeholder; + return setWrapToString(result, func, bitmask); } + /** + * Creates a function like `_.round`. + * + * @private + * @param {string} methodName The name of the `Math` method to use when rounding. + * @returns {Function} Returns the new round function. + */ - if (callback) callback(null, d); - }); - }, - // Get all cached QAItems covering the viewport - getItems: function getItems(projection) { - var viewport = projection.clipExtent(); - var min = [viewport[0][0], viewport[1][1]]; - var max = [viewport[1][0], viewport[0][1]]; - var bbox = geoExtent(projection.invert(min), projection.invert(max)).bbox(); - return _cache$2.rtree.search(bbox).map(function (d) { - return d.data; - }); - }, - // Get a QAItem from cache - // NOTE: Don't change method name until UI v3 is merged - getError: function getError(id) { - return _cache$2.data[id]; - }, - // Replace a single QAItem in the cache - replaceItem: function replaceItem(item) { - if (!(item instanceof QAItem) || !item.id) return; - _cache$2.data[item.id] = item; - updateRtree$3(encodeIssueRtree$2(item), true); // true = replace - return item; - }, - // Remove a single QAItem from the cache - removeItem: function removeItem(item) { - if (!(item instanceof QAItem) || !item.id) return; - delete _cache$2.data[item.id]; - updateRtree$3(encodeIssueRtree$2(item), false); // false = remove - }, - issueURL: function issueURL(item) { - return "".concat(_krUrlRoot, "/report_map.php?schema=").concat(item.schema, "&error=").concat(item.id); - }, - // Get an array of issues closed during this session. - // Used to populate `closed:keepright` changeset tag - getClosedIDs: function getClosedIDs() { - return Object.keys(_cache$2.closed).sort(); - } - }; + function createRound(methodName) { + var func = Math[methodName]; + return function (number, precision) { + number = toNumber(number); + precision = precision == null ? 0 : nativeMin(toInteger(precision), 292); - var tiler$5 = utilTiler(); - var dispatch$6 = dispatch$8('loaded'); - var _tileZoom$2 = 14; - var _impOsmUrls = { - ow: 'https://grab.community.improve-osm.org/directionOfFlowService', - mr: 'https://grab.community.improve-osm.org/missingGeoService', - tr: 'https://grab.community.improve-osm.org/turnRestrictionService' - }; - var _impOsmData = { - icons: {} - }; // This gets reassigned if reset + if (precision && nativeIsFinite(number)) { + // Shift with exponential notation to avoid floating-point issues. + // See [MDN](https://mdn.io/round#Examples) for more details. + var pair = (toString(number) + 'e').split('e'), + value = func(pair[0] + 'e' + (+pair[1] + precision)); + pair = (toString(value) + 'e').split('e'); + return +(pair[0] + 'e' + (+pair[1] - precision)); + } - var _cache$1; + return func(number); + }; + } + /** + * Creates a set object of `values`. + * + * @private + * @param {Array} values The values to add to the set. + * @returns {Object} Returns the new set. + */ - function abortRequest$5(i) { - Object.values(i).forEach(function (controller) { - if (controller) { - controller.abort(); - } - }); - } - function abortUnwantedRequests$2(cache, tiles) { - Object.keys(cache.inflightTile).forEach(function (k) { - var wanted = tiles.find(function (tile) { - return k === tile.id; - }); + var createSet = !(Set && 1 / setToArray(new Set([, -0]))[1] == INFINITY) ? noop : function (values) { + return new Set(values); + }; + /** + * Creates a `_.toPairs` or `_.toPairsIn` function. + * + * @private + * @param {Function} keysFunc The function to get the keys of a given object. + * @returns {Function} Returns the new pairs function. + */ - if (!wanted) { - abortRequest$5(cache.inflightTile[k]); - delete cache.inflightTile[k]; - } - }); - } + function createToPairs(keysFunc) { + return function (object) { + var tag = getTag(object); - function encodeIssueRtree$1(d) { - return { - minX: d.loc[0], - minY: d.loc[1], - maxX: d.loc[0], - maxY: d.loc[1], - data: d - }; - } // Replace or remove QAItem from rtree + if (tag == mapTag) { + return mapToArray(object); + } + if (tag == setTag) { + return setToPairs(object); + } - function updateRtree$2(item, replace) { - _cache$1.rtree.remove(item, function (a, b) { - return a.data.id === b.data.id; - }); + return baseToPairs(object, keysFunc(object)); + }; + } + /** + * Creates a function that either curries or invokes `func` with optional + * `this` binding and partially applied arguments. + * + * @private + * @param {Function|string} func The function or method name to wrap. + * @param {number} bitmask The bitmask flags. + * 1 - `_.bind` + * 2 - `_.bindKey` + * 4 - `_.curry` or `_.curryRight` of a bound function + * 8 - `_.curry` + * 16 - `_.curryRight` + * 32 - `_.partial` + * 64 - `_.partialRight` + * 128 - `_.rearg` + * 256 - `_.ary` + * 512 - `_.flip` + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to be partially applied. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ - if (replace) { - _cache$1.rtree.insert(item); - } - } - function linkErrorObject(d) { - return "".concat(d, ""); - } + function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) { + var isBindKey = bitmask & WRAP_BIND_KEY_FLAG; - function linkEntity(d) { - return "".concat(d, ""); - } + if (!isBindKey && typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } - function pointAverage(points) { - if (points.length) { - var sum = points.reduce(function (acc, point) { - return geoVecAdd(acc, [point.lon, point.lat]); - }, [0, 0]); - return geoVecScale(sum, 1 / points.length); - } else { - return [0, 0]; - } - } + var length = partials ? partials.length : 0; - function relativeBearing(p1, p2) { - var angle = Math.atan2(p2.lon - p1.lon, p2.lat - p1.lat); + if (!length) { + bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG); + partials = holders = undefined$1; + } - if (angle < 0) { - angle += 2 * Math.PI; - } // Return degrees + ary = ary === undefined$1 ? ary : nativeMax(toInteger(ary), 0); + arity = arity === undefined$1 ? arity : toInteger(arity); + length -= holders ? holders.length : 0; + if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) { + var partialsRight = partials, + holdersRight = holders; + partials = holders = undefined$1; + } - return angle * 180 / Math.PI; - } // Assuming range [0,360) + var data = isBindKey ? undefined$1 : getData(func); + var newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity]; + if (data) { + mergeData(newData, data); + } - function cardinalDirection(bearing) { - var dir = 45 * Math.round(bearing / 45); - var compass = { - 0: 'north', - 45: 'northeast', - 90: 'east', - 135: 'southeast', - 180: 'south', - 225: 'southwest', - 270: 'west', - 315: 'northwest', - 360: 'north' - }; - return _t("QA.improveOSM.directions.".concat(compass[dir])); - } // Errors shouldn't obscure each other + func = newData[0]; + bitmask = newData[1]; + thisArg = newData[2]; + partials = newData[3]; + holders = newData[4]; + arity = newData[9] = newData[9] === undefined$1 ? isBindKey ? 0 : func.length : nativeMax(newData[9] - length, 0); + if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) { + bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG); + } - function preventCoincident$1(loc, bumpUp) { - var coincident = false; + if (!bitmask || bitmask == WRAP_BIND_FLAG) { + var result = createBind(func, bitmask, thisArg); + } else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) { + result = createCurry(func, bitmask, arity); + } else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) { + result = createPartial(func, bitmask, thisArg, partials); + } else { + result = createHybrid.apply(undefined$1, newData); + } - do { - // first time, move marker up. after that, move marker right. - var delta = coincident ? [0.00001, 0] : bumpUp ? [0, 0.00001] : [0, 0]; - loc = geoVecAdd(loc, delta); - var bbox = geoExtent(loc).bbox(); - coincident = _cache$1.rtree.search(bbox).length; - } while (coincident); + var setter = data ? baseSetData : setData; + return setWrapToString(setter(result, newData), func, bitmask); + } + /** + * Used by `_.defaults` to customize its `_.assignIn` use to assign properties + * of source objects to the destination object for all destination properties + * that resolve to `undefined`. + * + * @private + * @param {*} objValue The destination value. + * @param {*} srcValue The source value. + * @param {string} key The key of the property to assign. + * @param {Object} object The parent object of `objValue`. + * @returns {*} Returns the value to assign. + */ - return loc; - } - var serviceImproveOSM = { - title: 'improveOSM', - init: function init() { - _mainFileFetcher.get('qa_data').then(function (d) { - return _impOsmData = d.improveOSM; - }); + function customDefaultsAssignIn(objValue, srcValue, key, object) { + if (objValue === undefined$1 || eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key)) { + return srcValue; + } - if (!_cache$1) { - this.reset(); - } + return objValue; + } + /** + * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source + * objects into destination objects that are passed thru. + * + * @private + * @param {*} objValue The destination value. + * @param {*} srcValue The source value. + * @param {string} key The key of the property to merge. + * @param {Object} object The parent object of `objValue`. + * @param {Object} source The parent object of `srcValue`. + * @param {Object} [stack] Tracks traversed source values and their merged + * counterparts. + * @returns {*} Returns the value to assign. + */ - this.event = utilRebind(this, dispatch$6, 'on'); - }, - reset: function reset() { - if (_cache$1) { - Object.values(_cache$1.inflightTile).forEach(abortRequest$5); - } - _cache$1 = { - data: {}, - loadedTile: {}, - inflightTile: {}, - inflightPost: {}, - closed: {}, - rtree: new RBush() - }; - }, - loadIssues: function loadIssues(projection) { - var _this = this; + function customDefaultsMerge(objValue, srcValue, key, object, source, stack) { + if (isObject(objValue) && isObject(srcValue)) { + // Recursively merge objects and arrays (susceptible to call stack limits). + stack.set(srcValue, objValue); + baseMerge(objValue, srcValue, undefined$1, customDefaultsMerge, stack); + stack['delete'](srcValue); + } - var options = { - client: 'iD', - status: 'OPEN', - zoom: '19' // Use a high zoom so that clusters aren't returned + return objValue; + } + /** + * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain + * objects. + * + * @private + * @param {*} value The value to inspect. + * @param {string} key The key of the property to inspect. + * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`. + */ - }; // determine the needed tiles to cover the view - var tiles = tiler$5.zoomExtent([_tileZoom$2, _tileZoom$2]).getTiles(projection); // abort inflight requests that are no longer needed + function customOmitClone(value) { + return isPlainObject(value) ? undefined$1 : value; + } + /** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `array` and `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ - abortUnwantedRequests$2(_cache$1, tiles); // issue new requests.. - tiles.forEach(function (tile) { - if (_cache$1.loadedTile[tile.id] || _cache$1.inflightTile[tile.id]) return; + function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, + arrLength = array.length, + othLength = other.length; - var _tile$extent$rectangl = tile.extent.rectangle(), - _tile$extent$rectangl2 = _slicedToArray(_tile$extent$rectangl, 4), - east = _tile$extent$rectangl2[0], - north = _tile$extent$rectangl2[1], - west = _tile$extent$rectangl2[2], - south = _tile$extent$rectangl2[3]; + if (arrLength != othLength && !(isPartial && othLength > arrLength)) { + return false; + } // Check that cyclic values are equal. - var params = Object.assign({}, options, { - east: east, - south: south, - west: west, - north: north - }); // 3 separate requests to store for each tile - var requests = {}; - Object.keys(_impOsmUrls).forEach(function (k) { - // We exclude WATER from missing geometry as it doesn't seem useful - // We use most confident one-way and turn restrictions only, still have false positives - var kParams = Object.assign({}, params, k === 'mr' ? { - type: 'PARKING,ROAD,BOTH,PATH' - } : { - confidenceLevel: 'C1' - }); - var url = "".concat(_impOsmUrls[k], "/search?") + utilQsString(kParams); - var controller = new AbortController(); - requests[k] = controller; - d3_json(url, { - signal: controller.signal - }).then(function (data) { - delete _cache$1.inflightTile[tile.id][k]; + var arrStacked = stack.get(array); + var othStacked = stack.get(other); - if (!Object.keys(_cache$1.inflightTile[tile.id]).length) { - delete _cache$1.inflightTile[tile.id]; - _cache$1.loadedTile[tile.id] = true; - } // Road segments at high zoom == oneways + if (arrStacked && othStacked) { + return arrStacked == other && othStacked == array; + } + var index = -1, + result = true, + seen = bitmask & COMPARE_UNORDERED_FLAG ? new SetCache() : undefined$1; + stack.set(array, other); + stack.set(other, array); // Ignore non-index properties. - if (data.roadSegments) { - data.roadSegments.forEach(function (feature) { - // Position error at the approximate middle of the segment - var points = feature.points, - wayId = feature.wayId, - fromNodeId = feature.fromNodeId, - toNodeId = feature.toNodeId; - var itemId = "".concat(wayId).concat(fromNodeId).concat(toNodeId); - var mid = points.length / 2; - var loc; // Even number of points, find midpoint of the middle two - // Odd number of points, use position of very middle point + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index]; - if (mid % 1 === 0) { - loc = pointAverage([points[mid - 1], points[mid]]); - } else { - mid = points[Math.floor(mid)]; - loc = [mid.lon, mid.lat]; - } // One-ways can land on same segment in opposite direction + if (customizer) { + var compared = isPartial ? customizer(othValue, arrValue, index, other, array, stack) : customizer(arrValue, othValue, index, array, other, stack); + } + if (compared !== undefined$1) { + if (compared) { + continue; + } - loc = preventCoincident$1(loc, false); - var d = new QAItem(loc, _this, k, itemId, { - issueKey: k, - // used as a category - identifier: { - // used to post changes - wayId: wayId, - fromNodeId: fromNodeId, - toNodeId: toNodeId - }, - objectId: wayId, - objectType: 'way' - }); // Variables used in the description + result = false; + break; + } // Recursively compare arrays (susceptible to call stack limits). - d.replacements = { - percentage: feature.percentOfTrips, - num_trips: feature.numberOfTrips, - highway: linkErrorObject(_t('QA.keepRight.error_parts.highway')), - from_node: linkEntity('n' + feature.fromNodeId), - to_node: linkEntity('n' + feature.toNodeId) - }; - _cache$1.data[d.id] = d; - _cache$1.rtree.insert(encodeIssueRtree$1(d)); - }); - } // Tiles at high zoom == missing roads + if (seen) { + if (!arraySome(other, function (othValue, othIndex) { + if (!cacheHas(seen, othIndex) && (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { + return seen.push(othIndex); + } + })) { + result = false; + break; + } + } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { + result = false; + break; + } + } + stack['delete'](array); + stack['delete'](other); + return result; + } + /** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ - if (data.tiles) { - data.tiles.forEach(function (feature) { - var type = feature.type, - x = feature.x, - y = feature.y, - numberOfTrips = feature.numberOfTrips; - var geoType = type.toLowerCase(); - var itemId = "".concat(geoType).concat(x).concat(y).concat(numberOfTrips); // Average of recorded points should land on the missing geometry - // Missing geometry could happen to land on another error - var loc = pointAverage(feature.points); - loc = preventCoincident$1(loc, false); - var d = new QAItem(loc, _this, "".concat(k, "-").concat(geoType), itemId, { - issueKey: k, - identifier: { - x: x, - y: y - } - }); - d.replacements = { - num_trips: numberOfTrips, - geometry_type: _t("QA.improveOSM.geometry_types.".concat(geoType)) - }; // -1 trips indicates data came from a 3rd party + function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { + switch (tag) { + case dataViewTag: + if (object.byteLength != other.byteLength || object.byteOffset != other.byteOffset) { + return false; + } - if (numberOfTrips === -1) { - d.desc = _t('QA.improveOSM.error_types.mr.description_alt', d.replacements); - } + object = object.buffer; + other = other.buffer; - _cache$1.data[d.id] = d; + case arrayBufferTag: + if (object.byteLength != other.byteLength || !equalFunc(new Uint8Array(object), new Uint8Array(other))) { + return false; + } - _cache$1.rtree.insert(encodeIssueRtree$1(d)); - }); - } // Entities at high zoom == turn restrictions + return true; + case boolTag: + case dateTag: + case numberTag: + // Coerce booleans to `1` or `0` and dates to milliseconds. + // Invalid dates are coerced to `NaN`. + return eq(+object, +other); - if (data.entities) { - data.entities.forEach(function (feature) { - var point = feature.point, - id = feature.id, - segments = feature.segments, - numberOfPasses = feature.numberOfPasses, - turnType = feature.turnType; - var itemId = "".concat(id.replace(/[,:+#]/g, '_')); // Turn restrictions could be missing at same junction - // We also want to bump the error up so node is accessible + case errorTag: + return object.name == other.name && object.message == other.message; - var loc = preventCoincident$1([point.lon, point.lat], true); // Elements are presented in a strange way + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings, primitives and objects, + // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring + // for more details. + return object == other + ''; - var ids = id.split(','); - var from_way = ids[0]; - var via_node = ids[3]; - var to_way = ids[2].split(':')[1]; - var d = new QAItem(loc, _this, k, itemId, { - issueKey: k, - identifier: id, - objectId: via_node, - objectType: 'node' - }); // Travel direction along from_way clarifies the turn restriction + case mapTag: + var convert = mapToArray; - var _segments$0$points = _slicedToArray(segments[0].points, 2), - p1 = _segments$0$points[0], - p2 = _segments$0$points[1]; + case setTag: + var isPartial = bitmask & COMPARE_PARTIAL_FLAG; + convert || (convert = setToArray); - var dir_of_travel = cardinalDirection(relativeBearing(p1, p2)); // Variables used in the description + if (object.size != other.size && !isPartial) { + return false; + } // Assume cyclic values are equal. - d.replacements = { - num_passed: numberOfPasses, - num_trips: segments[0].numberOfTrips, - turn_restriction: turnType.toLowerCase(), - from_way: linkEntity('w' + from_way), - to_way: linkEntity('w' + to_way), - travel_direction: dir_of_travel, - junction: linkErrorObject(_t('QA.keepRight.error_parts.this_node')) - }; - _cache$1.data[d.id] = d; - _cache$1.rtree.insert(encodeIssueRtree$1(d)); + var stacked = stack.get(object); - dispatch$6.call('loaded'); - }); - } - })["catch"](function () { - delete _cache$1.inflightTile[tile.id][k]; + if (stacked) { + return stacked == other; + } - if (!Object.keys(_cache$1.inflightTile[tile.id]).length) { - delete _cache$1.inflightTile[tile.id]; - _cache$1.loadedTile[tile.id] = true; - } - }); - }); - _cache$1.inflightTile[tile.id] = requests; - }); - }, - getComments: function getComments(item) { - var _this2 = this; + bitmask |= COMPARE_UNORDERED_FLAG; // Recursively compare objects (susceptible to call stack limits). - // If comments already retrieved no need to do so again - if (item.comments) { - return Promise.resolve(item); - } + stack.set(object, other); + var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); + stack['delete'](object); + return result; - var key = item.issueKey; - var qParams = {}; + case symbolTag: + if (symbolValueOf) { + return symbolValueOf.call(object) == symbolValueOf.call(other); + } - if (key === 'ow') { - qParams = item.identifier; - } else if (key === 'mr') { - qParams.tileX = item.identifier.x; - qParams.tileY = item.identifier.y; - } else if (key === 'tr') { - qParams.targetId = item.identifier; - } + } - var url = "".concat(_impOsmUrls[key], "/retrieveComments?") + utilQsString(qParams); + return false; + } + /** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ - var cacheComments = function cacheComments(data) { - // Assign directly for immediate use afterwards - // comments are served newest to oldest - item.comments = data.comments ? data.comments.reverse() : []; - _this2.replaceItem(item); - }; + function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, + objProps = getAllKeys(object), + objLength = objProps.length, + othProps = getAllKeys(other), + othLength = othProps.length; - return d3_json(url).then(cacheComments).then(function () { - return item; - }); - }, - postUpdate: function postUpdate(d, callback) { - if (!serviceOsm.authenticated()) { - // Username required in payload - return callback({ - message: 'Not Authenticated', - status: -3 - }, d); - } + if (objLength != othLength && !isPartial) { + return false; + } - if (_cache$1.inflightPost[d.id]) { - return callback({ - message: 'Error update already inflight', - status: -2 - }, d); - } // Payload can only be sent once username is established + var index = objLength; + while (index--) { + var key = objProps[index]; - serviceOsm.userDetails(sendPayload.bind(this)); + if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) { + return false; + } + } // Check that cyclic values are equal. - function sendPayload(err, user) { - var _this3 = this; - if (err) { - return callback(err, d); - } + var objStacked = stack.get(object); + var othStacked = stack.get(other); - var key = d.issueKey; - var url = "".concat(_impOsmUrls[key], "/comment"); - var payload = { - username: user.display_name, - targetIds: [d.identifier] - }; + if (objStacked && othStacked) { + return objStacked == other && othStacked == object; + } - if (d.newStatus) { - payload.status = d.newStatus; - payload.text = 'status changed'; - } // Comment take place of default text + var result = true; + stack.set(object, other); + stack.set(other, object); + var skipCtor = isPartial; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key]; - if (d.newComment) { - payload.text = d.newComment; - } + if (customizer) { + var compared = isPartial ? customizer(othValue, objValue, key, other, object, stack) : customizer(objValue, othValue, key, object, other, stack); + } // Recursively compare objects (susceptible to call stack limits). - var controller = new AbortController(); - _cache$1.inflightPost[d.id] = controller; - var options = { - method: 'POST', - signal: controller.signal, - body: JSON.stringify(payload) - }; - d3_json(url, options).then(function () { - delete _cache$1.inflightPost[d.id]; // Just a comment, update error in cache - if (!d.newStatus) { - var now = new Date(); - var comments = d.comments ? d.comments : []; - comments.push({ - username: payload.username, - text: payload.text, - timestamp: now.getTime() / 1000 - }); + if (!(compared === undefined$1 ? objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack) : compared)) { + result = false; + break; + } - _this3.replaceItem(d.update({ - comments: comments, - newComment: undefined - })); - } else { - _this3.removeItem(d); + skipCtor || (skipCtor = key == 'constructor'); + } - if (d.newStatus === 'SOLVED') { - // Keep track of the number of issues closed per type to tag the changeset - if (!(d.issueKey in _cache$1.closed)) { - _cache$1.closed[d.issueKey] = 0; - } + if (result && !skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; // Non `Object` object instances with different constructors are not equal. - _cache$1.closed[d.issueKey] += 1; + if (objCtor != othCtor && 'constructor' in object && 'constructor' in other && !(typeof objCtor == 'function' && objCtor instanceof objCtor && typeof othCtor == 'function' && othCtor instanceof othCtor)) { + result = false; } } - if (callback) callback(null, d); - })["catch"](function (err) { - delete _cache$1.inflightPost[d.id]; - if (callback) callback(err.message); - }); - } - }, - // Get all cached QAItems covering the viewport - getItems: function getItems(projection) { - var viewport = projection.clipExtent(); - var min = [viewport[0][0], viewport[1][1]]; - var max = [viewport[1][0], viewport[0][1]]; - var bbox = geoExtent(projection.invert(min), projection.invert(max)).bbox(); - return _cache$1.rtree.search(bbox).map(function (d) { - return d.data; - }); - }, - // Get a QAItem from cache - // NOTE: Don't change method name until UI v3 is merged - getError: function getError(id) { - return _cache$1.data[id]; - }, - // get the name of the icon to display for this item - getIcon: function getIcon(itemType) { - return _impOsmData.icons[itemType]; - }, - // Replace a single QAItem in the cache - replaceItem: function replaceItem(issue) { - if (!(issue instanceof QAItem) || !issue.id) return; - _cache$1.data[issue.id] = issue; - updateRtree$2(encodeIssueRtree$1(issue), true); // true = replace + stack['delete'](object); + stack['delete'](other); + return result; + } + /** + * A specialized version of `baseRest` which flattens the rest array. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @returns {Function} Returns the new function. + */ - return issue; - }, - // Remove a single QAItem from the cache - removeItem: function removeItem(issue) { - if (!(issue instanceof QAItem) || !issue.id) return; - delete _cache$1.data[issue.id]; - updateRtree$2(encodeIssueRtree$1(issue), false); // false = remove - }, - // Used to populate `closed:improveosm:*` changeset tags - getClosedCounts: function getClosedCounts() { - return _cache$1.closed; - } - }; - var defaults$5 = {exports: {}}; + function flatRest(func) { + return setToString(overRest(func, undefined$1, flatten), func + ''); + } + /** + * Creates an array of own enumerable property names and symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ - function getDefaults$1() { - return { - baseUrl: null, - breaks: false, - gfm: true, - headerIds: true, - headerPrefix: '', - highlight: null, - langPrefix: 'language-', - mangle: true, - pedantic: false, - renderer: null, - sanitize: false, - sanitizer: null, - silent: false, - smartLists: false, - smartypants: false, - tokenizer: null, - walkTokens: null, - xhtml: false - }; - } - function changeDefaults$1(newDefaults) { - defaults$5.exports.defaults = newDefaults; - } + function getAllKeys(object) { + return baseGetAllKeys(object, keys, getSymbols); + } + /** + * Creates an array of own and inherited enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ - defaults$5.exports = { - defaults: getDefaults$1(), - getDefaults: getDefaults$1, - changeDefaults: changeDefaults$1 - }; - var escapeTest = /[&<>"']/; - var escapeReplace = /[&<>"']/g; - var escapeTestNoEncode = /[<>"']|&(?!#?\w+;)/; - var escapeReplaceNoEncode = /[<>"']|&(?!#?\w+;)/g; - var escapeReplacements = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''' - }; + function getAllKeysIn(object) { + return baseGetAllKeys(object, keysIn, getSymbolsIn); + } + /** + * Gets metadata for `func`. + * + * @private + * @param {Function} func The function to query. + * @returns {*} Returns the metadata for `func`. + */ - var getEscapeReplacement = function getEscapeReplacement(ch) { - return escapeReplacements[ch]; - }; - function escape$3(html, encode) { - if (encode) { - if (escapeTest.test(html)) { - return html.replace(escapeReplace, getEscapeReplacement); - } - } else { - if (escapeTestNoEncode.test(html)) { - return html.replace(escapeReplaceNoEncode, getEscapeReplacement); - } - } + var getData = !metaMap ? noop : function (func) { + return metaMap.get(func); + }; + /** + * Gets the name of `func`. + * + * @private + * @param {Function} func The function to query. + * @returns {string} Returns the function name. + */ - return html; - } + function getFuncName(func) { + var result = func.name + '', + array = realNames[result], + length = hasOwnProperty.call(realNames, result) ? array.length : 0; - var unescapeTest = /&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig; + while (length--) { + var data = array[length], + otherFunc = data.func; - function unescape$2(html) { - // explicitly match decimal, hex, and named HTML entities - return html.replace(unescapeTest, function (_, n) { - n = n.toLowerCase(); - if (n === 'colon') return ':'; + if (otherFunc == null || otherFunc == func) { + return data.name; + } + } - if (n.charAt(0) === '#') { - return n.charAt(1) === 'x' ? String.fromCharCode(parseInt(n.substring(2), 16)) : String.fromCharCode(+n.substring(1)); - } + return result; + } + /** + * Gets the argument placeholder value for `func`. + * + * @private + * @param {Function} func The function to inspect. + * @returns {*} Returns the placeholder value. + */ - return ''; - }); - } - var caret = /(^|[^\[])\^/g; + function getHolder(func) { + var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func; + return object.placeholder; + } + /** + * Gets the appropriate "iteratee" function. If `_.iteratee` is customized, + * this function returns the custom method, otherwise it returns `baseIteratee`. + * If arguments are provided, the chosen function is invoked with them and + * its result is returned. + * + * @private + * @param {*} [value] The value to convert to an iteratee. + * @param {number} [arity] The arity of the created iteratee. + * @returns {Function} Returns the chosen function or its result. + */ - function edit$1(regex, opt) { - regex = regex.source || regex; - opt = opt || ''; - var obj = { - replace: function replace(name, val) { - val = val.source || val; - val = val.replace(caret, '$1'); - regex = regex.replace(name, val); - return obj; - }, - getRegex: function getRegex() { - return new RegExp(regex, opt); - } - }; - return obj; - } - var nonWordAndColonTest = /[^\w:]/g; - var originIndependentUrl = /^$|^[a-z][a-z0-9+.-]*:|^[?#]/i; + function getIteratee() { + var result = lodash.iteratee || iteratee; + result = result === iteratee ? baseIteratee : result; + return arguments.length ? result(arguments[0], arguments[1]) : result; + } + /** + * Gets the data for `map`. + * + * @private + * @param {Object} map The map to query. + * @param {string} key The reference key. + * @returns {*} Returns the map data. + */ - function cleanUrl$1(sanitize, base, href) { - if (sanitize) { - var prot; - try { - prot = decodeURIComponent(unescape$2(href)).replace(nonWordAndColonTest, '').toLowerCase(); - } catch (e) { - return null; - } + function getMapData(map, key) { + var data = map.__data__; + return isKeyable(key) ? data[typeof key == 'string' ? 'string' : 'hash'] : data.map; + } + /** + * Gets the property names, values, and compare flags of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the match data of `object`. + */ - if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0 || prot.indexOf('data:') === 0) { - return null; - } - } - if (base && !originIndependentUrl.test(href)) { - href = resolveUrl$2(base, href); - } + function getMatchData(object) { + var result = keys(object), + length = result.length; - try { - href = encodeURI(href).replace(/%25/g, '%'); - } catch (e) { - return null; - } + while (length--) { + var key = result[length], + value = object[key]; + result[length] = [key, value, isStrictComparable(value)]; + } - return href; - } + return result; + } + /** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ - var baseUrls = {}; - var justDomain = /^[^:]+:\/*[^/]*$/; - var protocol = /^([^:]+:)[\s\S]*$/; - var domain = /^([^:]+:\/*[^/]*)[\s\S]*$/; - function resolveUrl$2(base, href) { - if (!baseUrls[' ' + base]) { - // we can ignore everything in base after the last slash of its path component, - // but we might need to add _that_ - // https://tools.ietf.org/html/rfc3986#section-3 - if (justDomain.test(base)) { - baseUrls[' ' + base] = base + '/'; - } else { - baseUrls[' ' + base] = rtrim$1(base, '/', true); - } - } + function getNative(object, key) { + var value = getValue(object, key); + return baseIsNative(value) ? value : undefined$1; + } + /** + * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the raw `toStringTag`. + */ - base = baseUrls[' ' + base]; - var relativeBase = base.indexOf(':') === -1; - if (href.substring(0, 2) === '//') { - if (relativeBase) { - return href; - } + function getRawTag(value) { + var isOwn = hasOwnProperty.call(value, symToStringTag), + tag = value[symToStringTag]; - return base.replace(protocol, '$1') + href; - } else if (href.charAt(0) === '/') { - if (relativeBase) { - return href; - } + try { + value[symToStringTag] = undefined$1; + var unmasked = true; + } catch (e) {} - return base.replace(domain, '$1') + href; - } else { - return base + href; - } - } + var result = nativeObjectToString.call(value); - var noopTest$1 = { - exec: function noopTest() {} - }; + if (unmasked) { + if (isOwn) { + value[symToStringTag] = tag; + } else { + delete value[symToStringTag]; + } + } - function merge$2(obj) { - var i = 1, - target, - key; + return result; + } + /** + * Creates an array of the own enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ - for (; i < arguments.length; i++) { - target = arguments[i]; - for (key in target) { - if (Object.prototype.hasOwnProperty.call(target, key)) { - obj[key] = target[key]; - } - } - } + var getSymbols = !nativeGetSymbols ? stubArray : function (object) { + if (object == null) { + return []; + } - return obj; - } + object = Object(object); + return arrayFilter(nativeGetSymbols(object), function (symbol) { + return propertyIsEnumerable.call(object, symbol); + }); + }; + /** + * Creates an array of the own and inherited enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ - function splitCells$1(tableRow, count) { - // ensure that every cell-delimiting pipe has a space - // before it to distinguish it from an escaped pipe - var row = tableRow.replace(/\|/g, function (match, offset, str) { - var escaped = false, - curr = offset; + var getSymbolsIn = !nativeGetSymbols ? stubArray : function (object) { + var result = []; - while (--curr >= 0 && str[curr] === '\\') { - escaped = !escaped; - } + while (object) { + arrayPush(result, getSymbols(object)); + object = getPrototype(object); + } - if (escaped) { - // odd number of slashes means | is escaped - // so we leave it alone - return '|'; - } else { - // add space before unescaped | - return ' |'; - } - }), - cells = row.split(/ \|/); - var i = 0; + return result; + }; + /** + * Gets the `toStringTag` of `value`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ - if (cells.length > count) { - cells.splice(count); - } else { - while (cells.length < count) { - cells.push(''); - } - } + var getTag = baseGetTag; // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6. - for (; i < cells.length; i++) { - // leading or trailing whitespace is ignored per the gfm spec - cells[i] = cells[i].trim().replace(/\\\|/g, '|'); - } + if (DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag || Map && getTag(new Map()) != mapTag || Promise && getTag(Promise.resolve()) != promiseTag || Set && getTag(new Set()) != setTag || WeakMap && getTag(new WeakMap()) != weakMapTag) { + getTag = function getTag(value) { + var result = baseGetTag(value), + Ctor = result == objectTag ? value.constructor : undefined$1, + ctorString = Ctor ? toSource(Ctor) : ''; - return cells; - } // Remove trailing 'c's. Equivalent to str.replace(/c*$/, ''). - // /c*$/ is vulnerable to REDOS. - // invert: Remove suffix of non-c chars instead. Default falsey. + if (ctorString) { + switch (ctorString) { + case dataViewCtorString: + return dataViewTag; + case mapCtorString: + return mapTag; - function rtrim$1(str, c, invert) { - var l = str.length; + case promiseCtorString: + return promiseTag; - if (l === 0) { - return ''; - } // Length of suffix matching the invert condition. + case setCtorString: + return setTag; + case weakMapCtorString: + return weakMapTag; + } + } - var suffLen = 0; // Step left until we fail to match the invert condition. + return result; + }; + } + /** + * Gets the view, applying any `transforms` to the `start` and `end` positions. + * + * @private + * @param {number} start The start of the view. + * @param {number} end The end of the view. + * @param {Array} transforms The transformations to apply to the view. + * @returns {Object} Returns an object containing the `start` and `end` + * positions of the view. + */ - while (suffLen < l) { - var currChar = str.charAt(l - suffLen - 1); - if (currChar === c && !invert) { - suffLen++; - } else if (currChar !== c && invert) { - suffLen++; - } else { - break; - } - } + function getView(start, end, transforms) { + var index = -1, + length = transforms.length; - return str.substr(0, l - suffLen); - } + while (++index < length) { + var data = transforms[index], + size = data.size; - function findClosingBracket$1(str, b) { - if (str.indexOf(b[1]) === -1) { - return -1; - } + switch (data.type) { + case 'drop': + start += size; + break; - var l = str.length; - var level = 0, - i = 0; + case 'dropRight': + end -= size; + break; - for (; i < l; i++) { - if (str[i] === '\\') { - i++; - } else if (str[i] === b[0]) { - level++; - } else if (str[i] === b[1]) { - level--; + case 'take': + end = nativeMin(end, start + size); + break; - if (level < 0) { - return i; + case 'takeRight': + start = nativeMax(start, end - size); + break; + } + } + + return { + 'start': start, + 'end': end + }; } - } - } + /** + * Extracts wrapper details from the `source` body comment. + * + * @private + * @param {string} source The source to inspect. + * @returns {Array} Returns the wrapper details. + */ - return -1; - } - function checkSanitizeDeprecation$1(opt) { - if (opt && opt.sanitize && !opt.silent) { - console.warn('marked(): sanitize and sanitizer parameters are deprecated since version 0.7.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/#/USING_ADVANCED.md#options'); - } - } // copied from https://stackoverflow.com/a/5450113/806777 + function getWrapDetails(source) { + var match = source.match(reWrapDetails); + return match ? match[1].split(reSplitDetails) : []; + } + /** + * Checks if `path` exists on `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @param {Function} hasFunc The function to check properties. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + */ - function repeatString$1(pattern, count) { - if (count < 1) { - return ''; - } + function hasPath(object, path, hasFunc) { + path = castPath(path, object); + var index = -1, + length = path.length, + result = false; - var result = ''; + while (++index < length) { + var key = toKey(path[index]); - while (count > 1) { - if (count & 1) { - result += pattern; - } + if (!(result = object != null && hasFunc(object, key))) { + break; + } - count >>= 1; - pattern += pattern; - } + object = object[key]; + } - return result + pattern; - } + if (result || ++index != length) { + return result; + } - var helpers = { - escape: escape$3, - unescape: unescape$2, - edit: edit$1, - cleanUrl: cleanUrl$1, - resolveUrl: resolveUrl$2, - noopTest: noopTest$1, - merge: merge$2, - splitCells: splitCells$1, - rtrim: rtrim$1, - findClosingBracket: findClosingBracket$1, - checkSanitizeDeprecation: checkSanitizeDeprecation$1, - repeatString: repeatString$1 - }; + length = object == null ? 0 : object.length; + return !!length && isLength(length) && isIndex(key, length) && (isArray(object) || isArguments(object)); + } + /** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ - var defaults$4 = defaults$5.exports.defaults; - var rtrim = helpers.rtrim, - splitCells = helpers.splitCells, - _escape = helpers.escape, - findClosingBracket = helpers.findClosingBracket; - function outputLink(cap, link, raw) { - var href = link.href; - var title = link.title ? _escape(link.title) : null; - var text = cap[1].replace(/\\([\[\]])/g, '$1'); + function initCloneArray(array) { + var length = array.length, + result = new array.constructor(length); // Add properties assigned by `RegExp#exec`. - if (cap[0].charAt(0) !== '!') { - return { - type: 'link', - raw: raw, - href: href, - title: title, - text: text - }; - } else { - return { - type: 'image', - raw: raw, - href: href, - title: title, - text: _escape(text) - }; - } - } + if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } - function indentCodeCompensation(raw, text) { - var matchIndentToCode = raw.match(/^(\s+)(?:```)/); + return result; + } + /** + * Initializes an object clone. + * + * @private + * @param {Object} object The object to clone. + * @returns {Object} Returns the initialized clone. + */ - if (matchIndentToCode === null) { - return text; - } - var indentToCode = matchIndentToCode[1]; - return text.split('\n').map(function (node) { - var matchIndentInNode = node.match(/^\s+/); + function initCloneObject(object) { + return typeof object.constructor == 'function' && !isPrototype(object) ? baseCreate(getPrototype(object)) : {}; + } + /** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ - if (matchIndentInNode === null) { - return node; - } - var _matchIndentInNode = _slicedToArray(matchIndentInNode, 1), - indentInNode = _matchIndentInNode[0]; + function initCloneByTag(object, tag, isDeep) { + var Ctor = object.constructor; - if (indentInNode.length >= indentToCode.length) { - return node.slice(indentToCode.length); - } + switch (tag) { + case arrayBufferTag: + return cloneArrayBuffer(object); - return node; - }).join('\n'); - } - /** - * Tokenizer - */ + case boolTag: + case dateTag: + return new Ctor(+object); + case dataViewTag: + return cloneDataView(object, isDeep); - var Tokenizer_1 = /*#__PURE__*/function () { - function Tokenizer(options) { - _classCallCheck$1(this, Tokenizer); + case float32Tag: + case float64Tag: + case int8Tag: + case int16Tag: + case int32Tag: + case uint8Tag: + case uint8ClampedTag: + case uint16Tag: + case uint32Tag: + return cloneTypedArray(object, isDeep); - this.options = options || defaults$4; - } + case mapTag: + return new Ctor(); - _createClass$1(Tokenizer, [{ - key: "space", - value: function space(src) { - var cap = this.rules.block.newline.exec(src); + case numberTag: + case stringTag: + return new Ctor(object); - if (cap) { - if (cap[0].length > 1) { - return { - type: 'space', - raw: cap[0] - }; - } + case regexpTag: + return cloneRegExp(object); - return { - raw: '\n' - }; + case setTag: + return new Ctor(); + + case symbolTag: + return cloneSymbol(object); + } } - } - }, { - key: "code", - value: function code(src) { - var cap = this.rules.block.code.exec(src); + /** + * Inserts wrapper `details` in a comment at the top of the `source` body. + * + * @private + * @param {string} source The source to modify. + * @returns {Array} details The details to insert. + * @returns {string} Returns the modified source. + */ - if (cap) { - var text = cap[0].replace(/^ {1,4}/gm, ''); - return { - type: 'code', - raw: cap[0], - codeBlockStyle: 'indented', - text: !this.options.pedantic ? rtrim(text, '\n') : text - }; + + function insertWrapDetails(source, details) { + var length = details.length; + + if (!length) { + return source; + } + + var lastIndex = length - 1; + details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex]; + details = details.join(length > 2 ? ', ' : ' '); + return source.replace(reWrapComment, '{\n/* [wrapped with ' + details + '] */\n'); } - } - }, { - key: "fences", - value: function fences(src) { - var cap = this.rules.block.fences.exec(src); + /** + * Checks if `value` is a flattenable `arguments` object or array. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is flattenable, else `false`. + */ - if (cap) { - var raw = cap[0]; - var text = indentCodeCompensation(raw, cap[3] || ''); - return { - type: 'code', - raw: raw, - lang: cap[2] ? cap[2].trim() : cap[2], - text: text - }; + + function isFlattenable(value) { + return isArray(value) || isArguments(value) || !!(spreadableSymbol && value && value[spreadableSymbol]); } - } - }, { - key: "heading", - value: function heading(src) { - var cap = this.rules.block.heading.exec(src); + /** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ - if (cap) { - var text = cap[2].trim(); // remove trailing #s - if (/#$/.test(text)) { - var trimmed = rtrim(text, '#'); + function isIndex(value, length) { + var type = _typeof(value); - if (this.options.pedantic) { - text = trimmed.trim(); - } else if (!trimmed || / $/.test(trimmed)) { - // CommonMark requires space before trailing #s - text = trimmed.trim(); - } + length = length == null ? MAX_SAFE_INTEGER : length; + return !!length && (type == 'number' || type != 'symbol' && reIsUint.test(value)) && value > -1 && value % 1 == 0 && value < length; + } + /** + * Checks if the given arguments are from an iteratee call. + * + * @private + * @param {*} value The potential iteratee value argument. + * @param {*} index The potential iteratee index or key argument. + * @param {*} object The potential iteratee object argument. + * @returns {boolean} Returns `true` if the arguments are from an iteratee call, + * else `false`. + */ + + + function isIterateeCall(value, index, object) { + if (!isObject(object)) { + return false; } - return { - type: 'heading', - raw: cap[0], - depth: cap[1].length, - text: text - }; - } - } - }, { - key: "nptable", - value: function nptable(src) { - var cap = this.rules.block.nptable.exec(src); + var type = _typeof(index); - if (cap) { - var item = { - type: 'table', - header: splitCells(cap[1].replace(/^ *| *\| *$/g, '')), - align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */), - cells: cap[3] ? cap[3].replace(/\n$/, '').split('\n') : [], - raw: cap[0] - }; + if (type == 'number' ? isArrayLike(object) && isIndex(index, object.length) : type == 'string' && index in object) { + return eq(object[index], value); + } - if (item.header.length === item.align.length) { - var l = item.align.length; - var i; + return false; + } + /** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ - for (i = 0; i < l; i++) { - if (/^ *-+: *$/.test(item.align[i])) { - item.align[i] = 'right'; - } else if (/^ *:-+: *$/.test(item.align[i])) { - item.align[i] = 'center'; - } else if (/^ *:-+ *$/.test(item.align[i])) { - item.align[i] = 'left'; - } else { - item.align[i] = null; - } - } - l = item.cells.length; + function isKey(value, object) { + if (isArray(value)) { + return false; + } - for (i = 0; i < l; i++) { - item.cells[i] = splitCells(item.cells[i], item.header.length); - } + var type = _typeof(value); - return item; + if (type == 'number' || type == 'symbol' || type == 'boolean' || value == null || isSymbol(value)) { + return true; } + + return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || object != null && value in Object(object); } - } - }, { - key: "hr", - value: function hr(src) { - var cap = this.rules.block.hr.exec(src); + /** + * Checks if `value` is suitable for use as unique object key. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is suitable, else `false`. + */ - if (cap) { - return { - type: 'hr', - raw: cap[0] - }; + + function isKeyable(value) { + var type = _typeof(value); + + return type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean' ? value !== '__proto__' : value === null; } - } - }, { - key: "blockquote", - value: function blockquote(src) { - var cap = this.rules.block.blockquote.exec(src); + /** + * Checks if `func` has a lazy counterpart. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` has a lazy counterpart, + * else `false`. + */ - if (cap) { - var text = cap[0].replace(/^ *> ?/gm, ''); - return { - type: 'blockquote', - raw: cap[0], - text: text - }; + + function isLaziable(func) { + var funcName = getFuncName(func), + other = lodash[funcName]; + + if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) { + return false; + } + + if (func === other) { + return true; + } + + var data = getData(other); + return !!data && func === data[0]; } - } - }, { - key: "list", - value: function list(src) { - var cap = this.rules.block.list.exec(src); + /** + * Checks if `func` has its source masked. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` is masked, else `false`. + */ - if (cap) { - var raw = cap[0]; - var bull = cap[2]; - var isordered = bull.length > 1; - var list = { - type: 'list', - raw: raw, - ordered: isordered, - start: isordered ? +bull.slice(0, -1) : '', - loose: false, - items: [] - }; // Get each top-level item. - var itemMatch = cap[0].match(this.rules.block.item); - var next = false, - item, - space, - bcurr, - bnext, - addBack, - loose, - istask, - ischecked, - endMatch; - var l = itemMatch.length; - bcurr = this.rules.block.listItemStart.exec(itemMatch[0]); + function isMasked(func) { + return !!maskSrcKey && maskSrcKey in func; + } + /** + * Checks if `func` is capable of being masked. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `func` is maskable, else `false`. + */ - for (var i = 0; i < l; i++) { - item = itemMatch[i]; - raw = item; - if (!this.options.pedantic) { - // Determine if current item contains the end of the list - endMatch = item.match(new RegExp('\\n\\s*\\n {0,' + (bcurr[0].length - 1) + '}\\S')); + var isMaskable = coreJsData ? isFunction : stubFalse; + /** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ - if (endMatch) { - addBack = item.length - endMatch.index + itemMatch.slice(i + 1).join('\n').length; - list.raw = list.raw.substring(0, list.raw.length - addBack); - item = item.substring(0, endMatch.index); - raw = item; - l = i + 1; - } - } // Determine whether the next list item belongs here. - // Backpedal if it does not belong in this list. + function isPrototype(value) { + var Ctor = value && value.constructor, + proto = typeof Ctor == 'function' && Ctor.prototype || objectProto; + return value === proto; + } + /** + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. + */ - if (i !== l - 1) { - bnext = this.rules.block.listItemStart.exec(itemMatch[i + 1]); + function isStrictComparable(value) { + return value === value && !isObject(value); + } + /** + * A specialized version of `matchesProperty` for source values suitable + * for strict equality comparisons, i.e. `===`. + * + * @private + * @param {string} key The key of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ - if (!this.options.pedantic ? bnext[1].length >= bcurr[0].length || bnext[1].length > 3 : bnext[1].length > bcurr[1].length) { - // nested list or continuation - itemMatch.splice(i, 2, itemMatch[i] + (!this.options.pedantic && bnext[1].length < bcurr[0].length && !itemMatch[i].match(/\n$/) ? '' : '\n') + itemMatch[i + 1]); - i--; - l--; - continue; - } else if ( // different bullet style - !this.options.pedantic || this.options.smartLists ? bnext[2][bnext[2].length - 1] !== bull[bull.length - 1] : isordered === (bnext[2].length === 1)) { - addBack = itemMatch.slice(i + 1).join('\n').length; - list.raw = list.raw.substring(0, list.raw.length - addBack); - i = l - 1; - } - bcurr = bnext; - } // Remove the list item's bullet - // so it is seen as the next token. + function matchesStrictComparable(key, srcValue) { + return function (object) { + if (object == null) { + return false; + } + return object[key] === srcValue && (srcValue !== undefined$1 || key in Object(object)); + }; + } + /** + * A specialized version of `_.memoize` which clears the memoized function's + * cache when it exceeds `MAX_MEMOIZE_SIZE`. + * + * @private + * @param {Function} func The function to have its output memoized. + * @returns {Function} Returns the new memoized function. + */ - space = item.length; - item = item.replace(/^ *([*+-]|\d+[.)]) ?/, ''); // Outdent whatever the - // list item contains. Hacky. - if (~item.indexOf('\n ')) { - space -= item.length; - item = !this.options.pedantic ? item.replace(new RegExp('^ {1,' + space + '}', 'gm'), '') : item.replace(/^ {1,4}/gm, ''); - } // trim item newlines at end + function memoizeCapped(func) { + var result = memoize(func, function (key) { + if (cache.size === MAX_MEMOIZE_SIZE) { + cache.clear(); + } + return key; + }); + var cache = result.cache; + return result; + } + /** + * Merges the function metadata of `source` into `data`. + * + * Merging metadata reduces the number of wrappers used to invoke a function. + * This is possible because methods like `_.bind`, `_.curry`, and `_.partial` + * may be applied regardless of execution order. Methods like `_.ary` and + * `_.rearg` modify function arguments, making the order in which they are + * executed important, preventing the merging of metadata. However, we make + * an exception for a safe combined case where curried functions have `_.ary` + * and or `_.rearg` applied. + * + * @private + * @param {Array} data The destination metadata. + * @param {Array} source The source metadata. + * @returns {Array} Returns `data`. + */ - item = rtrim(item, '\n'); - if (i !== l - 1) { - raw = raw + '\n'; - } // Determine whether item is loose or not. - // Use: /(^|\n)(?! )[^\n]+\n\n(?!\s*$)/ - // for discount behavior. + function mergeData(data, source) { + var bitmask = data[1], + srcBitmask = source[1], + newBitmask = bitmask | srcBitmask, + isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG); + var isCombo = srcBitmask == WRAP_ARY_FLAG && bitmask == WRAP_CURRY_FLAG || srcBitmask == WRAP_ARY_FLAG && bitmask == WRAP_REARG_FLAG && data[7].length <= source[8] || srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG) && source[7].length <= source[8] && bitmask == WRAP_CURRY_FLAG; // Exit early if metadata can't be merged. + if (!(isCommon || isCombo)) { + return data; + } // Use source `thisArg` if available. - loose = next || /\n\n(?!\s*$)/.test(raw); - if (i !== l - 1) { - next = raw.slice(-2) === '\n\n'; - if (!loose) loose = next; - } + if (srcBitmask & WRAP_BIND_FLAG) { + data[2] = source[2]; // Set when currying a bound function. - if (loose) { - list.loose = true; - } // Check for task list items + newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG; + } // Compose partial arguments. - if (this.options.gfm) { - istask = /^\[[ xX]\] /.test(item); - ischecked = undefined; + var value = source[3]; - if (istask) { - ischecked = item[1] !== ' '; - item = item.replace(/^\[[ xX]\] +/, ''); - } - } + if (value) { + var partials = data[3]; + data[3] = partials ? composeArgs(partials, value, source[4]) : value; + data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4]; + } // Compose partial right arguments. - list.items.push({ - type: 'list_item', - raw: raw, - task: istask, - checked: ischecked, - loose: loose, - text: item - }); - } - return list; + value = source[5]; + + if (value) { + partials = data[5]; + data[5] = partials ? composeArgsRight(partials, value, source[6]) : value; + data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6]; + } // Use source `argPos` if available. + + + value = source[7]; + + if (value) { + data[7] = value; + } // Use source `ary` if it's smaller. + + + if (srcBitmask & WRAP_ARY_FLAG) { + data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]); + } // Use source `arity` if one is not provided. + + + if (data[9] == null) { + data[9] = source[9]; + } // Use source `func` and merge bitmasks. + + + data[0] = source[0]; + data[1] = newBitmask; + return data; } - } - }, { - key: "html", - value: function html(src) { - var cap = this.rules.block.html.exec(src); + /** + * This function is like + * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * except that it includes inherited enumerable properties. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ - if (cap) { - return { - type: this.options.sanitize ? 'paragraph' : 'html', - raw: cap[0], - pre: !this.options.sanitizer && (cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style'), - text: this.options.sanitize ? this.options.sanitizer ? this.options.sanitizer(cap[0]) : _escape(cap[0]) : cap[0] - }; + + function nativeKeysIn(object) { + var result = []; + + if (object != null) { + for (var key in Object(object)) { + result.push(key); + } + } + + return result; } - } - }, { - key: "def", - value: function def(src) { - var cap = this.rules.block.def.exec(src); + /** + * Converts `value` to a string using `Object.prototype.toString`. + * + * @private + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + */ - if (cap) { - if (cap[3]) cap[3] = cap[3].substring(1, cap[3].length - 1); - var tag = cap[1].toLowerCase().replace(/\s+/g, ' '); - return { - type: 'def', - tag: tag, - raw: cap[0], - href: cap[2], - title: cap[3] - }; + + function objectToString(value) { + return nativeObjectToString.call(value); } - } - }, { - key: "table", - value: function table(src) { - var cap = this.rules.block.table.exec(src); + /** + * A specialized version of `baseRest` which transforms the rest array. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @param {Function} transform The rest array transform. + * @returns {Function} Returns the new function. + */ - if (cap) { - var item = { - type: 'table', - header: splitCells(cap[1].replace(/^ *| *\| *$/g, '')), - align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */), - cells: cap[3] ? cap[3].replace(/\n$/, '').split('\n') : [] - }; - if (item.header.length === item.align.length) { - item.raw = cap[0]; - var l = item.align.length; - var i; + function overRest(func, start, transform) { + start = nativeMax(start === undefined$1 ? func.length - 1 : start, 0); + return function () { + var args = arguments, + index = -1, + length = nativeMax(args.length - start, 0), + array = Array(length); - for (i = 0; i < l; i++) { - if (/^ *-+: *$/.test(item.align[i])) { - item.align[i] = 'right'; - } else if (/^ *:-+: *$/.test(item.align[i])) { - item.align[i] = 'center'; - } else if (/^ *:-+ *$/.test(item.align[i])) { - item.align[i] = 'left'; - } else { - item.align[i] = null; - } + while (++index < length) { + array[index] = args[start + index]; } - l = item.cells.length; + index = -1; + var otherArgs = Array(start + 1); - for (i = 0; i < l; i++) { - item.cells[i] = splitCells(item.cells[i].replace(/^ *\| *| *\| *$/g, ''), item.header.length); + while (++index < start) { + otherArgs[index] = args[index]; } - return item; - } - } - } - }, { - key: "lheading", - value: function lheading(src) { - var cap = this.rules.block.lheading.exec(src); - - if (cap) { - return { - type: 'heading', - raw: cap[0], - depth: cap[2].charAt(0) === '=' ? 1 : 2, - text: cap[1] + otherArgs[start] = transform(array); + return apply(func, this, otherArgs); }; } - } - }, { - key: "paragraph", - value: function paragraph(src) { - var cap = this.rules.block.paragraph.exec(src); + /** + * Gets the parent value at `path` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} path The path to get the parent value of. + * @returns {*} Returns the parent value. + */ - if (cap) { - return { - type: 'paragraph', - raw: cap[0], - text: cap[1].charAt(cap[1].length - 1) === '\n' ? cap[1].slice(0, -1) : cap[1] - }; - } - } - }, { - key: "text", - value: function text(src) { - var cap = this.rules.block.text.exec(src); - if (cap) { - return { - type: 'text', - raw: cap[0], - text: cap[0] - }; + function parent(object, path) { + return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1)); } - } - }, { - key: "escape", - value: function escape(src) { - var cap = this.rules.inline.escape.exec(src); + /** + * Reorder `array` according to the specified indexes where the element at + * the first index is assigned as the first element, the element at + * the second index is assigned as the second element, and so on. + * + * @private + * @param {Array} array The array to reorder. + * @param {Array} indexes The arranged array indexes. + * @returns {Array} Returns `array`. + */ - if (cap) { - return { - type: 'escape', - raw: cap[0], - text: _escape(cap[1]) - }; + + function reorder(array, indexes) { + var arrLength = array.length, + length = nativeMin(indexes.length, arrLength), + oldArray = copyArray(array); + + while (length--) { + var index = indexes[length]; + array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined$1; + } + + return array; } - } - }, { - key: "tag", - value: function tag(src, inLink, inRawBlock) { - var cap = this.rules.inline.tag.exec(src); + /** + * Gets the value at `key`, unless `key` is "__proto__" or "constructor". + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ - if (cap) { - if (!inLink && /^/i.test(cap[0])) { - inLink = false; + + function safeGet(object, key) { + if (key === 'constructor' && typeof object[key] === 'function') { + return; } - if (!inRawBlock && /^<(pre|code|kbd|script)(\s|>)/i.test(cap[0])) { - inRawBlock = true; - } else if (inRawBlock && /^<\/(pre|code|kbd|script)(\s|>)/i.test(cap[0])) { - inRawBlock = false; + if (key == '__proto__') { + return; } - return { - type: this.options.sanitize ? 'text' : 'html', - raw: cap[0], - inLink: inLink, - inRawBlock: inRawBlock, - text: this.options.sanitize ? this.options.sanitizer ? this.options.sanitizer(cap[0]) : _escape(cap[0]) : cap[0] - }; + return object[key]; } - } - }, { - key: "link", - value: function link(src) { - var cap = this.rules.inline.link.exec(src); + /** + * Sets metadata for `func`. + * + * **Note:** If this function becomes hot, i.e. is invoked a lot in a short + * period of time, it will trip its breaker and transition to an identity + * function to avoid garbage collection pauses in V8. See + * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070) + * for more details. + * + * @private + * @param {Function} func The function to associate metadata with. + * @param {*} data The metadata. + * @returns {Function} Returns `func`. + */ - if (cap) { - var trimmedUrl = cap[2].trim(); - if (!this.options.pedantic && /^$/.test(trimmedUrl)) { - return; - } // ending angle bracket cannot be escaped + var setData = shortOut(baseSetData); + /** + * A simple wrapper around the global [`setTimeout`](https://mdn.io/setTimeout). + * + * @private + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @returns {number|Object} Returns the timer id or timeout object. + */ + var setTimeout = ctxSetTimeout || function (func, wait) { + return root.setTimeout(func, wait); + }; + /** + * Sets the `toString` method of `func` to return `string`. + * + * @private + * @param {Function} func The function to modify. + * @param {Function} string The `toString` result. + * @returns {Function} Returns `func`. + */ - var rtrimSlash = rtrim(trimmedUrl.slice(0, -1), '\\'); - if ((trimmedUrl.length - rtrimSlash.length) % 2 === 0) { - return; - } - } else { - // find closing parenthesis - var lastParenIndex = findClosingBracket(cap[2], '()'); + var setToString = shortOut(baseSetToString); + /** + * Sets the `toString` method of `wrapper` to mimic the source of `reference` + * with wrapper details in a comment at the top of the source body. + * + * @private + * @param {Function} wrapper The function to modify. + * @param {Function} reference The reference function. + * @param {number} bitmask The bitmask flags. See `createWrap` for more details. + * @returns {Function} Returns `wrapper`. + */ - if (lastParenIndex > -1) { - var start = cap[0].indexOf('!') === 0 ? 5 : 4; - var linkLen = start + cap[1].length + lastParenIndex; - cap[2] = cap[2].substring(0, lastParenIndex); - cap[0] = cap[0].substring(0, linkLen).trim(); - cap[3] = ''; + function setWrapToString(wrapper, reference, bitmask) { + var source = reference + ''; + return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask))); + } + /** + * Creates a function that'll short out and invoke `identity` instead + * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN` + * milliseconds. + * + * @private + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new shortable function. + */ + + + function shortOut(func) { + var count = 0, + lastCalled = 0; + return function () { + var stamp = nativeNow(), + remaining = HOT_SPAN - (stamp - lastCalled); + lastCalled = stamp; + + if (remaining > 0) { + if (++count >= HOT_COUNT) { + return arguments[0]; + } + } else { + count = 0; } + + return func.apply(undefined$1, arguments); + }; + } + /** + * A specialized version of `_.shuffle` which mutates and sets the size of `array`. + * + * @private + * @param {Array} array The array to shuffle. + * @param {number} [size=array.length] The size of `array`. + * @returns {Array} Returns `array`. + */ + + + function shuffleSelf(array, size) { + var index = -1, + length = array.length, + lastIndex = length - 1; + size = size === undefined$1 ? length : size; + + while (++index < size) { + var rand = baseRandom(index, lastIndex), + value = array[rand]; + array[rand] = array[index]; + array[index] = value; } - var href = cap[2]; - var title = ''; + array.length = size; + return array; + } + /** + * Converts `string` to a property path array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the property path array. + */ - if (this.options.pedantic) { - // split pedantic href and title - var link = /^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(href); - if (link) { - href = link[1]; - title = link[3]; - } - } else { - title = cap[3] ? cap[3].slice(1, -1) : ''; + var stringToPath = memoizeCapped(function (string) { + var result = []; + + if (string.charCodeAt(0) === 46 + /* . */ + ) { + result.push(''); } - href = href.trim(); + string.replace(rePropName, function (match, number, quote, subString) { + result.push(quote ? subString.replace(reEscapeChar, '$1') : number || match); + }); + return result; + }); + /** + * Converts `value` to a string key if it's not a string or symbol. + * + * @private + * @param {*} value The value to inspect. + * @returns {string|symbol} Returns the key. + */ - if (/^$/.test(trimmedUrl)) { - // pedantic allows starting angle bracket without ending angle bracket - href = href.slice(1); - } else { - href = href.slice(1, -1); - } + function toKey(value) { + if (typeof value == 'string' || isSymbol(value)) { + return value; } - return outputLink(cap, { - href: href ? href.replace(this.rules.inline._escapes, '$1') : href, - title: title ? title.replace(this.rules.inline._escapes, '$1') : title - }, cap[0]); + var result = value + ''; + return result == '0' && 1 / value == -INFINITY ? '-0' : result; } - } - }, { - key: "reflink", - value: function reflink(src, links) { - var cap; + /** + * Converts `func` to its source code. + * + * @private + * @param {Function} func The function to convert. + * @returns {string} Returns the source code. + */ - if ((cap = this.rules.inline.reflink.exec(src)) || (cap = this.rules.inline.nolink.exec(src))) { - var link = (cap[2] || cap[1]).replace(/\s+/g, ' '); - link = links[link.toLowerCase()]; - if (!link || !link.href) { - var text = cap[0].charAt(0); - return { - type: 'text', - raw: text, - text: text - }; + function toSource(func) { + if (func != null) { + try { + return funcToString.call(func); + } catch (e) {} + + try { + return func + ''; + } catch (e) {} } - return outputLink(cap, link, cap[0]); + return ''; } - } - }, { - key: "emStrong", - value: function emStrong(src, maskedSrc) { - var prevChar = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ''; - var match = this.rules.inline.emStrong.lDelim.exec(src); - if (!match) return; // _ can't be between two alphanumerics. \p{L}\p{N} includes non-english alphabet/numbers as well + /** + * Updates wrapper `details` based on `bitmask` flags. + * + * @private + * @returns {Array} details The details to modify. + * @param {number} bitmask The bitmask flags. See `createWrap` for more details. + * @returns {Array} Returns `details`. + */ - if (match[3] && prevChar.match(/(?:[0-9A-Za-z\xAA\xB2\xB3\xB5\xB9\xBA\xBC-\xBE\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0560-\u0588\u05D0-\u05EA\u05EF-\u05F2\u0620-\u064A\u0660-\u0669\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07C0-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08C7\u0904-\u0939\u093D\u0950\u0958-\u0961\u0966-\u096F\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09E6-\u09F1\u09F4-\u09F9\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A66-\u0A6F\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AE6-\u0AEF\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B66-\u0B6F\u0B71-\u0B77\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0BE6-\u0BF2\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C66-\u0C6F\u0C78-\u0C7E\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CE6-\u0CEF\u0CF1\u0CF2\u0D04-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D58-\u0D61\u0D66-\u0D78\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DE6-\u0DEF\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E86-\u0E8A\u0E8C-\u0EA3\u0EA5\u0EA7-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F20-\u0F33\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F-\u1049\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u1090-\u1099\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1369-\u137C\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u17E0-\u17E9\u17F0-\u17F9\u1810-\u1819\u1820-\u1878\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A16\u1A20-\u1A54\u1A80-\u1A89\u1A90-\u1A99\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B50-\u1B59\u1B83-\u1BA0\u1BAE-\u1BE5\u1C00-\u1C23\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1C90-\u1CBA\u1CBD-\u1CBF\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5\u1CF6\u1CFA\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2070\u2071\u2074-\u2079\u207F-\u2089\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2150-\u2189\u2460-\u249B\u24EA-\u24FF\u2776-\u2793\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2CFD\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312F\u3131-\u318E\u3192-\u3195\u31A0-\u31BF\u31F0-\u31FF\u3220-\u3229\u3248-\u324F\u3251-\u325F\u3280-\u3289\u32B1-\u32BF\u3400-\u4DBF\u4E00-\u9FFC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7BF\uA7C2-\uA7CA\uA7F5-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA830-\uA835\uA840-\uA873\uA882-\uA8B3\uA8D0-\uA8D9\uA8F2-\uA8F7\uA8FB\uA8FD\uA8FE\uA900-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF-\uA9D9\uA9E0-\uA9E4\uA9E6-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA50-\uAA59\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB69\uAB70-\uABE2\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD07-\uDD33\uDD40-\uDD78\uDD8A\uDD8B\uDE80-\uDE9C\uDEA0-\uDED0\uDEE1-\uDEFB\uDF00-\uDF23\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC58-\uDC76\uDC79-\uDC9E\uDCA7-\uDCAF\uDCE0-\uDCF2\uDCF4\uDCF5\uDCFB-\uDD1B\uDD20-\uDD39\uDD80-\uDDB7\uDDBC-\uDDCF\uDDD2-\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE35\uDE40-\uDE48\uDE60-\uDE7E\uDE80-\uDE9F\uDEC0-\uDEC7\uDEC9-\uDEE4\uDEEB-\uDEEF\uDF00-\uDF35\uDF40-\uDF55\uDF58-\uDF72\uDF78-\uDF91\uDFA9-\uDFAF]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2\uDCFA-\uDD23\uDD30-\uDD39\uDE60-\uDE7E\uDE80-\uDEA9\uDEB0\uDEB1\uDF00-\uDF27\uDF30-\uDF45\uDF51-\uDF54\uDFB0-\uDFCB\uDFE0-\uDFF6]|\uD804[\uDC03-\uDC37\uDC52-\uDC6F\uDC83-\uDCAF\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD03-\uDD26\uDD36-\uDD3F\uDD44\uDD47\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDD0-\uDDDA\uDDDC\uDDE1-\uDDF4\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDEF0-\uDEF9\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC50-\uDC59\uDC5F-\uDC61\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE50-\uDE59\uDE80-\uDEAA\uDEB8\uDEC0-\uDEC9\uDF00-\uDF1A\uDF30-\uDF3B]|\uD806[\uDC00-\uDC2B\uDCA0-\uDCF2\uDCFF-\uDD06\uDD09\uDD0C-\uDD13\uDD15\uDD16\uDD18-\uDD2F\uDD3F\uDD41\uDD50-\uDD59\uDDA0-\uDDA7\uDDAA-\uDDD0\uDDE1\uDDE3\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE89\uDE9D\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC50-\uDC6C\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46\uDD50-\uDD59\uDD60-\uDD65\uDD67\uDD68\uDD6A-\uDD89\uDD98\uDDA0-\uDDA9\uDEE0-\uDEF2\uDFB0\uDFC0-\uDFD4]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD822\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879\uD880-\uD883][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF50-\uDF59\uDF5B-\uDF61\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDE40-\uDE96\uDF00-\uDF4A\uDF50\uDF93-\uDF9F\uDFE0\uDFE1\uDFE3]|\uD821[\uDC00-\uDFF7]|\uD823[\uDC00-\uDCD5\uDD00-\uDD08]|\uD82C[\uDC00-\uDD1E\uDD50-\uDD52\uDD64-\uDD67\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD834[\uDEE0-\uDEF3\uDF60-\uDF78]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD838[\uDD00-\uDD2C\uDD37-\uDD3D\uDD40-\uDD49\uDD4E\uDEC0-\uDEEB\uDEF0-\uDEF9]|\uD83A[\uDC00-\uDCC4\uDCC7-\uDCCF\uDD00-\uDD43\uDD4B\uDD50-\uDD59]|\uD83B[\uDC71-\uDCAB\uDCAD-\uDCAF\uDCB1-\uDCB4\uDD01-\uDD2D\uDD2F-\uDD3D\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD83C[\uDD00-\uDD0C]|\uD83E[\uDFF0-\uDFF9]|\uD869[\uDC00-\uDEDD\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uD884[\uDC00-\uDF4A])/)) return; - var nextChar = match[1] || match[2] || ''; - if (!nextChar || nextChar && (prevChar === '' || this.rules.inline.punctuation.exec(prevChar))) { - var lLength = match[0].length - 1; - var rDelim, - rLength, - delimTotal = lLength, - midDelimTotal = 0; - var endReg = match[0][0] === '*' ? this.rules.inline.emStrong.rDelimAst : this.rules.inline.emStrong.rDelimUnd; - endReg.lastIndex = 0; // Clip maskedSrc to same section of string as src (move to lexer?) + function updateWrapDetails(details, bitmask) { + arrayEach(wrapFlags, function (pair) { + var value = '_.' + pair[0]; - maskedSrc = maskedSrc.slice(-1 * src.length + lLength); + if (bitmask & pair[1] && !arrayIncludes(details, value)) { + details.push(value); + } + }); + return details.sort(); + } + /** + * Creates a clone of `wrapper`. + * + * @private + * @param {Object} wrapper The wrapper to clone. + * @returns {Object} Returns the cloned wrapper. + */ - while ((match = endReg.exec(maskedSrc)) != null) { - rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6]; - if (!rDelim) continue; // skip single * in __abc*abc__ - rLength = rDelim.length; + function wrapperClone(wrapper) { + if (wrapper instanceof LazyWrapper) { + return wrapper.clone(); + } - if (match[3] || match[4]) { - // found another Left Delim - delimTotal += rLength; - continue; - } else if (match[5] || match[6]) { - // either Left or Right Delim - if (lLength % 3 && !((lLength + rLength) % 3)) { - midDelimTotal += rLength; - continue; // CommonMark Emphasis Rules 9-10 - } - } + var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__); + result.__actions__ = copyArray(wrapper.__actions__); + result.__index__ = wrapper.__index__; + result.__values__ = wrapper.__values__; + return result; + } + /*------------------------------------------------------------------------*/ - delimTotal -= rLength; - if (delimTotal > 0) continue; // Haven't found enough closing delimiters - // Remove extra characters. *a*** -> *a* + /** + * Creates an array of elements split into groups the length of `size`. + * If `array` can't be split evenly, the final chunk will be the remaining + * elements. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to process. + * @param {number} [size=1] The length of each chunk + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Array} Returns the new array of chunks. + * @example + * + * _.chunk(['a', 'b', 'c', 'd'], 2); + * // => [['a', 'b'], ['c', 'd']] + * + * _.chunk(['a', 'b', 'c', 'd'], 3); + * // => [['a', 'b', 'c'], ['d']] + */ - rLength = Math.min(rLength, rLength + delimTotal + midDelimTotal); // Create `em` if smallest delimiter has odd char count. *a*** - if (Math.min(lLength, rLength) % 2) { - return { - type: 'em', - raw: src.slice(0, lLength + match.index + rLength + 1), - text: src.slice(1, lLength + match.index + rLength) - }; - } // Create 'strong' if smallest delimiter has even char count. **a*** + function chunk(array, size, guard) { + if (guard ? isIterateeCall(array, size, guard) : size === undefined$1) { + size = 1; + } else { + size = nativeMax(toInteger(size), 0); + } + var length = array == null ? 0 : array.length; - return { - type: 'strong', - raw: src.slice(0, lLength + match.index + rLength + 1), - text: src.slice(2, lLength + match.index + rLength - 1) - }; + if (!length || size < 1) { + return []; } - } - } - }, { - key: "codespan", - value: function codespan(src) { - var cap = this.rules.inline.code.exec(src); - if (cap) { - var text = cap[2].replace(/\n/g, ' '); - var hasNonSpaceChars = /[^ ]/.test(text); - var hasSpaceCharsOnBothEnds = /^ /.test(text) && / $/.test(text); + var index = 0, + resIndex = 0, + result = Array(nativeCeil(length / size)); - if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) { - text = text.substring(1, text.length - 1); + while (index < length) { + result[resIndex++] = baseSlice(array, index, index += size); } - text = _escape(text, true); - return { - type: 'codespan', - raw: cap[0], - text: text - }; + return result; } - } - }, { - key: "br", - value: function br(src) { - var cap = this.rules.inline.br.exec(src); - - if (cap) { - return { - type: 'br', - raw: cap[0] - }; - } - } - }, { - key: "del", - value: function del(src) { - var cap = this.rules.inline.del.exec(src); + /** + * Creates an array with all falsey values removed. The values `false`, `null`, + * `0`, `""`, `undefined`, and `NaN` are falsey. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to compact. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.compact([0, 1, false, 2, '', 3]); + * // => [1, 2, 3] + */ - if (cap) { - return { - type: 'del', - raw: cap[0], - text: cap[2] - }; - } - } - }, { - key: "autolink", - value: function autolink(src, mangle) { - var cap = this.rules.inline.autolink.exec(src); - if (cap) { - var text, href; + function compact(array) { + var index = -1, + length = array == null ? 0 : array.length, + resIndex = 0, + result = []; - if (cap[2] === '@') { - text = _escape(this.options.mangle ? mangle(cap[1]) : cap[1]); - href = 'mailto:' + text; - } else { - text = _escape(cap[1]); - href = text; + while (++index < length) { + var value = array[index]; + + if (value) { + result[resIndex++] = value; + } } - return { - type: 'link', - raw: cap[0], - text: text, - href: href, - tokens: [{ - type: 'text', - raw: text, - text: text - }] - }; + return result; } - } - }, { - key: "url", - value: function url(src, mangle) { - var cap; + /** + * Creates a new array concatenating `array` with any additional arrays + * and/or values. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to concatenate. + * @param {...*} [values] The values to concatenate. + * @returns {Array} Returns the new concatenated array. + * @example + * + * var array = [1]; + * var other = _.concat(array, 2, [3], [[4]]); + * + * console.log(other); + * // => [1, 2, 3, [4]] + * + * console.log(array); + * // => [1] + */ - if (cap = this.rules.inline.url.exec(src)) { - var text, href; - if (cap[2] === '@') { - text = _escape(this.options.mangle ? mangle(cap[0]) : cap[0]); - href = 'mailto:' + text; - } else { - // do extended autolink path validation - var prevCapZero; + function concat() { + var length = arguments.length; - do { - prevCapZero = cap[0]; - cap[0] = this.rules.inline._backpedal.exec(cap[0])[0]; - } while (prevCapZero !== cap[0]); + if (!length) { + return []; + } - text = _escape(cap[0]); + var args = Array(length - 1), + array = arguments[0], + index = length; - if (cap[1] === 'www.') { - href = 'http://' + text; - } else { - href = text; - } + while (index--) { + args[index - 1] = arguments[index]; } - return { - type: 'link', - raw: cap[0], - text: text, - href: href, - tokens: [{ - type: 'text', - raw: text, - text: text - }] - }; + return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1)); } - } - }, { - key: "inlineText", - value: function inlineText(src, inRawBlock, smartypants) { - var cap = this.rules.inline.text.exec(src); - - if (cap) { - var text; + /** + * Creates an array of `array` values not included in the other given arrays + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. The order and references of result values are + * determined by the first array. + * + * **Note:** Unlike `_.pullAll`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {...Array} [values] The values to exclude. + * @returns {Array} Returns the new array of filtered values. + * @see _.without, _.xor + * @example + * + * _.difference([2, 1], [2, 3]); + * // => [1] + */ - if (inRawBlock) { - text = this.options.sanitize ? this.options.sanitizer ? this.options.sanitizer(cap[0]) : _escape(cap[0]) : cap[0]; - } else { - text = _escape(this.options.smartypants ? smartypants(cap[0]) : cap[0]); - } - return { - type: 'text', - raw: cap[0], - text: text - }; - } - } - }]); + var difference = baseRest(function (array, values) { + return isArrayLikeObject(array) ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true)) : []; + }); + /** + * This method is like `_.difference` except that it accepts `iteratee` which + * is invoked for each element of `array` and `values` to generate the criterion + * by which they're compared. The order and references of result values are + * determined by the first array. The iteratee is invoked with one argument: + * (value). + * + * **Note:** Unlike `_.pullAllBy`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {...Array} [values] The values to exclude. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor); + * // => [1.2] + * + * // The `_.property` iteratee shorthand. + * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x'); + * // => [{ 'x': 2 }] + */ - return Tokenizer; - }(); + var differenceBy = baseRest(function (array, values) { + var iteratee = last(values); - var noopTest = helpers.noopTest, - edit = helpers.edit, - merge$1 = helpers.merge; - /** - * Block-Level Grammar - */ + if (isArrayLikeObject(iteratee)) { + iteratee = undefined$1; + } - var block$1 = { - newline: /^(?: *(?:\n|$))+/, - code: /^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/, - fences: /^ {0,3}(`{3,}(?=[^`\n]*\n)|~{3,})([^\n]*)\n(?:|([\s\S]*?)\n)(?: {0,3}\1[~`]* *(?:\n+|$)|$)/, - hr: /^ {0,3}((?:- *){3,}|(?:_ *){3,}|(?:\* *){3,})(?:\n+|$)/, - heading: /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/, - blockquote: /^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/, - list: /^( {0,3})(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?! {0,3}bull )\n*|\s*$)/, - html: '^ {0,3}(?:' // optional indentation - + '<(script|pre|style)[\\s>][\\s\\S]*?(?:[^\\n]*\\n+|$)' // (1) - + '|comment[^\\n]*(\\n+|$)' // (2) - + '|<\\?[\\s\\S]*?(?:\\?>\\n*|$)' // (3) - + '|\\n*|$)' // (4) - + '|\\n*|$)' // (5) - + '|)[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (6) - + '|<(?!script|pre|style)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) open tag - + '|(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) closing tag - + ')', - def: /^ {0,3}\[(label)\]: *\n? *]+)>?(?:(?: +\n? *| *\n *)(title))? *(?:\n+|$)/, - nptable: noopTest, - table: noopTest, - lheading: /^([^\n]+)\n {0,3}(=+|-+) *(?:\n+|$)/, - // regex template, placeholders will be replaced according to different paragraph - // interruption rules of commonmark and the original markdown spec: - _paragraph: /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html| +\n)[^\n]+)*)/, - text: /^[^\n]+/ - }; - block$1._label = /(?!\s*\])(?:\\[\[\]]|[^\[\]])+/; - block$1._title = /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/; - block$1.def = edit(block$1.def).replace('label', block$1._label).replace('title', block$1._title).getRegex(); - block$1.bullet = /(?:[*+-]|\d{1,9}[.)])/; - block$1.item = /^( *)(bull) ?[^\n]*(?:\n(?! *bull ?)[^\n]*)*/; - block$1.item = edit(block$1.item, 'gm').replace(/bull/g, block$1.bullet).getRegex(); - block$1.listItemStart = edit(/^( *)(bull) */).replace('bull', block$1.bullet).getRegex(); - block$1.list = edit(block$1.list).replace(/bull/g, block$1.bullet).replace('hr', '\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))').replace('def', '\\n+(?=' + block$1.def.source + ')').getRegex(); - block$1._tag = 'address|article|aside|base|basefont|blockquote|body|caption' + '|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption' + '|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe' + '|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option' + '|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr' + '|track|ul'; - block$1._comment = /|$)/; - block$1.html = edit(block$1.html, 'i').replace('comment', block$1._comment).replace('tag', block$1._tag).replace('attribute', / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(); - block$1.paragraph = edit(block$1._paragraph).replace('hr', block$1.hr).replace('heading', ' {0,3}#{1,6} ').replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs - .replace('blockquote', ' {0,3}>').replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n').replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt - .replace('html', ')|<(?:script|pre|style|!--)').replace('tag', block$1._tag) // pars can be interrupted by type (6) html blocks - .getRegex(); - block$1.blockquote = edit(block$1.blockquote).replace('paragraph', block$1.paragraph).getRegex(); - /** - * Normal Block Grammar - */ + return isArrayLikeObject(array) ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee, 2)) : []; + }); + /** + * This method is like `_.difference` except that it accepts `comparator` + * which is invoked to compare elements of `array` to `values`. The order and + * references of result values are determined by the first array. The comparator + * is invoked with two arguments: (arrVal, othVal). + * + * **Note:** Unlike `_.pullAllWith`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {...Array} [values] The values to exclude. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; + * + * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual); + * // => [{ 'x': 2, 'y': 1 }] + */ - block$1.normal = merge$1({}, block$1); - /** - * GFM Block Grammar - */ + var differenceWith = baseRest(function (array, values) { + var comparator = last(values); - block$1.gfm = merge$1({}, block$1.normal, { - nptable: '^ *([^|\\n ].*\\|.*)\\n' // Header - + ' {0,3}([-:]+ *\\|[-| :]*)' // Align - + '(?:\\n((?:(?!\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)', - // Cells - table: '^ *\\|(.+)\\n' // Header - + ' {0,3}\\|?( *[-:]+[-| :]*)' // Align - + '(?:\\n *((?:(?!\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)' // Cells + if (isArrayLikeObject(comparator)) { + comparator = undefined$1; + } - }); - block$1.gfm.nptable = edit(block$1.gfm.nptable).replace('hr', block$1.hr).replace('heading', ' {0,3}#{1,6} ').replace('blockquote', ' {0,3}>').replace('code', ' {4}[^\\n]').replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n').replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt - .replace('html', ')|<(?:script|pre|style|!--)').replace('tag', block$1._tag) // tables can be interrupted by type (6) html blocks - .getRegex(); - block$1.gfm.table = edit(block$1.gfm.table).replace('hr', block$1.hr).replace('heading', ' {0,3}#{1,6} ').replace('blockquote', ' {0,3}>').replace('code', ' {4}[^\\n]').replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n').replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt - .replace('html', ')|<(?:script|pre|style|!--)').replace('tag', block$1._tag) // tables can be interrupted by type (6) html blocks - .getRegex(); - /** - * Pedantic grammar (original John Gruber's loose markdown specification) - */ + return isArrayLikeObject(array) ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined$1, comparator) : []; + }); + /** + * Creates a slice of `array` with `n` elements dropped from the beginning. + * + * @static + * @memberOf _ + * @since 0.5.0 + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to drop. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.drop([1, 2, 3]); + * // => [2, 3] + * + * _.drop([1, 2, 3], 2); + * // => [3] + * + * _.drop([1, 2, 3], 5); + * // => [] + * + * _.drop([1, 2, 3], 0); + * // => [1, 2, 3] + */ - block$1.pedantic = merge$1({}, block$1.normal, { - html: edit('^ *(?:comment *(?:\\n|\\s*$)' + '|<(tag)[\\s\\S]+? *(?:\\n{2,}|\\s*$)' // closed tag - + '|\\s]*)*?/?> *(?:\\n{2,}|\\s*$))').replace('comment', block$1._comment).replace(/tag/g, '(?!(?:' + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub' + '|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)' + '\\b)\\w+(?!:|[^\\w\\s@]*@)\\b').getRegex(), - def: /^ *\[([^\]]+)\]: *]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/, - heading: /^(#{1,6})(.*)(?:\n+|$)/, - fences: noopTest, - // fences not supported - paragraph: edit(block$1.normal._paragraph).replace('hr', block$1.hr).replace('heading', ' *#{1,6} *[^\n]').replace('lheading', block$1.lheading).replace('blockquote', ' {0,3}>').replace('|fences', '').replace('|list', '').replace('|html', '').getRegex() - }); - /** - * Inline-Level Grammar - */ + function drop(array, n, guard) { + var length = array == null ? 0 : array.length; - var inline$1 = { - escape: /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/, - autolink: /^<(scheme:[^\s\x00-\x1f<>]*|email)>/, - url: noopTest, - tag: '^comment' + '|^' // self-closing tag - + '|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>' // open tag - + '|^<\\?[\\s\\S]*?\\?>' // processing instruction, e.g. - + '|^' // declaration, e.g. - + '|^', - // CDATA section - link: /^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/, - reflink: /^!?\[(label)\]\[(?!\s*\])((?:\\[\[\]]?|[^\[\]\\])+)\]/, - nolink: /^!?\[(?!\s*\])((?:\[[^\[\]]*\]|\\[\[\]]|[^\[\]])*)\](?:\[\])?/, - reflinkSearch: 'reflink|nolink(?!\\()', - emStrong: { - lDelim: /^(?:\*+(?:([punct_])|[^\s*]))|^_+(?:([punct*])|([^\s_]))/, - // (1) and (2) can only be a Right Delimiter. (3) and (4) can only be Left. (5) and (6) can be either Left or Right. - // () Skip other delimiter (1) #*** (2) a***#, a*** (3) #***a, ***a (4) ***# (5) #***# (6) a***a - rDelimAst: /\_\_[^_*]*?\*[^_*]*?\_\_|[punct_](\*+)(?=[\s]|$)|[^punct*_\s](\*+)(?=[punct_\s]|$)|[punct_\s](\*+)(?=[^punct*_\s])|[\s](\*+)(?=[punct_])|[punct_](\*+)(?=[punct_])|[^punct*_\s](\*+)(?=[^punct*_\s])/, - rDelimUnd: /\*\*[^_*]*?\_[^_*]*?\*\*|[punct*](\_+)(?=[\s]|$)|[^punct*_\s](\_+)(?=[punct*\s]|$)|[punct*\s](\_+)(?=[^punct*_\s])|[\s](\_+)(?=[punct*])|[punct*](\_+)(?=[punct*])/ // ^- Not allowed for _ + if (!length) { + return []; + } - }, - code: /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/, - br: /^( {2,}|\\)\n(?!\s*$)/, - del: noopTest, - text: /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\ [1, 2] + * + * _.dropRight([1, 2, 3], 2); + * // => [1] + * + * _.dropRight([1, 2, 3], 5); + * // => [] + * + * _.dropRight([1, 2, 3], 0); + * // => [1, 2, 3] + */ - inline$1._punctuation = '!"#$%&\'()+\\-.,/:;<=>?@\\[\\]`^{|}~'; - inline$1.punctuation = edit(inline$1.punctuation).replace(/punctuation/g, inline$1._punctuation).getRegex(); // sequences em should skip over [title](link), `code`, - inline$1.blockSkip = /\[[^\]]*?\]\([^\)]*?\)|`[^`]*?`|<[^>]*?>/g; - inline$1.escapedEmSt = /\\\*|\\_/g; - inline$1._comment = edit(block$1._comment).replace('(?:-->|$)', '-->').getRegex(); - inline$1.emStrong.lDelim = edit(inline$1.emStrong.lDelim).replace(/punct/g, inline$1._punctuation).getRegex(); - inline$1.emStrong.rDelimAst = edit(inline$1.emStrong.rDelimAst, 'g').replace(/punct/g, inline$1._punctuation).getRegex(); - inline$1.emStrong.rDelimUnd = edit(inline$1.emStrong.rDelimUnd, 'g').replace(/punct/g, inline$1._punctuation).getRegex(); - inline$1._escapes = /\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g; - inline$1._scheme = /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/; - inline$1._email = /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/; - inline$1.autolink = edit(inline$1.autolink).replace('scheme', inline$1._scheme).replace('email', inline$1._email).getRegex(); - inline$1._attribute = /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/; - inline$1.tag = edit(inline$1.tag).replace('comment', inline$1._comment).replace('attribute', inline$1._attribute).getRegex(); - inline$1._label = /(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/; - inline$1._href = /<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/; - inline$1._title = /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/; - inline$1.link = edit(inline$1.link).replace('label', inline$1._label).replace('href', inline$1._href).replace('title', inline$1._title).getRegex(); - inline$1.reflink = edit(inline$1.reflink).replace('label', inline$1._label).getRegex(); - inline$1.reflinkSearch = edit(inline$1.reflinkSearch, 'g').replace('reflink', inline$1.reflink).replace('nolink', inline$1.nolink).getRegex(); - /** - * Normal Inline Grammar - */ + function dropRight(array, n, guard) { + var length = array == null ? 0 : array.length; - inline$1.normal = merge$1({}, inline$1); - /** - * Pedantic Inline Grammar - */ + if (!length) { + return []; + } - inline$1.pedantic = merge$1({}, inline$1.normal, { - strong: { - start: /^__|\*\*/, - middle: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/, - endAst: /\*\*(?!\*)/g, - endUnd: /__(?!_)/g - }, - em: { - start: /^_|\*/, - middle: /^()\*(?=\S)([\s\S]*?\S)\*(?!\*)|^_(?=\S)([\s\S]*?\S)_(?!_)/, - endAst: /\*(?!\*)/g, - endUnd: /_(?!_)/g - }, - link: edit(/^!?\[(label)\]\((.*?)\)/).replace('label', inline$1._label).getRegex(), - reflink: edit(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace('label', inline$1._label).getRegex() - }); - /** - * GFM Inline Grammar - */ + n = guard || n === undefined$1 ? 1 : toInteger(n); + n = length - n; + return baseSlice(array, 0, n < 0 ? 0 : n); + } + /** + * Creates a slice of `array` excluding elements dropped from the end. + * Elements are dropped until `predicate` returns falsey. The predicate is + * invoked with three arguments: (value, index, array). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to query. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the slice of `array`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * _.dropRightWhile(users, function(o) { return !o.active; }); + * // => objects for ['barney'] + * + * // The `_.matches` iteratee shorthand. + * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false }); + * // => objects for ['barney', 'fred'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.dropRightWhile(users, ['active', false]); + * // => objects for ['barney'] + * + * // The `_.property` iteratee shorthand. + * _.dropRightWhile(users, 'active'); + * // => objects for ['barney', 'fred', 'pebbles'] + */ - inline$1.gfm = merge$1({}, inline$1.normal, { - escape: edit(inline$1.escape).replace('])', '~|])').getRegex(), - _extended_email: /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/, - url: /^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/, - _backpedal: /(?:[^?!.,:;*_~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_~)]+(?!$))+/, - del: /^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/, - text: /^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\ objects for ['pebbles'] + * + * // The `_.matches` iteratee shorthand. + * _.dropWhile(users, { 'user': 'barney', 'active': false }); + * // => objects for ['fred', 'pebbles'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.dropWhile(users, ['active', false]); + * // => objects for ['pebbles'] + * + * // The `_.property` iteratee shorthand. + * _.dropWhile(users, 'active'); + * // => objects for ['barney', 'fred', 'pebbles'] + */ - var Tokenizer$1 = Tokenizer_1; - var defaults$3 = defaults$5.exports.defaults; - var block = rules.block, - inline = rules.inline; - var repeatString = helpers.repeatString; - /** - * smartypants text replacement - */ - function smartypants(text) { - return text // em-dashes - .replace(/---/g, "\u2014") // en-dashes - .replace(/--/g, "\u2013") // opening singles - .replace(/(^|[-\u2014/(\[{"\s])'/g, "$1\u2018") // closing singles & apostrophes - .replace(/'/g, "\u2019") // opening doubles - .replace(/(^|[-\u2014/(\[{\u2018\s])"/g, "$1\u201C") // closing doubles - .replace(/"/g, "\u201D") // ellipses - .replace(/\.{3}/g, "\u2026"); - } - /** - * mangle email addresses - */ + function dropWhile(array, predicate) { + return array && array.length ? baseWhile(array, getIteratee(predicate, 3), true) : []; + } + /** + * Fills elements of `array` with `value` from `start` up to, but not + * including, `end`. + * + * **Note:** This method mutates `array`. + * + * @static + * @memberOf _ + * @since 3.2.0 + * @category Array + * @param {Array} array The array to fill. + * @param {*} value The value to fill `array` with. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3]; + * + * _.fill(array, 'a'); + * console.log(array); + * // => ['a', 'a', 'a'] + * + * _.fill(Array(3), 2); + * // => [2, 2, 2] + * + * _.fill([4, 6, 8, 10], '*', 1, 3); + * // => [4, '*', '*', 10] + */ - function mangle(text) { - var out = '', - i, - ch; - var l = text.length; + function fill(array, value, start, end) { + var length = array == null ? 0 : array.length; - for (i = 0; i < l; i++) { - ch = text.charCodeAt(i); + if (!length) { + return []; + } - if (Math.random() > 0.5) { - ch = 'x' + ch.toString(16); - } + if (start && typeof start != 'number' && isIterateeCall(array, value, start)) { + start = 0; + end = length; + } - out += '&#' + ch + ';'; - } + return baseFill(array, value, start, end); + } + /** + * This method is like `_.find` except that it returns the index of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.findIndex(users, function(o) { return o.user == 'barney'; }); + * // => 0 + * + * // The `_.matches` iteratee shorthand. + * _.findIndex(users, { 'user': 'fred', 'active': false }); + * // => 1 + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findIndex(users, ['active', false]); + * // => 0 + * + * // The `_.property` iteratee shorthand. + * _.findIndex(users, 'active'); + * // => 2 + */ - return out; - } - /** - * Block Lexer - */ + function findIndex(array, predicate, fromIndex) { + var length = array == null ? 0 : array.length; - var Lexer_1 = /*#__PURE__*/function () { - function Lexer(options) { - _classCallCheck$1(this, Lexer); + if (!length) { + return -1; + } - this.tokens = []; - this.tokens.links = Object.create(null); - this.options = options || defaults$3; - this.options.tokenizer = this.options.tokenizer || new Tokenizer$1(); - this.tokenizer = this.options.tokenizer; - this.tokenizer.options = this.options; - var rules = { - block: block.normal, - inline: inline.normal - }; + var index = fromIndex == null ? 0 : toInteger(fromIndex); - if (this.options.pedantic) { - rules.block = block.pedantic; - rules.inline = inline.pedantic; - } else if (this.options.gfm) { - rules.block = block.gfm; + if (index < 0) { + index = nativeMax(length + index, 0); + } - if (this.options.breaks) { - rules.inline = inline.breaks; - } else { - rules.inline = inline.gfm; + return baseFindIndex(array, getIteratee(predicate, 3), index); } - } + /** + * This method is like `_.findIndex` except that it iterates over elements + * of `collection` from right to left. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=array.length-1] The index to search from. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; }); + * // => 2 + * + * // The `_.matches` iteratee shorthand. + * _.findLastIndex(users, { 'user': 'barney', 'active': true }); + * // => 0 + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findLastIndex(users, ['active', false]); + * // => 2 + * + * // The `_.property` iteratee shorthand. + * _.findLastIndex(users, 'active'); + * // => 0 + */ - this.tokenizer.rules = rules; - } - /** - * Expose Rules - */ + function findLastIndex(array, predicate, fromIndex) { + var length = array == null ? 0 : array.length; - _createClass$1(Lexer, [{ - key: "lex", - value: - /** - * Preprocessing - */ - function lex(src) { - src = src.replace(/\r\n|\r/g, '\n').replace(/\t/g, ' '); - this.blockTokens(src, this.tokens, true); - this.inline(this.tokens); - return this.tokens; - } - /** - * Lexing - */ + if (!length) { + return -1; + } - }, { - key: "blockTokens", - value: function blockTokens(src) { - var tokens = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; - var top = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; + var index = length - 1; - if (this.options.pedantic) { - src = src.replace(/^ +$/gm, ''); + if (fromIndex !== undefined$1) { + index = toInteger(fromIndex); + index = fromIndex < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1); + } + + return baseFindIndex(array, getIteratee(predicate, 3), index, true); } + /** + * Flattens `array` a single level deep. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flatten([1, [2, [3, [4]], 5]]); + * // => [1, 2, [3, [4]], 5] + */ - var token, i, l, lastToken; - while (src) { - // newline - if (token = this.tokenizer.space(src)) { - src = src.substring(token.raw.length); + function flatten(array) { + var length = array == null ? 0 : array.length; + return length ? baseFlatten(array, 1) : []; + } + /** + * Recursively flattens `array`. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flattenDeep([1, [2, [3, [4]], 5]]); + * // => [1, 2, 3, 4, 5] + */ - if (token.type) { - tokens.push(token); - } - continue; - } // code + function flattenDeep(array) { + var length = array == null ? 0 : array.length; + return length ? baseFlatten(array, INFINITY) : []; + } + /** + * Recursively flatten `array` up to `depth` times. + * + * @static + * @memberOf _ + * @since 4.4.0 + * @category Array + * @param {Array} array The array to flatten. + * @param {number} [depth=1] The maximum recursion depth. + * @returns {Array} Returns the new flattened array. + * @example + * + * var array = [1, [2, [3, [4]], 5]]; + * + * _.flattenDepth(array, 1); + * // => [1, 2, [3, [4]], 5] + * + * _.flattenDepth(array, 2); + * // => [1, 2, 3, [4], 5] + */ - if (token = this.tokenizer.code(src)) { - src = src.substring(token.raw.length); - lastToken = tokens[tokens.length - 1]; // An indented code block cannot interrupt a paragraph. - - if (lastToken && lastToken.type === 'paragraph') { - lastToken.raw += '\n' + token.raw; - lastToken.text += '\n' + token.text; - } else { - tokens.push(token); - } - - continue; - } // fences + function flattenDepth(array, depth) { + var length = array == null ? 0 : array.length; + if (!length) { + return []; + } - if (token = this.tokenizer.fences(src)) { - src = src.substring(token.raw.length); - tokens.push(token); - continue; - } // heading + depth = depth === undefined$1 ? 1 : toInteger(depth); + return baseFlatten(array, depth); + } + /** + * The inverse of `_.toPairs`; this method returns an object composed + * from key-value `pairs`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} pairs The key-value pairs. + * @returns {Object} Returns the new object. + * @example + * + * _.fromPairs([['a', 1], ['b', 2]]); + * // => { 'a': 1, 'b': 2 } + */ - if (token = this.tokenizer.heading(src)) { - src = src.substring(token.raw.length); - tokens.push(token); - continue; - } // table no leading pipe (gfm) + function fromPairs(pairs) { + var index = -1, + length = pairs == null ? 0 : pairs.length, + result = {}; + while (++index < length) { + var pair = pairs[index]; + result[pair[0]] = pair[1]; + } - if (token = this.tokenizer.nptable(src)) { - src = src.substring(token.raw.length); - tokens.push(token); - continue; - } // hr + return result; + } + /** + * Gets the first element of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @alias first + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the first element of `array`. + * @example + * + * _.head([1, 2, 3]); + * // => 1 + * + * _.head([]); + * // => undefined + */ - if (token = this.tokenizer.hr(src)) { - src = src.substring(token.raw.length); - tokens.push(token); - continue; - } // blockquote + function head(array) { + return array && array.length ? array[0] : undefined$1; + } + /** + * Gets the index at which the first occurrence of `value` is found in `array` + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. If `fromIndex` is negative, it's used as the + * offset from the end of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.indexOf([1, 2, 1, 2], 2); + * // => 1 + * + * // Search from the `fromIndex`. + * _.indexOf([1, 2, 1, 2], 2, 2); + * // => 3 + */ - if (token = this.tokenizer.blockquote(src)) { - src = src.substring(token.raw.length); - token.tokens = this.blockTokens(token.text, [], top); - tokens.push(token); - continue; - } // list + function indexOf(array, value, fromIndex) { + var length = array == null ? 0 : array.length; + if (!length) { + return -1; + } - if (token = this.tokenizer.list(src)) { - src = src.substring(token.raw.length); - l = token.items.length; + var index = fromIndex == null ? 0 : toInteger(fromIndex); - for (i = 0; i < l; i++) { - token.items[i].tokens = this.blockTokens(token.items[i].text, [], false); - } + if (index < 0) { + index = nativeMax(length + index, 0); + } - tokens.push(token); - continue; - } // html + return baseIndexOf(array, value, index); + } + /** + * Gets all but the last element of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to query. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.initial([1, 2, 3]); + * // => [1, 2] + */ - if (token = this.tokenizer.html(src)) { - src = src.substring(token.raw.length); - tokens.push(token); - continue; - } // def + function initial(array) { + var length = array == null ? 0 : array.length; + return length ? baseSlice(array, 0, -1) : []; + } + /** + * Creates an array of unique values that are included in all given arrays + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. The order and references of result values are + * determined by the first array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of intersecting values. + * @example + * + * _.intersection([2, 1], [2, 3]); + * // => [2] + */ - if (top && (token = this.tokenizer.def(src))) { - src = src.substring(token.raw.length); + var intersection = baseRest(function (arrays) { + var mapped = arrayMap(arrays, castArrayLikeObject); + return mapped.length && mapped[0] === arrays[0] ? baseIntersection(mapped) : []; + }); + /** + * This method is like `_.intersection` except that it accepts `iteratee` + * which is invoked for each element of each `arrays` to generate the criterion + * by which they're compared. The order and references of result values are + * determined by the first array. The iteratee is invoked with one argument: + * (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new array of intersecting values. + * @example + * + * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor); + * // => [2.1] + * + * // The `_.property` iteratee shorthand. + * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }] + */ - if (!this.tokens.links[token.tag]) { - this.tokens.links[token.tag] = { - href: token.href, - title: token.title - }; - } + var intersectionBy = baseRest(function (arrays) { + var iteratee = last(arrays), + mapped = arrayMap(arrays, castArrayLikeObject); - continue; - } // table (gfm) + if (iteratee === last(mapped)) { + iteratee = undefined$1; + } else { + mapped.pop(); + } + return mapped.length && mapped[0] === arrays[0] ? baseIntersection(mapped, getIteratee(iteratee, 2)) : []; + }); + /** + * This method is like `_.intersection` except that it accepts `comparator` + * which is invoked to compare elements of `arrays`. The order and references + * of result values are determined by the first array. The comparator is + * invoked with two arguments: (arrVal, othVal). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of intersecting values. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; + * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; + * + * _.intersectionWith(objects, others, _.isEqual); + * // => [{ 'x': 1, 'y': 2 }] + */ - if (token = this.tokenizer.table(src)) { - src = src.substring(token.raw.length); - tokens.push(token); - continue; - } // lheading + var intersectionWith = baseRest(function (arrays) { + var comparator = last(arrays), + mapped = arrayMap(arrays, castArrayLikeObject); + comparator = typeof comparator == 'function' ? comparator : undefined$1; + if (comparator) { + mapped.pop(); + } - if (token = this.tokenizer.lheading(src)) { - src = src.substring(token.raw.length); - tokens.push(token); - continue; - } // top-level paragraph + return mapped.length && mapped[0] === arrays[0] ? baseIntersection(mapped, undefined$1, comparator) : []; + }); + /** + * Converts all elements in `array` into a string separated by `separator`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to convert. + * @param {string} [separator=','] The element separator. + * @returns {string} Returns the joined string. + * @example + * + * _.join(['a', 'b', 'c'], '~'); + * // => 'a~b~c' + */ + function join(array, separator) { + return array == null ? '' : nativeJoin.call(array, separator); + } + /** + * Gets the last element of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the last element of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + */ - if (top && (token = this.tokenizer.paragraph(src))) { - src = src.substring(token.raw.length); - tokens.push(token); - continue; - } // text + function last(array) { + var length = array == null ? 0 : array.length; + return length ? array[length - 1] : undefined$1; + } + /** + * This method is like `_.indexOf` except that it iterates over elements of + * `array` from right to left. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} [fromIndex=array.length-1] The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.lastIndexOf([1, 2, 1, 2], 2); + * // => 3 + * + * // Search from the `fromIndex`. + * _.lastIndexOf([1, 2, 1, 2], 2, 2); + * // => 1 + */ - if (token = this.tokenizer.text(src)) { - src = src.substring(token.raw.length); - lastToken = tokens[tokens.length - 1]; - if (lastToken && lastToken.type === 'text') { - lastToken.raw += '\n' + token.raw; - lastToken.text += '\n' + token.text; - } else { - tokens.push(token); - } + function lastIndexOf(array, value, fromIndex) { + var length = array == null ? 0 : array.length; - continue; + if (!length) { + return -1; } - if (src) { - var errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0); + var index = length; - if (this.options.silent) { - console.error(errMsg); - break; - } else { - throw new Error(errMsg); - } + if (fromIndex !== undefined$1) { + index = toInteger(fromIndex); + index = index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1); } + + return value === value ? strictLastIndexOf(array, value, index) : baseFindIndex(array, baseIsNaN, index, true); } + /** + * Gets the element at index `n` of `array`. If `n` is negative, the nth + * element from the end is returned. + * + * @static + * @memberOf _ + * @since 4.11.0 + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=0] The index of the element to return. + * @returns {*} Returns the nth element of `array`. + * @example + * + * var array = ['a', 'b', 'c', 'd']; + * + * _.nth(array, 1); + * // => 'b' + * + * _.nth(array, -2); + * // => 'c'; + */ - return tokens; - } - }, { - key: "inline", - value: function inline(tokens) { - var i, j, k, l2, row, token; - var l = tokens.length; - for (i = 0; i < l; i++) { - token = tokens[i]; + function nth(array, n) { + return array && array.length ? baseNth(array, toInteger(n)) : undefined$1; + } + /** + * Removes all given values from `array` using + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove` + * to remove elements from an array by predicate. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Array + * @param {Array} array The array to modify. + * @param {...*} [values] The values to remove. + * @returns {Array} Returns `array`. + * @example + * + * var array = ['a', 'b', 'c', 'a', 'b', 'c']; + * + * _.pull(array, 'a', 'c'); + * console.log(array); + * // => ['b', 'b'] + */ - switch (token.type) { - case 'paragraph': - case 'text': - case 'heading': - { - token.tokens = []; - this.inlineTokens(token.text, token.tokens); - break; - } - case 'table': - { - token.tokens = { - header: [], - cells: [] - }; // header + var pull = baseRest(pullAll); + /** + * This method is like `_.pull` except that it accepts an array of values to remove. + * + * **Note:** Unlike `_.difference`, this method mutates `array`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to modify. + * @param {Array} values The values to remove. + * @returns {Array} Returns `array`. + * @example + * + * var array = ['a', 'b', 'c', 'a', 'b', 'c']; + * + * _.pullAll(array, ['a', 'c']); + * console.log(array); + * // => ['b', 'b'] + */ - l2 = token.header.length; + function pullAll(array, values) { + return array && array.length && values && values.length ? basePullAll(array, values) : array; + } + /** + * This method is like `_.pullAll` except that it accepts `iteratee` which is + * invoked for each element of `array` and `values` to generate the criterion + * by which they're compared. The iteratee is invoked with one argument: (value). + * + * **Note:** Unlike `_.differenceBy`, this method mutates `array`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to modify. + * @param {Array} values The values to remove. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns `array`. + * @example + * + * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }]; + * + * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x'); + * console.log(array); + * // => [{ 'x': 2 }] + */ - for (j = 0; j < l2; j++) { - token.tokens.header[j] = []; - this.inlineTokens(token.header[j], token.tokens.header[j]); - } // cells + function pullAllBy(array, values, iteratee) { + return array && array.length && values && values.length ? basePullAll(array, values, getIteratee(iteratee, 2)) : array; + } + /** + * This method is like `_.pullAll` except that it accepts `comparator` which + * is invoked to compare elements of `array` to `values`. The comparator is + * invoked with two arguments: (arrVal, othVal). + * + * **Note:** Unlike `_.differenceWith`, this method mutates `array`. + * + * @static + * @memberOf _ + * @since 4.6.0 + * @category Array + * @param {Array} array The array to modify. + * @param {Array} values The values to remove. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns `array`. + * @example + * + * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }]; + * + * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual); + * console.log(array); + * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }] + */ - l2 = token.cells.length; - for (j = 0; j < l2; j++) { - row = token.cells[j]; - token.tokens.cells[j] = []; + function pullAllWith(array, values, comparator) { + return array && array.length && values && values.length ? basePullAll(array, values, undefined$1, comparator) : array; + } + /** + * Removes elements from `array` corresponding to `indexes` and returns an + * array of removed elements. + * + * **Note:** Unlike `_.at`, this method mutates `array`. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to modify. + * @param {...(number|number[])} [indexes] The indexes of elements to remove. + * @returns {Array} Returns the new array of removed elements. + * @example + * + * var array = ['a', 'b', 'c', 'd']; + * var pulled = _.pullAt(array, [1, 3]); + * + * console.log(array); + * // => ['a', 'c'] + * + * console.log(pulled); + * // => ['b', 'd'] + */ - for (k = 0; k < row.length; k++) { - token.tokens.cells[j][k] = []; - this.inlineTokens(row[k], token.tokens.cells[j][k]); - } - } - break; - } + var pullAt = flatRest(function (array, indexes) { + var length = array == null ? 0 : array.length, + result = baseAt(array, indexes); + basePullAt(array, arrayMap(indexes, function (index) { + return isIndex(index, length) ? +index : index; + }).sort(compareAscending)); + return result; + }); + /** + * Removes all elements from `array` that `predicate` returns truthy for + * and returns an array of the removed elements. The predicate is invoked + * with three arguments: (value, index, array). + * + * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull` + * to pull elements from an array by value. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Array + * @param {Array} array The array to modify. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new array of removed elements. + * @example + * + * var array = [1, 2, 3, 4]; + * var evens = _.remove(array, function(n) { + * return n % 2 == 0; + * }); + * + * console.log(array); + * // => [1, 3] + * + * console.log(evens); + * // => [2, 4] + */ - case 'blockquote': - { - this.inline(token.tokens); - break; - } + function remove(array, predicate) { + var result = []; - case 'list': - { - l2 = token.items.length; + if (!(array && array.length)) { + return result; + } - for (j = 0; j < l2; j++) { - this.inline(token.items[j].tokens); - } + var index = -1, + indexes = [], + length = array.length; + predicate = getIteratee(predicate, 3); - break; - } + while (++index < length) { + var value = array[index]; + + if (predicate(value, index, array)) { + result.push(value); + indexes.push(index); + } } + + basePullAt(array, indexes); + return result; } + /** + * Reverses `array` so that the first element becomes the last, the second + * element becomes the second to last, and so on. + * + * **Note:** This method mutates `array` and is based on + * [`Array#reverse`](https://mdn.io/Array/reverse). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to modify. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3]; + * + * _.reverse(array); + * // => [3, 2, 1] + * + * console.log(array); + * // => [3, 2, 1] + */ - return tokens; - } - /** - * Lexing/Compiling - */ - }, { - key: "inlineTokens", - value: function inlineTokens(src) { - var tokens = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; - var inLink = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; - var inRawBlock = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; - var token, lastToken; // String with links masked to avoid interference with em and strong + function reverse(array) { + return array == null ? array : nativeReverse.call(array); + } + /** + * Creates a slice of `array` from `start` up to, but not including, `end`. + * + * **Note:** This method is used instead of + * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are + * returned. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ - var maskedSrc = src; - var match; - var keepPrevChar, prevChar; // Mask out reflinks - if (this.tokens.links) { - var links = Object.keys(this.tokens.links); + function slice(array, start, end) { + var length = array == null ? 0 : array.length; - if (links.length > 0) { - while ((match = this.tokenizer.rules.inline.reflinkSearch.exec(maskedSrc)) != null) { - if (links.includes(match[0].slice(match[0].lastIndexOf('[') + 1, -1))) { - maskedSrc = maskedSrc.slice(0, match.index) + '[' + repeatString('a', match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex); - } - } + if (!length) { + return []; } - } // Mask out other blocks + if (end && typeof end != 'number' && isIterateeCall(array, start, end)) { + start = 0; + end = length; + } else { + start = start == null ? 0 : toInteger(start); + end = end === undefined$1 ? length : toInteger(end); + } - while ((match = this.tokenizer.rules.inline.blockSkip.exec(maskedSrc)) != null) { - maskedSrc = maskedSrc.slice(0, match.index) + '[' + repeatString('a', match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.blockSkip.lastIndex); - } // Mask out escaped em & strong delimiters + return baseSlice(array, start, end); + } + /** + * Uses a binary search to determine the lowest index at which `value` + * should be inserted into `array` in order to maintain its sort order. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * _.sortedIndex([30, 50], 40); + * // => 1 + */ - while ((match = this.tokenizer.rules.inline.escapedEmSt.exec(maskedSrc)) != null) { - maskedSrc = maskedSrc.slice(0, match.index) + '++' + maskedSrc.slice(this.tokenizer.rules.inline.escapedEmSt.lastIndex); + function sortedIndex(array, value) { + return baseSortedIndex(array, value); } + /** + * This method is like `_.sortedIndex` except that it accepts `iteratee` + * which is invoked for `value` and each element of `array` to compute their + * sort ranking. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * var objects = [{ 'x': 4 }, { 'x': 5 }]; + * + * _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; }); + * // => 0 + * + * // The `_.property` iteratee shorthand. + * _.sortedIndexBy(objects, { 'x': 4 }, 'x'); + * // => 0 + */ - while (src) { - if (!keepPrevChar) { - prevChar = ''; - } - keepPrevChar = false; // escape + function sortedIndexBy(array, value, iteratee) { + return baseSortedIndexBy(array, value, getIteratee(iteratee, 2)); + } + /** + * This method is like `_.indexOf` except that it performs a binary + * search on a sorted `array`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.sortedIndexOf([4, 5, 5, 5, 6], 5); + * // => 1 + */ - if (token = this.tokenizer.escape(src)) { - src = src.substring(token.raw.length); - tokens.push(token); - continue; - } // tag + function sortedIndexOf(array, value) { + var length = array == null ? 0 : array.length; - if (token = this.tokenizer.tag(src, inLink, inRawBlock)) { - src = src.substring(token.raw.length); - inLink = token.inLink; - inRawBlock = token.inRawBlock; - var _lastToken = tokens[tokens.length - 1]; + if (length) { + var index = baseSortedIndex(array, value); - if (_lastToken && token.type === 'text' && _lastToken.type === 'text') { - _lastToken.raw += token.raw; - _lastToken.text += token.text; - } else { - tokens.push(token); + if (index < length && eq(array[index], value)) { + return index; } + } - continue; - } // link - + return -1; + } + /** + * This method is like `_.sortedIndex` except that it returns the highest + * index at which `value` should be inserted into `array` in order to + * maintain its sort order. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * _.sortedLastIndex([4, 5, 5, 5, 6], 5); + * // => 4 + */ - if (token = this.tokenizer.link(src)) { - src = src.substring(token.raw.length); - if (token.type === 'link') { - token.tokens = this.inlineTokens(token.text, [], true, inRawBlock); - } + function sortedLastIndex(array, value) { + return baseSortedIndex(array, value, true); + } + /** + * This method is like `_.sortedLastIndex` except that it accepts `iteratee` + * which is invoked for `value` and each element of `array` to compute their + * sort ranking. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * var objects = [{ 'x': 4 }, { 'x': 5 }]; + * + * _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; }); + * // => 1 + * + * // The `_.property` iteratee shorthand. + * _.sortedLastIndexBy(objects, { 'x': 4 }, 'x'); + * // => 1 + */ - tokens.push(token); - continue; - } // reflink, nolink + function sortedLastIndexBy(array, value, iteratee) { + return baseSortedIndexBy(array, value, getIteratee(iteratee, 2), true); + } + /** + * This method is like `_.lastIndexOf` except that it performs a binary + * search on a sorted `array`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.sortedLastIndexOf([4, 5, 5, 5, 6], 5); + * // => 3 + */ - if (token = this.tokenizer.reflink(src, this.tokens.links)) { - src = src.substring(token.raw.length); - var _lastToken2 = tokens[tokens.length - 1]; - if (token.type === 'link') { - token.tokens = this.inlineTokens(token.text, [], true, inRawBlock); - tokens.push(token); - } else if (_lastToken2 && token.type === 'text' && _lastToken2.type === 'text') { - _lastToken2.raw += token.raw; - _lastToken2.text += token.text; - } else { - tokens.push(token); - } + function sortedLastIndexOf(array, value) { + var length = array == null ? 0 : array.length; - continue; - } // em & strong + if (length) { + var index = baseSortedIndex(array, value, true) - 1; + if (eq(array[index], value)) { + return index; + } + } - if (token = this.tokenizer.emStrong(src, maskedSrc, prevChar)) { - src = src.substring(token.raw.length); - token.tokens = this.inlineTokens(token.text, [], inLink, inRawBlock); - tokens.push(token); - continue; - } // code + return -1; + } + /** + * This method is like `_.uniq` except that it's designed and optimized + * for sorted arrays. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @returns {Array} Returns the new duplicate free array. + * @example + * + * _.sortedUniq([1, 1, 2]); + * // => [1, 2] + */ - if (token = this.tokenizer.codespan(src)) { - src = src.substring(token.raw.length); - tokens.push(token); - continue; - } // br + function sortedUniq(array) { + return array && array.length ? baseSortedUniq(array) : []; + } + /** + * This method is like `_.uniqBy` except that it's designed and optimized + * for sorted arrays. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @returns {Array} Returns the new duplicate free array. + * @example + * + * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor); + * // => [1.1, 2.3] + */ - if (token = this.tokenizer.br(src)) { - src = src.substring(token.raw.length); - tokens.push(token); - continue; - } // del (gfm) + function sortedUniqBy(array, iteratee) { + return array && array.length ? baseSortedUniq(array, getIteratee(iteratee, 2)) : []; + } + /** + * Gets all but the first element of `array`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to query. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.tail([1, 2, 3]); + * // => [2, 3] + */ - if (token = this.tokenizer.del(src)) { - src = src.substring(token.raw.length); - token.tokens = this.inlineTokens(token.text, [], inLink, inRawBlock); - tokens.push(token); - continue; - } // autolink + function tail(array) { + var length = array == null ? 0 : array.length; + return length ? baseSlice(array, 1, length) : []; + } + /** + * Creates a slice of `array` with `n` elements taken from the beginning. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to take. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.take([1, 2, 3]); + * // => [1] + * + * _.take([1, 2, 3], 2); + * // => [1, 2] + * + * _.take([1, 2, 3], 5); + * // => [1, 2, 3] + * + * _.take([1, 2, 3], 0); + * // => [] + */ - if (token = this.tokenizer.autolink(src, mangle)) { - src = src.substring(token.raw.length); - tokens.push(token); - continue; - } // url (gfm) + function take(array, n, guard) { + if (!(array && array.length)) { + return []; + } + n = guard || n === undefined$1 ? 1 : toInteger(n); + return baseSlice(array, 0, n < 0 ? 0 : n); + } + /** + * Creates a slice of `array` with `n` elements taken from the end. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to take. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.takeRight([1, 2, 3]); + * // => [3] + * + * _.takeRight([1, 2, 3], 2); + * // => [2, 3] + * + * _.takeRight([1, 2, 3], 5); + * // => [1, 2, 3] + * + * _.takeRight([1, 2, 3], 0); + * // => [] + */ - if (!inLink && (token = this.tokenizer.url(src, mangle))) { - src = src.substring(token.raw.length); - tokens.push(token); - continue; - } // text + function takeRight(array, n, guard) { + var length = array == null ? 0 : array.length; - if (token = this.tokenizer.inlineText(src, inRawBlock, smartypants)) { - src = src.substring(token.raw.length); + if (!length) { + return []; + } - if (token.raw.slice(-1) !== '_') { - // Track prevChar before string of ____ started - prevChar = token.raw.slice(-1); - } + n = guard || n === undefined$1 ? 1 : toInteger(n); + n = length - n; + return baseSlice(array, n < 0 ? 0 : n, length); + } + /** + * Creates a slice of `array` with elements taken from the end. Elements are + * taken until `predicate` returns falsey. The predicate is invoked with + * three arguments: (value, index, array). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to query. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the slice of `array`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * _.takeRightWhile(users, function(o) { return !o.active; }); + * // => objects for ['fred', 'pebbles'] + * + * // The `_.matches` iteratee shorthand. + * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false }); + * // => objects for ['pebbles'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.takeRightWhile(users, ['active', false]); + * // => objects for ['fred', 'pebbles'] + * + * // The `_.property` iteratee shorthand. + * _.takeRightWhile(users, 'active'); + * // => [] + */ - keepPrevChar = true; - lastToken = tokens[tokens.length - 1]; - if (lastToken && lastToken.type === 'text') { - lastToken.raw += token.raw; - lastToken.text += token.text; - } else { - tokens.push(token); - } + function takeRightWhile(array, predicate) { + return array && array.length ? baseWhile(array, getIteratee(predicate, 3), false, true) : []; + } + /** + * Creates a slice of `array` with elements taken from the beginning. Elements + * are taken until `predicate` returns falsey. The predicate is invoked with + * three arguments: (value, index, array). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to query. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the slice of `array`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.takeWhile(users, function(o) { return !o.active; }); + * // => objects for ['barney', 'fred'] + * + * // The `_.matches` iteratee shorthand. + * _.takeWhile(users, { 'user': 'barney', 'active': false }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.takeWhile(users, ['active', false]); + * // => objects for ['barney', 'fred'] + * + * // The `_.property` iteratee shorthand. + * _.takeWhile(users, 'active'); + * // => [] + */ - continue; - } - if (src) { - var errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0); + function takeWhile(array, predicate) { + return array && array.length ? baseWhile(array, getIteratee(predicate, 3)) : []; + } + /** + * Creates an array of unique values, in order, from all given arrays using + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of combined values. + * @example + * + * _.union([2], [1, 2]); + * // => [2, 1] + */ - if (this.options.silent) { - console.error(errMsg); - break; - } else { - throw new Error(errMsg); - } + + var union = baseRest(function (arrays) { + return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true)); + }); + /** + * This method is like `_.union` except that it accepts `iteratee` which is + * invoked for each element of each `arrays` to generate the criterion by + * which uniqueness is computed. Result values are chosen from the first + * array in which the value occurs. The iteratee is invoked with one argument: + * (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new array of combined values. + * @example + * + * _.unionBy([2.1], [1.2, 2.3], Math.floor); + * // => [2.1, 1.2] + * + * // The `_.property` iteratee shorthand. + * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }, { 'x': 2 }] + */ + + var unionBy = baseRest(function (arrays) { + var iteratee = last(arrays); + + if (isArrayLikeObject(iteratee)) { + iteratee = undefined$1; } + + return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee, 2)); + }); + /** + * This method is like `_.union` except that it accepts `comparator` which + * is invoked to compare elements of `arrays`. Result values are chosen from + * the first array in which the value occurs. The comparator is invoked + * with two arguments: (arrVal, othVal). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of combined values. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; + * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; + * + * _.unionWith(objects, others, _.isEqual); + * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }] + */ + + var unionWith = baseRest(function (arrays) { + var comparator = last(arrays); + comparator = typeof comparator == 'function' ? comparator : undefined$1; + return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined$1, comparator); + }); + /** + * Creates a duplicate-free version of an array, using + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons, in which only the first occurrence of each element + * is kept. The order of result values is determined by the order they occur + * in the array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @returns {Array} Returns the new duplicate free array. + * @example + * + * _.uniq([2, 1, 2]); + * // => [2, 1] + */ + + function uniq(array) { + return array && array.length ? baseUniq(array) : []; } + /** + * This method is like `_.uniq` except that it accepts `iteratee` which is + * invoked for each element in `array` to generate the criterion by which + * uniqueness is computed. The order of result values is determined by the + * order they occur in the array. The iteratee is invoked with one argument: + * (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new duplicate free array. + * @example + * + * _.uniqBy([2.1, 1.2, 2.3], Math.floor); + * // => [2.1, 1.2] + * + * // The `_.property` iteratee shorthand. + * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }, { 'x': 2 }] + */ - return tokens; - } - }], [{ - key: "rules", - get: function get() { - return { - block: block, - inline: inline - }; - } - /** - * Static Lex Method - */ - }, { - key: "lex", - value: function lex(src, options) { - var lexer = new Lexer(options); - return lexer.lex(src); - } - /** - * Static Lex Inline Method - */ + function uniqBy(array, iteratee) { + return array && array.length ? baseUniq(array, getIteratee(iteratee, 2)) : []; + } + /** + * This method is like `_.uniq` except that it accepts `comparator` which + * is invoked to compare elements of `array`. The order of result values is + * determined by the order they occur in the array.The comparator is invoked + * with two arguments: (arrVal, othVal). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new duplicate free array. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }]; + * + * _.uniqWith(objects, _.isEqual); + * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }] + */ - }, { - key: "lexInline", - value: function lexInline(src, options) { - var lexer = new Lexer(options); - return lexer.inlineTokens(src); - } - }]); - return Lexer; - }(); + function uniqWith(array, comparator) { + comparator = typeof comparator == 'function' ? comparator : undefined$1; + return array && array.length ? baseUniq(array, undefined$1, comparator) : []; + } + /** + * This method is like `_.zip` except that it accepts an array of grouped + * elements and creates an array regrouping the elements to their pre-zip + * configuration. + * + * @static + * @memberOf _ + * @since 1.2.0 + * @category Array + * @param {Array} array The array of grouped elements to process. + * @returns {Array} Returns the new array of regrouped elements. + * @example + * + * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]); + * // => [['a', 1, true], ['b', 2, false]] + * + * _.unzip(zipped); + * // => [['a', 'b'], [1, 2], [true, false]] + */ - var defaults$2 = defaults$5.exports.defaults; - var cleanUrl = helpers.cleanUrl, - escape$2 = helpers.escape; - /** - * Renderer - */ - var Renderer_1 = /*#__PURE__*/function () { - function Renderer(options) { - _classCallCheck$1(this, Renderer); + function unzip(array) { + if (!(array && array.length)) { + return []; + } - this.options = options || defaults$2; - } + var length = 0; + array = arrayFilter(array, function (group) { + if (isArrayLikeObject(group)) { + length = nativeMax(group.length, length); + return true; + } + }); + return baseTimes(length, function (index) { + return arrayMap(array, baseProperty(index)); + }); + } + /** + * This method is like `_.unzip` except that it accepts `iteratee` to specify + * how regrouped values should be combined. The iteratee is invoked with the + * elements of each group: (...group). + * + * @static + * @memberOf _ + * @since 3.8.0 + * @category Array + * @param {Array} array The array of grouped elements to process. + * @param {Function} [iteratee=_.identity] The function to combine + * regrouped values. + * @returns {Array} Returns the new array of regrouped elements. + * @example + * + * var zipped = _.zip([1, 2], [10, 20], [100, 200]); + * // => [[1, 10, 100], [2, 20, 200]] + * + * _.unzipWith(zipped, _.add); + * // => [3, 30, 300] + */ - _createClass$1(Renderer, [{ - key: "code", - value: function code(_code, infostring, escaped) { - var lang = (infostring || '').match(/\S*/)[0]; - if (this.options.highlight) { - var out = this.options.highlight(_code, lang); + function unzipWith(array, iteratee) { + if (!(array && array.length)) { + return []; + } - if (out != null && out !== _code) { - escaped = true; - _code = out; + var result = unzip(array); + + if (iteratee == null) { + return result; } + + return arrayMap(result, function (group) { + return apply(iteratee, undefined$1, group); + }); } + /** + * Creates an array excluding all given values using + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * **Note:** Unlike `_.pull`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {...*} [values] The values to exclude. + * @returns {Array} Returns the new array of filtered values. + * @see _.difference, _.xor + * @example + * + * _.without([2, 1, 2, 3], 1, 2); + * // => [3] + */ - _code = _code.replace(/\n$/, '') + '\n'; - if (!lang) { - return '
' + (escaped ? _code : escape$2(_code, true)) + '
\n'; - } + var without = baseRest(function (array, values) { + return isArrayLikeObject(array) ? baseDifference(array, values) : []; + }); + /** + * Creates an array of unique values that is the + * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference) + * of the given arrays. The order of result values is determined by the order + * they occur in the arrays. + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of filtered values. + * @see _.difference, _.without + * @example + * + * _.xor([2, 1], [2, 3]); + * // => [1, 3] + */ - return '
' + (escaped ? _code : escape$2(_code, true)) + '
\n'; - } - }, { - key: "blockquote", - value: function blockquote(quote) { - return '
\n' + quote + '
\n'; - } - }, { - key: "html", - value: function html(_html) { - return _html; - } - }, { - key: "heading", - value: function heading(text, level, raw, slugger) { - if (this.options.headerIds) { - return '' + text + '\n'; - } // ignore IDs + var xor = baseRest(function (arrays) { + return baseXor(arrayFilter(arrays, isArrayLikeObject)); + }); + /** + * This method is like `_.xor` except that it accepts `iteratee` which is + * invoked for each element of each `arrays` to generate the criterion by + * which by which they're compared. The order of result values is determined + * by the order they occur in the arrays. The iteratee is invoked with one + * argument: (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor); + * // => [1.2, 3.4] + * + * // The `_.property` iteratee shorthand. + * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 2 }] + */ + var xorBy = baseRest(function (arrays) { + var iteratee = last(arrays); - return '' + text + '\n'; - } - }, { - key: "hr", - value: function hr() { - return this.options.xhtml ? '
\n' : '
\n'; - } - }, { - key: "list", - value: function list(body, ordered, start) { - var type = ordered ? 'ol' : 'ul', - startatt = ordered && start !== 1 ? ' start="' + start + '"' : ''; - return '<' + type + startatt + '>\n' + body + '\n'; - } - }, { - key: "listitem", - value: function listitem(text) { - return '
  • ' + text + '
  • \n'; - } - }, { - key: "checkbox", - value: function checkbox(checked) { - return ' '; - } - }, { - key: "paragraph", - value: function paragraph(text) { - return '

    ' + text + '

    \n'; - } - }, { - key: "table", - value: function table(header, body) { - if (body) body = '' + body + ''; - return '\n' + '\n' + header + '\n' + body + '
    \n'; - } - }, { - key: "tablerow", - value: function tablerow(content) { - return '\n' + content + '\n'; - } - }, { - key: "tablecell", - value: function tablecell(content, flags) { - var type = flags.header ? 'th' : 'td'; - var tag = flags.align ? '<' + type + ' align="' + flags.align + '">' : '<' + type + '>'; - return tag + content + '\n'; - } // span level renderer + if (isArrayLikeObject(iteratee)) { + iteratee = undefined$1; + } - }, { - key: "strong", - value: function strong(text) { - return '' + text + ''; - } - }, { - key: "em", - value: function em(text) { - return '' + text + ''; - } - }, { - key: "codespan", - value: function codespan(text) { - return '' + text + ''; - } - }, { - key: "br", - value: function br() { - return this.options.xhtml ? '
    ' : '
    '; - } - }, { - key: "del", - value: function del(text) { - return '' + text + ''; - } - }, { - key: "link", - value: function link(href, title, text) { - href = cleanUrl(this.options.sanitize, this.options.baseUrl, href); + return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee, 2)); + }); + /** + * This method is like `_.xor` except that it accepts `comparator` which is + * invoked to compare elements of `arrays`. The order of result values is + * determined by the order they occur in the arrays. The comparator is invoked + * with two arguments: (arrVal, othVal). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; + * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; + * + * _.xorWith(objects, others, _.isEqual); + * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }] + */ - if (href === null) { - return text; - } + var xorWith = baseRest(function (arrays) { + var comparator = last(arrays); + comparator = typeof comparator == 'function' ? comparator : undefined$1; + return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined$1, comparator); + }); + /** + * Creates an array of grouped elements, the first of which contains the + * first elements of the given arrays, the second of which contains the + * second elements of the given arrays, and so on. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {...Array} [arrays] The arrays to process. + * @returns {Array} Returns the new array of grouped elements. + * @example + * + * _.zip(['a', 'b'], [1, 2], [true, false]); + * // => [['a', 1, true], ['b', 2, false]] + */ - var out = '
    { 'a': 1, 'b': 2 } + */ - if (title) { - out += ' title="' + title + '"'; + function zipObject(props, values) { + return baseZipObject(props || [], values || [], assignValue); } + /** + * This method is like `_.zipObject` except that it supports property paths. + * + * @static + * @memberOf _ + * @since 4.1.0 + * @category Array + * @param {Array} [props=[]] The property identifiers. + * @param {Array} [values=[]] The property values. + * @returns {Object} Returns the new object. + * @example + * + * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]); + * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } } + */ - out += '>' + text + ''; - return out; - } - }, { - key: "image", - value: function image(href, title, text) { - href = cleanUrl(this.options.sanitize, this.options.baseUrl, href); - if (href === null) { - return text; + function zipObjectDeep(props, values) { + return baseZipObject(props || [], values || [], baseSet); } + /** + * This method is like `_.zip` except that it accepts `iteratee` to specify + * how grouped values should be combined. The iteratee is invoked with the + * elements of each group: (...group). + * + * @static + * @memberOf _ + * @since 3.8.0 + * @category Array + * @param {...Array} [arrays] The arrays to process. + * @param {Function} [iteratee=_.identity] The function to combine + * grouped values. + * @returns {Array} Returns the new array of grouped elements. + * @example + * + * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) { + * return a + b + c; + * }); + * // => [111, 222] + */ - var out = '' + text + ' 1 ? arrays[length - 1] : undefined$1; + iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined$1; + return unzipWith(arrays, iteratee); + }); + /*------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` wrapper instance that wraps `value` with explicit method + * chain sequences enabled. The result of such sequences must be unwrapped + * with `_#value`. + * + * @static + * @memberOf _ + * @since 1.3.0 + * @category Seq + * @param {*} value The value to wrap. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'pebbles', 'age': 1 } + * ]; + * + * var youngest = _ + * .chain(users) + * .sortBy('age') + * .map(function(o) { + * return o.user + ' is ' + o.age; + * }) + * .head() + * .value(); + * // => 'pebbles is 1' + */ + + function chain(value) { + var result = lodash(value); + result.__chain__ = true; + return result; } + /** + * This method invokes `interceptor` and returns `value`. The interceptor + * is invoked with one argument; (value). The purpose of this method is to + * "tap into" a method chain sequence in order to modify intermediate results. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Seq + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @returns {*} Returns `value`. + * @example + * + * _([1, 2, 3]) + * .tap(function(array) { + * // Mutate input array. + * array.pop(); + * }) + * .reverse() + * .value(); + * // => [2, 1] + */ - out += this.options.xhtml ? '/>' : '>'; - return out; - } - }, { - key: "text", - value: function text(_text) { - return _text; - } - }]); - return Renderer; - }(); + function tap(value, interceptor) { + interceptor(value); + return value; + } + /** + * This method is like `_.tap` except that it returns the result of `interceptor`. + * The purpose of this method is to "pass thru" values replacing intermediate + * results in a method chain sequence. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Seq + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @returns {*} Returns the result of `interceptor`. + * @example + * + * _(' abc ') + * .chain() + * .trim() + * .thru(function(value) { + * return [value]; + * }) + * .value(); + * // => ['abc'] + */ - var TextRenderer_1 = /*#__PURE__*/function () { - function TextRenderer() { - _classCallCheck$1(this, TextRenderer); - } - _createClass$1(TextRenderer, [{ - key: "strong", - value: // no need for block level renderers - function strong(text) { - return text; - } - }, { - key: "em", - value: function em(text) { - return text; - } - }, { - key: "codespan", - value: function codespan(text) { - return text; - } - }, { - key: "del", - value: function del(text) { - return text; - } - }, { - key: "html", - value: function html(text) { - return text; - } - }, { - key: "text", - value: function text(_text) { - return _text; - } - }, { - key: "link", - value: function link(href, title, text) { - return '' + text; - } - }, { - key: "image", - value: function image(href, title, text) { - return '' + text; - } - }, { - key: "br", - value: function br() { - return ''; - } - }]); + function thru(value, interceptor) { + return interceptor(value); + } + /** + * This method is the wrapper version of `_.at`. + * + * @name at + * @memberOf _ + * @since 1.0.0 + * @category Seq + * @param {...(string|string[])} [paths] The property paths to pick. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] }; + * + * _(object).at(['a[0].b.c', 'a[1]']).value(); + * // => [3, 4] + */ - return TextRenderer; - }(); - var Slugger_1 = /*#__PURE__*/function () { - function Slugger() { - _classCallCheck$1(this, Slugger); + var wrapperAt = flatRest(function (paths) { + var length = paths.length, + start = length ? paths[0] : 0, + value = this.__wrapped__, + interceptor = function interceptor(object) { + return baseAt(object, paths); + }; - this.seen = {}; - } + if (length > 1 || this.__actions__.length || !(value instanceof LazyWrapper) || !isIndex(start)) { + return this.thru(interceptor); + } - _createClass$1(Slugger, [{ - key: "serialize", - value: function serialize(value) { - return value.toLowerCase().trim() // remove html tags - .replace(/<[!\/a-z].*?>/ig, '') // remove unwanted chars - .replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g, '').replace(/\s/g, '-'); - } - /** - * Finds the next safe (unique) slug to use - */ + value = value.slice(start, +start + (length ? 1 : 0)); - }, { - key: "getNextSafeSlug", - value: function getNextSafeSlug(originalSlug, isDryRun) { - var slug = originalSlug; - var occurenceAccumulator = 0; + value.__actions__.push({ + 'func': thru, + 'args': [interceptor], + 'thisArg': undefined$1 + }); - if (this.seen.hasOwnProperty(slug)) { - occurenceAccumulator = this.seen[originalSlug]; + return new LodashWrapper(value, this.__chain__).thru(function (array) { + if (length && !array.length) { + array.push(undefined$1); + } - do { - occurenceAccumulator++; - slug = originalSlug + '-' + occurenceAccumulator; - } while (this.seen.hasOwnProperty(slug)); + return array; + }); + }); + /** + * Creates a `lodash` wrapper instance with explicit method chain sequences enabled. + * + * @name chain + * @memberOf _ + * @since 0.1.0 + * @category Seq + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } + * ]; + * + * // A sequence without explicit chaining. + * _(users).head(); + * // => { 'user': 'barney', 'age': 36 } + * + * // A sequence with explicit chaining. + * _(users) + * .chain() + * .head() + * .pick('user') + * .value(); + * // => { 'user': 'barney' } + */ + + function wrapperChain() { + return chain(this); } + /** + * Executes the chain sequence and returns the wrapped result. + * + * @name commit + * @memberOf _ + * @since 3.2.0 + * @category Seq + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var array = [1, 2]; + * var wrapped = _(array).push(3); + * + * console.log(array); + * // => [1, 2] + * + * wrapped = wrapped.commit(); + * console.log(array); + * // => [1, 2, 3] + * + * wrapped.last(); + * // => 3 + * + * console.log(array); + * // => [1, 2, 3] + */ - if (!isDryRun) { - this.seen[originalSlug] = occurenceAccumulator; - this.seen[slug] = 0; + + function wrapperCommit() { + return new LodashWrapper(this.value(), this.__chain__); } + /** + * Gets the next value on a wrapped object following the + * [iterator protocol](https://mdn.io/iteration_protocols#iterator). + * + * @name next + * @memberOf _ + * @since 4.0.0 + * @category Seq + * @returns {Object} Returns the next iterator value. + * @example + * + * var wrapped = _([1, 2]); + * + * wrapped.next(); + * // => { 'done': false, 'value': 1 } + * + * wrapped.next(); + * // => { 'done': false, 'value': 2 } + * + * wrapped.next(); + * // => { 'done': true, 'value': undefined } + */ - return slug; - } - /** - * Convert string to unique id - * @param {object} options - * @param {boolean} options.dryrun Generates the next unique slug without updating the internal accumulator. - */ - }, { - key: "slug", - value: function slug(value) { - var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - var slug = this.serialize(value); - return this.getNextSafeSlug(slug, options.dryrun); - } - }]); + function wrapperNext() { + if (this.__values__ === undefined$1) { + this.__values__ = toArray(this.value()); + } - return Slugger; - }(); + var done = this.__index__ >= this.__values__.length, + value = done ? undefined$1 : this.__values__[this.__index__++]; + return { + 'done': done, + 'value': value + }; + } + /** + * Enables the wrapper to be iterable. + * + * @name Symbol.iterator + * @memberOf _ + * @since 4.0.0 + * @category Seq + * @returns {Object} Returns the wrapper object. + * @example + * + * var wrapped = _([1, 2]); + * + * wrapped[Symbol.iterator]() === wrapped; + * // => true + * + * Array.from(wrapped); + * // => [1, 2] + */ - var Renderer$1 = Renderer_1; - var TextRenderer$1 = TextRenderer_1; - var Slugger$1 = Slugger_1; - var defaults$1 = defaults$5.exports.defaults; - var unescape$1 = helpers.unescape; - /** - * Parsing & Compiling - */ - var Parser_1 = /*#__PURE__*/function () { - function Parser(options) { - _classCallCheck$1(this, Parser); + function wrapperToIterator() { + return this; + } + /** + * Creates a clone of the chain sequence planting `value` as the wrapped value. + * + * @name plant + * @memberOf _ + * @since 3.2.0 + * @category Seq + * @param {*} value The value to plant. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * function square(n) { + * return n * n; + * } + * + * var wrapped = _([1, 2]).map(square); + * var other = wrapped.plant([3, 4]); + * + * other.value(); + * // => [9, 16] + * + * wrapped.value(); + * // => [1, 4] + */ - this.options = options || defaults$1; - this.options.renderer = this.options.renderer || new Renderer$1(); - this.renderer = this.options.renderer; - this.renderer.options = this.options; - this.textRenderer = new TextRenderer$1(); - this.slugger = new Slugger$1(); - } - /** - * Static Parse Method - */ + function wrapperPlant(value) { + var result, + parent = this; - _createClass$1(Parser, [{ - key: "parse", - value: - /** - * Parse Loop - */ - function parse(tokens) { - var top = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; - var out = '', - i, - j, - k, - l2, - l3, - row, - cell, - header, - body, - token, - ordered, - start, - loose, - itemBody, - item, - checked, - task, - checkbox; - var l = tokens.length; + while (parent instanceof baseLodash) { + var clone = wrapperClone(parent); + clone.__index__ = 0; + clone.__values__ = undefined$1; - for (i = 0; i < l; i++) { - token = tokens[i]; + if (result) { + previous.__wrapped__ = clone; + } else { + result = clone; + } - switch (token.type) { - case 'space': - { - continue; - } + var previous = clone; + parent = parent.__wrapped__; + } - case 'hr': - { - out += this.renderer.hr(); - continue; - } + previous.__wrapped__ = value; + return result; + } + /** + * This method is the wrapper version of `_.reverse`. + * + * **Note:** This method mutates the wrapped array. + * + * @name reverse + * @memberOf _ + * @since 0.1.0 + * @category Seq + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var array = [1, 2, 3]; + * + * _(array).reverse().value() + * // => [3, 2, 1] + * + * console.log(array); + * // => [3, 2, 1] + */ - case 'heading': - { - out += this.renderer.heading(this.parseInline(token.tokens), token.depth, unescape$1(this.parseInline(token.tokens, this.textRenderer)), this.slugger); - continue; - } - case 'code': - { - out += this.renderer.code(token.text, token.lang, token.escaped); - continue; - } + function wrapperReverse() { + var value = this.__wrapped__; - case 'table': - { - header = ''; // header + if (value instanceof LazyWrapper) { + var wrapped = value; - cell = ''; - l2 = token.header.length; + if (this.__actions__.length) { + wrapped = new LazyWrapper(this); + } - for (j = 0; j < l2; j++) { - cell += this.renderer.tablecell(this.parseInline(token.tokens.header[j]), { - header: true, - align: token.align[j] - }); - } + wrapped = wrapped.reverse(); - header += this.renderer.tablerow(cell); - body = ''; - l2 = token.cells.length; + wrapped.__actions__.push({ + 'func': thru, + 'args': [reverse], + 'thisArg': undefined$1 + }); - for (j = 0; j < l2; j++) { - row = token.tokens.cells[j]; - cell = ''; - l3 = row.length; + return new LodashWrapper(wrapped, this.__chain__); + } - for (k = 0; k < l3; k++) { - cell += this.renderer.tablecell(this.parseInline(row[k]), { - header: false, - align: token.align[k] - }); - } + return this.thru(reverse); + } + /** + * Executes the chain sequence to resolve the unwrapped value. + * + * @name value + * @memberOf _ + * @since 0.1.0 + * @alias toJSON, valueOf + * @category Seq + * @returns {*} Returns the resolved unwrapped value. + * @example + * + * _([1, 2, 3]).value(); + * // => [1, 2, 3] + */ - body += this.renderer.tablerow(cell); - } - out += this.renderer.table(header, body); - continue; - } + function wrapperValue() { + return baseWrapperValue(this.__wrapped__, this.__actions__); + } + /*------------------------------------------------------------------------*/ - case 'blockquote': - { - body = this.parse(token.tokens); - out += this.renderer.blockquote(body); - continue; - } + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` thru `iteratee`. The corresponding value of + * each key is the number of times the key was returned by `iteratee`. The + * iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 0.5.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The iteratee to transform keys. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.countBy([6.1, 4.2, 6.3], Math.floor); + * // => { '4': 1, '6': 2 } + * + * // The `_.property` iteratee shorthand. + * _.countBy(['one', 'two', 'three'], 'length'); + * // => { '3': 2, '5': 1 } + */ - case 'list': - { - ordered = token.ordered; - start = token.start; - loose = token.loose; - l2 = token.items.length; - body = ''; - for (j = 0; j < l2; j++) { - item = token.items[j]; - checked = item.checked; - task = item.task; - itemBody = ''; + var countBy = createAggregator(function (result, value, key) { + if (hasOwnProperty.call(result, key)) { + ++result[key]; + } else { + baseAssignValue(result, key, 1); + } + }); + /** + * Checks if `predicate` returns truthy for **all** elements of `collection`. + * Iteration is stopped once `predicate` returns falsey. The predicate is + * invoked with three arguments: (value, index|key, collection). + * + * **Note:** This method returns `true` for + * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because + * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of + * elements of empty collections. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false`. + * @example + * + * _.every([true, 1, null, 'yes'], Boolean); + * // => false + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * // The `_.matches` iteratee shorthand. + * _.every(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // The `_.matchesProperty` iteratee shorthand. + * _.every(users, ['active', false]); + * // => true + * + * // The `_.property` iteratee shorthand. + * _.every(users, 'active'); + * // => false + */ - if (item.task) { - checkbox = this.renderer.checkbox(checked); + function every(collection, predicate, guard) { + var func = isArray(collection) ? arrayEvery : baseEvery; - if (loose) { - if (item.tokens.length > 0 && item.tokens[0].type === 'text') { - item.tokens[0].text = checkbox + ' ' + item.tokens[0].text; + if (guard && isIterateeCall(collection, predicate, guard)) { + predicate = undefined$1; + } - if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === 'text') { - item.tokens[0].tokens[0].text = checkbox + ' ' + item.tokens[0].tokens[0].text; - } - } else { - item.tokens.unshift({ - type: 'text', - text: checkbox - }); - } - } else { - itemBody += checkbox; - } - } + return func(collection, getIteratee(predicate, 3)); + } + /** + * Iterates over elements of `collection`, returning an array of all elements + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * **Note:** Unlike `_.remove`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + * @see _.reject + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * _.filter(users, function(o) { return !o.active; }); + * // => objects for ['fred'] + * + * // The `_.matches` iteratee shorthand. + * _.filter(users, { 'age': 36, 'active': true }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.filter(users, ['active', false]); + * // => objects for ['fred'] + * + * // The `_.property` iteratee shorthand. + * _.filter(users, 'active'); + * // => objects for ['barney'] + * + * // Combining several predicates using `_.overEvery` or `_.overSome`. + * _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]])); + * // => objects for ['fred', 'barney'] + */ - itemBody += this.parse(item.tokens, loose); - body += this.renderer.listitem(itemBody, task, checked); - } - out += this.renderer.list(body, ordered, start); - continue; - } + function filter(collection, predicate) { + var func = isArray(collection) ? arrayFilter : baseFilter; + return func(collection, getIteratee(predicate, 3)); + } + /** + * Iterates over elements of `collection`, returning the first element + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false }, + * { 'user': 'pebbles', 'age': 1, 'active': true } + * ]; + * + * _.find(users, function(o) { return o.age < 40; }); + * // => object for 'barney' + * + * // The `_.matches` iteratee shorthand. + * _.find(users, { 'age': 1, 'active': true }); + * // => object for 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.find(users, ['active', false]); + * // => object for 'fred' + * + * // The `_.property` iteratee shorthand. + * _.find(users, 'active'); + * // => object for 'barney' + */ - case 'html': - { - // TODO parse inline content if parameter markdown=1 - out += this.renderer.html(token.text); - continue; - } - case 'paragraph': - { - out += this.renderer.paragraph(this.parseInline(token.tokens)); - continue; - } + var find = createFind(findIndex); + /** + * This method is like `_.find` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Collection + * @param {Array|Object} collection The collection to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=collection.length-1] The index to search from. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * _.findLast([1, 2, 3, 4], function(n) { + * return n % 2 == 1; + * }); + * // => 3 + */ - case 'text': - { - body = token.tokens ? this.parseInline(token.tokens) : token.text; + var findLast = createFind(findLastIndex); + /** + * Creates a flattened array of values by running each element in `collection` + * thru `iteratee` and flattening the mapped results. The iteratee is invoked + * with three arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new flattened array. + * @example + * + * function duplicate(n) { + * return [n, n]; + * } + * + * _.flatMap([1, 2], duplicate); + * // => [1, 1, 2, 2] + */ - while (i + 1 < l && tokens[i + 1].type === 'text') { - token = tokens[++i]; - body += '\n' + (token.tokens ? this.parseInline(token.tokens) : token.text); - } + function flatMap(collection, iteratee) { + return baseFlatten(map(collection, iteratee), 1); + } + /** + * This method is like `_.flatMap` except that it recursively flattens the + * mapped results. + * + * @static + * @memberOf _ + * @since 4.7.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new flattened array. + * @example + * + * function duplicate(n) { + * return [[[n, n]]]; + * } + * + * _.flatMapDeep([1, 2], duplicate); + * // => [1, 1, 2, 2] + */ - out += top ? this.renderer.paragraph(body) : body; - continue; - } - default: - { - var errMsg = 'Token with "' + token.type + '" type was not found.'; + function flatMapDeep(collection, iteratee) { + return baseFlatten(map(collection, iteratee), INFINITY); + } + /** + * This method is like `_.flatMap` except that it recursively flattens the + * mapped results up to `depth` times. + * + * @static + * @memberOf _ + * @since 4.7.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {number} [depth=1] The maximum recursion depth. + * @returns {Array} Returns the new flattened array. + * @example + * + * function duplicate(n) { + * return [[[n, n]]]; + * } + * + * _.flatMapDepth([1, 2], duplicate, 2); + * // => [[1, 1], [2, 2]] + */ - if (this.options.silent) { - console.error(errMsg); - return; - } else { - throw new Error(errMsg); - } - } - } + + function flatMapDepth(collection, iteratee, depth) { + depth = depth === undefined$1 ? 1 : toInteger(depth); + return baseFlatten(map(collection, iteratee), depth); } + /** + * Iterates over elements of `collection` and invokes `iteratee` for each element. + * The iteratee is invoked with three arguments: (value, index|key, collection). + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * **Note:** As with other "Collections" methods, objects with a "length" + * property are iterated like arrays. To avoid this behavior use `_.forIn` + * or `_.forOwn` for object iteration. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @alias each + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + * @see _.forEachRight + * @example + * + * _.forEach([1, 2], function(value) { + * console.log(value); + * }); + * // => Logs `1` then `2`. + * + * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ - return out; - } - /** - * Parse Inline Tokens - */ - }, { - key: "parseInline", - value: function parseInline(tokens, renderer) { - renderer = renderer || this.renderer; - var out = '', - i, - token; - var l = tokens.length; + function forEach(collection, iteratee) { + var func = isArray(collection) ? arrayEach : baseEach; + return func(collection, getIteratee(iteratee, 3)); + } + /** + * This method is like `_.forEach` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @alias eachRight + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + * @see _.forEach + * @example + * + * _.forEachRight([1, 2], function(value) { + * console.log(value); + * }); + * // => Logs `2` then `1`. + */ - for (i = 0; i < l; i++) { - token = tokens[i]; - switch (token.type) { - case 'escape': - { - out += renderer.text(token.text); - break; - } + function forEachRight(collection, iteratee) { + var func = isArray(collection) ? arrayEachRight : baseEachRight; + return func(collection, getIteratee(iteratee, 3)); + } + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` thru `iteratee`. The order of grouped values + * is determined by the order they occur in `collection`. The corresponding + * value of each key is an array of elements responsible for generating the + * key. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The iteratee to transform keys. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.groupBy([6.1, 4.2, 6.3], Math.floor); + * // => { '4': [4.2], '6': [6.1, 6.3] } + * + * // The `_.property` iteratee shorthand. + * _.groupBy(['one', 'two', 'three'], 'length'); + * // => { '3': ['one', 'two'], '5': ['three'] } + */ - case 'html': - { - out += renderer.html(token.text); - break; - } - case 'link': - { - out += renderer.link(token.href, token.title, this.parseInline(token.tokens, renderer)); - break; - } + var groupBy = createAggregator(function (result, value, key) { + if (hasOwnProperty.call(result, key)) { + result[key].push(value); + } else { + baseAssignValue(result, key, [value]); + } + }); + /** + * Checks if `value` is in `collection`. If `collection` is a string, it's + * checked for a substring of `value`, otherwise + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * is used for equality comparisons. If `fromIndex` is negative, it's used as + * the offset from the end of `collection`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object|string} collection The collection to inspect. + * @param {*} value The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`. + * @returns {boolean} Returns `true` if `value` is found, else `false`. + * @example + * + * _.includes([1, 2, 3], 1); + * // => true + * + * _.includes([1, 2, 3], 1, 2); + * // => false + * + * _.includes({ 'a': 1, 'b': 2 }, 1); + * // => true + * + * _.includes('abcd', 'bc'); + * // => true + */ - case 'image': - { - out += renderer.image(token.href, token.title, token.text); - break; - } + function includes(collection, value, fromIndex, guard) { + collection = isArrayLike(collection) ? collection : values(collection); + fromIndex = fromIndex && !guard ? toInteger(fromIndex) : 0; + var length = collection.length; - case 'strong': - { - out += renderer.strong(this.parseInline(token.tokens, renderer)); - break; - } + if (fromIndex < 0) { + fromIndex = nativeMax(length + fromIndex, 0); + } - case 'em': - { - out += renderer.em(this.parseInline(token.tokens, renderer)); - break; - } + return isString(collection) ? fromIndex <= length && collection.indexOf(value, fromIndex) > -1 : !!length && baseIndexOf(collection, value, fromIndex) > -1; + } + /** + * Invokes the method at `path` of each element in `collection`, returning + * an array of the results of each invoked method. Any additional arguments + * are provided to each invoked method. If `path` is a function, it's invoked + * for, and `this` bound to, each element in `collection`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Array|Function|string} path The path of the method to invoke or + * the function invoked per iteration. + * @param {...*} [args] The arguments to invoke each method with. + * @returns {Array} Returns the array of results. + * @example + * + * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort'); + * // => [[1, 5, 7], [1, 2, 3]] + * + * _.invokeMap([123, 456], String.prototype.split, ''); + * // => [['1', '2', '3'], ['4', '5', '6']] + */ - case 'codespan': - { - out += renderer.codespan(token.text); - break; - } - case 'br': - { - out += renderer.br(); - break; - } + var invokeMap = baseRest(function (collection, path, args) { + var index = -1, + isFunc = typeof path == 'function', + result = isArrayLike(collection) ? Array(collection.length) : []; + baseEach(collection, function (value) { + result[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args); + }); + return result; + }); + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` thru `iteratee`. The corresponding value of + * each key is the last element responsible for generating the key. The + * iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The iteratee to transform keys. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * var array = [ + * { 'dir': 'left', 'code': 97 }, + * { 'dir': 'right', 'code': 100 } + * ]; + * + * _.keyBy(array, function(o) { + * return String.fromCharCode(o.code); + * }); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + * + * _.keyBy(array, 'dir'); + * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } + */ - case 'del': - { - out += renderer.del(this.parseInline(token.tokens, renderer)); - break; - } + var keyBy = createAggregator(function (result, value, key) { + baseAssignValue(result, key, value); + }); + /** + * Creates an array of values by running each element in `collection` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. + * + * The guarded methods are: + * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, + * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`, + * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`, + * `template`, `trim`, `trimEnd`, `trimStart`, and `words` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + * @example + * + * function square(n) { + * return n * n; + * } + * + * _.map([4, 8], square); + * // => [16, 64] + * + * _.map({ 'a': 4, 'b': 8 }, square); + * // => [16, 64] (iteration order is not guaranteed) + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * // The `_.property` iteratee shorthand. + * _.map(users, 'user'); + * // => ['barney', 'fred'] + */ - case 'text': - { - out += renderer.text(token.text); - break; - } + function map(collection, iteratee) { + var func = isArray(collection) ? arrayMap : baseMap; + return func(collection, getIteratee(iteratee, 3)); + } + /** + * This method is like `_.sortBy` except that it allows specifying the sort + * orders of the iteratees to sort by. If `orders` is unspecified, all values + * are sorted in ascending order. Otherwise, specify an order of "desc" for + * descending or "asc" for ascending sort order of corresponding values. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]] + * The iteratees to sort by. + * @param {string[]} [orders] The sort orders of `iteratees`. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 34 }, + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'barney', 'age': 36 } + * ]; + * + * // Sort by `user` in ascending order and by `age` in descending order. + * _.orderBy(users, ['user', 'age'], ['asc', 'desc']); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]] + */ - default: - { - var errMsg = 'Token with "' + token.type + '" type was not found.'; - if (this.options.silent) { - console.error(errMsg); - return; - } else { - throw new Error(errMsg); - } - } + function orderBy(collection, iteratees, orders, guard) { + if (collection == null) { + return []; } - } - return out; - } - }], [{ - key: "parse", - value: function parse(tokens, options) { - var parser = new Parser(options); - return parser.parse(tokens); - } - /** - * Static Parse Inline Method - */ + if (!isArray(iteratees)) { + iteratees = iteratees == null ? [] : [iteratees]; + } - }, { - key: "parseInline", - value: function parseInline(tokens, options) { - var parser = new Parser(options); - return parser.parseInline(tokens); - } - }]); + orders = guard ? undefined$1 : orders; - return Parser; - }(); + if (!isArray(orders)) { + orders = orders == null ? [] : [orders]; + } - var Lexer = Lexer_1; - var Parser = Parser_1; - var Tokenizer = Tokenizer_1; - var Renderer = Renderer_1; - var TextRenderer = TextRenderer_1; - var Slugger = Slugger_1; - var merge = helpers.merge, - checkSanitizeDeprecation = helpers.checkSanitizeDeprecation, - escape$1 = helpers.escape; - var getDefaults = defaults$5.exports.getDefaults, - changeDefaults = defaults$5.exports.changeDefaults, - defaults = defaults$5.exports.defaults; - /** - * Marked - */ + return baseOrderBy(collection, iteratees, orders); + } + /** + * Creates an array of elements split into two groups, the first of which + * contains elements `predicate` returns truthy for, the second of which + * contains elements `predicate` returns falsey for. The predicate is + * invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the array of grouped elements. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': true }, + * { 'user': 'pebbles', 'age': 1, 'active': false } + * ]; + * + * _.partition(users, function(o) { return o.active; }); + * // => objects for [['fred'], ['barney', 'pebbles']] + * + * // The `_.matches` iteratee shorthand. + * _.partition(users, { 'age': 1, 'active': false }); + * // => objects for [['pebbles'], ['barney', 'fred']] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.partition(users, ['active', false]); + * // => objects for [['barney', 'pebbles'], ['fred']] + * + * // The `_.property` iteratee shorthand. + * _.partition(users, 'active'); + * // => objects for [['fred'], ['barney', 'pebbles']] + */ - function marked(src, opt, callback) { - // throw error in case of non string input - if (typeof src === 'undefined' || src === null) { - throw new Error('marked(): input parameter is undefined or null'); - } - if (typeof src !== 'string') { - throw new Error('marked(): input parameter is of type ' + Object.prototype.toString.call(src) + ', string expected'); - } + var partition = createAggregator(function (result, value, key) { + result[key ? 0 : 1].push(value); + }, function () { + return [[], []]; + }); + /** + * Reduces `collection` to a value which is the accumulated result of running + * each element in `collection` thru `iteratee`, where each successive + * invocation is supplied the return value of the previous. If `accumulator` + * is not given, the first element of `collection` is used as the initial + * value. The iteratee is invoked with four arguments: + * (accumulator, value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.reduce`, `_.reduceRight`, and `_.transform`. + * + * The guarded methods are: + * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`, + * and `sortBy` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @returns {*} Returns the accumulated value. + * @see _.reduceRight + * @example + * + * _.reduce([1, 2], function(sum, n) { + * return sum + n; + * }, 0); + * // => 3 + * + * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { + * (result[value] || (result[value] = [])).push(key); + * return result; + * }, {}); + * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed) + */ - if (typeof opt === 'function') { - callback = opt; - opt = null; - } + function reduce(collection, iteratee, accumulator) { + var func = isArray(collection) ? arrayReduce : baseReduce, + initAccum = arguments.length < 3; + return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach); + } + /** + * This method is like `_.reduce` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @returns {*} Returns the accumulated value. + * @see _.reduce + * @example + * + * var array = [[0, 1], [2, 3], [4, 5]]; + * + * _.reduceRight(array, function(flattened, other) { + * return flattened.concat(other); + * }, []); + * // => [4, 5, 2, 3, 0, 1] + */ - opt = merge({}, marked.defaults, opt || {}); - checkSanitizeDeprecation(opt); - if (callback) { - var highlight = opt.highlight; - var tokens; + function reduceRight(collection, iteratee, accumulator) { + var func = isArray(collection) ? arrayReduceRight : baseReduce, + initAccum = arguments.length < 3; + return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight); + } + /** + * The opposite of `_.filter`; this method returns the elements of `collection` + * that `predicate` does **not** return truthy for. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + * @see _.filter + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': true } + * ]; + * + * _.reject(users, function(o) { return !o.active; }); + * // => objects for ['fred'] + * + * // The `_.matches` iteratee shorthand. + * _.reject(users, { 'age': 40, 'active': true }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.reject(users, ['active', false]); + * // => objects for ['fred'] + * + * // The `_.property` iteratee shorthand. + * _.reject(users, 'active'); + * // => objects for ['barney'] + */ - try { - tokens = Lexer.lex(src, opt); - } catch (e) { - return callback(e); - } - var done = function done(err) { - var out; + function reject(collection, predicate) { + var func = isArray(collection) ? arrayFilter : baseFilter; + return func(collection, negate(getIteratee(predicate, 3))); + } + /** + * Gets a random element from `collection`. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Collection + * @param {Array|Object} collection The collection to sample. + * @returns {*} Returns the random element. + * @example + * + * _.sample([1, 2, 3, 4]); + * // => 2 + */ - if (!err) { - try { - if (opt.walkTokens) { - marked.walkTokens(tokens, opt.walkTokens); - } - out = Parser.parse(tokens, opt); - } catch (e) { - err = e; - } + function sample(collection) { + var func = isArray(collection) ? arraySample : baseSample; + return func(collection); } + /** + * Gets `n` random elements at unique keys from `collection` up to the + * size of `collection`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Collection + * @param {Array|Object} collection The collection to sample. + * @param {number} [n=1] The number of elements to sample. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Array} Returns the random elements. + * @example + * + * _.sampleSize([1, 2, 3], 2); + * // => [3, 1] + * + * _.sampleSize([1, 2, 3], 4); + * // => [2, 3, 1] + */ - opt.highlight = highlight; - return err ? callback(err) : callback(null, out); - }; - if (!highlight || highlight.length < 3) { - return done(); - } + function sampleSize(collection, n, guard) { + if (guard ? isIterateeCall(collection, n, guard) : n === undefined$1) { + n = 1; + } else { + n = toInteger(n); + } - delete opt.highlight; - if (!tokens.length) return done(); - var pending = 0; - marked.walkTokens(tokens, function (token) { - if (token.type === 'code') { - pending++; - setTimeout(function () { - highlight(token.text, token.lang, function (err, code) { - if (err) { - return done(err); - } - - if (code != null && code !== token.text) { - token.text = code; - token.escaped = true; - } + var func = isArray(collection) ? arraySampleSize : baseSampleSize; + return func(collection, n); + } + /** + * Creates an array of shuffled values, using a version of the + * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to shuffle. + * @returns {Array} Returns the new shuffled array. + * @example + * + * _.shuffle([1, 2, 3, 4]); + * // => [4, 1, 3, 2] + */ - pending--; - if (pending === 0) { - done(); - } - }); - }, 0); + function shuffle(collection) { + var func = isArray(collection) ? arrayShuffle : baseShuffle; + return func(collection); } - }); + /** + * Gets the size of `collection` by returning its length for array-like + * values or the number of own enumerable string keyed properties for objects. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object|string} collection The collection to inspect. + * @returns {number} Returns the collection size. + * @example + * + * _.size([1, 2, 3]); + * // => 3 + * + * _.size({ 'a': 1, 'b': 2 }); + * // => 2 + * + * _.size('pebbles'); + * // => 7 + */ - if (pending === 0) { - done(); - } - return; - } + function size(collection) { + if (collection == null) { + return 0; + } - try { - var _tokens = Lexer.lex(src, opt); + if (isArrayLike(collection)) { + return isString(collection) ? stringSize(collection) : collection.length; + } - if (opt.walkTokens) { - marked.walkTokens(_tokens, opt.walkTokens); - } + var tag = getTag(collection); - return Parser.parse(_tokens, opt); - } catch (e) { - e.message += '\nPlease report this to https://github.com/markedjs/marked.'; + if (tag == mapTag || tag == setTag) { + return collection.size; + } - if (opt.silent) { - return '

    An error occurred:

    ' + escape$1(e.message + '', true) + '
    '; - } + return baseKeys(collection).length; + } + /** + * Checks if `predicate` returns truthy for **any** element of `collection`. + * Iteration is stopped once `predicate` returns truthy. The predicate is + * invoked with three arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + * @example + * + * _.some([null, 0, 'yes', false], Boolean); + * // => true + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false } + * ]; + * + * // The `_.matches` iteratee shorthand. + * _.some(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // The `_.matchesProperty` iteratee shorthand. + * _.some(users, ['active', false]); + * // => true + * + * // The `_.property` iteratee shorthand. + * _.some(users, 'active'); + * // => true + */ - throw e; - } - } - /** - * Options - */ + function some(collection, predicate, guard) { + var func = isArray(collection) ? arraySome : baseSome; - marked.options = marked.setOptions = function (opt) { - merge(marked.defaults, opt); - changeDefaults(marked.defaults); - return marked; - }; + if (guard && isIterateeCall(collection, predicate, guard)) { + predicate = undefined$1; + } - marked.getDefaults = getDefaults; - marked.defaults = defaults; - /** - * Use Extension - */ + return func(collection, getIteratee(predicate, 3)); + } + /** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection thru each iteratee. This method + * performs a stable sort, that is, it preserves the original sort order of + * equal elements. The iteratees are invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {...(Function|Function[])} [iteratees=[_.identity]] + * The iteratees to sort by. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 30 }, + * { 'user': 'barney', 'age': 34 } + * ]; + * + * _.sortBy(users, [function(o) { return o.user; }]); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 30]] + * + * _.sortBy(users, ['user', 'age']); + * // => objects for [['barney', 34], ['barney', 36], ['fred', 30], ['fred', 48]] + */ - marked.use = function (extension) { - var opts = merge({}, extension); - if (extension.renderer) { - (function () { - var renderer = marked.defaults.renderer || new Renderer(); + var sortBy = baseRest(function (collection, iteratees) { + if (collection == null) { + return []; + } - var _loop = function _loop(prop) { - var prevRenderer = renderer[prop]; + var length = iteratees.length; - renderer[prop] = function () { - for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; - } + if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) { + iteratees = []; + } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) { + iteratees = [iteratees[0]]; + } - var ret = extension.renderer[prop].apply(renderer, args); + return baseOrderBy(collection, baseFlatten(iteratees, 1), []); + }); + /*------------------------------------------------------------------------*/ - if (ret === false) { - ret = prevRenderer.apply(renderer, args); - } + /** + * Gets the timestamp of the number of milliseconds that have elapsed since + * the Unix epoch (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Date + * @returns {number} Returns the timestamp. + * @example + * + * _.defer(function(stamp) { + * console.log(_.now() - stamp); + * }, _.now()); + * // => Logs the number of milliseconds it took for the deferred invocation. + */ - return ret; - }; + var now = ctxNow || function () { + return root.Date.now(); }; + /*------------------------------------------------------------------------*/ - for (var prop in extension.renderer) { - _loop(prop); + /** + * The opposite of `_.before`; this method creates a function that invokes + * `func` once it's called `n` or more times. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {number} n The number of calls before `func` is invoked. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var saves = ['profile', 'settings']; + * + * var done = _.after(saves.length, function() { + * console.log('done saving!'); + * }); + * + * _.forEach(saves, function(type) { + * asyncSave({ 'type': type, 'complete': done }); + * }); + * // => Logs 'done saving!' after the two async saves have completed. + */ + + + function after(n, func) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + + n = toInteger(n); + return function () { + if (--n < 1) { + return func.apply(this, arguments); + } + }; } + /** + * Creates a function that invokes `func`, with up to `n` arguments, + * ignoring any additional arguments. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Function + * @param {Function} func The function to cap arguments for. + * @param {number} [n=func.length] The arity cap. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Function} Returns the new capped function. + * @example + * + * _.map(['6', '8', '10'], _.ary(parseInt, 1)); + * // => [6, 8, 10] + */ - opts.renderer = renderer; - })(); - } - if (extension.tokenizer) { - (function () { - var tokenizer = marked.defaults.tokenizer || new Tokenizer(); + function ary(func, n, guard) { + n = guard ? undefined$1 : n; + n = func && n == null ? func.length : n; + return createWrap(func, WRAP_ARY_FLAG, undefined$1, undefined$1, undefined$1, undefined$1, n); + } + /** + * Creates a function that invokes `func`, with the `this` binding and arguments + * of the created function, while it's called less than `n` times. Subsequent + * calls to the created function return the result of the last `func` invocation. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Function + * @param {number} n The number of calls at which `func` is no longer invoked. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * jQuery(element).on('click', _.before(5, addContactToList)); + * // => Allows adding up to 4 contacts to the list. + */ - var _loop2 = function _loop2(prop) { - var prevTokenizer = tokenizer[prop]; - tokenizer[prop] = function () { - for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { - args[_key2] = arguments[_key2]; - } + function before(n, func) { + var result; - var ret = extension.tokenizer[prop].apply(tokenizer, args); + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } - if (ret === false) { - ret = prevTokenizer.apply(tokenizer, args); + n = toInteger(n); + return function () { + if (--n > 0) { + result = func.apply(this, arguments); } - return ret; - }; - }; + if (n <= 1) { + func = undefined$1; + } - for (var prop in extension.tokenizer) { - _loop2(prop); + return result; + }; } + /** + * Creates a function that invokes `func` with the `this` binding of `thisArg` + * and `partials` prepended to the arguments it receives. + * + * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds, + * may be used as a placeholder for partially applied arguments. + * + * **Note:** Unlike native `Function#bind`, this method doesn't set the "length" + * property of bound functions. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to bind. + * @param {*} thisArg The `this` binding of `func`. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * function greet(greeting, punctuation) { + * return greeting + ' ' + this.user + punctuation; + * } + * + * var object = { 'user': 'fred' }; + * + * var bound = _.bind(greet, object, 'hi'); + * bound('!'); + * // => 'hi fred!' + * + * // Bound with placeholders. + * var bound = _.bind(greet, object, _, '!'); + * bound('hi'); + * // => 'hi fred!' + */ - opts.tokenizer = tokenizer; - })(); - } - if (extension.walkTokens) { - var walkTokens = marked.defaults.walkTokens; + var bind = baseRest(function (func, thisArg, partials) { + var bitmask = WRAP_BIND_FLAG; - opts.walkTokens = function (token) { - extension.walkTokens(token); + if (partials.length) { + var holders = replaceHolders(partials, getHolder(bind)); + bitmask |= WRAP_PARTIAL_FLAG; + } - if (walkTokens) { - walkTokens(token); + return createWrap(func, bitmask, thisArg, partials, holders); + }); + /** + * Creates a function that invokes the method at `object[key]` with `partials` + * prepended to the arguments it receives. + * + * This method differs from `_.bind` by allowing bound functions to reference + * methods that may be redefined or don't yet exist. See + * [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern) + * for more details. + * + * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * @static + * @memberOf _ + * @since 0.10.0 + * @category Function + * @param {Object} object The object to invoke the method on. + * @param {string} key The key of the method. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var object = { + * 'user': 'fred', + * 'greet': function(greeting, punctuation) { + * return greeting + ' ' + this.user + punctuation; + * } + * }; + * + * var bound = _.bindKey(object, 'greet', 'hi'); + * bound('!'); + * // => 'hi fred!' + * + * object.greet = function(greeting, punctuation) { + * return greeting + 'ya ' + this.user + punctuation; + * }; + * + * bound('!'); + * // => 'hiya fred!' + * + * // Bound with placeholders. + * var bound = _.bindKey(object, 'greet', _, '!'); + * bound('hi'); + * // => 'hiya fred!' + */ + + var bindKey = baseRest(function (object, key, partials) { + var bitmask = WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG; + + if (partials.length) { + var holders = replaceHolders(partials, getHolder(bindKey)); + bitmask |= WRAP_PARTIAL_FLAG; + } + + return createWrap(key, bitmask, object, partials, holders); + }); + /** + * Creates a function that accepts arguments of `func` and either invokes + * `func` returning its result, if at least `arity` number of arguments have + * been provided, or returns a function that accepts the remaining `func` + * arguments, and so on. The arity of `func` may be specified if `func.length` + * is not sufficient. + * + * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds, + * may be used as a placeholder for provided arguments. + * + * **Note:** This method doesn't set the "length" property of curried functions. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Function + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Function} Returns the new curried function. + * @example + * + * var abc = function(a, b, c) { + * return [a, b, c]; + * }; + * + * var curried = _.curry(abc); + * + * curried(1)(2)(3); + * // => [1, 2, 3] + * + * curried(1, 2)(3); + * // => [1, 2, 3] + * + * curried(1, 2, 3); + * // => [1, 2, 3] + * + * // Curried with placeholders. + * curried(1)(_, 3)(2); + * // => [1, 2, 3] + */ + + function curry(func, arity, guard) { + arity = guard ? undefined$1 : arity; + var result = createWrap(func, WRAP_CURRY_FLAG, undefined$1, undefined$1, undefined$1, undefined$1, undefined$1, arity); + result.placeholder = curry.placeholder; + return result; } - }; - } + /** + * This method is like `_.curry` except that arguments are applied to `func` + * in the manner of `_.partialRight` instead of `_.partial`. + * + * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for provided arguments. + * + * **Note:** This method doesn't set the "length" property of curried functions. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Function + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Function} Returns the new curried function. + * @example + * + * var abc = function(a, b, c) { + * return [a, b, c]; + * }; + * + * var curried = _.curryRight(abc); + * + * curried(3)(2)(1); + * // => [1, 2, 3] + * + * curried(2, 3)(1); + * // => [1, 2, 3] + * + * curried(1, 2, 3); + * // => [1, 2, 3] + * + * // Curried with placeholders. + * curried(3)(1, _)(2); + * // => [1, 2, 3] + */ - marked.setOptions(opts); - }; - /** - * Run callback for every token - */ + function curryRight(func, arity, guard) { + arity = guard ? undefined$1 : arity; + var result = createWrap(func, WRAP_CURRY_RIGHT_FLAG, undefined$1, undefined$1, undefined$1, undefined$1, undefined$1, arity); + result.placeholder = curryRight.placeholder; + return result; + } + /** + * Creates a debounced function that delays invoking `func` until after `wait` + * milliseconds have elapsed since the last time the debounced function was + * invoked. The debounced function comes with a `cancel` method to cancel + * delayed `func` invocations and a `flush` method to immediately invoke them. + * Provide `options` to indicate whether `func` should be invoked on the + * leading and/or trailing edge of the `wait` timeout. The `func` is invoked + * with the last arguments provided to the debounced function. Subsequent + * calls to the debounced function return the result of the last `func` + * invocation. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is + * invoked on the trailing edge of the timeout only if the debounced function + * is invoked more than once during the `wait` timeout. + * + * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred + * until to the next tick, similar to `setTimeout` with a timeout of `0`. + * + * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) + * for details over the differences between `_.debounce` and `_.throttle`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to debounce. + * @param {number} [wait=0] The number of milliseconds to delay. + * @param {Object} [options={}] The options object. + * @param {boolean} [options.leading=false] + * Specify invoking on the leading edge of the timeout. + * @param {number} [options.maxWait] + * The maximum time `func` is allowed to be delayed before it's invoked. + * @param {boolean} [options.trailing=true] + * Specify invoking on the trailing edge of the timeout. + * @returns {Function} Returns the new debounced function. + * @example + * + * // Avoid costly calculations while the window size is in flux. + * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); + * + * // Invoke `sendMail` when clicked, debouncing subsequent calls. + * jQuery(element).on('click', _.debounce(sendMail, 300, { + * 'leading': true, + * 'trailing': false + * })); + * + * // Ensure `batchLog` is invoked once after 1 second of debounced calls. + * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 }); + * var source = new EventSource('/stream'); + * jQuery(source).on('message', debounced); + * + * // Cancel the trailing debounced invocation. + * jQuery(window).on('popstate', debounced.cancel); + */ - marked.walkTokens = function (tokens, callback) { - var _iterator = _createForOfIteratorHelper(tokens), - _step; - try { - for (_iterator.s(); !(_step = _iterator.n()).done;) { - var token = _step.value; - callback(token); + function debounce(func, wait, options) { + var lastArgs, + lastThis, + maxWait, + result, + timerId, + lastCallTime, + lastInvokeTime = 0, + leading = false, + maxing = false, + trailing = true; - switch (token.type) { - case 'table': - { - var _iterator2 = _createForOfIteratorHelper(token.tokens.header), - _step2; + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } - try { - for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { - var cell = _step2.value; - marked.walkTokens(cell, callback); - } - } catch (err) { - _iterator2.e(err); - } finally { - _iterator2.f(); - } + wait = toNumber(wait) || 0; - var _iterator3 = _createForOfIteratorHelper(token.tokens.cells), - _step3; + if (isObject(options)) { + leading = !!options.leading; + maxing = 'maxWait' in options; + maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait; + trailing = 'trailing' in options ? !!options.trailing : trailing; + } - try { - for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) { - var row = _step3.value; + function invokeFunc(time) { + var args = lastArgs, + thisArg = lastThis; + lastArgs = lastThis = undefined$1; + lastInvokeTime = time; + result = func.apply(thisArg, args); + return result; + } - var _iterator4 = _createForOfIteratorHelper(row), - _step4; + function leadingEdge(time) { + // Reset any `maxWait` timer. + lastInvokeTime = time; // Start the timer for the trailing edge. - try { - for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) { - var _cell = _step4.value; - marked.walkTokens(_cell, callback); - } - } catch (err) { - _iterator4.e(err); - } finally { - _iterator4.f(); - } - } - } catch (err) { - _iterator3.e(err); - } finally { - _iterator3.f(); - } + timerId = setTimeout(timerExpired, wait); // Invoke the leading edge. - break; - } + return leading ? invokeFunc(time) : result; + } - case 'list': - { - marked.walkTokens(token.items, callback); - break; - } + function remainingWait(time) { + var timeSinceLastCall = time - lastCallTime, + timeSinceLastInvoke = time - lastInvokeTime, + timeWaiting = wait - timeSinceLastCall; + return maxing ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke) : timeWaiting; + } - default: - { - if (token.tokens) { - marked.walkTokens(token.tokens, callback); - } - } - } - } - } catch (err) { - _iterator.e(err); - } finally { - _iterator.f(); - } - }; - /** - * Parse Inline - */ + function shouldInvoke(time) { + var timeSinceLastCall = time - lastCallTime, + timeSinceLastInvoke = time - lastInvokeTime; // Either this is the first call, activity has stopped and we're at the + // trailing edge, the system time has gone backwards and we're treating + // it as the trailing edge, or we've hit the `maxWait` limit. + return lastCallTime === undefined$1 || timeSinceLastCall >= wait || timeSinceLastCall < 0 || maxing && timeSinceLastInvoke >= maxWait; + } - marked.parseInline = function (src, opt) { - // throw error in case of non string input - if (typeof src === 'undefined' || src === null) { - throw new Error('marked.parseInline(): input parameter is undefined or null'); - } + function timerExpired() { + var time = now(); - if (typeof src !== 'string') { - throw new Error('marked.parseInline(): input parameter is of type ' + Object.prototype.toString.call(src) + ', string expected'); - } + if (shouldInvoke(time)) { + return trailingEdge(time); + } // Restart the timer. - opt = merge({}, marked.defaults, opt || {}); - checkSanitizeDeprecation(opt); - try { - var tokens = Lexer.lexInline(src, opt); + timerId = setTimeout(timerExpired, remainingWait(time)); + } - if (opt.walkTokens) { - marked.walkTokens(tokens, opt.walkTokens); - } + function trailingEdge(time) { + timerId = undefined$1; // Only invoke if we have `lastArgs` which means `func` has been + // debounced at least once. - return Parser.parseInline(tokens, opt); - } catch (e) { - e.message += '\nPlease report this to https://github.com/markedjs/marked.'; + if (trailing && lastArgs) { + return invokeFunc(time); + } - if (opt.silent) { - return '

    An error occurred:

    ' + escape$1(e.message + '', true) + '
    '; - } + lastArgs = lastThis = undefined$1; + return result; + } - throw e; - } - }; - /** - * Expose - */ + function cancel() { + if (timerId !== undefined$1) { + clearTimeout(timerId); + } + lastInvokeTime = 0; + lastArgs = lastCallTime = lastThis = timerId = undefined$1; + } - marked.Parser = Parser; - marked.parser = Parser.parse; - marked.Renderer = Renderer; - marked.TextRenderer = TextRenderer; - marked.Lexer = Lexer; - marked.lexer = Lexer.lex; - marked.Tokenizer = Tokenizer; - marked.Slugger = Slugger; - marked.parse = marked; - var marked_1 = marked; + function flush() { + return timerId === undefined$1 ? result : trailingEdge(now()); + } - var tiler$4 = utilTiler(); - var dispatch$5 = dispatch$8('loaded'); - var _tileZoom$1 = 14; - var _osmoseUrlRoot = 'https://osmose.openstreetmap.fr/api/0.3'; - var _osmoseData = { - icons: {}, - items: [] - }; // This gets reassigned if reset + function debounced() { + var time = now(), + isInvoking = shouldInvoke(time); + lastArgs = arguments; + lastThis = this; + lastCallTime = time; - var _cache; + if (isInvoking) { + if (timerId === undefined$1) { + return leadingEdge(lastCallTime); + } - function abortRequest$4(controller) { - if (controller) { - controller.abort(); - } - } + if (maxing) { + // Handle invocations in a tight loop. + clearTimeout(timerId); + timerId = setTimeout(timerExpired, wait); + return invokeFunc(lastCallTime); + } + } - function abortUnwantedRequests$1(cache, tiles) { - Object.keys(cache.inflightTile).forEach(function (k) { - var wanted = tiles.find(function (tile) { - return k === tile.id; - }); + if (timerId === undefined$1) { + timerId = setTimeout(timerExpired, wait); + } - if (!wanted) { - abortRequest$4(cache.inflightTile[k]); - delete cache.inflightTile[k]; - } - }); - } + return result; + } - function encodeIssueRtree(d) { - return { - minX: d.loc[0], - minY: d.loc[1], - maxX: d.loc[0], - maxY: d.loc[1], - data: d - }; - } // Replace or remove QAItem from rtree + debounced.cancel = cancel; + debounced.flush = flush; + return debounced; + } + /** + * Defers invoking the `func` until the current call stack has cleared. Any + * additional arguments are provided to `func` when it's invoked. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to defer. + * @param {...*} [args] The arguments to invoke `func` with. + * @returns {number} Returns the timer id. + * @example + * + * _.defer(function(text) { + * console.log(text); + * }, 'deferred'); + * // => Logs 'deferred' after one millisecond. + */ - function updateRtree$1(item, replace) { - _cache.rtree.remove(item, function (a, b) { - return a.data.id === b.data.id; - }); + var defer = baseRest(function (func, args) { + return baseDelay(func, 1, args); + }); + /** + * Invokes `func` after `wait` milliseconds. Any additional arguments are + * provided to `func` when it's invoked. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @param {...*} [args] The arguments to invoke `func` with. + * @returns {number} Returns the timer id. + * @example + * + * _.delay(function(text) { + * console.log(text); + * }, 1000, 'later'); + * // => Logs 'later' after one second. + */ - if (replace) { - _cache.rtree.insert(item); - } - } // Issues shouldn't obscure each other + var delay = baseRest(function (func, wait, args) { + return baseDelay(func, toNumber(wait) || 0, args); + }); + /** + * Creates a function that invokes `func` with arguments reversed. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Function + * @param {Function} func The function to flip arguments for. + * @returns {Function} Returns the new flipped function. + * @example + * + * var flipped = _.flip(function() { + * return _.toArray(arguments); + * }); + * + * flipped('a', 'b', 'c', 'd'); + * // => ['d', 'c', 'b', 'a'] + */ + function flip(func) { + return createWrap(func, WRAP_FLIP_FLAG); + } + /** + * Creates a function that memoizes the result of `func`. If `resolver` is + * provided, it determines the cache key for storing the result based on the + * arguments provided to the memoized function. By default, the first argument + * provided to the memoized function is used as the map cache key. The `func` + * is invoked with the `this` binding of the memoized function. + * + * **Note:** The cache is exposed as the `cache` property on the memoized + * function. Its creation may be customized by replacing the `_.memoize.Cache` + * constructor with one whose instances implement the + * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) + * method interface of `clear`, `delete`, `get`, `has`, and `set`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to have its output memoized. + * @param {Function} [resolver] The function to resolve the cache key. + * @returns {Function} Returns the new memoized function. + * @example + * + * var object = { 'a': 1, 'b': 2 }; + * var other = { 'c': 3, 'd': 4 }; + * + * var values = _.memoize(_.values); + * values(object); + * // => [1, 2] + * + * values(other); + * // => [3, 4] + * + * object.a = 2; + * values(object); + * // => [1, 2] + * + * // Modify the result cache. + * values.cache.set(object, ['a', 'b']); + * values(object); + * // => ['a', 'b'] + * + * // Replace `_.memoize.Cache`. + * _.memoize.Cache = WeakMap; + */ - function preventCoincident(loc) { - var coincident = false; - do { - // first time, move marker up. after that, move marker right. - var delta = coincident ? [0.00001, 0] : [0, 0.00001]; - loc = geoVecAdd(loc, delta); - var bbox = geoExtent(loc).bbox(); - coincident = _cache.rtree.search(bbox).length; - } while (coincident); + function memoize(func, resolver) { + if (typeof func != 'function' || resolver != null && typeof resolver != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } - return loc; - } + var memoized = function memoized() { + var args = arguments, + key = resolver ? resolver.apply(this, args) : args[0], + cache = memoized.cache; - var serviceOsmose = { - title: 'osmose', - init: function init() { - _mainFileFetcher.get('qa_data').then(function (d) { - _osmoseData = d.osmose; - _osmoseData.items = Object.keys(d.osmose.icons).map(function (s) { - return s.split('-')[0]; - }).reduce(function (unique, item) { - return unique.indexOf(item) !== -1 ? unique : [].concat(_toConsumableArray(unique), [item]); - }, []); - }); + if (cache.has(key)) { + return cache.get(key); + } - if (!_cache) { - this.reset(); - } + var result = func.apply(this, args); + memoized.cache = cache.set(key, result) || cache; + return result; + }; - this.event = utilRebind(this, dispatch$5, 'on'); - }, - reset: function reset() { - var _strings = {}; - var _colors = {}; + memoized.cache = new (memoize.Cache || MapCache)(); + return memoized; + } // Expose `MapCache`. - if (_cache) { - Object.values(_cache.inflightTile).forEach(abortRequest$4); // Strings and colors are static and should not be re-populated - _strings = _cache.strings; - _colors = _cache.colors; - } + memoize.Cache = MapCache; + /** + * Creates a function that negates the result of the predicate `func`. The + * `func` predicate is invoked with the `this` binding and arguments of the + * created function. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Function + * @param {Function} predicate The predicate to negate. + * @returns {Function} Returns the new negated function. + * @example + * + * function isEven(n) { + * return n % 2 == 0; + * } + * + * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); + * // => [1, 3, 5] + */ - _cache = { - data: {}, - loadedTile: {}, - inflightTile: {}, - inflightPost: {}, - closed: {}, - rtree: new RBush(), - strings: _strings, - colors: _colors - }; - }, - loadIssues: function loadIssues(projection) { - var _this = this; + function negate(predicate) { + if (typeof predicate != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } - var params = { - // Tiles return a maximum # of issues - // So we want to filter our request for only types iD supports - item: _osmoseData.items - }; // determine the needed tiles to cover the view + return function () { + var args = arguments; - var tiles = tiler$4.zoomExtent([_tileZoom$1, _tileZoom$1]).getTiles(projection); // abort inflight requests that are no longer needed + switch (args.length) { + case 0: + return !predicate.call(this); - abortUnwantedRequests$1(_cache, tiles); // issue new requests.. + case 1: + return !predicate.call(this, args[0]); - tiles.forEach(function (tile) { - if (_cache.loadedTile[tile.id] || _cache.inflightTile[tile.id]) return; + case 2: + return !predicate.call(this, args[0], args[1]); - var _tile$xyz = _slicedToArray(tile.xyz, 3), - x = _tile$xyz[0], - y = _tile$xyz[1], - z = _tile$xyz[2]; + case 3: + return !predicate.call(this, args[0], args[1], args[2]); + } - var url = "".concat(_osmoseUrlRoot, "/issues/").concat(z, "/").concat(x, "/").concat(y, ".json?") + utilQsString(params); - var controller = new AbortController(); - _cache.inflightTile[tile.id] = controller; - d3_json(url, { - signal: controller.signal - }).then(function (data) { - delete _cache.inflightTile[tile.id]; - _cache.loadedTile[tile.id] = true; + return !predicate.apply(this, args); + }; + } + /** + * Creates a function that is restricted to invoking `func` once. Repeat calls + * to the function return the value of the first invocation. The `func` is + * invoked with the `this` binding and arguments of the created function. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var initialize = _.once(createApplication); + * initialize(); + * initialize(); + * // => `createApplication` is invoked once + */ - if (data.features) { - data.features.forEach(function (issue) { - var _issue$properties = issue.properties, - item = _issue$properties.item, - cl = _issue$properties["class"], - id = _issue$properties.uuid; - /* Osmose issues are uniquely identified by a unique - `item` and `class` combination (both integer values) */ - var itemType = "".concat(item, "-").concat(cl); // Filter out unsupported issue types (some are too specific or advanced) + function once(func) { + return before(2, func); + } + /** + * Creates a function that invokes `func` with its arguments transformed. + * + * @static + * @since 4.0.0 + * @memberOf _ + * @category Function + * @param {Function} func The function to wrap. + * @param {...(Function|Function[])} [transforms=[_.identity]] + * The argument transforms. + * @returns {Function} Returns the new function. + * @example + * + * function doubled(n) { + * return n * 2; + * } + * + * function square(n) { + * return n * n; + * } + * + * var func = _.overArgs(function(x, y) { + * return [x, y]; + * }, [square, doubled]); + * + * func(9, 3); + * // => [81, 6] + * + * func(10, 5); + * // => [100, 10] + */ - if (itemType in _osmoseData.icons) { - var loc = issue.geometry.coordinates; // lon, lat - loc = preventCoincident(loc); - var d = new QAItem(loc, _this, itemType, id, { - item: item - }); // Setting elems here prevents UI detail requests + var overArgs = castRest(function (func, transforms) { + transforms = transforms.length == 1 && isArray(transforms[0]) ? arrayMap(transforms[0], baseUnary(getIteratee())) : arrayMap(baseFlatten(transforms, 1), baseUnary(getIteratee())); + var funcsLength = transforms.length; + return baseRest(function (args) { + var index = -1, + length = nativeMin(args.length, funcsLength); - if (item === 8300 || item === 8360) { - d.elems = []; - } + while (++index < length) { + args[index] = transforms[index].call(this, args[index]); + } - _cache.data[d.id] = d; + return apply(func, this, args); + }); + }); + /** + * Creates a function that invokes `func` with `partials` prepended to the + * arguments it receives. This method is like `_.bind` except it does **not** + * alter the `this` binding. + * + * The `_.partial.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * **Note:** This method doesn't set the "length" property of partially + * applied functions. + * + * @static + * @memberOf _ + * @since 0.2.0 + * @category Function + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * function greet(greeting, name) { + * return greeting + ' ' + name; + * } + * + * var sayHelloTo = _.partial(greet, 'hello'); + * sayHelloTo('fred'); + * // => 'hello fred' + * + * // Partially applied with placeholders. + * var greetFred = _.partial(greet, _, 'fred'); + * greetFred('hi'); + * // => 'hi fred' + */ - _cache.rtree.insert(encodeIssueRtree(d)); - } - }); - } + var partial = baseRest(function (func, partials) { + var holders = replaceHolders(partials, getHolder(partial)); + return createWrap(func, WRAP_PARTIAL_FLAG, undefined$1, partials, holders); + }); + /** + * This method is like `_.partial` except that partially applied arguments + * are appended to the arguments it receives. + * + * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * **Note:** This method doesn't set the "length" property of partially + * applied functions. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Function + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * function greet(greeting, name) { + * return greeting + ' ' + name; + * } + * + * var greetFred = _.partialRight(greet, 'fred'); + * greetFred('hi'); + * // => 'hi fred' + * + * // Partially applied with placeholders. + * var sayHelloTo = _.partialRight(greet, 'hello', _); + * sayHelloTo('fred'); + * // => 'hello fred' + */ - dispatch$5.call('loaded'); - })["catch"](function () { - delete _cache.inflightTile[tile.id]; - _cache.loadedTile[tile.id] = true; + var partialRight = baseRest(function (func, partials) { + var holders = replaceHolders(partials, getHolder(partialRight)); + return createWrap(func, WRAP_PARTIAL_RIGHT_FLAG, undefined$1, partials, holders); }); - }); - }, - loadIssueDetail: function loadIssueDetail(issue) { - var _this2 = this; + /** + * Creates a function that invokes `func` with arguments arranged according + * to the specified `indexes` where the argument value at the first index is + * provided as the first argument, the argument value at the second index is + * provided as the second argument, and so on. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Function + * @param {Function} func The function to rearrange arguments for. + * @param {...(number|number[])} indexes The arranged argument indexes. + * @returns {Function} Returns the new function. + * @example + * + * var rearged = _.rearg(function(a, b, c) { + * return [a, b, c]; + * }, [2, 0, 1]); + * + * rearged('b', 'c', 'a') + * // => ['a', 'b', 'c'] + */ - // Issue details only need to be fetched once - if (issue.elems !== undefined) { - return Promise.resolve(issue); - } + var rearg = flatRest(function (func, indexes) { + return createWrap(func, WRAP_REARG_FLAG, undefined$1, undefined$1, undefined$1, indexes); + }); + /** + * Creates a function that invokes `func` with the `this` binding of the + * created function and arguments from `start` and beyond provided as + * an array. + * + * **Note:** This method is based on the + * [rest parameter](https://mdn.io/rest_parameters). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Function + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @returns {Function} Returns the new function. + * @example + * + * var say = _.rest(function(what, names) { + * return what + ' ' + _.initial(names).join(', ') + + * (_.size(names) > 1 ? ', & ' : '') + _.last(names); + * }); + * + * say('hello', 'fred', 'barney', 'pebbles'); + * // => 'hello fred, barney, & pebbles' + */ - var url = "".concat(_osmoseUrlRoot, "/issue/").concat(issue.id, "?langs=").concat(_mainLocalizer.localeCode()); + function rest(func, start) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } - var cacheDetails = function cacheDetails(data) { - // Associated elements used for highlighting - // Assign directly for immediate use in the callback - issue.elems = data.elems.map(function (e) { - return e.type.substring(0, 1) + e.id; - }); // Some issues have instance specific detail in a subtitle + start = start === undefined$1 ? start : toInteger(start); + return baseRest(func, start); + } + /** + * Creates a function that invokes `func` with the `this` binding of the + * create function and an array of arguments much like + * [`Function#apply`](http://www.ecma-international.org/ecma-262/7.0/#sec-function.prototype.apply). + * + * **Note:** This method is based on the + * [spread operator](https://mdn.io/spread_operator). + * + * @static + * @memberOf _ + * @since 3.2.0 + * @category Function + * @param {Function} func The function to spread arguments over. + * @param {number} [start=0] The start position of the spread. + * @returns {Function} Returns the new function. + * @example + * + * var say = _.spread(function(who, what) { + * return who + ' says ' + what; + * }); + * + * say(['fred', 'hello']); + * // => 'fred says hello' + * + * var numbers = Promise.all([ + * Promise.resolve(40), + * Promise.resolve(36) + * ]); + * + * numbers.then(_.spread(function(x, y) { + * return x + y; + * })); + * // => a Promise of 76 + */ - issue.detail = data.subtitle ? marked_1(data.subtitle.auto) : ''; - _this2.replaceItem(issue); - }; + function spread(func, start) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } - return d3_json(url).then(cacheDetails).then(function () { - return issue; - }); - }, - loadStrings: function loadStrings() { - var locale = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _mainLocalizer.localeCode(); - var items = Object.keys(_osmoseData.icons); + start = start == null ? 0 : nativeMax(toInteger(start), 0); + return baseRest(function (args) { + var array = args[start], + otherArgs = castSlice(args, 0, start); - if (locale in _cache.strings && Object.keys(_cache.strings[locale]).length === items.length) { - return Promise.resolve(_cache.strings[locale]); - } // May be partially populated already if some requests were successful + if (array) { + arrayPush(otherArgs, array); + } + return apply(func, this, otherArgs); + }); + } + /** + * Creates a throttled function that only invokes `func` at most once per + * every `wait` milliseconds. The throttled function comes with a `cancel` + * method to cancel delayed `func` invocations and a `flush` method to + * immediately invoke them. Provide `options` to indicate whether `func` + * should be invoked on the leading and/or trailing edge of the `wait` + * timeout. The `func` is invoked with the last arguments provided to the + * throttled function. Subsequent calls to the throttled function return the + * result of the last `func` invocation. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is + * invoked on the trailing edge of the timeout only if the throttled function + * is invoked more than once during the `wait` timeout. + * + * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred + * until to the next tick, similar to `setTimeout` with a timeout of `0`. + * + * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) + * for details over the differences between `_.throttle` and `_.debounce`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to throttle. + * @param {number} [wait=0] The number of milliseconds to throttle invocations to. + * @param {Object} [options={}] The options object. + * @param {boolean} [options.leading=true] + * Specify invoking on the leading edge of the timeout. + * @param {boolean} [options.trailing=true] + * Specify invoking on the trailing edge of the timeout. + * @returns {Function} Returns the new throttled function. + * @example + * + * // Avoid excessively updating the position while scrolling. + * jQuery(window).on('scroll', _.throttle(updatePosition, 100)); + * + * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes. + * var throttled = _.throttle(renewToken, 300000, { 'trailing': false }); + * jQuery(element).on('click', throttled); + * + * // Cancel the trailing throttled invocation. + * jQuery(window).on('popstate', throttled.cancel); + */ - if (!(locale in _cache.strings)) { - _cache.strings[locale] = {}; - } // Only need to cache strings for supported issue types - // Using multiple individual item + class requests to reduce fetched data size + function throttle(func, wait, options) { + var leading = true, + trailing = true; - var allRequests = items.map(function (itemType) { - // No need to request data we already have - if (itemType in _cache.strings[locale]) return null; + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } - var cacheData = function cacheData(data) { - // Bunch of nested single value arrays of objects - var _data$categories = _slicedToArray(data.categories, 1), - _data$categories$ = _data$categories[0], - cat = _data$categories$ === void 0 ? { - items: [] - } : _data$categories$; + if (isObject(options)) { + leading = 'leading' in options ? !!options.leading : leading; + trailing = 'trailing' in options ? !!options.trailing : trailing; + } - var _cat$items = _slicedToArray(cat.items, 1), - _cat$items$ = _cat$items[0], - item = _cat$items$ === void 0 ? { - "class": [] - } : _cat$items$; + return debounce(func, wait, { + 'leading': leading, + 'maxWait': wait, + 'trailing': trailing + }); + } + /** + * Creates a function that accepts up to one argument, ignoring any + * additional arguments. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Function + * @param {Function} func The function to cap arguments for. + * @returns {Function} Returns the new capped function. + * @example + * + * _.map(['6', '8', '10'], _.unary(parseInt)); + * // => [6, 8, 10] + */ - var _item$class = _slicedToArray(item["class"], 1), - _item$class$ = _item$class[0], - cl = _item$class$ === void 0 ? null : _item$class$; // If null default value is reached, data wasn't as expected (or was empty) + function unary(func) { + return ary(func, 1); + } + /** + * Creates a function that provides `value` to `wrapper` as its first + * argument. Any additional arguments provided to the function are appended + * to those provided to the `wrapper`. The wrapper is invoked with the `this` + * binding of the created function. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {*} value The value to wrap. + * @param {Function} [wrapper=identity] The wrapper function. + * @returns {Function} Returns the new function. + * @example + * + * var p = _.wrap(_.escape, function(func, text) { + * return '

    ' + func(text) + '

    '; + * }); + * + * p('fred, barney, & pebbles'); + * // => '

    fred, barney, & pebbles

    ' + */ - if (!cl) { - /* eslint-disable no-console */ - console.log("Osmose strings request (".concat(itemType, ") had unexpected data")); - /* eslint-enable no-console */ - return; - } // Cache served item colors to automatically style issue markers later + function wrap(value, wrapper) { + return partial(castFunction(wrapper), value); + } + /*------------------------------------------------------------------------*/ + /** + * Casts `value` as an array if it's not one. + * + * @static + * @memberOf _ + * @since 4.4.0 + * @category Lang + * @param {*} value The value to inspect. + * @returns {Array} Returns the cast array. + * @example + * + * _.castArray(1); + * // => [1] + * + * _.castArray({ 'a': 1 }); + * // => [{ 'a': 1 }] + * + * _.castArray('abc'); + * // => ['abc'] + * + * _.castArray(null); + * // => [null] + * + * _.castArray(undefined); + * // => [undefined] + * + * _.castArray(); + * // => [] + * + * var array = [1, 2, 3]; + * console.log(_.castArray(array) === array); + * // => true + */ - var itemInt = item.item, - color = item.color; - if (/^#[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3}/.test(color)) { - _cache.colors[itemInt] = color; - } // Value of root key will be null if no string exists - // If string exists, value is an object with key 'auto' for string + function castArray() { + if (!arguments.length) { + return []; + } + var value = arguments[0]; + return isArray(value) ? value : [value]; + } + /** + * Creates a shallow clone of `value`. + * + * **Note:** This method is loosely based on the + * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm) + * and supports cloning arrays, array buffers, booleans, date objects, maps, + * numbers, `Object` objects, regexes, sets, strings, symbols, and typed + * arrays. The own enumerable properties of `arguments` objects are cloned + * as plain objects. An empty object is returned for uncloneable values such + * as error objects, functions, DOM nodes, and WeakMaps. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to clone. + * @returns {*} Returns the cloned value. + * @see _.cloneDeep + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var shallow = _.clone(objects); + * console.log(shallow[0] === objects[0]); + * // => true + */ - var title = cl.title, - detail = cl.detail, - fix = cl.fix, - trap = cl.trap; // Osmose titles shouldn't contain markdown - var issueStrings = {}; - if (title) issueStrings.title = title.auto; - if (detail) issueStrings.detail = marked_1(detail.auto); - if (trap) issueStrings.trap = marked_1(trap.auto); - if (fix) issueStrings.fix = marked_1(fix.auto); - _cache.strings[locale][itemType] = issueStrings; - }; + function clone(value) { + return baseClone(value, CLONE_SYMBOLS_FLAG); + } + /** + * This method is like `_.clone` except that it accepts `customizer` which + * is invoked to produce the cloned value. If `customizer` returns `undefined`, + * cloning is handled by the method instead. The `customizer` is invoked with + * up to four arguments; (value [, index|key, object, stack]). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to clone. + * @param {Function} [customizer] The function to customize cloning. + * @returns {*} Returns the cloned value. + * @see _.cloneDeepWith + * @example + * + * function customizer(value) { + * if (_.isElement(value)) { + * return value.cloneNode(false); + * } + * } + * + * var el = _.cloneWith(document.body, customizer); + * + * console.log(el === document.body); + * // => false + * console.log(el.nodeName); + * // => 'BODY' + * console.log(el.childNodes.length); + * // => 0 + */ - var _itemType$split = itemType.split('-'), - _itemType$split2 = _slicedToArray(_itemType$split, 2), - item = _itemType$split2[0], - cl = _itemType$split2[1]; // Osmose API falls back to English strings where untranslated or if locale doesn't exist + function cloneWith(value, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined$1; + return baseClone(value, CLONE_SYMBOLS_FLAG, customizer); + } + /** + * This method is like `_.clone` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @returns {*} Returns the deep cloned value. + * @see _.clone + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var deep = _.cloneDeep(objects); + * console.log(deep[0] === objects[0]); + * // => false + */ - var url = "".concat(_osmoseUrlRoot, "/items/").concat(item, "/class/").concat(cl, "?langs=").concat(locale); - return d3_json(url).then(cacheData); - }).filter(Boolean); - return Promise.all(allRequests).then(function () { - return _cache.strings[locale]; - }); - }, - getStrings: function getStrings(itemType) { - var locale = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _mainLocalizer.localeCode(); - // No need to fallback to English, Osmose API handles this for us - return locale in _cache.strings ? _cache.strings[locale][itemType] : {}; - }, - getColor: function getColor(itemType) { - return itemType in _cache.colors ? _cache.colors[itemType] : '#FFFFFF'; - }, - postUpdate: function postUpdate(issue, callback) { - var _this3 = this; - if (_cache.inflightPost[issue.id]) { - return callback({ - message: 'Issue update already inflight', - status: -2 - }, issue); - } // UI sets the status to either 'done' or 'false' + function cloneDeep(value) { + return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG); + } + /** + * This method is like `_.cloneWith` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @param {Function} [customizer] The function to customize cloning. + * @returns {*} Returns the deep cloned value. + * @see _.cloneWith + * @example + * + * function customizer(value) { + * if (_.isElement(value)) { + * return value.cloneNode(true); + * } + * } + * + * var el = _.cloneDeepWith(document.body, customizer); + * + * console.log(el === document.body); + * // => false + * console.log(el.nodeName); + * // => 'BODY' + * console.log(el.childNodes.length); + * // => 20 + */ - var url = "".concat(_osmoseUrlRoot, "/issue/").concat(issue.id, "/").concat(issue.newStatus); - var controller = new AbortController(); + function cloneDeepWith(value, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined$1; + return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer); + } + /** + * Checks if `object` conforms to `source` by invoking the predicate + * properties of `source` with the corresponding property values of `object`. + * + * **Note:** This method is equivalent to `_.conforms` when `source` is + * partially applied. + * + * @static + * @memberOf _ + * @since 4.14.0 + * @category Lang + * @param {Object} object The object to inspect. + * @param {Object} source The object of property predicates to conform to. + * @returns {boolean} Returns `true` if `object` conforms, else `false`. + * @example + * + * var object = { 'a': 1, 'b': 2 }; + * + * _.conformsTo(object, { 'b': function(n) { return n > 1; } }); + * // => true + * + * _.conformsTo(object, { 'b': function(n) { return n > 2; } }); + * // => false + */ - var after = function after() { - delete _cache.inflightPost[issue.id]; - _this3.removeItem(issue); + function conformsTo(object, source) { + return source == null || baseConformsTo(object, source, keys(source)); + } + /** + * Performs a + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ - if (issue.newStatus === 'done') { - // Keep track of the number of issues closed per `item` to tag the changeset - if (!(issue.item in _cache.closed)) { - _cache.closed[issue.item] = 0; - } - _cache.closed[issue.item] += 1; + function eq(value, other) { + return value === other || value !== value && other !== other; } + /** + * Checks if `value` is greater than `other`. + * + * @static + * @memberOf _ + * @since 3.9.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than `other`, + * else `false`. + * @see _.lt + * @example + * + * _.gt(3, 1); + * // => true + * + * _.gt(3, 3); + * // => false + * + * _.gt(1, 3); + * // => false + */ - if (callback) callback(null, issue); - }; - _cache.inflightPost[issue.id] = controller; - fetch(url, { - signal: controller.signal - }).then(after)["catch"](function (err) { - delete _cache.inflightPost[issue.id]; - if (callback) callback(err.message); - }); - }, - // Get all cached QAItems covering the viewport - getItems: function getItems(projection) { - var viewport = projection.clipExtent(); - var min = [viewport[0][0], viewport[1][1]]; - var max = [viewport[1][0], viewport[0][1]]; - var bbox = geoExtent(projection.invert(min), projection.invert(max)).bbox(); - return _cache.rtree.search(bbox).map(function (d) { - return d.data; - }); - }, - // Get a QAItem from cache - // NOTE: Don't change method name until UI v3 is merged - getError: function getError(id) { - return _cache.data[id]; - }, - // get the name of the icon to display for this item - getIcon: function getIcon(itemType) { - return _osmoseData.icons[itemType]; - }, - // Replace a single QAItem in the cache - replaceItem: function replaceItem(item) { - if (!(item instanceof QAItem) || !item.id) return; - _cache.data[item.id] = item; - updateRtree$1(encodeIssueRtree(item), true); // true = replace + var gt = createRelationalOperation(baseGt); + /** + * Checks if `value` is greater than or equal to `other`. + * + * @static + * @memberOf _ + * @since 3.9.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than or equal to + * `other`, else `false`. + * @see _.lte + * @example + * + * _.gte(3, 1); + * // => true + * + * _.gte(3, 3); + * // => true + * + * _.gte(1, 3); + * // => false + */ - return item; - }, - // Remove a single QAItem from the cache - removeItem: function removeItem(item) { - if (!(item instanceof QAItem) || !item.id) return; - delete _cache.data[item.id]; - updateRtree$1(encodeIssueRtree(item), false); // false = remove - }, - // Used to populate `closed:osmose:*` changeset tags - getClosedCounts: function getClosedCounts() { - return _cache.closed; - }, - itemURL: function itemURL(item) { - return "https://osmose.openstreetmap.fr/en/error/".concat(item.id); - } - }; + var gte = createRelationalOperation(function (value, other) { + return value >= other; + }); + /** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ - var ieee754$1 = {}; + var isArguments = baseIsArguments(function () { + return arguments; + }()) ? baseIsArguments : function (value) { + return isObjectLike(value) && hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee'); + }; + /** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ - /*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh */ + var isArray = Array.isArray; + /** + * Checks if `value` is classified as an `ArrayBuffer` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`. + * @example + * + * _.isArrayBuffer(new ArrayBuffer(2)); + * // => true + * + * _.isArrayBuffer(new Array(2)); + * // => false + */ - ieee754$1.read = function (buffer, offset, isLE, mLen, nBytes) { - var e, m; - var eLen = nBytes * 8 - mLen - 1; - var eMax = (1 << eLen) - 1; - var eBias = eMax >> 1; - var nBits = -7; - var i = isLE ? nBytes - 1 : 0; - var d = isLE ? -1 : 1; - var s = buffer[offset + i]; - i += d; - e = s & (1 << -nBits) - 1; - s >>= -nBits; - nBits += eLen; + var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer; + /** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ - for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {} + function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); + } + /** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, + * else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ - m = e & (1 << -nBits) - 1; - e >>= -nBits; - nBits += mLen; - for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {} + function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); + } + /** + * Checks if `value` is classified as a boolean primitive or object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a boolean, else `false`. + * @example + * + * _.isBoolean(false); + * // => true + * + * _.isBoolean(null); + * // => false + */ - if (e === 0) { - e = 1 - eBias; - } else if (e === eMax) { - return m ? NaN : (s ? -1 : 1) * Infinity; - } else { - m = m + Math.pow(2, mLen); - e = e - eBias; - } - return (s ? -1 : 1) * m * Math.pow(2, e - mLen); - }; + function isBoolean(value) { + return value === true || value === false || isObjectLike(value) && baseGetTag(value) == boolTag; + } + /** + * Checks if `value` is a buffer. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. + * @example + * + * _.isBuffer(new Buffer(2)); + * // => true + * + * _.isBuffer(new Uint8Array(2)); + * // => false + */ - ieee754$1.write = function (buffer, value, offset, isLE, mLen, nBytes) { - var e, m, c; - var eLen = nBytes * 8 - mLen - 1; - var eMax = (1 << eLen) - 1; - var eBias = eMax >> 1; - var rt = mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0; - var i = isLE ? 0 : nBytes - 1; - var d = isLE ? 1 : -1; - var s = value < 0 || value === 0 && 1 / value < 0 ? 1 : 0; - value = Math.abs(value); - if (isNaN(value) || value === Infinity) { - m = isNaN(value) ? 1 : 0; - e = eMax; - } else { - e = Math.floor(Math.log(value) / Math.LN2); + var isBuffer = nativeIsBuffer || stubFalse; + /** + * Checks if `value` is classified as a `Date` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a date object, else `false`. + * @example + * + * _.isDate(new Date); + * // => true + * + * _.isDate('Mon April 23 2012'); + * // => false + */ - if (value * (c = Math.pow(2, -e)) < 1) { - e--; - c *= 2; - } + var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate; + /** + * Checks if `value` is likely a DOM element. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`. + * @example + * + * _.isElement(document.body); + * // => true + * + * _.isElement(''); + * // => false + */ - if (e + eBias >= 1) { - value += rt / c; - } else { - value += rt * Math.pow(2, 1 - eBias); - } + function isElement(value) { + return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value); + } + /** + * Checks if `value` is an empty object, collection, map, or set. + * + * Objects are considered empty if they have no own enumerable string keyed + * properties. + * + * Array-like values such as `arguments` objects, arrays, buffers, strings, or + * jQuery-like collections are considered empty if they have a `length` of `0`. + * Similarly, maps and sets are considered empty if they have a `size` of `0`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is empty, else `false`. + * @example + * + * _.isEmpty(null); + * // => true + * + * _.isEmpty(true); + * // => true + * + * _.isEmpty(1); + * // => true + * + * _.isEmpty([1, 2, 3]); + * // => false + * + * _.isEmpty({ 'a': 1 }); + * // => false + */ - if (value * c >= 2) { - e++; - c /= 2; - } - if (e + eBias >= eMax) { - m = 0; - e = eMax; - } else if (e + eBias >= 1) { - m = (value * c - 1) * Math.pow(2, mLen); - e = e + eBias; - } else { - m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); - e = 0; - } - } + function isEmpty(value) { + if (value == null) { + return true; + } - for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} + if (isArrayLike(value) && (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' || isBuffer(value) || isTypedArray(value) || isArguments(value))) { + return !value.length; + } - e = e << mLen | m; - eLen += mLen; + var tag = getTag(value); - for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} + if (tag == mapTag || tag == setTag) { + return !value.size; + } - buffer[offset + i - d] |= s * 128; - }; + if (isPrototype(value)) { + return !baseKeys(value).length; + } - var pbf = Pbf; - var ieee754 = ieee754$1; + for (var key in value) { + if (hasOwnProperty.call(value, key)) { + return false; + } + } - function Pbf(buf) { - this.buf = ArrayBuffer.isView && ArrayBuffer.isView(buf) ? buf : new Uint8Array(buf || 0); - this.pos = 0; - this.type = 0; - this.length = this.buf.length; - } + return true; + } + /** + * Performs a deep comparison between two values to determine if they are + * equivalent. + * + * **Note:** This method supports comparing arrays, array buffers, booleans, + * date objects, error objects, maps, numbers, `Object` objects, regexes, + * sets, strings, symbols, and typed arrays. `Object` objects are compared + * by their own, not inherited, enumerable properties. Functions and DOM + * nodes are compared by strict equality, i.e. `===`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.isEqual(object, other); + * // => true + * + * object === other; + * // => false + */ - Pbf.Varint = 0; // varint: int32, int64, uint32, uint64, sint32, sint64, bool, enum - Pbf.Fixed64 = 1; // 64-bit: double, fixed64, sfixed64 + function isEqual(value, other) { + return baseIsEqual(value, other); + } + /** + * This method is like `_.isEqual` except that it accepts `customizer` which + * is invoked to compare values. If `customizer` returns `undefined`, comparisons + * are handled by the method instead. The `customizer` is invoked with up to + * six arguments: (objValue, othValue [, index|key, object, other, stack]). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * function isGreeting(value) { + * return /^h(?:i|ello)$/.test(value); + * } + * + * function customizer(objValue, othValue) { + * if (isGreeting(objValue) && isGreeting(othValue)) { + * return true; + * } + * } + * + * var array = ['hello', 'goodbye']; + * var other = ['hi', 'goodbye']; + * + * _.isEqualWith(array, other, customizer); + * // => true + */ - Pbf.Bytes = 2; // length-delimited: string, bytes, embedded messages, packed repeated fields - Pbf.Fixed32 = 5; // 32-bit: float, fixed32, sfixed32 + function isEqualWith(value, other, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined$1; + var result = customizer ? customizer(value, other) : undefined$1; + return result === undefined$1 ? baseIsEqual(value, other, undefined$1, customizer) : !!result; + } + /** + * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`, + * `SyntaxError`, `TypeError`, or `URIError` object. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an error object, else `false`. + * @example + * + * _.isError(new Error); + * // => true + * + * _.isError(Error); + * // => false + */ - var SHIFT_LEFT_32 = (1 << 16) * (1 << 16), - SHIFT_RIGHT_32 = 1 / SHIFT_LEFT_32; // Threshold chosen based on both benchmarking and knowledge about browser string - // data structures (which currently switch structure types at 12 bytes or more) - var TEXT_DECODER_MIN_LENGTH = 12; - var utf8TextDecoder = typeof TextDecoder === 'undefined' ? null : new TextDecoder('utf8'); - Pbf.prototype = { - destroy: function destroy() { - this.buf = null; - }, - // === READING ================================================================= - readFields: function readFields(readField, result, end) { - end = end || this.length; + function isError(value) { + if (!isObjectLike(value)) { + return false; + } - while (this.pos < end) { - var val = this.readVarint(), - tag = val >> 3, - startPos = this.pos; - this.type = val & 0x7; - readField(tag, result, this); - if (this.pos === startPos) this.skip(val); - } + var tag = baseGetTag(value); + return tag == errorTag || tag == domExcTag || typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value); + } + /** + * Checks if `value` is a finite primitive number. + * + * **Note:** This method is based on + * [`Number.isFinite`](https://mdn.io/Number/isFinite). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a finite number, else `false`. + * @example + * + * _.isFinite(3); + * // => true + * + * _.isFinite(Number.MIN_VALUE); + * // => true + * + * _.isFinite(Infinity); + * // => false + * + * _.isFinite('3'); + * // => false + */ - return result; - }, - readMessage: function readMessage(readField, result) { - return this.readFields(readField, result, this.readVarint() + this.pos); - }, - readFixed32: function readFixed32() { - var val = readUInt32(this.buf, this.pos); - this.pos += 4; - return val; - }, - readSFixed32: function readSFixed32() { - var val = readInt32(this.buf, this.pos); - this.pos += 4; - return val; - }, - // 64-bit int handling is based on github.com/dpw/node-buffer-more-ints (MIT-licensed) - readFixed64: function readFixed64() { - var val = readUInt32(this.buf, this.pos) + readUInt32(this.buf, this.pos + 4) * SHIFT_LEFT_32; - this.pos += 8; - return val; - }, - readSFixed64: function readSFixed64() { - var val = readUInt32(this.buf, this.pos) + readInt32(this.buf, this.pos + 4) * SHIFT_LEFT_32; - this.pos += 8; - return val; - }, - readFloat: function readFloat() { - var val = ieee754.read(this.buf, this.pos, true, 23, 4); - this.pos += 4; - return val; - }, - readDouble: function readDouble() { - var val = ieee754.read(this.buf, this.pos, true, 52, 8); - this.pos += 8; - return val; - }, - readVarint: function readVarint(isSigned) { - var buf = this.buf, - val, - b; - b = buf[this.pos++]; - val = b & 0x7f; - if (b < 0x80) return val; - b = buf[this.pos++]; - val |= (b & 0x7f) << 7; - if (b < 0x80) return val; - b = buf[this.pos++]; - val |= (b & 0x7f) << 14; - if (b < 0x80) return val; - b = buf[this.pos++]; - val |= (b & 0x7f) << 21; - if (b < 0x80) return val; - b = buf[this.pos]; - val |= (b & 0x0f) << 28; - return readVarintRemainder(val, isSigned, this); - }, - readVarint64: function readVarint64() { - // for compatibility with v2.0.1 - return this.readVarint(true); - }, - readSVarint: function readSVarint() { - var num = this.readVarint(); - return num % 2 === 1 ? (num + 1) / -2 : num / 2; // zigzag encoding - }, - readBoolean: function readBoolean() { - return Boolean(this.readVarint()); - }, - readString: function readString() { - var end = this.readVarint() + this.pos; - var pos = this.pos; - this.pos = end; - if (end - pos >= TEXT_DECODER_MIN_LENGTH && utf8TextDecoder) { - // longer strings are fast with the built-in browser TextDecoder API - return readUtf8TextDecoder(this.buf, pos, end); - } // short strings are fast with our custom implementation + function isFinite(value) { + return typeof value == 'number' && nativeIsFinite(value); + } + /** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ - return readUtf8(this.buf, pos, end); - }, - readBytes: function readBytes() { - var end = this.readVarint() + this.pos, - buffer = this.buf.subarray(this.pos, end); - this.pos = end; - return buffer; - }, - // verbose for performance reasons; doesn't affect gzipped size - readPackedVarint: function readPackedVarint(arr, isSigned) { - if (this.type !== Pbf.Bytes) return arr.push(this.readVarint(isSigned)); - var end = readPackedEnd(this); - arr = arr || []; + function isFunction(value) { + if (!isObject(value)) { + return false; + } // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 9 which returns 'object' for typed arrays and other constructors. - while (this.pos < end) { - arr.push(this.readVarint(isSigned)); - } - return arr; - }, - readPackedSVarint: function readPackedSVarint(arr) { - if (this.type !== Pbf.Bytes) return arr.push(this.readSVarint()); - var end = readPackedEnd(this); - arr = arr || []; + var tag = baseGetTag(value); + return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; + } + /** + * Checks if `value` is an integer. + * + * **Note:** This method is based on + * [`Number.isInteger`](https://mdn.io/Number/isInteger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an integer, else `false`. + * @example + * + * _.isInteger(3); + * // => true + * + * _.isInteger(Number.MIN_VALUE); + * // => false + * + * _.isInteger(Infinity); + * // => false + * + * _.isInteger('3'); + * // => false + */ - while (this.pos < end) { - arr.push(this.readSVarint()); - } - return arr; - }, - readPackedBoolean: function readPackedBoolean(arr) { - if (this.type !== Pbf.Bytes) return arr.push(this.readBoolean()); - var end = readPackedEnd(this); - arr = arr || []; + function isInteger(value) { + return typeof value == 'number' && value == toInteger(value); + } + /** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ - while (this.pos < end) { - arr.push(this.readBoolean()); - } - return arr; - }, - readPackedFloat: function readPackedFloat(arr) { - if (this.type !== Pbf.Bytes) return arr.push(this.readFloat()); - var end = readPackedEnd(this); - arr = arr || []; + function isLength(value) { + return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; + } + /** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ - while (this.pos < end) { - arr.push(this.readFloat()); - } - return arr; - }, - readPackedDouble: function readPackedDouble(arr) { - if (this.type !== Pbf.Bytes) return arr.push(this.readDouble()); - var end = readPackedEnd(this); - arr = arr || []; + function isObject(value) { + var type = _typeof(value); - while (this.pos < end) { - arr.push(this.readDouble()); - } + return value != null && (type == 'object' || type == 'function'); + } + /** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ - return arr; - }, - readPackedFixed32: function readPackedFixed32(arr) { - if (this.type !== Pbf.Bytes) return arr.push(this.readFixed32()); - var end = readPackedEnd(this); - arr = arr || []; - while (this.pos < end) { - arr.push(this.readFixed32()); - } + function isObjectLike(value) { + return value != null && _typeof(value) == 'object'; + } + /** + * Checks if `value` is classified as a `Map` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + * @example + * + * _.isMap(new Map); + * // => true + * + * _.isMap(new WeakMap); + * // => false + */ - return arr; - }, - readPackedSFixed32: function readPackedSFixed32(arr) { - if (this.type !== Pbf.Bytes) return arr.push(this.readSFixed32()); - var end = readPackedEnd(this); - arr = arr || []; - while (this.pos < end) { - arr.push(this.readSFixed32()); - } + var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap; + /** + * Performs a partial deep comparison between `object` and `source` to + * determine if `object` contains equivalent property values. + * + * **Note:** This method is equivalent to `_.matches` when `source` is + * partially applied. + * + * Partial comparisons will match empty array and empty object `source` + * values against any array or object value, respectively. See `_.isEqual` + * for a list of supported value comparisons. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + * @example + * + * var object = { 'a': 1, 'b': 2 }; + * + * _.isMatch(object, { 'b': 2 }); + * // => true + * + * _.isMatch(object, { 'b': 1 }); + * // => false + */ - return arr; - }, - readPackedFixed64: function readPackedFixed64(arr) { - if (this.type !== Pbf.Bytes) return arr.push(this.readFixed64()); - var end = readPackedEnd(this); - arr = arr || []; + function isMatch(object, source) { + return object === source || baseIsMatch(object, source, getMatchData(source)); + } + /** + * This method is like `_.isMatch` except that it accepts `customizer` which + * is invoked to compare values. If `customizer` returns `undefined`, comparisons + * are handled by the method instead. The `customizer` is invoked with five + * arguments: (objValue, srcValue, index|key, object, source). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + * @example + * + * function isGreeting(value) { + * return /^h(?:i|ello)$/.test(value); + * } + * + * function customizer(objValue, srcValue) { + * if (isGreeting(objValue) && isGreeting(srcValue)) { + * return true; + * } + * } + * + * var object = { 'greeting': 'hello' }; + * var source = { 'greeting': 'hi' }; + * + * _.isMatchWith(object, source, customizer); + * // => true + */ - while (this.pos < end) { - arr.push(this.readFixed64()); - } - return arr; - }, - readPackedSFixed64: function readPackedSFixed64(arr) { - if (this.type !== Pbf.Bytes) return arr.push(this.readSFixed64()); - var end = readPackedEnd(this); - arr = arr || []; + function isMatchWith(object, source, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined$1; + return baseIsMatch(object, source, getMatchData(source), customizer); + } + /** + * Checks if `value` is `NaN`. + * + * **Note:** This method is based on + * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as + * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for + * `undefined` and other non-number values. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + * @example + * + * _.isNaN(NaN); + * // => true + * + * _.isNaN(new Number(NaN)); + * // => true + * + * isNaN(undefined); + * // => true + * + * _.isNaN(undefined); + * // => false + */ - while (this.pos < end) { - arr.push(this.readSFixed64()); - } - return arr; - }, - skip: function skip(val) { - var type = val & 0x7; - if (type === Pbf.Varint) while (this.buf[this.pos++] > 0x7f) {} else if (type === Pbf.Bytes) this.pos = this.readVarint() + this.pos;else if (type === Pbf.Fixed32) this.pos += 4;else if (type === Pbf.Fixed64) this.pos += 8;else throw new Error('Unimplemented type: ' + type); - }, - // === WRITING ================================================================= - writeTag: function writeTag(tag, type) { - this.writeVarint(tag << 3 | type); - }, - realloc: function realloc(min) { - var length = this.length || 16; + function isNaN(value) { + // An `NaN` primitive is the only value that is not equal to itself. + // Perform the `toStringTag` check first to avoid errors with some + // ActiveX objects in IE. + return isNumber(value) && value != +value; + } + /** + * Checks if `value` is a pristine native function. + * + * **Note:** This method can't reliably detect native functions in the presence + * of the core-js package because core-js circumvents this kind of detection. + * Despite multiple requests, the core-js maintainer has made it clear: any + * attempt to fix the detection will be obstructed. As a result, we're left + * with little choice but to throw an error. Unfortunately, this also affects + * packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill), + * which rely on core-js. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + * @example + * + * _.isNative(Array.prototype.push); + * // => true + * + * _.isNative(_); + * // => false + */ - while (length < this.pos + min) { - length *= 2; - } - if (length !== this.length) { - var buf = new Uint8Array(length); - buf.set(this.buf); - this.buf = buf; - this.length = length; - } - }, - finish: function finish() { - this.length = this.pos; - this.pos = 0; - return this.buf.subarray(0, this.length); - }, - writeFixed32: function writeFixed32(val) { - this.realloc(4); - writeInt32(this.buf, val, this.pos); - this.pos += 4; - }, - writeSFixed32: function writeSFixed32(val) { - this.realloc(4); - writeInt32(this.buf, val, this.pos); - this.pos += 4; - }, - writeFixed64: function writeFixed64(val) { - this.realloc(8); - writeInt32(this.buf, val & -1, this.pos); - writeInt32(this.buf, Math.floor(val * SHIFT_RIGHT_32), this.pos + 4); - this.pos += 8; - }, - writeSFixed64: function writeSFixed64(val) { - this.realloc(8); - writeInt32(this.buf, val & -1, this.pos); - writeInt32(this.buf, Math.floor(val * SHIFT_RIGHT_32), this.pos + 4); - this.pos += 8; - }, - writeVarint: function writeVarint(val) { - val = +val || 0; + function isNative(value) { + if (isMaskable(value)) { + throw new Error(CORE_ERROR_TEXT); + } - if (val > 0xfffffff || val < 0) { - writeBigVarint(val, this); - return; - } + return baseIsNative(value); + } + /** + * Checks if `value` is `null`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `null`, else `false`. + * @example + * + * _.isNull(null); + * // => true + * + * _.isNull(void 0); + * // => false + */ - this.realloc(4); - this.buf[this.pos++] = val & 0x7f | (val > 0x7f ? 0x80 : 0); - if (val <= 0x7f) return; - this.buf[this.pos++] = (val >>>= 7) & 0x7f | (val > 0x7f ? 0x80 : 0); - if (val <= 0x7f) return; - this.buf[this.pos++] = (val >>>= 7) & 0x7f | (val > 0x7f ? 0x80 : 0); - if (val <= 0x7f) return; - this.buf[this.pos++] = val >>> 7 & 0x7f; - }, - writeSVarint: function writeSVarint(val) { - this.writeVarint(val < 0 ? -val * 2 - 1 : val * 2); - }, - writeBoolean: function writeBoolean(val) { - this.writeVarint(Boolean(val)); - }, - writeString: function writeString(str) { - str = String(str); - this.realloc(str.length * 4); - this.pos++; // reserve 1 byte for short string length - var startPos = this.pos; // write the string directly to the buffer and see how much was written + function isNull(value) { + return value === null; + } + /** + * Checks if `value` is `null` or `undefined`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is nullish, else `false`. + * @example + * + * _.isNil(null); + * // => true + * + * _.isNil(void 0); + * // => true + * + * _.isNil(NaN); + * // => false + */ - this.pos = writeUtf8(this.buf, str, this.pos); - var len = this.pos - startPos; - if (len >= 0x80) makeRoomForExtraLength(startPos, len, this); // finally, write the message length in the reserved place and restore the position - this.pos = startPos - 1; - this.writeVarint(len); - this.pos += len; - }, - writeFloat: function writeFloat(val) { - this.realloc(4); - ieee754.write(this.buf, val, this.pos, true, 23, 4); - this.pos += 4; - }, - writeDouble: function writeDouble(val) { - this.realloc(8); - ieee754.write(this.buf, val, this.pos, true, 52, 8); - this.pos += 8; - }, - writeBytes: function writeBytes(buffer) { - var len = buffer.length; - this.writeVarint(len); - this.realloc(len); + function isNil(value) { + return value == null; + } + /** + * Checks if `value` is classified as a `Number` primitive or object. + * + * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are + * classified as numbers, use the `_.isFinite` method. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a number, else `false`. + * @example + * + * _.isNumber(3); + * // => true + * + * _.isNumber(Number.MIN_VALUE); + * // => true + * + * _.isNumber(Infinity); + * // => true + * + * _.isNumber('3'); + * // => false + */ - for (var i = 0; i < len; i++) { - this.buf[this.pos++] = buffer[i]; - } - }, - writeRawMessage: function writeRawMessage(fn, obj) { - this.pos++; // reserve 1 byte for short message length - // write the message directly to the buffer and see how much was written - var startPos = this.pos; - fn(obj, this); - var len = this.pos - startPos; - if (len >= 0x80) makeRoomForExtraLength(startPos, len, this); // finally, write the message length in the reserved place and restore the position + function isNumber(value) { + return typeof value == 'number' || isObjectLike(value) && baseGetTag(value) == numberTag; + } + /** + * Checks if `value` is a plain object, that is, an object created by the + * `Object` constructor or one with a `[[Prototype]]` of `null`. + * + * @static + * @memberOf _ + * @since 0.8.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * _.isPlainObject(new Foo); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'x': 0, 'y': 0 }); + * // => true + * + * _.isPlainObject(Object.create(null)); + * // => true + */ - this.pos = startPos - 1; - this.writeVarint(len); - this.pos += len; - }, - writeMessage: function writeMessage(tag, fn, obj) { - this.writeTag(tag, Pbf.Bytes); - this.writeRawMessage(fn, obj); - }, - writePackedVarint: function writePackedVarint(tag, arr) { - if (arr.length) this.writeMessage(tag, _writePackedVarint, arr); - }, - writePackedSVarint: function writePackedSVarint(tag, arr) { - if (arr.length) this.writeMessage(tag, _writePackedSVarint, arr); - }, - writePackedBoolean: function writePackedBoolean(tag, arr) { - if (arr.length) this.writeMessage(tag, _writePackedBoolean, arr); - }, - writePackedFloat: function writePackedFloat(tag, arr) { - if (arr.length) this.writeMessage(tag, _writePackedFloat, arr); - }, - writePackedDouble: function writePackedDouble(tag, arr) { - if (arr.length) this.writeMessage(tag, _writePackedDouble, arr); - }, - writePackedFixed32: function writePackedFixed32(tag, arr) { - if (arr.length) this.writeMessage(tag, _writePackedFixed, arr); - }, - writePackedSFixed32: function writePackedSFixed32(tag, arr) { - if (arr.length) this.writeMessage(tag, _writePackedSFixed, arr); - }, - writePackedFixed64: function writePackedFixed64(tag, arr) { - if (arr.length) this.writeMessage(tag, _writePackedFixed2, arr); - }, - writePackedSFixed64: function writePackedSFixed64(tag, arr) { - if (arr.length) this.writeMessage(tag, _writePackedSFixed2, arr); - }, - writeBytesField: function writeBytesField(tag, buffer) { - this.writeTag(tag, Pbf.Bytes); - this.writeBytes(buffer); - }, - writeFixed32Field: function writeFixed32Field(tag, val) { - this.writeTag(tag, Pbf.Fixed32); - this.writeFixed32(val); - }, - writeSFixed32Field: function writeSFixed32Field(tag, val) { - this.writeTag(tag, Pbf.Fixed32); - this.writeSFixed32(val); - }, - writeFixed64Field: function writeFixed64Field(tag, val) { - this.writeTag(tag, Pbf.Fixed64); - this.writeFixed64(val); - }, - writeSFixed64Field: function writeSFixed64Field(tag, val) { - this.writeTag(tag, Pbf.Fixed64); - this.writeSFixed64(val); - }, - writeVarintField: function writeVarintField(tag, val) { - this.writeTag(tag, Pbf.Varint); - this.writeVarint(val); - }, - writeSVarintField: function writeSVarintField(tag, val) { - this.writeTag(tag, Pbf.Varint); - this.writeSVarint(val); - }, - writeStringField: function writeStringField(tag, str) { - this.writeTag(tag, Pbf.Bytes); - this.writeString(str); - }, - writeFloatField: function writeFloatField(tag, val) { - this.writeTag(tag, Pbf.Fixed32); - this.writeFloat(val); - }, - writeDoubleField: function writeDoubleField(tag, val) { - this.writeTag(tag, Pbf.Fixed64); - this.writeDouble(val); - }, - writeBooleanField: function writeBooleanField(tag, val) { - this.writeVarintField(tag, Boolean(val)); - } - }; - - function readVarintRemainder(l, s, p) { - var buf = p.buf, - h, - b; - b = buf[p.pos++]; - h = (b & 0x70) >> 4; - if (b < 0x80) return toNum(l, h, s); - b = buf[p.pos++]; - h |= (b & 0x7f) << 3; - if (b < 0x80) return toNum(l, h, s); - b = buf[p.pos++]; - h |= (b & 0x7f) << 10; - if (b < 0x80) return toNum(l, h, s); - b = buf[p.pos++]; - h |= (b & 0x7f) << 17; - if (b < 0x80) return toNum(l, h, s); - b = buf[p.pos++]; - h |= (b & 0x7f) << 24; - if (b < 0x80) return toNum(l, h, s); - b = buf[p.pos++]; - h |= (b & 0x01) << 31; - if (b < 0x80) return toNum(l, h, s); - throw new Error('Expected varint not more than 10 bytes'); - } - - function readPackedEnd(pbf) { - return pbf.type === Pbf.Bytes ? pbf.readVarint() + pbf.pos : pbf.pos + 1; - } - - function toNum(low, high, isSigned) { - if (isSigned) { - return high * 0x100000000 + (low >>> 0); - } - - return (high >>> 0) * 0x100000000 + (low >>> 0); - } - - function writeBigVarint(val, pbf) { - var low, high; - if (val >= 0) { - low = val % 0x100000000 | 0; - high = val / 0x100000000 | 0; - } else { - low = ~(-val % 0x100000000); - high = ~(-val / 0x100000000); + function isPlainObject(value) { + if (!isObjectLike(value) || baseGetTag(value) != objectTag) { + return false; + } - if (low ^ 0xffffffff) { - low = low + 1 | 0; - } else { - low = 0; - high = high + 1 | 0; - } - } + var proto = getPrototype(value); - if (val >= 0x10000000000000000 || val < -0x10000000000000000) { - throw new Error('Given varint doesn\'t fit into 10 bytes'); - } + if (proto === null) { + return true; + } - pbf.realloc(10); - writeBigVarintLow(low, high, pbf); - writeBigVarintHigh(high, pbf); - } + var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor; + return typeof Ctor == 'function' && Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString; + } + /** + * Checks if `value` is classified as a `RegExp` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a regexp, else `false`. + * @example + * + * _.isRegExp(/abc/); + * // => true + * + * _.isRegExp('/abc/'); + * // => false + */ - function writeBigVarintLow(low, high, pbf) { - pbf.buf[pbf.pos++] = low & 0x7f | 0x80; - low >>>= 7; - pbf.buf[pbf.pos++] = low & 0x7f | 0x80; - low >>>= 7; - pbf.buf[pbf.pos++] = low & 0x7f | 0x80; - low >>>= 7; - pbf.buf[pbf.pos++] = low & 0x7f | 0x80; - low >>>= 7; - pbf.buf[pbf.pos] = low & 0x7f; - } - function writeBigVarintHigh(high, pbf) { - var lsb = (high & 0x07) << 4; - pbf.buf[pbf.pos++] |= lsb | ((high >>>= 3) ? 0x80 : 0); - if (!high) return; - pbf.buf[pbf.pos++] = high & 0x7f | ((high >>>= 7) ? 0x80 : 0); - if (!high) return; - pbf.buf[pbf.pos++] = high & 0x7f | ((high >>>= 7) ? 0x80 : 0); - if (!high) return; - pbf.buf[pbf.pos++] = high & 0x7f | ((high >>>= 7) ? 0x80 : 0); - if (!high) return; - pbf.buf[pbf.pos++] = high & 0x7f | ((high >>>= 7) ? 0x80 : 0); - if (!high) return; - pbf.buf[pbf.pos++] = high & 0x7f; - } + var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp; + /** + * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754 + * double precision number which isn't the result of a rounded unsafe integer. + * + * **Note:** This method is based on + * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`. + * @example + * + * _.isSafeInteger(3); + * // => true + * + * _.isSafeInteger(Number.MIN_VALUE); + * // => false + * + * _.isSafeInteger(Infinity); + * // => false + * + * _.isSafeInteger('3'); + * // => false + */ - function makeRoomForExtraLength(startPos, len, pbf) { - var extraLen = len <= 0x3fff ? 1 : len <= 0x1fffff ? 2 : len <= 0xfffffff ? 3 : Math.floor(Math.log(len) / (Math.LN2 * 7)); // if 1 byte isn't enough for encoding message length, shift the data to the right + function isSafeInteger(value) { + return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER; + } + /** + * Checks if `value` is classified as a `Set` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + * @example + * + * _.isSet(new Set); + * // => true + * + * _.isSet(new WeakSet); + * // => false + */ - pbf.realloc(extraLen); - for (var i = pbf.pos - 1; i >= startPos; i--) { - pbf.buf[i + extraLen] = pbf.buf[i]; - } - } + var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet; + /** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a string, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ - function _writePackedVarint(arr, pbf) { - for (var i = 0; i < arr.length; i++) { - pbf.writeVarint(arr[i]); - } - } + function isString(value) { + return typeof value == 'string' || !isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag; + } + /** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ - function _writePackedSVarint(arr, pbf) { - for (var i = 0; i < arr.length; i++) { - pbf.writeSVarint(arr[i]); - } - } - function _writePackedFloat(arr, pbf) { - for (var i = 0; i < arr.length; i++) { - pbf.writeFloat(arr[i]); - } - } + function isSymbol(value) { + return _typeof(value) == 'symbol' || isObjectLike(value) && baseGetTag(value) == symbolTag; + } + /** + * Checks if `value` is classified as a typed array. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. + * @example + * + * _.isTypedArray(new Uint8Array); + * // => true + * + * _.isTypedArray([]); + * // => false + */ - function _writePackedDouble(arr, pbf) { - for (var i = 0; i < arr.length; i++) { - pbf.writeDouble(arr[i]); - } - } - function _writePackedBoolean(arr, pbf) { - for (var i = 0; i < arr.length; i++) { - pbf.writeBoolean(arr[i]); - } - } + var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray; + /** + * Checks if `value` is `undefined`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + * + * _.isUndefined(null); + * // => false + */ - function _writePackedFixed(arr, pbf) { - for (var i = 0; i < arr.length; i++) { - pbf.writeFixed32(arr[i]); - } - } + function isUndefined(value) { + return value === undefined$1; + } + /** + * Checks if `value` is classified as a `WeakMap` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a weak map, else `false`. + * @example + * + * _.isWeakMap(new WeakMap); + * // => true + * + * _.isWeakMap(new Map); + * // => false + */ - function _writePackedSFixed(arr, pbf) { - for (var i = 0; i < arr.length; i++) { - pbf.writeSFixed32(arr[i]); - } - } - function _writePackedFixed2(arr, pbf) { - for (var i = 0; i < arr.length; i++) { - pbf.writeFixed64(arr[i]); - } - } + function isWeakMap(value) { + return isObjectLike(value) && getTag(value) == weakMapTag; + } + /** + * Checks if `value` is classified as a `WeakSet` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a weak set, else `false`. + * @example + * + * _.isWeakSet(new WeakSet); + * // => true + * + * _.isWeakSet(new Set); + * // => false + */ - function _writePackedSFixed2(arr, pbf) { - for (var i = 0; i < arr.length; i++) { - pbf.writeSFixed64(arr[i]); - } - } // Buffer code below from https://github.com/feross/buffer, MIT-licensed + function isWeakSet(value) { + return isObjectLike(value) && baseGetTag(value) == weakSetTag; + } + /** + * Checks if `value` is less than `other`. + * + * @static + * @memberOf _ + * @since 3.9.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than `other`, + * else `false`. + * @see _.gt + * @example + * + * _.lt(1, 3); + * // => true + * + * _.lt(3, 3); + * // => false + * + * _.lt(3, 1); + * // => false + */ - function readUInt32(buf, pos) { - return (buf[pos] | buf[pos + 1] << 8 | buf[pos + 2] << 16) + buf[pos + 3] * 0x1000000; - } - function writeInt32(buf, val, pos) { - buf[pos] = val; - buf[pos + 1] = val >>> 8; - buf[pos + 2] = val >>> 16; - buf[pos + 3] = val >>> 24; - } + var lt = createRelationalOperation(baseLt); + /** + * Checks if `value` is less than or equal to `other`. + * + * @static + * @memberOf _ + * @since 3.9.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than or equal to + * `other`, else `false`. + * @see _.gte + * @example + * + * _.lte(1, 3); + * // => true + * + * _.lte(3, 3); + * // => true + * + * _.lte(3, 1); + * // => false + */ - function readInt32(buf, pos) { - return (buf[pos] | buf[pos + 1] << 8 | buf[pos + 2] << 16) + (buf[pos + 3] << 24); - } + var lte = createRelationalOperation(function (value, other) { + return value <= other; + }); + /** + * Converts `value` to an array. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to convert. + * @returns {Array} Returns the converted array. + * @example + * + * _.toArray({ 'a': 1, 'b': 2 }); + * // => [1, 2] + * + * _.toArray('abc'); + * // => ['a', 'b', 'c'] + * + * _.toArray(1); + * // => [] + * + * _.toArray(null); + * // => [] + */ - function readUtf8(buf, pos, end) { - var str = ''; - var i = pos; + function toArray(value) { + if (!value) { + return []; + } - while (i < end) { - var b0 = buf[i]; - var c = null; // codepoint + if (isArrayLike(value)) { + return isString(value) ? stringToArray(value) : copyArray(value); + } - var bytesPerSequence = b0 > 0xEF ? 4 : b0 > 0xDF ? 3 : b0 > 0xBF ? 2 : 1; - if (i + bytesPerSequence > end) break; - var b1, b2, b3; + if (symIterator && value[symIterator]) { + return iteratorToArray(value[symIterator]()); + } - if (bytesPerSequence === 1) { - if (b0 < 0x80) { - c = b0; + var tag = getTag(value), + func = tag == mapTag ? mapToArray : tag == setTag ? setToArray : values; + return func(value); } - } else if (bytesPerSequence === 2) { - b1 = buf[i + 1]; + /** + * Converts `value` to a finite number. + * + * @static + * @memberOf _ + * @since 4.12.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted number. + * @example + * + * _.toFinite(3.2); + * // => 3.2 + * + * _.toFinite(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toFinite(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toFinite('3.2'); + * // => 3.2 + */ - if ((b1 & 0xC0) === 0x80) { - c = (b0 & 0x1F) << 0x6 | b1 & 0x3F; - if (c <= 0x7F) { - c = null; + function toFinite(value) { + if (!value) { + return value === 0 ? value : 0; } - } - } else if (bytesPerSequence === 3) { - b1 = buf[i + 1]; - b2 = buf[i + 2]; - if ((b1 & 0xC0) === 0x80 && (b2 & 0xC0) === 0x80) { - c = (b0 & 0xF) << 0xC | (b1 & 0x3F) << 0x6 | b2 & 0x3F; + value = toNumber(value); - if (c <= 0x7FF || c >= 0xD800 && c <= 0xDFFF) { - c = null; + if (value === INFINITY || value === -INFINITY) { + var sign = value < 0 ? -1 : 1; + return sign * MAX_INTEGER; } + + return value === value ? value : 0; } - } else if (bytesPerSequence === 4) { - b1 = buf[i + 1]; - b2 = buf[i + 2]; - b3 = buf[i + 3]; + /** + * Converts `value` to an integer. + * + * **Note:** This method is loosely based on + * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toInteger(3.2); + * // => 3 + * + * _.toInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toInteger(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toInteger('3.2'); + * // => 3 + */ - if ((b1 & 0xC0) === 0x80 && (b2 & 0xC0) === 0x80 && (b3 & 0xC0) === 0x80) { - c = (b0 & 0xF) << 0x12 | (b1 & 0x3F) << 0xC | (b2 & 0x3F) << 0x6 | b3 & 0x3F; - if (c <= 0xFFFF || c >= 0x110000) { - c = null; - } + function toInteger(value) { + var result = toFinite(value), + remainder = result % 1; + return result === result ? remainder ? result - remainder : result : 0; } - } + /** + * Converts `value` to an integer suitable for use as the length of an + * array-like object. + * + * **Note:** This method is based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toLength(3.2); + * // => 3 + * + * _.toLength(Number.MIN_VALUE); + * // => 0 + * + * _.toLength(Infinity); + * // => 4294967295 + * + * _.toLength('3.2'); + * // => 3 + */ - if (c === null) { - c = 0xFFFD; - bytesPerSequence = 1; - } else if (c > 0xFFFF) { - c -= 0x10000; - str += String.fromCharCode(c >>> 10 & 0x3FF | 0xD800); - c = 0xDC00 | c & 0x3FF; - } - str += String.fromCharCode(c); - i += bytesPerSequence; - } + function toLength(value) { + return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0; + } + /** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3.2); + * // => 3.2 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3.2'); + * // => 3.2 + */ - return str; - } - function readUtf8TextDecoder(buf, pos, end) { - return utf8TextDecoder.decode(buf.subarray(pos, end)); - } + function toNumber(value) { + if (typeof value == 'number') { + return value; + } - function writeUtf8(buf, str, pos) { - for (var i = 0, c, lead; i < str.length; i++) { - c = str.charCodeAt(i); // code point + if (isSymbol(value)) { + return NAN; + } - if (c > 0xD7FF && c < 0xE000) { - if (lead) { - if (c < 0xDC00) { - buf[pos++] = 0xEF; - buf[pos++] = 0xBF; - buf[pos++] = 0xBD; - lead = c; - continue; - } else { - c = lead - 0xD800 << 10 | c - 0xDC00 | 0x10000; - lead = null; + if (isObject(value)) { + var other = typeof value.valueOf == 'function' ? value.valueOf() : value; + value = isObject(other) ? other + '' : other; } - } else { - if (c > 0xDBFF || i + 1 === str.length) { - buf[pos++] = 0xEF; - buf[pos++] = 0xBF; - buf[pos++] = 0xBD; - } else { - lead = c; + + if (typeof value != 'string') { + return value === 0 ? value : +value; } - continue; + value = baseTrim(value); + var isBinary = reIsBinary.test(value); + return isBinary || reIsOctal.test(value) ? freeParseInt(value.slice(2), isBinary ? 2 : 8) : reIsBadHex.test(value) ? NAN : +value; } - } else if (lead) { - buf[pos++] = 0xEF; - buf[pos++] = 0xBF; - buf[pos++] = 0xBD; - lead = null; - } + /** + * Converts `value` to a plain object flattening inherited enumerable string + * keyed properties of `value` to own properties of the plain object. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {Object} Returns the converted plain object. + * @example + * + * function Foo() { + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.assign({ 'a': 1 }, new Foo); + * // => { 'a': 1, 'b': 2 } + * + * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); + * // => { 'a': 1, 'b': 2, 'c': 3 } + */ - if (c < 0x80) { - buf[pos++] = c; - } else { - if (c < 0x800) { - buf[pos++] = c >> 0x6 | 0xC0; - } else { - if (c < 0x10000) { - buf[pos++] = c >> 0xC | 0xE0; - } else { - buf[pos++] = c >> 0x12 | 0xF0; - buf[pos++] = c >> 0xC & 0x3F | 0x80; - } - buf[pos++] = c >> 0x6 & 0x3F | 0x80; + function toPlainObject(value) { + return copyObject(value, keysIn(value)); } + /** + * Converts `value` to a safe integer. A safe integer can be compared and + * represented correctly. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toSafeInteger(3.2); + * // => 3 + * + * _.toSafeInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toSafeInteger(Infinity); + * // => 9007199254740991 + * + * _.toSafeInteger('3.2'); + * // => 3 + */ - buf[pos++] = c & 0x3F | 0x80; - } - } - return pos; - } + function toSafeInteger(value) { + return value ? baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER) : value === 0 ? value : 0; + } + /** + * Converts `value` to a string. An empty string is returned for `null` + * and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ - var vectorTile = {}; - var pointGeometry = Point$1; - /** - * A standalone point geometry with useful accessor, comparison, and - * modification methods. - * - * @class Point - * @param {Number} x the x-coordinate. this could be longitude or screen - * pixels, or any other sort of unit. - * @param {Number} y the y-coordinate. this could be latitude or screen - * pixels, or any other sort of unit. - * @example - * var point = new Point(-77, 38); - */ + function toString(value) { + return value == null ? '' : baseToString(value); + } + /*------------------------------------------------------------------------*/ - function Point$1(x, y) { - this.x = x; - this.y = y; - } + /** + * Assigns own enumerable string keyed properties of source objects to the + * destination object. Source objects are applied from left to right. + * Subsequent sources overwrite property assignments of previous sources. + * + * **Note:** This method mutates `object` and is loosely based on + * [`Object.assign`](https://mdn.io/Object/assign). + * + * @static + * @memberOf _ + * @since 0.10.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.assignIn + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * function Bar() { + * this.c = 3; + * } + * + * Foo.prototype.b = 2; + * Bar.prototype.d = 4; + * + * _.assign({ 'a': 0 }, new Foo, new Bar); + * // => { 'a': 1, 'c': 3 } + */ - Point$1.prototype = { - /** - * Clone this point, returning a new point that can be modified - * without affecting the old one. - * @return {Point} the clone - */ - clone: function clone() { - return new Point$1(this.x, this.y); - }, - /** - * Add this point's x & y coordinates to another point, - * yielding a new point. - * @param {Point} p the other point - * @return {Point} output point - */ - add: function add(p) { - return this.clone()._add(p); - }, + var assign = createAssigner(function (object, source) { + if (isPrototype(source) || isArrayLike(source)) { + copyObject(source, keys(source), object); + return; + } - /** - * Subtract this point's x & y coordinates to from point, - * yielding a new point. - * @param {Point} p the other point - * @return {Point} output point - */ - sub: function sub(p) { - return this.clone()._sub(p); - }, - - /** - * Multiply this point's x & y coordinates by point, - * yielding a new point. - * @param {Point} p the other point - * @return {Point} output point - */ - multByPoint: function multByPoint(p) { - return this.clone()._multByPoint(p); - }, + for (var key in source) { + if (hasOwnProperty.call(source, key)) { + assignValue(object, key, source[key]); + } + } + }); + /** + * This method is like `_.assign` except that it iterates over own and + * inherited source properties. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @alias extend + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.assign + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * function Bar() { + * this.c = 3; + * } + * + * Foo.prototype.b = 2; + * Bar.prototype.d = 4; + * + * _.assignIn({ 'a': 0 }, new Foo, new Bar); + * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 } + */ - /** - * Divide this point's x & y coordinates by point, - * yielding a new point. - * @param {Point} p the other point - * @return {Point} output point - */ - divByPoint: function divByPoint(p) { - return this.clone()._divByPoint(p); - }, + var assignIn = createAssigner(function (object, source) { + copyObject(source, keysIn(source), object); + }); + /** + * This method is like `_.assignIn` except that it accepts `customizer` + * which is invoked to produce the assigned values. If `customizer` returns + * `undefined`, assignment is handled by the method instead. The `customizer` + * is invoked with five arguments: (objValue, srcValue, key, object, source). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @alias extendWith + * @category Object + * @param {Object} object The destination object. + * @param {...Object} sources The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @see _.assignWith + * @example + * + * function customizer(objValue, srcValue) { + * return _.isUndefined(objValue) ? srcValue : objValue; + * } + * + * var defaults = _.partialRight(_.assignInWith, customizer); + * + * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ - /** - * Multiply this point's x & y coordinates by a factor, - * yielding a new point. - * @param {Point} k factor - * @return {Point} output point - */ - mult: function mult(k) { - return this.clone()._mult(k); - }, + var assignInWith = createAssigner(function (object, source, srcIndex, customizer) { + copyObject(source, keysIn(source), object, customizer); + }); + /** + * This method is like `_.assign` except that it accepts `customizer` + * which is invoked to produce the assigned values. If `customizer` returns + * `undefined`, assignment is handled by the method instead. The `customizer` + * is invoked with five arguments: (objValue, srcValue, key, object, source). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} sources The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @see _.assignInWith + * @example + * + * function customizer(objValue, srcValue) { + * return _.isUndefined(objValue) ? srcValue : objValue; + * } + * + * var defaults = _.partialRight(_.assignWith, customizer); + * + * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ - /** - * Divide this point's x & y coordinates by a factor, - * yielding a new point. - * @param {Point} k factor - * @return {Point} output point - */ - div: function div(k) { - return this.clone()._div(k); - }, + var assignWith = createAssigner(function (object, source, srcIndex, customizer) { + copyObject(source, keys(source), object, customizer); + }); + /** + * Creates an array of values corresponding to `paths` of `object`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {...(string|string[])} [paths] The property paths to pick. + * @returns {Array} Returns the picked values. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] }; + * + * _.at(object, ['a[0].b.c', 'a[1]']); + * // => [3, 4] + */ - /** - * Rotate this point around the 0, 0 origin by an angle a, - * given in radians - * @param {Number} a angle to rotate around, in radians - * @return {Point} output point - */ - rotate: function rotate(a) { - return this.clone()._rotate(a); - }, + var at = flatRest(baseAt); + /** + * Creates an object that inherits from the `prototype` object. If a + * `properties` object is given, its own enumerable string keyed properties + * are assigned to the created object. + * + * @static + * @memberOf _ + * @since 2.3.0 + * @category Object + * @param {Object} prototype The object to inherit from. + * @param {Object} [properties] The properties to assign to the object. + * @returns {Object} Returns the new object. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * function Circle() { + * Shape.call(this); + * } + * + * Circle.prototype = _.create(Shape.prototype, { + * 'constructor': Circle + * }); + * + * var circle = new Circle; + * circle instanceof Circle; + * // => true + * + * circle instanceof Shape; + * // => true + */ - /** - * Rotate this point around p point by an angle a, - * given in radians - * @param {Number} a angle to rotate around, in radians - * @param {Point} p Point to rotate around - * @return {Point} output point - */ - rotateAround: function rotateAround(a, p) { - return this.clone()._rotateAround(a, p); - }, + function create(prototype, properties) { + var result = baseCreate(prototype); + return properties == null ? result : baseAssign(result, properties); + } + /** + * Assigns own and inherited enumerable string keyed properties of source + * objects to the destination object for all destination properties that + * resolve to `undefined`. Source objects are applied from left to right. + * Once a property is set, additional values of the same property are ignored. + * + * **Note:** This method mutates `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.defaultsDeep + * @example + * + * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ - /** - * Multiply this point by a 4x1 transformation matrix - * @param {Array} m transformation matrix - * @return {Point} output point - */ - matMult: function matMult(m) { - return this.clone()._matMult(m); - }, - /** - * Calculate this point but as a unit vector from 0, 0, meaning - * that the distance from the resulting point to the 0, 0 - * coordinate will be equal to 1 and the angle from the resulting - * point to the 0, 0 coordinate will be the same as before. - * @return {Point} unit vector point - */ - unit: function unit() { - return this.clone()._unit(); - }, + var defaults = baseRest(function (object, sources) { + object = Object(object); + var index = -1; + var length = sources.length; + var guard = length > 2 ? sources[2] : undefined$1; - /** - * Compute a perpendicular point, where the new y coordinate - * is the old x coordinate and the new x coordinate is the old y - * coordinate multiplied by -1 - * @return {Point} perpendicular point - */ - perp: function perp() { - return this.clone()._perp(); - }, + if (guard && isIterateeCall(sources[0], sources[1], guard)) { + length = 1; + } - /** - * Return a version of this point with the x & y coordinates - * rounded to integers. - * @return {Point} rounded point - */ - round: function round() { - return this.clone()._round(); - }, + while (++index < length) { + var source = sources[index]; + var props = keysIn(source); + var propsIndex = -1; + var propsLength = props.length; - /** - * Return the magitude of this point: this is the Euclidean - * distance from the 0, 0 coordinate to this point's x and y - * coordinates. - * @return {Number} magnitude - */ - mag: function mag() { - return Math.sqrt(this.x * this.x + this.y * this.y); - }, + while (++propsIndex < propsLength) { + var key = props[propsIndex]; + var value = object[key]; - /** - * Judge whether this point is equal to another point, returning - * true or false. - * @param {Point} other the other point - * @return {boolean} whether the points are equal - */ - equals: function equals(other) { - return this.x === other.x && this.y === other.y; - }, + if (value === undefined$1 || eq(value, objectProto[key]) && !hasOwnProperty.call(object, key)) { + object[key] = source[key]; + } + } + } - /** - * Calculate the distance from this point to another point - * @param {Point} p the other point - * @return {Number} distance - */ - dist: function dist(p) { - return Math.sqrt(this.distSqr(p)); - }, + return object; + }); + /** + * This method is like `_.defaults` except that it recursively assigns + * default properties. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 3.10.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.defaults + * @example + * + * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } }); + * // => { 'a': { 'b': 2, 'c': 3 } } + */ - /** - * Calculate the distance from this point to another point, - * without the square root step. Useful if you're comparing - * relative distances. - * @param {Point} p the other point - * @return {Number} distance - */ - distSqr: function distSqr(p) { - var dx = p.x - this.x, - dy = p.y - this.y; - return dx * dx + dy * dy; - }, + var defaultsDeep = baseRest(function (args) { + args.push(undefined$1, customDefaultsMerge); + return apply(mergeWith, undefined$1, args); + }); + /** + * This method is like `_.find` except that it returns the key of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category Object + * @param {Object} object The object to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {string|undefined} Returns the key of the matched element, + * else `undefined`. + * @example + * + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; + * + * _.findKey(users, function(o) { return o.age < 40; }); + * // => 'barney' (iteration order is not guaranteed) + * + * // The `_.matches` iteratee shorthand. + * _.findKey(users, { 'age': 1, 'active': true }); + * // => 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findKey(users, ['active', false]); + * // => 'fred' + * + * // The `_.property` iteratee shorthand. + * _.findKey(users, 'active'); + * // => 'barney' + */ - /** - * Get the angle from the 0, 0 coordinate to this point, in radians - * coordinates. - * @return {Number} angle - */ - angle: function angle() { - return Math.atan2(this.y, this.x); - }, + function findKey(object, predicate) { + return baseFindKey(object, getIteratee(predicate, 3), baseForOwn); + } + /** + * This method is like `_.findKey` except that it iterates over elements of + * a collection in the opposite order. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Object + * @param {Object} object The object to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {string|undefined} Returns the key of the matched element, + * else `undefined`. + * @example + * + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; + * + * _.findLastKey(users, function(o) { return o.age < 40; }); + * // => returns 'pebbles' assuming `_.findKey` returns 'barney' + * + * // The `_.matches` iteratee shorthand. + * _.findLastKey(users, { 'age': 36, 'active': true }); + * // => 'barney' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findLastKey(users, ['active', false]); + * // => 'fred' + * + * // The `_.property` iteratee shorthand. + * _.findLastKey(users, 'active'); + * // => 'pebbles' + */ - /** - * Get the angle from this point to another point, in radians - * @param {Point} b the other point - * @return {Number} angle - */ - angleTo: function angleTo(b) { - return Math.atan2(this.y - b.y, this.x - b.x); - }, - /** - * Get the angle between this point and another point, in radians - * @param {Point} b the other point - * @return {Number} angle - */ - angleWith: function angleWith(b) { - return this.angleWithSep(b.x, b.y); - }, + function findLastKey(object, predicate) { + return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight); + } + /** + * Iterates over own and inherited enumerable string keyed properties of an + * object and invokes `iteratee` for each property. The iteratee is invoked + * with three arguments: (value, key, object). Iteratee functions may exit + * iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forInRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forIn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed). + */ - /* - * Find the angle of the two vectors, solving the formula for - * the cross product a x b = |a||b|sin(θ) for θ. - * @param {Number} x the x-coordinate - * @param {Number} y the y-coordinate - * @return {Number} the angle in radians - */ - angleWithSep: function angleWithSep(x, y) { - return Math.atan2(this.x * y - this.y * x, this.x * x + this.y * y); - }, - _matMult: function _matMult(m) { - var x = m[0] * this.x + m[1] * this.y, - y = m[2] * this.x + m[3] * this.y; - this.x = x; - this.y = y; - return this; - }, - _add: function _add(p) { - this.x += p.x; - this.y += p.y; - return this; - }, - _sub: function _sub(p) { - this.x -= p.x; - this.y -= p.y; - return this; - }, - _mult: function _mult(k) { - this.x *= k; - this.y *= k; - return this; - }, - _div: function _div(k) { - this.x /= k; - this.y /= k; - return this; - }, - _multByPoint: function _multByPoint(p) { - this.x *= p.x; - this.y *= p.y; - return this; - }, - _divByPoint: function _divByPoint(p) { - this.x /= p.x; - this.y /= p.y; - return this; - }, - _unit: function _unit() { - this._div(this.mag()); - return this; - }, - _perp: function _perp() { - var y = this.y; - this.y = this.x; - this.x = -y; - return this; - }, - _rotate: function _rotate(angle) { - var cos = Math.cos(angle), - sin = Math.sin(angle), - x = cos * this.x - sin * this.y, - y = sin * this.x + cos * this.y; - this.x = x; - this.y = y; - return this; - }, - _rotateAround: function _rotateAround(angle, p) { - var cos = Math.cos(angle), - sin = Math.sin(angle), - x = p.x + cos * (this.x - p.x) - sin * (this.y - p.y), - y = p.y + sin * (this.x - p.x) + cos * (this.y - p.y); - this.x = x; - this.y = y; - return this; - }, - _round: function _round() { - this.x = Math.round(this.x); - this.y = Math.round(this.y); - return this; - } - }; - /** - * Construct a point from an array if necessary, otherwise if the input - * is already a Point, or an unknown type, return it unchanged - * @param {Array|Point|*} a any kind of input value - * @return {Point} constructed point, or passed-through value. - * @example - * // this - * var point = Point.convert([0, 1]); - * // is equivalent to - * var point = new Point(0, 1); - */ + function forIn(object, iteratee) { + return object == null ? object : baseFor(object, getIteratee(iteratee, 3), keysIn); + } + /** + * This method is like `_.forIn` except that it iterates over properties of + * `object` in the opposite order. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forIn + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forInRight(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'. + */ - Point$1.convert = function (a) { - if (a instanceof Point$1) { - return a; - } - if (Array.isArray(a)) { - return new Point$1(a[0], a[1]); - } + function forInRight(object, iteratee) { + return object == null ? object : baseForRight(object, getIteratee(iteratee, 3), keysIn); + } + /** + * Iterates over own enumerable string keyed properties of an object and + * invokes `iteratee` for each property. The iteratee is invoked with three + * arguments: (value, key, object). Iteratee functions may exit iteration + * early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forOwnRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ - return a; - }; - var Point = pointGeometry; - var vectortilefeature = VectorTileFeature$1; + function forOwn(object, iteratee) { + return object && baseForOwn(object, getIteratee(iteratee, 3)); + } + /** + * This method is like `_.forOwn` except that it iterates over properties of + * `object` in the opposite order. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forOwn + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwnRight(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'. + */ - function VectorTileFeature$1(pbf, end, extent, keys, values) { - // Public - this.properties = {}; - this.extent = extent; - this.type = 0; // Private - this._pbf = pbf; - this._geometry = -1; - this._keys = keys; - this._values = values; - pbf.readFields(readFeature, this, end); - } + function forOwnRight(object, iteratee) { + return object && baseForOwnRight(object, getIteratee(iteratee, 3)); + } + /** + * Creates an array of function property names from own enumerable properties + * of `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to inspect. + * @returns {Array} Returns the function names. + * @see _.functionsIn + * @example + * + * function Foo() { + * this.a = _.constant('a'); + * this.b = _.constant('b'); + * } + * + * Foo.prototype.c = _.constant('c'); + * + * _.functions(new Foo); + * // => ['a', 'b'] + */ - function readFeature(tag, feature, pbf) { - if (tag == 1) feature.id = pbf.readVarint();else if (tag == 2) readTag(pbf, feature);else if (tag == 3) feature.type = pbf.readVarint();else if (tag == 4) feature._geometry = pbf.pos; - } - function readTag(pbf, feature) { - var end = pbf.readVarint() + pbf.pos; + function functions(object) { + return object == null ? [] : baseFunctions(object, keys(object)); + } + /** + * Creates an array of function property names from own and inherited + * enumerable properties of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to inspect. + * @returns {Array} Returns the function names. + * @see _.functions + * @example + * + * function Foo() { + * this.a = _.constant('a'); + * this.b = _.constant('b'); + * } + * + * Foo.prototype.c = _.constant('c'); + * + * _.functionsIn(new Foo); + * // => ['a', 'b', 'c'] + */ - while (pbf.pos < end) { - var key = feature._keys[pbf.readVarint()], - value = feature._values[pbf.readVarint()]; - feature.properties[key] = value; - } - } + function functionsIn(object) { + return object == null ? [] : baseFunctions(object, keysIn(object)); + } + /** + * Gets the value at `path` of `object`. If the resolved value is + * `undefined`, the `defaultValue` is returned in its place. + * + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' + */ - VectorTileFeature$1.types = ['Unknown', 'Point', 'LineString', 'Polygon']; - VectorTileFeature$1.prototype.loadGeometry = function () { - var pbf = this._pbf; - pbf.pos = this._geometry; - var end = pbf.readVarint() + pbf.pos, - cmd = 1, - length = 0, - x = 0, - y = 0, - lines = [], - line; + function get(object, path, defaultValue) { + var result = object == null ? undefined$1 : baseGet(object, path); + return result === undefined$1 ? defaultValue : result; + } + /** + * Checks if `path` is a direct property of `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = { 'a': { 'b': 2 } }; + * var other = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.has(object, 'a'); + * // => true + * + * _.has(object, 'a.b'); + * // => true + * + * _.has(object, ['a', 'b']); + * // => true + * + * _.has(other, 'a'); + * // => false + */ - while (pbf.pos < end) { - if (length <= 0) { - var cmdLen = pbf.readVarint(); - cmd = cmdLen & 0x7; - length = cmdLen >> 3; - } - length--; + function has(object, path) { + return object != null && hasPath(object, path, baseHas); + } + /** + * Checks if `path` is a direct or inherited property of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.hasIn(object, 'a'); + * // => true + * + * _.hasIn(object, 'a.b'); + * // => true + * + * _.hasIn(object, ['a', 'b']); + * // => true + * + * _.hasIn(object, 'b'); + * // => false + */ - if (cmd === 1 || cmd === 2) { - x += pbf.readSVarint(); - y += pbf.readSVarint(); - if (cmd === 1) { - // moveTo - if (line) lines.push(line); - line = []; + function hasIn(object, path) { + return object != null && hasPath(object, path, baseHasIn); } + /** + * Creates an object composed of the inverted keys and values of `object`. + * If `object` contains duplicate values, subsequent values overwrite + * property assignments of previous values. + * + * @static + * @memberOf _ + * @since 0.7.0 + * @category Object + * @param {Object} object The object to invert. + * @returns {Object} Returns the new inverted object. + * @example + * + * var object = { 'a': 1, 'b': 2, 'c': 1 }; + * + * _.invert(object); + * // => { '1': 'c', '2': 'b' } + */ - line.push(new Point(x, y)); - } else if (cmd === 7) { - // Workaround for https://github.com/mapbox/mapnik-vector-tile/issues/90 - if (line) { - line.push(line[0].clone()); // closePolygon - } - } else { - throw new Error('unknown command ' + cmd); - } - } - if (line) lines.push(line); - return lines; - }; + var invert = createInverter(function (result, value, key) { + if (value != null && typeof value.toString != 'function') { + value = nativeObjectToString.call(value); + } - VectorTileFeature$1.prototype.bbox = function () { - var pbf = this._pbf; - pbf.pos = this._geometry; - var end = pbf.readVarint() + pbf.pos, - cmd = 1, - length = 0, - x = 0, - y = 0, - x1 = Infinity, - x2 = -Infinity, - y1 = Infinity, - y2 = -Infinity; + result[value] = key; + }, constant(identity)); + /** + * This method is like `_.invert` except that the inverted object is generated + * from the results of running each element of `object` thru `iteratee`. The + * corresponding inverted value of each inverted key is an array of keys + * responsible for generating the inverted value. The iteratee is invoked + * with one argument: (value). + * + * @static + * @memberOf _ + * @since 4.1.0 + * @category Object + * @param {Object} object The object to invert. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Object} Returns the new inverted object. + * @example + * + * var object = { 'a': 1, 'b': 2, 'c': 1 }; + * + * _.invertBy(object); + * // => { '1': ['a', 'c'], '2': ['b'] } + * + * _.invertBy(object, function(value) { + * return 'group' + value; + * }); + * // => { 'group1': ['a', 'c'], 'group2': ['b'] } + */ - while (pbf.pos < end) { - if (length <= 0) { - var cmdLen = pbf.readVarint(); - cmd = cmdLen & 0x7; - length = cmdLen >> 3; - } + var invertBy = createInverter(function (result, value, key) { + if (value != null && typeof value.toString != 'function') { + value = nativeObjectToString.call(value); + } - length--; + if (hasOwnProperty.call(result, value)) { + result[value].push(key); + } else { + result[value] = [key]; + } + }, getIteratee); + /** + * Invokes the method at `path` of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the method to invoke. + * @param {...*} [args] The arguments to invoke the method with. + * @returns {*} Returns the result of the invoked method. + * @example + * + * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] }; + * + * _.invoke(object, 'a[0].b.c.slice', 1, 3); + * // => [2, 3] + */ - if (cmd === 1 || cmd === 2) { - x += pbf.readSVarint(); - y += pbf.readSVarint(); - if (x < x1) x1 = x; - if (x > x2) x2 = x; - if (y < y1) y1 = y; - if (y > y2) y2 = y; - } else if (cmd !== 7) { - throw new Error('unknown command ' + cmd); - } - } + var invoke = baseRest(baseInvoke); + /** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ - return [x1, y1, x2, y2]; - }; + function keys(object) { + return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); + } + /** + * Creates an array of the own and inherited enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keysIn(new Foo); + * // => ['a', 'b', 'c'] (iteration order is not guaranteed) + */ - VectorTileFeature$1.prototype.toGeoJSON = function (x, y, z) { - var size = this.extent * Math.pow(2, z), - x0 = this.extent * x, - y0 = this.extent * y, - coords = this.loadGeometry(), - type = VectorTileFeature$1.types[this.type], - i, - j; - function project(line) { - for (var j = 0; j < line.length; j++) { - var p = line[j], - y2 = 180 - (p.y + y0) * 360 / size; - line[j] = [(p.x + x0) * 360 / size - 180, 360 / Math.PI * Math.atan(Math.exp(y2 * Math.PI / 180)) - 90]; - } - } + function keysIn(object) { + return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object); + } + /** + * The opposite of `_.mapValues`; this method creates an object with the + * same values as `object` and keys generated by running each own enumerable + * string keyed property of `object` thru `iteratee`. The iteratee is invoked + * with three arguments: (value, key, object). + * + * @static + * @memberOf _ + * @since 3.8.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new mapped object. + * @see _.mapValues + * @example + * + * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) { + * return key + value; + * }); + * // => { 'a1': 1, 'b2': 2 } + */ - switch (this.type) { - case 1: - var points = []; - for (i = 0; i < coords.length; i++) { - points[i] = coords[i][0]; + function mapKeys(object, iteratee) { + var result = {}; + iteratee = getIteratee(iteratee, 3); + baseForOwn(object, function (value, key, object) { + baseAssignValue(result, iteratee(value, key, object), value); + }); + return result; } + /** + * Creates an object with the same keys as `object` and values generated + * by running each own enumerable string keyed property of `object` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, key, object). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new mapped object. + * @see _.mapKeys + * @example + * + * var users = { + * 'fred': { 'user': 'fred', 'age': 40 }, + * 'pebbles': { 'user': 'pebbles', 'age': 1 } + * }; + * + * _.mapValues(users, function(o) { return o.age; }); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + * + * // The `_.property` iteratee shorthand. + * _.mapValues(users, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + */ - coords = points; - project(coords); - break; - case 2: - for (i = 0; i < coords.length; i++) { - project(coords[i]); + function mapValues(object, iteratee) { + var result = {}; + iteratee = getIteratee(iteratee, 3); + baseForOwn(object, function (value, key, object) { + baseAssignValue(result, key, iteratee(value, key, object)); + }); + return result; } + /** + * This method is like `_.assign` except that it recursively merges own and + * inherited enumerable string keyed properties of source objects into the + * destination object. Source properties that resolve to `undefined` are + * skipped if a destination value exists. Array and plain object properties + * are merged recursively. Other objects and value types are overridden by + * assignment. Source objects are applied from left to right. Subsequent + * sources overwrite property assignments of previous sources. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 0.5.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * var object = { + * 'a': [{ 'b': 2 }, { 'd': 4 }] + * }; + * + * var other = { + * 'a': [{ 'c': 3 }, { 'e': 5 }] + * }; + * + * _.merge(object, other); + * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] } + */ - break; - - case 3: - coords = classifyRings(coords); - for (i = 0; i < coords.length; i++) { - for (j = 0; j < coords[i].length; j++) { - project(coords[i][j]); - } - } + var merge = createAssigner(function (object, source, srcIndex) { + baseMerge(object, source, srcIndex); + }); + /** + * This method is like `_.merge` except that it accepts `customizer` which + * is invoked to produce the merged values of the destination and source + * properties. If `customizer` returns `undefined`, merging is handled by the + * method instead. The `customizer` is invoked with six arguments: + * (objValue, srcValue, key, object, source, stack). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} sources The source objects. + * @param {Function} customizer The function to customize assigned values. + * @returns {Object} Returns `object`. + * @example + * + * function customizer(objValue, srcValue) { + * if (_.isArray(objValue)) { + * return objValue.concat(srcValue); + * } + * } + * + * var object = { 'a': [1], 'b': [2] }; + * var other = { 'a': [3], 'b': [4] }; + * + * _.mergeWith(object, other, customizer); + * // => { 'a': [1, 3], 'b': [2, 4] } + */ - break; - } + var mergeWith = createAssigner(function (object, source, srcIndex, customizer) { + baseMerge(object, source, srcIndex, customizer); + }); + /** + * The opposite of `_.pick`; this method creates an object composed of the + * own and inherited enumerable property paths of `object` that are not omitted. + * + * **Note:** This method is considerably slower than `_.pick`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {...(string|string[])} [paths] The property paths to omit. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.omit(object, ['a', 'c']); + * // => { 'b': '2' } + */ - if (coords.length === 1) { - coords = coords[0]; - } else { - type = 'Multi' + type; - } + var omit = flatRest(function (object, paths) { + var result = {}; - var result = { - type: "Feature", - geometry: { - type: type, - coordinates: coords - }, - properties: this.properties - }; + if (object == null) { + return result; + } - if ('id' in this) { - result.id = this.id; - } + var isDeep = false; + paths = arrayMap(paths, function (path) { + path = castPath(path, object); + isDeep || (isDeep = path.length > 1); + return path; + }); + copyObject(object, getAllKeysIn(object), result); - return result; - }; // classifies an array of rings into polygons with outer rings and holes + if (isDeep) { + result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone); + } + var length = paths.length; - function classifyRings(rings) { - var len = rings.length; - if (len <= 1) return [rings]; - var polygons = [], - polygon, - ccw; + while (length--) { + baseUnset(result, paths[length]); + } - for (var i = 0; i < len; i++) { - var area = signedArea(rings[i]); - if (area === 0) continue; - if (ccw === undefined) ccw = area < 0; + return result; + }); + /** + * The opposite of `_.pickBy`; this method creates an object composed of + * the own and inherited enumerable string keyed properties of `object` that + * `predicate` doesn't return truthy for. The predicate is invoked with two + * arguments: (value, key). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The source object. + * @param {Function} [predicate=_.identity] The function invoked per property. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.omitBy(object, _.isNumber); + * // => { 'b': '2' } + */ - if (ccw === area < 0) { - if (polygon) polygons.push(polygon); - polygon = [rings[i]]; - } else { - polygon.push(rings[i]); - } - } + function omitBy(object, predicate) { + return pickBy(object, negate(getIteratee(predicate))); + } + /** + * Creates an object composed of the picked `object` properties. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {...(string|string[])} [paths] The property paths to pick. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pick(object, ['a', 'c']); + * // => { 'a': 1, 'c': 3 } + */ - if (polygon) polygons.push(polygon); - return polygons; - } - function signedArea(ring) { - var sum = 0; + var pick = flatRest(function (object, paths) { + return object == null ? {} : basePick(object, paths); + }); + /** + * Creates an object composed of the `object` properties `predicate` returns + * truthy for. The predicate is invoked with two arguments: (value, key). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The source object. + * @param {Function} [predicate=_.identity] The function invoked per property. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pickBy(object, _.isNumber); + * // => { 'a': 1, 'c': 3 } + */ - for (var i = 0, len = ring.length, j = len - 1, p1, p2; i < len; j = i++) { - p1 = ring[i]; - p2 = ring[j]; - sum += (p2.x - p1.x) * (p1.y + p2.y); - } + function pickBy(object, predicate) { + if (object == null) { + return {}; + } - return sum; - } + var props = arrayMap(getAllKeysIn(object), function (prop) { + return [prop]; + }); + predicate = getIteratee(predicate); + return basePickBy(object, props, function (value, path) { + return predicate(value, path[0]); + }); + } + /** + * This method is like `_.get` except that if the resolved value is a + * function it's invoked with the `this` binding of its parent object and + * its result is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to resolve. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] }; + * + * _.result(object, 'a[0].b.c1'); + * // => 3 + * + * _.result(object, 'a[0].b.c2'); + * // => 4 + * + * _.result(object, 'a[0].b.c3', 'default'); + * // => 'default' + * + * _.result(object, 'a[0].b.c3', _.constant('default')); + * // => 'default' + */ - var VectorTileFeature = vectortilefeature; - var vectortilelayer = VectorTileLayer$1; - function VectorTileLayer$1(pbf, end) { - // Public - this.version = 1; - this.name = null; - this.extent = 4096; - this.length = 0; // Private + function result(object, path, defaultValue) { + path = castPath(path, object); + var index = -1, + length = path.length; // Ensure the loop is entered when path is empty. - this._pbf = pbf; - this._keys = []; - this._values = []; - this._features = []; - pbf.readFields(readLayer, this, end); - this.length = this._features.length; - } + if (!length) { + length = 1; + object = undefined$1; + } - function readLayer(tag, layer, pbf) { - if (tag === 15) layer.version = pbf.readVarint();else if (tag === 1) layer.name = pbf.readString();else if (tag === 5) layer.extent = pbf.readVarint();else if (tag === 2) layer._features.push(pbf.pos);else if (tag === 3) layer._keys.push(pbf.readString());else if (tag === 4) layer._values.push(readValueMessage(pbf)); - } + while (++index < length) { + var value = object == null ? undefined$1 : object[toKey(path[index])]; - function readValueMessage(pbf) { - var value = null, - end = pbf.readVarint() + pbf.pos; + if (value === undefined$1) { + index = length; + value = defaultValue; + } - while (pbf.pos < end) { - var tag = pbf.readVarint() >> 3; - value = tag === 1 ? pbf.readString() : tag === 2 ? pbf.readFloat() : tag === 3 ? pbf.readDouble() : tag === 4 ? pbf.readVarint64() : tag === 5 ? pbf.readVarint() : tag === 6 ? pbf.readSVarint() : tag === 7 ? pbf.readBoolean() : null; - } + object = isFunction(value) ? value.call(object) : value; + } - return value; - } // return feature `i` from this layer as a `VectorTileFeature` + return object; + } + /** + * Sets the value at `path` of `object`. If a portion of `path` doesn't exist, + * it's created. Arrays are created for missing index properties while objects + * are created for all other missing properties. Use `_.setWith` to customize + * `path` creation. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @returns {Object} Returns `object`. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.set(object, 'a[0].b.c', 4); + * console.log(object.a[0].b.c); + * // => 4 + * + * _.set(object, ['x', '0', 'y', 'z'], 5); + * console.log(object.x[0].y.z); + * // => 5 + */ - VectorTileLayer$1.prototype.feature = function (i) { - if (i < 0 || i >= this._features.length) throw new Error('feature index out of bounds'); - this._pbf.pos = this._features[i]; + function set(object, path, value) { + return object == null ? object : baseSet(object, path, value); + } + /** + * This method is like `_.set` except that it accepts `customizer` which is + * invoked to produce the objects of `path`. If `customizer` returns `undefined` + * path creation is handled by the method instead. The `customizer` is invoked + * with three arguments: (nsValue, key, nsObject). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @example + * + * var object = {}; + * + * _.setWith(object, '[0][1]', 'a', Object); + * // => { '0': { '1': 'a' } } + */ - var end = this._pbf.readVarint() + this._pbf.pos; - return new VectorTileFeature(this._pbf, end, this.extent, this._keys, this._values); - }; + function setWith(object, path, value, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined$1; + return object == null ? object : baseSet(object, path, value, customizer); + } + /** + * Creates an array of own enumerable string keyed-value pairs for `object` + * which can be consumed by `_.fromPairs`. If `object` is a map or set, its + * entries are returned. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @alias entries + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the key-value pairs. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.toPairs(new Foo); + * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed) + */ - var VectorTileLayer = vectortilelayer; - var vectortile = VectorTile$1; - function VectorTile$1(pbf, end) { - this.layers = pbf.readFields(readTile, {}, end); - } + var toPairs = createToPairs(keys); + /** + * Creates an array of own and inherited enumerable string keyed-value pairs + * for `object` which can be consumed by `_.fromPairs`. If `object` is a map + * or set, its entries are returned. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @alias entriesIn + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the key-value pairs. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.toPairsIn(new Foo); + * // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed) + */ - function readTile(tag, layers, pbf) { - if (tag === 3) { - var layer = new VectorTileLayer(pbf, pbf.readVarint() + pbf.pos); - if (layer.length) layers[layer.name] = layer; - } - } + var toPairsIn = createToPairs(keysIn); + /** + * An alternative to `_.reduce`; this method transforms `object` to a new + * `accumulator` object which is the result of running each of its own + * enumerable string keyed properties thru `iteratee`, with each invocation + * potentially mutating the `accumulator` object. If `accumulator` is not + * provided, a new object with the same `[[Prototype]]` will be used. The + * iteratee is invoked with four arguments: (accumulator, value, key, object). + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 1.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The custom accumulator value. + * @returns {*} Returns the accumulated value. + * @example + * + * _.transform([2, 3, 4], function(result, n) { + * result.push(n *= n); + * return n % 2 == 0; + * }, []); + * // => [4, 9] + * + * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { + * (result[value] || (result[value] = [])).push(key); + * }, {}); + * // => { '1': ['a', 'c'], '2': ['b'] } + */ - var VectorTile = vectorTile.VectorTile = vectortile; - vectorTile.VectorTileFeature = vectortilefeature; - vectorTile.VectorTileLayer = vectortilelayer; + function transform(object, iteratee, accumulator) { + var isArr = isArray(object), + isArrLike = isArr || isBuffer(object) || isTypedArray(object); + iteratee = getIteratee(iteratee, 4); - var accessToken = 'MLY|4100327730013843|5bb78b81720791946a9a7b956c57b7cf'; - var apiUrl = 'https://graph.mapillary.com/'; - var baseTileUrl = 'https://tiles.mapillary.com/maps/vtp'; - var mapFeatureTileUrl = "".concat(baseTileUrl, "/mly_map_feature_point/2/{z}/{x}/{y}?access_token=").concat(accessToken); - var tileUrl = "".concat(baseTileUrl, "/mly1_public/2/{z}/{x}/{y}?access_token=").concat(accessToken); - var trafficSignTileUrl = "".concat(baseTileUrl, "/mly_map_feature_traffic_sign/2/{z}/{x}/{y}?access_token=").concat(accessToken); - var viewercss = 'mapillary-js/mapillary.css'; - var viewerjs = 'mapillary-js/mapillary.js'; - var minZoom$1 = 14; - var dispatch$4 = dispatch$8('change', 'loadedImages', 'loadedSigns', 'loadedMapFeatures', 'bearingChanged', 'imageChanged'); + if (accumulator == null) { + var Ctor = object && object.constructor; - var _loadViewerPromise$2; + if (isArrLike) { + accumulator = isArr ? new Ctor() : []; + } else if (isObject(object)) { + accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {}; + } else { + accumulator = {}; + } + } - var _mlyActiveImage; + (isArrLike ? arrayEach : baseForOwn)(object, function (value, index, object) { + return iteratee(accumulator, value, index, object); + }); + return accumulator; + } + /** + * Removes the property at `path` of `object`. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to unset. + * @returns {boolean} Returns `true` if the property is deleted, else `false`. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 7 } }] }; + * _.unset(object, 'a[0].b.c'); + * // => true + * + * console.log(object); + * // => { 'a': [{ 'b': {} }] }; + * + * _.unset(object, ['a', '0', 'b', 'c']); + * // => true + * + * console.log(object); + * // => { 'a': [{ 'b': {} }] }; + */ - var _mlyCache; - var _mlyFallback = false; + function unset(object, path) { + return object == null ? true : baseUnset(object, path); + } + /** + * This method is like `_.set` except that accepts `updater` to produce the + * value to set. Use `_.updateWith` to customize `path` creation. The `updater` + * is invoked with one argument: (value). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.6.0 + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {Function} updater The function to produce the updated value. + * @returns {Object} Returns `object`. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.update(object, 'a[0].b.c', function(n) { return n * n; }); + * console.log(object.a[0].b.c); + * // => 9 + * + * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; }); + * console.log(object.x[0].y.z); + * // => 0 + */ - var _mlyHighlightedDetection; - var _mlyShowFeatureDetections = false; - var _mlyShowSignDetections = false; + function update(object, path, updater) { + return object == null ? object : baseUpdate(object, path, castFunction(updater)); + } + /** + * This method is like `_.update` except that it accepts `customizer` which is + * invoked to produce the objects of `path`. If `customizer` returns `undefined` + * path creation is handled by the method instead. The `customizer` is invoked + * with three arguments: (nsValue, key, nsObject). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.6.0 + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {Function} updater The function to produce the updated value. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @example + * + * var object = {}; + * + * _.updateWith(object, '[0][1]', _.constant('a'), Object); + * // => { '0': { '1': 'a' } } + */ - var _mlyViewer; - var _mlyViewerFilter = ['all']; // Load all data for the specified type from Mapillary vector tiles + function updateWith(object, path, updater, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined$1; + return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer); + } + /** + * Creates an array of the own enumerable string keyed property values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.values(new Foo); + * // => [1, 2] (iteration order is not guaranteed) + * + * _.values('hi'); + * // => ['h', 'i'] + */ - function loadTiles$2(which, url, maxZoom, projection) { - var tiler = utilTiler().zoomExtent([minZoom$1, maxZoom]).skipNullIsland(true); - var tiles = tiler.getTiles(projection); - tiles.forEach(function (tile) { - loadTile$1(which, url, tile); - }); - } // Load all data for the specified type from one vector tile + function values(object) { + return object == null ? [] : baseValues(object, keys(object)); + } + /** + * Creates an array of the own and inherited enumerable string keyed property + * values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.valuesIn(new Foo); + * // => [1, 2, 3] (iteration order is not guaranteed) + */ - function loadTile$1(which, url, tile) { - var cache = _mlyCache.requests; - var tileId = "".concat(tile.id, "-").concat(which); - if (cache.loaded[tileId] || cache.inflight[tileId]) return; - var controller = new AbortController(); - cache.inflight[tileId] = controller; - var requestUrl = url.replace('{x}', tile.xyz[0]).replace('{y}', tile.xyz[1]).replace('{z}', tile.xyz[2]); - fetch(requestUrl, { - signal: controller.signal - }).then(function (response) { - if (!response.ok) { - throw new Error(response.status + ' ' + response.statusText); - } - cache.loaded[tileId] = true; - delete cache.inflight[tileId]; - return response.arrayBuffer(); - }).then(function (data) { - if (!data) { - throw new Error('No Data'); - } + function valuesIn(object) { + return object == null ? [] : baseValues(object, keysIn(object)); + } + /*------------------------------------------------------------------------*/ - loadTileDataToCache(data, tile, which); + /** + * Clamps `number` within the inclusive `lower` and `upper` bounds. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Number + * @param {number} number The number to clamp. + * @param {number} [lower] The lower bound. + * @param {number} upper The upper bound. + * @returns {number} Returns the clamped number. + * @example + * + * _.clamp(-10, -5, 5); + * // => -5 + * + * _.clamp(10, -5, 5); + * // => 5 + */ - if (which === 'images') { - dispatch$4.call('loadedImages'); - } else if (which === 'signs') { - dispatch$4.call('loadedSigns'); - } else if (which === 'points') { - dispatch$4.call('loadedMapFeatures'); - } - })["catch"](function () { - cache.loaded[tileId] = true; - delete cache.inflight[tileId]; - }); - } // Load the data from the vector tile into cache + function clamp(number, lower, upper) { + if (upper === undefined$1) { + upper = lower; + lower = undefined$1; + } - function loadTileDataToCache(data, tile, which) { - var vectorTile = new VectorTile(new pbf(data)); - var features, cache, layer, i, feature, loc, d; + if (upper !== undefined$1) { + upper = toNumber(upper); + upper = upper === upper ? upper : 0; + } - if (vectorTile.layers.hasOwnProperty('image')) { - features = []; - cache = _mlyCache.images; - layer = vectorTile.layers.image; + if (lower !== undefined$1) { + lower = toNumber(lower); + lower = lower === lower ? lower : 0; + } - for (i = 0; i < layer.length; i++) { - feature = layer.feature(i).toGeoJSON(tile.xyz[0], tile.xyz[1], tile.xyz[2]); - loc = feature.geometry.coordinates; - d = { - loc: loc, - captured_at: feature.properties.captured_at, - ca: feature.properties.compass_angle, - id: feature.properties.id, - is_pano: feature.properties.is_pano, - sequence_id: feature.properties.sequence_id - }; - cache.forImageId[d.id] = d; - features.push({ - minX: loc[0], - minY: loc[1], - maxX: loc[0], - maxY: loc[1], - data: d - }); - } + return baseClamp(toNumber(number), lower, upper); + } + /** + * Checks if `n` is between `start` and up to, but not including, `end`. If + * `end` is not specified, it's set to `start` with `start` then set to `0`. + * If `start` is greater than `end` the params are swapped to support + * negative ranges. + * + * @static + * @memberOf _ + * @since 3.3.0 + * @category Number + * @param {number} number The number to check. + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @returns {boolean} Returns `true` if `number` is in the range, else `false`. + * @see _.range, _.rangeRight + * @example + * + * _.inRange(3, 2, 4); + * // => true + * + * _.inRange(4, 8); + * // => true + * + * _.inRange(4, 2); + * // => false + * + * _.inRange(2, 2); + * // => false + * + * _.inRange(1.2, 2); + * // => true + * + * _.inRange(5.2, 4); + * // => false + * + * _.inRange(-3, -2, -6); + * // => true + */ - if (cache.rtree) { - cache.rtree.load(features); - } - } - if (vectorTile.layers.hasOwnProperty('sequence')) { - features = []; - cache = _mlyCache.sequences; - layer = vectorTile.layers.sequence; + function inRange(number, start, end) { + start = toFinite(start); - for (i = 0; i < layer.length; i++) { - feature = layer.feature(i).toGeoJSON(tile.xyz[0], tile.xyz[1], tile.xyz[2]); + if (end === undefined$1) { + end = start; + start = 0; + } else { + end = toFinite(end); + } - if (cache.lineString[feature.properties.id]) { - cache.lineString[feature.properties.id].push(feature); - } else { - cache.lineString[feature.properties.id] = [feature]; + number = toNumber(number); + return baseInRange(number, start, end); } - } - } + /** + * Produces a random number between the inclusive `lower` and `upper` bounds. + * If only one argument is provided a number between `0` and the given number + * is returned. If `floating` is `true`, or either `lower` or `upper` are + * floats, a floating-point number is returned instead of an integer. + * + * **Note:** JavaScript follows the IEEE-754 standard for resolving + * floating-point values which can produce unexpected results. + * + * @static + * @memberOf _ + * @since 0.7.0 + * @category Number + * @param {number} [lower=0] The lower bound. + * @param {number} [upper=1] The upper bound. + * @param {boolean} [floating] Specify returning a floating-point number. + * @returns {number} Returns the random number. + * @example + * + * _.random(0, 5); + * // => an integer between 0 and 5 + * + * _.random(5); + * // => also an integer between 0 and 5 + * + * _.random(5, true); + * // => a floating-point number between 0 and 5 + * + * _.random(1.2, 5.2); + * // => a floating-point number between 1.2 and 5.2 + */ - if (vectorTile.layers.hasOwnProperty('point')) { - features = []; - cache = _mlyCache[which]; - layer = vectorTile.layers.point; - for (i = 0; i < layer.length; i++) { - feature = layer.feature(i).toGeoJSON(tile.xyz[0], tile.xyz[1], tile.xyz[2]); - loc = feature.geometry.coordinates; - d = { - loc: loc, - id: feature.properties.id, - first_seen_at: feature.properties.first_seen_at, - last_seen_at: feature.properties.last_seen_at, - value: feature.properties.value - }; - features.push({ - minX: loc[0], - minY: loc[1], - maxX: loc[0], - maxY: loc[1], - data: d - }); - } + function random(lower, upper, floating) { + if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) { + upper = floating = undefined$1; + } - if (cache.rtree) { - cache.rtree.load(features); - } - } + if (floating === undefined$1) { + if (typeof upper == 'boolean') { + floating = upper; + upper = undefined$1; + } else if (typeof lower == 'boolean') { + floating = lower; + lower = undefined$1; + } + } - if (vectorTile.layers.hasOwnProperty('traffic_sign')) { - features = []; - cache = _mlyCache[which]; - layer = vectorTile.layers.traffic_sign; + if (lower === undefined$1 && upper === undefined$1) { + lower = 0; + upper = 1; + } else { + lower = toFinite(lower); - for (i = 0; i < layer.length; i++) { - feature = layer.feature(i).toGeoJSON(tile.xyz[0], tile.xyz[1], tile.xyz[2]); - loc = feature.geometry.coordinates; - d = { - loc: loc, - id: feature.properties.id, - first_seen_at: feature.properties.first_seen_at, - last_seen_at: feature.properties.last_seen_at, - value: feature.properties.value - }; - features.push({ - minX: loc[0], - minY: loc[1], - maxX: loc[0], - maxY: loc[1], - data: d + if (upper === undefined$1) { + upper = lower; + lower = 0; + } else { + upper = toFinite(upper); + } + } + + if (lower > upper) { + var temp = lower; + lower = upper; + upper = temp; + } + + if (floating || lower % 1 || upper % 1) { + var rand = nativeRandom(); + return nativeMin(lower + rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1))), upper); + } + + return baseRandom(lower, upper); + } + /*------------------------------------------------------------------------*/ + + /** + * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the camel cased string. + * @example + * + * _.camelCase('Foo Bar'); + * // => 'fooBar' + * + * _.camelCase('--foo-bar--'); + * // => 'fooBar' + * + * _.camelCase('__FOO_BAR__'); + * // => 'fooBar' + */ + + + var camelCase = createCompounder(function (result, word, index) { + word = word.toLowerCase(); + return result + (index ? capitalize(word) : word); }); - } + /** + * Converts the first character of `string` to upper case and the remaining + * to lower case. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to capitalize. + * @returns {string} Returns the capitalized string. + * @example + * + * _.capitalize('FRED'); + * // => 'Fred' + */ - if (cache.rtree) { - cache.rtree.load(features); - } - } - } // Get data from the API + function capitalize(string) { + return upperFirst(toString(string).toLowerCase()); + } + /** + * Deburrs `string` by converting + * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) + * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A) + * letters to basic Latin letters and removing + * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to deburr. + * @returns {string} Returns the deburred string. + * @example + * + * _.deburr('déjà vu'); + * // => 'deja vu' + */ - function loadData(url) { - return fetch(url).then(function (response) { - if (!response.ok) { - throw new Error(response.status + ' ' + response.statusText); - } + function deburr(string) { + string = toString(string); + return string && string.replace(reLatin, deburrLetter).replace(reComboMark, ''); + } + /** + * Checks if `string` ends with the given target string. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to inspect. + * @param {string} [target] The string to search for. + * @param {number} [position=string.length] The position to search up to. + * @returns {boolean} Returns `true` if `string` ends with `target`, + * else `false`. + * @example + * + * _.endsWith('abc', 'c'); + * // => true + * + * _.endsWith('abc', 'b'); + * // => false + * + * _.endsWith('abc', 'b', 2); + * // => true + */ - return response.json(); - }).then(function (result) { - if (!result) { - return []; - } - return result.data || []; - }); - } // Partition viewport into higher zoom tiles + function endsWith(string, target, position) { + string = toString(string); + target = baseToString(target); + var length = string.length; + position = position === undefined$1 ? length : baseClamp(toInteger(position), 0, length); + var end = position; + position -= target.length; + return position >= 0 && string.slice(position, end) == target; + } + /** + * Converts the characters "&", "<", ">", '"', and "'" in `string` to their + * corresponding HTML entities. + * + * **Note:** No other characters are escaped. To escape additional + * characters use a third-party library like [_he_](https://mths.be/he). + * + * Though the ">" character is escaped for symmetry, characters like + * ">" and "/" don't need escaping in HTML and have no special meaning + * unless they're part of a tag or unquoted attribute value. See + * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands) + * (under "semi-related fun fact") for more details. + * + * When working with HTML you should always + * [quote attribute values](http://wonko.com/post/html-escaping) to reduce + * XSS vectors. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escape('fred, barney, & pebbles'); + * // => 'fred, barney, & pebbles' + */ - function partitionViewport$2(projection) { - var z = geoScaleToZoom(projection.scale()); - var z2 = Math.ceil(z * 2) / 2 + 2.5; // round to next 0.5 and add 2.5 + function escape(string) { + string = toString(string); + return string && reHasUnescapedHtml.test(string) ? string.replace(reUnescapedHtml, escapeHtmlChar) : string; + } + /** + * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+", + * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escapeRegExp('[lodash](https://lodash.com/)'); + * // => '\[lodash\]\(https://lodash\.com/\)' + */ - var tiler = utilTiler().zoomExtent([z2, z2]); - return tiler.getTiles(projection).map(function (tile) { - return tile.extent; - }); - } // Return no more than `limit` results per partition. + function escapeRegExp(string) { + string = toString(string); + return string && reHasRegExpChar.test(string) ? string.replace(reRegExpChar, '\\$&') : string; + } + /** + * Converts `string` to + * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the kebab cased string. + * @example + * + * _.kebabCase('Foo Bar'); + * // => 'foo-bar' + * + * _.kebabCase('fooBar'); + * // => 'foo-bar' + * + * _.kebabCase('__FOO_BAR__'); + * // => 'foo-bar' + */ - function searchLimited$2(limit, projection, rtree) { - limit = limit || 5; - return partitionViewport$2(projection).reduce(function (result, extent) { - var found = rtree.search(extent.bbox()).slice(0, limit).map(function (d) { - return d.data; - }); - return found.length ? result.concat(found) : result; - }, []); - } - var serviceMapillary = { - // Initialize Mapillary - init: function init() { - if (!_mlyCache) { - this.reset(); - } + var kebabCase = createCompounder(function (result, word, index) { + return result + (index ? '-' : '') + word.toLowerCase(); + }); + /** + * Converts `string`, as space separated words, to lower case. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the lower cased string. + * @example + * + * _.lowerCase('--Foo-Bar--'); + * // => 'foo bar' + * + * _.lowerCase('fooBar'); + * // => 'foo bar' + * + * _.lowerCase('__FOO_BAR__'); + * // => 'foo bar' + */ - this.event = utilRebind(this, dispatch$4, 'on'); - }, - // Reset cache and state - reset: function reset() { - if (_mlyCache) { - Object.values(_mlyCache.requests.inflight).forEach(function (request) { - request.abort(); + var lowerCase = createCompounder(function (result, word, index) { + return result + (index ? ' ' : '') + word.toLowerCase(); }); - } + /** + * Converts the first character of `string` to lower case. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.lowerFirst('Fred'); + * // => 'fred' + * + * _.lowerFirst('FRED'); + * // => 'fRED' + */ - _mlyCache = { - images: { - rtree: new RBush(), - forImageId: {} - }, - image_detections: { - forImageId: {} - }, - signs: { - rtree: new RBush() - }, - points: { - rtree: new RBush() - }, - sequences: { - rtree: new RBush(), - lineString: {} - }, - requests: { - loaded: {}, - inflight: {} + var lowerFirst = createCaseFirst('toLowerCase'); + /** + * Pads `string` on the left and right sides if it's shorter than `length`. + * Padding characters are truncated if they can't be evenly divided by `length`. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. + * @example + * + * _.pad('abc', 8); + * // => ' abc ' + * + * _.pad('abc', 8, '_-'); + * // => '_-abc_-_' + * + * _.pad('abc', 3); + * // => 'abc' + */ + + function pad(string, length, chars) { + string = toString(string); + length = toInteger(length); + var strLength = length ? stringSize(string) : 0; + + if (!length || strLength >= length) { + return string; + } + + var mid = (length - strLength) / 2; + return createPadding(nativeFloor(mid), chars) + string + createPadding(nativeCeil(mid), chars); } - }; - _mlyActiveImage = null; - }, - // Get visible images - images: function images(projection) { - var limit = 5; - return searchLimited$2(limit, projection, _mlyCache.images.rtree); - }, - // Get visible traffic signs - signs: function signs(projection) { - var limit = 5; - return searchLimited$2(limit, projection, _mlyCache.signs.rtree); - }, - // Get visible map (point) features - mapFeatures: function mapFeatures(projection) { - var limit = 5; - return searchLimited$2(limit, projection, _mlyCache.points.rtree); - }, - // Get cached image by id - cachedImage: function cachedImage(imageId) { - return _mlyCache.images.forImageId[imageId]; - }, - // Get visible sequences - sequences: function sequences(projection) { - var viewport = projection.clipExtent(); - var min = [viewport[0][0], viewport[1][1]]; - var max = [viewport[1][0], viewport[0][1]]; - var bbox = geoExtent(projection.invert(min), projection.invert(max)).bbox(); - var sequenceIds = {}; - var lineStrings = []; + /** + * Pads `string` on the right side if it's shorter than `length`. Padding + * characters are truncated if they exceed `length`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. + * @example + * + * _.padEnd('abc', 6); + * // => 'abc ' + * + * _.padEnd('abc', 6, '_-'); + * // => 'abc_-_' + * + * _.padEnd('abc', 3); + * // => 'abc' + */ - _mlyCache.images.rtree.search(bbox).forEach(function (d) { - if (d.data.sequence_id) { - sequenceIds[d.data.sequence_id] = true; + + function padEnd(string, length, chars) { + string = toString(string); + length = toInteger(length); + var strLength = length ? stringSize(string) : 0; + return length && strLength < length ? string + createPadding(length - strLength, chars) : string; } - }); + /** + * Pads `string` on the left side if it's shorter than `length`. Padding + * characters are truncated if they exceed `length`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. + * @example + * + * _.padStart('abc', 6); + * // => ' abc' + * + * _.padStart('abc', 6, '_-'); + * // => '_-_abc' + * + * _.padStart('abc', 3); + * // => 'abc' + */ - Object.keys(sequenceIds).forEach(function (sequenceId) { - if (_mlyCache.sequences.lineString[sequenceId]) { - lineStrings = lineStrings.concat(_mlyCache.sequences.lineString[sequenceId]); + + function padStart(string, length, chars) { + string = toString(string); + length = toInteger(length); + var strLength = length ? stringSize(string) : 0; + return length && strLength < length ? createPadding(length - strLength, chars) + string : string; } - }); - return lineStrings; - }, - // Load images in the visible area - loadImages: function loadImages(projection) { - loadTiles$2('images', tileUrl, 14, projection); - }, - // Load traffic signs in the visible area - loadSigns: function loadSigns(projection) { - loadTiles$2('signs', trafficSignTileUrl, 14, projection); - }, - // Load map (point) features in the visible area - loadMapFeatures: function loadMapFeatures(projection) { - loadTiles$2('points', mapFeatureTileUrl, 14, projection); - }, - // Return a promise that resolves when the image viewer (Mapillary JS) library has finished loading - ensureViewerLoaded: function ensureViewerLoaded(context) { - if (_loadViewerPromise$2) return _loadViewerPromise$2; // add mly-wrapper + /** + * Converts `string` to an integer of the specified radix. If `radix` is + * `undefined` or `0`, a `radix` of `10` is used unless `value` is a + * hexadecimal, in which case a `radix` of `16` is used. + * + * **Note:** This method aligns with the + * [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category String + * @param {string} string The string to convert. + * @param {number} [radix=10] The radix to interpret `value` by. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {number} Returns the converted integer. + * @example + * + * _.parseInt('08'); + * // => 8 + * + * _.map(['6', '08', '10'], _.parseInt); + * // => [6, 8, 10] + */ - var wrap = context.container().select('.photoviewer').selectAll('.mly-wrapper').data([0]); - wrap.enter().append('div').attr('id', 'ideditor-mly').attr('class', 'photo-wrapper mly-wrapper').classed('hide', true); - var that = this; - _loadViewerPromise$2 = new Promise(function (resolve, reject) { - var loadedCount = 0; - function loaded() { - loadedCount += 1; // wait until both files are loaded + function parseInt(string, radix, guard) { + if (guard || radix == null) { + radix = 0; + } else if (radix) { + radix = +radix; + } - if (loadedCount === 2) resolve(); + return nativeParseInt(toString(string).replace(reTrimStart, ''), radix || 0); } + /** + * Repeats the given string `n` times. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to repeat. + * @param {number} [n=1] The number of times to repeat the string. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {string} Returns the repeated string. + * @example + * + * _.repeat('*', 3); + * // => '***' + * + * _.repeat('abc', 2); + * // => 'abcabc' + * + * _.repeat('abc', 0); + * // => '' + */ - var head = select('head'); // load mapillary-viewercss - head.selectAll('#ideditor-mapillary-viewercss').data([0]).enter().append('link').attr('id', 'ideditor-mapillary-viewercss').attr('rel', 'stylesheet').attr('crossorigin', 'anonymous').attr('href', context.asset(viewercss)).on('load.serviceMapillary', loaded).on('error.serviceMapillary', function () { - reject(); - }); // load mapillary-viewerjs + function repeat(string, n, guard) { + if (guard ? isIterateeCall(string, n, guard) : n === undefined$1) { + n = 1; + } else { + n = toInteger(n); + } - head.selectAll('#ideditor-mapillary-viewerjs').data([0]).enter().append('script').attr('id', 'ideditor-mapillary-viewerjs').attr('crossorigin', 'anonymous').attr('src', context.asset(viewerjs)).on('load.serviceMapillary', loaded).on('error.serviceMapillary', function () { - reject(); - }); - })["catch"](function () { - _loadViewerPromise$2 = null; - }).then(function () { - that.initViewer(context); - }); - return _loadViewerPromise$2; - }, - // Load traffic sign image sprites - loadSignResources: function loadSignResources(context) { - context.ui().svgDefs.addSprites(['mapillary-sprite'], false - /* don't override colors */ - ); - return this; - }, - // Load map (point) feature image sprites - loadObjectResources: function loadObjectResources(context) { - context.ui().svgDefs.addSprites(['mapillary-object-sprite'], false - /* don't override colors */ - ); - return this; - }, - // Remove previous detections in image viewer - resetTags: function resetTags() { - if (_mlyViewer && !_mlyFallback) { - _mlyViewer.getComponent('tag').removeAll(); - } - }, - // Show map feature detections in image viewer - showFeatureDetections: function showFeatureDetections(value) { - _mlyShowFeatureDetections = value; + return baseRepeat(toString(string), n); + } + /** + * Replaces matches for `pattern` in `string` with `replacement`. + * + * **Note:** This method is based on + * [`String#replace`](https://mdn.io/String/replace). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category String + * @param {string} [string=''] The string to modify. + * @param {RegExp|string} pattern The pattern to replace. + * @param {Function|string} replacement The match replacement. + * @returns {string} Returns the modified string. + * @example + * + * _.replace('Hi Fred', 'Fred', 'Barney'); + * // => 'Hi Barney' + */ - if (!_mlyShowFeatureDetections && !_mlyShowSignDetections) { - this.resetTags(); - } - }, - // Show traffic sign detections in image viewer - showSignDetections: function showSignDetections(value) { - _mlyShowSignDetections = value; - if (!_mlyShowFeatureDetections && !_mlyShowSignDetections) { - this.resetTags(); - } - }, - // Apply filter to image viewer - filterViewer: function filterViewer(context) { - var showsPano = context.photos().showsPanoramic(); - var showsFlat = context.photos().showsFlat(); - var fromDate = context.photos().fromDate(); - var toDate = context.photos().toDate(); - var filter = ['all']; - if (!showsPano) filter.push(['!=', 'cameraType', 'spherical']); - if (!showsFlat && showsPano) filter.push(['==', 'pano', true]); + function replace() { + var args = arguments, + string = toString(args[0]); + return args.length < 3 ? string : string.replace(args[1], args[2]); + } + /** + * Converts `string` to + * [snake case](https://en.wikipedia.org/wiki/Snake_case). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the snake cased string. + * @example + * + * _.snakeCase('Foo Bar'); + * // => 'foo_bar' + * + * _.snakeCase('fooBar'); + * // => 'foo_bar' + * + * _.snakeCase('--FOO-BAR--'); + * // => 'foo_bar' + */ - if (fromDate) { - filter.push(['>=', 'capturedAt', new Date(fromDate).getTime()]); - } - if (toDate) { - filter.push(['>=', 'capturedAt', new Date(toDate).getTime()]); - } + var snakeCase = createCompounder(function (result, word, index) { + return result + (index ? '_' : '') + word.toLowerCase(); + }); + /** + * Splits `string` by `separator`. + * + * **Note:** This method is based on + * [`String#split`](https://mdn.io/String/split). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category String + * @param {string} [string=''] The string to split. + * @param {RegExp|string} separator The separator pattern to split by. + * @param {number} [limit] The length to truncate results to. + * @returns {Array} Returns the string segments. + * @example + * + * _.split('a-b-c', '-', 2); + * // => ['a', 'b'] + */ - if (_mlyViewer) { - _mlyViewer.setFilter(filter); - } + function split(string, separator, limit) { + if (limit && typeof limit != 'number' && isIterateeCall(string, separator, limit)) { + separator = limit = undefined$1; + } - _mlyViewerFilter = filter; - return filter; - }, - // Make the image viewer visible - showViewer: function showViewer(context) { - var wrap = context.container().select('.photoviewer').classed('hide', false); - var isHidden = wrap.selectAll('.photo-wrapper.mly-wrapper.hide').size(); + limit = limit === undefined$1 ? MAX_ARRAY_LENGTH : limit >>> 0; - if (isHidden && _mlyViewer) { - wrap.selectAll('.photo-wrapper:not(.mly-wrapper)').classed('hide', true); - wrap.selectAll('.photo-wrapper.mly-wrapper').classed('hide', false); + if (!limit) { + return []; + } - _mlyViewer.resize(); - } + string = toString(string); - return this; - }, - // Hide the image viewer and resets map markers - hideViewer: function hideViewer(context) { - _mlyActiveImage = null; + if (string && (typeof separator == 'string' || separator != null && !isRegExp(separator))) { + separator = baseToString(separator); - if (!_mlyFallback && _mlyViewer) { - _mlyViewer.getComponent('sequence').stop(); - } + if (!separator && hasUnicode(string)) { + return castSlice(stringToArray(string), 0, limit); + } + } - var viewer = context.container().select('.photoviewer'); - if (!viewer.empty()) viewer.datum(null); - viewer.classed('hide', true).selectAll('.photo-wrapper').classed('hide', true); - this.updateUrlImage(null); - dispatch$4.call('imageChanged'); - dispatch$4.call('loadedMapFeatures'); - dispatch$4.call('loadedSigns'); - return this.setStyles(context, null); - }, - // Update the URL with current image id - updateUrlImage: function updateUrlImage(imageId) { - if (!window.mocha) { - var hash = utilStringQs(window.location.hash); + return string.split(separator, limit); + } + /** + * Converts `string` to + * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage). + * + * @static + * @memberOf _ + * @since 3.1.0 + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the start cased string. + * @example + * + * _.startCase('--foo-bar--'); + * // => 'Foo Bar' + * + * _.startCase('fooBar'); + * // => 'Foo Bar' + * + * _.startCase('__FOO_BAR__'); + * // => 'FOO BAR' + */ - if (imageId) { - hash.photo = 'mapillary/' + imageId; - } else { - delete hash.photo; + + var startCase = createCompounder(function (result, word, index) { + return result + (index ? ' ' : '') + upperFirst(word); + }); + /** + * Checks if `string` starts with the given target string. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to inspect. + * @param {string} [target] The string to search for. + * @param {number} [position=0] The position to search from. + * @returns {boolean} Returns `true` if `string` starts with `target`, + * else `false`. + * @example + * + * _.startsWith('abc', 'a'); + * // => true + * + * _.startsWith('abc', 'b'); + * // => false + * + * _.startsWith('abc', 'b', 1); + * // => true + */ + + function startsWith(string, target, position) { + string = toString(string); + position = position == null ? 0 : baseClamp(toInteger(position), 0, string.length); + target = baseToString(target); + return string.slice(position, position + target.length) == target; } + /** + * Creates a compiled template function that can interpolate data properties + * in "interpolate" delimiters, HTML-escape interpolated data properties in + * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data + * properties may be accessed as free variables in the template. If a setting + * object is given, it takes precedence over `_.templateSettings` values. + * + * **Note:** In the development build `_.template` utilizes + * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) + * for easier debugging. + * + * For more information on precompiling templates see + * [lodash's custom builds documentation](https://lodash.com/custom-builds). + * + * For more information on Chrome extension sandboxes see + * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval). + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category String + * @param {string} [string=''] The template string. + * @param {Object} [options={}] The options object. + * @param {RegExp} [options.escape=_.templateSettings.escape] + * The HTML "escape" delimiter. + * @param {RegExp} [options.evaluate=_.templateSettings.evaluate] + * The "evaluate" delimiter. + * @param {Object} [options.imports=_.templateSettings.imports] + * An object to import into the template as free variables. + * @param {RegExp} [options.interpolate=_.templateSettings.interpolate] + * The "interpolate" delimiter. + * @param {string} [options.sourceURL='lodash.templateSources[n]'] + * The sourceURL of the compiled template. + * @param {string} [options.variable='obj'] + * The data object variable name. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Function} Returns the compiled template function. + * @example + * + * // Use the "interpolate" delimiter to create a compiled template. + * var compiled = _.template('hello <%= user %>!'); + * compiled({ 'user': 'fred' }); + * // => 'hello fred!' + * + * // Use the HTML "escape" delimiter to escape data property values. + * var compiled = _.template('<%- value %>'); + * compiled({ 'value': '