@angular/google-maps 19.0.0-next.0 → 19.0.0-next.2

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.
Files changed (27) hide show
  1. package/package.json +1 -3
  2. package/esm2022/google-map/google-map.mjs +0 -473
  3. package/esm2022/google-maps-module.mjs +0 -90
  4. package/esm2022/google-maps_public_index.mjs +0 -5
  5. package/esm2022/index.mjs +0 -9
  6. package/esm2022/map-advanced-marker/map-advanced-marker.mjs +0 -217
  7. package/esm2022/map-anchor-point.mjs +0 -10
  8. package/esm2022/map-base-layer.mjs +0 -51
  9. package/esm2022/map-bicycling-layer/map-bicycling-layer.mjs +0 -69
  10. package/esm2022/map-circle/map-circle.mjs +0 -280
  11. package/esm2022/map-directions-renderer/map-directions-renderer.mjs +0 -149
  12. package/esm2022/map-directions-renderer/map-directions-service.mjs +0 -61
  13. package/esm2022/map-event-manager.mjs +0 -73
  14. package/esm2022/map-geocoder/map-geocoder.mjs +0 -57
  15. package/esm2022/map-ground-overlay/map-ground-overlay.mjs +0 -193
  16. package/esm2022/map-heatmap-layer/map-heatmap-layer.mjs +0 -151
  17. package/esm2022/map-info-window/map-info-window.mjs +0 -238
  18. package/esm2022/map-kml-layer/map-kml-layer.mjs +0 -183
  19. package/esm2022/map-marker/map-marker.mjs +0 -447
  20. package/esm2022/map-marker-clusterer/map-marker-clusterer.mjs +0 -421
  21. package/esm2022/map-marker-clusterer/marker-clusterer-types.mjs +0 -10
  22. package/esm2022/map-polygon/map-polygon.mjs +0 -227
  23. package/esm2022/map-polyline/map-polyline.mjs +0 -220
  24. package/esm2022/map-rectangle/map-rectangle.mjs +0 -240
  25. package/esm2022/map-traffic-layer/map-traffic-layer.mjs +0 -103
  26. package/esm2022/map-transit-layer/map-transit-layer.mjs +0 -69
  27. package/esm2022/public-api.mjs +0 -29
