@sumaris-net/ngx-components 0.24.1 → 0.25.1

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 (51) hide show
  1. package/bundles/{ngx-sumaris-components.umd.js → sumaris-net.ngx-components.umd.js} +923 -882
  2. package/bundles/sumaris-net.ngx-components.umd.js.map +1 -0
  3. package/bundles/sumaris-net.ngx-components.umd.min.js +25 -0
  4. package/bundles/sumaris-net.ngx-components.umd.min.js.map +1 -0
  5. package/esm2015/public_api.js +2 -1
  6. package/esm2015/src/app/admin/services/filter/person.filter.js +4 -2
  7. package/esm2015/src/app/admin/services/person.service.js +3 -2
  8. package/esm2015/src/app/admin/users/list/users.js +6 -4
  9. package/esm2015/src/app/core/graphql/graphql.service.js +17 -63
  10. package/esm2015/src/app/core/graphql/graphql.utils.js +1 -1
  11. package/esm2015/src/app/core/install/install-upgrade-card.component.js +28 -16
  12. package/esm2015/src/app/core/services/account.service.js +146 -149
  13. package/esm2015/src/app/core/services/config.service.js +21 -14
  14. package/esm2015/src/app/core/services/local-settings.service.js +72 -87
  15. package/esm2015/src/app/core/services/network.service.js +135 -170
  16. package/esm2015/src/app/core/services/platform.service.js +32 -17
  17. package/esm2015/src/app/core/services/storage/entities-storage.service.js +59 -63
  18. package/esm2015/src/app/shared/audio/audio.js +10 -39
  19. package/esm2015/src/app/shared/functions.js +6 -7
  20. package/esm2015/src/app/shared/material/boolean/material.boolean.js +1 -1
  21. package/esm2015/src/app/shared/services/startable-service.class.js +74 -0
  22. package/esm2015/src/environments/environment.class.js +1 -1
  23. package/esm2015/src/environments/environment.js +5 -1
  24. package/esm2015/sumaris-net.ngx-components.js +13 -0
  25. package/fesm2015/{ngx-sumaris-components.js → sumaris-net.ngx-components.js} +605 -629
  26. package/fesm2015/sumaris-net.ngx-components.js.map +1 -0
  27. package/package.json +13 -9
  28. package/public_api.d.ts +1 -0
  29. package/src/app/admin/services/filter/person.filter.d.ts +1 -0
  30. package/src/app/admin/users/list/users.d.ts +1 -0
  31. package/src/app/core/graphql/graphql.service.d.ts +5 -13
  32. package/src/app/core/graphql/graphql.utils.d.ts +2 -1
  33. package/src/app/core/install/install-upgrade-card.component.d.ts +4 -4
  34. package/src/app/core/services/account.service.d.ts +11 -10
  35. package/src/app/core/services/config.service.d.ts +6 -5
  36. package/src/app/core/services/local-settings.service.d.ts +4 -9
  37. package/src/app/core/services/network.service.d.ts +27 -38
  38. package/src/app/core/services/platform.service.d.ts +2 -1
  39. package/src/app/core/services/storage/entities-storage.service.d.ts +13 -13
  40. package/src/app/shared/audio/audio.d.ts +4 -8
  41. package/src/app/shared/functions.d.ts +1 -1
  42. package/src/app/shared/services/startable-service.class.d.ts +25 -0
  43. package/src/environments/environment.class.d.ts +1 -0
  44. package/{ngx-sumaris-components.d.ts → sumaris-net.ngx-components.d.ts} +0 -0
  45. package/sumaris-net.ngx-components.metadata.json +1 -0
  46. package/bundles/ngx-sumaris-components.umd.js.map +0 -1
  47. package/bundles/ngx-sumaris-components.umd.min.js +0 -25
  48. package/bundles/ngx-sumaris-components.umd.min.js.map +0 -1
  49. package/esm2015/ngx-sumaris-components.js +0 -13
  50. package/fesm2015/ngx-sumaris-components.js.map +0 -1
  51. package/ngx-sumaris-components.metadata.json +0 -1
@@ -15,11 +15,11 @@ const MimeTypes = Object.freeze({
15
15
  ANDROID_APK: 'application/vnd.android.package-archive'
16
16
  });
