ngx-avatar
Version:
A universal avatar component for Angular applications that fetches / generates avatar based on the information you have about the user.
250 lines • 27.6 kB
JavaScript
import { Component, Input, Output, EventEmitter } from '@angular/core';
import { AsyncSource } from './sources/async-source';
import { SourceFactory } from './sources/source.factory';
import { AvatarService } from './avatar.service';
import { AvatarSource } from './sources/avatar-source.enum';
import { takeWhile, map } from 'rxjs/operators';
/**
* Universal avatar component that
* generates avatar from different sources
*
* export
* class AvatarComponent
* implements {OnChanges}
*/
export class AvatarComponent {
constructor(sourceFactory, avatarService) {
this.sourceFactory = sourceFactory;
this.avatarService = avatarService;
this.round = true;
this.size = 50;
this.textSizeRatio = 3;
this.fgColor = '#FFF';
this.style = {};
this.cornerRadius = 0;
this.initialsSize = 0;
this.clickOnAvatar = new EventEmitter();
this.isAlive = true;
this.avatarSrc = null;
this.avatarText = null;
this.avatarStyle = {};
this.hostStyle = {};
this.currentIndex = -1;
this.sources = [];
}
onAvatarClicked() {
this.clickOnAvatar.emit(this.sources[this.currentIndex]);
}
/**
* Detect inputs change
*
* param {{ [propKey: string]: SimpleChange }} changes
*
* memberof AvatarComponent
*/
ngOnChanges(changes) {
for (const propName in changes) {
if (this.avatarService.isSource(propName)) {
const sourceType = AvatarSource[propName.toUpperCase()];
const currentValue = changes[propName].currentValue;
if (currentValue && typeof currentValue === 'string') {
this.addSource(sourceType, currentValue);
}
else {
this.removeSource(sourceType);
}
}
}
// reinitialize the avatar component when a source property value has changed
// the fallback system must be re-invoked with the new values.
this.initializeAvatar();
}
/**
* Fetch avatar source
*
* memberOf AvatarComponent
*/
fetchAvatarSource() {
const previousSource = this.sources[this.currentIndex];
if (previousSource) {
this.avatarService.markSourceAsFailed(previousSource);
}
const source = this.findNextSource();
if (!source) {
return;
}
if (this.avatarService.isTextAvatar(source.sourceType)) {
this.buildTextAvatar(source);
this.avatarSrc = null;
}
else {
this.buildImageAvatar(source);
}
}
findNextSource() {
while (++this.currentIndex < this.sources.length) {
const source = this.sources[this.currentIndex];
if (source && !this.avatarService.sourceHasFailedBefore(source)) {
return source;
}
}
return null;
}
ngOnDestroy() {
this.isAlive = false;
}
/**
* Initialize the avatar component and its fallback system
*/
initializeAvatar() {
this.currentIndex = -1;
if (this.sources.length > 0) {
this.sortAvatarSources();
this.fetchAvatarSource();
this.hostStyle = {
width: this.size + 'px',
height: this.size + 'px'
};
}
}
sortAvatarSources() {
this.sources.sort((source1, source2) => this.avatarService.compareSources(source1.sourceType, source2.sourceType));
}
buildTextAvatar(avatarSource) {
this.avatarText = avatarSource.getAvatar(+this.initialsSize);
this.avatarStyle = this.getInitialsStyle(avatarSource.sourceId);
}
buildImageAvatar(avatarSource) {
this.avatarStyle = this.getImageStyle();
if (avatarSource instanceof AsyncSource) {
this.fetchAndProcessAsyncAvatar(avatarSource);
}
else {
this.avatarSrc = avatarSource.getAvatar(+this.size);
}
}
/**
*
* returns initials style
*
* memberOf AvatarComponent
*/
getInitialsStyle(avatarValue) {
return Object.assign({ textAlign: 'center', borderRadius: this.round ? '100%' : this.cornerRadius + 'px', border: this.borderColor ? '1px solid ' + this.borderColor : '', textTransform: 'uppercase', color: this.fgColor, backgroundColor: this.bgColor
? this.bgColor
: this.avatarService.getRandomColor(avatarValue), font: Math.floor(+this.size / this.textSizeRatio) +
'px Helvetica, Arial, sans-serif', lineHeight: this.size + 'px' }, this.style);
}
/**
*
* returns image style
*
* memberOf AvatarComponent
*/
getImageStyle() {
return Object.assign({ maxWidth: '100%', borderRadius: this.round ? '50%' : this.cornerRadius + 'px', border: this.borderColor ? '1px solid ' + this.borderColor : '', width: this.size + 'px', height: this.size + 'px' }, this.style);
}
/**
* Fetch avatar image asynchronously.
*
* param {Source} source represents avatar source
* memberof AvatarComponent
*/
fetchAndProcessAsyncAvatar(source) {
if (this.avatarService.sourceHasFailedBefore(source)) {
return;
}
this.avatarService
.fetchAvatar(source.getAvatar(+this.size))
.pipe(takeWhile(() => this.isAlive), map(response => source.processResponse(response, +this.size)))
.subscribe(avatarSrc => (this.avatarSrc = avatarSrc), err => {
this.fetchAvatarSource();
});
}
/**
* Add avatar source
*
* param sourceType avatar source type e.g facebook,twitter, etc.
* param sourceValue source value e.g facebookId value, etc.
*/
addSource(sourceType, sourceValue) {
const source = this.sources.find(s => s.sourceType === sourceType);
if (source) {
source.sourceId = sourceValue;
}
else {
this.sources.push(this.sourceFactory.newInstance(sourceType, sourceValue));
}
}
/**
* Remove avatar source
*
* param sourceType avatar source type e.g facebook,twitter, etc.
*/
removeSource(sourceType) {
this.sources = this.sources.filter(source => source.sourceType !== sourceType);
}
}
AvatarComponent.decorators = [
{ type: Component, args: [{
// tslint:disable-next-line:component-selector
selector: 'ngx-avatar',
template: `
<div
(click)="onAvatarClicked()"
class="avatar-container"
[ngStyle]="hostStyle"
>
<img
*ngIf="avatarSrc; else textAvatar"
[src]="avatarSrc"
[width]="size"
[height]="size"
[ngStyle]="avatarStyle"
(error)="fetchAvatarSource()"
class="avatar-content"
loading="lazy"
/>
<ng-template #textAvatar>
<div *ngIf="avatarText" class="avatar-content" [ngStyle]="avatarStyle">
{{ avatarText }}
</div>
</ng-template>
</div>
`,
styles: [`
:host {
border-radius: 50%;
}
`]
},] }
];
AvatarComponent.ctorParameters = () => [
{ type: SourceFactory },
{ type: AvatarService }
];
AvatarComponent.propDecorators = {
round: [{ type: Input }],
size: [{ type: Input }],
textSizeRatio: [{ type: Input }],
bgColor: [{ type: Input }],
fgColor: [{ type: Input }],
borderColor: [{ type: Input }],
style: [{ type: Input }],
cornerRadius: [{ type: Input }],
facebook: [{ type: Input, args: ['facebookId',] }],
twitter: [{ type: Input, args: ['twitterId',] }],
google: [{ type: Input, args: ['googleId',] }],
instagram: [{ type: Input, args: ['instagramId',] }],
vkontakte: [{ type: Input, args: ['vkontakteId',] }],
skype: [{ type: Input, args: ['skypeId',] }],
gravatar: [{ type: Input, args: ['gravatarId',] }],
github: [{ type: Input, args: ['githubId',] }],
custom: [{ type: Input, args: ['src',] }],
initials: [{ type: Input, args: ['name',] }],
value: [{ type: Input }],
placeholder: [{ type: Input }],
initialsSize: [{ type: Input }],
clickOnAvatar: [{ type: Output }]
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXZhdGFyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1hdmF0YXIvc3JjL2xpYi9hdmF0YXIuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxTQUFTLEVBQ1QsS0FBSyxFQUNMLE1BQU0sRUFDTixZQUFZLEVBSWIsTUFBTSxlQUFlLENBQUM7QUFHdkIsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3JELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDakQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQzVELE9BQU8sRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFJaEQ7Ozs7Ozs7R0FPRztBQW9DSCxNQUFNLE9BQU8sZUFBZTtJQXdEMUIsWUFDUyxhQUE0QixFQUMzQixhQUE0QjtRQUQ3QixrQkFBYSxHQUFiLGFBQWEsQ0FBZTtRQUMzQixrQkFBYSxHQUFiLGFBQWEsQ0FBZTtRQXhEL0IsVUFBSyxHQUFHLElBQUksQ0FBQztRQUViLFNBQUksR0FBb0IsRUFBRSxDQUFDO1FBRTNCLGtCQUFhLEdBQUcsQ0FBQyxDQUFDO1FBSWxCLFlBQU8sR0FBRyxNQUFNLENBQUM7UUFJakIsVUFBSyxHQUFVLEVBQUUsQ0FBQztRQUVsQixpQkFBWSxHQUFvQixDQUFDLENBQUM7UUEwQmxDLGlCQUFZLEdBQW9CLENBQUMsQ0FBQztRQUdsQyxrQkFBYSxHQUF5QixJQUFJLFlBQVksRUFBVSxDQUFDO1FBRWpFLFlBQU8sR0FBRyxJQUFJLENBQUM7UUFDZixjQUFTLEdBQWtCLElBQUksQ0FBQztRQUNoQyxlQUFVLEdBQWtCLElBQUksQ0FBQztRQUNqQyxnQkFBVyxHQUFVLEVBQUUs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O29CQWtEbkIsS0FBSzttQkFFTCxLQUFLOzRCQUVMLEtBQUs7c0JBRUwsS0FBSztzQkFFTCxLQUFLOzBCQUVMLEtBQUs7b0JBRUwsS0FBSzsyQkFFTCxLQUFLO3VCQUVMLEtBQUssU0FBQyxZQUFZO3NCQUVsQixLQUFLLFNBQUMsV0FBVztxQkFFakIsS0FBSyxTQUFDLFVBQVU7d0JBRWhCLEtBQUssU0FBQyxhQUFhO3dCQUVuQixLQUFLLFNBQUMsYUFBYTtvQkFFbkIsS0FBSyxTQUFDLFNBQVM7dUJBRWYsS0FBSyxTQUFDLFlBQVk7cUJBRWxCLEtBQUssU0FBQyxVQUFVO3FCQUVoQixLQUFLLFNBQUMsS0FBSzt1QkFFWCxLQUFLLFNBQUMsTUFBTTtvQkFFWixLQUFLOzBCQUVMLEtBQUs7MkJBRUwsS0FBSzs0QkFHTCxNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBJbnB1dCxcbiAgT3V0cHV0LFxuICBFdmVudEVtaXR0ZXIsXG4gIE9uQ2hhbmdlcyxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgT25EZXN0cm95XG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQgeyBTb3VyY2UgfSBmcm9tICcuL3NvdXJjZXMvc291cmNlJztcbmltcG9ydCB7IEFzeW5jU291cmNlIH0gZnJvbSAnLi9zb3VyY2VzL2FzeW5jLXNvdXJjZSc7XG5pbXBvcnQgeyBTb3VyY2VGYWN0b3J5IH0gZnJvbSAnLi9zb3VyY2VzL3NvdXJjZS5mYWN0b3J5JztcbmltcG9ydCB7IEF2YXRhclNlcnZpY2UgfSBmcm9tICcuL2F2YXRhci5zZXJ2aWNlJztcbmltcG9ydCB7IEF2YXRhclNvdXJjZSB9IGZyb20gJy4vc291cmNlcy9hdmF0YXItc291cmNlLmVudW0nO1xuaW1wb3J0IHsgdGFrZVdoaWxlLCBtYXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbnR5cGUgU3R5bGUgPSBQYXJ0aWFsPENTU1N0eWxlRGVjbGFyYXRpb24+O1xuXG4vKipcbiAqIFVuaXZlcnNhbCBhdmF0YXIgY29tcG9uZW50IHRoYXRcbiAqIGdlbmVyYXRlcyBhdmF0YXIgZnJvbSBkaWZmZXJlbnQgc291cmNlc1xuICpcbiAqIGV4cG9ydFxuICogY2xhc3MgQXZhdGFyQ29tcG9uZW50XG4gKiBpbXBsZW1lbnRzIHtPbkNoYW5nZXN9XG4gKi9cblxuQENvbXBvbmVudCh7XG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpjb21wb25lbnQtc2VsZWN0b3JcbiAgc2VsZWN0b3I6ICduZ3gtYXZhdGFyJyxcbiAgc3R5bGVzOiBbXG4gICAgYFxuICAgICAgOmhvc3Qge1xuICAgICAgICBib3JkZXItcmFkaXVzOiA1MCU7XG4gICAgICB9XG4gICAgYFxuICBdLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXZcbiAgICAgIChjbGljayk9XCJvbkF2YXRhckNsaWNrZWQoKVwiXG4gICAgICBjbGFzcz1cImF2YXRhci1jb250YWluZXJcIlxuICAgICAgW25nU3R5bGVdPVwiaG9zdFN0eWxlXCJcbiAgICA+XG4gICAgICA8aW1nXG4gICAgICAgICpuZ0lmPVwiYXZhdGFyU3JjOyBlbHNlIHRleHRBdmF0YXJcIlxuICAgICAgICBbc3JjXT1cImF2YXRhclNyY1wiXG4gICAgICAgIFt3aWR0aF09XCJzaXplXCJcbiAgICAgICAgW2hlaWdodF09XCJzaXplXCJcbiAgICAgICAgW25nU3R5bGVdPVwiYXZhdGFyU3R5bGVcIlxuICAgICAgICAoZXJyb3IpPVwiZmV0Y2hBdmF0YXJTb3VyY2UoKVwiXG4gICAgICAgIGNsYXNzPVwiYXZhdGFyLWNvbnRlbnRcIlxuICAgICAgICBsb2FkaW5nPVwibGF6eVwiXG4gICAgICAvPlxuICAgICAgPG5nLXRlbXBsYXRlICN0ZXh0QXZhdGFyPlxuICAgICAgICA8ZGl2ICpuZ0lmPVwiYXZhdGFyVGV4dFwiIGNsYXNzPVwiYXZhdGFyLWNvbnRlbnRcIiBbbmdTdHlsZV09XCJhdmF0YXJTdHlsZVwiPlxuICAgICAgICAgIHt7IGF2YXRhclRleHQgfX1cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L25nLXRlbXBsYXRlPlxuICAgIDwvZGl2PlxuICBgXG59KVxuZXhwb3J0IGNsYXNzIEF2YXRhckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uQ2hhbmdlcywgT25EZXN0cm95IHtcbiAgQElucHV0KClcbiAgcHVibGljIHJvdW5kID0gdHJ1ZTtcbiAgQElucHV0KClcbiAgcHVibGljIHNpemU6IHN0cmluZyB8IG51bWJlciA9IDUwO1xuICBASW5wdXQoKVxuICBwdWJsaWMgdGV4dFNpemVSYXRpbyA9IDM7XG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBiZ0NvbG9yOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBmZ0NvbG9yID0gJyNGRkYnO1xuICBASW5wdXQoKVxuICBwdWJsaWMgYm9yZGVyQ29sb3I6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgQElucHV0KClcbiAgcHVibGljIHN0eWxlOiBTdHlsZSA9IHt9O1xuICBASW5wdXQoKVxuICBwdWJsaWMgY29ybmVyUmFkaXVzOiBzdHJpbmcgfCBudW1iZXIgPSAwO1xuICBASW5wdXQoJ2ZhY2Vib29rSWQnKVxuICBwdWJsaWMgZmFjZWJvb2s/OiBzdHJpbmcgfCBudWxsO1xuICBASW5wdXQoJ3R3aXR0ZXJJZCcpXG4gIHB1YmxpYyB0d2l0dGVyPzogc3RyaW5nIHwgbnVsbDtcbiAgQElucHV0KCdnb29nbGVJZCcpXG4gIHB1YmxpYyBnb29nbGU/OiBzdHJpbmcgfCBudWxsO1xuICBASW5wdXQoJ2luc3RhZ3JhbUlkJylcbiAgcHVibGljIGluc3RhZ3JhbT86IHN0cmluZyB8IG51bGw7XG4gIEBJbnB1dCgndmtvbnRha3RlSWQnKVxuICBwdWJsaWMgdmtvbnRha3RlPzogc3RyaW5nIHwgbnVsbDtcbiAgQElucHV0KCdza3lwZUlkJylcbiAgcHVibGljIHNreXBlPzogc3RyaW5nIHwgbnVsbDtcbiAgQElucHV0KCdncmF2YXRhcklkJylcbiAgcHVibGljIGdyYXZhdGFyPzogc3RyaW5nIHwgbnVsbDtcbiAgQElucHV0KCdnaXRodWJJZCcpXG4gIHB1YmxpYyBnaXRodWI/OiBzdHJpbmcgfCBudWxsO1xuICBASW5wdXQoJ3NyYycpXG4gIHB1YmxpYyBjdXN0b20/OiBzdHJpbmcgfCBudWxsO1xuICBASW5wdXQoJ25hbWUnKVxuICBwdWJsaWMgaW5pdGlhbHM/OiBzdHJpbmcgfCBudWxsO1xuICBASW5wdXQoKVxuICBwdWJsaWMgdmFsdWU/OiBzdHJpbmcgfCBudWxsO1xuICBASW5wdXQoKVxuICBwdWJsaWMgcGxhY2Vob2xkZXI/OiBzdHJpbmc7XG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBpbml0aWFsc1NpemU6IHN0cmluZyB8IG51bWJlciA9IDA7XG5cbiAgQE91dHB1dCgpXG4gIHB1YmxpYyBjbGlja09uQXZhdGFyOiBFdmVudEVtaXR0ZXI8U291cmNlPiA9IG5ldyBFdmVudEVtaXR0ZXI8U291cmNlPigpO1xuXG4gIHB1YmxpYyBpc0FsaXZlID0gdHJ1ZTtcbiAgcHVibGljIGF2YXRhclNyYzogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gIHB1YmxpYyBhdmF0YXJUZXh0OiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgcHVibGljIGF2YXRhclN0eWxlOiBTdHlsZSA9IHt9O1xuICBwdWJsaWMgaG9zdFN0eWxlOiBTdHlsZSA9IHt9O1xuXG4gIHByaXZhdGUgY3VycmVudEluZGV4ID0gLTE7XG4gIHByaXZhdGUgc291cmNlczogU291cmNlW10gPSBbXTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgc291cmNlRmFjdG9yeTogU291cmNlRmFjdG9yeSxcbiAgICBwcml2YXRlIGF2YXRhclNlcnZpY2U6IEF2YXRhclNlcnZpY2VcbiAgKSB7fVxuXG4gIHB1YmxpYyBvbkF2YXRhckNsaWNrZWQoKTogdm9pZCB7XG4gICAgdGhpcy5jbGlja09uQXZhdGFyLmVtaXQodGhpcy5zb3VyY2VzW3RoaXMuY3VycmVudEluZGV4XSk7XG4gIH1cblxuICAvKipcbiAgICogRGV0ZWN0IGlucHV0cyBjaGFuZ2VcbiAgICpcbiAgICogcGFyYW0ge3sgW3Byb3BLZXk6IHN0cmluZ106IFNpbXBsZUNoYW5nZSB9fSBjaGFuZ2VzXG4gICAqXG4gICAqIG1lbWJlcm9mIEF2YXRhckNvbXBvbmVudFxuICAgKi9cbiAgcHVibGljIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBmb3IgKGNvbnN0IHByb3BOYW1lIGluIGNoYW5nZXMpIHtcbiAgICAgIGlmICh0aGlzLmF2YXRhclNlcnZpY2UuaXNTb3VyY2UocHJvcE5hbWUpKSB7XG4gICAgICAgIGNvbnN0IHNvdXJjZVR5cGU6IEF2YXRhclNvdXJjZSA9IEF2YXRhclNvdXJjZVtwcm9wTmFtZS50b1VwcGVyQ2FzZSgpIGFzIGtleW9mIHR5cGVvZiBBdmF0YXJTb3VyY2VdIDtcbiAgICAgICAgY29uc3QgY3VycmVudFZhbHVlID0gY2hhbmdlc1twcm9wTmFtZV0uY3VycmVudFZhbHVlO1xuICAgICAgICBpZiAoY3VycmVudFZhbHVlICYmIHR5cGVvZiBjdXJyZW50VmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgdGhpcy5hZGRTb3VyY2Uoc291cmNlVHlwZSwgY3VycmVudFZhbHVlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnJlbW92ZVNvdXJjZShzb3VyY2VUeXBlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICAvLyByZWluaXRpYWxpemUgdGhlIGF2YXRhciBjb21wb25lbnQgd2hlbiBhIHNvdXJjZSBwcm9wZXJ0eSB2YWx1ZSBoYXMgY2hhbmdlZFxuICAgIC8vIHRoZSBmYWxsYmFjayBzeXN0ZW0gbXVzdCBiZSByZS1pbnZva2VkIHdpdGggdGhlIG5ldyB2YWx1ZXMuXG4gICAgdGhpcy5pbml0aWFsaXplQXZhdGFyKCk7XG4gIH1cblxuICAvKipcbiAgICogRmV0Y2ggYXZhdGFyIHNvdXJjZVxuICAgKlxuICAgKiBtZW1iZXJPZiBBdmF0YXJDb21wb25lbnRcbiAgICovXG4gIHB1YmxpYyBmZXRjaEF2YXRhclNvdXJjZSgpOiB2b2lkIHtcbiAgICBjb25zdCBwcmV2aW91c1NvdXJjZSA9IHRoaXMuc291cmNlc1t0aGlzLmN1cnJlbnRJbmRleF07XG4gICAgaWYgKHByZXZpb3VzU291cmNlKSB7XG4gICAgICB0aGlzLmF2YXRhclNlcnZpY2UubWFya1NvdXJjZUFzRmFpbGVkKHByZXZpb3VzU291cmNlKTtcbiAgICB9XG5cbiAgICBjb25zdCBzb3VyY2UgPSB0aGlzLmZpbmROZXh0U291cmNlKCk7XG4gICAgaWYgKCFzb3VyY2UpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5hdmF0YXJTZXJ2aWNlLmlzVGV4dEF2YXRhcihzb3VyY2Uuc291cmNlVHlwZSkpIHtcbiAgICAgIHRoaXMuYnVpbGRUZXh0QXZhdGFyKHNvdXJjZSk7XG4gICAgICB0aGlzLmF2YXRhclNyYyA9IG51bGw7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYnVpbGRJbWFnZUF2YXRhcihzb3VyY2UpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZmluZE5leHRTb3VyY2UoKTogU291cmNlIHwgbnVsbCB7XG4gICAgd2hpbGUgKCsrdGhpcy5jdXJyZW50SW5kZXggPCB0aGlzLnNvdXJjZXMubGVuZ3RoKSB7XG4gICAgICBjb25zdCBzb3VyY2UgPSB0aGlzLnNvdXJjZXNbdGhpcy5jdXJyZW50SW5kZXhdO1xuICAgICAgaWYgKHNvdXJjZSAmJiAhdGhpcy5hdmF0YXJTZXJ2aWNlLnNvdXJjZUhhc0ZhaWxlZEJlZm9yZShzb3VyY2UpKSB7XG4gICAgICAgIHJldHVybiBzb3VyY2U7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBwdWJsaWMgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5pc0FsaXZlID0gZmFsc2U7XG4gIH1cblxuICAvKipcbiAgICogSW5pdGlhbGl6ZSB0aGUgYXZhdGFyIGNvbXBvbmVudCBhbmQgaXRzIGZhbGxiYWNrIHN5c3RlbVxuICAgKi9cbiAgcHJpdmF0ZSBpbml0aWFsaXplQXZhdGFyKCk6IHZvaWQge1xuICAgIHRoaXMuY3VycmVudEluZGV4ID0gLTE7XG4gICAgaWYgKHRoaXMuc291cmNlcy5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLnNvcnRBdmF0YXJTb3VyY2VzKCk7XG4gICAgICB0aGlzLmZldGNoQXZhdGFyU291cmNlKCk7XG4gICAgICB0aGlzLmhvc3RTdHlsZSA9IHtcbiAgICAgICAgd2lkdGg6IHRoaXMuc2l6ZSArICdweCcsXG4gICAgICAgIGhlaWdodDogdGhpcy5zaXplICsgJ3B4J1xuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHNvcnRBdmF0YXJTb3VyY2VzKCk6IHZvaWQge1xuICAgIHRoaXMuc291cmNlcy5zb3J0KChzb3VyY2UxLCBzb3VyY2UyKSA9PlxuICAgICAgdGhpcy5hdmF0YXJTZXJ2aWNlLmNvbXBhcmVTb3VyY2VzKHNvdXJjZTEuc291cmNlVHlwZSwgc291cmNlMi5zb3VyY2VUeXBlKVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGJ1aWxkVGV4dEF2YXRhcihhdmF0YXJTb3VyY2U6IFNvdXJjZSk6IHZvaWQge1xuICAgIHRoaXMuYXZhdGFyVGV4dCA9IGF2YXRhclNvdXJjZS5nZXRBdmF0YXIoK3RoaXMuaW5pdGlhbHNTaXplKTtcbiAgICB0aGlzLmF2YXRhclN0eWxlID0gdGhpcy5nZXRJbml0aWFsc1N0eWxlKGF2YXRhclNvdXJjZS5zb3VyY2VJZCk7XG4gIH1cblxuICBwcml2YXRlIGJ1aWxkSW1hZ2VBdmF0YXIoYXZhdGFyU291cmNlOiBTb3VyY2UpOiB2b2lkIHtcbiAgICB0aGlzLmF2YXRhclN0eWxlID0gdGhpcy5nZXRJbWFnZVN0eWxlKCk7XG4gICAgaWYgKGF2YXRhclNvdXJjZSBpbnN0YW5jZW9mIEFzeW5jU291cmNlKSB7XG4gICAgICB0aGlzLmZldGNoQW5kUHJvY2Vzc0FzeW5jQXZhdGFyKGF2YXRhclNvdXJjZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYXZhdGFyU3JjID0gYXZhdGFyU291cmNlLmdldEF2YXRhcigrdGhpcy5zaXplKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICpcbiAgICogcmV0dXJucyBpbml0aWFscyBzdHlsZVxuICAgKlxuICAgKiBtZW1iZXJPZiBBdmF0YXJDb21wb25lbnRcbiAgICovXG4gIHByaXZhdGUgZ2V0SW5pdGlhbHNTdHlsZShhdmF0YXJWYWx1ZTogc3RyaW5nKTogU3R5bGUge1xuICAgIHJldHVybiB7XG4gICAgICB0ZXh0QWxpZ246ICdjZW50ZXInLFxuICAgICAgYm9yZGVyUmFkaXVzOiB0aGlzLnJvdW5kID8gJzEwMCUnIDogdGhpcy5jb3JuZXJSYWRpdXMgKyAncHgnLFxuICAgICAgYm9yZGVyOiB0aGlzLmJvcmRlckNvbG9yID8gJzFweCBzb2xpZCAnICsgdGhpcy5ib3JkZXJDb2xvciA6ICcnLFxuICAgICAgdGV4dFRyYW5zZm9ybTogJ3VwcGVyY2FzZScsXG4gICAgICBjb2xvcjogdGhpcy5mZ0NvbG9yLFxuICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGlzLmJnQ29sb3JcbiAgICAgICAgPyB0aGlzLmJnQ29sb3JcbiAgICAgICAgOiB0aGlzLmF2YXRhclNlcnZpY2UuZ2V0UmFuZG9tQ29sb3IoYXZhdGFyVmFsdWUpLFxuICAgICAgZm9udDpcbiAgICAgICAgTWF0aC5mbG9vcigrdGhpcy5zaXplIC8gdGhpcy50ZXh0U2l6ZVJhdGlvKSArXG4gICAgICAgICdweCBIZWx2ZXRpY2EsIEFyaWFsLCBzYW5zLXNlcmlmJyxcbiAgICAgIGxpbmVIZWlnaHQ6IHRoaXMuc2l6ZSArICdweCcsXG4gICAgICAuLi50aGlzLnN0eWxlXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKlxuICAgKiByZXR1cm5zIGltYWdlIHN0eWxlXG4gICAqXG4gICAqIG1lbWJlck9mIEF2YXRhckNvbXBvbmVudFxuICAgKi9cbiAgcHJpdmF0ZSBnZXRJbWFnZVN0eWxlKCk6IFN0eWxlIHtcbiAgICByZXR1cm4ge1xuICAgICAgbWF4V2lkdGg6ICcxMDAlJyxcbiAgICAgIGJvcmRlclJhZGl1czogdGhpcy5yb3VuZCA/ICc1MCUnIDogdGhpcy5jb3JuZXJSYWRpdXMgKyAncHgnLFxuICAgICAgYm9yZGVyOiB0aGlzLmJvcmRlckNvbG9yID8gJzFweCBzb2xpZCAnICsgdGhpcy5ib3JkZXJDb2xvciA6ICcnLFxuICAgICAgd2lkdGg6IHRoaXMuc2l6ZSArICdweCcsXG4gICAgICBoZWlnaHQ6IHRoaXMuc2l6ZSArICdweCcsXG4gICAgICAuLi50aGlzLnN0eWxlLFxuICAgIH07XG4gIH1cbiAgLyoqXG4gICAqIEZldGNoIGF2YXRhciBpbWFnZSBhc3luY2hyb25vdXNseS5cbiAgICpcbiAgICogcGFyYW0ge1NvdXJjZX0gc291cmNlIHJlcHJlc2VudHMgYXZhdGFyIHNvdXJjZVxuICAgKiBtZW1iZXJvZiBBdmF0YXJDb21wb25lbnRcbiAgICovXG4gIHByaXZhdGUgZmV0Y2hBbmRQcm9jZXNzQXN5bmNBdmF0YXIoc291cmNlOiBBc3luY1NvdXJjZSk6IHZvaWQge1xuICAgIGlmICh0aGlzLmF2YXRhclNlcnZpY2Uuc291cmNlSGFzRmFpbGVkQmVmb3JlKHNvdXJjZSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmF2YXRhclNlcnZpY2VcbiAgICAgICAgLmZldGNoQXZhdGFyKHNvdXJjZS5nZXRBdmF0YXIoK3RoaXMuc2l6ZSkpXG4gICAgICAgIC5waXBlKFxuICAgICAgICAgICAgdGFrZVdoaWxlKCgpID0+IHRoaXMuaXNBbGl2ZSksXG4gICAgICAgICAgICBtYXAocmVzcG9uc2UgPT4gc291cmNlLnByb2Nlc3NSZXNwb25zZShyZXNwb25zZSwgK3RoaXMuc2l6ZSkpLFxuICAgICAgICApXG4gICAgICAgIC5zdWJzY3JpYmUoXG4gICAgICAgICAgICBhdmF0YXJTcmMgPT4gKHRoaXMuYXZhdGFyU3JjID0gYXZhdGFyU3JjKSxcbiAgICAgICAgICAgIGVyciA9PiB7XG4gICAgICAgICAgICAgIHRoaXMuZmV0Y2hBdmF0YXJTb3VyY2UoKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQWRkIGF2YXRhciBzb3VyY2VcbiAgICpcbiAgICogcGFyYW0gc291cmNlVHlwZSBhdmF0YXIgc291cmNlIHR5cGUgZS5nIGZhY2Vib29rLHR3aXR0ZXIsIGV0Yy5cbiAgICogcGFyYW0gc291cmNlVmFsdWUgIHNvdXJjZSB2YWx1ZSBlLmcgZmFjZWJvb2tJZCB2YWx1ZSwgZXRjLlxuICAgKi9cbiAgcHJpdmF0ZSBhZGRTb3VyY2Uoc291cmNlVHlwZTogQXZhdGFyU291cmNlLCBzb3VyY2VWYWx1ZTogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3Qgc291cmNlID0gdGhpcy5zb3VyY2VzLmZpbmQocyA9PiBzLnNvdXJjZVR5cGUgPT09IHNvdXJjZVR5cGUpO1xuICAgIGlmIChzb3VyY2UpIHtcbiAgICAgIHNvdXJjZS5zb3VyY2VJZCA9IHNvdXJjZVZhbHVlO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNvdXJjZXMucHVzaChcbiAgICAgICAgICB0aGlzLnNvdXJjZUZhY3RvcnkubmV3SW5zdGFuY2Uoc291cmNlVHlwZSwgc291cmNlVmFsdWUpLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlIGF2YXRhciBzb3VyY2VcbiAgICpcbiAgICogcGFyYW0gc291cmNlVHlwZSBhdmF0YXIgc291cmNlIHR5cGUgZS5nIGZhY2Vib29rLHR3aXR0ZXIsIGV0Yy5cbiAgICovXG4gIHByaXZhdGUgcmVtb3ZlU291cmNlKHNvdXJjZVR5cGU6IEF2YXRhclNvdXJjZSk6IHZvaWQge1xuICAgIHRoaXMuc291cmNlcyA9IHRoaXMuc291cmNlcy5maWx0ZXIoc291cmNlID0+IHNvdXJjZS5zb3VyY2VUeXBlICE9PSBzb3VyY2VUeXBlKTtcbiAgfVxufVxuIl19