@@ -1,57 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright Google LLC All Rights Reserved.
4
- *
5
- * Use of this source code is governed by an MIT-style license that can be
6
- * found in the LICENSE file at https://angular.io/license
7
- */
8
- // Workaround for: https://github.com/bazelbuild/rules_nodejs/issues/1265
9
- /// <reference types="google.maps" preserve="true" />
10
- import { Injectable, NgZone } from '@angular/core';
11
- import { Observable } from 'rxjs';
12
- import * as i0 from "@angular/core";
13
- /**
14
- * Angular service that wraps the Google Maps Geocoder from the Google Maps JavaScript API.
15
- * See developers.google.com/maps/documentation/javascript/reference/geocoder#Geocoder
16
- */
17
- export class MapGeocoder {
18
- constructor(_ngZone) {
19
- this._ngZone = _ngZone;
20
- }
21
- /**
22
- * See developers.google.com/maps/documentation/javascript/reference/geocoder#Geocoder.geocode
23
- */
24
- geocode(request) {
25
- return new Observable(observer => {
26
- this._getGeocoder().then(geocoder => {
27
- geocoder.geocode(request, (results, status) => {
28
- this._ngZone.run(() => {
29
- observer.next({ results: results || [], status });
30
- observer.complete();
31
- });
32
- });
33
- });
34
- });
35
- }
36
- _getGeocoder() {
37
- if (!this._geocoder) {
38
- if (google.maps.Geocoder) {
39
- this._geocoder = new google.maps.Geocoder();
40
- }
41
- else {
42
- return google.maps.importLibrary('geocoding').then(lib => {
43
- this._geocoder = new lib.Geocoder();
44
- return this._geocoder;
45
- });
46
- }
47
- }
48
- return Promise.resolve(this._geocoder);
49
- }
50
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.0-next.2", ngImport: i0, type: MapGeocoder, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable }); }
51
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.0-next.2", ngImport: i0, type: MapGeocoder, providedIn: 'root' }); }
52
- }
53
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.0-next.2", ngImport: i0, type: MapGeocoder, decorators: [{
54
- type: Injectable,
55
- args: [{ providedIn: 'root' }]
56
- }], ctorParameters: () => [{ type: i0.NgZone }] });
57
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFwLWdlb2NvZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2dvb2dsZS1tYXBzL21hcC1nZW9jb2Rlci9tYXAtZ2VvY29kZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztHQU1HO0FBRUgseUVBQXlFO0FBQ3pFLHFEQUFxRDtBQUVyRCxPQUFPLEVBQUMsVUFBVSxFQUFFLE1BQU0sRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUNqRCxPQUFPLEVBQUMsVUFBVSxFQUFDLE1BQU0sTUFBTSxDQUFDOztBQU9oQzs7O0dBR0c7QUFFSCxNQUFNLE9BQU8sV0FBVztJQUd0QixZQUE2QixPQUFlO1FBQWYsWUFBTyxHQUFQLE9BQU8sQ0FBUTtJQUFHLENBQUM7SUFFaEQ7O09BRUc7SUFDSCxPQUFPLENBQUMsT0FBb0M7UUFDMUMsT0FBTyxJQUFJLFVBQVUsQ0FBQyxRQUFRLENBQUMsRUFBRTtZQUMvQixJQUFJLENBQUMsWUFBWSxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFO2dCQUNsQyxRQUFRLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsRUFBRTtvQkFDNUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFO3dCQUNwQixRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUMsT0FBTyxFQUFFLE9BQU8sSUFBSSxFQUFFLEVBQUUsTUFBTSxFQUFDLENBQUMsQ0FBQzt3QkFDaEQsUUFBUSxDQUFDLFFBQVEsRUFBRSxDQUFDO29CQUN0QixDQUFDLENBQUMsQ0FBQztnQkFDTCxDQUFDLENBQUMsQ0FBQztZQUNMLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU8sWUFBWTtRQUNsQixJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ3BCLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztnQkFDekIsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDOUMsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFO29CQUN2RCxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUssR0FBb0MsQ0FBQyxRQUFRLEVBQUUsQ0FBQztvQkFDdEUsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDO2dCQUN4QixDQUFDLENBQUMsQ0FBQztZQUNMLENBQUM7UUFDSCxDQUFDO1FBRUQsT0FBTyxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUN6QyxDQUFDO3FIQWxDVSxXQUFXO3lIQUFYLFdBQVcsY0FEQyxNQUFNOztrR0FDbEIsV0FBVztrQkFEdkIsVUFBVTttQkFBQyxFQUFDLFVBQVUsRUFBRSxNQUFNLEVBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIExMQyBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cblxuLy8gV29ya2Fyb3VuZCBmb3I6IGh0dHBzOi8vZ2l0aHViLmNvbS9iYXplbGJ1aWxkL3J1bGVzX25vZGVqcy9pc3N1ZXMvMTI2NVxuLy8vIDxyZWZlcmVuY2UgdHlwZXM9XCJnb29nbGUubWFwc1wiIHByZXNlcnZlPVwidHJ1ZVwiIC8+XG5cbmltcG9ydCB7SW5qZWN0YWJsZSwgTmdab25lfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7T2JzZXJ2YWJsZX0gZnJvbSAncnhqcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgTWFwR2VvY29kZXJSZXNwb25zZSB7XG4gIHN0YXR1czogZ29vZ2xlLm1hcHMuR2VvY29kZXJTdGF0dXM7XG4gIHJlc3VsdHM6IGdvb2dsZS5tYXBzLkdlb2NvZGVyUmVzdWx0W107XG59XG5cbi8qKlxuICogQW5ndWxhciBzZXJ2aWNlIHRoYXQgd3JhcHMgdGhlIEdvb2dsZSBNYXBzIEdlb2NvZGVyIGZyb20gdGhlIEdvb2dsZSBNYXBzIEphdmFTY3JpcHQgQVBJLlxuICogU2VlIGRldmVsb3BlcnMuZ29vZ2xlLmNvbS9tYXBzL2RvY3VtZW50YXRpb24vamF2YXNjcmlwdC9yZWZlcmVuY2UvZ2VvY29kZXIjR2VvY29kZXJcbiAqL1xuQEluamVjdGFibGUoe3Byb3ZpZGVkSW46ICdyb290J30pXG5leHBvcnQgY2xhc3MgTWFwR2VvY29kZXIge1xuICBwcml2YXRlIF9nZW9jb2RlcjogZ29vZ2xlLm1hcHMuR2VvY29kZXIgfCB1bmRlZmluZWQ7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSBfbmdab25lOiBOZ1pvbmUpIHt9XG5cbiAgLyoqXG4gICAqIFNlZSBkZXZlbG9wZXJzLmdvb2dsZS5jb20vbWFwcy9kb2N1bWVudGF0aW9uL2phdmFzY3JpcHQvcmVmZXJlbmNlL2dlb2NvZGVyI0dlb2NvZGVyLmdlb2NvZGVcbiAgICovXG4gIGdlb2NvZGUocmVxdWVzdDogZ29vZ2xlLm1hcHMuR2VvY29kZXJSZXF1ZXN0KTogT2JzZXJ2YWJsZTxNYXBHZW9jb2RlclJlc3BvbnNlPiB7XG4gICAgcmV0dXJuIG5ldyBPYnNlcnZhYmxlKG9ic2VydmVyID0+IHtcbiAgICAgIHRoaXMuX2dldEdlb2NvZGVyKCkudGhlbihnZW9jb2RlciA9PiB7XG4gICAgICAgIGdlb2NvZGVyLmdlb2NvZGUocmVxdWVzdCwgKHJlc3VsdHMsIHN0YXR1cykgPT4ge1xuICAgICAgICAgIHRoaXMuX25nWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgICAgICAgb2JzZXJ2ZXIubmV4dCh7cmVzdWx0czogcmVzdWx0cyB8fCBbXSwgc3RhdHVzfSk7XG4gICAgICAgICAgICBvYnNlcnZlci5jb21wbGV0ZSgpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBfZ2V0R2VvY29kZXIoKTogUHJvbWlzZTxnb29nbGUubWFwcy5HZW9jb2Rlcj4ge1xuICAgIGlmICghdGhpcy5fZ2VvY29kZXIpIHtcbiAgICAgIGlmIChnb29nbGUubWFwcy5HZW9jb2Rlcikge1xuICAgICAgICB0aGlzLl9nZW9jb2RlciA9IG5ldyBnb29nbGUubWFwcy5HZW9jb2RlcigpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGdvb2dsZS5tYXBzLmltcG9ydExpYnJhcnkoJ2dlb2NvZGluZycpLnRoZW4obGliID0+IHtcbiAgICAgICAgICB0aGlzLl9nZW9jb2RlciA9IG5ldyAobGliIGFzIGdvb2dsZS5tYXBzLkdlb2NvZGluZ0xpYnJhcnkpLkdlb2NvZGVyKCk7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuX2dlb2NvZGVyO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRoaXMuX2dlb2NvZGVyKTtcbiAgfVxufVxuIl19
@@ -1,193 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright Google LLC All Rights Reserved.
4
- *
5
- * Use of this source code is governed by an MIT-style license that can be
6
- * found in the LICENSE file at https://angular.io/license
7
- */
8
- // Workaround for: https://github.com/bazelbuild/rules_nodejs/issues/1265
9
- /// <reference types="google.maps" preserve="true" />
10
- import { Directive, EventEmitter, Input, NgZone, Output, inject, } from '@angular/core';
11
- import { BehaviorSubject, Observable, Subject } from 'rxjs';
12
- import { takeUntil } from 'rxjs/operators';
13
- import { GoogleMap } from '../google-map/google-map';
14
- import { MapEventManager } from '../map-event-manager';
15
- import * as i0 from "@angular/core";
16
- import * as i1 from "../google-map/google-map";
17
- /**
18
- * Angular component that renders a Google Maps Ground Overlay via the Google Maps JavaScript API.
19
- *
20
- * See developers.google.com/maps/documentation/javascript/reference/image-overlay#GroundOverlay
21
- */
22
- export class MapGroundOverlay {
23
- /** URL of the image that will be shown in the overlay. */
24
- set url(url) {
25
- this._url.next(url);
26
- }
27
- /** Bounds for the overlay. */
28
- get bounds() {
29
- return this._bounds.value;
30
- }
31
- set bounds(bounds) {
32
- this._bounds.next(bounds);
33
- }
34
- /** Opacity of the overlay. */
35
- set opacity(opacity) {
36
- this._opacity.next(opacity);
37
- }
38
- constructor(_map, _ngZone) {
39
- this._map = _map;
40
- this._ngZone = _ngZone;
41
- this._eventManager = new MapEventManager(inject(NgZone));
42
- this._opacity = new BehaviorSubject(1);
43
- this._url = new BehaviorSubject('');
44
- this._bounds = new BehaviorSubject(undefined);
45
- this._destroyed = new Subject();
46
- /** Whether the overlay is clickable */
47
- this.clickable = false;
48
- /**
49
- * See
50
- * developers.google.com/maps/documentation/javascript/reference/image-overlay#GroundOverlay.click
51
- */
52
- this.mapClick = this._eventManager.getLazyEmitter('click');
53
- /**
54
- * See
55
- * developers.google.com/maps/documentation/javascript/reference/image-overlay
56
- * #GroundOverlay.dblclick
57
- */
58
- this.mapDblclick = this._eventManager.getLazyEmitter('dblclick');
59
- /** Event emitted when the ground overlay is initialized. */
60
- this.groundOverlayInitialized = new EventEmitter();
61
- }
62
- ngOnInit() {
63
- if (this._map._isBrowser) {
64
- // The ground overlay setup is slightly different from the other Google Maps objects in that
65
- // we have to recreate the `GroundOverlay` object whenever the bounds change, because
66
- // Google Maps doesn't provide an API to update the bounds of an existing overlay.
67
- this._bounds.pipe(takeUntil(this._destroyed)).subscribe(bounds => {
68
- if (this.groundOverlay) {
69
- this.groundOverlay.setMap(null);
70
- this.groundOverlay = undefined;
71
- }
72
- if (!bounds) {
73
- return;
74
- }
75
- if (google.maps.GroundOverlay && this._map.googleMap) {
76
- this._initialize(this._map.googleMap, google.maps.GroundOverlay, bounds);
77
- }
78
- else {
79
- this._ngZone.runOutsideAngular(() => {
80
- Promise.all([this._map._resolveMap(), google.maps.importLibrary('maps')]).then(([map, lib]) => {
81
- this._initialize(map, lib.GroundOverlay, bounds);
82
- });
83
- });
84
- }
85
- });
86
- }
87
- }
88
- _initialize(map, overlayConstructor, bounds) {
89
- // Create the object outside the zone so its events don't trigger change detection.
90
- // We'll bring it back in inside the `MapEventManager` only for the events that the
91
- // user has subscribed to.
92
- this._ngZone.runOutsideAngular(() => {
93
- this.groundOverlay = new overlayConstructor(this._url.getValue(), bounds, {
94
- clickable: this.clickable,
95
- opacity: this._opacity.value,
96
- });
97
- this._assertInitialized();
98
- this.groundOverlay.setMap(map);
99
- this._eventManager.setTarget(this.groundOverlay);
100
- this.groundOverlayInitialized.emit(this.groundOverlay);
101
- // We only need to set up the watchers once.
102
- if (!this._hasWatchers) {
103
- this._hasWatchers = true;
104
- this._watchForOpacityChanges();
105
- this._watchForUrlChanges();
106
- }
107
- });
108
- }
109
- ngOnDestroy() {
110
- this._eventManager.destroy();
111
- this._destroyed.next();
112
- this._destroyed.complete();
113
- this.groundOverlay?.setMap(null);
114
- }
115
- /**
116
- * See
117
- * developers.google.com/maps/documentation/javascript/reference/image-overlay
118
- * #GroundOverlay.getBounds
119
- */
120
- getBounds() {
121
- this._assertInitialized();
122
- return this.groundOverlay.getBounds();
123
- }
124
- /**
125
- * See
126
- * developers.google.com/maps/documentation/javascript/reference/image-overlay
127
- * #GroundOverlay.getOpacity
128
- */
129
- getOpacity() {
130
- this._assertInitialized();
131
- return this.groundOverlay.getOpacity();
132
- }
133
- /**
134
- * See
135
- * developers.google.com/maps/documentation/javascript/reference/image-overlay
136
- * #GroundOverlay.getUrl
137
- */
138
- getUrl() {
139
- this._assertInitialized();
140
- return this.groundOverlay.getUrl();
141
- }
142
- _watchForOpacityChanges() {
143
- this._opacity.pipe(takeUntil(this._destroyed)).subscribe(opacity => {
144
- if (opacity != null) {
145
- this.groundOverlay?.setOpacity(opacity);
146
- }
147
- });
148
- }
149
- _watchForUrlChanges() {
150
- this._url.pipe(takeUntil(this._destroyed)).subscribe(url => {
151
- const overlay = this.groundOverlay;
152
- if (overlay) {
153
- overlay.set('url', url);
154
- // Google Maps only redraws the overlay if we re-set the map.
155
- overlay.setMap(null);
156
- overlay.setMap(this._map.googleMap);
157
- }
158
- });
159
- }
160
- _assertInitialized() {
161
- if (typeof ngDevMode === 'undefined' || ngDevMode) {
162
- if (!this.groundOverlay) {
163
- throw Error('Cannot interact with a Google Map GroundOverlay before it has been initialized. ' +
164
- 'Please wait for the GroundOverlay to load before trying to interact with it.');
165
- }
166
- }
167
- }
168
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.0-next.2", ngImport: i0, type: MapGroundOverlay, deps: [{ token: i1.GoogleMap }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive }); }
169
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.0-next.2", type: MapGroundOverlay, isStandalone: true, selector: "map-ground-overlay", inputs: { url: "url", bounds: "bounds", clickable: "clickable", opacity: "opacity" }, outputs: { mapClick: "mapClick", mapDblclick: "mapDblclick", groundOverlayInitialized: "groundOverlayInitialized" }, exportAs: ["mapGroundOverlay"], ngImport: i0 }); }
170
- }
171
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.0-next.2", ngImport: i0, type: MapGroundOverlay, decorators: [{
172
- type: Directive,
173
- args: [{
174
- selector: 'map-ground-overlay',
175
- exportAs: 'mapGroundOverlay',
176
- standalone: true,
177
- }]
178
- }], ctorParameters: () => [{ type: i1.GoogleMap }, { type: i0.NgZone }], propDecorators: { url: [{
179
- type: Input
180
- }], bounds: [{
181
- type: Input
182
- }], clickable: [{
183
- type: Input
184
- }], opacity: [{
185
- type: Input
186
- }], mapClick: [{
187
- type: Output
188
- }], mapDblclick: [{
189
- type: Output
190
- }], groundOverlayInitialized: [{
191
- type: Output
192
- }] } });
193
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFwLWdyb3VuZC1vdmVybGF5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2dvb2dsZS1tYXBzL21hcC1ncm91bmQtb3ZlcmxheS9tYXAtZ3JvdW5kLW92ZXJsYXkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztHQU1HO0FBRUgseUVBQXlFO0FBQ3pFLHFEQUFxRDtBQUVyRCxPQUFPLEVBQ0wsU0FBUyxFQUNULFlBQVksRUFDWixLQUFLLEVBQ0wsTUFBTSxFQUdOLE1BQU0sRUFDTixNQUFNLEdBQ1AsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFDLGVBQWUsRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBQzFELE9BQU8sRUFBQyxTQUFTLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUV6QyxPQUFPLEVBQUMsU0FBUyxFQUFDLE1BQU0sMEJBQTBCLENBQUM7QUFDbkQsT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLHNCQUFzQixDQUFDOzs7QUFFckQ7Ozs7R0FJRztBQU1ILE1BQU0sT0FBTyxnQkFBZ0I7SUFrQjNCLDBEQUEwRDtJQUMxRCxJQUNJLEdBQUcsQ0FBQyxHQUFXO1FBQ2pCLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ3RCLENBQUM7SUFFRCw4QkFBOEI7SUFDOUIsSUFDSSxNQUFNO1FBQ1IsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQU0sQ0FBQztJQUM3QixDQUFDO0lBQ0QsSUFBSSxNQUFNLENBQUMsTUFBa0U7UUFDM0UsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDNUIsQ0FBQztJQUtELDhCQUE4QjtJQUM5QixJQUNJLE9BQU8sQ0FBQyxPQUFlO1FBQ3pCLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQzlCLENBQUM7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Q0FBQztJQUNILENBQUM7cUhBOUxVLGdCQUFnQjt5R0FBaEIsZ0JBQWdCOztrR0FBaEIsZ0JBQWdCO2tCQUw1QixTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSxvQkFBb0I7b0JBQzlCLFFBQVEsRUFBRSxrQkFBa0I7b0JBQzVCLFVBQVUsRUFBRSxJQUFJO2lCQUNqQjttR0FxQkssR0FBRztzQkFETixLQUFLO2dCQU9GLE1BQU07c0JBRFQsS0FBSztnQkFTRyxTQUFTO3NCQUFqQixLQUFLO2dCQUlGLE9BQU87c0JBRFYsS0FBSztnQkFTYSxRQUFRO3NCQUExQixNQUFNO2dCQVFZLFdBQVc7c0JBQTdCLE1BQU07Z0JBSVksd0JBQXdCO3NCQUExQyxNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5cbi8vIFdvcmthcm91bmQgZm9yOiBodHRwczovL2dpdGh1Yi5jb20vYmF6ZWxidWlsZC9ydWxlc19ub2RlanMvaXNzdWVzLzEyNjVcbi8vLyA8cmVmZXJlbmNlIHR5cGVzPVwiZ29vZ2xlLm1hcHNcIiBwcmVzZXJ2ZT1cInRydWVcIiAvPlxuXG5pbXBvcnQge1xuICBEaXJlY3RpdmUsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5wdXQsXG4gIE5nWm9uZSxcbiAgT25EZXN0cm95LFxuICBPbkluaXQsXG4gIE91dHB1dCxcbiAgaW5qZWN0LFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7QmVoYXZpb3JTdWJqZWN0LCBPYnNlcnZhYmxlLCBTdWJqZWN0fSBmcm9tICdyeGpzJztcbmltcG9ydCB7dGFrZVVudGlsfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7R29vZ2xlTWFwfSBmcm9tICcuLi9nb29nbGUtbWFwL2dvb2dsZS1tYXAnO1xuaW1wb3J0IHtNYXBFdmVudE1hbmFnZXJ9IGZyb20gJy4uL21hcC1ldmVudC1tYW5hZ2VyJztcblxuLyoqXG4gKiBBbmd1bGFyIGNvbXBvbmVudCB0aGF0IHJlbmRlcnMgYSBHb29nbGUgTWFwcyBHcm91bmQgT3ZlcmxheSB2aWEgdGhlIEdvb2dsZSBNYXBzIEphdmFTY3JpcHQgQVBJLlxuICpcbiAqIFNlZSBkZXZlbG9wZXJzLmdvb2dsZS5jb20vbWFwcy9kb2N1bWVudGF0aW9uL2phdmFzY3JpcHQvcmVmZXJlbmNlL2ltYWdlLW92ZXJsYXkjR3JvdW5kT3ZlcmxheVxuICovXG5ARGlyZWN0aXZlKHtcbiAgc2VsZWN0b3I6ICdtYXAtZ3JvdW5kLW92ZXJsYXknLFxuICBleHBvcnRBczogJ21hcEdyb3VuZE92ZXJsYXknLFxuICBzdGFuZGFsb25lOiB0cnVlLFxufSlcbmV4cG9ydCBjbGFzcyBNYXBHcm91bmRPdmVybGF5IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuICBwcml2YXRlIF9ldmVudE1hbmFnZXIgPSBuZXcgTWFwRXZlbnRNYW5hZ2VyKGluamVjdChOZ1pvbmUpKTtcblxuICBwcml2YXRlIHJlYWRvbmx5IF9vcGFjaXR5ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxudW1iZXI+KDEpO1xuICBwcml2YXRlIHJlYWRvbmx5IF91cmwgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PHN0cmluZz4oJycpO1xuICBwcml2YXRlIHJlYWRvbmx5IF9ib3VuZHMgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFxuICAgIGdvb2dsZS5tYXBzLkxhdExuZ0JvdW5kcyB8IGdvb2dsZS5tYXBzLkxhdExuZ0JvdW5kc0xpdGVyYWwgfCB1bmRlZmluZWRcbiAgPih1bmRlZmluZWQpO1xuICBwcml2YXRlIHJlYWRvbmx5IF9kZXN0cm95ZWQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuICBwcml2YXRlIF9oYXNXYXRjaGVyczogYm9vbGVhbjtcblxuICAvKipcbiAgICogVGhlIHVuZGVybHlpbmcgZ29vZ2xlLm1hcHMuR3JvdW5kT3ZlcmxheSBvYmplY3QuXG4gICAqXG4gICAqIFNlZSBkZXZlbG9wZXJzLmdvb2dsZS5jb20vbWFwcy9kb2N1bWVudGF0aW9uL2phdmFzY3JpcHQvcmVmZXJlbmNlL2ltYWdlLW92ZXJsYXkjR3JvdW5kT3ZlcmxheVxuICAgKi9cbiAgZ3JvdW5kT3ZlcmxheT86IGdvb2dsZS5tYXBzLkdyb3VuZE92ZXJsYXk7XG5cbiAgLyoqIFVSTCBvZiB0aGUgaW1hZ2UgdGhhdCB3aWxsIGJlIHNob3duIGluIHRoZSBvdmVybGF5LiAqL1xuICBASW5wdXQoKVxuICBzZXQgdXJsKHVybDogc3RyaW5nKSB7XG4gICAgdGhpcy5fdXJsLm5leHQodXJsKTtcbiAgfVxuXG4gIC8qKiBCb3VuZHMgZm9yIHRoZSBvdmVybGF5LiAqL1xuICBASW5wdXQoKVxuICBnZXQgYm91bmRzKCk6IGdvb2dsZS5tYXBzLkxhdExuZ0JvdW5kcyB8IGdvb2dsZS5tYXBzLkxhdExuZ0JvdW5kc0xpdGVyYWwge1xuICAgIHJldHVybiB0aGlzLl9ib3VuZHMudmFsdWUhO1xuICB9XG4gIHNldCBib3VuZHMoYm91bmRzOiBnb29nbGUubWFwcy5MYXRMbmdCb3VuZHMgfCBnb29nbGUubWFwcy5MYXRMbmdCb3VuZHNMaXRlcmFsKSB7XG4gICAgdGhpcy5fYm91bmRzLm5leHQoYm91bmRzKTtcbiAgfVxuXG4gIC8qKiBXaGV0aGVyIHRoZSBvdmVybGF5IGlzIGNsaWNrYWJsZSAqL1xuICBASW5wdXQoKSBjbGlja2FibGU6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAvKiogT3BhY2l0eSBvZiB0aGUgb3ZlcmxheS4gKi9cbiAgQElucHV0KClcbiAgc2V0IG9wYWNpdHkob3BhY2l0eTogbnVtYmVyKSB7XG4gICAgdGhpcy5fb3BhY2l0eS5uZXh0KG9wYWNpdHkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNlZVxuICAgKiBkZXZlbG9wZXJzLmdvb2dsZS5jb20vbWFwcy9kb2N1bWVudGF0aW9uL2phdmFzY3JpcHQvcmVmZXJlbmNlL2ltYWdlLW92ZXJsYXkjR3JvdW5kT3ZlcmxheS5jbGlja1xuICAgKi9cbiAgQE91dHB1dCgpIHJlYWRvbmx5IG1hcENsaWNrOiBPYnNlcnZhYmxlPGdvb2dsZS5tYXBzLk1hcE1vdXNlRXZlbnQ+ID1cbiAgICB0aGlzLl9ldmVudE1hbmFnZXIuZ2V0TGF6eUVtaXR0ZXI8Z29vZ2xlLm1hcHMuTWFwTW91c2VFdmVudD4oJ2NsaWNrJyk7XG5cbiAgLyoqXG4gICAqIFNlZVxuICAgKiBkZXZlbG9wZXJzLmdvb2dsZS5jb20vbWFwcy9kb2N1bWVudGF0aW9uL2phdmFzY3JpcHQvcmVmZXJlbmNlL2ltYWdlLW92ZXJsYXlcbiAgICogI0dyb3VuZE92ZXJsYXkuZGJsY2xpY2tcbiAgICovXG4gIEBPdXRwdXQoKSByZWFkb25seSBtYXBEYmxjbGljazogT2JzZXJ2YWJsZTxnb29nbGUubWFwcy5NYXBNb3VzZUV2ZW50PiA9XG4gICAgdGhpcy5fZXZlbnRNYW5hZ2VyLmdldExhenlFbWl0dGVyPGdvb2dsZS5tYXBzLk1hcE1vdXNlRXZlbnQ+KCdkYmxjbGljaycpO1xuXG4gIC8qKiBFdmVudCBlbWl0dGVkIHdoZW4gdGhlIGdyb3VuZCBvdmVybGF5IGlzIGluaXRpYWxpemVkLiAqL1xuICBAT3V0cHV0KCkgcmVhZG9ubHkgZ3JvdW5kT3ZlcmxheUluaXRpYWxpemVkOiBFdmVudEVtaXR0ZXI8Z29vZ2xlLm1hcHMuR3JvdW5kT3ZlcmxheT4gPVxuICAgIG5ldyBFdmVudEVtaXR0ZXI8Z29vZ2xlLm1hcHMuR3JvdW5kT3ZlcmxheT4oKTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9tYXA6IEdvb2dsZU1hcCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9uZ1pvbmU6IE5nWm9uZSxcbiAgKSB7fVxuXG4gIG5nT25Jbml0KCkge1xuICAgIGlmICh0aGlzLl9tYXAuX2lzQnJvd3Nlcikge1xuICAgICAgLy8gVGhlIGdyb3VuZCBvdmVybGF5IHNldHVwIGlzIHNsaWdodGx5IGRpZmZlcmVudCBmcm9tIHRoZSBvdGhlciBHb29nbGUgTWFwcyBvYmplY3RzIGluIHRoYXRcbiAgICAgIC8vIHdlIGhhdmUgdG8gcmVjcmVhdGUgdGhlIGBHcm91bmRPdmVybGF5YCBvYmplY3Qgd2hlbmV2ZXIgdGhlIGJvdW5kcyBjaGFuZ2UsIGJlY2F1c2VcbiAgICAgIC8vIEdvb2dsZSBNYXBzIGRvZXNuJ3QgcHJvdmlkZSBhbiBBUEkgdG8gdXBkYXRlIHRoZSBib3VuZHMgb2YgYW4gZXhpc3Rpbmcgb3ZlcmxheS5cbiAgICAgIHRoaXMuX2JvdW5kcy5waXBlKHRha2VVbnRpbCh0aGlzLl9kZXN0cm95ZWQpKS5zdWJzY3JpYmUoYm91bmRzID0+IHtcbiAgICAgICAgaWYgKHRoaXMuZ3JvdW5kT3ZlcmxheSkge1xuICAgICAgICAgIHRoaXMuZ3JvdW5kT3ZlcmxheS5zZXRNYXAobnVsbCk7XG4gICAgICAgICAgdGhpcy5ncm91bmRPdmVybGF5ID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFib3VuZHMpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZ29vZ2xlLm1hcHMuR3JvdW5kT3ZlcmxheSAmJiB0aGlzLl9tYXAuZ29vZ2xlTWFwKSB7XG4gICAgICAgICAgdGhpcy5faW5pdGlhbGl6ZSh0aGlzLl9tYXAuZ29vZ2xlTWFwLCBnb29nbGUubWFwcy5Hcm91bmRPdmVybGF5LCBib3VuZHMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuX25nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XG4gICAgICAgICAgICBQcm9taXNlLmFsbChbdGhpcy5fbWFwLl9yZXNvbHZlTWFwKCksIGdvb2dsZS5tYXBzLmltcG9ydExpYnJhcnkoJ21hcHMnKV0pLnRoZW4oXG4gICAgICAgICAgICAgIChbbWFwLCBsaWJdKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5faW5pdGlhbGl6ZShtYXAsIChsaWIgYXMgZ29vZ2xlLm1hcHMuTWFwc0xpYnJhcnkpLkdyb3VuZE92ZXJsYXksIGJvdW5kcyk7XG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIF9pbml0aWFsaXplKFxuICAgIG1hcDogZ29vZ2xlLm1hcHMuTWFwLFxuICAgIG92ZXJsYXlDb25zdHJ1Y3RvcjogdHlwZW9mIGdvb2dsZS5tYXBzLkdyb3VuZE92ZXJsYXksXG4gICAgYm91bmRzOiBnb29nbGUubWFwcy5MYXRMbmdCb3VuZHMgfCBnb29nbGUubWFwcy5MYXRMbmdCb3VuZHNMaXRlcmFsLFxuICApIHtcbiAgICAvLyBDcmVhdGUgdGhlIG9iamVjdCBvdXRzaWRlIHRoZSB6b25lIHNvIGl0cyBldmVudHMgZG9uJ3QgdHJpZ2dlciBjaGFuZ2UgZGV0ZWN0aW9uLlxuICAgIC8vIFdlJ2xsIGJyaW5nIGl0IGJhY2sgaW4gaW5zaWRlIHRoZSBgTWFwRXZlbnRNYW5hZ2VyYCBvbmx5IGZvciB0aGUgZXZlbnRzIHRoYXQgdGhlXG4gICAgLy8gdXNlciBoYXMgc3Vic2NyaWJlZCB0by5cbiAgICB0aGlzLl9uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgdGhpcy5ncm91bmRPdmVybGF5ID0gbmV3IG92ZXJsYXlDb25zdHJ1Y3Rvcih0aGlzLl91cmwuZ2V0VmFsdWUoKSwgYm91bmRzLCB7XG4gICAgICAgIGNsaWNrYWJsZTogdGhpcy5jbGlja2FibGUsXG4gICAgICAgIG9wYWNpdHk6IHRoaXMuX29wYWNpdHkudmFsdWUsXG4gICAgICB9KTtcbiAgICAgIHRoaXMuX2Fzc2VydEluaXRpYWxpemVkKCk7XG4gICAgICB0aGlzLmdyb3VuZE92ZXJsYXkuc2V0TWFwKG1hcCk7XG4gICAgICB0aGlzLl9ldmVudE1hbmFnZXIuc2V0VGFyZ2V0KHRoaXMuZ3JvdW5kT3ZlcmxheSk7XG4gICAgICB0aGlzLmdyb3VuZE92ZXJsYXlJbml0aWFsaXplZC5lbWl0KHRoaXMuZ3JvdW5kT3ZlcmxheSk7XG5cbiAgICAgIC8vIFdlIG9ubHkgbmVlZCB0byBzZXQgdXAgdGhlIHdhdGNoZXJzIG9uY2UuXG4gICAgICBpZiAoIXRoaXMuX2hhc1dhdGNoZXJzKSB7XG4gICAgICAgIHRoaXMuX2hhc1dhdGNoZXJzID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5fd2F0Y2hGb3JPcGFjaXR5Q2hhbmdlcygpO1xuICAgICAgICB0aGlzLl93YXRjaEZvclVybENoYW5nZXMoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMuX2V2ZW50TWFuYWdlci5kZXN0cm95KCk7XG4gICAgdGhpcy5fZGVzdHJveWVkLm5leHQoKTtcbiAgICB0aGlzLl9kZXN0cm95ZWQuY29tcGxldGUoKTtcbiAgICB0aGlzLmdyb3VuZE92ZXJsYXk/LnNldE1hcChudWxsKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZWVcbiAgICogZGV2ZWxvcGVycy5nb29nbGUuY29tL21hcHMvZG9jdW1lbnRhdGlvbi9qYXZhc2NyaXB0L3JlZmVyZW5jZS9pbWFnZS1vdmVybGF5XG4gICAqICNHcm91bmRPdmVybGF5LmdldEJvdW5kc1xuICAgKi9cbiAgZ2V0Qm91bmRzKCk6IGdvb2dsZS5tYXBzLkxhdExuZ0JvdW5kcyB8IG51bGwge1xuICAgIHRoaXMuX2Fzc2VydEluaXRpYWxpemVkKCk7XG4gICAgcmV0dXJuIHRoaXMuZ3JvdW5kT3ZlcmxheS5nZXRCb3VuZHMoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZWVcbiAgICogZGV2ZWxvcGVycy5nb29nbGUuY29tL21hcHMvZG9jdW1lbnRhdGlvbi9qYXZhc2NyaXB0L3JlZmVyZW5jZS9pbWFnZS1vdmVybGF5XG4gICAqICNHcm91bmRPdmVybGF5LmdldE9wYWNpdHlcbiAgICovXG4gIGdldE9wYWNpdHkoKTogbnVtYmVyIHtcbiAgICB0aGlzLl9hc3NlcnRJbml0aWFsaXplZCgpO1xuICAgIHJldHVybiB0aGlzLmdyb3VuZE92ZXJsYXkuZ2V0T3BhY2l0eSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNlZVxuICAgKiBkZXZlbG9wZXJzLmdvb2dsZS5jb20vbWFwcy9kb2N1bWVudGF0aW9uL2phdmFzY3JpcHQvcmVmZXJlbmNlL2ltYWdlLW92ZXJsYXlcbiAgICogI0dyb3VuZE92ZXJsYXkuZ2V0VXJsXG4gICAqL1xuICBnZXRVcmwoKTogc3RyaW5nIHtcbiAgICB0aGlzLl9hc3NlcnRJbml0aWFsaXplZCgpO1xuICAgIHJldHVybiB0aGlzLmdyb3VuZE92ZXJsYXkuZ2V0VXJsKCk7XG4gIH1cblxuICBwcml2YXRlIF93YXRjaEZvck9wYWNpdHlDaGFuZ2VzKCkge1xuICAgIHRoaXMuX29wYWNpdHkucGlwZSh0YWtlVW50aWwodGhpcy5fZGVzdHJveWVkKSkuc3Vic2NyaWJlKG9wYWNpdHkgPT4ge1xuICAgICAgaWYgKG9wYWNpdHkgIT0gbnVsbCkge1xuICAgICAgICB0aGlzLmdyb3VuZE92ZXJsYXk/LnNldE9wYWNpdHkob3BhY2l0eSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIF93YXRjaEZvclVybENoYW5nZXMoKSB7XG4gICAgdGhpcy5fdXJsLnBpcGUodGFrZVVudGlsKHRoaXMuX2Rlc3Ryb3llZCkpLnN1YnNjcmliZSh1cmwgPT4ge1xuICAgICAgY29uc3Qgb3ZlcmxheSA9IHRoaXMuZ3JvdW5kT3ZlcmxheTtcblxuICAgICAgaWYgKG92ZXJsYXkpIHtcbiAgICAgICAgb3ZlcmxheS5zZXQoJ3VybCcsIHVybCk7XG4gICAgICAgIC8vIEdvb2dsZSBNYXBzIG9ubHkgcmVkcmF3cyB0aGUgb3ZlcmxheSBpZiB3ZSByZS1zZXQgdGhlIG1hcC5cbiAgICAgICAgb3ZlcmxheS5zZXRNYXAobnVsbCk7XG4gICAgICAgIG92ZXJsYXkuc2V0TWFwKHRoaXMuX21hcC5nb29nbGVNYXAhKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgX2Fzc2VydEluaXRpYWxpemVkKCk6IGFzc2VydHMgdGhpcyBpcyB7Z3JvdW5kT3ZlcmxheTogZ29vZ2xlLm1hcHMuR3JvdW5kT3ZlcmxheX0ge1xuICAgIGlmICh0eXBlb2YgbmdEZXZNb2RlID09PSAndW5kZWZpbmVkJyB8fCBuZ0Rldk1vZGUpIHtcbiAgICAgIGlmICghdGhpcy5ncm91bmRPdmVybGF5KSB7XG4gICAgICAgIHRocm93IEVycm9yKFxuICAgICAgICAgICdDYW5ub3QgaW50ZXJhY3Qgd2l0aCBhIEdvb2dsZSBNYXAgR3JvdW5kT3ZlcmxheSBiZWZvcmUgaXQgaGFzIGJlZW4gaW5pdGlhbGl6ZWQuICcgK1xuICAgICAgICAgICAgJ1BsZWFzZSB3YWl0IGZvciB0aGUgR3JvdW5kT3ZlcmxheSB0byBsb2FkIGJlZm9yZSB0cnlpbmcgdG8gaW50ZXJhY3Qgd2l0aCBpdC4nLFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuIl19
@@ -1,151 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright Google LLC All Rights Reserved.
4
- *
5
- * Use of this source code is governed by an MIT-style license that can be
6
- * found in the LICENSE file at https://angular.io/license
7
- */
8
- // Workaround for: https://github.com/bazelbuild/rules_nodejs/issues/1265
9
- /// <reference types="google.maps" preserve="true" />
10
- import { Input, NgZone, Directive, Output, EventEmitter, } from '@angular/core';
11
- import { GoogleMap } from '../google-map/google-map';
12
- import * as i0 from "@angular/core";
13
- import * as i1 from "../google-map/google-map";
14
- /**
15
- * Angular directive that renders a Google Maps heatmap via the Google Maps JavaScript API.
16
- *
17
- * See: https://developers.google.com/maps/documentation/javascript/reference/visualization
18
- */
19
- export class MapHeatmapLayer {
20
- /**
21
- * Data shown on the heatmap.
22
- * See: https://developers.google.com/maps/documentation/javascript/reference/visualization
23
- */
24
- set data(data) {
25
- this._data = data;
26
- }
27
- /**
28
- * Options used to configure the heatmap. See:
29
- * developers.google.com/maps/documentation/javascript/reference/visualization#HeatmapLayerOptions
30
- */
31
- set options(options) {
32
- this._options = options;
33
- }
34
- constructor(_googleMap, _ngZone) {
35
- this._googleMap = _googleMap;
36
- this._ngZone = _ngZone;
37
- /** Event emitted when the heatmap is initialized. */
38
- this.heatmapInitialized = new EventEmitter();
39
- }
40
- ngOnInit() {
41
- if (this._googleMap._isBrowser) {
42
- if (!window.google?.maps?.visualization &&
43
- !window.google?.maps.importLibrary &&
44
- (typeof ngDevMode === 'undefined' || ngDevMode)) {
45
- throw Error('Namespace `google.maps.visualization` not found, cannot construct heatmap. ' +
46
- 'Please install the Google Maps JavaScript API with the "visualization" library: ' +
47
- 'https://developers.google.com/maps/documentation/javascript/visualization');
48
- }
49
- if (google.maps.visualization?.HeatmapLayer && this._googleMap.googleMap) {
50
- this._initialize(this._googleMap.googleMap, google.maps.visualization.HeatmapLayer);
51
- }
52
- else {
53
- this._ngZone.runOutsideAngular(() => {
54
- Promise.all([
55
- this._googleMap._resolveMap(),
56
- google.maps.importLibrary('visualization'),
57
- ]).then(([map, lib]) => {
58
- this._initialize(map, lib.HeatmapLayer);
59
- });
60
- });
61
- }
62
- }
63
- }
64
- _initialize(map, heatmapConstructor) {
65
- // Create the object outside the zone so its events don't trigger change detection.
66
- // We'll bring it back in inside the `MapEventManager` only for the events that the
67
- // user has subscribed to.
68
- this._ngZone.runOutsideAngular(() => {
69
- this.heatmap = new heatmapConstructor(this._combineOptions());
70
- this._assertInitialized();
71
- this.heatmap.setMap(map);
72
- this.heatmapInitialized.emit(this.heatmap);
73
- });
74
- }
75
- ngOnChanges(changes) {
76
- const { _data, heatmap } = this;
77
- if (heatmap) {
78
- if (changes['options']) {
79
- heatmap.setOptions(this._combineOptions());
80
- }
81
- if (changes['data'] && _data !== undefined) {
82
- heatmap.setData(this._normalizeData(_data));
83
- }
84
- }
85
- }
86
- ngOnDestroy() {
87
- this.heatmap?.setMap(null);
88
- }
89
- /**
90
- * Gets the data that is currently shown on the heatmap.
91
- * See: developers.google.com/maps/documentation/javascript/reference/visualization#HeatmapLayer
92
- */
93
- getData() {
94
- this._assertInitialized();
95
- return this.heatmap.getData();
96
- }
97
- /** Creates a combined options object using the passed-in options and the individual inputs. */
98
- _combineOptions() {
99
- const options = this._options || {};
100
- return {
101
- ...options,
102
- data: this._normalizeData(this._data || options.data || []),
103
- map: this._googleMap.googleMap,
104
- };
105
- }
106
- /**
107
- * Most Google Maps APIs support both `LatLng` objects and `LatLngLiteral`. The latter is more
108
- * convenient to write out, because the Google Maps API doesn't have to have been loaded in order
109
- * to construct them. The `HeatmapLayer` appears to be an exception that only allows a `LatLng`
110
- * object, or it throws a runtime error. Since it's more convenient and we expect that Angular
111
- * users will load the API asynchronously, we allow them to pass in a `LatLngLiteral` and we
112
- * convert it to a `LatLng` object before passing it off to Google Maps.
113
- */
114
- _normalizeData(data) {
115
- const result = [];
116
- data.forEach(item => {
117
- result.push(isLatLngLiteral(item) ? new google.maps.LatLng(item.lat, item.lng) : item);
118
- });
119
- return result;
120
- }
121
- /** Asserts that the heatmap object has been initialized. */
122
- _assertInitialized() {
123
- if (typeof ngDevMode === 'undefined' || ngDevMode) {
124
- if (!this.heatmap) {
125
- throw Error('Cannot interact with a Google Map HeatmapLayer before it has been ' +
126
- 'initialized. Please wait for the heatmap to load before trying to interact with it.');
127
- }
128
- }
129
- }
130
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.0-next.2", ngImport: i0, type: MapHeatmapLayer, deps: [{ token: i1.GoogleMap }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive }); }
131
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.0-next.2", type: MapHeatmapLayer, isStandalone: true, selector: "map-heatmap-layer", inputs: { data: "data", options: "options" }, outputs: { heatmapInitialized: "heatmapInitialized" }, exportAs: ["mapHeatmapLayer"], usesOnChanges: true, ngImport: i0 }); }
132
- }
133
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.0-next.2", ngImport: i0, type: MapHeatmapLayer, decorators: [{
134
- type: Directive,
135
- args: [{
136
- selector: 'map-heatmap-layer',
137
- exportAs: 'mapHeatmapLayer',
138
- standalone: true,
139
- }]
140
- }], ctorParameters: () => [{ type: i1.GoogleMap }, { type: i0.NgZone }], propDecorators: { data: [{
141
- type: Input
142
- }], options: [{
143
- type: Input
144
- }], heatmapInitialized: [{
145
- type: Output
146
- }] } });
147
- /** Asserts that an object is a `LatLngLiteral`. */
148
- function isLatLngLiteral(value) {
149
- return value && typeof value.lat === 'number' && typeof value.lng === 'number';
150
- }
151
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFwLWhlYXRtYXAtbGF5ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvZ29vZ2xlLW1hcHMvbWFwLWhlYXRtYXAtbGF5ZXIvbWFwLWhlYXRtYXAtbGF5ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztHQU1HO0FBRUgseUVBQXlFO0FBQ3pFLHFEQUFxRDtBQUVyRCxPQUFPLEVBQ0wsS0FBSyxFQUdMLE1BQU0sRUFDTixTQUFTLEVBR1QsTUFBTSxFQUNOLFlBQVksR0FDYixNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQUMsU0FBUyxFQUFDLE1BQU0sMEJBQTBCLENBQUM7OztBQVNuRDs7OztHQUlHO0FBTUgsTUFBTSxPQUFPLGVBQWU7SUFDMUI7OztPQUdHO0lBQ0gsSUFDSSxJQUFJLENBQUMsSUFBaUI7UUFDeEIsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7SUFDcEIsQ0FBQztJQUdEOzs7T0FHRztJQUNILElBQ0ksT0FBTyxDQUFDLE9BQStEO1FBQ3pFLElBQUksQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDO0lBQzFCLENBQUM7SUFjRCxZQUNtQixVQUFxQixFQUM5QixPQUFlO1FBRE4sZUFBVSxHQUFWLFVBQVUsQ0FBVztRQUM5QixZQUFPLEdBQVAsT0FBTyxDQUFRO1FBTnpCLHFEQUFxRDtRQUNsQyx1QkFBa0IsR0FDbkMsSUFBSSxZQUFZLEVBQTBDLENBQUM7SUFLMUQsQ0FBQztJQUVKLFFBQVE7UUFDTixJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDL0IsSUFDRSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLGFBQWE7Z0JBQ25DLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsYUFBYTtnQkFDbEMsQ0FBQyxPQUFPLFNBQVMsS0FBSyxXQUFXLElBQUksU0FBUyxDQUFDLEVBQy9DLENBQUM7Z0JBQ0Qs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biAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIExMQyBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cblxuLy8gV29ya2Fyb3VuZCBmb3I6IGh0dHBzOi8vZ2l0aHViLmNvbS9iYXplbGJ1aWxkL3J1bGVzX25vZGVqcy9pc3N1ZXMvMTI2NVxuLy8vIDxyZWZlcmVuY2UgdHlwZXM9XCJnb29nbGUubWFwc1wiIHByZXNlcnZlPVwidHJ1ZVwiIC8+XG5cbmltcG9ydCB7XG4gIElucHV0LFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgTmdab25lLFxuICBEaXJlY3RpdmUsXG4gIE9uQ2hhbmdlcyxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgT3V0cHV0LFxuICBFdmVudEVtaXR0ZXIsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQge0dvb2dsZU1hcH0gZnJvbSAnLi4vZ29vZ2xlLW1hcC9nb29nbGUtbWFwJztcblxuLyoqIFBvc3NpYmxlIGRhdGEgdGhhdCBjYW4gYmUgc2hvd24gb24gYSBoZWF0bWFwIGxheWVyLiAqL1xuZXhwb3J0IHR5cGUgSGVhdG1hcERhdGEgPVxuICB8IGdvb2dsZS5tYXBzLk1WQ0FycmF5PFxuICAgICAgZ29vZ2xlLm1hcHMuTGF0TG5nIHwgZ29vZ2xlLm1hcHMudmlzdWFsaXphdGlvbi5XZWlnaHRlZExvY2F0aW9uIHwgZ29vZ2xlLm1hcHMuTGF0TG5nTGl0ZXJhbFxuICAgID5cbiAgfCAoZ29vZ2xlLm1hcHMuTGF0TG5nIHwgZ29vZ2xlLm1hcHMudmlzdWFsaXphdGlvbi5XZWlnaHRlZExvY2F0aW9uIHwgZ29vZ2xlLm1hcHMuTGF0TG5nTGl0ZXJhbClbXTtcblxuLyoqXG4gKiBBbmd1bGFyIGRpcmVjdGl2ZSB0aGF0IHJlbmRlcnMgYSBHb29nbGUgTWFwcyBoZWF0bWFwIHZpYSB0aGUgR29vZ2xlIE1hcHMgSmF2YVNjcmlwdCBBUEkuXG4gKlxuICogU2VlOiBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9tYXBzL2RvY3VtZW50YXRpb24vamF2YXNjcmlwdC9yZWZlcmVuY2UvdmlzdWFsaXphdGlvblxuICovXG5ARGlyZWN0aXZlKHtcbiAgc2VsZWN0b3I6ICdtYXAtaGVhdG1hcC1sYXllcicsXG4gIGV4cG9ydEFzOiAnbWFwSGVhdG1hcExheWVyJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbn0pXG5leHBvcnQgY2xhc3MgTWFwSGVhdG1hcExheWVyIGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMsIE9uRGVzdHJveSB7XG4gIC8qKlxuICAgKiBEYXRhIHNob3duIG9uIHRoZSBoZWF0bWFwLlxuICAgKiBTZWU6IGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL21hcHMvZG9jdW1lbnRhdGlvbi9qYXZhc2NyaXB0L3JlZmVyZW5jZS92aXN1YWxpemF0aW9uXG4gICAqL1xuICBASW5wdXQoKVxuICBzZXQgZGF0YShkYXRhOiBIZWF0bWFwRGF0YSkge1xuICAgIHRoaXMuX2RhdGEgPSBkYXRhO1xuICB9XG4gIHByaXZhdGUgX2RhdGE6IEhlYXRtYXBEYXRhO1xuXG4gIC8qKlxuICAgKiBPcHRpb25zIHVzZWQgdG8gY29uZmlndXJlIHRoZSBoZWF0bWFwLiBTZWU6XG4gICAqIGRldmVsb3BlcnMuZ29vZ2xlLmNvbS9tYXBzL2RvY3VtZW50YXRpb24vamF2YXNjcmlwdC9yZWZlcmVuY2UvdmlzdWFsaXphdGlvbiNIZWF0bWFwTGF5ZXJPcHRpb25zXG4gICAqL1xuICBASW5wdXQoKVxuICBzZXQgb3B0aW9ucyhvcHRpb25zOiBQYXJ0aWFsPGdvb2dsZS5tYXBzLnZpc3VhbGl6YXRpb24uSGVhdG1hcExheWVyT3B0aW9ucz4pIHtcbiAgICB0aGlzLl9vcHRpb25zID0gb3B0aW9ucztcbiAgfVxuICBwcml2YXRlIF9vcHRpb25zOiBQYXJ0aWFsPGdvb2dsZS5tYXBzLnZpc3VhbGl6YXRpb24uSGVhdG1hcExheWVyT3B0aW9ucz47XG5cbiAgLyoqXG4gICAqIFRoZSB1bmRlcmx5aW5nIGdvb2dsZS5tYXBzLnZpc3VhbGl6YXRpb24uSGVhdG1hcExheWVyIG9iamVjdC5cbiAgICpcbiAgICogU2VlOiBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9tYXBzL2RvY3VtZW50YXRpb24vamF2YXNjcmlwdC9yZWZlcmVuY2UvdmlzdWFsaXphdGlvblxuICAgKi9cbiAgaGVhdG1hcD86IGdvb2dsZS5tYXBzLnZpc3VhbGl6YXRpb24uSGVhdG1hcExheWVyO1xuXG4gIC8qKiBFdmVudCBlbWl0dGVkIHdoZW4gdGhlIGhlYXRtYXAgaXMgaW5pdGlhbGl6ZWQuICovXG4gIEBPdXRwdXQoKSByZWFkb25seSBoZWF0bWFwSW5pdGlhbGl6ZWQ6IEV2ZW50RW1pdHRlcjxnb29nbGUubWFwcy52aXN1YWxpemF0aW9uLkhlYXRtYXBMYXllcj4gPVxuICAgIG5ldyBFdmVudEVtaXR0ZXI8Z29vZ2xlLm1hcHMudmlzdWFsaXphdGlvbi5IZWF0bWFwTGF5ZXI+KCk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBfZ29vZ2xlTWFwOiBHb29nbGVNYXAsXG4gICAgcHJpdmF0ZSBfbmdab25lOiBOZ1pvbmUsXG4gICkge31cblxuICBuZ09uSW5pdCgpIHtcbiAgICBpZiAodGhpcy5fZ29vZ2xlTWFwLl9pc0Jyb3dzZXIpIHtcbiAgICAgIGlmIChcbiAgICAgICAgIXdpbmRvdy5nb29nbGU/Lm1hcHM/LnZpc3VhbGl6YXRpb24gJiZcbiAgICAgICAgIXdpbmRvdy5nb29nbGU/Lm1hcHMuaW1wb3J0TGlicmFyeSAmJlxuICAgICAgICAodHlwZW9mIG5nRGV2TW9kZSA9PT0gJ3VuZGVmaW5lZCcgfHwgbmdEZXZNb2RlKVxuICAgICAgKSB7XG4gICAgICAgIHRocm93IEVycm9yKFxuICAgICAgICAgICdOYW1lc3BhY2UgYGdvb2dsZS5tYXBzLnZpc3VhbGl6YXRpb25gIG5vdCBmb3VuZCwgY2Fubm90IGNvbnN0cnVjdCBoZWF0bWFwLiAnICtcbiAgICAgICAgICAgICdQbGVhc2UgaW5zdGFsbCB0aGUgR29vZ2xlIE1hcHMgSmF2YVNjcmlwdCBBUEkgd2l0aCB0aGUgXCJ2aXN1YWxpemF0aW9uXCIgbGlicmFyeTogJyArXG4gICAgICAgICAgICAnaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vbWFwcy9kb2N1bWVudGF0aW9uL2phdmFzY3JpcHQvdmlzdWFsaXphdGlvbicsXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGlmIChnb29nbGUubWFwcy52aXN1YWxpemF0aW9uPy5IZWF0bWFwTGF5ZXIgJiYgdGhpcy5fZ29vZ2xlTWFwLmdvb2dsZU1hcCkge1xuICAgICAgICB0aGlzLl9pbml0aWFsaXplKHRoaXMuX2dvb2dsZU1hcC5nb29nbGVNYXAsIGdvb2dsZS5tYXBzLnZpc3VhbGl6YXRpb24uSGVhdG1hcExheWVyKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuX25nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XG4gICAgICAgICAgUHJvbWlzZS5hbGwoW1xuICAgICAgICAgICAgdGhpcy5fZ29vZ2xlTWFwLl9yZXNvbHZlTWFwKCksXG4gICAgICAgICAgICBnb29nbGUubWFwcy5pbXBvcnRMaWJyYXJ5KCd2aXN1YWxpemF0aW9uJyksXG4gICAgICAgICAgXSkudGhlbigoW21hcCwgbGliXSkgPT4ge1xuICAgICAgICAgICAgdGhpcy5faW5pdGlhbGl6ZShtYXAsIChsaWIgYXMgZ29vZ2xlLm1hcHMuVmlzdWFsaXphdGlvbkxpYnJhcnkpLkhlYXRtYXBMYXllcik7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX2luaXRpYWxpemUoXG4gICAgbWFwOiBnb29nbGUubWFwcy5NYXAsXG4gICAgaGVhdG1hcENvbnN0cnVjdG9yOiB0eXBlb2YgZ29vZ2xlLm1hcHMudmlzdWFsaXphdGlvbi5IZWF0bWFwTGF5ZXIsXG4gICkge1xuICAgIC8vIENyZWF0ZSB0aGUgb2JqZWN0IG91dHNpZGUgdGhlIHpvbmUgc28gaXRzIGV2ZW50cyBkb24ndCB0cmlnZ2VyIGNoYW5nZSBkZXRlY3Rpb24uXG4gICAgLy8gV2UnbGwgYnJpbmcgaXQgYmFjayBpbiBpbnNpZGUgdGhlIGBNYXBFdmVudE1hbmFnZXJgIG9ubHkgZm9yIHRoZSBldmVudHMgdGhhdCB0aGVcbiAgICAvLyB1c2VyIGhhcyBzdWJzY3JpYmVkIHRvLlxuICAgIHRoaXMuX25nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XG4gICAgICB0aGlzLmhlYXRtYXAgPSBuZXcgaGVhdG1hcENvbnN0cnVjdG9yKHRoaXMuX2NvbWJpbmVPcHRpb25zKCkpO1xuICAgICAgdGhpcy5fYXNzZXJ0SW5pdGlhbGl6ZWQoKTtcbiAgICAgIHRoaXMuaGVhdG1hcC5zZXRNYXAobWFwKTtcbiAgICAgIHRoaXMuaGVhdG1hcEluaXRpYWxpemVkLmVtaXQodGhpcy5oZWF0bWFwKTtcbiAgICB9KTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpIHtcbiAgICBjb25zdCB7X2RhdGEsIGhlYXRtYXB9ID0gdGhpcztcblxuICAgIGlmIChoZWF0bWFwKSB7XG4gICAgICBpZiAoY2hhbmdlc1snb3B0aW9ucyddKSB7XG4gICAgICAgIGhlYXRtYXAuc2V0T3B0aW9ucyh0aGlzLl9jb21iaW5lT3B0aW9ucygpKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGNoYW5nZXNbJ2RhdGEnXSAmJiBfZGF0YSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGhlYXRtYXAuc2V0RGF0YSh0aGlzLl9ub3JtYWxpemVEYXRhKF9kYXRhKSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgdGhpcy5oZWF0bWFwPy5zZXRNYXAobnVsbCk7XG4gIH1cblxuICAvKipcbiAgICogR2V0cyB0aGUgZGF0YSB0aGF0IGlzIGN1cnJlbnRseSBzaG93biBvbiB0aGUgaGVhdG1hcC5cbiAgICogU2VlOiBkZXZlbG9wZXJzLmdvb2dsZS5jb20vbWFwcy9kb2N1bWVudGF0aW9uL2phdmFzY3JpcHQvcmVmZXJlbmNlL3Zpc3VhbGl6YXRpb24jSGVhdG1hcExheWVyXG4gICAqL1xuICBnZXREYXRhKCk6IEhlYXRtYXBEYXRhIHtcbiAgICB0aGlzLl9hc3NlcnRJbml0aWFsaXplZCgpO1xuICAgIHJldHVybiB0aGlzLmhlYXRtYXAuZ2V0RGF0YSgpO1xuICB9XG5cbiAgLyoqIENyZWF0ZXMgYSBjb21iaW5lZCBvcHRpb25zIG9iamVjdCB1c2luZyB0aGUgcGFzc2VkLWluIG9wdGlvbnMgYW5kIHRoZSBpbmRpdmlkdWFsIGlucHV0cy4gKi9cbiAgcHJpdmF0ZSBfY29tYmluZU9wdGlvbnMoKTogZ29vZ2xlLm1hcHMudmlzdWFsaXphdGlvbi5IZWF0bWFwTGF5ZXJPcHRpb25zIHtcbiAgICBjb25zdCBvcHRpb25zID0gdGhpcy5fb3B0aW9ucyB8fCB7fTtcbiAgICByZXR1cm4ge1xuICAgICAgLi4ub3B0aW9ucyxcbiAgICAgIGRhdGE6IHRoaXMuX25vcm1hbGl6ZURhdGEodGhpcy5fZGF0YSB8fCBvcHRpb25zLmRhdGEgfHwgW10pLFxuICAgICAgbWFwOiB0aGlzLl9nb29nbGVNYXAuZ29vZ2xlTWFwLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogTW9zdCBHb29nbGUgTWFwcyBBUElzIHN1cHBvcnQgYm90aCBgTGF0TG5nYCBvYmplY3RzIGFuZCBgTGF0TG5nTGl0ZXJhbGAuIFRoZSBsYXR0ZXIgaXMgbW9yZVxuICAgKiBjb252ZW5pZW50IHRvIHdyaXRlIG91dCwgYmVjYXVzZSB0aGUgR29vZ2xlIE1hcHMgQVBJIGRvZXNuJ3QgaGF2ZSB0byBoYXZlIGJlZW4gbG9hZGVkIGluIG9yZGVyXG4gICAqIHRvIGNvbnN0cnVjdCB0aGVtLiBUaGUgYEhlYXRtYXBMYXllcmAgYXBwZWFycyB0byBiZSBhbiBleGNlcHRpb24gdGhhdCBvbmx5IGFsbG93cyBhIGBMYXRMbmdgXG4gICAqIG9iamVjdCwgb3IgaXQgdGhyb3dzIGEgcnVudGltZSBlcnJvci4gU2luY2UgaXQncyBtb3JlIGNvbnZlbmllbnQgYW5kIHdlIGV4cGVjdCB0aGF0IEFuZ3VsYXJcbiAgICogdXNlcnMgd2lsbCBsb2FkIHRoZSBBUEkgYXN5bmNocm9ub3VzbHksIHdlIGFsbG93IHRoZW0gdG8gcGFzcyBpbiBhIGBMYXRMbmdMaXRlcmFsYCBhbmQgd2VcbiAgICogY29udmVydCBpdCB0byBhIGBMYXRMbmdgIG9iamVjdCBiZWZvcmUgcGFzc2luZyBpdCBvZmYgdG8gR29vZ2xlIE1hcHMuXG4gICAqL1xuICBwcml2YXRlIF9ub3JtYWxpemVEYXRhKGRhdGE6IEhlYXRtYXBEYXRhKSB7XG4gICAgY29uc3QgcmVzdWx0OiAoZ29vZ2xlLm1hcHMuTGF0TG5nIHwgZ29vZ2xlLm1hcHMudmlzdWFsaXphdGlvbi5XZWlnaHRlZExvY2F0aW9uKVtdID0gW107XG5cbiAgICBkYXRhLmZvckVhY2goaXRlbSA9PiB7XG4gICAgICByZXN1bHQucHVzaChpc0xhdExuZ0xpdGVyYWwoaXRlbSkgPyBuZXcgZ29vZ2xlLm1hcHMuTGF0TG5nKGl0ZW0ubGF0LCBpdGVtLmxuZykgOiBpdGVtKTtcbiAgICB9KTtcblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKiogQXNzZXJ0cyB0aGF0IHRoZSBoZWF0bWFwIG9iamVjdCBoYXMgYmVlbiBpbml0aWFsaXplZC4gKi9cbiAgcHJpdmF0ZSBfYXNzZXJ0SW5pdGlhbGl6ZWQoKTogYXNzZXJ0cyB0aGlzIGlzIHtoZWF0bWFwOiBnb29nbGUubWFwcy52aXN1YWxpemF0aW9uLkhlYXRtYXBMYXllcn0ge1xuICAgIGlmICh0eXBlb2YgbmdEZXZNb2RlID09PSAndW5kZWZpbmVkJyB8fCBuZ0Rldk1vZGUpIHtcbiAgICAgIGlmICghdGhpcy5oZWF0bWFwKSB7XG4gICAgICAgIHRocm93IEVycm9yKFxuICAgICAgICAgICdDYW5ub3QgaW50ZXJhY3Qgd2l0aCBhIEdvb2dsZSBNYXAgSGVhdG1hcExheWVyIGJlZm9yZSBpdCBoYXMgYmVlbiAnICtcbiAgICAgICAgICAgICdpbml0aWFsaXplZC4gUGxlYXNlIHdhaXQgZm9yIHRoZSBoZWF0bWFwIHRvIGxvYWQgYmVmb3JlIHRyeWluZyB0byBpbnRlcmFjdCB3aXRoIGl0LicsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbi8qKiBBc3NlcnRzIHRoYXQgYW4gb2JqZWN0IGlzIGEgYExhdExuZ0xpdGVyYWxgLiAqL1xuZnVuY3Rpb24gaXNMYXRMbmdMaXRlcmFsKHZhbHVlOiBhbnkpOiB2YWx1ZSBpcyBnb29nbGUubWFwcy5MYXRMbmdMaXRlcmFsIHtcbiAgcmV0dXJuIHZhbHVlICYmIHR5cGVvZiB2YWx1ZS5sYXQgPT09ICdudW1iZXInICYmIHR5cGVvZiB2YWx1ZS5sbmcgPT09ICdudW1iZXInO1xufVxuIl19