17
17
  export class AppInstallUpgradeCard {
18
- constructor(modalCtrl, configService, platform, cd, network, environment) {
18
+ constructor(modalCtrl, configService, cd, platform, network, environment) {
19
19
  this.modalCtrl = modalCtrl;
20
20
  this.configService = configService;
21
- this.platform = platform;
22
21
  this.cd = cd;
22
+ this.platform = platform;
23
23
  this.network = network;
24
24
  this.environment = environment;
25
25
  this._subscription = new Subscription();
@@ -30,7 +30,6 @@ export class AppInstallUpgradeCard {
30
30
  this.showOfflineWarning = true;
31
31
  this.showInstallButton = false;
32
32
  this.onUpdateOfflineModeClick = new EventEmitter();
33
- this.isAndroidCordova = platform.isAndroidCordova();
34
33
  }
35
34
  set showUpdateOfflineFeature(value) {
36
35
  if (value === this._showUpdateOfflineFeature)
@@ -74,13 +73,21 @@ export class AppInstallUpgradeCard {
74
73
  ngOnDestroy() {
75
74
  this._subscription.unsubscribe();
76
75
  }
77
- downloadLink(event, link) {
78
- if (!link || !link.url)
79
- return; // Skip
80
- this.platform.download({
81
- uri: link.url,
82
- filename: link.downloadFilename,
83
- mimeType: link.mimeType
76
+ downloadUsingPlatform(event, link) {
77
+ return __awaiter(this, void 0, void 0, function* () {
78
+ if (!link || !link.url) {
79
+ console.info('[install-upgrade] Invalid link: ' + JSON.stringify(link));
80
+ return; // Skip
81
+ }
82
+ console.info('[install-upgrade] User ask download of: ' + link.url);
83
+ this.platform.download({
84
+ uri: link.url,
85
+ filename: link.downloadFilename,
86
+ mimeType: link.mimeType
87
+ }).then(location => {
88
+ console.info('[install-upgrade] File downloaded at: ' + location);
89
+ // TODO: display a info toast ?
90
+ });
84
91
  });
85
92
  }
86
93
  tryOnline() {
@@ -121,15 +128,20 @@ export class AppInstallUpgradeCard {
121
128
  return undefined;
122
129
  }
123
130
  getCompatibleUpgradeLinks(installLinks, config) {
124
- const appMinVersion = config.getProperty(CORE_CONFIG_OPTIONS.APP_MIN_VERSION);
125
- const needUpgrade = appMinVersion && !VersionUtils.isCompatible(appMinVersion, this.environment.version);
131
+ const appVersion = this.environment.version;
132
+ const appMinVersionFromPod = config.getProperty(CORE_CONFIG_OPTIONS.APP_MIN_VERSION);
133
+ if (!appVersion) {
134
+ console.error('Missing value for \'environment.version\': cannot check app compatibility!');
135
+ return undefined;
136
+ }
137
+ const needUpgrade = appMinVersionFromPod && !VersionUtils.isCompatible(appMinVersionFromPod, appVersion);
126
138
  if (!needUpgrade)
127
139
  return undefined;
128
140
  const upgradeLinks = installLinks
129
141
  .filter(link => this.platform.is('mobileweb') || (link.platform && this.platform.is(link.platform)));
130
142
  // Use min version as default version
131
143
  upgradeLinks.forEach(link => {
132
- link.version = link.version || appMinVersion;
144
+ link.version = link.version || appMinVersionFromPod;
133
145
  });
134
146
  return isNotEmptyArray(upgradeLinks) ? upgradeLinks : undefined;
135
147
  }
@@ -198,7 +210,7 @@ export class AppInstallUpgradeCard {
198
210
  AppInstallUpgradeCard.decorators = [
199
211
  { type: Component, args: [{
200
212
  selector: 'app-install-upgrade-card',
201
- template: "\n\n<!-- Offline mode card-->\n<ion-card *ngIf=\"showOfflineWarning && (!loading && offline || waitingNetwork)\"\n color=\"accent\"\n class=\"main ion-no-margin\"\n @slideUpDownAnimation>\n <ion-card-content class=\"ion-no-padding\">\n <ion-grid>\n <ion-row>\n <ion-col>\n <ion-text class=\"ion-text-wrap\" *ngIf=\"!waitingNetwork; else waitingNetworkText\">\n <h4>\n <b *ngIf=\"isLogin; else notLogin\" [innerHTML]=\"'NETWORK.INFO.OFFLINE_OR_UNAUTHORIZED'| translate\"></b>\n <ng-template #notLogin>\n <b [innerHTML]=\"'NETWORK.INFO.OFFLINE'| translate\"></b>\n </ng-template>\n </h4>\n <h3>\n <small [innerHTML]=\"'NETWORK.INFO.OFFLINE_HELP'|translate\"></small>\n </h3>\n </ion-text>\n <ng-template #waitingNetworkText>\n <ion-text class=\"ion-text-wrap\" [innerHTML]=\"'NETWORK.INFO.RETRY_TO_CONNECT'| translate\"></ion-text>\n </ng-template>\n </ion-col>\n <ion-col size=\"auto\">\n\n <!-- Retry button -->\n <ion-button *ngIf=\"!waitingNetwork; else waitingSpinner\" color=\"tertiary\" class=\"ion-float-end\"\n (click)=\"tryOnline()\">\n <span translate>NETWORK.BTN_CHECK_ALIVE</span>\n </ion-button>\n\n <!-- Waiting spinner -->\n <ng-template #waitingSpinner>\n <ion-spinner *ngIf=\"waitingNetwork\" color=\"light\"></ion-spinner>\n </ng-template>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n </ion-card-content>\n</ion-card>\n\n<!-- Upgrade links -->\n<ion-card *ngIf=\"showUpgradeWarning && !loading && !offline && updateLinks\"\n color=\"accent\"\n class=\"ion-no-margin\"\n @slideUpDownAnimation>\n <ion-card-content class=\"ion-no-padding\">\n <ion-grid>\n <ion-row *ngFor=\"let link of updateLinks; last as last\">\n <ion-col>\n <ion-text class=\"ion-text-wrap\">\n <h3>\n <span *ngIf=\"link.version\" [innerHTML]=\"'INFO.UPDATE_APP_TO_VERSION'| translate: link\"></span>\n <span *ngIf=\"!link.version\" [innerHTML]=\"'INFO.UPDATE_APP'| translate: link\"></span>\n </h3>\n <h4>\n <small *ngIf=\"last\" [innerHTML]=\"'INFO.UPDATE_APP_HELP'|translate\"></small>\n </h4>\n </ion-text>\n </ion-col>\n\n <ion-col size=\"auto\">\n\n <!-- Download button -->\n <ion-button *ngIf=\"link.downloadFilename; else redirectButton\"\n [download]=\"link.downloadFilename\"\n [href]=\"link.url\"\n color=\"tertiary\" class=\"ion-float-end\" >\n <ion-label translate>COMMON.BTN_DOWNLOAD</ion-label>\n </ion-button>\n\n <!-- Redirect button -->\n <ng-template #redirectButton>\n <ion-button [href]=\"link.url\" rel=\"external\" color=\"tertiary\" class=\"ion-float-end\" target=\"_blank\">\n <ion-label translate>COMMON.BTN_SHOW_MORE</ion-label>\n </ion-button>\n </ng-template>\n\n </ion-col>\n </ion-row>\n\n </ion-grid>\n\n </ion-card-content>\n</ion-card>\n\n<!-- Install links -->\n<ion-card *ngIf=\"showInstallButton && !loading && !offline && installLinks\"\n color=\"secondary\"\n class=\"ion-no-margin\"\n @slideUpDownAnimation>\n <ion-card-content class=\"ion-no-padding\">\n <ion-grid>\n <ion-row *ngFor=\"let link of installLinks; last as last\">\n <ion-col>\n <ion-text class=\"ion-text-wrap\">\n <h3 [innerHTML]=\"'INFO.DOWNLOAD_APP_TITLE'| translate: {name: link.name, platform: getPlatformName(link.platform) }\"></h3>\n <h4><small *ngIf=\"last\" [innerHTML]=\"'INFO.DOWNLOAD_APP_HELP'|translate\"></small></h4>\n </ion-text>\n </ion-col>\n <ion-col size=\"auto\">\n <ng-container *ngTemplateOutlet=\"downloadButton; context: { $implicit: link }\"></ng-container>\n </ion-col>\n </ion-row>\n\n </ion-grid>\n\n </ion-card-content>\n</ion-card>\n\n<!-- Update offline feature card-->\n<ion-card *ngIf=\"showUpdateOfflineFeature && !loading && !offline\"\n color=\"accent\"\n class=\"main ion-no-margin\"\n @slideUpDownAnimation>\n <ion-card-content class=\"ion-no-padding\">\n <ion-grid>\n <ion-row>\n <ion-col>\n <ion-text class=\"ion-text-wrap\">\n <h4>\n <b [innerHTML]=\"'NETWORK.INFO.UPDATE_OFFLINE_MODE'| translate\"></b>\n </h4>\n <h3>\n <small [innerHTML]=\"'NETWORK.INFO.UPDATE_OFFLINE_MODE_HELP'|translate\"></small>\n </h3>\n </ion-text>\n </ion-col>\n <ion-col size=\"auto\">\n\n <!-- Retry button -->\n <ion-button color=\"tertiary\" class=\"ion-float-end\"\n (click)=\"onUpdateOfflineModeClick.emit($event)\">\n <span translate>NETWORK.BTN_UPDATE</span>\n </ion-button>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n </ion-card-content>\n</ion-card>\n\n<!-- Display a download button, depending on the link URL, and the device platform -->\n<ng-template #downloadButton let-link>\n\n <ng-container *ngIf=\"link.downloadFilename; else redirectButton\">\n\n <!-- Cordova download button -->\n <ion-button *ngIf=\"isAndroidCordova; else webDownloadButton\"\n (click)=\"downloadLink($event, asLink(link))\"\n color=\"tertiary\" class=\"ion-float-end\" >\n <ion-label translate>COMMON.BTN_DOWNLOAD</ion-label>\n </ion-button>\n\n <!-- Web download button -->\n <ng-template #webDownloadButton>\n <ion-button [download]=\"link.downloadFilename\"\n [href]=\"link.url\"\n color=\"tertiary\" class=\"ion-float-end\" >\n <ion-label translate>COMMON.BTN_DOWNLOAD</ion-label>\n </ion-button>\n </ng-template>\n </ng-container>\n\n <!-- Web redirect button -->\n <ng-template #redirectButton>\n <ion-button [href]=\"link.url\" rel=\"external\" color=\"tertiary\" class=\"ion-float-end\" target=\"_blank\">\n <ion-label translate>COMMON.BTN_SHOW_MORE</ion-label>\n </ion-button>\n </ng-template>\n</ng-template>\n",
213
+ template: "\n\n<!-- Offline mode card-->\n<ion-card *ngIf=\"showOfflineWarning && (!loading && offline || waitingNetwork)\"\n color=\"accent\"\n class=\"main ion-no-margin\"\n @slideUpDownAnimation>\n <ion-card-content class=\"ion-no-padding\">\n <ion-grid>\n <ion-row>\n <ion-col>\n <ion-text class=\"ion-text-wrap\" *ngIf=\"!waitingNetwork; else waitingNetworkText\">\n <h4>\n <b *ngIf=\"isLogin; else notLogin\" [innerHTML]=\"'NETWORK.INFO.OFFLINE_OR_UNAUTHORIZED'| translate\"></b>\n <ng-template #notLogin>\n <b [innerHTML]=\"'NETWORK.INFO.OFFLINE'| translate\"></b>\n </ng-template>\n </h4>\n <h3>\n <small [innerHTML]=\"'NETWORK.INFO.OFFLINE_HELP'|translate\"></small>\n </h3>\n </ion-text>\n <ng-template #waitingNetworkText>\n <ion-text class=\"ion-text-wrap\" [innerHTML]=\"'NETWORK.INFO.RETRY_TO_CONNECT'| translate\"></ion-text>\n </ng-template>\n </ion-col>\n <ion-col size=\"auto\">\n\n <!-- Retry button -->\n <ion-button *ngIf=\"!waitingNetwork; else waitingSpinner\" color=\"tertiary\" class=\"ion-float-end\"\n (click)=\"tryOnline()\">\n <span translate>NETWORK.BTN_CHECK_ALIVE</span>\n </ion-button>\n\n <!-- Waiting spinner -->\n <ng-template #waitingSpinner>\n <ion-spinner *ngIf=\"waitingNetwork\" color=\"light\"></ion-spinner>\n </ng-template>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n </ion-card-content>\n</ion-card>\n\n<!-- Upgrade links -->\n<ion-card *ngIf=\"showUpgradeWarning && !loading && !offline && updateLinks\"\n color=\"accent\"\n class=\"ion-no-margin\"\n @slideUpDownAnimation>\n <ion-card-content class=\"ion-no-padding\">\n <ion-grid>\n <ion-row *ngFor=\"let link of updateLinks; last as last\">\n <ion-col>\n <ion-text class=\"ion-text-wrap\">\n <h3>\n <span *ngIf=\"link.version\" [innerHTML]=\"'INFO.UPDATE_APP_TO_VERSION'| translate: link\"></span>\n <span *ngIf=\"!link.version\" [innerHTML]=\"'INFO.UPDATE_APP'| translate: link\"></span>\n </h3>\n <h4>\n <small *ngIf=\"last\" [innerHTML]=\"'INFO.UPDATE_APP_HELP'|translate\"></small>\n </h4>\n </ion-text>\n </ion-col>\n\n <ion-col size=\"auto\">\n <ng-container *ngTemplateOutlet=\"downloadButton; context: { $implicit: link }\"></ng-container>\n </ion-col>\n </ion-row>\n\n </ion-grid>\n\n </ion-card-content>\n</ion-card>\n\n<!-- Install links -->\n<ion-card *ngIf=\"showInstallButton && !loading && !offline && installLinks\"\n color=\"secondary\"\n class=\"ion-no-margin\"\n @slideUpDownAnimation>\n <ion-card-content class=\"ion-no-padding\">\n <ion-grid>\n <ion-row *ngFor=\"let link of installLinks; last as last\">\n <ion-col>\n <ion-text class=\"ion-text-wrap\">\n <h3 [innerHTML]=\"'INFO.DOWNLOAD_APP_TITLE'| translate: {name: link.name, platform: getPlatformName(link.platform) }\"></h3>\n <h4><small *ngIf=\"last\" [innerHTML]=\"'INFO.DOWNLOAD_APP_HELP'|translate\"></small></h4>\n </ion-text>\n </ion-col>\n <ion-col size=\"auto\">\n <ng-container *ngTemplateOutlet=\"downloadButton; context: { $implicit: link }\"></ng-container>\n </ion-col>\n </ion-row>\n\n </ion-grid>\n\n </ion-card-content>\n</ion-card>\n\n<!-- Update offline feature card-->\n<ion-card *ngIf=\"showUpdateOfflineFeature && !loading && !offline\"\n color=\"accent\"\n class=\"main ion-no-margin\"\n @slideUpDownAnimation>\n <ion-card-content class=\"ion-no-padding\">\n <ion-grid>\n <ion-row>\n <ion-col>\n <ion-text class=\"ion-text-wrap\">\n <h4>\n <b [innerHTML]=\"'NETWORK.INFO.UPDATE_OFFLINE_MODE'| translate\"></b>\n </h4>\n <h3>\n <small [innerHTML]=\"'NETWORK.INFO.UPDATE_OFFLINE_MODE_HELP'|translate\"></small>\n </h3>\n </ion-text>\n </ion-col>\n <ion-col size=\"auto\">\n\n <!-- Retry button -->\n <ion-button color=\"tertiary\" class=\"ion-float-end\"\n (click)=\"onUpdateOfflineModeClick.emit($event)\">\n <span translate>NETWORK.BTN_UPDATE</span>\n </ion-button>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n </ion-card-content>\n</ion-card>\n\n<!-- Display a download button, depending on the link URL, and the device platform -->\n<ng-template #downloadButton let-link>\n\n <ng-container *ngIf=\"link.downloadFilename; else redirectButton\">\n\n <!-- Download using platform -->\n <ion-button *ngIf=\"platform.canDownload; else webDownloadButton\"\n (click)=\"downloadUsingPlatform($event, asLink(link))\"\n color=\"tertiary\" class=\"ion-float-end\">\n <ion-icon slot=\"start\" name=\"download\"></ion-icon>\n <ion-label translate>COMMON.BTN_DOWNLOAD</ion-label>\n </ion-button>\n\n <!-- Web download button -->\n <ng-template #webDownloadButton>\n <ion-button [download]=\"link.downloadFilename\"\n [href]=\"link.url\"\n color=\"tertiary\" class=\"ion-float-end\" >\n <ion-label translate>COMMON.BTN_DOWNLOAD</ion-label>\n </ion-button>\n </ng-template>\n </ng-container>\n\n <!-- Web redirect button -->\n <ng-template #redirectButton>\n <ion-button [href]=\"link.url\" rel=\"external\" color=\"tertiary\" class=\"ion-float-end\" target=\"_blank\">\n <ion-label translate>COMMON.BTN_SHOW_MORE</ion-label>\n </ion-button>\n </ng-template>\n</ng-template>\n",
202
214
  changeDetection: ChangeDetectionStrategy.OnPush,
203
215
  animations: [slideUpDownAnimation],
204
216
  styles: ["ion-text small{font-size:85%}"]
@@ -207,8 +219,8 @@ AppInstallUpgradeCard.decorators = [
207
219
  AppInstallUpgradeCard.ctorParameters = () => [
208
220
  { type: ModalController },
209
221
  { type: ConfigService },
210
- { type: PlatformService },
211
222
  { type: ChangeDetectorRef },
223
+ { type: PlatformService },
212
224
  { type: NetworkService },
213
225
  { type: undefined, decorators: [{ type: Inject, args: [ENVIRONMENT,] }] }
214
226
  ];
@@ -220,4 +232,4 @@ AppInstallUpgradeCard.propDecorators = {
220
232
  showUpdateOfflineFeature: [{ type: Input }],
221
233
  onUpdateOfflineModeClick: [{ type: Output }]
222
234
  };
223
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5zdGFsbC11cGdyYWRlLWNhcmQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9jb3JlL2luc3RhbGwvaW5zdGFsbC11cGdyYWRlLWNhcmQuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUMsdUJBQXVCLEVBQUUsaUJBQWlCLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFxQixNQUFNLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFDNUksT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBQy9DLE9BQU8sRUFBQyxZQUFZLEVBQUMsTUFBTSxNQUFNLENBQUM7QUFFbEMsT0FBTyxFQUFDLGFBQWEsRUFBQyxNQUFNLDRCQUE0QixDQUFDO0FBQ3pELE9BQU8sRUFBQyxlQUFlLEVBQUMsTUFBTSw4QkFBOEIsQ0FBQztBQUM3RCxPQUFPLEVBQUMsb0JBQW9CLEVBQUUsR0FBRyxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7QUFDekQsT0FBTyxFQUFDLGNBQWMsRUFBQyxNQUFNLDZCQUE2QixDQUFDO0FBQzNELE9BQU8sRUFBQyxtQkFBbUIsRUFBQyxNQUFNLGdDQUFnQyxDQUFDO0FBQ25FLE9BQU8sRUFBQyxZQUFZLEVBQUMsTUFBTSwrQkFBK0IsQ0FBQztBQUMzRCxPQUFPLEVBQUMsb0JBQW9CLEVBQUMsTUFBTSwyQ0FBMkMsQ0FBQztBQUMvRSxPQUFPLEVBQUMsWUFBWSxFQUFFLGVBQWUsRUFBRSxlQUFlLEVBQUMsTUFBTSx3QkFBd0IsQ0FBQztBQUN0RixPQUFPLEVBQUMsV0FBVyxFQUFDLE1BQU0seUNBQXlDLENBQUM7QUFhcEUsTUFBTSxTQUFTLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUM5QixXQUFXLEVBQUUseUNBQXlDO0NBQ3ZELENBQUMsQ0FBQztBQVNILE1BQU0sT0FBTyxxQkFBcUI7SUE4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Q0FBQyxNQUFNO2dCQUMvQyxVQUFVLEVBQUUsQ0FBQyxvQkFBb0IsQ0FBQzs7YUFDbkM7OztZQWxDTyxlQUFlO1lBR2YsYUFBYTtZQUNiLGVBQWU7WUFMVSxpQkFBaUI7WUFPMUMsY0FBYzs0Q0FpRWpCLE1BQU0sU0FBQyxXQUFXOzs7c0JBdEJwQixLQUFLO2lDQUNMLEtBQUs7aUNBQ0wsS0FBSztnQ0FDTCxLQUFLO3VDQUVMLEtBQUs7dUNBc0JMLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0NoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDaGFuZ2VEZXRlY3RvclJlZiwgQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIEluamVjdCwgSW5wdXQsIE9uRGVzdHJveSwgT25Jbml0LCBPdXRwdXR9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtNb2RhbENvbnRyb2xsZXJ9IGZyb20gJ0Bpb25pYy9hbmd1bGFyJztcbmltcG9ydCB7U3Vic2NyaXB0aW9ufSBmcm9tICdyeGpzJztcbmltcG9ydCB7Q29uZmlndXJhdGlvbn0gZnJvbSAnLi4vc2VydmljZXMvbW9kZWwvY29uZmlnLm1vZGVsJztcbmltcG9ydCB7Q29uZmlnU2VydmljZX0gZnJvbSAnLi4vc2VydmljZXMvY29uZmlnLnNlcnZpY2UnO1xuaW1wb3J0IHtQbGF0Zm9ybVNlcnZpY2V9IGZyb20gJy4uL3NlcnZpY2VzL3BsYXRmb3JtLnNlcnZpY2UnO1xuaW1wb3J0IHtkaXN0aW5jdFVudGlsQ2hhbmdlZCwgbWFwfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQge05ldHdvcmtTZXJ2aWNlfSBmcm9tICcuLi9zZXJ2aWNlcy9uZXR3b3JrLnNlcnZpY2UnO1xuaW1wb3J0IHtDT1JFX0NPTkZJR19PUFRJT05TfSBmcm9tICcuLi9zZXJ2aWNlcy9jb25maWcvY29yZS5jb25maWcnO1xuaW1wb3J0IHtWZXJzaW9uVXRpbHN9IGZyb20gJy4uLy4uL3NoYXJlZC92ZXJzaW9uL3ZlcnNpb25zJztcbmltcG9ydCB7c2xpZGVVcERvd25BbmltYXRpb259IGZyb20gJy4uLy4uL3NoYXJlZC9tYXRlcmlhbC9tYXRlcmlhbC5hbmltYXRpb25zJztcbmltcG9ydCB7aXNOaWxPckJsYW5rLCBpc05vdEVtcHR5QXJyYXksIGlzTm90TmlsT3JCbGFua30gZnJvbSAnLi4vLi4vc2hhcmVkL2Z1bmN0aW9ucyc7XG5pbXBvcnQge0VOVklST05NRU5UfSBmcm9tICcuLi8uLi8uLi9lbnZpcm9ubWVudHMvZW52aXJvbm1lbnQuY2xhc3MnO1xuXG5cbmV4cG9ydCBkZWNsYXJlIGludGVyZmFjZSBJbnN0YWxsQXBwTGluayB7XG4gIG5hbWU6IHN0cmluZztcbiAgdXJsOiBzdHJpbmc7XG4gIHBsYXRmb3JtPzogJ2FuZHJvaWQnIHwgJ2lvcyc7XG4gIHZlcnNpb24/OiBzdHJpbmc7XG4gIGRvd25sb2FkRmlsZW5hbWU/OiBzdHJpbmc7XG4gIGRlc2NyaXB0aW9uPzogc3RyaW5nO1xuICBtaW1lVHlwZT86IHN0cmluZztcbn1cblxuY29uc3QgTWltZVR5cGVzID0gT2JqZWN0LmZyZWV6ZSh7XG4gIEFORFJPSURfQVBLOiAnYXBwbGljYXRpb24vdm5kLmFuZHJvaWQucGFja2FnZS1hcmNoaXZlJ1xufSk7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2FwcC1pbnN0YWxsLXVwZ3JhZGUtY2FyZCcsXG4gIHRlbXBsYXRlVXJsOiAnaW5zdGFsbC11cGdyYWRlLWNhcmQuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9pbnN0YWxsLXVwZ3JhZGUtY2FyZC5jb21wb25lbnQuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgYW5pbWF0aW9uczogW3NsaWRlVXBEb3duQW5pbWF0aW9uXVxufSlcbmV4cG9ydCBjbGFzcyBBcHBJbnN0YWxsVXBncmFkZUNhcmQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XG5cbiAgcHJpdmF0ZSBfc3Vic2NyaXB0aW9uID0gbmV3IFN1YnNjcmlwdGlvbigpO1xuICBwcml2YXRlIF9zaG93VXBkYXRlT2ZmbGluZUZlYXR1cmUgPSBmYWxzZTtcblxuICBsb2FkaW5nID0gdHJ1ZTtcbiAgd2FpdGluZ05ldHdvcmsgPSBmYWxzZTtcbiAgYWxsTGlua3M6IEluc3RhbGxBcHBMaW5rW107XG4gIGluc3RhbGxMaW5rczogSW5zdGFsbEFwcExpbmtbXTtcbiAgdXBkYXRlTGlua3M6IEluc3RhbGxBcHBMaW5rW107XG4gIG9mZmxpbmU6IGJvb2xlYW47XG4gIHVwZ3JhZGVWZXJzaW9uOiBzdHJpbmc7XG4gIGlzQW5kcm9pZENvcmRvdmE6IGJvb2xlYW47XG5cbiAgQElucHV0KCkgaXNMb2dpbjogYm9vbGVhbjtcbiAgQElucHV0KCkgc2hvd1VwZ3JhZGVXYXJuaW5nID0gdHJ1ZTtcbiAgQElucHV0KCkgc2hvd09mZmxpbmVXYXJuaW5nID0gdHJ1ZTtcbiAgQElucHV0KCkgc2hvd0luc3RhbGxCdXR0b24gPSBmYWxzZTtcblxuICBASW5wdXQoKVxuICBzZXQgc2hvd1VwZGF0ZU9mZmxpbmVGZWF0dXJlKHZhbHVlOiBib29sZWFuKSB7XG4gICAgaWYgKHZhbHVlID09PSB0aGlzLl9zaG93VXBkYXRlT2ZmbGluZUZlYXR1cmUpIHJldHVybjsgLy8gU2tpcFxuICAgIHRoaXMuX3Nob3dVcGRhdGVPZmZsaW5lRmVhdHVyZSA9IHZhbHVlO1xuICAgIHRoaXMubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBnZXQgc2hvd1VwZGF0ZU9mZmxpbmVGZWF0dXJlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9zaG93VXBkYXRlT2ZmbGluZUZlYXR1cmU7XG4gIH1cblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIG1vZGFsQ3RybDogTW9kYWxDb250cm9sbGVyLFxuICAgIHByaXZhdGUgY29uZmlnU2VydmljZTogQ29uZmlnU2VydmljZSxcbiAgICBwcml2YXRlIHBsYXRmb3JtOiBQbGF0Zm9ybVNlcnZpY2UsXG4gICAgcHJpdmF0ZSBjZDogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgcHVibGljIG5ldHdvcms6IE5ldHdvcmtTZXJ2aWNlLFxuICAgIEBJbmplY3QoRU5WSVJPTk1FTlQpIHByb3RlY3RlZCBlbnZpcm9ubWVudFxuICApIHtcbiAgICB0aGlzLmlzQW5kcm9pZENvcmRvdmEgPSBwbGF0Zm9ybS5pc0FuZHJvaWRDb3Jkb3ZhKCk7XG4gIH1cblxuICBAT3V0cHV0KClcbiAgb25VcGRhdGVPZmZsaW5lTW9kZUNsaWNrID0gbmV3IEV2ZW50RW1pdHRlcjxVSUV2ZW50PigpO1xuXG4gIGFzeW5jIG5nT25Jbml0KCkge1xuXG4gICAgYXdhaXQgdGhpcy5wbGF0Zm9ybS5yZWFkeSgpO1xuXG4gICAgdGhpcy5vZmZsaW5lID0gdGhpcy5uZXR3b3JrLm9mZmxpbmU7XG5cbiAgICAvLyBMaXN0ZW4gcG9kIGNvbmZpZ1xuICAgIHRoaXMuX3N1YnNjcmlwdGlvbi5hZGQoXG4gICAgICB0aGlzLmNvbmZpZ1NlcnZpY2UuY29uZmlnXG4gICAgICAgIC5zdWJzY3JpYmUoY29uZmlnID0+IHtcbiAgICAgICAgICBjb25zb2xlLmluZm8oJ1tpbnN0YWxsXSBDaGVja2luZyBpZiB1cGdyYWRlICBvciBpbnN0YWxsIGlzIG5lZWQuLi4nKTtcblxuICAgICAgICAgIGNvbnN0IGluc3RhbGxMaW5rcyA9IHRoaXMuZ2V0QWxsSW5zdGFsbExpbmtzKGNvbmZpZyk7XG5cbiAgICAgICAgICAvLyBDaGVjayBmb3IgdXBncmFkZVxuICAgICAgICAgIHRoaXMudXBkYXRlTGlua3MgPSB0aGlzLmdldENvbXBhdGlibGVVcGdyYWRlTGlua3MoaW5zdGFsbExpbmtzLCBjb25maWcpO1xuXG4gICAgICAgICAgLy8gQ2hlY2sgZm9yIGluc3RhbGwgbGlua3MgKGlmIG5vIHVwZ3JhZGUgbmVlZClcbiAgICAgICAgICB0aGlzLmluc3RhbGxMaW5rcyA9ICF0aGlzLnVwZGF0ZUxpbmtzICYmIHRoaXMuZ2V0Q29tcGF0aWJsZUluc3RhbGxMaW5rcyhpbnN0YWxsTGlua3MpO1xuXG4gICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmxvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMubWFya0ZvckNoZWNrKCk7XG4gICAgICAgICAgfSwgMjAwMCk7IC8vIEFkZCBhIGRlbGF5LCBmb3IgYW5pbWF0aW9uXG4gICAgICAgIH0pKTtcblxuICAgIC8vIExpc3RlbiBuZXR3b3JrIGNoYW5nZXNcbiAgICB0aGlzLl9zdWJzY3JpcHRpb24uYWRkKFxuICAgICAgdGhpcy5uZXR3b3JrLm9uTmV0d29ya1N0YXR1c0NoYW5nZXNcbiAgICAgICAgLnBpcGUoXG4gICAgICAgICAgLy9kZWJvdW5jZVRpbWUoNDUwKSxcbiAgICAgICAgICAvL3RhcCgoKSA9PiB0aGlzLndhaXRpbmdOZXR3b3JrID0gZmFsc2UpLFxuICAgICAgICAgIG1hcChjb25uZWN0aW9uVHlwZSA9PiBjb25uZWN0aW9uVHlwZSA9PT0gJ25vbmUnKSxcbiAgICAgICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpXG4gICAgICAgIClcbiAgICAgICAgLnN1YnNjcmliZShvZmZsaW5lID0+IHtcbiAgICAgICAgICB0aGlzLm9mZmxpbmUgPSBvZmZsaW5lO1xuICAgICAgICAgIHRoaXMubWFya0ZvckNoZWNrKCk7XG4gICAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMuX3N1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICB9XG5cbiAgZG93bmxvYWRMaW5rKGV2ZW50OiBVSUV2ZW50LCBsaW5rOiBJbnN0YWxsQXBwTGluaykge1xuICAgIGlmICghbGluayB8fCAhbGluay51cmwpIHJldHVybjsgLy8gU2tpcFxuXG4gICAgdGhpcy5wbGF0Zm9ybS5kb3dubG9hZCh7XG4gICAgICB1cmk6IGxpbmsudXJsLFxuICAgICAgZmlsZW5hbWU6IGxpbmsuZG93bmxvYWRGaWxlbmFtZSxcbiAgICAgIG1pbWVUeXBlOiBsaW5rLm1pbWVUeXBlXG4gICAgfSk7XG4gIH1cblxuICB0cnlPbmxpbmUoKSB7XG4gICAgdGhpcy53YWl0aW5nTmV0d29yayA9IHRydWU7XG4gICAgdGhpcy5tYXJrRm9yQ2hlY2soKTtcblxuICAgIHRoaXMubmV0d29yay50cnlPbmxpbmUoe1xuICAgICAgc2hvd0xvYWRpbmdUb2FzdDogZmFsc2UsXG4gICAgICBzaG93T25saW5lVG9hc3Q6IHRydWUsXG4gICAgICBzaG93T2ZmbGluZVRvYXN0OiBmYWxzZVxuICAgIH0pXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIHRoaXMud2FpdGluZ05ldHdvcmsgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5tYXJrRm9yQ2hlY2soKTtcbiAgICAgIH0pO1xuXG4gIH1cblxuICBnZXRQbGF0Zm9ybU5hbWUocGxhdGZvcm06ICdhbmRyb2lkJ3wnaW9zJykge1xuICAgIHN3aXRjaCAocGxhdGZvcm0pIHtcbiAgICAgIGNhc2UgJ2FuZHJvaWQnOlxuICAgICAgICByZXR1cm4gJ0FuZHJvaWQnO1xuICAgICAgY2FzZSAnaW9zJzpcbiAgICAgICAgcmV0dXJuICdpT1MnO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuICcnO1xuICAgIH1cbiAgfVxuXG4gIGFzTGluayh2YWx1ZTogYW55KTogSW5zdGFsbEFwcExpbmsge1xuICAgIHJldHVybiB2YWx1ZSBhcyBJbnN0YWxsQXBwTGluaztcbiAgfVxuXG4gIC8qIC0tIHByaXZhdGUgbWV0aG9kICAtLSAqL1xuXG4gIHByaXZhdGUgZ2V0Q29tcGF0aWJsZUluc3RhbGxMaW5rcyhpbnN0YWxsTGlua3M6IEluc3RhbGxBcHBMaW5rW10pOiBJbnN0YWxsQXBwTGlua1tdIHtcblxuICAgIC8vIENvcmRvdmEgYWxyZWFkeSBydW5uaW5nOiBub3QgbmVlZCB0byBpbnN0YWxsXG4gICAgaWYgKHRoaXMucGxhdGZvcm0uaXMoJ2NvcmRvdmEnKSkgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAgIC8vIElmIG1vYmlsZSB3ZWI6IHJldHVybiBhbGxcbiAgICBpZiAodGhpcy5wbGF0Zm9ybS5pcygnbW9iaWxld2ViJykpIHtcbiAgICAgIHJldHVybiBpbnN0YWxsTGlua3M7XG4gICAgfVxuXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0Q29tcGF0aWJsZVVwZ3JhZGVMaW5rcyhpbnN0YWxsTGlua3M6IEluc3RhbGxBcHBMaW5rW10sIGNvbmZpZzogQ29uZmlndXJhdGlvbik6IEluc3RhbGxBcHBMaW5rW10ge1xuICAgIGNvbnN0IGFwcE1pblZlcnNpb24gPSBjb25maWcuZ2V0UHJvcGVydHkoQ09SRV9DT05GSUdfT1BUSU9OUy5BUFBfTUlOX1ZFUlNJT04pO1xuXG4gICAgY29uc3QgbmVlZFVwZ3JhZGUgPSBhcHBNaW5WZXJzaW9uICYmICFWZXJzaW9uVXRpbHMuaXNDb21wYXRpYmxlKGFwcE1pblZlcnNpb24sIHRoaXMuZW52aXJvbm1lbnQudmVyc2lvbik7XG4gICAgaWYgKCFuZWVkVXBncmFkZSkgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAgIGNvbnN0IHVwZ3JhZGVMaW5rcyA9IGluc3RhbGxMaW5rc1xuICAgICAgLmZpbHRlcihsaW5rID0+IHRoaXMucGxhdGZvcm0uaXMoJ21vYmlsZXdlYicpIHx8IChsaW5rLnBsYXRmb3JtICYmIMKgdGhpcy5wbGF0Zm9ybS5pcyhsaW5rLnBsYXRmb3JtKSkpO1xuXG4gICAgLy8gVXNlIG1pbiB2ZXJzaW9uIGFzIGRlZmF1bHQgdmVyc2lvblxuICAgIHVwZ3JhZGVMaW5rcy5mb3JFYWNoKGxpbmsgPT4ge1xuICAgICAgbGluay52ZXJzaW9uID0gbGluay52ZXJzaW9uIHx8IGFwcE1pblZlcnNpb247XG4gICAgfSk7XG5cbiAgICByZXR1cm4gaXNOb3RFbXB0eUFycmF5KHVwZ3JhZGVMaW5rcykgPyB1cGdyYWRlTGlua3MgOiB1bmRlZmluZWQ7XG4gIH1cblxuICBwcml2YXRlIGdldEFsbEluc3RhbGxMaW5rcyhjb25maWc6IENvbmZpZ3VyYXRpb24pOiBJbnN0YWxsQXBwTGlua1tdIHtcbiAgICBjb25zdCByZXN1bHQ6IEluc3RhbGxBcHBMaW5rW10gPSBbXTtcblxuICAgIC8vIEFuZHJvaWRcbiAgICB7XG4gICAgICAvLyBHZXQgVVJMIChmcm9tIGNvbmZpZywgb3IgZW52aXJvbm1lbnQpXG4gICAgICBsZXQgdXJsID0gY29uZmlnLmdldFByb3BlcnR5KENPUkVfQ09ORklHX09QVElPTlMuQU5EUk9JRF9JTlNUQUxMX1VSTCk7XG4gICAgICBpZiAoaXNOaWxPckJsYW5rKHVybCkpIHVybCA9IHRoaXMuZW52aXJvbm1lbnQuZGVmYXVsdEFuZHJvaWRJbnN0YWxsVXJsIHx8IG51bGw7XG4gICAgICBjb25zdCBtaW5WZXJzaW9uID0gY29uZmlnLmdldFByb3BlcnR5KENPUkVfQ09ORklHX09QVElPTlMuQVBQX01JTl9WRVJTSU9OKTtcblxuICAgICAgLy8gQ29tcHV0ZSBBcHAgbmFtZVxuICAgICAgY29uc3QgbmFtZTogc3RyaW5nID0gaXNOb3ROaWxPckJsYW5rKHVybCkgJiYgY29uZmlnLmxhYmVsIHx8IHRoaXMuZW52aXJvbm1lbnQuZGVmYXVsdEFwcE5hbWUgfHwgJ1NVTUFSaVMnO1xuXG4gICAgICBpZiAodXJsKSB7XG4gICAgICAgIGxldCBkb3dubG9hZEZpbGVuYW1lOiBzdHJpbmc7XG4gICAgICAgIGxldCB2ZXJzaW9uO1xuICAgICAgICBsZXQgbWltZVR5cGU7XG5cbiAgICAgICAgLy8gR2V0IGZpbGUgbmFtZVxuICAgICAgICBjb25zdCBmaWxlbmFtZSA9IHRoaXMuZ2V0RmlsZW5hbWUodXJsKTtcbiAgICAgICAgdmVyc2lvbiA9IG1pblZlcnNpb24gfHwgJ2xhdGVzdCc7XG5cbiAgICAgICAgLy8gT0ssIHRoaXMgaXMgYSBkb3dubG9hZGFibGUgQVBLIGZpbGUgKGUuZy4gTk9UIGEgbGluayB0byBhIHBsYXlzdG9yZSlcbiAgICAgICAgaWYgKGZpbGVuYW1lPy5lbmRzV2l0aCgnLmFwaycpKSB7XG4gICAgICAgICAgLy8gRGVmaW5lIG1pbWUgdHlwZVxuICAgICAgICAgIG1pbWVUeXBlID0gTWltZVR5cGVzLkFORFJPSURfQVBLO1xuXG4gICAgICAgICAgLy8gR2V0IHRoZSBmaWxlIHZlcnNpb24gKGlmIGFueSlcbiAgICAgICAgICBjb25zdCB2ZXJzaW9uTWF0Y2hlcyA9IC8tdihbMS05XVswLTldKlxcLlswLTldK1xcLig6Pyg6P2FscGhhfGJldGF8cmMpP1swLTldKikpL2kuZXhlYyhmaWxlbmFtZSk7XG4gICAgICAgICAgdmVyc2lvbiA9IHZlcnNpb25NYXRjaGVzICYmIHZlcnNpb25NYXRjaGVzWzFdIHx8IHZlcnNpb247XG5cbiAgICAgICAgICAvLyBDb21wdXRlIGEgbmV3IGZpbGUgbmFtZSwgd2l0aCB0aGUgdmVyc2lvblxuICAgICAgICAgIGlmIChpc05vdE5pbE9yQmxhbmsobmFtZSkpIHtcbiAgICAgICAgICAgIGRvd25sb2FkRmlsZW5hbWUgPSBgJHtuYW1lfS12JHt2ZXJzaW9ufS5hcGtgLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBkb3dubG9hZEZpbGVuYW1lID0gZmlsZW5hbWU7XG5cbiAgICAgICAgICAgIC8vIFJlcGxhY2UgJ2xhdGVzdCcgd2l0aCB0aGUgYXBwIHZlcnNpb24sIGlmIHByZXNlbnRcbiAgICAgICAgICAgIGlmIChkb3dubG9hZEZpbGVuYW1lLmluZGV4T2YoJ2xhdGVzdCcpKSB7XG4gICAgICAgICAgICAgIGRvd25sb2FkRmlsZW5hbWUgPSBkb3dubG9hZEZpbGVuYW1lLnJlcGxhY2UoJ2xhdGVzdCcsIHZlcnNpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJlc3VsdC5wdXNoKHsgbmFtZSwgdXJsLCBwbGF0Zm9ybTogJ2FuZHJvaWQnLCB2ZXJzaW9uLCBkb3dubG9hZEZpbGVuYW1lLCBtaW1lVHlwZSB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBpT1MgLSBUT0RPXG4gICAgLy97XG4gICAgLy8gICguLi4pXG4gICAgLy99XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRGaWxlbmFtZSh1cmw6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgaWYgKCF1cmwpIHJldHVybjtcbiAgICAvLyBHZXQgbGFzdCBwYXJ0IChvciBhbGwgc3RyaW5nLCBpZiBubyAnLycpXG4gICAgbGV0IGZpbGVuYW1lID0gdXJsLnN1YnN0cmluZyh1cmwubGFzdEluZGV4T2YoJy8nKSsxKTtcblxuICAgIGNvbnN0IHF1ZXJ5UGFyYW1JbmRleCA9IGZpbGVuYW1lLmluZGV4T2YoJz8nKTtcbiAgICBpZiAocXVlcnlQYXJhbUluZGV4ICE9PSAtMSkge1xuICAgICAgLy8gUmVtb3ZlIHF1ZXJ5IHBhcmFtc1xuICAgICAgcmV0dXJuIGZpbGVuYW1lLnN1YnN0cmluZygwLCBxdWVyeVBhcmFtSW5kZXgpO1xuICAgIH1cblxuICAgIHJldHVybiBmaWxlbmFtZTtcbiAgfVxuXG4gIHByaXZhdGUgbWFya0ZvckNoZWNrKCkge1xuICAgIHRoaXMuY2QubWFya0ZvckNoZWNrKCk7XG4gIH1cbn1cbiJdfQ==
235
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5zdGFsbC11cGdyYWRlLWNhcmQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9jb3JlL2luc3RhbGwvaW5zdGFsbC11cGdyYWRlLWNhcmQuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUMsdUJBQXVCLEVBQUUsaUJBQWlCLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFxQixNQUFNLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFDNUksT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBQy9DLE9BQU8sRUFBQyxZQUFZLEVBQUMsTUFBTSxNQUFNLENBQUM7QUFFbEMsT0FBTyxFQUFDLGFBQWEsRUFBQyxNQUFNLDRCQUE0QixDQUFDO0FBQ3pELE9BQU8sRUFBQyxlQUFlLEVBQUMsTUFBTSw4QkFBOEIsQ0FBQztBQUM3RCxPQUFPLEVBQUMsb0JBQW9CLEVBQUUsR0FBRyxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7QUFDekQsT0FBTyxFQUFDLGNBQWMsRUFBQyxNQUFNLDZCQUE2QixDQUFDO0FBQzNELE9BQU8sRUFBQyxtQkFBbUIsRUFBQyxNQUFNLGdDQUFnQyxDQUFDO0FBQ25FLE9BQU8sRUFBQyxZQUFZLEVBQUMsTUFBTSwrQkFBK0IsQ0FBQztBQUMzRCxPQUFPLEVBQUMsb0JBQW9CLEVBQUMsTUFBTSwyQ0FBMkMsQ0FBQztBQUMvRSxPQUFPLEVBQUMsWUFBWSxFQUFFLGVBQWUsRUFBRSxlQUFlLEVBQUMsTUFBTSx3QkFBd0IsQ0FBQztBQUN0RixPQUFPLEVBQUMsV0FBVyxFQUFDLE1BQU0seUNBQXlDLENBQUM7QUFhcEUsTUFBTSxTQUFTLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUM5QixXQUFXLEVBQUUseUNBQXlDO0NBQ3ZELENBQUMsQ0FBQztBQVNILE1BQU0sT0FBTyxxQkFBcUI7SUE4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LENBQUMsQ0FBQyxDQUFDO1FBRXJELE1BQU0sZUFBZSxHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDOUMsSUFBSSxlQUFlLEtBQUssQ0FBQyxDQUFDLEVBQUU7WUFDMUIsc0JBQXNCO1lBQ3RCLE9BQU8sUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsZUFBZSxDQUFDLENBQUM7U0FDL0M7UUFFRCxPQUFPLFFBQVEsQ0FBQztJQUNsQixDQUFDO0lBRU8sWUFBWTtRQUNsQixJQUFJLENBQUMsRUFBRSxDQUFDLFlBQVksRUFBRSxDQUFDO0lBQ3pCLENBQUM7OztZQWpRRixTQUFTLFNBQUM7Z0JBQ1QsUUFBUSxFQUFFLDBCQUEwQjtnQkFDcEMsNnlMQUFrRDtnQkFFbEQsZUFBZSxFQUFFLHVCQUF1QixDQUFDLE1BQU07Z0JBQy9DLFVBQVUsRUFBRSxDQUFDLG9CQUFvQixDQUFDOzthQUNuQzs7O1lBbENPLGVBQWU7WUFHZixhQUFhO1lBSlksaUJBQWlCO1lBSzFDLGVBQWU7WUFFZixjQUFjOzRDQWlFakIsTUFBTSxTQUFDLFdBQVc7OztzQkF0QnBCLEtBQUs7aUNBQ0wsS0FBSztpQ0FDTCxLQUFLO2dDQUNMLEtBQUs7dUNBRUwsS0FBSzt1Q0FxQkwsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7Q2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENoYW5nZURldGVjdG9yUmVmLCBDb21wb25lbnQsIEV2ZW50RW1pdHRlciwgSW5qZWN0LCBJbnB1dCwgT25EZXN0cm95LCBPbkluaXQsIE91dHB1dH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge01vZGFsQ29udHJvbGxlcn0gZnJvbSAnQGlvbmljL2FuZ3VsYXInO1xuaW1wb3J0IHtTdWJzY3JpcHRpb259IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtDb25maWd1cmF0aW9ufSBmcm9tICcuLi9zZXJ2aWNlcy9tb2RlbC9jb25maWcubW9kZWwnO1xuaW1wb3J0IHtDb25maWdTZXJ2aWNlfSBmcm9tICcuLi9zZXJ2aWNlcy9jb25maWcuc2VydmljZSc7XG5pbXBvcnQge1BsYXRmb3JtU2VydmljZX0gZnJvbSAnLi4vc2VydmljZXMvcGxhdGZvcm0uc2VydmljZSc7XG5pbXBvcnQge2Rpc3RpbmN0VW50aWxDaGFuZ2VkLCBtYXB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7TmV0d29ya1NlcnZpY2V9IGZyb20gJy4uL3NlcnZpY2VzL25ldHdvcmsuc2VydmljZSc7XG5pbXBvcnQge0NPUkVfQ09ORklHX09QVElPTlN9IGZyb20gJy4uL3NlcnZpY2VzL2NvbmZpZy9jb3JlLmNvbmZpZyc7XG5pbXBvcnQge1ZlcnNpb25VdGlsc30gZnJvbSAnLi4vLi4vc2hhcmVkL3ZlcnNpb24vdmVyc2lvbnMnO1xuaW1wb3J0IHtzbGlkZVVwRG93bkFuaW1hdGlvbn0gZnJvbSAnLi4vLi4vc2hhcmVkL21hdGVyaWFsL21hdGVyaWFsLmFuaW1hdGlvbnMnO1xuaW1wb3J0IHtpc05pbE9yQmxhbmssIGlzTm90RW1wdHlBcnJheSwgaXNOb3ROaWxPckJsYW5rfSBmcm9tICcuLi8uLi9zaGFyZWQvZnVuY3Rpb25zJztcbmltcG9ydCB7RU5WSVJPTk1FTlR9IGZyb20gJy4uLy4uLy4uL2Vudmlyb25tZW50cy9lbnZpcm9ubWVudC5jbGFzcyc7XG5cblxuZXhwb3J0IGRlY2xhcmUgaW50ZXJmYWNlIEluc3RhbGxBcHBMaW5rIHtcbiAgbmFtZTogc3RyaW5nO1xuICB1cmw6IHN0cmluZztcbiAgcGxhdGZvcm0/OiAnYW5kcm9pZCcgfCAnaW9zJztcbiAgdmVyc2lvbj86IHN0cmluZztcbiAgZG93bmxvYWRGaWxlbmFtZT86IHN0cmluZztcbiAgZGVzY3JpcHRpb24/OiBzdHJpbmc7XG4gIG1pbWVUeXBlPzogc3RyaW5nO1xufVxuXG5jb25zdCBNaW1lVHlwZXMgPSBPYmplY3QuZnJlZXplKHtcbiAgQU5EUk9JRF9BUEs6ICdhcHBsaWNhdGlvbi92bmQuYW5kcm9pZC5wYWNrYWdlLWFyY2hpdmUnXG59KTtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYXBwLWluc3RhbGwtdXBncmFkZS1jYXJkJyxcbiAgdGVtcGxhdGVVcmw6ICdpbnN0YWxsLXVwZ3JhZGUtY2FyZC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2luc3RhbGwtdXBncmFkZS1jYXJkLmNvbXBvbmVudC5zY3NzJ10sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBhbmltYXRpb25zOiBbc2xpZGVVcERvd25BbmltYXRpb25dXG59KVxuZXhwb3J0IGNsYXNzIEFwcEluc3RhbGxVcGdyYWRlQ2FyZCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcblxuICBwcml2YXRlIF9zdWJzY3JpcHRpb24gPSBuZXcgU3Vic2NyaXB0aW9uKCk7XG4gIHByaXZhdGUgX3Nob3dVcGRhdGVPZmZsaW5lRmVhdHVyZSA9IGZhbHNlO1xuXG4gIGxvYWRpbmcgPSB0cnVlO1xuICB3YWl0aW5nTmV0d29yayA9IGZhbHNlO1xuICBhbGxMaW5rczogSW5zdGFsbEFwcExpbmtbXTtcbiAgaW5zdGFsbExpbmtzOiBJbnN0YWxsQXBwTGlua1tdO1xuICB1cGRhdGVMaW5rczogSW5zdGFsbEFwcExpbmtbXTtcbiAgb2ZmbGluZTogYm9vbGVhbjtcbiAgdXBncmFkZVZlcnNpb246IHN0cmluZztcbiAgY2FuRG93bmxvYWQ6IGJvb2xlYW47XG5cbiAgQElucHV0KCkgaXNMb2dpbjogYm9vbGVhbjtcbiAgQElucHV0KCkgc2hvd1VwZ3JhZGVXYXJuaW5nID0gdHJ1ZTtcbiAgQElucHV0KCkgc2hvd09mZmxpbmVXYXJuaW5nID0gdHJ1ZTtcbiAgQElucHV0KCkgc2hvd0luc3RhbGxCdXR0b24gPSBmYWxzZTtcblxuICBASW5wdXQoKVxuICBzZXQgc2hvd1VwZGF0ZU9mZmxpbmVGZWF0dXJlKHZhbHVlOiBib29sZWFuKSB7XG4gICAgaWYgKHZhbHVlID09PSB0aGlzLl9zaG93VXBkYXRlT2ZmbGluZUZlYXR1cmUpIHJldHVybjsgLy8gU2tpcFxuICAgIHRoaXMuX3Nob3dVcGRhdGVPZmZsaW5lRmVhdHVyZSA9IHZhbHVlO1xuICAgIHRoaXMubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBnZXQgc2hvd1VwZGF0ZU9mZmxpbmVGZWF0dXJlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9zaG93VXBkYXRlT2ZmbGluZUZlYXR1cmU7XG4gIH1cblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIG1vZGFsQ3RybDogTW9kYWxDb250cm9sbGVyLFxuICAgIHByaXZhdGUgY29uZmlnU2VydmljZTogQ29uZmlnU2VydmljZSxcbiAgICBwcml2YXRlIGNkOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBwdWJsaWMgcGxhdGZvcm06IFBsYXRmb3JtU2VydmljZSxcbiAgICBwdWJsaWMgbmV0d29yazogTmV0d29ya1NlcnZpY2UsXG4gICAgQEluamVjdChFTlZJUk9OTUVOVCkgcHJvdGVjdGVkIGVudmlyb25tZW50XG4gICkge1xuICB9XG5cbiAgQE91dHB1dCgpXG4gIG9uVXBkYXRlT2ZmbGluZU1vZGVDbGljayA9IG5ldyBFdmVudEVtaXR0ZXI8VUlFdmVudD4oKTtcblxuICBhc3luYyBuZ09uSW5pdCgpIHtcblxuICAgIGF3YWl0IHRoaXMucGxhdGZvcm0ucmVhZHkoKTtcblxuICAgIHRoaXMub2ZmbGluZSA9IHRoaXMubmV0d29yay5vZmZsaW5lO1xuXG4gICAgLy8gTGlzdGVuIHBvZCBjb25maWdcbiAgICB0aGlzLl9zdWJzY3JpcHRpb24uYWRkKFxuICAgICAgdGhpcy5jb25maWdTZXJ2aWNlLmNvbmZpZ1xuICAgICAgICAuc3Vic2NyaWJlKGNvbmZpZyA9PiB7XG4gICAgICAgICAgY29uc29sZS5pbmZvKCdbaW5zdGFsbF0gQ2hlY2tpbmcgaWYgdXBncmFkZSAgb3IgaW5zdGFsbCBpcyBuZWVkLi4uJyk7XG5cbiAgICAgICAgICBjb25zdCBpbnN0YWxsTGlua3MgPSB0aGlzLmdldEFsbEluc3RhbGxMaW5rcyhjb25maWcpO1xuXG4gICAgICAgICAgLy8gQ2hlY2sgZm9yIHVwZ3JhZGVcbiAgICAgICAgICB0aGlzLnVwZGF0ZUxpbmtzID0gdGhpcy5nZXRDb21wYXRpYmxlVXBncmFkZUxpbmtzKGluc3RhbGxMaW5rcywgY29uZmlnKTtcblxuICAgICAgICAgIC8vIENoZWNrIGZvciBpbnN0YWxsIGxpbmtzIChpZiBubyB1cGdyYWRlIG5lZWQpXG4gICAgICAgICAgdGhpcy5pbnN0YWxsTGlua3MgPSAhdGhpcy51cGRhdGVMaW5rcyAmJiB0aGlzLmdldENvbXBhdGlibGVJbnN0YWxsTGlua3MoaW5zdGFsbExpbmtzKTtcblxuICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5sb2FkaW5nID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICAgICAgICAgIH0sIDIwMDApOyAvLyBBZGQgYSBkZWxheSwgZm9yIGFuaW1hdGlvblxuICAgICAgICB9KSk7XG5cbiAgICAvLyBMaXN0ZW4gbmV0d29yayBjaGFuZ2VzXG4gICAgdGhpcy5fc3Vic2NyaXB0aW9uLmFkZChcbiAgICAgIHRoaXMubmV0d29yay5vbk5ldHdvcmtTdGF0dXNDaGFuZ2VzXG4gICAgICAgIC5waXBlKFxuICAgICAgICAgIC8vZGVib3VuY2VUaW1lKDQ1MCksXG4gICAgICAgICAgLy90YXAoKCkgPT4gdGhpcy53YWl0aW5nTmV0d29yayA9IGZhbHNlKSxcbiAgICAgICAgICBtYXAoY29ubmVjdGlvblR5cGUgPT4gY29ubmVjdGlvblR5cGUgPT09ICdub25lJyksXG4gICAgICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKVxuICAgICAgICApXG4gICAgICAgIC5zdWJzY3JpYmUob2ZmbGluZSA9PiB7XG4gICAgICAgICAgdGhpcy5vZmZsaW5lID0gb2ZmbGluZTtcbiAgICAgICAgICB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICAgICAgICB9KVxuICAgICk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICB0aGlzLl9zdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgfVxuXG4gIGFzeW5jIGRvd25sb2FkVXNpbmdQbGF0Zm9ybShldmVudDogVUlFdmVudCwgbGluazogSW5zdGFsbEFwcExpbmspIHtcbiAgICBpZiAoIWxpbmsgfHwgIWxpbmsudXJsKXtcbiAgICAgIGNvbnNvbGUuaW5mbygnW2luc3RhbGwtdXBncmFkZV0gSW52YWxpZCBsaW5rOiAnICsgSlNPTi5zdHJpbmdpZnkobGluaykpO1xuICAgICAgcmV0dXJuOyAvLyBTa2lwXG4gICAgfVxuXG4gICAgY29uc29sZS5pbmZvKCdbaW5zdGFsbC11cGdyYWRlXSBVc2VyIGFzayBkb3dubG9hZCBvZjogJyArIGxpbmsudXJsKTtcblxuICAgIHRoaXMucGxhdGZvcm0uZG93bmxvYWQoe1xuICAgICAgdXJpOiBsaW5rLnVybCxcbiAgICAgIGZpbGVuYW1lOiBsaW5rLmRvd25sb2FkRmlsZW5hbWUsXG4gICAgICBtaW1lVHlwZTogbGluay5taW1lVHlwZVxuICAgIH0pLnRoZW4obG9jYXRpb24gPT4ge1xuICAgICAgY29uc29sZS5pbmZvKCdbaW5zdGFsbC11cGdyYWRlXSBGaWxlIGRvd25sb2FkZWQgYXQ6ICcgKyBsb2NhdGlvbik7XG4gICAgICAvLyBUT0RPOiBkaXNwbGF5IGEgaW5mbyB0b2FzdCA/XG4gICAgfSk7XG4gIH1cblxuICB0cnlPbmxpbmUoKSB7XG4gICAgdGhpcy53YWl0aW5nTmV0d29yayA9IHRydWU7XG4gICAgdGhpcy5tYXJrRm9yQ2hlY2soKTtcblxuICAgIHRoaXMubmV0d29yay50cnlPbmxpbmUoe1xuICAgICAgc2hvd0xvYWRpbmdUb2FzdDogZmFsc2UsXG4gICAgICBzaG93T25saW5lVG9hc3Q6IHRydWUsXG4gICAgICBzaG93T2ZmbGluZVRvYXN0OiBmYWxzZVxuICAgIH0pXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIHRoaXMud2FpdGluZ05ldHdvcmsgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5tYXJrRm9yQ2hlY2soKTtcbiAgICAgIH0pO1xuXG4gIH1cblxuICBnZXRQbGF0Zm9ybU5hbWUocGxhdGZvcm06ICdhbmRyb2lkJ3wnaW9zJykge1xuICAgIHN3aXRjaCAocGxhdGZvcm0pIHtcbiAgICAgIGNhc2UgJ2FuZHJvaWQnOlxuICAgICAgICByZXR1cm4gJ0FuZHJvaWQnO1xuICAgICAgY2FzZSAnaW9zJzpcbiAgICAgICAgcmV0dXJuICdpT1MnO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuICcnO1xuICAgIH1cbiAgfVxuXG4gIGFzTGluayh2YWx1ZTogYW55KTogSW5zdGFsbEFwcExpbmsge1xuICAgIHJldHVybiB2YWx1ZSBhcyBJbnN0YWxsQXBwTGluaztcbiAgfVxuXG4gIC8qIC0tIHByaXZhdGUgbWV0aG9kICAtLSAqL1xuXG4gIHByaXZhdGUgZ2V0Q29tcGF0aWJsZUluc3RhbGxMaW5rcyhpbnN0YWxsTGlua3M6IEluc3RhbGxBcHBMaW5rW10pOiBJbnN0YWxsQXBwTGlua1tdIHtcblxuICAgIC8vIENvcmRvdmEgYWxyZWFkeSBydW5uaW5nOiBub3QgbmVlZCB0byBpbnN0YWxsXG4gICAgaWYgKHRoaXMucGxhdGZvcm0uaXMoJ2NvcmRvdmEnKSkgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAgIC8vIElmIG1vYmlsZSB3ZWI6IHJldHVybiBhbGxcbiAgICBpZiAodGhpcy5wbGF0Zm9ybS5pcygnbW9iaWxld2ViJykpIHtcbiAgICAgIHJldHVybiBpbnN0YWxsTGlua3M7XG4gICAgfVxuXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0Q29tcGF0aWJsZVVwZ3JhZGVMaW5rcyhpbnN0YWxsTGlua3M6IEluc3RhbGxBcHBMaW5rW10sIGNvbmZpZzogQ29uZmlndXJhdGlvbik6IEluc3RhbGxBcHBMaW5rW10ge1xuICAgIGNvbnN0IGFwcFZlcnNpb24gPSB0aGlzLmVudmlyb25tZW50LnZlcnNpb247XG4gICAgY29uc3QgYXBwTWluVmVyc2lvbkZyb21Qb2QgPSBjb25maWcuZ2V0UHJvcGVydHkoQ09SRV9DT05GSUdfT1BUSU9OUy5BUFBfTUlOX1ZFUlNJT04pO1xuXG4gICAgaWYgKCFhcHBWZXJzaW9uKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdNaXNzaW5nIHZhbHVlIGZvciBcXCdlbnZpcm9ubWVudC52ZXJzaW9uXFwnOiBjYW5ub3QgY2hlY2sgYXBwIGNvbXBhdGliaWxpdHkhJyk7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGNvbnN0IG5lZWRVcGdyYWRlID0gYXBwTWluVmVyc2lvbkZyb21Qb2QgJiYgIVZlcnNpb25VdGlscy5pc0NvbXBhdGlibGUoYXBwTWluVmVyc2lvbkZyb21Qb2QsIGFwcFZlcnNpb24pO1xuICAgIGlmICghbmVlZFVwZ3JhZGUpIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICBjb25zdCB1cGdyYWRlTGlua3MgPSBpbnN0YWxsTGlua3NcbiAgICAgIC5maWx0ZXIobGluayA9PiB0aGlzLnBsYXRmb3JtLmlzKCdtb2JpbGV3ZWInKSB8fCAobGluay5wbGF0Zm9ybSAmJiB0aGlzLnBsYXRmb3JtLmlzKGxpbmsucGxhdGZvcm0pKSk7XG5cbiAgICAvLyBVc2UgbWluIHZlcnNpb24gYXMgZGVmYXVsdCB2ZXJzaW9uXG4gICAgdXBncmFkZUxpbmtzLmZvckVhY2gobGluayA9PiB7XG4gICAgICBsaW5rLnZlcnNpb24gPSBsaW5rLnZlcnNpb24gfHwgYXBwTWluVmVyc2lvbkZyb21Qb2Q7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gaXNOb3RFbXB0eUFycmF5KHVwZ3JhZGVMaW5rcykgPyB1cGdyYWRlTGlua3MgOiB1bmRlZmluZWQ7XG4gIH1cblxuICBwcml2YXRlIGdldEFsbEluc3RhbGxMaW5rcyhjb25maWc6IENvbmZpZ3VyYXRpb24pOiBJbnN0YWxsQXBwTGlua1tdIHtcbiAgICBjb25zdCByZXN1bHQ6IEluc3RhbGxBcHBMaW5rW10gPSBbXTtcblxuICAgIC8vIEFuZHJvaWRcbiAgICB7XG4gICAgICAvLyBHZXQgVVJMIChmcm9tIGNvbmZpZywgb3IgZW52aXJvbm1lbnQpXG4gICAgICBsZXQgdXJsID0gY29uZmlnLmdldFByb3BlcnR5KENPUkVfQ09ORklHX09QVElPTlMuQU5EUk9JRF9JTlNUQUxMX1VSTCk7XG4gICAgICBpZiAoaXNOaWxPckJsYW5rKHVybCkpIHVybCA9IHRoaXMuZW52aXJvbm1lbnQuZGVmYXVsdEFuZHJvaWRJbnN0YWxsVXJsIHx8IG51bGw7XG4gICAgICBjb25zdCBtaW5WZXJzaW9uID0gY29uZmlnLmdldFByb3BlcnR5KENPUkVfQ09ORklHX09QVElPTlMuQVBQX01JTl9WRVJTSU9OKTtcblxuICAgICAgLy8gQ29tcHV0ZSBBcHAgbmFtZVxuICAgICAgY29uc3QgbmFtZTogc3RyaW5nID0gaXNOb3ROaWxPckJsYW5rKHVybCkgJiYgY29uZmlnLmxhYmVsIHx8IHRoaXMuZW52aXJvbm1lbnQuZGVmYXVsdEFwcE5hbWUgfHwgJ1NVTUFSaVMnO1xuXG4gICAgICBpZiAodXJsKSB7XG4gICAgICAgIGxldCBkb3dubG9hZEZpbGVuYW1lOiBzdHJpbmc7XG4gICAgICAgIGxldCB2ZXJzaW9uO1xuICAgICAgICBsZXQgbWltZVR5cGU7XG5cbiAgICAgICAgLy8gR2V0IGZpbGUgbmFtZVxuICAgICAgICBjb25zdCBmaWxlbmFtZSA9IHRoaXMuZ2V0RmlsZW5hbWUodXJsKTtcbiAgICAgICAgdmVyc2lvbiA9IG1pblZlcnNpb24gfHwgJ2xhdGVzdCc7XG5cbiAgICAgICAgLy8gT0ssIHRoaXMgaXMgYSBkb3dubG9hZGFibGUgQVBLIGZpbGUgKGUuZy4gTk9UIGEgbGluayB0byBhIHBsYXlzdG9yZSlcbiAgICAgICAgaWYgKGZpbGVuYW1lPy5lbmRzV2l0aCgnLmFwaycpKSB7XG4gICAgICAgICAgLy8gRGVmaW5lIG1pbWUgdHlwZVxuICAgICAgICAgIG1pbWVUeXBlID0gTWltZVR5cGVzLkFORFJPSURfQVBLO1xuXG4gICAgICAgICAgLy8gR2V0IHRoZSBmaWxlIHZlcnNpb24gKGlmIGFueSlcbiAgICAgICAgICBjb25zdCB2ZXJzaW9uTWF0Y2hlcyA9IC8tdihbMS05XVswLTldKlxcLlswLTldK1xcLig6Pyg6P2FscGhhfGJldGF8cmMpP1swLTldKikpL2kuZXhlYyhmaWxlbmFtZSk7XG4gICAgICAgICAgdmVyc2lvbiA9IHZlcnNpb25NYXRjaGVzICYmIHZlcnNpb25NYXRjaGVzWzFdIHx8IHZlcnNpb247XG5cbiAgICAgICAgICAvLyBDb21wdXRlIGEgbmV3IGZpbGUgbmFtZSwgd2l0aCB0aGUgdmVyc2lvblxuICAgICAgICAgIGlmIChpc05vdE5pbE9yQmxhbmsobmFtZSkpIHtcbiAgICAgICAgICAgIGRvd25sb2FkRmlsZW5hbWUgPSBgJHtuYW1lfS12JHt2ZXJzaW9ufS5hcGtgLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBkb3dubG9hZEZpbGVuYW1lID0gZmlsZW5hbWU7XG5cbiAgICAgICAgICAgIC8vIFJlcGxhY2UgJ2xhdGVzdCcgd2l0aCB0aGUgYXBwIHZlcnNpb24sIGlmIHByZXNlbnRcbiAgICAgICAgICAgIGlmIChkb3dubG9hZEZpbGVuYW1lLmluZGV4T2YoJ2xhdGVzdCcpKSB7XG4gICAgICAgICAgICAgIGRvd25sb2FkRmlsZW5hbWUgPSBkb3dubG9hZEZpbGVuYW1lLnJlcGxhY2UoJ2xhdGVzdCcsIHZlcnNpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJlc3VsdC5wdXNoKHsgbmFtZSwgdXJsLCBwbGF0Zm9ybTogJ2FuZHJvaWQnLCB2ZXJzaW9uLCBkb3dubG9hZEZpbGVuYW1lLCBtaW1lVHlwZSB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBpT1MgLSBUT0RPXG4gICAgLy97XG4gICAgLy8gICguLi4pXG4gICAgLy99XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRGaWxlbmFtZSh1cmw6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgaWYgKCF1cmwpIHJldHVybjtcbiAgICAvLyBHZXQgbGFzdCBwYXJ0IChvciBhbGwgc3RyaW5nLCBpZiBubyAnLycpXG4gICAgbGV0IGZpbGVuYW1lID0gdXJsLnN1YnN0cmluZyh1cmwubGFzdEluZGV4T2YoJy8nKSsxKTtcblxuICAgIGNvbnN0IHF1ZXJ5UGFyYW1JbmRleCA9IGZpbGVuYW1lLmluZGV4T2YoJz8nKTtcbiAgICBpZiAocXVlcnlQYXJhbUluZGV4ICE9PSAtMSkge1xuICAgICAgLy8gUmVtb3ZlIHF1ZXJ5IHBhcmFtc1xuICAgICAgcmV0dXJuIGZpbGVuYW1lLnN1YnN0cmluZygwLCBxdWVyeVBhcmFtSW5kZXgpO1xuICAgIH1cblxuICAgIHJldHVybiBmaWxlbmFtZTtcbiAgfVxuXG4gIHByaXZhdGUgbWFya0ZvckNoZWNrKCkge1xuICAgIHRoaXMuY2QubWFya0ZvckNoZWNrKCk7XG4gIH1cbn1cbiJdfQ==