@geoit/ui 0.0.4 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +12 -8
- package/README.md +49 -62
- package/ai/AGENTS.md +38 -28
- package/ai/README.md +35 -1
- package/ai/catalog.json +2796 -288
- package/ai/components/geo-alert.md +3 -3
- package/ai/components/geo-back-button.md +2 -2
- package/ai/components/geo-breadcrumb.md +1 -1
- package/ai/components/geo-button.md +3 -3
- package/ai/components/geo-chart.md +103 -0
- package/ai/components/geo-checkbox.md +4 -6
- package/ai/components/geo-column-picker.md +3 -3
- package/ai/components/geo-confirm-modal.md +4 -5
- package/ai/components/geo-dashboard.md +91 -0
- package/ai/components/geo-date-picker.md +5 -3
- package/ai/components/geo-date-range-picker.md +5 -3
- package/ai/components/geo-empty-state.md +75 -0
- package/ai/components/geo-feedback-form.md +97 -0
- package/ai/components/geo-file-picker.md +4 -2
- package/ai/components/geo-forgot-password.md +78 -0
- package/ai/components/geo-form-modal.md +9 -10
- package/ai/components/geo-icon.md +3 -3
- package/ai/components/geo-input.md +8 -6
- package/ai/components/geo-layout-footer.md +70 -0
- package/ai/components/geo-layout-header-actions.md +82 -0
- package/ai/components/geo-layout-header.md +89 -0
- package/ai/components/geo-layout-sidebar.md +86 -0
- package/ai/components/geo-layout.md +155 -0
- package/ai/components/geo-list-page.md +72 -0
- package/ai/components/geo-login.md +94 -0
- package/ai/components/geo-map-admin-filter.md +80 -0
- package/ai/components/geo-map-basemap-switcher.md +75 -0
- package/ai/components/geo-map-help.md +72 -0
- package/ai/components/geo-map-layer-card.md +73 -0
- package/ai/components/geo-map-layer-panel.md +75 -0
- package/ai/components/geo-map-layers-drawer.md +78 -0
- package/ai/components/geo-map-legend.md +74 -0
- package/ai/components/geo-map-locate.md +75 -0
- package/ai/components/geo-map-location-chip.md +71 -0
- package/ai/components/geo-map-measure.md +74 -0
- package/ai/components/geo-map-opacity.md +75 -0
- package/ai/components/geo-map-parcel-popup.md +79 -0
- package/ai/components/geo-map-search.md +83 -0
- package/ai/components/geo-map-shell.md +110 -0
- package/ai/components/geo-map-snapshot.md +75 -0
- package/ai/components/geo-map-swipe.md +73 -0
- package/ai/components/geo-map-toolbar.md +76 -0
- package/ai/components/geo-map-zoom.md +74 -0
- package/ai/components/geo-map.md +205 -0
- package/ai/components/geo-overlap-result.md +88 -0
- package/ai/components/geo-page-header.md +72 -0
- package/ai/components/geo-page-title.md +1 -1
- package/ai/components/geo-pagination.md +4 -7
- package/ai/components/geo-radio.md +3 -1
- package/ai/components/geo-row-actions.md +3 -3
- package/ai/components/geo-select.md +4 -2
- package/ai/components/geo-slider.md +5 -7
- package/ai/components/geo-stat-card.md +98 -0
- package/ai/components/geo-status-tag.md +2 -2
- package/ai/components/geo-step-form-layout.md +7 -8
- package/ai/components/geo-stepper.md +3 -4
- package/ai/components/geo-table-filter.md +4 -5
- package/ai/components/geo-table-pagination.md +4 -7
- package/ai/components/geo-table-toolbar.md +7 -7
- package/ai/components/geo-table.md +17 -20
- package/ai/components/geo-tabs.md +4 -6
- package/ai/components/geo-textarea.md +4 -2
- package/ai/components/geo-toast.md +4 -4
- package/ai/components/geo-tree.md +4 -6
- package/ai/components/geo-typography.md +1 -1
- package/ai/components/geo-upload.md +9 -10
- package/ai/mockup.html +1194 -0
- package/ai/recipes.md +98 -85
- package/esm2022/lib/figma/geo-alert/geo-alert.component.mjs +19 -36
- package/esm2022/lib/figma/geo-back-button/geo-back-button.component.mjs +14 -24
- package/esm2022/lib/figma/geo-breadcrumb/geo-breadcrumb.component.mjs +8 -11
- package/esm2022/lib/figma/geo-button/geo-button.component.mjs +30 -59
- package/esm2022/lib/figma/geo-chart/geo-chart.component.mjs +88 -0
- package/esm2022/lib/figma/geo-chart/geo-chart.types.mjs +2 -0
- package/esm2022/lib/figma/geo-checkbox/geo-checkbox.component.mjs +11 -22
- package/esm2022/lib/figma/geo-confirm-modal/geo-confirm-modal.component.mjs +22 -54
- package/esm2022/lib/figma/geo-dashboard/geo-dashboard.component.mjs +49 -0
- package/esm2022/lib/figma/geo-dashboard/geo-dashboard.types.mjs +2 -0
- package/esm2022/lib/figma/geo-date-picker/geo-date-picker.component.mjs +48 -78
- package/esm2022/lib/figma/geo-date-range-picker/geo-date-range-picker.component.mjs +47 -75
- package/esm2022/lib/figma/geo-empty-state/geo-empty-state.component.mjs +25 -0
- package/esm2022/lib/figma/geo-feedback-form/geo-feedback-form.component.mjs +75 -0
- package/esm2022/lib/figma/geo-feedback-form/geo-feedback-form.types.mjs +2 -0
- package/esm2022/lib/figma/geo-file-picker/geo-file-picker.component.mjs +59 -81
- package/esm2022/lib/figma/geo-forgot-password/geo-forgot-password.component.mjs +51 -0
- package/esm2022/lib/figma/geo-form-modal/geo-form-modal.component.mjs +45 -112
- package/esm2022/lib/figma/geo-icon/geo-icon.component.mjs +22 -32
- package/esm2022/lib/figma/geo-input/geo-input.component.mjs +41 -70
- package/esm2022/lib/figma/geo-layout/footer/geo-layout-footer.component.mjs +18 -0
- package/esm2022/lib/figma/geo-layout/geo-layout-actions.directive.mjs +15 -0
- package/esm2022/lib/figma/geo-layout/geo-layout.component.mjs +79 -0
- package/esm2022/lib/figma/geo-layout/geo-layout.types.mjs +42 -0
- package/esm2022/lib/figma/geo-layout/header/geo-layout-header.component.mjs +60 -0
- package/esm2022/lib/figma/geo-layout/header-actions/geo-layout-header-actions.component.mjs +70 -0
- package/esm2022/lib/figma/geo-layout/sidebar/geo-layout-sidebar.component.mjs +90 -0
- package/esm2022/lib/figma/geo-list-page/geo-list-page.component.mjs +22 -0
- package/esm2022/lib/figma/geo-login/geo-login.component.mjs +58 -0
- package/esm2022/lib/figma/geo-login/geo-login.types.mjs +2 -0
- package/esm2022/lib/figma/geo-map/chrome/geo-map-admin-filter/geo-map-admin-filter.component.mjs +52 -0
- package/esm2022/lib/figma/geo-map/chrome/geo-map-basemap-switcher/geo-map-basemap-switcher.component.mjs +61 -0
- package/esm2022/lib/figma/geo-map/chrome/geo-map-help/geo-map-help.component.mjs +26 -0
- package/esm2022/lib/figma/geo-map/chrome/geo-map-layer-card/geo-map-layer-card.component.mjs +24 -0
- package/esm2022/lib/figma/geo-map/chrome/geo-map-layer-panel/geo-map-layer-panel.component.mjs +146 -0
- package/esm2022/lib/figma/geo-map/chrome/geo-map-layers-drawer/geo-map-layers-drawer.component.mjs +37 -0
- package/esm2022/lib/figma/geo-map/chrome/geo-map-legend/geo-map-legend.component.mjs +30 -0
- package/esm2022/lib/figma/geo-map/chrome/geo-map-locate/geo-map-locate.component.mjs +72 -0
- package/esm2022/lib/figma/geo-map/chrome/geo-map-location-chip/geo-map-location-chip.component.mjs +21 -0
- package/esm2022/lib/figma/geo-map/chrome/geo-map-measure/geo-map-measure.component.mjs +375 -0
- package/esm2022/lib/figma/geo-map/chrome/geo-map-opacity/geo-map-opacity.component.mjs +94 -0
- package/esm2022/lib/figma/geo-map/chrome/geo-map-parcel-popup/geo-map-parcel-popup.component.mjs +136 -0
- package/esm2022/lib/figma/geo-map/chrome/geo-map-search/geo-map-search.component.mjs +182 -0
- package/esm2022/lib/figma/geo-map/chrome/geo-map-shell/geo-map-shell.component.mjs +577 -0
- package/esm2022/lib/figma/geo-map/chrome/geo-map-snapshot/geo-map-snapshot.component.mjs +93 -0
- package/esm2022/lib/figma/geo-map/chrome/geo-map-swipe/geo-map-swipe.component.mjs +129 -0
- package/esm2022/lib/figma/geo-map/chrome/geo-map-toolbar/geo-map-toolbar.component.mjs +64 -0
- package/esm2022/lib/figma/geo-map/chrome/geo-map-zoom/geo-map-zoom.component.mjs +295 -0
- package/esm2022/lib/figma/geo-map/geo-map-toolbar.icons.mjs +18 -0
- package/esm2022/lib/figma/geo-map/geo-map.component.mjs +144 -0
- package/esm2022/lib/figma/geo-map/geo-map.constants.mjs +497 -0
- package/esm2022/lib/figma/geo-map/geo-map.controller.mjs +71 -0
- package/esm2022/lib/figma/geo-map/geo-map.types.mjs +2 -0
- package/esm2022/lib/figma/geo-map/services/geo-map-layer.service.mjs +368 -0
- package/esm2022/lib/figma/geo-map/services/geo-map-projection.service.mjs +110 -0
- package/esm2022/lib/figma/geo-map/services/geo-map.service.mjs +540 -0
- package/esm2022/lib/figma/geo-map/utils/geo-map-fullscreen-overlay.util.mjs +47 -0
- package/esm2022/lib/figma/geo-map/utils/geo-map-interactions.util.mjs +30 -0
- package/esm2022/lib/figma/geo-overlap-result/geo-overlap-result.component.mjs +25 -0
- package/esm2022/lib/figma/geo-overlap-result/geo-overlap-result.types.mjs +2 -0
- package/esm2022/lib/figma/geo-page-header/geo-page-header.component.mjs +23 -0
- package/esm2022/lib/figma/geo-page-title/geo-page-title.component.mjs +20 -35
- package/esm2022/lib/figma/geo-pagination/geo-pagination.component.mjs +13 -43
- package/esm2022/lib/figma/geo-radio/geo-radio.component.mjs +32 -52
- package/esm2022/lib/figma/geo-select/geo-select.component.mjs +46 -72
- package/esm2022/lib/figma/geo-slider/geo-slider.component.mjs +12 -28
- package/esm2022/lib/figma/geo-stat-card/geo-stat-card.component.mjs +163 -0
- package/esm2022/lib/figma/geo-stat-card/geo-stat-card.types.mjs +2 -0
- package/esm2022/lib/figma/geo-status-tag/geo-status-tag.component.mjs +23 -27
- package/esm2022/lib/figma/geo-step-form-layout/geo-step-form-layout.component.mjs +39 -96
- package/esm2022/lib/figma/geo-stepper/geo-stepper.component.mjs +18 -33
- package/esm2022/lib/figma/geo-table/geo-column-picker/geo-column-picker.component.mjs +14 -24
- package/esm2022/lib/figma/geo-table/geo-row-actions/geo-row-actions.component.mjs +18 -36
- package/esm2022/lib/figma/geo-table/geo-table-filter/geo-table-filter.component.mjs +41 -98
- package/esm2022/lib/figma/geo-table/geo-table-pagination/geo-table-pagination.component.mjs +40 -73
- package/esm2022/lib/figma/geo-table/geo-table-toolbar/geo-table-toolbar.component.mjs +26 -56
- package/esm2022/lib/figma/geo-table/geo-table.component.mjs +110 -210
- package/esm2022/lib/figma/geo-tabs/geo-tabs.component.mjs +33 -63
- package/esm2022/lib/figma/geo-textarea/geo-textarea.component.mjs +28 -44
- package/esm2022/lib/figma/geo-toast/geo-toast.component.mjs +18 -39
- package/esm2022/lib/figma/geo-tree/geo-tree.component.mjs +12 -40
- package/esm2022/lib/figma/geo-typography/geo-typography.component.mjs +49 -64
- package/esm2022/lib/figma/geo-upload/geo-upload.component.mjs +50 -101
- package/esm2022/lib/figma/index.mjs +50 -1
- package/esm2022/lib/styles/tokens.mjs +56 -24
- package/fesm2022/geoit-ui.mjs +5981 -1825
- package/fesm2022/geoit-ui.mjs.map +1 -1
- package/lib/figma/geo-alert/geo-alert.component.d.ts +10 -11
- package/lib/figma/geo-back-button/geo-back-button.component.d.ts +6 -7
- package/lib/figma/geo-breadcrumb/geo-breadcrumb.component.d.ts +2 -2
- package/lib/figma/geo-button/geo-button.component.d.ts +21 -17
- package/lib/figma/geo-chart/geo-chart.component.d.ts +40 -0
- package/lib/figma/geo-chart/geo-chart.types.d.ts +13 -0
- package/lib/figma/geo-checkbox/geo-checkbox.component.d.ts +6 -7
- package/lib/figma/geo-confirm-modal/geo-confirm-modal.component.d.ts +15 -17
- package/lib/figma/geo-dashboard/geo-dashboard.component.d.ts +29 -0
- package/lib/figma/geo-dashboard/geo-dashboard.types.d.ts +7 -0
- package/lib/figma/geo-date-picker/geo-date-picker.component.d.ts +26 -21
- package/lib/figma/geo-date-range-picker/geo-date-range-picker.component.d.ts +25 -20
- package/lib/figma/geo-empty-state/geo-empty-state.component.d.ts +17 -0
- package/lib/figma/geo-feedback-form/geo-feedback-form.component.d.ts +36 -0
- package/lib/figma/geo-feedback-form/geo-feedback-form.types.d.ts +8 -0
- package/lib/figma/geo-file-picker/geo-file-picker.component.d.ts +23 -20
- package/lib/figma/geo-forgot-password/geo-forgot-password.component.d.ts +24 -0
- package/lib/figma/geo-form-modal/geo-form-modal.component.d.ts +33 -35
- package/lib/figma/geo-icon/geo-icon.component.d.ts +7 -7
- package/lib/figma/geo-input/geo-input.component.d.ts +23 -21
- package/lib/figma/geo-layout/footer/geo-layout-footer.component.d.ts +10 -0
- package/lib/figma/geo-layout/geo-layout-actions.directive.d.ts +6 -0
- package/lib/figma/geo-layout/geo-layout.component.d.ts +48 -0
- package/lib/figma/geo-layout/geo-layout.types.d.ts +44 -0
- package/lib/figma/geo-layout/header/geo-layout-header.component.d.ts +31 -0
- package/lib/figma/geo-layout/header-actions/geo-layout-header-actions.component.d.ts +32 -0
- package/lib/figma/geo-layout/sidebar/geo-layout-sidebar.component.d.ts +34 -0
- package/lib/figma/geo-list-page/geo-list-page.component.d.ts +16 -0
- package/lib/figma/geo-login/geo-login.component.d.ts +27 -0
- package/lib/figma/geo-login/geo-login.types.d.ts +6 -0
- package/lib/figma/geo-map/chrome/geo-map-admin-filter/geo-map-admin-filter.component.d.ts +28 -0
- package/lib/figma/geo-map/chrome/geo-map-basemap-switcher/geo-map-basemap-switcher.component.d.ts +26 -0
- package/lib/figma/geo-map/chrome/geo-map-help/geo-map-help.component.d.ts +20 -0
- package/lib/figma/geo-map/chrome/geo-map-layer-card/geo-map-layer-card.component.d.ts +15 -0
- package/lib/figma/geo-map/chrome/geo-map-layer-panel/geo-map-layer-panel.component.d.ts +40 -0
- package/lib/figma/geo-map/chrome/geo-map-layers-drawer/geo-map-layers-drawer.component.d.ts +25 -0
- package/lib/figma/geo-map/chrome/geo-map-legend/geo-map-legend.component.d.ts +18 -0
- package/lib/figma/geo-map/chrome/geo-map-locate/geo-map-locate.component.d.ts +24 -0
- package/lib/figma/geo-map/chrome/geo-map-location-chip/geo-map-location-chip.component.d.ts +14 -0
- package/lib/figma/geo-map/chrome/geo-map-measure/geo-map-measure.component.d.ts +49 -0
- package/lib/figma/geo-map/chrome/geo-map-opacity/geo-map-opacity.component.d.ts +30 -0
- package/lib/figma/geo-map/chrome/geo-map-parcel-popup/geo-map-parcel-popup.component.d.ts +44 -0
- package/lib/figma/geo-map/chrome/geo-map-search/geo-map-search.component.d.ts +56 -0
- package/lib/figma/geo-map/chrome/geo-map-shell/geo-map-shell.component.d.ts +103 -0
- package/lib/figma/geo-map/chrome/geo-map-snapshot/geo-map-snapshot.component.d.ts +21 -0
- package/lib/figma/geo-map/chrome/geo-map-swipe/geo-map-swipe.component.d.ts +33 -0
- package/lib/figma/geo-map/chrome/geo-map-toolbar/geo-map-toolbar.component.d.ts +30 -0
- package/lib/figma/geo-map/chrome/geo-map-zoom/geo-map-zoom.component.d.ts +67 -0
- package/lib/figma/geo-map/geo-map-toolbar.icons.d.ts +17 -0
- package/lib/figma/geo-map/geo-map.component.d.ts +53 -0
- package/lib/figma/geo-map/geo-map.constants.d.ts +73 -0
- package/lib/figma/geo-map/geo-map.controller.d.ts +49 -0
- package/lib/figma/geo-map/geo-map.types.d.ts +224 -0
- package/lib/figma/geo-map/services/geo-map-layer.service.d.ts +42 -0
- package/lib/figma/geo-map/services/geo-map-projection.service.d.ts +32 -0
- package/lib/figma/geo-map/services/geo-map.service.d.ts +99 -0
- package/lib/figma/geo-map/utils/geo-map-fullscreen-overlay.util.d.ts +13 -0
- package/lib/figma/geo-map/utils/geo-map-interactions.util.d.ts +9 -0
- package/lib/figma/geo-overlap-result/geo-overlap-result.component.d.ts +18 -0
- package/lib/figma/geo-overlap-result/geo-overlap-result.types.d.ts +7 -0
- package/lib/figma/geo-page-header/geo-page-header.component.d.ts +16 -0
- package/lib/figma/geo-page-title/geo-page-title.component.d.ts +9 -9
- package/lib/figma/geo-pagination/geo-pagination.component.d.ts +9 -14
- package/lib/figma/geo-radio/geo-radio.component.d.ts +17 -15
- package/lib/figma/geo-select/geo-select.component.d.ts +24 -19
- package/lib/figma/geo-slider/geo-slider.component.d.ts +7 -9
- package/lib/figma/geo-stat-card/geo-stat-card.component.d.ts +50 -0
- package/lib/figma/geo-stat-card/geo-stat-card.types.d.ts +11 -0
- package/lib/figma/geo-status-tag/geo-status-tag.component.d.ts +7 -7
- package/lib/figma/geo-step-form-layout/geo-step-form-layout.component.d.ts +27 -29
- package/lib/figma/geo-stepper/geo-stepper.component.d.ts +6 -8
- package/lib/figma/geo-table/geo-column-picker/geo-column-picker.component.d.ts +6 -7
- package/lib/figma/geo-table/geo-row-actions/geo-row-actions.component.d.ts +11 -12
- package/lib/figma/geo-table/geo-table-filter/geo-table-filter.component.d.ts +21 -28
- package/lib/figma/geo-table/geo-table-pagination/geo-table-pagination.component.d.ts +17 -20
- package/lib/figma/geo-table/geo-table-toolbar/geo-table-toolbar.component.d.ts +17 -18
- package/lib/figma/geo-table/geo-table.component.d.ts +58 -62
- package/lib/figma/geo-tabs/geo-tabs.component.d.ts +14 -17
- package/lib/figma/geo-textarea/geo-textarea.component.d.ts +15 -13
- package/lib/figma/geo-toast/geo-toast.component.d.ts +11 -12
- package/lib/figma/geo-tree/geo-tree.component.d.ts +8 -13
- package/lib/figma/geo-typography/geo-typography.component.d.ts +13 -13
- package/lib/figma/geo-upload/geo-upload.component.d.ts +26 -28
- package/lib/figma/index.d.ts +49 -0
- package/lib/styles/tokens.d.ts +56 -23
- package/package.json +4 -2
- package/src/lib/figma/geo-map/assets/toolbar/fullscreen.svg +8 -0
- package/src/lib/figma/geo-map/assets/toolbar/home.svg +3 -0
- package/src/lib/figma/geo-map/assets/toolbar/layers.svg +3 -0
- package/src/lib/figma/geo-map/assets/toolbar/measure-area.svg +12 -0
- package/src/lib/figma/geo-map/assets/toolbar/measure-distance.svg +5 -0
- package/src/lib/figma/geo-map/assets/toolbar/pan.svg +13 -0
- package/src/lib/figma/geo-map/assets/toolbar/search.svg +3 -0
- package/src/lib/figma/geo-map/assets/toolbar/zoom-in.svg +3 -0
- package/src/lib/figma/geo-map/assets/toolbar/zoom-out.svg +5 -0
- package/src/lib/styles/design-tokens.scss +108 -35
- package/src/lib/styles/scrollbar.scss +2 -2
- package/src/lib/styles/theme.scss +1 -1
|
@@ -0,0 +1,540 @@
|
|
|
1
|
+
import { Injectable, inject } from '@angular/core';
|
|
2
|
+
import OlMap from 'ol/Map';
|
|
3
|
+
import View from 'ol/View';
|
|
4
|
+
import { defaults as defaultControls } from 'ol/control/defaults';
|
|
5
|
+
import ScaleLine from 'ol/control/ScaleLine';
|
|
6
|
+
import MousePosition from 'ol/control/MousePosition';
|
|
7
|
+
import { createStringXY } from 'ol/coordinate';
|
|
8
|
+
import { unByKey } from 'ol/Observable';
|
|
9
|
+
import GeoJSON from 'ol/format/GeoJSON';
|
|
10
|
+
import VectorLayer from 'ol/layer/Vector';
|
|
11
|
+
import VectorSource from 'ol/source/Vector';
|
|
12
|
+
import { transformExtent } from 'ol/proj';
|
|
13
|
+
import { Fill, Icon, Stroke, Style } from 'ol/style';
|
|
14
|
+
import { GEO_MAP_BASEMAP_LAYER_ID, GEO_MAP_DEFAULT_MAX_ZOOM, GEO_MAP_DEFAULT_PROVINCE_EXTENT_4326, GEO_MAP_HIGHLIGHT_LAYER_ID, } from '../geo-map.constants';
|
|
15
|
+
import { GeoMapLayerService, } from './geo-map-layer.service';
|
|
16
|
+
import { GeoMapProjectionService } from './geo-map-projection.service';
|
|
17
|
+
import * as i0 from "@angular/core";
|
|
18
|
+
/**
|
|
19
|
+
* Owns a single OpenLayers Map instance for the providing component injector.
|
|
20
|
+
* Do not put Map/Layer objects into Angular template state.
|
|
21
|
+
*/
|
|
22
|
+
export class GeoMapService {
|
|
23
|
+
layerService = inject(GeoMapLayerService);
|
|
24
|
+
projection = inject(GeoMapProjectionService);
|
|
25
|
+
map = null;
|
|
26
|
+
managedLayers = new Map();
|
|
27
|
+
listenerKeys = [];
|
|
28
|
+
resizeObserver = null;
|
|
29
|
+
resizeCleanup = null;
|
|
30
|
+
activeBasemapId = GEO_MAP_BASEMAP_LAYER_ID;
|
|
31
|
+
highlightLayer = null;
|
|
32
|
+
highlightSource = null;
|
|
33
|
+
getMap() {
|
|
34
|
+
return this.map;
|
|
35
|
+
}
|
|
36
|
+
isInitialized() {
|
|
37
|
+
return this.map != null;
|
|
38
|
+
}
|
|
39
|
+
init(options) {
|
|
40
|
+
if (this.map) {
|
|
41
|
+
console.warn('[GeoMapService] Map already initialized; returning existing instance.');
|
|
42
|
+
return this.map;
|
|
43
|
+
}
|
|
44
|
+
if (!options.target) {
|
|
45
|
+
throw new Error('Map target element is required.');
|
|
46
|
+
}
|
|
47
|
+
const { width, height } = options.target.getBoundingClientRect();
|
|
48
|
+
if (width === 0 || height === 0) {
|
|
49
|
+
console.warn('[GeoMapService] Map container has zero size; call updateSize() after layout.');
|
|
50
|
+
}
|
|
51
|
+
this.projection.ensureRegistered(options.viewProjection);
|
|
52
|
+
const controls = defaultControls({
|
|
53
|
+
zoom: options.showZoomControl !== false,
|
|
54
|
+
rotate: false,
|
|
55
|
+
attribution: false,
|
|
56
|
+
}).extend([new ScaleLine({ units: 'metric' })]);
|
|
57
|
+
if (options.showMousePosition) {
|
|
58
|
+
const mouseProj = options.mousePositionProjection ?? 'EPSG:4326';
|
|
59
|
+
this.projection.ensureRegistered(mouseProj);
|
|
60
|
+
controls.push(new MousePosition({
|
|
61
|
+
coordinateFormat: createStringXY(mouseProj === 'EPSG:4326' ? 6 : 2),
|
|
62
|
+
projection: mouseProj,
|
|
63
|
+
className: 'geo-map__mouse-position',
|
|
64
|
+
placeholder: '',
|
|
65
|
+
}));
|
|
66
|
+
}
|
|
67
|
+
const view = new View({
|
|
68
|
+
center: options.center,
|
|
69
|
+
zoom: options.zoom,
|
|
70
|
+
minZoom: options.minZoom,
|
|
71
|
+
maxZoom: options.maxZoom,
|
|
72
|
+
projection: options.viewProjection,
|
|
73
|
+
});
|
|
74
|
+
this.map = new OlMap({
|
|
75
|
+
target: options.target,
|
|
76
|
+
view,
|
|
77
|
+
controls,
|
|
78
|
+
layers: [],
|
|
79
|
+
});
|
|
80
|
+
if (options.basemap != null) {
|
|
81
|
+
const basemapCreated = this.layerService.createFromBasemapInput(options.basemap);
|
|
82
|
+
this.addManagedLayer(basemapCreated);
|
|
83
|
+
this.activeBasemapId = basemapCreated.id;
|
|
84
|
+
}
|
|
85
|
+
this.syncLayers(options.layers ?? [], { replaceBasemapShortcut: false });
|
|
86
|
+
this.observeResize(options.target);
|
|
87
|
+
// Ensure correct canvas size after paint
|
|
88
|
+
queueMicrotask(() => this.updateSize());
|
|
89
|
+
return this.map;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Sync layer stack with configs. Preserves OL layers when only visibility/opacity change.
|
|
93
|
+
*/
|
|
94
|
+
syncLayers(configs, options) {
|
|
95
|
+
if (!this.map) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const nextIds = new Set(configs.map((c) => c.id));
|
|
99
|
+
if (options?.replaceBasemapShortcut === false) {
|
|
100
|
+
// Keep existing basemap shortcut layer unless configs include it.
|
|
101
|
+
}
|
|
102
|
+
// Remove obsolete (except reserved basemap shortcut when not in configs)
|
|
103
|
+
for (const [id, managed] of this.managedLayers) {
|
|
104
|
+
const keepBasemap = id === GEO_MAP_BASEMAP_LAYER_ID &&
|
|
105
|
+
options?.replaceBasemapShortcut === false &&
|
|
106
|
+
!nextIds.has(id);
|
|
107
|
+
if (!nextIds.has(id) && !keepBasemap) {
|
|
108
|
+
this.map.removeLayer(managed.layer);
|
|
109
|
+
this.managedLayers.delete(id);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
// Sort by zIndex for predictable stacking
|
|
113
|
+
const sorted = [...configs].sort((a, b) => (a.zIndex ?? 0) - (b.zIndex ?? 0));
|
|
114
|
+
for (const config of sorted) {
|
|
115
|
+
const existing = this.managedLayers.get(config.id);
|
|
116
|
+
if (!existing) {
|
|
117
|
+
const created = this.layerService.createLayer(config);
|
|
118
|
+
this.addManagedLayer(created);
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
if (this.layerService.needsRecreate(existing.config, config)) {
|
|
122
|
+
this.map.removeLayer(existing.layer);
|
|
123
|
+
const created = this.layerService.createLayer(config);
|
|
124
|
+
this.addManagedLayer(created);
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
this.layerService.patchLayer(existing.layer, config);
|
|
128
|
+
existing.config = config;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
this.enforceSingleBasemap();
|
|
132
|
+
}
|
|
133
|
+
setLayerVisibility(layerId, visible) {
|
|
134
|
+
const managed = this.managedLayers.get(layerId);
|
|
135
|
+
if (!managed || !this.map) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
if (managed.config.basemap && visible) {
|
|
139
|
+
this.activeBasemapId = layerId;
|
|
140
|
+
this.layerService.resolveBasemapExclusive([...this.managedLayers.values()], this.activeBasemapId);
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
if (managed.config.basemap && !visible) {
|
|
144
|
+
// Keep at least one basemap if possible
|
|
145
|
+
const otherBasemap = [...this.managedLayers.values()].find((item) => item.config.basemap && item.id !== layerId);
|
|
146
|
+
if (otherBasemap) {
|
|
147
|
+
this.activeBasemapId = otherBasemap.id;
|
|
148
|
+
this.layerService.resolveBasemapExclusive([...this.managedLayers.values()], this.activeBasemapId);
|
|
149
|
+
}
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
this.layerService.setVisible(managed.layer, visible);
|
|
153
|
+
managed.config = { ...managed.config, visible };
|
|
154
|
+
}
|
|
155
|
+
setLayerOpacity(layerId, opacity) {
|
|
156
|
+
const managed = this.managedLayers.get(layerId);
|
|
157
|
+
if (!managed) {
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
this.layerService.setOpacity(managed.layer, opacity);
|
|
161
|
+
managed.config = { ...managed.config, opacity };
|
|
162
|
+
}
|
|
163
|
+
getManagedLayers() {
|
|
164
|
+
return [...this.managedLayers.values()];
|
|
165
|
+
}
|
|
166
|
+
setCenter(center, zoom) {
|
|
167
|
+
const view = this.map?.getView();
|
|
168
|
+
if (!view) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
const current = view.getCenter();
|
|
172
|
+
const sameCenter = current != null &&
|
|
173
|
+
current.length >= 2 &&
|
|
174
|
+
Math.abs(current[0] - center[0]) < 1e-6 &&
|
|
175
|
+
Math.abs(current[1] - center[1]) < 1e-6;
|
|
176
|
+
if (!sameCenter) {
|
|
177
|
+
view.setCenter(center);
|
|
178
|
+
}
|
|
179
|
+
if (zoom != null) {
|
|
180
|
+
this.setZoom(zoom);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
setZoom(zoom) {
|
|
184
|
+
const view = this.map?.getView();
|
|
185
|
+
if (!view) {
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
const current = view.getZoom();
|
|
189
|
+
if (current != null && Math.abs(current - zoom) < 1e-6) {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
view.setZoom(zoom);
|
|
193
|
+
}
|
|
194
|
+
getZoom() {
|
|
195
|
+
return this.map?.getView().getZoom() ?? undefined;
|
|
196
|
+
}
|
|
197
|
+
zoomBy(delta) {
|
|
198
|
+
const view = this.map?.getView();
|
|
199
|
+
if (!view) {
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
const zoom = view.getZoom();
|
|
203
|
+
if (zoom == null) {
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
const next = Math.min(view.getMaxZoom() ?? GEO_MAP_DEFAULT_MAX_ZOOM, Math.max(view.getMinZoom() ?? 0, zoom + delta));
|
|
207
|
+
view.animate({ zoom: next, duration: 180 });
|
|
208
|
+
}
|
|
209
|
+
/** Replace the shortcut basemap layer (`GEO_MAP_BASEMAP_LAYER_ID`). */
|
|
210
|
+
setBasemap(basemap) {
|
|
211
|
+
if (!this.map) {
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
const existing = this.managedLayers.get(GEO_MAP_BASEMAP_LAYER_ID);
|
|
215
|
+
if (existing) {
|
|
216
|
+
this.map.removeLayer(existing.layer);
|
|
217
|
+
this.managedLayers.delete(GEO_MAP_BASEMAP_LAYER_ID);
|
|
218
|
+
}
|
|
219
|
+
const created = this.layerService.createFromBasemapInput(basemap);
|
|
220
|
+
this.addManagedLayer(created);
|
|
221
|
+
this.activeBasemapId = created.id;
|
|
222
|
+
this.enforceSingleBasemap();
|
|
223
|
+
// Basemap should sit under overlays
|
|
224
|
+
created.layer.setZIndex(created.config.zIndex ?? 0);
|
|
225
|
+
}
|
|
226
|
+
fitExtent(extent, options) {
|
|
227
|
+
const view = this.map?.getView();
|
|
228
|
+
if (!view) {
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
view.fit(extent, {
|
|
232
|
+
padding: options?.padding ?? [48, 48, 48, 48],
|
|
233
|
+
maxZoom: options?.maxZoom ?? 14,
|
|
234
|
+
duration: options?.duration ?? 250,
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
/** Fit lon/lat extent (EPSG:4326) after transforming to the active view projection. */
|
|
238
|
+
fitLonLatExtent(extent4326, options) {
|
|
239
|
+
const map = this.map;
|
|
240
|
+
if (!map) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
const viewProj = map.getView().getProjection().getCode();
|
|
244
|
+
const extent = transformExtent(extent4326, 'EPSG:4326', viewProj);
|
|
245
|
+
this.fitExtent(extent, options);
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Fit the default (or provided) province extent — TCQH.14 “xem toàn tỉnh”.
|
|
249
|
+
* Distinct from browser fullscreen (TCQH.15).
|
|
250
|
+
*/
|
|
251
|
+
fitProvince(extent4326 = GEO_MAP_DEFAULT_PROVINCE_EXTENT_4326, options) {
|
|
252
|
+
this.fitLonLatExtent([...extent4326], {
|
|
253
|
+
maxZoom: 11,
|
|
254
|
+
duration: 400,
|
|
255
|
+
padding: [56, 56, 56, 56],
|
|
256
|
+
...options,
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Highlight search / select results (TCQH.7–12). Pass GeoJSON Feature or FeatureCollection.
|
|
261
|
+
*/
|
|
262
|
+
setHighlightFromGeoJson(data, options) {
|
|
263
|
+
const map = this.map;
|
|
264
|
+
if (!map) {
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
this.ensureHighlightLayer();
|
|
268
|
+
const viewProj = map.getView().getProjection().getCode();
|
|
269
|
+
const format = new GeoJSON();
|
|
270
|
+
let features = [];
|
|
271
|
+
try {
|
|
272
|
+
features = format.readFeatures(data, {
|
|
273
|
+
dataProjection: options?.dataProjection ?? 'EPSG:4326',
|
|
274
|
+
featureProjection: viewProj,
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
catch (err) {
|
|
278
|
+
console.error('[GeoMapService] Invalid highlight GeoJSON', err);
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
this.setHighlightFeatures(features, options);
|
|
282
|
+
}
|
|
283
|
+
setHighlightFeatures(features, options) {
|
|
284
|
+
if (!this.map) {
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
this.ensureHighlightLayer();
|
|
288
|
+
this.highlightSource?.clear();
|
|
289
|
+
if (features.length) {
|
|
290
|
+
this.highlightSource?.addFeatures(features);
|
|
291
|
+
}
|
|
292
|
+
const shouldFit = options?.fit !== false && features.length > 0;
|
|
293
|
+
if (shouldFit && this.highlightSource) {
|
|
294
|
+
const extent = this.highlightSource.getExtent();
|
|
295
|
+
if (extent &&
|
|
296
|
+
Number.isFinite(extent[0]) &&
|
|
297
|
+
Number.isFinite(extent[1]) &&
|
|
298
|
+
Number.isFinite(extent[2]) &&
|
|
299
|
+
Number.isFinite(extent[3])) {
|
|
300
|
+
this.fitExtent(extent, {
|
|
301
|
+
maxZoom: 17,
|
|
302
|
+
duration: 280,
|
|
303
|
+
...options?.fitOptions,
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
clearHighlight() {
|
|
309
|
+
this.highlightSource?.clear();
|
|
310
|
+
}
|
|
311
|
+
updateSize() {
|
|
312
|
+
this.map?.updateSize();
|
|
313
|
+
}
|
|
314
|
+
onClick(handler) {
|
|
315
|
+
const map = this.map;
|
|
316
|
+
if (!map) {
|
|
317
|
+
return () => undefined;
|
|
318
|
+
}
|
|
319
|
+
const key = map.on('singleclick', (evt) => {
|
|
320
|
+
const coordinate = evt.coordinate;
|
|
321
|
+
const lonLat = this.projection.transformCoordinate(coordinate, map.getView().getProjection().getCode(), 'EPSG:4326');
|
|
322
|
+
handler({
|
|
323
|
+
coordinate: [...coordinate],
|
|
324
|
+
lonLat,
|
|
325
|
+
pixel: [evt.pixel[0], evt.pixel[1]],
|
|
326
|
+
originalEvent: evt.originalEvent,
|
|
327
|
+
});
|
|
328
|
+
});
|
|
329
|
+
this.listenerKeys.push(key);
|
|
330
|
+
return () => {
|
|
331
|
+
unByKey(key);
|
|
332
|
+
this.listenerKeys = this.listenerKeys.filter((k) => k !== key);
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Emit after the view settles (`moveend`), not on every resolution tick —
|
|
337
|
+
* continuous emitters flood Storybook Actions / host bindings and cause UI flicker.
|
|
338
|
+
*/
|
|
339
|
+
onViewChange(handler) {
|
|
340
|
+
const map = this.map;
|
|
341
|
+
if (!map) {
|
|
342
|
+
return () => undefined;
|
|
343
|
+
}
|
|
344
|
+
const view = map.getView();
|
|
345
|
+
const emit = () => {
|
|
346
|
+
handler({
|
|
347
|
+
center: [...(view.getCenter() ?? [0, 0])],
|
|
348
|
+
zoom: view.getZoom() ?? 0,
|
|
349
|
+
resolution: view.getResolution() ?? 0,
|
|
350
|
+
rotation: view.getRotation(),
|
|
351
|
+
});
|
|
352
|
+
};
|
|
353
|
+
const key = map.on('moveend', emit);
|
|
354
|
+
this.listenerKeys.push(key);
|
|
355
|
+
return () => {
|
|
356
|
+
unByKey(key);
|
|
357
|
+
this.listenerKeys = this.listenerKeys.filter((k) => k !== key);
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Tear down map, listeners, and resize observer. Safe to call multiple times.
|
|
362
|
+
*/
|
|
363
|
+
destroy() {
|
|
364
|
+
unByKey(this.listenerKeys);
|
|
365
|
+
this.listenerKeys = [];
|
|
366
|
+
this.resizeCleanup?.();
|
|
367
|
+
this.resizeCleanup = null;
|
|
368
|
+
this.resizeObserver = null;
|
|
369
|
+
if (this.highlightLayer && this.map) {
|
|
370
|
+
this.map.removeLayer(this.highlightLayer);
|
|
371
|
+
}
|
|
372
|
+
this.highlightLayer = null;
|
|
373
|
+
this.highlightSource = null;
|
|
374
|
+
if (this.map) {
|
|
375
|
+
this.map.setTarget(undefined);
|
|
376
|
+
this.map.dispose();
|
|
377
|
+
this.map = null;
|
|
378
|
+
}
|
|
379
|
+
this.managedLayers.clear();
|
|
380
|
+
}
|
|
381
|
+
ensureHighlightLayer() {
|
|
382
|
+
const map = this.map;
|
|
383
|
+
if (!map) {
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
if (this.highlightLayer && this.highlightSource) {
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
this.highlightSource = new VectorSource();
|
|
390
|
+
this.highlightLayer = new VectorLayer({
|
|
391
|
+
source: this.highlightSource,
|
|
392
|
+
properties: { geoLayerId: GEO_MAP_HIGHLIGHT_LAYER_ID },
|
|
393
|
+
style: this.createHighlightStyle(),
|
|
394
|
+
zIndex: 450,
|
|
395
|
+
updateWhileAnimating: true,
|
|
396
|
+
updateWhileInteracting: true,
|
|
397
|
+
});
|
|
398
|
+
map.addLayer(this.highlightLayer);
|
|
399
|
+
}
|
|
400
|
+
createHighlightStyle() {
|
|
401
|
+
const stroke = this.cssColor('--geo-color-warning-default', '#f59e0b');
|
|
402
|
+
const fill = this.cssColor('--geo-color-warning-default', '#f59e0b', 0.22);
|
|
403
|
+
const pin = this.cssColor('--geo-color-error-default', '#dc2626');
|
|
404
|
+
const pinIcon = this.createPinIconDataUri(pin);
|
|
405
|
+
const areaStyle = new Style({
|
|
406
|
+
fill: new Fill({ color: fill }),
|
|
407
|
+
stroke: new Stroke({
|
|
408
|
+
color: stroke,
|
|
409
|
+
width: 3,
|
|
410
|
+
}),
|
|
411
|
+
});
|
|
412
|
+
const pointStyle = new Style({
|
|
413
|
+
image: new Icon({
|
|
414
|
+
anchor: [0.5, 1],
|
|
415
|
+
anchorXUnits: 'fraction',
|
|
416
|
+
anchorYUnits: 'fraction',
|
|
417
|
+
src: pinIcon,
|
|
418
|
+
scale: 1,
|
|
419
|
+
}),
|
|
420
|
+
});
|
|
421
|
+
return (feature) => {
|
|
422
|
+
const type = feature.getGeometry()?.getType();
|
|
423
|
+
if (type === 'Point' || type === 'MultiPoint') {
|
|
424
|
+
return pointStyle;
|
|
425
|
+
}
|
|
426
|
+
return areaStyle;
|
|
427
|
+
};
|
|
428
|
+
}
|
|
429
|
+
/** Inline SVG map pin for clicked / selected points. */
|
|
430
|
+
createPinIconDataUri(color) {
|
|
431
|
+
const svg = `
|
|
432
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="40" viewBox="0 0 32 40">
|
|
433
|
+
<path fill="${color}" stroke="#ffffff" stroke-width="1.75"
|
|
434
|
+
d="M16 1C9.373 1 4 6.373 4 13c0 8.284 12 26 12 26s12-17.716 12-26C28 6.373 22.627 1 16 1z"/>
|
|
435
|
+
<circle cx="16" cy="13" r="4.5" fill="#ffffff"/>
|
|
436
|
+
</svg>
|
|
437
|
+
`.trim();
|
|
438
|
+
return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`;
|
|
439
|
+
}
|
|
440
|
+
/** Resolve a design token for OpenLayers canvas styles. */
|
|
441
|
+
cssColor(token, fallback, alpha) {
|
|
442
|
+
if (typeof document === 'undefined') {
|
|
443
|
+
return alpha == null ? fallback : this.withAlpha(fallback, alpha);
|
|
444
|
+
}
|
|
445
|
+
const raw = getComputedStyle(document.documentElement)
|
|
446
|
+
.getPropertyValue(token)
|
|
447
|
+
.trim();
|
|
448
|
+
const color = raw || fallback;
|
|
449
|
+
return alpha == null ? color : this.withAlpha(color, alpha);
|
|
450
|
+
}
|
|
451
|
+
withAlpha(color, alpha) {
|
|
452
|
+
if (color.startsWith('rgba(') || color.startsWith('hsla(')) {
|
|
453
|
+
return color;
|
|
454
|
+
}
|
|
455
|
+
if (color.startsWith('rgb(')) {
|
|
456
|
+
return color.replace('rgb(', 'rgba(').replace(')', `, ${alpha})`);
|
|
457
|
+
}
|
|
458
|
+
if (color.startsWith('#')) {
|
|
459
|
+
const hex = color.slice(1);
|
|
460
|
+
const full = hex.length === 3
|
|
461
|
+
? hex
|
|
462
|
+
.split('')
|
|
463
|
+
.map((c) => c + c)
|
|
464
|
+
.join('')
|
|
465
|
+
: hex;
|
|
466
|
+
if (full.length !== 6) {
|
|
467
|
+
return color;
|
|
468
|
+
}
|
|
469
|
+
const r = parseInt(full.slice(0, 2), 16);
|
|
470
|
+
const g = parseInt(full.slice(2, 4), 16);
|
|
471
|
+
const b = parseInt(full.slice(4, 6), 16);
|
|
472
|
+
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
|
|
473
|
+
}
|
|
474
|
+
return color;
|
|
475
|
+
}
|
|
476
|
+
addManagedLayer(created) {
|
|
477
|
+
if (!this.map) {
|
|
478
|
+
return;
|
|
479
|
+
}
|
|
480
|
+
this.managedLayers.set(created.id, created);
|
|
481
|
+
this.map.addLayer(created.layer);
|
|
482
|
+
}
|
|
483
|
+
enforceSingleBasemap() {
|
|
484
|
+
const basemaps = [...this.managedLayers.values()].filter((item) => item.config.basemap);
|
|
485
|
+
if (basemaps.length === 0) {
|
|
486
|
+
return;
|
|
487
|
+
}
|
|
488
|
+
const active = basemaps.find((item) => item.id === this.activeBasemapId && (item.config.visible ?? true)) ??
|
|
489
|
+
basemaps.find((item) => item.config.visible ?? true) ??
|
|
490
|
+
basemaps[0];
|
|
491
|
+
this.activeBasemapId = active.id;
|
|
492
|
+
this.layerService.resolveBasemapExclusive(basemaps, this.activeBasemapId);
|
|
493
|
+
}
|
|
494
|
+
observeResize(target) {
|
|
495
|
+
if (typeof ResizeObserver === 'undefined') {
|
|
496
|
+
return;
|
|
497
|
+
}
|
|
498
|
+
let lastWidth = -1;
|
|
499
|
+
let lastHeight = -1;
|
|
500
|
+
let rafId = null;
|
|
501
|
+
this.resizeObserver = new ResizeObserver((entries) => {
|
|
502
|
+
const rect = entries[0]?.contentRect;
|
|
503
|
+
if (!rect) {
|
|
504
|
+
return;
|
|
505
|
+
}
|
|
506
|
+
const width = Math.round(rect.width);
|
|
507
|
+
const height = Math.round(rect.height);
|
|
508
|
+
if (width === 0 || height === 0) {
|
|
509
|
+
return;
|
|
510
|
+
}
|
|
511
|
+
if (width === lastWidth && height === lastHeight) {
|
|
512
|
+
return;
|
|
513
|
+
}
|
|
514
|
+
lastWidth = width;
|
|
515
|
+
lastHeight = height;
|
|
516
|
+
if (rafId != null) {
|
|
517
|
+
cancelAnimationFrame(rafId);
|
|
518
|
+
}
|
|
519
|
+
rafId = requestAnimationFrame(() => {
|
|
520
|
+
rafId = null;
|
|
521
|
+
this.updateSize();
|
|
522
|
+
});
|
|
523
|
+
});
|
|
524
|
+
this.resizeObserver.observe(target);
|
|
525
|
+
this.resizeCleanup = () => {
|
|
526
|
+
if (rafId != null) {
|
|
527
|
+
cancelAnimationFrame(rafId);
|
|
528
|
+
rafId = null;
|
|
529
|
+
}
|
|
530
|
+
this.resizeObserver?.disconnect();
|
|
531
|
+
this.resizeObserver = null;
|
|
532
|
+
};
|
|
533
|
+
}
|
|
534
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: GeoMapService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
535
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: GeoMapService });
|
|
536
|
+
}
|
|
537
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: GeoMapService, decorators: [{
|
|
538
|
+
type: Injectable
|
|
539
|
+
}] });
|
|
540
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VvLW1hcC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZ2VvLXVpL3NyYy9saWIvZmlnbWEvZ2VvLW1hcC9zZXJ2aWNlcy9nZW8tbWFwLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkQsT0FBTyxLQUFLLE1BQU0sUUFBUSxDQUFDO0FBQzNCLE9BQU8sSUFBSSxNQUFNLFNBQVMsQ0FBQztBQUUzQixPQUFPLEVBQUUsUUFBUSxJQUFJLGVBQWUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ2xFLE9BQU8sU0FBUyxNQUFNLHNCQUFzQixDQUFDO0FBQzdDLE9BQU8sYUFBYSxNQUFNLDBCQUEwQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDL0MsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUl4QyxPQUFPLE9BQU8sTUFBTSxtQkFBbUIsQ0FBQztBQUN4QyxPQUFPLFdBQVcsTUFBTSxpQkFBaUIsQ0FBQztBQUMxQyxPQUFPLFlBQVksTUFBTSxrQkFBa0IsQ0FBQztBQUM1QyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQzFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFFckQsT0FBTyxFQUNMLHdCQUF3QixFQUN4Qix3QkFBd0IsRUFDeEIsb0NBQW9DLEVBQ3BDLDBCQUEwQixHQUMzQixNQUFNLHNCQUFzQixDQUFDO0FBUzlCLE9BQU8sRUFFTCxrQkFBa0IsR0FDbkIsTUFBTSx5QkFBeUIsQ0FBQztBQUNqQyxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQzs7QUFZdkU7OztHQUdHO0FBRUgs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QVUsRUFBRSxDQUFDO1lBQ3BCLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUVwQyxJQUFJLENBQUMsYUFBYSxHQUFHLEdBQUcsRUFBRTtZQUN4QixJQUFJLEtBQUssSUFBSSxJQUFJLEVBQUUsQ0FBQztnQkFDbEIsb0JBQW9CLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQzVCLEtBQUssR0FBRyxJQUFJLENBQUM7WUFDZixDQUFDO1lBQ0QsSUFBSSxDQUFDLGNBQWMsRUFBRSxVQUFVLEVBQUUsQ0FBQztZQUNsQyxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQztRQUM3QixDQUFDLENBQUM7SUFDSixDQUFDO3dHQTNtQlUsYUFBYTs0R0FBYixhQUFhOzs0RkFBYixhQUFhO2tCQUR6QixVQUFVIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgaW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgT2xNYXAgZnJvbSAnb2wvTWFwJztcbmltcG9ydCBWaWV3IGZyb20gJ29sL1ZpZXcnO1xuaW1wb3J0IHR5cGUgeyBDb29yZGluYXRlIH0gZnJvbSAnb2wvY29vcmRpbmF0ZSc7XG5pbXBvcnQgeyBkZWZhdWx0cyBhcyBkZWZhdWx0Q29udHJvbHMgfSBmcm9tICdvbC9jb250cm9sL2RlZmF1bHRzJztcbmltcG9ydCBTY2FsZUxpbmUgZnJvbSAnb2wvY29udHJvbC9TY2FsZUxpbmUnO1xuaW1wb3J0IE1vdXNlUG9zaXRpb24gZnJvbSAnb2wvY29udHJvbC9Nb3VzZVBvc2l0aW9uJztcbmltcG9ydCB7IGNyZWF0ZVN0cmluZ1hZIH0gZnJvbSAnb2wvY29vcmRpbmF0ZSc7XG5pbXBvcnQgeyB1bkJ5S2V5IH0gZnJvbSAnb2wvT2JzZXJ2YWJsZSc7XG5pbXBvcnQgdHlwZSB7IEV2ZW50c0tleSB9IGZyb20gJ29sL2V2ZW50cyc7XG5pbXBvcnQgdHlwZSBGZWF0dXJlIGZyb20gJ29sL0ZlYXR1cmUnO1xuaW1wb3J0IHR5cGUgR2VvbWV0cnkgZnJvbSAnb2wvZ2VvbS9HZW9tZXRyeSc7XG5pbXBvcnQgR2VvSlNPTiBmcm9tICdvbC9mb3JtYXQvR2VvSlNPTic7XG5pbXBvcnQgVmVjdG9yTGF5ZXIgZnJvbSAnb2wvbGF5ZXIvVmVjdG9yJztcbmltcG9ydCBWZWN0b3JTb3VyY2UgZnJvbSAnb2wvc291cmNlL1ZlY3Rvcic7XG5pbXBvcnQgeyB0cmFuc2Zvcm1FeHRlbnQgfSBmcm9tICdvbC9wcm9qJztcbmltcG9ydCB7IEZpbGwsIEljb24sIFN0cm9rZSwgU3R5bGUgfSBmcm9tICdvbC9zdHlsZSc7XG5pbXBvcnQgdHlwZSB7IFN0eWxlTGlrZSB9IGZyb20gJ29sL3N0eWxlL1N0eWxlJztcbmltcG9ydCB7XG4gIEdFT19NQVBfQkFTRU1BUF9MQVlFUl9JRCxcbiAgR0VPX01BUF9ERUZBVUxUX01BWF9aT09NLFxuICBHRU9fTUFQX0RFRkFVTFRfUFJPVklOQ0VfRVhURU5UXzQzMjYsXG4gIEdFT19NQVBfSElHSExJR0hUX0xBWUVSX0lELFxufSBmcm9tICcuLi9nZW8tbWFwLmNvbnN0YW50cyc7XG5pbXBvcnQgdHlwZSB7XG4gIEdlb01hcEJhc2VtYXBJbnB1dCxcbiAgR2VvTWFwQ2xpY2tFdmVudCxcbiAgR2VvTWFwSGlnaGxpZ2h0T3B0aW9ucyxcbiAgR2VvTWFwTGF5ZXJDb25maWcsXG4gIEdlb01hcFZpZXdDaGFuZ2VFdmVudCxcbiAgTWFwSW5pdE9wdGlvbnMsXG59IGZyb20gJy4uL2dlby1tYXAudHlwZXMnO1xuaW1wb3J0IHtcbiAgQ3JlYXRlZE1hcExheWVyLFxuICBHZW9NYXBMYXllclNlcnZpY2UsXG59IGZyb20gJy4vZ2VvLW1hcC1sYXllci5zZXJ2aWNlJztcbmltcG9ydCB7IEdlb01hcFByb2plY3Rpb25TZXJ2aWNlIH0gZnJvbSAnLi9nZW8tbWFwLXByb2plY3Rpb24uc2VydmljZSc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgR2VvTWFwQ3JlYXRlT3B0aW9ucyBleHRlbmRzIE1hcEluaXRPcHRpb25zIHtcbiAgYmFzZW1hcD86IEdlb01hcEJhc2VtYXBJbnB1dDtcbiAgbGF5ZXJzPzogR2VvTWFwTGF5ZXJDb25maWdbXTtcbiAgLyoqIFNob3cgT0wgTW91c2VQb3NpdGlvbiBjb250cm9sIChyYXc7IFVJIGNocm9tZSBtYXkgd3JhcCBsYXRlcikuICovXG4gIHNob3dNb3VzZVBvc2l0aW9uPzogYm9vbGVhbjtcbiAgbW91c2VQb3NpdGlvblByb2plY3Rpb24/OiBzdHJpbmc7XG4gIC8qKiBXaGVuIGZhbHNlLCBoaWRlIGJ1aWx0LWluIE9MIHpvb20gKHVzZSBgZ2VvLW1hcC16b29tYCBpbnN0ZWFkKS4gKi9cbiAgc2hvd1pvb21Db250cm9sPzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBPd25zIGEgc2luZ2xlIE9wZW5MYXllcnMgTWFwIGluc3RhbmNlIGZvciB0aGUgcHJvdmlkaW5nIGNvbXBvbmVudCBpbmplY3Rvci5cbiAqIERvIG5vdCBwdXQgTWFwL0xheWVyIG9iamVjdHMgaW50byBBbmd1bGFyIHRlbXBsYXRlIHN0YXRlLlxuICovXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgR2VvTWFwU2VydmljZSB7XG4gIHByaXZhdGUgcmVhZG9ubHkgbGF5ZXJTZXJ2aWNlID0gaW5qZWN0KEdlb01hcExheWVyU2VydmljZSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgcHJvamVjdGlvbiA9IGluamVjdChHZW9NYXBQcm9qZWN0aW9uU2VydmljZSk7XG5cbiAgcHJpdmF0ZSBtYXA6IE9sTWFwIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgbWFuYWdlZExheWVycyA9IG5ldyBNYXA8c3RyaW5nLCBDcmVhdGVkTWFwTGF5ZXI+KCk7XG4gIHByaXZhdGUgbGlzdGVuZXJLZXlzOiBFdmVudHNLZXlbXSA9IFtdO1xuICBwcml2YXRlIHJlc2l6ZU9ic2VydmVyOiBSZXNpemVPYnNlcnZlciB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHJlc2l6ZUNsZWFudXA6ICgoKSA9PiB2b2lkKSB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGFjdGl2ZUJhc2VtYXBJZCA9IEdFT19NQVBfQkFTRU1BUF9MQVlFUl9JRDtcbiAgcHJpdmF0ZSBoaWdobGlnaHRMYXllcjogVmVjdG9yTGF5ZXI8VmVjdG9yU291cmNlPEZlYXR1cmU8R2VvbWV0cnk+Pj4gfCBudWxsID1cbiAgICBudWxsO1xuICBwcml2YXRlIGhpZ2hsaWdodFNvdXJjZTogVmVjdG9yU291cmNlPEZlYXR1cmU8R2VvbWV0cnk+PiB8IG51bGwgPSBudWxsO1xuXG4gIGdldE1hcCgpOiBPbE1hcCB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLm1hcDtcbiAgfVxuXG4gIGlzSW5pdGlhbGl6ZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMubWFwICE9IG51bGw7XG4gIH1cblxuICBpbml0KG9wdGlvbnM6IEdlb01hcENyZWF0ZU9wdGlvbnMpOiBPbE1hcCB7XG4gICAgaWYgKHRoaXMubWFwKSB7XG4gICAgICBjb25zb2xlLndhcm4oJ1tHZW9NYXBTZXJ2aWNlXSBNYXAgYWxyZWFkeSBpbml0aWFsaXplZDsgcmV0dXJuaW5nIGV4aXN0aW5nIGluc3RhbmNlLicpO1xuICAgICAgcmV0dXJuIHRoaXMubWFwO1xuICAgIH1cblxuICAgIGlmICghb3B0aW9ucy50YXJnZXQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTWFwIHRhcmdldCBlbGVtZW50IGlzIHJlcXVpcmVkLicpO1xuICAgIH1cbiAgICBjb25zdCB7IHdpZHRoLCBoZWlnaHQgfSA9IG9wdGlvbnMudGFyZ2V0LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIGlmICh3aWR0aCA9PT0gMCB8fCBoZWlnaHQgPT09IDApIHtcbiAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgJ1tHZW9NYXBTZXJ2aWNlXSBNYXAgY29udGFpbmVyIGhhcyB6ZXJvIHNpemU7IGNhbGwgdXBkYXRlU2l6ZSgpIGFmdGVyIGxheW91dC4nLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICB0aGlzLnByb2plY3Rpb24uZW5zdXJlUmVnaXN0ZXJlZChvcHRpb25zLnZpZXdQcm9qZWN0aW9uKTtcblxuICAgIGNvbnN0IGNvbnRyb2xzID0gZGVmYXVsdENvbnRyb2xzKHtcbiAgICAgIHpvb206IG9wdGlvbnMuc2hvd1pvb21Db250cm9sICE9PSBmYWxzZSxcbiAgICAgIHJvdGF0ZTogZmFsc2UsXG4gICAgICBhdHRyaWJ1dGlvbjogZmFsc2UsXG4gICAgfSkuZXh0ZW5kKFtuZXcgU2NhbGVMaW5lKHsgdW5pdHM6ICdtZXRyaWMnIH0pXSk7XG5cbiAgICBpZiAob3B0aW9ucy5zaG93TW91c2VQb3NpdGlvbikge1xuICAgICAgY29uc3QgbW91c2VQcm9qID0gb3B0aW9ucy5tb3VzZVBvc2l0aW9uUHJvamVjdGlvbiA/PyAnRVBTRzo0MzI2JztcbiAgICAgIHRoaXMucHJvamVjdGlvbi5lbnN1cmVSZWdpc3RlcmVkKG1vdXNlUHJvaik7XG4gICAgICBjb250cm9scy5wdXNoKFxuICAgICAgICBuZXcgTW91c2VQb3NpdGlvbih7XG4gICAgICAgICAgY29vcmRpbmF0ZUZvcm1hdDogY3JlYXRlU3RyaW5nWFkobW91c2VQcm9qID09PSAnRVBTRzo0MzI2JyA/IDYgOiAyKSxcbiAgICAgICAgICBwcm9qZWN0aW9uOiBtb3VzZVByb2osXG4gICAgICAgICAgY2xhc3NOYW1lOiAnZ2VvLW1hcF9fbW91c2UtcG9zaXRpb24nLFxuICAgICAgICAgIHBsYWNlaG9sZGVyOiAnJyxcbiAgICAgICAgfSksXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IHZpZXcgPSBuZXcgVmlldyh7XG4gICAgICBjZW50ZXI6IG9wdGlvbnMuY2VudGVyLFxuICAgICAgem9vbTogb3B0aW9ucy56b29tLFxuICAgICAgbWluWm9vbTogb3B0aW9ucy5taW5ab29tLFxuICAgICAgbWF4Wm9vbTogb3B0aW9ucy5tYXhab29tLFxuICAgICAgcHJvamVjdGlvbjogb3B0aW9ucy52aWV3UHJvamVjdGlvbixcbiAgICB9KTtcblxuICAgIHRoaXMubWFwID0gbmV3IE9sTWFwKHtcbiAgICAgIHRhcmdldDogb3B0aW9ucy50YXJnZXQsXG4gICAgICB2aWV3LFxuICAgICAgY29udHJvbHMsXG4gICAgICBsYXllcnM6IFtdLFxuICAgIH0pO1xuXG4gICAgaWYgKG9wdGlvbnMuYmFzZW1hcCAhPSBudWxsKSB7XG4gICAgICBjb25zdCBiYXNlbWFwQ3JlYXRlZCA9IHRoaXMubGF5ZXJTZXJ2aWNlLmNyZWF0ZUZyb21CYXNlbWFwSW5wdXQob3B0aW9ucy5iYXNlbWFwKTtcbiAgICAgIHRoaXMuYWRkTWFuYWdlZExheWVyKGJhc2VtYXBDcmVhdGVkKTtcbiAgICAgIHRoaXMuYWN0aXZlQmFzZW1hcElkID0gYmFzZW1hcENyZWF0ZWQuaWQ7XG4gICAgfVxuICAgIHRoaXMuc3luY0xheWVycyhvcHRpb25zLmxheWVycyA/PyBbXSwgeyByZXBsYWNlQmFzZW1hcFNob3J0Y3V0OiBmYWxzZSB9KTtcblxuICAgIHRoaXMub2JzZXJ2ZVJlc2l6ZShvcHRpb25zLnRhcmdldCk7XG4gICAgLy8gRW5zdXJlIGNvcnJlY3QgY2FudmFzIHNpemUgYWZ0ZXIgcGFpbnRcbiAgICBxdWV1ZU1pY3JvdGFzaygoKSA9PiB0aGlzLnVwZGF0ZVNpemUoKSk7XG5cbiAgICByZXR1cm4gdGhpcy5tYXA7XG4gIH1cblxuICAvKipcbiAgICogU3luYyBsYXllciBzdGFjayB3aXRoIGNvbmZpZ3MuIFByZXNlcnZlcyBPTCBsYXllcnMgd2hlbiBvbmx5IHZpc2liaWxpdHkvb3BhY2l0eSBjaGFuZ2UuXG4gICAqL1xuICBzeW5jTGF5ZXJzKFxuICAgIGNvbmZpZ3M6IEdlb01hcExheWVyQ29uZmlnW10sXG4gICAgb3B0aW9ucz86IHsgcmVwbGFjZUJhc2VtYXBTaG9ydGN1dD86IGJvb2xlYW4gfSxcbiAgKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLm1hcCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IG5leHRJZHMgPSBuZXcgU2V0KGNvbmZpZ3MubWFwKChjKSA9PiBjLmlkKSk7XG4gICAgaWYgKG9wdGlvbnM/LnJlcGxhY2VCYXNlbWFwU2hvcnRjdXQgPT09IGZhbHNlKSB7XG4gICAgICAvLyBLZWVwIGV4aXN0aW5nIGJhc2VtYXAgc2hvcnRjdXQgbGF5ZXIgdW5sZXNzIGNvbmZpZ3MgaW5jbHVkZSBpdC5cbiAgICB9XG5cbiAgICAvLyBSZW1vdmUgb2Jzb2xldGUgKGV4Y2VwdCByZXNlcnZlZCBiYXNlbWFwIHNob3J0Y3V0IHdoZW4gbm90IGluIGNvbmZpZ3MpXG4gICAgZm9yIChjb25zdCBbaWQsIG1hbmFnZWRdIG9mIHRoaXMubWFuYWdlZExheWVycykge1xuICAgICAgY29uc3Qga2VlcEJhc2VtYXAgPVxuICAgICAgICBpZCA9PT0gR0VPX01BUF9CQVNFTUFQX0xBWUVSX0lEICYmXG4gICAgICAgIG9wdGlvbnM/LnJlcGxhY2VCYXNlbWFwU2hvcnRjdXQgPT09IGZhbHNlICYmXG4gICAgICAgICFuZXh0SWRzLmhhcyhpZCk7XG4gICAgICBpZiAoIW5leHRJZHMuaGFzKGlkKSAmJiAha2VlcEJhc2VtYXApIHtcbiAgICAgICAgdGhpcy5tYXAucmVtb3ZlTGF5ZXIobWFuYWdlZC5sYXllcik7XG4gICAgICAgIHRoaXMubWFuYWdlZExheWVycy5kZWxldGUoaWQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFNvcnQgYnkgekluZGV4IGZvciBwcmVkaWN0YWJsZSBzdGFja2luZ1xuICAgIGNvbnN0IHNvcnRlZCA9IFsuLi5jb25maWdzXS5zb3J0KFxuICAgICAgKGEsIGIpID0+IChhLnpJbmRleCA/PyAwKSAtIChiLnpJbmRleCA/PyAwKSxcbiAgICApO1xuXG4gICAgZm9yIChjb25zdCBjb25maWcgb2Ygc29ydGVkKSB7XG4gICAgICBjb25zdCBleGlzdGluZyA9IHRoaXMubWFuYWdlZExheWVycy5nZXQoY29uZmlnLmlkKTtcbiAgICAgIGlmICghZXhpc3RpbmcpIHtcbiAgICAgICAgY29uc3QgY3JlYXRlZCA9IHRoaXMubGF5ZXJTZXJ2aWNlLmNyZWF0ZUxheWVyKGNvbmZpZyk7XG4gICAgICAgIHRoaXMuYWRkTWFuYWdlZExheWVyKGNyZWF0ZWQpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMubGF5ZXJTZXJ2aWNlLm5lZWRzUmVjcmVhdGUoZXhpc3RpbmcuY29uZmlnLCBjb25maWcpKSB7XG4gICAgICAgIHRoaXMubWFwLnJlbW92ZUxheWVyKGV4aXN0aW5nLmxheWVyKTtcbiAgICAgICAgY29uc3QgY3JlYXRlZCA9IHRoaXMubGF5ZXJTZXJ2aWNlLmNyZWF0ZUxheWVyKGNvbmZpZyk7XG4gICAgICAgIHRoaXMuYWRkTWFuYWdlZExheWVyKGNyZWF0ZWQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5sYXllclNlcnZpY2UucGF0Y2hMYXllcihleGlzdGluZy5sYXllciwgY29uZmlnKTtcbiAgICAgICAgZXhpc3RpbmcuY29uZmlnID0gY29uZmlnO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuZW5mb3JjZVNpbmdsZUJhc2VtYXAoKTtcbiAgfVxuXG4gIHNldExheWVyVmlzaWJpbGl0eShsYXllcklkOiBzdHJpbmcsIHZpc2libGU6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBjb25zdCBtYW5hZ2VkID0gdGhpcy5tYW5hZ2VkTGF5ZXJzLmdldChsYXllcklkKTtcbiAgICBpZiAoIW1hbmFnZWQgfHwgIXRoaXMubWFwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKG1hbmFnZWQuY29uZmlnLmJhc2VtYXAgJiYgdmlzaWJsZSkge1xuICAgICAgdGhpcy5hY3RpdmVCYXNlbWFwSWQgPSBsYXllcklkO1xuICAgICAgdGhpcy5sYXllclNlcnZpY2UucmVzb2x2ZUJhc2VtYXBFeGNsdXNpdmUoXG4gICAgICAgIFsuLi50aGlzLm1hbmFnZWRMYXllcnMudmFsdWVzKCldLFxuICAgICAgICB0aGlzLmFjdGl2ZUJhc2VtYXBJZCxcbiAgICAgICk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKG1hbmFnZWQuY29uZmlnLmJhc2VtYXAgJiYgIXZpc2libGUpIHtcbiAgICAgIC8vIEtlZXAgYXQgbGVhc3Qgb25lIGJhc2VtYXAgaWYgcG9zc2libGVcbiAgICAgIGNvbnN0IG90aGVyQmFzZW1hcCA9IFsuLi50aGlzLm1hbmFnZWRMYXllcnMudmFsdWVzKCldLmZpbmQoXG4gICAgICAgIChpdGVtKSA9PiBpdGVtLmNvbmZpZy5iYXNlbWFwICYmIGl0ZW0uaWQgIT09IGxheWVySWQsXG4gICAgICApO1xuICAgICAgaWYgKG90aGVyQmFzZW1hcCkge1xuICAgICAgICB0aGlzLmFjdGl2ZUJhc2VtYXBJZCA9IG90aGVyQmFzZW1hcC5pZDtcbiAgICAgICAgdGhpcy5sYXllclNlcnZpY2UucmVzb2x2ZUJhc2VtYXBFeGNsdXNpdmUoXG4gICAgICAgICAgWy4uLnRoaXMubWFuYWdlZExheWVycy52YWx1ZXMoKV0sXG4gICAgICAgICAgdGhpcy5hY3RpdmVCYXNlbWFwSWQsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5sYXllclNlcnZpY2Uuc2V0VmlzaWJsZShtYW5hZ2VkLmxheWVyLCB2aXNpYmxlKTtcbiAgICBtYW5hZ2VkLmNvbmZpZyA9IHsgLi4ubWFuYWdlZC5jb25maWcsIHZpc2libGUgfTtcbiAgfVxuXG4gIHNldExheWVyT3BhY2l0eShsYXllcklkOiBzdHJpbmcsIG9wYWNpdHk6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IG1hbmFnZWQgPSB0aGlzLm1hbmFnZWRMYXllcnMuZ2V0KGxheWVySWQpO1xuICAgIGlmICghbWFuYWdlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmxheWVyU2VydmljZS5zZXRPcGFjaXR5KG1hbmFnZWQubGF5ZXIsIG9wYWNpdHkpO1xuICAgIG1hbmFnZWQuY29uZmlnID0geyAuLi5tYW5hZ2VkLmNvbmZpZywgb3BhY2l0eSB9O1xuICB9XG5cbiAgZ2V0TWFuYWdlZExheWVycygpOiBDcmVhdGVkTWFwTGF5ZXJbXSB7XG4gICAgcmV0dXJuIFsuLi50aGlzLm1hbmFnZWRMYXllcnMudmFsdWVzKCldO1xuICB9XG5cbiAgc2V0Q2VudGVyKGNlbnRlcjogQ29vcmRpbmF0ZSwgem9vbT86IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IHZpZXcgPSB0aGlzLm1hcD8uZ2V0VmlldygpO1xuICAgIGlmICghdmlldykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBjdXJyZW50ID0gdmlldy5nZXRDZW50ZXIoKTtcbiAgICBjb25zdCBzYW1lQ2VudGVyID1cbiAgICAgIGN1cnJlbnQgIT0gbnVsbCAmJlxuICAgICAgY3VycmVudC5sZW5ndGggPj0gMiAmJlxuICAgICAgTWF0aC5hYnMoY3VycmVudFswXSAtIGNlbnRlclswXSkgPCAxZS02ICYmXG4gICAgICBNYXRoLmFicyhjdXJyZW50WzFdIC0gY2VudGVyWzFdKSA8IDFlLTY7XG4gICAgaWYgKCFzYW1lQ2VudGVyKSB7XG4gICAgICB2aWV3LnNldENlbnRlcihjZW50ZXIpO1xuICAgIH1cbiAgICBpZiAoem9vbSAhPSBudWxsKSB7XG4gICAgICB0aGlzLnNldFpvb20oem9vbSk7XG4gICAgfVxuICB9XG5cbiAgc2V0Wm9vbSh6b29tOiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCB2aWV3ID0gdGhpcy5tYXA/LmdldFZpZXcoKTtcbiAgICBpZiAoIXZpZXcpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgY3VycmVudCA9IHZpZXcuZ2V0Wm9vbSgpO1xuICAgIGlmIChjdXJyZW50ICE9IG51bGwgJiYgTWF0aC5hYnMoY3VycmVudCAtIHpvb20pIDwgMWUtNikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB2aWV3LnNldFpvb20oem9vbSk7XG4gIH1cblxuICBnZXRab29tKCk6IG51bWJlciB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMubWFwPy5nZXRWaWV3KCkuZ2V0Wm9vbSgpID8/IHVuZGVmaW5lZDtcbiAgfVxuXG4gIHpvb21CeShkZWx0YTogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgdmlldyA9IHRoaXMubWFwPy5nZXRWaWV3KCk7XG4gICAgaWYgKCF2aWV3KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHpvb20gPSB2aWV3LmdldFpvb20oKTtcbiAgICBpZiAoem9vbSA9PSBudWxsKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IG5leHQgPSBNYXRoLm1pbihcbiAgICAgIHZpZXcuZ2V0TWF4Wm9vbSgpID8/IEdFT19NQVBfREVGQVVMVF9NQVhfWk9PTSxcbiAgICAgIE1hdGgubWF4KHZpZXcuZ2V0TWluWm9vbSgpID8/IDAsIHpvb20gKyBkZWx0YSksXG4gICAgKTtcbiAgICB2aWV3LmFuaW1hdGUoeyB6b29tOiBuZXh0LCBkdXJhdGlvbjogMTgwIH0pO1xuICB9XG5cbiAgLyoqIFJlcGxhY2UgdGhlIHNob3J0Y3V0IGJhc2VtYXAgbGF5ZXIgKGBHRU9fTUFQX0JBU0VNQVBfTEFZRVJfSURgKS4gKi9cbiAgc2V0QmFzZW1hcChiYXNlbWFwOiBHZW9NYXBCYXNlbWFwSW5wdXQpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMubWFwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGV4aXN0aW5nID0gdGhpcy5tYW5hZ2VkTGF5ZXJzLmdldChHRU9fTUFQX0JBU0VNQVBfTEFZRVJfSUQpO1xuICAgIGlmIChleGlzdGluZykge1xuICAgICAgdGhpcy5tYXAucmVtb3ZlTGF5ZXIoZXhpc3RpbmcubGF5ZXIpO1xuICAgICAgdGhpcy5tYW5hZ2VkTGF5ZXJzLmRlbGV0ZShHRU9fTUFQX0JBU0VNQVBfTEFZRVJfSUQpO1xuICAgIH1cbiAgICBjb25zdCBjcmVhdGVkID0gdGhpcy5sYXllclNlcnZpY2UuY3JlYXRlRnJvbUJhc2VtYXBJbnB1dChiYXNlbWFwKTtcbiAgICB0aGlzLmFkZE1hbmFnZWRMYXllcihjcmVhdGVkKTtcbiAgICB0aGlzLmFjdGl2ZUJhc2VtYXBJZCA9IGNyZWF0ZWQuaWQ7XG4gICAgdGhpcy5lbmZvcmNlU2luZ2xlQmFzZW1hcCgpO1xuICAgIC8vIEJhc2VtYXAgc2hvdWxkIHNpdCB1bmRlciBvdmVybGF5c1xuICAgIGNyZWF0ZWQubGF5ZXIuc2V0WkluZGV4KGNyZWF0ZWQuY29uZmlnLnpJbmRleCA/PyAwKTtcbiAgfVxuXG4gIGZpdEV4dGVudChcbiAgICBleHRlbnQ6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICAgIG9wdGlvbnM/OiB7IHBhZGRpbmc/OiBudW1iZXJbXTsgbWF4Wm9vbT86IG51bWJlcjsgZHVyYXRpb24/OiBudW1iZXIgfSxcbiAgKTogdm9pZCB7XG4gICAgY29uc3QgdmlldyA9IHRoaXMubWFwPy5nZXRWaWV3KCk7XG4gICAgaWYgKCF2aWV3KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHZpZXcuZml0KGV4dGVudCwge1xuICAgICAgcGFkZGluZzogb3B0aW9ucz8ucGFkZGluZyA/PyBbNDgsIDQ4LCA0OCwgNDhdLFxuICAgICAgbWF4Wm9vbTogb3B0aW9ucz8ubWF4Wm9vbSA/PyAxNCxcbiAgICAgIGR1cmF0aW9uOiBvcHRpb25zPy5kdXJhdGlvbiA/PyAyNTAsXG4gICAgfSk7XG4gIH1cblxuICAvKiogRml0IGxvbi9sYXQgZXh0ZW50IChFUFNHOjQzMjYpIGFmdGVyIHRyYW5zZm9ybWluZyB0byB0aGUgYWN0aXZlIHZpZXcgcHJvamVjdGlvbi4gKi9cbiAgZml0TG9uTGF0RXh0ZW50KFxuICAgIGV4dGVudDQzMjY6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICAgIG9wdGlvbnM/OiB7IHBhZGRpbmc/OiBudW1iZXJbXTsgbWF4Wm9vbT86IG51bWJlcjsgZHVyYXRpb24/OiBudW1iZXIgfSxcbiAgKTogdm9pZCB7XG4gICAgY29uc3QgbWFwID0gdGhpcy5tYXA7XG4gICAgaWYgKCFtYXApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3Qgdmlld1Byb2ogPSBtYXAuZ2V0VmlldygpLmdldFByb2plY3Rpb24oKS5nZXRDb2RlKCk7XG4gICAgY29uc3QgZXh0ZW50ID0gdHJhbnNmb3JtRXh0ZW50KGV4dGVudDQzMjYsICdFUFNHOjQzMjYnLCB2aWV3UHJvaikgYXMgW1xuICAgICAgbnVtYmVyLFxuICAgICAgbnVtYmVyLFxuICAgICAgbnVtYmVyLFxuICAgICAgbnVtYmVyLFxuICAgIF07XG4gICAgdGhpcy5maXRFeHRlbnQoZXh0ZW50LCBvcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaXQgdGhlIGRlZmF1bHQgKG9yIHByb3ZpZGVkKSBwcm92aW5jZSBleHRlbnQg4oCUIFRDUUguMTQg4oCceGVtIHRvw6BuIHThu4luaOKAnS5cbiAgICogRGlzdGluY3QgZnJvbSBicm93c2VyIGZ1bGxzY3JlZW4gKFRDUUguMTUpLlxuICAgKi9cbiAgZml0UHJvdmluY2UoXG4gICAgZXh0ZW50NDMyNjogcmVhZG9ubHkgW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gPSBHRU9fTUFQX0RFRkFVTFRfUFJPVklOQ0VfRVhURU5UXzQzMjYsXG4gICAgb3B0aW9ucz86IHsgcGFkZGluZz86IG51bWJlcltdOyBtYXhab29tPzogbnVtYmVyOyBkdXJhdGlvbj86IG51bWJlciB9LFxuICApOiB2b2lkIHtcbiAgICB0aGlzLmZpdExvbkxhdEV4dGVudChbLi4uZXh0ZW50NDMyNl0gYXMgW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sIHtcbiAgICAgIG1heFpvb206IDExLFxuICAgICAgZHVyYXRpb246IDQwMCxcbiAgICAgIHBhZGRpbmc6IFs1NiwgNTYsIDU2LCA1Nl0sXG4gICAgICAuLi5vcHRpb25zLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEhpZ2hsaWdodCBzZWFyY2ggLyBzZWxlY3QgcmVzdWx0cyAoVENRSC434oCTMTIpLiBQYXNzIEdlb0pTT04gRmVhdHVyZSBvciBGZWF0dXJlQ29sbGVjdGlvbi5cbiAgICovXG4gIHNldEhpZ2hsaWdodEZyb21HZW9Kc29uKFxuICAgIGRhdGE6IG9iamVjdCxcbiAgICBvcHRpb25zPzogR2VvTWFwSGlnaGxpZ2h0T3B0aW9ucyxcbiAgKTogdm9pZCB7XG4gICAgY29uc3QgbWFwID0gdGhpcy5tYXA7XG4gICAgaWYgKCFtYXApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5lbnN1cmVIaWdobGlnaHRMYXllcigpO1xuICAgIGNvbnN0IHZpZXdQcm9qID0gbWFwLmdldFZpZXcoKS5nZXRQcm9qZWN0aW9uKCkuZ2V0Q29kZSgpO1xuICAgIGNvbnN0IGZvcm1hdCA9IG5ldyBHZW9KU09OKCk7XG4gICAgbGV0IGZlYXR1cmVzOiBGZWF0dXJlPEdlb21ldHJ5PltdID0gW107XG4gICAgdHJ5IHtcbiAgICAgIGZlYXR1cmVzID0gZm9ybWF0LnJlYWRGZWF0dXJlcyhkYXRhLCB7XG4gICAgICAgIGRhdGFQcm9qZWN0aW9uOiBvcHRpb25zPy5kYXRhUHJvamVjdGlvbiA/PyAnRVBTRzo0MzI2JyxcbiAgICAgICAgZmVhdHVyZVByb2plY3Rpb246IHZpZXdQcm9qLFxuICAgICAgfSkgYXMgRmVhdHVyZTxHZW9tZXRyeT5bXTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1tHZW9NYXBTZXJ2aWNlXSBJbnZhbGlkIGhpZ2hsaWdodCBHZW9KU09OJywgZXJyKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5zZXRIaWdobGlnaHRGZWF0dXJlcyhmZWF0dXJlcywgb3B0aW9ucyk7XG4gIH1cblxuICBzZXRIaWdobGlnaHRGZWF0dXJlcyhcbiAgICBmZWF0dXJlczogRmVhdHVyZTxHZW9tZXRyeT5bXSxcbiAgICBvcHRpb25zPzogR2VvTWFwSGlnaGxpZ2h0T3B0aW9ucyxcbiAgKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLm1hcCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmVuc3VyZUhpZ2hsaWdodExheWVyKCk7XG4gICAgdGhpcy5oaWdobGlnaHRTb3VyY2U/LmNsZWFyKCk7XG4gICAgaWYgKGZlYXR1cmVzLmxlbmd0aCkge1xuICAgICAgdGhpcy5oaWdobGlnaHRTb3VyY2U/LmFkZEZlYXR1cmVzKGZlYXR1cmVzKTtcbiAgICB9XG4gICAgY29uc3Qgc2hvdWxkRml0ID0gb3B0aW9ucz8uZml0ICE9PSBmYWxzZSAmJiBmZWF0dXJlcy5sZW5ndGggPiAwO1xuICAgIGlmIChzaG91bGRGaXQgJiYgdGhpcy5oaWdobGlnaHRTb3VyY2UpIHtcbiAgICAgIGNvbnN0IGV4dGVudCA9IHRoaXMuaGlnaGxpZ2h0U291cmNlLmdldEV4dGVudCgpO1xuICAgICAgaWYgKFxuICAgICAgICBleHRlbnQgJiZcbiAgICAgICAgTnVtYmVyLmlzRmluaXRlKGV4dGVudFswXSkgJiZcbiAgICAgICAgTnVtYmVyLmlzRmluaXRlKGV4dGVudFsxXSkgJiZcbiAgICAgICAgTnVtYmVyLmlzRmluaXRlKGV4dGVudFsyXSkgJiZcbiAgICAgICAgTnVtYmVyLmlzRmluaXRlKGV4dGVudFszXSlcbiAgICAgICkge1xuICAgICAgICB0aGlzLmZpdEV4dGVudChleHRlbnQgYXMgW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sIHtcbiAgICAgICAgICBtYXhab29tOiAxNyxcbiAgICAgICAgICBkdXJhdGlvbjogMjgwLFxuICAgICAgICAgIC4uLm9wdGlvbnM/LmZpdE9wdGlvbnMsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGNsZWFySGlnaGxpZ2h0KCk6IHZvaWQge1xuICAgIHRoaXMuaGlnaGxpZ2h0U291cmNlPy5jbGVhcigpO1xuICB9XG5cbiAgdXBkYXRlU2l6ZSgpOiB2b2lkIHtcbiAgICB0aGlzLm1hcD8udXBkYXRlU2l6ZSgpO1xuICB9XG5cbiAgb25DbGljayhoYW5kbGVyOiAoZXZlbnQ6IEdlb01hcENsaWNrRXZlbnQpID0+IHZvaWQpOiAoKSA9PiB2b2lkIHtcbiAgICBjb25zdCBtYXAgPSB0aGlzLm1hcDtcbiAgICBpZiAoIW1hcCkge1xuICAgICAgcmV0dXJuICgpID0+IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBjb25zdCBrZXkgPSBtYXAub24oJ3NpbmdsZWNsaWNrJywgKGV2dCkgPT4ge1xuICAgICAgY29uc3QgY29vcmRpbmF0ZSA9IGV2dC5jb29yZGluYXRlO1xuICAgICAgY29uc3QgbG9uTGF0ID0gdGhpcy5wcm9qZWN0aW9uLnRyYW5zZm9ybUNvb3JkaW5hdGUoXG4gICAgICAgIGNvb3JkaW5hdGUsXG4gICAgICAgIG1hcC5nZXRWaWV3KCkuZ2V0UHJvamVjdGlvbigpLmdldENvZGUoKSxcbiAgICAgICAgJ0VQU0c6NDMyNicsXG4gICAgICApO1xuICAgICAgaGFuZGxlcih7XG4gICAgICAgIGNvb3JkaW5hdGU6IFsuLi5jb29yZGluYXRlXSxcbiAgICAgICAgbG9uTGF0LFxuICAgICAgICBwaXhlbDogW2V2dC5waXhlbFswXSwgZXZ0LnBpeGVsWzFdXSxcbiAgICAgICAgb3JpZ2luYWxFdmVudDogZXZ0Lm9yaWdpbmFsRXZlbnQgYXMgVUlFdmVudCxcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIHRoaXMubGlzdGVuZXJLZXlzLnB1c2goa2V5KTtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgdW5CeUtleShrZXkpO1xuICAgICAgdGhpcy5saXN0ZW5lcktleXMgPSB0aGlzLmxpc3RlbmVyS2V5cy5maWx0ZXIoKGspID0+IGsgIT09IGtleSk7XG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbWl0IGFmdGVyIHRoZSB2aWV3IHNldHRsZXMgKGBtb3ZlZW5kYCksIG5vdCBvbiBldmVyeSByZXNvbHV0aW9uIHRpY2sg4oCUXG4gICAqIGNvbnRpbnVvdXMgZW1pdHRlcnMgZmxvb2QgU3Rvcnlib29rIEFjdGlvbnMgLyBob3N0IGJpbmRpbmdzIGFuZCBjYXVzZSBVSSBmbGlja2VyLlxuICAgKi9cbiAgb25WaWV3Q2hhbmdlKGhhbmRsZXI6IChldmVudDogR2VvTWFwVmlld0NoYW5nZUV2ZW50KSA9PiB2b2lkKTogKCkgPT4gdm9pZCB7XG4gICAgY29uc3QgbWFwID0gdGhpcy5tYXA7XG4gICAgaWYgKCFtYXApIHtcbiAgICAgIHJldHVybiAoKSA9PiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgY29uc3QgdmlldyA9IG1hcC5nZXRWaWV3KCk7XG4gICAgY29uc3QgZW1pdCA9ICgpOiB2b2lkID0+IHtcbiAgICAgIGhhbmRsZXIoe1xuICAgICAgICBjZW50ZXI6IFsuLi4odmlldy5nZXRDZW50ZXIoKSA/PyBbMCwgMF0pXSxcbiAgICAgICAgem9vbTogdmlldy5nZXRab29tKCkgPz8gMCxcbiAgICAgICAgcmVzb2x1dGlvbjogdmlldy5nZXRSZXNvbHV0aW9uKCkgPz8gMCxcbiAgICAgICAgcm90YXRpb246IHZpZXcuZ2V0Um90YXRpb24oKSxcbiAgICAgIH0pO1xuICAgIH07XG4gICAgY29uc3Qga2V5ID0gbWFwLm9uKCdtb3ZlZW5kJywgZW1pdCk7XG4gICAgdGhpcy5saXN0ZW5lcktleXMucHVzaChrZXkpO1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICB1bkJ5S2V5KGtleSk7XG4gICAgICB0aGlzLmxpc3RlbmVyS2V5cyA9IHRoaXMubGlzdGVuZXJLZXlzLmZpbHRlcigoaykgPT4gayAhPT0ga2V5KTtcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFRlYXIgZG93biBtYXAsIGxpc3RlbmVycywgYW5kIHJlc2l6ZSBvYnNlcnZlci4gU2FmZSB0byBjYWxsIG11bHRpcGxlIHRpbWVzLlxuICAgKi9cbiAgZGVzdHJveSgpOiB2b2lkIHtcbiAgICB1bkJ5S2V5KHRoaXMubGlzdGVuZXJLZXlzKTtcbiAgICB0aGlzLmxpc3RlbmVyS2V5cyA9IFtdO1xuXG4gICAgdGhpcy5yZXNpemVDbGVhbnVwPy4oKTtcbiAgICB0aGlzLnJlc2l6ZUNsZWFudXAgPSBudWxsO1xuICAgIHRoaXMucmVzaXplT2JzZXJ2ZXIgPSBudWxsO1xuXG4gICAgaWYgKHRoaXMuaGlnaGxpZ2h0TGF5ZXIgJiYgdGhpcy5tYXApIHtcbiAgICAgIHRoaXMubWFwLnJlbW92ZUxheWVyKHRoaXMuaGlnaGxpZ2h0TGF5ZXIpO1xuICAgIH1cbiAgICB0aGlzLmhpZ2hsaWdodExheWVyID0gbnVsbDtcbiAgICB0aGlzLmhpZ2hsaWdodFNvdXJjZSA9IG51bGw7XG5cbiAgICBpZiAodGhpcy5tYXApIHtcbiAgICAgIHRoaXMubWFwLnNldFRhcmdldCh1bmRlZmluZWQpO1xuICAgICAgdGhpcy5tYXAuZGlzcG9zZSgpO1xuICAgICAgdGhpcy5tYXAgPSBudWxsO1xuICAgIH1cbiAgICB0aGlzLm1hbmFnZWRMYXllcnMuY2xlYXIoKTtcbiAgfVxuXG4gIHByaXZhdGUgZW5zdXJlSGlnaGxpZ2h0TGF5ZXIoKTogdm9pZCB7XG4gICAgY29uc3QgbWFwID0gdGhpcy5tYXA7XG4gICAgaWYgKCFtYXApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHRoaXMuaGlnaGxpZ2h0TGF5ZXIgJiYgdGhpcy5oaWdobGlnaHRTb3VyY2UpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5oaWdobGlnaHRTb3VyY2UgPSBuZXcgVmVjdG9yU291cmNlKCk7XG4gICAgdGhpcy5oaWdobGlnaHRMYXllciA9IG5ldyBWZWN0b3JMYXllcih7XG4gICAgICBzb3VyY2U6IHRoaXMuaGlnaGxpZ2h0U291cmNlLFxuICAgICAgcHJvcGVydGllczogeyBnZW9MYXllcklkOiBHRU9fTUFQX0hJR0hMSUdIVF9MQVlFUl9JRCB9LFxuICAgICAgc3R5bGU6IHRoaXMuY3JlYXRlSGlnaGxpZ2h0U3R5bGUoKSxcbiAgICAgIHpJbmRleDogNDUwLFxuICAgICAgdXBkYXRlV2hpbGVBbmltYXRpbmc6IHRydWUsXG4gICAgICB1cGRhdGVXaGlsZUludGVyYWN0aW5nOiB0cnVlLFxuICAgIH0pO1xuICAgIG1hcC5hZGRMYXllcih0aGlzLmhpZ2hsaWdodExheWVyKTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlSGlnaGxpZ2h0U3R5bGUoKTogU3R5bGVMaWtlIHtcbiAgICBjb25zdCBzdHJva2UgPSB0aGlzLmNzc0NvbG9yKCctLWdlby1jb2xvci13YXJuaW5nLWRlZmF1bHQnLCAnI2Y1OWUwYicpO1xuICAgIGNvbnN0IGZpbGwgPSB0aGlzLmNzc0NvbG9yKCctLWdlby1jb2xvci13YXJuaW5nLWRlZmF1bHQnLCAnI2Y1OWUwYicsIDAuMjIpO1xuICAgIGNvbnN0IHBpbiA9IHRoaXMuY3NzQ29sb3IoJy0tZ2VvLWNvbG9yLWVycm9yLWRlZmF1bHQnLCAnI2RjMjYyNicpO1xuICAgIGNvbnN0IHBpbkljb24gPSB0aGlzLmNyZWF0ZVBpbkljb25EYXRhVXJpKHBpbik7XG5cbiAgICBjb25zdCBhcmVhU3R5bGUgPSBuZXcgU3R5bGUoe1xuICAgICAgZmlsbDogbmV3IEZpbGwoeyBjb2xvcjogZmlsbCB9KSxcbiAgICAgIHN0cm9rZTogbmV3IFN0cm9rZSh7XG4gICAgICAgIGNvbG9yOiBzdHJva2UsXG4gICAgICAgIHdpZHRoOiAzLFxuICAgICAgfSksXG4gICAgfSk7XG5cbiAgICBjb25zdCBwb2ludFN0eWxlID0gbmV3IFN0eWxlKHtcbiAgICAgIGltYWdlOiBuZXcgSWNvbih7XG4gICAgICAgIGFuY2hvcjogWzAuNSwgMV0sXG4gICAgICAgIGFuY2hvclhVbml0czogJ2ZyYWN0aW9uJyxcbiAgICAgICAgYW5jaG9yWVVuaXRzOiAnZnJhY3Rpb24nLFxuICAgICAgICBzcmM6IHBpbkljb24sXG4gICAgICAgIHNjYWxlOiAxLFxuICAgICAgfSksXG4gICAgfSk7XG5cbiAgICByZXR1cm4gKGZlYXR1cmUpID0+IHtcbiAgICAgIGNvbnN0IHR5cGUgPSBmZWF0dXJlLmdldEdlb21ldHJ5KCk/LmdldFR5cGUoKTtcbiAgICAgIGlmICh0eXBlID09PSAnUG9pbnQnIHx8IHR5cGUgPT09ICdNdWx0aVBvaW50Jykge1xuICAgICAgICByZXR1cm4gcG9pbnRTdHlsZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhcmVhU3R5bGU7XG4gICAgfTtcbiAgfVxuXG4gIC8qKiBJbmxpbmUgU1ZHIG1hcCBwaW4gZm9yIGNsaWNrZWQgLyBzZWxlY3RlZCBwb2ludHMuICovXG4gIHByaXZhdGUgY3JlYXRlUGluSWNvbkRhdGFVcmkoY29sb3I6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3Qgc3ZnID0gYFxuICAgICAgPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgd2lkdGg9XCIzMlwiIGhlaWdodD1cIjQwXCIgdmlld0JveD1cIjAgMCAzMiA0MFwiPlxuICAgICAgICA8cGF0aCBmaWxsPVwiJHtjb2xvcn1cIiBzdHJva2U9XCIjZmZmZmZmXCIgc3Ryb2tlLXdpZHRoPVwiMS43NVwiXG4gICAgICAgICAgZD1cIk0xNiAxQzkuMzczIDEgNCA2LjM3MyA0IDEzYzAgOC4yODQgMTIgMjYgMTIgMjZzMTItMTcuNzE2IDEyLTI2QzI4IDYuMzczIDIyLjYyNyAxIDE2IDF6XCIvPlxuICAgICAgICA8Y2lyY2xlIGN4PVwiMTZcIiBjeT1cIjEzXCIgcj1cIjQuNVwiIGZpbGw9XCIjZmZmZmZmXCIvPlxuICAgICAgPC9zdmc+XG4gICAgYC50cmltKCk7XG4gICAgcmV0dXJuIGBkYXRhOmltYWdlL3N2Zyt4bWw7Y2hhcnNldD11dGYtOCwke2VuY29kZVVSSUNvbXBvbmVudChzdmcpfWA7XG4gIH1cblxuICAvKiogUmVzb2x2ZSBhIGRlc2lnbiB0b2tlbiBmb3IgT3BlbkxheWVycyBjYW52YXMgc3R5bGVzLiAqL1xuICBwcml2YXRlIGNzc0NvbG9yKHRva2VuOiBzdHJpbmcsIGZhbGxiYWNrOiBzdHJpbmcsIGFscGhhPzogbnVtYmVyKTogc3RyaW5nIHtcbiAgICBpZiAodHlwZW9mIGRvY3VtZW50ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgcmV0dXJuIGFscGhhID09IG51bGwgPyBmYWxsYmFjayA6IHRoaXMud2l0aEFscGhhKGZhbGxiYWNrLCBhbHBoYSk7XG4gICAgfVxuICAgIGNvbnN0IHJhdyA9IGdldENvbXB1dGVkU3R5bGUoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50KVxuICAgICAgLmdldFByb3BlcnR5VmFsdWUodG9rZW4pXG4gICAgICAudHJpbSgpO1xuICAgIGNvbnN0IGNvbG9yID0gcmF3IHx8IGZhbGxiYWNrO1xuICAgIHJldHVybiBhbHBoYSA9PSBudWxsID8gY29sb3IgOiB0aGlzLndpdGhBbHBoYShjb2xvciwgYWxwaGEpO1xuICB9XG5cbiAgcHJpdmF0ZSB3aXRoQWxwaGEoY29sb3I6IHN0cmluZywgYWxwaGE6IG51bWJlcik6IHN0cmluZyB7XG4gICAgaWYgKGNvbG9yLnN0YXJ0c1dpdGgoJ3JnYmEoJykgfHwgY29sb3Iuc3RhcnRzV2l0aCgnaHNsYSgnKSkge1xuICAgICAgcmV0dXJuIGNvbG9yO1xuICAgIH1cbiAgICBpZiAoY29sb3Iuc3RhcnRzV2l0aCgncmdiKCcpKSB7XG4gICAgICByZXR1cm4gY29sb3IucmVwbGFjZSgncmdiKCcsICdyZ2JhKCcpLnJlcGxhY2UoJyknLCBgLCAke2FscGhhfSlgKTtcbiAgICB9XG4gICAgaWYgKGNvbG9yLnN0YXJ0c1dpdGgoJyMnKSkge1xuICAgICAgY29uc3QgaGV4ID0gY29sb3Iuc2xpY2UoMSk7XG4gICAgICBjb25zdCBmdWxsID1cbiAgICAgICAgaGV4Lmxlbmd0aCA9PT0gM1xuICAgICAgICAgID8gaGV4XG4gICAgICAgICAgICAgIC5zcGxpdCgnJylcbiAgICAgICAgICAgICAgLm1hcCgoYykgPT4gYyArIGMpXG4gICAgICAgICAgICAgIC5qb2luKCcnKVxuICAgICAgICAgIDogaGV4O1xuICAgICAgaWYgKGZ1bGwubGVuZ3RoICE9PSA2KSB7XG4gICAgICAgIHJldHVybiBjb2xvcjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHIgPSBwYXJzZUludChmdWxsLnNsaWNlKDAsIDIpLCAxNik7XG4gICAgICBjb25zdCBnID0gcGFyc2VJbnQoZnVsbC5zbGljZSgyLCA0KSwgMTYpO1xuICAgICAgY29uc3QgYiA9IHBhcnNlSW50KGZ1bGwuc2xpY2UoNCwgNiksIDE2KTtcbiAgICAgIHJldHVybiBgcmdiYSgke3J9LCAke2d9LCAke2J9LCAke2FscGhhfSlgO1xuICAgIH1cbiAgICByZXR1cm4gY29sb3I7XG4gIH1cblxuICBwcml2YXRlIGFkZE1hbmFnZWRMYXllcihjcmVhdGVkOiBDcmVhdGVkTWFwTGF5ZXIpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMubWFwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMubWFuYWdlZExheWVycy5zZXQoY3JlYXRlZC5pZCwgY3JlYXRlZCk7XG4gICAgdGhpcy5tYXAuYWRkTGF5ZXIoY3JlYXRlZC5sYXllcik7XG4gIH1cblxuICBwcml2YXRlIGVuZm9yY2VTaW5nbGVCYXNlbWFwKCk6IHZvaWQge1xuICAgIGNvbnN0IGJhc2VtYXBzID0gWy4uLnRoaXMubWFuYWdlZExheWVycy52YWx1ZXMoKV0uZmlsdGVyKChpdGVtKSA9PiBpdGVtLmNvbmZpZy5iYXNlbWFwKTtcbiAgICBpZiAoYmFzZW1hcHMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGFjdGl2ZSA9XG4gICAgICBiYXNlbWFwcy5maW5kKChpdGVtKSA9PiBpdGVtLmlkID09PSB0aGlzLmFjdGl2ZUJhc2VtYXBJZCAmJiAoaXRlbS5jb25maWcudmlzaWJsZSA/PyB0cnVlKSkgPz9cbiAgICAgIGJhc2VtYXBzLmZpbmQoKGl0ZW0pID0+IGl0ZW0uY29uZmlnLnZpc2libGUgPz8gdHJ1ZSkgPz9cbiAgICAgIGJhc2VtYXBzWzBdO1xuICAgIHRoaXMuYWN0aXZlQmFzZW1hcElkID0gYWN0aXZlLmlkO1xuICAgIHRoaXMubGF5ZXJTZXJ2aWNlLnJlc29sdmVCYXNlbWFwRXhjbHVzaXZlKGJhc2VtYXBzLCB0aGlzLmFjdGl2ZUJhc2VtYXBJZCk7XG4gIH1cblxuICBwcml2YXRlIG9ic2VydmVSZXNpemUodGFyZ2V0OiBIVE1MRWxlbWVudCk6IHZvaWQge1xuICAgIGlmICh0eXBlb2YgUmVzaXplT2JzZXJ2ZXIgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGxldCBsYXN0V2lkdGggPSAtMTtcbiAgICBsZXQgbGFzdEhlaWdodCA9IC0xO1xuICAgIGxldCByYWZJZDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG5cbiAgICB0aGlzLnJlc2l6ZU9ic2VydmVyID0gbmV3IFJlc2l6ZU9ic2VydmVyKChlbnRyaWVzKSA9PiB7XG4gICAgICBjb25zdCByZWN0ID0gZW50cmllc1swXT8uY29udGVudFJlY3Q7XG4gICAgICBpZiAoIXJlY3QpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3Qgd2lkdGggPSBNYXRoLnJvdW5kKHJlY3Qud2lkdGgpO1xuICAgICAgY29uc3QgaGVpZ2h0ID0gTWF0aC5yb3VuZChyZWN0LmhlaWdodCk7XG4gICAgICBpZiAod2lkdGggPT09IDAgfHwgaGVpZ2h0ID09PSAwKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmICh3aWR0aCA9PT0gbGFzdFdpZHRoICYmIGhlaWdodCA9PT0gbGFzdEhlaWdodCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBsYXN0V2lkdGggPSB3aWR0aDtcbiAgICAgIGxhc3RIZWlnaHQgPSBoZWlnaHQ7XG4gICAgICBpZiAocmFmSWQgIT0gbnVsbCkge1xuICAgICAgICBjYW5jZWxBbmltYXRpb25GcmFtZShyYWZJZCk7XG4gICAgICB9XG4gICAgICByYWZJZCA9IHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICAgIHJhZklkID0gbnVsbDtcbiAgICAgICAgdGhpcy51cGRhdGVTaXplKCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgICB0aGlzLnJlc2l6ZU9ic2VydmVyLm9ic2VydmUodGFyZ2V0KTtcblxuICAgIHRoaXMucmVzaXplQ2xlYW51cCA9ICgpID0+IHtcbiAgICAgIGlmIChyYWZJZCAhPSBudWxsKSB7XG4gICAgICAgIGNhbmNlbEFuaW1hdGlvbkZyYW1lKHJhZklkKTtcbiAgICAgICAgcmFmSWQgPSBudWxsO1xuICAgICAgfVxuICAgICAgdGhpcy5yZXNpemVPYnNlcnZlcj8uZGlzY29ubmVjdCgpO1xuICAgICAgdGhpcy5yZXNpemVPYnNlcnZlciA9IG51bGw7XG4gICAgfTtcbiAgfVxufVxuIl19
|