UNPKG

ionic-image-loader-v5

Version:
381 lines 26.8 kB
/** * @fileoverview added by tsickle * Generated from: lib/ionic-image-loader.component.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { Component, ElementRef, EventEmitter, Input, Output, Renderer2 } from '@angular/core'; import { ImageLoaderConfigService } from './services/image-loader-config.service'; import { ImageLoaderService } from './services/image-loader.service'; /** @type {?} */ const propMap = { display: 'display', height: 'height', width: 'width', backgroundSize: 'background-size', backgroundRepeat: 'background-repeat', }; /** * @record */ export function ImageAttribute() { } if (false) { /** @type {?} */ ImageAttribute.prototype.element; /** @type {?} */ ImageAttribute.prototype.value; } export class IonicImageLoaderComponent { /** * @param {?} _element * @param {?} renderer * @param {?} imageLoader * @param {?} config */ constructor(_element, renderer, imageLoader, config) { this._element = _element; this.renderer = renderer; this.imageLoader = imageLoader; this.config = config; /** * Fallback URL to load when the image url fails to load or does not exist. */ this.fallbackUrl = this.config.fallbackUrl; /** * Whether to show a spinner while the image loads */ this.spinner = this.config.spinnerEnabled; /** * Whether to show the fallback image instead of a spinner while the image loads */ this.fallbackAsPlaceholder = this.config.fallbackAsPlaceholder; /** * Attributes to pass through to img tag if _useImg == true */ this.imgAttributes = []; /** * Enable/Disable caching */ this.cache = true; /** * Width of the image. This will be ignored if using useImg. */ this.width = this.config.width; /** * Height of the image. This will be ignored if using useImg. */ this.height = this.config.height; /** * Display type of the image. This will be ignored if using useImg. */ this.display = this.config.display; /** * Background size. This will be ignored if using useImg. */ this.backgroundSize = this.config.backgroundSize; /** * Background repeat. This will be ignored if using useImg. */ this.backgroundRepeat = this.config.backgroundRepeat; /** * Name of the spinner */ this.spinnerName = this.config.spinnerName; /** * Color of the spinner */ this.spinnerColor = this.config.spinnerColor; /** * Notify on image load.. */ this.load = new EventEmitter(); /** * Indicates if the image is still loading */ this.isLoading = true; this._useImg = this.config.useImg; } /** * Use <img> tag * @param {?} val * @return {?} */ set useImg(val) { this._useImg = val !== false; } /** * Convenience attribute to disable caching * @param {?} val * @return {?} */ set noCache(val) { this.cache = val !== false; } /** * @return {?} */ get src() { return this._src; } /** * The URL of the image to load. * @param {?} imageUrl * @return {?} */ set src(imageUrl) { this._src = this.processImageUrl(imageUrl); this.updateImage(this._src); } /** * @return {?} */ ngOnInit() { if (this.fallbackAsPlaceholder && this.fallbackUrl) { this.setImage(this.fallbackUrl, false); } if (!this.src) { // image url was not passed // this can happen when [src] is set to a variable that turned out to be undefined // one example could be a list of users with their profile pictures // in this case, it would be useful to use the fallback image instead // if fallbackUrl was used as placeholder we do not need to set it again if (!this.fallbackAsPlaceholder && this.fallbackUrl) { // we're not going to cache the fallback image since it should be locally saved this.setImage(this.fallbackUrl); } else { this.isLoading = false; } } } /** * @private * @param {?} imageUrl * @return {?} */ updateImage(imageUrl) { this.imageLoader .getImagePath(imageUrl) .then((/** * @param {?} url * @return {?} */ (url) => this.setImage(url))) .catch((/** * @param {?} error * @return {?} */ (error) => this.setImage(this.fallbackUrl || imageUrl))); } /** * Gets the image URL to be loaded and disables caching if necessary * @private * @param {?} imageUrl * @return {?} */ processImageUrl(imageUrl) { if (this.cache === false) { // need to disable caching if (imageUrl.indexOf('?') < 0) { // add ? if doesn't exists imageUrl += '?'; } else { imageUrl += '&'; } // append timestamp at the end to make URL unique imageUrl += 'cache_buster=' + Date.now(); } return imageUrl; } /** * Set the image to be displayed * @private * @param {?} imageUrl image src * @param {?=} stopLoading set to true to mark the image as loaded * @return {?} */ setImage(imageUrl, stopLoading = true) { this.isLoading = !stopLoading; if (this._useImg) { // Using <img> tag if (!this.element) { // create img element if we dont have one this.element = this.renderer.createElement('img'); this.renderer.appendChild(this._element.nativeElement, this.element); } // set it's src this.renderer.setAttribute(this.element, 'src', imageUrl); // if imgAttributes are defined, add them to our img element this.imgAttributes.forEach((/** * @param {?} attribute * @return {?} */ (attribute) => { this.renderer.setAttribute(this.element, attribute.element, attribute.value); })); if (this.fallbackUrl && !this.imageLoader.nativeAvailable) { this.renderer.listen(this.element, 'error', (/** * @return {?} */ () => this.renderer.setAttribute(this.element, 'src', this.fallbackUrl))); } } else { // Not using <img> tag this.element = this._element.nativeElement; for (const prop in propMap) { if (this[prop]) { this.renderer.setStyle(this.element, propMap[prop], this[prop]); } } this.renderer.setStyle(this.element, 'background-image', `url("${imageUrl || this.fallbackUrl}")`); } if (stopLoading) { this.load.emit(this); } } } IonicImageLoaderComponent.decorators = [ { type: Component, args: [{ selector: 'img-loader', template: ` <ion-spinner *ngIf="spinner && isLoading && !fallbackAsPlaceholder" [name]="spinnerName" [color]="spinnerColor" ></ion-spinner> <ng-content></ng-content> `, styles: ['ion-spinner { float: none; margin-left: auto; margin-right: auto; display: block; }'] }] } ]; /** @nocollapse */ IonicImageLoaderComponent.ctorParameters = () => [ { type: ElementRef }, { type: Renderer2 }, { type: ImageLoaderService }, { type: ImageLoaderConfigService } ]; IonicImageLoaderComponent.propDecorators = { fallbackUrl: [{ type: Input }], spinner: [{ type: Input }], fallbackAsPlaceholder: [{ type: Input }], imgAttributes: [{ type: Input }], cache: [{ type: Input }], width: [{ type: Input }], height: [{ type: Input }], display: [{ type: Input }], backgroundSize: [{ type: Input }], backgroundRepeat: [{ type: Input }], spinnerName: [{ type: Input }], spinnerColor: [{ type: Input }], load: [{ type: Output }], useImg: [{ type: Input }], noCache: [{ type: Input }], src: [{ type: Input }] }; if (false) { /** * Fallback URL to load when the image url fails to load or does not exist. * @type {?} */ IonicImageLoaderComponent.prototype.fallbackUrl; /** * Whether to show a spinner while the image loads * @type {?} */ IonicImageLoaderComponent.prototype.spinner; /** * Whether to show the fallback image instead of a spinner while the image loads * @type {?} */ IonicImageLoaderComponent.prototype.fallbackAsPlaceholder; /** * Attributes to pass through to img tag if _useImg == true * @type {?} */ IonicImageLoaderComponent.prototype.imgAttributes; /** * Enable/Disable caching * @type {?} */ IonicImageLoaderComponent.prototype.cache; /** * Width of the image. This will be ignored if using useImg. * @type {?} */ IonicImageLoaderComponent.prototype.width; /** * Height of the image. This will be ignored if using useImg. * @type {?} */ IonicImageLoaderComponent.prototype.height; /** * Display type of the image. This will be ignored if using useImg. * @type {?} */ IonicImageLoaderComponent.prototype.display; /** * Background size. This will be ignored if using useImg. * @type {?} */ IonicImageLoaderComponent.prototype.backgroundSize; /** * Background repeat. This will be ignored if using useImg. * @type {?} */ IonicImageLoaderComponent.prototype.backgroundRepeat; /** * Name of the spinner * @type {?} */ IonicImageLoaderComponent.prototype.spinnerName; /** * Color of the spinner * @type {?} */ IonicImageLoaderComponent.prototype.spinnerColor; /** * Notify on image load.. * @type {?} */ IonicImageLoaderComponent.prototype.load; /** * Indicates if the image is still loading * @type {?} */ IonicImageLoaderComponent.prototype.isLoading; /** @type {?} */ IonicImageLoaderComponent.prototype.element; /** * @type {?} * @private */ IonicImageLoaderComponent.prototype._useImg; /** * @type {?} * @private */ IonicImageLoaderComponent.prototype._src; /** * @type {?} * @private */ IonicImageLoaderComponent.prototype._element; /** * @type {?} * @private */ IonicImageLoaderComponent.prototype.renderer; /** * @type {?} * @private */ IonicImageLoaderComponent.prototype.imageLoader; /** * @type {?} * @private */ IonicImageLoaderComponent.prototype.config; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW9uaWMtaW1hZ2UtbG9hZGVyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL2lvbmljLWltYWdlLWxvYWRlci12NS8iLCJzb3VyY2VzIjpbImxpYi9pb25pYy1pbWFnZS1sb2FkZXIuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBVSxNQUFNLEVBQUUsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3RHLE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxNQUFNLHdDQUF3QyxDQUFDO0FBQ2xGLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGlDQUFpQyxDQUFDOztNQUUvRCxPQUFPLEdBQVE7SUFDbkIsT0FBTyxFQUFFLFNBQVM7SUFDbEIsTUFBTSxFQUFFLFFBQVE7SUFDaEIsS0FBSyxFQUFFLE9BQU87SUFDZCxjQUFjLEVBQUUsaUJBQWlCO0lBQ2pDLGdCQUFnQixFQUFFLG1CQUFtQjtDQUN0Qzs7OztBQUVELG9DQUdDOzs7SUFGQyxpQ0FBZ0I7O0lBQ2hCLCtCQUFjOztBQWlCaEIsTUFBTSxPQUFPLHlCQUF5Qjs7Ozs7OztJQTZEcEMsWUFDWSxRQUFvQixFQUNwQixRQUFtQixFQUNuQixXQUErQixFQUMvQixNQUFnQztRQUhoQyxhQUFRLEdBQVIsUUFBUSxDQUFZO1FBQ3BCLGFBQVEsR0FBUixRQUFRLENBQVc7UUFDbkIsZ0JBQVcsR0FBWCxXQUFXLENBQW9CO1FBQy9CLFdBQU0sR0FBTixNQUFNLENBQTBCOzs7O1FBN0RuQyxnQkFBVyxHQUFXLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDOzs7O1FBSTlDLFlBQU8sR0FBWSxJQUFJLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQzs7OztRQUs5QywwQkFBcUIsR0FBWSxJQUFJLENBQUMsTUFBTSxDQUFDLHFCQUFxQixDQUFDOzs7O1FBSW5FLGtCQUFhLEdBQXFCLEVBQUUs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Z0RBQXVEOzs7OztJQUl2RCw0Q0FBdUQ7Ozs7O0lBS3ZELDBEQUE0RTs7Ozs7SUFJNUUsa0RBQThDOzs7OztJQUk5QywwQ0FBc0I7Ozs7O0lBSXRCLDBDQUEyQzs7Ozs7SUFJM0MsMkNBQTZDOzs7OztJQUk3Qyw0Q0FBK0M7Ozs7O0lBSS9DLG1EQUE2RDs7Ozs7SUFJN0QscURBQWlFOzs7OztJQUlqRSxnREFBdUQ7Ozs7O0lBSXZELGlEQUF5RDs7Ozs7SUFJekQseUNBQzhGOzs7OztJQUk5Riw4Q0FBaUI7O0lBQ2pCLDRDQUFxQjs7Ozs7SUFVckIsNENBQThDOzs7OztJQWtCOUMseUNBQXFCOzs7OztJQXpCakIsNkNBQTRCOzs7OztJQUM1Qiw2Q0FBMkI7Ozs7O0lBQzNCLGdEQUF1Qzs7Ozs7SUFDdkMsMkNBQXdDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBFbGVtZW50UmVmLCBFdmVudEVtaXR0ZXIsIElucHV0LCBPbkluaXQsIE91dHB1dCwgUmVuZGVyZXIyIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBJbWFnZUxvYWRlckNvbmZpZ1NlcnZpY2UgfSBmcm9tICcuL3NlcnZpY2VzL2ltYWdlLWxvYWRlci1jb25maWcuc2VydmljZSc7XG5pbXBvcnQgeyBJbWFnZUxvYWRlclNlcnZpY2UgfSBmcm9tICcuL3NlcnZpY2VzL2ltYWdlLWxvYWRlci5zZXJ2aWNlJztcblxuY29uc3QgcHJvcE1hcDogYW55ID0ge1xuICBkaXNwbGF5OiAnZGlzcGxheScsXG4gIGhlaWdodDogJ2hlaWdodCcsXG4gIHdpZHRoOiAnd2lkdGgnLFxuICBiYWNrZ3JvdW5kU2l6ZTogJ2JhY2tncm91bmQtc2l6ZScsXG4gIGJhY2tncm91bmRSZXBlYXQ6ICdiYWNrZ3JvdW5kLXJlcGVhdCcsXG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIEltYWdlQXR0cmlidXRlIHtcbiAgZWxlbWVudDogc3RyaW5nO1xuICB2YWx1ZTogc3RyaW5nO1xufVxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdpbWctbG9hZGVyJyxcbiAgdGVtcGxhdGU6IGBcbiAgICA8aW9uLXNwaW5uZXJcbiAgICAgICAgKm5nSWY9XCJzcGlubmVyICYmIGlzTG9hZGluZyAmJiAhZmFsbGJhY2tBc1BsYWNlaG9sZGVyXCJcbiAgICAgICAgW25hbWVdPVwic3Bpbm5lck5hbWVcIlxuICAgICAgICBbY29sb3JdPVwic3Bpbm5lckNvbG9yXCJcbiAgICA+PC9pb24tc3Bpbm5lcj5cbiAgICA8bmctY29udGVudD48L25nLWNvbnRlbnQ+XG4gIGAsXG4gIHN0eWxlczogW1xuICAgICdpb24tc3Bpbm5lciB7IGZsb2F0OiBub25lOyBtYXJnaW4tbGVmdDogYXV0bzsgbWFyZ2luLXJpZ2h0OiBhdXRvOyBkaXNwbGF5OiBibG9jazsgfScsXG4gIF0sXG59KVxuZXhwb3J0IGNsYXNzIElvbmljSW1hZ2VMb2FkZXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICAvKipcbiAgICogRmFsbGJhY2sgVVJMIHRvIGxvYWQgd2hlbiB0aGUgaW1hZ2UgdXJsIGZhaWxzIHRvIGxvYWQgb3IgZG9lcyBub3QgZXhpc3QuXG4gICAqL1xuICBASW5wdXQoKSBmYWxsYmFja1VybDogc3RyaW5nID0gdGhpcy5jb25maWcuZmFsbGJhY2tVcmw7XG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIHNob3cgYSBzcGlubmVyIHdoaWxlIHRoZSBpbWFnZSBsb2Fkc1xuICAgKi9cbiAgQElucHV0KCkgc3Bpbm5lcjogYm9vbGVhbiA9IHRoaXMuY29uZmlnLnNwaW5uZXJFbmFibGVkO1xuICAvKipcbiAgICogV2hldGhlciB0byBzaG93IHRoZSBmYWxsYmFjayBpbWFnZSBpbnN0ZWFkIG9mIGEgc3Bpbm5lciB3aGlsZSB0aGUgaW1hZ2UgbG9hZHNcbiAgICovXG5cbiAgQElucHV0KCkgZmFsbGJhY2tBc1BsYWNlaG9sZGVyOiBib29sZWFuID0gdGhpcy5jb25maWcuZmFsbGJhY2tBc1BsYWNlaG9sZGVyO1xuICAvKipcbiAgICogQXR0cmlidXRlcyB0byBwYXNzIHRocm91Z2ggdG8gaW1nIHRhZyBpZiBfdXNlSW1nID09IHRydWVcbiAgICovXG4gIEBJbnB1dCgpIGltZ0F0dHJpYnV0ZXM6IEltYWdlQXR0cmlidXRlW10gPSBbXTtcbiAgLyoqXG4gICAqIEVuYWJsZS9EaXNhYmxlIGNhY2hpbmdcbiAgICovXG4gIEBJbnB1dCgpIGNhY2hlID0gdHJ1ZTtcbiAgLyoqXG4gICAqIFdpZHRoIG9mIHRoZSBpbWFnZS4gVGhpcyB3aWxsIGJlIGlnbm9yZWQgaWYgdXNpbmcgdXNlSW1nLlxuICAgKi9cbiAgQElucHV0KCkgd2lkdGg6IHN0cmluZyA9IHRoaXMuY29uZmlnLndpZHRoO1xuICAvKipcbiAgICogSGVpZ2h0IG9mIHRoZSBpbWFnZS4gVGhpcyB3aWxsIGJlIGlnbm9yZWQgaWYgdXNpbmcgdXNlSW1nLlxuICAgKi9cbiAgQElucHV0KCkgaGVpZ2h0OiBzdHJpbmcgPSB0aGlzLmNvbmZpZy5oZWlnaHQ7XG4gIC8qKlxuICAgKiBEaXNwbGF5IHR5cGUgb2YgdGhlIGltYWdlLiBUaGlzIHdpbGwgYmUgaWdub3JlZCBpZiB1c2luZyB1c2VJbWcuXG4gICAqL1xuICBASW5wdXQoKSBkaXNwbGF5OiBzdHJpbmcgPSB0aGlzLmNvbmZpZy5kaXNwbGF5O1xuICAvKipcbiAgICogQmFja2dyb3VuZCBzaXplLiBUaGlzIHdpbGwgYmUgaWdub3JlZCBpZiB1c2luZyB1c2VJbWcuXG4gICAqL1xuICBASW5wdXQoKSBiYWNrZ3JvdW5kU2l6ZTogc3RyaW5nID0gdGhpcy5jb25maWcuYmFja2dyb3VuZFNpemU7XG4gIC8qKlxuICAgKiBCYWNrZ3JvdW5kIHJlcGVhdC4gVGhpcyB3aWxsIGJlIGlnbm9yZWQgaWYgdXNpbmcgdXNlSW1nLlxuICAgKi9cbiAgQElucHV0KCkgYmFja2dyb3VuZFJlcGVhdDogc3RyaW5nID0gdGhpcy5jb25maWcuYmFja2dyb3VuZFJlcGVhdDtcbiAgLyoqXG4gICAqIE5hbWUgb2YgdGhlIHNwaW5uZXJcbiAgICovXG4gIEBJbnB1dCgpIHNwaW5uZXJOYW1lOiBzdHJpbmcgPSB0aGlzLmNvbmZpZy5zcGlubmVyTmFtZTtcbiAgLyoqXG4gICAqIENvbG9yIG9mIHRoZSBzcGlubmVyXG4gICAqL1xuICBASW5wdXQoKSBzcGlubmVyQ29sb3I6IHN0cmluZyA9IHRoaXMuY29uZmlnLnNwaW5uZXJDb2xvcjtcbiAgLyoqXG4gICAqIE5vdGlmeSBvbiBpbWFnZSBsb2FkLi5cbiAgICovXG4gIEBPdXRwdXQoKVxuICBsb2FkOiBFdmVudEVtaXR0ZXI8SW9uaWNJbWFnZUxvYWRlckNvbXBvbmVudD4gPSBuZXcgRXZlbnRFbWl0dGVyPElvbmljSW1hZ2VMb2FkZXJDb21wb25lbnQ+KCk7XG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgaWYgdGhlIGltYWdlIGlzIHN0aWxsIGxvYWRpbmdcbiAgICovXG4gIGlzTG9hZGluZyA9IHRydWU7XG4gIGVsZW1lbnQ6IEhUTUxFbGVtZW50O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgICAgcHJpdmF0ZSBfZWxlbWVudDogRWxlbWVudFJlZixcbiAgICAgIHByaXZhdGUgcmVuZGVyZXI6IFJlbmRlcmVyMixcbiAgICAgIHByaXZhdGUgaW1hZ2VMb2FkZXI6IEltYWdlTG9hZGVyU2VydmljZSxcbiAgICAgIHByaXZhdGUgY29uZmlnOiBJbWFnZUxvYWRlckNvbmZpZ1NlcnZpY2UsXG4gICkge1xuICB9XG5cbiAgcHJpdmF0ZSBfdXNlSW1nOiBib29sZWFuID0gdGhpcy5jb25maWcudXNlSW1nO1xuXG4gIC8qKlxuICAgKiBVc2UgPGltZz4gdGFnXG4gICAqL1xuICBASW5wdXQoKVxuICBzZXQgdXNlSW1nKHZhbDogYm9vbGVhbikge1xuICAgIHRoaXMuX3VzZUltZyA9IHZhbCAhPT0gZmFsc2U7XG4gIH1cblxuICAvKipcbiAgICogQ29udmVuaWVuY2UgYXR0cmlidXRlIHRvIGRpc2FibGUgY2FjaGluZ1xuICAgKi9cbiAgQElucHV0KClcbiAgc2V0IG5vQ2FjaGUodmFsOiBib29sZWFuKSB7XG4gICAgdGhpcy5jYWNoZSA9IHZhbCAhPT0gZmFsc2U7XG4gIH1cblxuICBwcml2YXRlIF9zcmM6IHN0cmluZztcblxuICBnZXQgc3JjKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuX3NyYztcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgVVJMIG9mIHRoZSBpbWFnZSB0byBsb2FkLlxuICAgKi9cbiAgQElucHV0KClcbiAgc2V0IHNyYyhpbWFnZVVybDogc3RyaW5nKSB7XG4gICAgdGhpcy5fc3JjID0gdGhpcy5wcm9jZXNzSW1hZ2VVcmwoaW1hZ2VVcmwpO1xuICAgIHRoaXMudXBkYXRlSW1hZ2UodGhpcy5fc3JjKTtcbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmZhbGxiYWNrQXNQbGFjZWhvbGRlciAmJiB0aGlzLmZhbGxiYWNrVXJsKSB7XG4gICAgICB0aGlzLnNldEltYWdlKHRoaXMuZmFsbGJhY2tVcmwsIGZhbHNlKTtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuc3JjKSB7XG4gICAgICAvLyBpbWFnZSB1cmwgd2FzIG5vdCBwYXNzZWRcbiAgICAgIC8vIHRoaXMgY2FuIGhhcHBlbiB3aGVuIFtzcmNdIGlzIHNldCB0byBhIHZhcmlhYmxlIHRoYXQgdHVybmVkIG91dCB0byBiZSB1bmRlZmluZWRcbiAgICAgIC8vIG9uZSBleGFtcGxlIGNvdWxkIGJlIGEgbGlzdCBvZiB1c2VycyB3aXRoIHRoZWlyIHByb2ZpbGUgcGljdHVyZXNcbiAgICAgIC8vIGluIHRoaXMgY2FzZSwgaXQgd291bGQgYmUgdXNlZnVsIHRvIHVzZSB0aGUgZmFsbGJhY2sgaW1hZ2UgaW5zdGVhZFxuICAgICAgLy8gaWYgZmFsbGJhY2tVcmwgd2FzIHVzZWQgYXMgcGxhY2Vob2xkZXIgd2UgZG8gbm90IG5lZWQgdG8gc2V0IGl0IGFnYWluXG4gICAgICBpZiAoIXRoaXMuZmFsbGJhY2tBc1BsYWNlaG9sZGVyICYmIHRoaXMuZmFsbGJhY2tVcmwpIHtcbiAgICAgICAgLy8gd2UncmUgbm90IGdvaW5nIHRvIGNhY2hlIHRoZSBmYWxsYmFjayBpbWFnZSBzaW5jZSBpdCBzaG91bGQgYmUgbG9jYWxseSBzYXZlZFxuICAgICAgICB0aGlzLnNldEltYWdlKHRoaXMuZmFsbGJhY2tVcmwpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5pc0xvYWRpbmcgPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZUltYWdlKGltYWdlVXJsOiBzdHJpbmcpIHtcbiAgICB0aGlzLmltYWdlTG9hZGVyXG4gICAgICAgIC5nZXRJbWFnZVBhdGgoaW1hZ2VVcmwpXG4gICAgICAgIC50aGVuKCh1cmw6IHN0cmluZykgPT4gdGhpcy5zZXRJbWFnZSh1cmwpKVxuICAgICAgICAuY2F0Y2goKGVycm9yOiBhbnkpID0+IHRoaXMuc2V0SW1hZ2UodGhpcy5mYWxsYmFja1VybCB8fCBpbWFnZVVybCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIGltYWdlIFVSTCB0byBiZSBsb2FkZWQgYW5kIGRpc2FibGVzIGNhY2hpbmcgaWYgbmVjZXNzYXJ5XG4gICAqL1xuICBwcml2YXRlIHByb2Nlc3NJbWFnZVVybChpbWFnZVVybDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBpZiAodGhpcy5jYWNoZSA9PT0gZmFsc2UpIHtcbiAgICAgIC8vIG5lZWQgdG8gZGlzYWJsZSBjYWNoaW5nXG5cbiAgICAgIGlmIChpbWFnZVVybC5pbmRleE9mKCc/JykgPCAwKSB7XG4gICAgICAgIC8vIGFkZCA/IGlmIGRvZXNuJ3QgZXhpc3RzXG4gICAgICAgIGltYWdlVXJsICs9ICc/JztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGltYWdlVXJsICs9ICcmJztcbiAgICAgIH1cbiAgICAgIC8vIGFwcGVuZCB0aW1lc3RhbXAgYXQgdGhlIGVuZCB0byBtYWtlIFVSTCB1bmlxdWVcbiAgICAgIGltYWdlVXJsICs9ICdjYWNoZV9idXN0ZXI9JyArIERhdGUubm93KCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGltYWdlVXJsO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldCB0aGUgaW1hZ2UgdG8gYmUgZGlzcGxheWVkXG4gICAqIEBwYXJhbSBpbWFnZVVybCBpbWFnZSBzcmNcbiAgICogQHBhcmFtIHN0b3BMb2FkaW5nIHNldCB0byB0cnVlIHRvIG1hcmsgdGhlIGltYWdlIGFzIGxvYWRlZFxuICAgKi9cbiAgcHJpdmF0ZSBzZXRJbWFnZShpbWFnZVVybDogc3RyaW5nLCBzdG9wTG9hZGluZzogYm9vbGVhbiA9IHRydWUpOiB2b2lkIHtcbiAgICB0aGlzLmlzTG9hZGluZyA9ICFzdG9wTG9hZGluZztcblxuICAgIGlmICh0aGlzLl91c2VJbWcpIHtcbiAgICAgIC8vIFVzaW5nIDxpbWc+IHRhZ1xuICAgICAgaWYgKCF0aGlzLmVsZW1lbnQpIHtcbiAgICAgICAgLy8gY3JlYXRlIGltZyBlbGVtZW50IGlmIHdlIGRvbnQgaGF2ZSBvbmVcbiAgICAgICAgdGhpcy5lbGVtZW50ID0gdGhpcy5yZW5kZXJlci5jcmVhdGVFbGVtZW50KCdpbWcnKTtcbiAgICAgICAgdGhpcy5yZW5kZXJlci5hcHBlbmRDaGlsZCh0aGlzLl9lbGVtZW50Lm5hdGl2ZUVsZW1lbnQsIHRoaXMuZWxlbWVudCk7XG4gICAgICB9XG5cbiAgICAgIC8vIHNldCBpdCdzIHNyY1xuICAgICAgdGhpcy5yZW5kZXJlci5zZXRBdHRyaWJ1dGUodGhpcy5lbGVtZW50LCAnc3JjJywgaW1hZ2VVcmwpO1xuXG4gICAgICAvLyBpZiBpbWdBdHRyaWJ1dGVzIGFyZSBkZWZpbmVkLCBhZGQgdGhlbSB0byBvdXIgaW1nIGVsZW1lbnRcbiAgICAgIHRoaXMuaW1nQXR0cmlidXRlcy5mb3JFYWNoKChhdHRyaWJ1dGUpID0+IHtcbiAgICAgICAgdGhpcy5yZW5kZXJlci5zZXRBdHRyaWJ1dGUodGhpcy5lbGVtZW50LCBhdHRyaWJ1dGUuZWxlbWVudCwgYXR0cmlidXRlLnZhbHVlKTtcbiAgICAgIH0pO1xuICAgICAgaWYgKHRoaXMuZmFsbGJhY2tVcmwgJiYgIXRoaXMuaW1hZ2VMb2FkZXIubmF0aXZlQXZhaWxhYmxlKSB7XG4gICAgICAgIHRoaXMucmVuZGVyZXIubGlzdGVuKHRoaXMuZWxlbWVudCwgJ2Vycm9yJywgKCkgPT5cbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2V0QXR0cmlidXRlKHRoaXMuZWxlbWVudCwgJ3NyYycsIHRoaXMuZmFsbGJhY2tVcmwpLFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBOb3QgdXNpbmcgPGltZz4gdGFnXG5cbiAgICAgIHRoaXMuZWxlbWVudCA9IHRoaXMuX2VsZW1lbnQubmF0aXZlRWxlbWVudDtcblxuICAgICAgZm9yIChjb25zdCBwcm9wIGluIHByb3BNYXApIHtcbiAgICAgICAgaWYgKHRoaXNbcHJvcF0pIHtcbiAgICAgICAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKHRoaXMuZWxlbWVudCwgcHJvcE1hcFtwcm9wXSwgdGhpc1twcm9wXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUoXG4gICAgICAgICAgdGhpcy5lbGVtZW50LFxuICAgICAgICAgICdiYWNrZ3JvdW5kLWltYWdlJyxcbiAgICAgICAgICBgdXJsKFwiJHtpbWFnZVVybCB8fCB0aGlzLmZhbGxiYWNrVXJsfVwiKWAsXG4gICAgICApO1xuICAgIH1cbiAgICBpZiAoc3RvcExvYWRpbmcpIHtcbiAgICAgIHRoaXMubG9hZC5lbWl0KHRoaXMpO1xuICAgIH1cbiAgfVxufVxuIl19