123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281 |
- import { DOCUMENT } from '@angular/common';
- import { HttpClient } from '@angular/common/http';
- import { Inject, Injectable, InjectionToken, Optional, SecurityContext } from '@angular/core';
- import { of, Observable, Subject } from 'rxjs';
- import { catchError, filter, finalize, map, share, take, tap } from 'rxjs/operators';
- import { cloneSVG, getIconDefinitionFromAbbr, getNameAndNamespace, getSecondaryColor, hasNamespace, isIconDefinition, replaceFillColor, warn, withSuffix, withSuffixAndColor } from '../utils';
- import { DynamicLoadingTimeoutError, HttpModuleNotImport, IconNotFoundError, NameSpaceIsNotSpecifyError, SVGTagNotFoundError, UrlNotSafeError } from './icon.error';
- import * as i0 from "@angular/core";
- import * as i1 from "@angular/common/http";
- import * as i2 from "@angular/platform-browser";
- const JSONP_HANDLER_NAME = '__ant_icon_load';
- export const ANT_ICONS = new InjectionToken('ant_icons');
- class IconService {
- set twoToneColor({ primaryColor, secondaryColor }) {
- this._twoToneColorPalette.primaryColor = primaryColor;
- this._twoToneColorPalette.secondaryColor =
- secondaryColor || getSecondaryColor(primaryColor);
- }
- get twoToneColor() {
- // Make a copy to avoid unexpected changes.
- return { ...this._twoToneColorPalette };
- }
- /**
- * Disable dynamic loading (support static loading only).
- */
- get _disableDynamicLoading() {
- return false;
- }
- constructor(_rendererFactory, _handler, _document, sanitizer, _antIcons) {
- this._rendererFactory = _rendererFactory;
- this._handler = _handler;
- this._document = _document;
- this.sanitizer = sanitizer;
- this._antIcons = _antIcons;
- this.defaultTheme = 'outline';
- /**
- * All icon definitions would be registered here.
- */
- this._svgDefinitions = new Map();
- /**
- * Cache all rendered icons. Icons are identified by name, theme,
- * and for twotone icons, primary color and secondary color.
- */
- this._svgRenderedDefinitions = new Map();
- this._inProgressFetches = new Map();
- /**
- * Url prefix for fetching inline SVG by dynamic importing.
- */
- this._assetsUrlRoot = '';
- this._twoToneColorPalette = {
- primaryColor: '#333333',
- secondaryColor: '#E6E6E6'
- };
- /** A flag indicates whether jsonp loading is enabled. */
- this._enableJsonpLoading = false;
- this._jsonpIconLoad$ = new Subject();
- this._renderer = this._rendererFactory.createRenderer(null, null);
- if (this._handler) {
- this._http = new HttpClient(this._handler);
- }
- if (this._antIcons) {
- this.addIcon(...this._antIcons);
- }
- }
- /**
- * Call this method to switch to jsonp like loading.
- */
- useJsonpLoading() {
- if (!this._enableJsonpLoading) {
- this._enableJsonpLoading = true;
- window[JSONP_HANDLER_NAME] = (icon) => {
- this._jsonpIconLoad$.next(icon);
- };
- }
- else {
- warn('You are already using jsonp loading.');
- }
- }
- /**
- * Change the prefix of the inline svg resources, so they could be deployed elsewhere, like CDN.
- * @param prefix
- */
- changeAssetsSource(prefix) {
- this._assetsUrlRoot = prefix.endsWith('/') ? prefix : prefix + '/';
- }
- /**
- * Add icons provided by ant design.
- * @param icons
- */
- addIcon(...icons) {
- icons.forEach(icon => {
- this._svgDefinitions.set(withSuffix(icon.name, icon.theme), icon);
- });
- }
- /**
- * Register an icon. Namespace is required.
- * @param type
- * @param literal
- */
- addIconLiteral(type, literal) {
- const [_, namespace] = getNameAndNamespace(type);
- if (!namespace) {
- throw NameSpaceIsNotSpecifyError();
- }
- this.addIcon({ name: type, icon: literal });
- }
- /**
- * Remove all cache.
- */
- clear() {
- this._svgDefinitions.clear();
- this._svgRenderedDefinitions.clear();
- }
- /**
- * Get a rendered `SVGElement`.
- * @param icon
- * @param twoToneColor
- */
- getRenderedContent(icon, twoToneColor) {
- // If `icon` is a `IconDefinition`, go to the next step. If not, try to fetch it from cache.
- const definition = isIconDefinition(icon)
- ? icon
- : this._svgDefinitions.get(icon) || null;
- if (!definition && this._disableDynamicLoading) {
- throw IconNotFoundError(icon);
- }
- // If `icon` is a `IconDefinition` of successfully fetch, wrap it in an `Observable`.
- // Otherwise try to fetch it from remote.
- const $iconDefinition = definition
- ? of(definition)
- : this._loadIconDynamically(icon);
- // If finally get an `IconDefinition`, render and return it. Otherwise throw an error.
- return $iconDefinition.pipe(map(i => {
- if (!i) {
- throw IconNotFoundError(icon);
- }
- return this._loadSVGFromCacheOrCreateNew(i, twoToneColor);
- }));
- }
- getCachedIcons() {
- return this._svgDefinitions;
- }
- /**
- * Get raw svg and assemble a `IconDefinition` object.
- * @param type
- */
- _loadIconDynamically(type) {
- // If developer doesn't provide HTTP module nor enable jsonp loading, just throw an error.
- if (!this._http && !this._enableJsonpLoading) {
- return of(HttpModuleNotImport());
- }
- // If multi directive ask for the same icon at the same time,
- // request should only be fired once.
- let inProgress = this._inProgressFetches.get(type);
- if (!inProgress) {
- const [name, namespace] = getNameAndNamespace(type);
- // If the string has a namespace within, create a simple `IconDefinition`.
- const icon = namespace
- ? { name: type, icon: '' }
- : getIconDefinitionFromAbbr(name);
- const suffix = this._enableJsonpLoading ? '.js' : '.svg';
- const url = (namespace
- ? `${this._assetsUrlRoot}assets/${namespace}/${name}`
- : `${this._assetsUrlRoot}assets/${icon.theme}/${icon.name}`) + suffix;
- const safeUrl = this.sanitizer.sanitize(SecurityContext.URL, url);
- if (!safeUrl) {
- throw UrlNotSafeError(url);
- }
- const source = !this._enableJsonpLoading
- ? this._http
- .get(safeUrl, { responseType: 'text' })
- .pipe(map(literal => ({ ...icon, icon: literal })))
- : this._loadIconDynamicallyWithJsonp(icon, safeUrl);
- inProgress = source.pipe(tap(definition => this.addIcon(definition)), finalize(() => this._inProgressFetches.delete(type)), catchError(() => of(null)), share());
- this._inProgressFetches.set(type, inProgress);
- }
- return inProgress;
- }
- _loadIconDynamicallyWithJsonp(icon, url) {
- return new Observable(subscriber => {
- const loader = this._document.createElement('script');
- const timer = setTimeout(() => {
- clean();
- subscriber.error(DynamicLoadingTimeoutError());
- }, 6000);
- loader.src = url;
- function clean() {
- loader.parentNode.removeChild(loader);
- clearTimeout(timer);
- }
- this._document.body.appendChild(loader);
- this._jsonpIconLoad$
- .pipe(filter(i => i.name === icon.name && i.theme === icon.theme), take(1))
- .subscribe(i => {
- subscriber.next(i);
- clean();
- });
- });
- }
- /**
- * Render a new `SVGElement` for a given `IconDefinition`, or make a copy from cache.
- * @param icon
- * @param twoToneColor
- */
- _loadSVGFromCacheOrCreateNew(icon, twoToneColor) {
- let svg;
- const pri = twoToneColor || this._twoToneColorPalette.primaryColor;
- const sec = getSecondaryColor(pri) || this._twoToneColorPalette.secondaryColor;
- const key = icon.theme === 'twotone'
- ? withSuffixAndColor(icon.name, icon.theme, pri, sec)
- : icon.theme === undefined
- ? icon.name
- : withSuffix(icon.name, icon.theme);
- // Try to make a copy from cache.
- const cached = this._svgRenderedDefinitions.get(key);
- if (cached) {
- svg = cached.icon;
- }
- else {
- svg = this._setSVGAttribute(this._colorizeSVGIcon(
- // Icons provided by ant design should be refined to remove preset colors.
- this._createSVGElementFromString(hasNamespace(icon.name) ? icon.icon : replaceFillColor(icon.icon)), icon.theme === 'twotone', pri, sec));
- // Cache it.
- this._svgRenderedDefinitions.set(key, {
- ...icon,
- icon: svg
- });
- }
- return cloneSVG(svg);
- }
- _createSVGElementFromString(str) {
- const div = this._document.createElement('div');
- div.innerHTML = str;
- const svg = div.querySelector('svg');
- if (!svg) {
- throw SVGTagNotFoundError;
- }
- return svg;
- }
- _setSVGAttribute(svg) {
- this._renderer.setAttribute(svg, 'width', '1em');
- this._renderer.setAttribute(svg, 'height', '1em');
- return svg;
- }
- _colorizeSVGIcon(svg, twotone, pri, sec) {
- if (twotone) {
- const children = svg.childNodes;
- const length = children.length;
- for (let i = 0; i < length; i++) {
- const child = children[i];
- if (child.getAttribute('fill') === 'secondaryColor') {
- this._renderer.setAttribute(child, 'fill', sec);
- }
- else {
- this._renderer.setAttribute(child, 'fill', pri);
- }
- }
- }
- this._renderer.setAttribute(svg, 'fill', 'currentColor');
- return svg;
- }
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.2", ngImport: i0, type: IconService, deps: [{ token: i0.RendererFactory2 }, { token: i1.HttpBackend, optional: true }, { token: DOCUMENT, optional: true }, { token: i2.DomSanitizer }, { token: ANT_ICONS, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.2", ngImport: i0, type: IconService }); }
- }
- export { IconService };
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.2", ngImport: i0, type: IconService, decorators: [{
- type: Injectable
- }], ctorParameters: function () { return [{ type: i0.RendererFactory2 }, { type: i1.HttpBackend, decorators: [{
- type: Optional
- }] }, { type: undefined, decorators: [{
- type: Optional
- }, {
- type: Inject,
- args: [DOCUMENT]
- }] }, { type: i2.DomSanitizer }, { type: undefined, decorators: [{
- type: Optional
- }, {
- type: Inject,
- args: [ANT_ICONS]
- }] }]; } });
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaWNvbi5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBvbmVudC9pY29uLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzNDLE9BQU8sRUFBZSxVQUFVLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUMvRCxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxjQUFjLEVBQUUsUUFBUSxFQUErQixlQUFlLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFM0gsT0FBTyxFQUFFLEVBQUUsRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQy9DLE9BQU8sRUFDTCxVQUFVLEVBQ1YsTUFBTSxFQUNOLFFBQVEsRUFDUixHQUFHLEVBQ0gsS0FBSyxFQUNMLElBQUksRUFDSixHQUFHLEVBQ0osTUFBTSxnQkFBZ0IsQ0FBQztBQVF4QixPQUFPLEVBQ0wsUUFBUSxFQUNSLHlCQUF5QixFQUN6QixtQkFBbUIsRUFDbkIsaUJBQWlCLEVBQ2pCLFlBQVksRUFDWixnQkFBZ0IsRUFDaEIsZ0JBQWdCLEVBQ2hCLElBQUksRUFDSixVQUFVLEVBQ1Ysa0JBQWtCLEVBQ25CLE1BQU0sVUFBVSxDQUFDO0FBQ2xCLE9BQU8sRUFDTCwwQkFBMEIsRUFDMUIsbUJBQW1CLEVBQ25CLGlCQUFpQixFQUNqQiwwQkFBMEIsRUFDMUIsbUJBQW1CLEVBQ25CLGVBQWUsRUFDaEIsTUFBTSxjQUFjLENBQUM7Ozs7QUFFdEIsTUFBTSxrQkFBa0IsR0FBRyxpQkFBaUIsQ0FBQztBQUU3QyxNQUFNLENBQUMsTUFBTSxTQUFTLEdBQUcsSUFBSSxjQUFjLENBQW1CLFdBQVcsQ0FBQyxDQUFDO0FBRTNFLE1BQ2EsV0FBVztJQUd0QixJQUFJLFlBQVksQ0FBQyxFQUNmLFlBQVksRUFDWixjQUFjLEVBQ1k7UUFDMUIsSUFBSSxDQUFDLG9C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SUFBSSxDQUFDLFNBQVMsQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQztpQkFDakQ7YUFDRjtTQUNGO1FBQ0QsSUFBSSxDQUFDLFNBQVMsQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFFLE1BQU0sRUFBRSxjQUFjLENBQUMsQ0FBQztRQUN6RCxPQUFPLEdBQUcsQ0FBQztJQUNiLENBQUM7OEdBaFZVLFdBQVcsNkZBNERBLFFBQVEseURBR1IsU0FBUztrSEEvRHBCLFdBQVc7O1NBQVgsV0FBVzsyRkFBWCxXQUFXO2tCQUR2QixVQUFVOzswQkE0RE4sUUFBUTs7MEJBQ1IsUUFBUTs7MEJBQUksTUFBTTsyQkFBQyxRQUFROzswQkFHM0IsUUFBUTs7MEJBQUksTUFBTTsyQkFBQyxTQUFTIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRE9DVU1FTlQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgSHR0cEJhY2tlbmQsIEh0dHBDbGllbnQgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5pbXBvcnQgeyBJbmplY3QsIEluamVjdGFibGUsIEluamVjdGlvblRva2VuLCBPcHRpb25hbCwgUmVuZGVyZXIyLCBSZW5kZXJlckZhY3RvcnkyLCBTZWN1cml0eUNvbnRleHQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IERvbVNhbml0aXplciB9IGZyb20gJ0Bhbmd1bGFyL3BsYXRmb3JtLWJyb3dzZXInO1xuaW1wb3J0IHsgb2YsIE9ic2VydmFibGUsIFN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7XG4gIGNhdGNoRXJyb3IsXG4gIGZpbHRlcixcbiAgZmluYWxpemUsXG4gIG1hcCxcbiAgc2hhcmUsXG4gIHRha2UsXG4gIHRhcFxufSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQge1xuICBDYWNoZWRJY29uRGVmaW5pdGlvbixcbiAgSWNvbkRlZmluaXRpb24sXG4gIFRoZW1lVHlwZSxcbiAgVHdvVG9uZUNvbG9yUGFsZXR0ZSxcbiAgVHdvVG9uZUNvbG9yUGFsZXR0ZVNldHRlclxufSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQge1xuICBjbG9uZVNWRyxcbiAgZ2V0SWNvbkRlZmluaXRpb25Gcm9tQWJicixcbiAgZ2V0TmFtZUFuZE5hbWVzcGFjZSxcbiAgZ2V0U2Vjb25kYXJ5Q29sb3IsXG4gIGhhc05hbWVzcGFjZSxcbiAgaXNJY29uRGVmaW5pdGlvbixcbiAgcmVwbGFjZUZpbGxDb2xvcixcbiAgd2FybixcbiAgd2l0aFN1ZmZpeCxcbiAgd2l0aFN1ZmZpeEFuZENvbG9yXG59IGZyb20gJy4uL3V0aWxzJztcbmltcG9ydCB7XG4gIER5bmFtaWNMb2FkaW5nVGltZW91dEVycm9yLFxuICBIdHRwTW9kdWxlTm90SW1wb3J0LFxuICBJY29uTm90Rm91bmRFcnJvcixcbiAgTmFtZVNwYWNlSXNOb3RTcGVjaWZ5RXJyb3IsXG4gIFNWR1RhZ05vdEZvdW5kRXJyb3IsXG4gIFVybE5vdFNhZmVFcnJvclxufSBmcm9tICcuL2ljb24uZXJyb3InO1xuXG5jb25zdCBKU09OUF9IQU5ETEVSX05BTUUgPSAnX19hbnRfaWNvbl9sb2FkJztcblxuZXhwb3J0IGNvbnN0IEFOVF9JQ09OUyA9IG5ldyBJbmplY3Rpb25Ub2tlbjxJY29uRGVmaW5pdGlvbltdPignYW50X2ljb25zJyk7XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBJY29uU2VydmljZSB7XG4gIGRlZmF1bHRUaGVtZTogVGhlbWVUeXBlID0gJ291dGxpbmUnO1xuXG4gIHNldCB0d29Ub25lQ29sb3Ioe1xuICAgIHByaW1hcnlDb2xvcixcbiAgICBzZWNvbmRhcnlDb2xvclxuICB9OiBUd29Ub25lQ29sb3JQYWxldHRlU2V0dGVyKSB7XG4gICAgdGhpcy5fdHdvVG9uZUNvbG9yUGFsZXR0ZS5wcmltYXJ5Q29sb3IgPSBwcmltYXJ5Q29sb3I7XG4gICAgdGhpcy5fdHdvVG9uZUNvbG9yUGFsZXR0ZS5zZWNvbmRhcnlDb2xvciA9XG4gICAgICBzZWNvbmRhcnlDb2xvciB8fCBnZXRTZWNvbmRhcnlDb2xvcihwcmltYXJ5Q29sb3IpO1xuICB9XG5cbiAgZ2V0IHR3b1RvbmVDb2xvcigpOiBUd29Ub25lQ29sb3JQYWxldHRlU2V0dGVyIHtcbiAgICAvLyBNYWtlIGEgY29weSB0byBhdm9pZCB1bmV4cGVjdGVkIGNoYW5nZXMuXG4gICAgcmV0dXJuIHsgLi4udGhpcy5fdHdvVG9uZUNvbG9yUGFsZXR0ZSB9IGFzIFR3b1RvbmVDb2xvclBhbGV0dGU7XG4gIH1cblxuICBwcm90ZWN0ZWQgX3JlbmRlcmVyOiBSZW5kZXJlcjI7XG4gIHByb3RlY3RlZCBfaHR0cDogSHR0cENsaWVudDtcblxuICAvKipcbiAgICogRGlzYWJsZSBkeW5hbWljIGxvYWRpbmcgKHN1cHBvcnQgc3RhdGljIGxvYWRpbmcgb25seSkuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0IF9kaXNhYmxlRHluYW1pY0xvYWRpbmcoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIEFsbCBpY29uIGRlZmluaXRpb25zIHdvdWxkIGJlIHJlZ2lzdGVyZWQgaGVyZS5cbiAgICovXG4gIHByb3RlY3RlZCByZWFkb25seSBfc3ZnRGVmaW5pdGlvbnMgPSBuZXcgTWFwPHN0cmluZywgSWNvbkRlZmluaXRpb24+KCk7XG5cbiAgLyoqXG4gICAqIENhY2hlIGFsbCByZW5kZXJlZCBpY29ucy4gSWNvbnMgYXJlIGlkZW50aWZpZWQgYnkgbmFtZSwgdGhlbWUsXG4gICAqIGFuZCBmb3IgdHdvdG9uZSBpY29ucywgcHJpbWFyeSBjb2xvciBhbmQgc2Vjb25kYXJ5IGNvbG9yLlxuICAgKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IF9zdmdSZW5kZXJlZERlZmluaXRpb25zID0gbmV3IE1hcDxzdHJpbmcsIENhY2hlZEljb25EZWZpbml0aW9uPigpO1xuXG4gIHByb3RlY3RlZCBfaW5Qcm9ncmVzc0ZldGNoZXMgPSBuZXcgTWFwPFxuICAgIHN0cmluZyxcbiAgICBPYnNlcnZhYmxlPEljb25EZWZpbml0aW9uIHwgbnVsbD5cbiAgPigpO1xuXG4gIC8qKlxuICAgKiBVcmwgcHJlZml4IGZvciBmZXRjaGluZyBpbmxpbmUgU1ZHIGJ5IGR5bmFtaWMgaW1wb3J0aW5nLlxuICAgKi9cbiAgcHJvdGVjdGVkIF9hc3NldHNVcmxSb290ID0gJyc7XG5cbiAgcHJvdGVjdGVkIF90d29Ub25lQ29sb3JQYWxldHRlOiBUd29Ub25lQ29sb3JQYWxldHRlID0ge1xuICAgIHByaW1hcnlDb2xvcjogJyMzMzMzMzMnLFxuICAgIHNlY29uZGFyeUNvbG9yOiAnI0U2RTZFNidcbiAgfTtcblxuICAvKiogQSBmbGFnIGluZGljYXRlcyB3aGV0aGVyIGpzb25wIGxvYWRpbmcgaXMgZW5hYmxlZC4gKi9cbiAgcHJpdmF0ZSBfZW5hYmxlSnNvbnBMb2FkaW5nID0gZmFsc2U7XG4gIHByaXZhdGUgcmVhZG9ubHkgX2pzb25wSWNvbkxvYWQkID0gbmV3IFN1YmplY3Q8SWNvbkRlZmluaXRpb24+KCk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJvdGVjdGVkIF9yZW5kZXJlckZhY3Rvcnk6IFJlbmRlcmVyRmFjdG9yeTIsXG4gICAgQE9wdGlvbmFsKCkgcHJvdGVjdGVkIF9oYW5kbGVyOiBIdHRwQmFja2VuZCxcbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KERPQ1VNRU5UKSBwcm90ZWN0ZWQgX2RvY3VtZW50OiBhbnksXG4gICAgcHJvdGVjdGVkIHNhbml0aXplcjogRG9tU2FuaXRpemVyLFxuXG4gICAgQE9wdGlvbmFsKCkgQEluamVjdChBTlRfSUNPTlMpIHByb3RlY3RlZCBfYW50SWNvbnM6IEljb25EZWZpbml0aW9uW11cbiAgKSB7XG4gICAgdGhpcy5fcmVuZGVyZXIgPSB0aGlzLl9yZW5kZXJlckZhY3RvcnkuY3JlYXRlUmVuZGVyZXIobnVsbCwgbnVsbCk7XG5cbiAgICBpZiAodGhpcy5faGFuZGxlcikge1xuICAgICAgdGhpcy5faHR0cCA9IG5ldyBIdHRwQ2xpZW50KHRoaXMuX2hhbmRsZXIpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9hbnRJY29ucykge1xuICAgICAgdGhpcy5hZGRJY29uKC4uLnRoaXMuX2FudEljb25zKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2FsbCB0aGlzIG1ldGhvZCB0byBzd2l0Y2ggdG8ganNvbnAgbGlrZSBsb2FkaW5nLlxuICAgKi9cbiAgdXNlSnNvbnBMb2FkaW5nKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5fZW5hYmxlSnNvbnBMb2FkaW5nKSB7XG4gICAgICB0aGlzLl9lbmFibGVKc29ucExvYWRpbmcgPSB0cnVlO1xuXG4gICAgICB3aW5kb3dbSlNPTlBfSEFORExFUl9OQU1FXSA9IChpY29uOiBJY29uRGVmaW5pdGlvbikgPT4ge1xuICAgICAgICB0aGlzLl9qc29ucEljb25Mb2FkJC5uZXh0KGljb24pO1xuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgd2FybignWW91IGFyZSBhbHJlYWR5IHVzaW5nIGpzb25wIGxvYWRpbmcuJyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENoYW5nZSB0aGUgcHJlZml4IG9mIHRoZSBpbmxpbmUgc3ZnIHJlc291cmNlcywgc28gdGhleSBjb3VsZCBiZSBkZXBsb3llZCBlbHNld2hlcmUsIGxpa2UgQ0ROLlxuICAgKiBAcGFyYW0gcHJlZml4XG4gICAqL1xuICBjaGFuZ2VBc3NldHNTb3VyY2UocHJlZml4OiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLl9hc3NldHNVcmxSb290ID0gcHJlZml4LmVuZHNXaXRoKCcvJykgPyBwcmVmaXggOiBwcmVmaXggKyAnLyc7XG4gIH1cblxuICAvKipcbiAgICogQWRkIGljb25zIHByb3ZpZGVkIGJ5IGFudCBkZXNpZ24uXG4gICAqIEBwYXJhbSBpY29uc1xuICAgKi9cbiAgYWRkSWNvbiguLi5pY29uczogSWNvbkRlZmluaXRpb25bXSk6IHZvaWQge1xuICAgIGljb25zLmZvckVhY2goaWNvbiA9PiB7XG4gICAgICB0aGlzLl9zdmdEZWZpbml0aW9ucy5zZXQod2l0aFN1ZmZpeChpY29uLm5hbWUsIGljb24udGhlbWUpLCBpY29uKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlciBhbiBpY29uLiBOYW1lc3BhY2UgaXMgcmVxdWlyZWQuXG4gICAqIEBwYXJhbSB0eXBlXG4gICAqIEBwYXJhbSBsaXRlcmFsXG4gICAqL1xuICBhZGRJY29uTGl0ZXJhbCh0eXBlOiBzdHJpbmcsIGxpdGVyYWw6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IFtfLCBuYW1lc3BhY2VdID0gZ2V0TmFtZUFuZE5hbWVzcGFjZSh0eXBlKTtcbiAgICBpZiAoIW5hbWVzcGFjZSkge1xuICAgICAgdGhyb3cgTmFtZVNwYWNlSXNOb3RTcGVjaWZ5RXJyb3IoKTtcbiAgICB9XG4gICAgdGhpcy5hZGRJY29uKHsgbmFtZTogdHlwZSwgaWNvbjogbGl0ZXJhbCB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmUgYWxsIGNhY2hlLlxuICAgKi9cbiAgY2xlYXIoKTogdm9pZCB7XG4gICAgdGhpcy5fc3ZnRGVmaW5pdGlvbnMuY2xlYXIoKTtcbiAgICB0aGlzLl9zdmdSZW5kZXJlZERlZmluaXRpb25zLmNsZWFyKCk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGEgcmVuZGVyZWQgYFNWR0VsZW1lbnRgLlxuICAgKiBAcGFyYW0gaWNvblxuICAgKiBAcGFyYW0gdHdvVG9uZUNvbG9yXG4gICAqL1xuICBnZXRSZW5kZXJlZENvbnRlbnQoXG4gICAgaWNvbjogSWNvbkRlZmluaXRpb24gfCBzdHJpbmcsXG4gICAgdHdvVG9uZUNvbG9yPzogc3RyaW5nXG4gICk6IE9ic2VydmFibGU8U1ZHRWxlbWVudD4ge1xuICAgIC8vIElmIGBpY29uYCBpcyBhIGBJY29uRGVmaW5pdGlvbmAsIGdvIHRvIHRoZSBuZXh0IHN0ZXAuIElmIG5vdCwgdHJ5IHRvIGZldGNoIGl0IGZyb20gY2FjaGUuXG4gICAgY29uc3QgZGVmaW5pdGlvbjogSWNvbkRlZmluaXRpb24gfCBudWxsID0gaXNJY29uRGVmaW5pdGlvbihpY29uKVxuICAgICAgPyAoaWNvbiBhcyBJY29uRGVmaW5pdGlvbilcbiAgICAgIDogdGhpcy5fc3ZnRGVmaW5pdGlvbnMuZ2V0KGljb24pIHx8IG51bGw7XG4gICAgXG4gICAgaWYgKCFkZWZpbml0aW9uICYmIHRoaXMuX2Rpc2FibGVEeW5hbWljTG9hZGluZykge1xuICAgICAgdGhyb3cgSWNvbk5vdEZvdW5kRXJyb3IoaWNvbiBhcyBzdHJpbmcpO1xuICAgIH1cblxuICAgIC8vIElmIGBpY29uYCBpcyBhIGBJY29uRGVmaW5pdGlvbmAgb2Ygc3VjY2Vzc2Z1bGx5IGZldGNoLCB3cmFwIGl0IGluIGFuIGBPYnNlcnZhYmxlYC5cbiAgICAvLyBPdGhlcndpc2UgdHJ5IHRvIGZldGNoIGl0IGZyb20gcmVtb3RlLlxuICAgIGNvbnN0ICRpY29uRGVmaW5pdGlvbiA9IGRlZmluaXRpb25cbiAgICAgID8gb2YoZGVmaW5pdGlvbilcbiAgICAgIDogdGhpcy5fbG9hZEljb25EeW5hbWljYWxseShpY29uIGFzIHN0cmluZyk7XG5cbiAgICAvLyBJZiBmaW5hbGx5IGdldCBhbiBgSWNvbkRlZmluaXRpb25gLCByZW5kZXIgYW5kIHJldHVybiBpdC4gT3RoZXJ3aXNlIHRocm93IGFuIGVycm9yLlxuICAgIHJldHVybiAkaWNvbkRlZmluaXRpb24ucGlwZShcbiAgICAgIG1hcChpID0+IHtcbiAgICAgICAgaWYgKCFpKSB7XG4gICAgICAgICAgdGhyb3cgSWNvbk5vdEZvdW5kRXJyb3IoaWNvbiBhcyBzdHJpbmcpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9sb2FkU1ZHRnJvbUNhY2hlT3JDcmVhdGVOZXcoaSwgdHdvVG9uZUNvbG9yKTtcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIGdldENhY2hlZEljb25zKCk6IE1hcDxzdHJpbmcsIEljb25EZWZpbml0aW9uPiB7XG4gICAgcmV0dXJuIHRoaXMuX3N2Z0RlZmluaXRpb25zO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCByYXcgc3ZnIGFuZCBhc3NlbWJsZSBhIGBJY29uRGVmaW5pdGlvbmAgb2JqZWN0LlxuICAgKiBAcGFyYW0gdHlwZVxuICAgKi9cbiAgcHJvdGVjdGVkIF9sb2FkSWNvbkR5bmFtaWNhbGx5KFxuICAgIHR5cGU6IHN0cmluZ1xuICApOiBPYnNlcnZhYmxlPEljb25EZWZpbml0aW9uIHwgbnVsbD4ge1xuICAgIC8vIElmIGRldmVsb3BlciBkb2Vzbid0IHByb3ZpZGUgSFRUUCBtb2R1bGUgbm9yIGVuYWJsZSBqc29ucCBsb2FkaW5nLCBqdXN0IHRocm93IGFuIGVycm9yLlxuICAgIGlmICghdGhpcy5faHR0cCAmJiAhdGhpcy5fZW5hYmxlSnNvbnBMb2FkaW5nKSB7XG4gICAgICByZXR1cm4gb2YoSHR0cE1vZHVsZU5vdEltcG9ydCgpKTtcbiAgICB9XG5cbiAgICAvLyBJZiBtdWx0aSBkaXJlY3RpdmUgYXNrIGZvciB0aGUgc2FtZSBpY29uIGF0IHRoZSBzYW1lIHRpbWUsXG4gICAgLy8gcmVxdWVzdCBzaG91bGQgb25seSBiZSBmaXJlZCBvbmNlLlxuICAgIGxldCBpblByb2dyZXNzID0gdGhpcy5faW5Qcm9ncmVzc0ZldGNoZXMuZ2V0KHR5cGUpO1xuXG4gICAgaWYgKCFpblByb2dyZXNzKSB7XG4gICAgICBjb25zdCBbbmFtZSwgbmFtZXNwYWNlXSA9IGdldE5hbWVBbmROYW1lc3BhY2UodHlwZSk7XG5cbiAgICAgIC8vIElmIHRoZSBzdHJpbmcgaGFzIGEgbmFtZXNwYWNlIHdpdGhpbiwgY3JlYXRlIGEgc2ltcGxlIGBJY29uRGVmaW5pdGlvbmAuXG4gICAgICBjb25zdCBpY29uOiBJY29uRGVmaW5pdGlvbiA9IG5hbWVzcGFjZVxuICAgICAgICA/IHsgbmFtZTogdHlwZSwgaWNvbjogJycgfVxuICAgICAgICA6IGdldEljb25EZWZpbml0aW9uRnJvbUFiYnIobmFtZSk7XG5cbiAgICAgIGNvbnN0IHN1ZmZpeCA9IHRoaXMuX2VuYWJsZUpzb25wTG9hZGluZyA/ICcuanMnIDogJy5zdmcnO1xuICAgICAgY29uc3QgdXJsID1cbiAgICAgICAgKG5hbWVzcGFjZVxuICAgICAgICAgID8gYCR7dGhpcy5fYXNzZXRzVXJsUm9vdH1hc3NldHMvJHtuYW1lc3BhY2V9LyR7bmFtZX1gXG4gICAgICAgICAgOiBgJHt0aGlzLl9hc3NldHNVcmxSb290fWFzc2V0cy8ke2ljb24udGhlbWV9LyR7aWNvbi5uYW1lfWApICsgc3VmZml4O1xuXG4gICAgICBjb25zdCBzYWZlVXJsID0gdGhpcy5zYW5pdGl6ZXIuc2FuaXRpemUoU2VjdXJpdHlDb250ZXh0LlVSTCwgdXJsKTtcblxuICAgICAgaWYgKCFzYWZlVXJsKSB7XG4gICAgICAgIHRocm93IFVybE5vdFNhZmVFcnJvcih1cmwpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBzb3VyY2UgPSAhdGhpcy5fZW5hYmxlSnNvbnBMb2FkaW5nXG4gICAgICAgID8gdGhpcy5faHR0cFxuICAgICAgICAgICAgLmdldChzYWZlVXJsLCB7IHJlc3BvbnNlVHlwZTogJ3RleHQnIH0pXG4gICAgICAgICAgICAucGlwZShtYXAobGl0ZXJhbCA9PiAoeyAuLi5pY29uLCBpY29uOiBsaXRlcmFsIH0pKSlcbiAgICAgICAgOiB0aGlzLl9sb2FkSWNvbkR5bmFtaWNhbGx5V2l0aEpzb25wKGljb24sIHNhZmVVcmwpO1xuXG4gICAgICBpblByb2dyZXNzID0gc291cmNlLnBpcGUoXG4gICAgICAgIHRhcChkZWZpbml0aW9uID0+IHRoaXMuYWRkSWNvbihkZWZpbml0aW9uKSksXG4gICAgICAgIGZpbmFsaXplKCgpID0+IHRoaXMuX2luUHJvZ3Jlc3NGZXRjaGVzLmRlbGV0ZSh0eXBlKSksXG4gICAgICAgIGNhdGNoRXJyb3IoKCkgPT4gb2YobnVsbCkpLFxuICAgICAgICBzaGFyZSgpXG4gICAgICApO1xuXG4gICAgICB0aGlzLl9pblByb2dyZXNzRmV0Y2hlcy5zZXQodHlwZSwgaW5Qcm9ncmVzcyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGluUHJvZ3Jlc3M7XG4gIH1cblxuICBwcm90ZWN0ZWQgX2xvYWRJY29uRHluYW1pY2FsbHlXaXRoSnNvbnAoaWNvbjogSWNvbkRlZmluaXRpb24sIHVybDogc3RyaW5nKTogT2JzZXJ2YWJsZTxJY29uRGVmaW5pdGlvbj4ge1xuICAgIHJldHVybiBuZXcgT2JzZXJ2YWJsZTxJY29uRGVmaW5pdGlvbj4oc3Vic2NyaWJlciA9PiB7XG4gICAgICBjb25zdCBsb2FkZXIgPSB0aGlzLl9kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTtcbiAgICAgIGNvbnN0IHRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIGNsZWFuKCk7XG4gICAgICAgIHN1YnNjcmliZXIuZXJyb3IoRHluYW1pY0xvYWRpbmdUaW1lb3V0RXJyb3IoKSk7XG4gICAgICB9LCA2MDAwKTtcblxuICAgICAgbG9hZGVyLnNyYyA9IHVybDtcblxuICAgICAgZnVuY3Rpb24gY2xlYW4oKTogdm9pZCB7XG4gICAgICAgIGxvYWRlci5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGxvYWRlcik7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lcik7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuX2RvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQobG9hZGVyKTtcbiAgICAgIHRoaXMuX2pzb25wSWNvbkxvYWQkXG4gICAgICAgICAgLnBpcGUoXG4gICAgICAgICAgICAgIGZpbHRlcihpID0+IGkubmFtZSA9PT0gaWNvbi5uYW1lICYmIGkudGhlbWUgPT09IGljb24udGhlbWUpLFxuICAgICAgICAgICAgICB0YWtlKDEpXG4gICAgICAgICAgKVxuICAgICAgICAgIC5zdWJzY3JpYmUoaSA9PiB7XG4gICAgICAgICAgICBzdWJzY3JpYmVyLm5leHQoaSk7XG4gICAgICAgICAgICBjbGVhbigpO1xuICAgICAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbmRlciBhIG5ldyBgU1ZHRWxlbWVudGAgZm9yIGEgZ2l2ZW4gYEljb25EZWZpbml0aW9uYCwgb3IgbWFrZSBhIGNvcHkgZnJvbSBjYWNoZS5cbiAgICogQHBhcmFtIGljb25cbiAgICogQHBhcmFtIHR3b1RvbmVDb2xvclxuICAgKi9cbiAgcHJvdGVjdGVkIF9sb2FkU1ZHRnJvbUNhY2hlT3JDcmVhdGVOZXcoXG4gICAgaWNvbjogSWNvbkRlZmluaXRpb24sXG4gICAgdHdvVG9uZUNvbG9yPzogc3RyaW5nXG4gICk6IFNWR0VsZW1lbnQge1xuICAgIGxldCBzdmc6IFNWR0VsZW1lbnQ7XG5cbiAgICBjb25zdCBwcmkgPSB0d29Ub25lQ29sb3IgfHwgdGhpcy5fdHdvVG9uZUNvbG9yUGFsZXR0ZS5wcmltYXJ5Q29sb3I7XG4gICAgY29uc3Qgc2VjID1cbiAgICAgIGdldFNlY29uZGFyeUNvbG9yKHByaSkgfHwgdGhpcy5fdHdvVG9uZUNvbG9yUGFsZXR0ZS5zZWNvbmRhcnlDb2xvcjtcbiAgICBjb25zdCBrZXkgPVxuICAgICAgaWNvbi50aGVtZSA9PT0gJ3R3b3RvbmUnXG4gICAgICAgID8gd2l0aFN1ZmZpeEFuZENvbG9yKGljb24ubmFtZSwgaWNvbi50aGVtZSwgcHJpLCBzZWMpXG4gICAgICAgIDogaWNvbi50aGVtZSA9PT0gdW5kZWZpbmVkXG4gICAgICAgID8gaWNvbi5uYW1lXG4gICAgICAgIDogd2l0aFN1ZmZpeChpY29uLm5hbWUsIGljb24udGhlbWUpO1xuXG4gICAgLy8gVHJ5IHRvIG1ha2UgYSBjb3B5IGZyb20gY2FjaGUuXG4gICAgY29uc3QgY2FjaGVkID0gdGhpcy5fc3ZnUmVuZGVyZWREZWZpbml0aW9ucy5nZXQoa2V5KTtcblxuICAgIGlmIChjYWNoZWQpIHtcbiAgICAgIHN2ZyA9IGNhY2hlZC5pY29uO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdmcgPSB0aGlzLl9zZXRTVkdBdHRyaWJ1dGUoXG4gICAgICAgIHRoaXMuX2NvbG9yaXplU1ZHSWNvbihcbiAgICAgICAgICAvLyBJY29ucyBwcm92aWRlZCBieSBhbnQgZGVzaWduIHNob3VsZCBiZSByZWZpbmVkIHRvIHJlbW92ZSBwcmVzZXQgY29sb3JzLlxuICAgICAgICAgIHRoaXMuX2NyZWF0ZVNWR0VsZW1lbnRGcm9tU3RyaW5nKFxuICAgICAgICAgICAgaGFzTmFtZXNwYWNlKGljb24ubmFtZSkgPyBpY29uLmljb24gOiByZXBsYWNlRmlsbENvbG9yKGljb24uaWNvbilcbiAgICAgICAgICApLFxuICAgICAgICAgIGljb24udGhlbWUgPT09ICd0d290b25lJyxcbiAgICAgICAgICBwcmksXG4gICAgICAgICAgc2VjXG4gICAgICAgIClcbiAgICAgICk7XG4gICAgICAvLyBDYWNoZSBpdC5cbiAgICAgIHRoaXMuX3N2Z1JlbmRlcmVkRGVmaW5pdGlvbnMuc2V0KGtleSwge1xuICAgICAgICAuLi5pY29uLFxuICAgICAgICBpY29uOiBzdmdcbiAgICAgIH0gYXMgQ2FjaGVkSWNvbkRlZmluaXRpb24pO1xuICAgIH1cblxuICAgIHJldHVybiBjbG9uZVNWRyhzdmcpO1xuICB9XG5cbiAgcHJvdGVjdGVkIF9jcmVhdGVTVkdFbGVtZW50RnJvbVN0cmluZyhzdHI6IHN0cmluZyk6IFNWR0VsZW1lbnQge1xuICAgIGNvbnN0IGRpdiA9IHRoaXMuX2RvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIGRpdi5pbm5lckhUTUwgPSBzdHI7XG4gICAgY29uc3Qgc3ZnOiBTVkdFbGVtZW50ID0gZGl2LnF1ZXJ5U2VsZWN0b3IoJ3N2ZycpO1xuICAgIGlmICghc3ZnKSB7XG4gICAgICB0aHJvdyBTVkdUYWdOb3RGb3VuZEVycm9yO1xuICAgIH1cbiAgICByZXR1cm4gc3ZnO1xuICB9XG5cbiAgcHJvdGVjdGVkIF9zZXRTVkdBdHRyaWJ1dGUoc3ZnOiBTVkdFbGVtZW50KTogU1ZHRWxlbWVudCB7XG4gICAgdGhpcy5fcmVuZGVyZXIuc2V0QXR0cmlidXRlKHN2ZywgJ3dpZHRoJywgJzFlbScpO1xuICAgIHRoaXMuX3JlbmRlcmVyLnNldEF0dHJpYnV0ZShzdmcsICdoZWlnaHQnLCAnMWVtJyk7XG4gICAgcmV0dXJuIHN2ZztcbiAgfVxuXG4gIHByb3RlY3RlZCBfY29sb3JpemVTVkdJY29uKFxuICAgIHN2ZzogU1ZHRWxlbWVudCxcbiAgICB0d290b25lOiBib29sZWFuLFxuICAgIHByaTogc3RyaW5nLFxuICAgIHNlYzogc3RyaW5nXG4gICk6IFNWR0VsZW1lbnQge1xuICAgIGlmICh0d290b25lKSB7XG4gICAgICBjb25zdCBjaGlsZHJlbiA9IHN2Zy5jaGlsZE5vZGVzO1xuICAgICAgY29uc3QgbGVuZ3RoID0gY2hpbGRyZW4ubGVuZ3RoO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBjaGlsZDogSFRNTEVsZW1lbnQgPSBjaGlsZHJlbltpXSBhcyBIVE1MRWxlbWVudDtcbiAgICAgICAgaWYgKGNoaWxkLmdldEF0dHJpYnV0ZSgnZmlsbCcpID09PSAnc2Vjb25kYXJ5Q29sb3InKSB7XG4gICAgICAgICAgdGhpcy5fcmVuZGVyZXIuc2V0QXR0cmlidXRlKGNoaWxkLCAnZmlsbCcsIHNlYyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5fcmVuZGVyZXIuc2V0QXR0cmlidXRlKGNoaWxkLCAnZmlsbCcsIHByaSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5fcmVuZGVyZXIuc2V0QXR0cmlidXRlKHN2ZywgJ2ZpbGwnLCAnY3VycmVudENvbG9yJyk7XG4gICAgcmV0dXJuIHN2ZztcbiAgfVxufVxuIl19
|