ngx-firebase-cms
Version:
Angular Content Management System using Google Firebase (Authentication, Storage & Firestore)
368 lines • 34.3 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { Component, ElementRef, ViewChild, HostListener } from '@angular/core';
import { UnsubscriptionService } from '../../service/unsubscription.service';
import { FormBuilder, FormControl, Validators } from '@angular/forms';
import { AngularFireAuth } from '@angular/fire/auth';
import { NzMessageService, NzNotificationService } from 'ng-zorro-antd';
import { AngularFireStorage } from '@angular/fire/storage';
import { AuthService } from '../../service/auth.service';
import { HelperService } from '../../service/helper.service';
import * as firebase from 'firebase/app';
import { of } from 'rxjs';
import { AngularFirestore } from '@angular/fire/firestore';
var ProfileComponent = /** @class */ (function () {
function ProfileComponent(unsubscription, afAuth, afs, message, storage, auth, fb, notification, helper) {
var _this = this;
this.unsubscription = unsubscription;
this.afAuth = afAuth;
this.afs = afs;
this.message = message;
this.storage = storage;
this.auth = auth;
this.fb = fb;
this.notification = notification;
this.helper = helper;
this.titlebar = {
title: "Profile",
description: "Edit your profile",
breadcrumbs: [
{
title: "Profile",
icon: 'team'
}
]
};
this.showChangePassword = false;
this.isLoading = false;
this.showDisplayName = false;
this.profileURL = null;
this.beforeUpload = (/**
* @param {?} file
* @return {?}
*/
function (file) {
if (file['type'] != "image/jpeg") {
_this.message.error("File type should be JPEG");
return false;
}
else if (file['size'] / 1024 / 1024 > 1) {
_this.message.error("File size should be less than 1 Mb");
return false;
}
else {
return true;
}
});
this.uploadProfilePic = (/**
* @param {?} item
* @return {?}
*/
function (item) {
_this.message.success("File is uploading");
/** @type {?} */
var timestamp = new Date().valueOf();
/** @type {?} */
var filePath = "/profile/" + timestamp + ".jpeg";
/** @type {?} */
var file = item['file'];
/** @type {?} */
var task = _this.storage.upload(filePath, file)
.then((/**
* @param {?} res
* @return {?}
*/
function (res) {
return _this.storage.ref(filePath).getDownloadURL().toPromise();
}))
.then((/**
* @param {?} res
* @return {?}
*/
function (res) {
return _this.afs.collection("users").doc(_this.auth.uid).update({
"profileURL": res,
"uploadTime": firebase.firestore.FieldValue.serverTimestamp()
});
}))
.then((/**
* @param {?} res
* @return {?}
*/
function (res) {
_this.auth.log("changed profile pic " + timestamp + ".jpeg");
_this.message.success("File Uploaded");
})).catch((/**
* @param {?} err
* @return {?}
*/
function (err) {
_this.message.error(err);
}));
return of().subscribe((/**
* @param {?} event
* @return {?}
*/
function (event) {
if (event['percent'] != 100) {
item.onProgress(event, item.file);
}
else {
item.onSuccess(event['body'], item.file, event);
}
}), (/**
* @param {?} err
* @return {?}
*/
function (err) {
item.onError(err, item.file);
}));
});
}
/**
* @return {?}
*/
ProfileComponent.prototype.ngOnInit = /**
* @return {?}
*/
function () {
var _this = this;
this.sub = this.auth.user$.subscribe((/**
* @param {?} res
* @return {?}
*/
function (res) {
_this.profileURL = res.profileURL;
}), (/**
* @param {?} err
* @return {?}
*/
function (err) { }));
this.initForm();
};
/**
* @return {?}
*/
ProfileComponent.prototype.ngOnDestroy = /**
* @return {?}
*/
function () {
this.sub.unsubscribe();
};
/**
* @return {?}
*/
ProfileComponent.prototype.initForm = /**
* @return {?}
*/
function () {
this.passwordForm = this.fb.group({
"previousPassword": new FormControl({ value: "", disabled: false }, [Validators.required]),
"newPassword": new FormControl({ value: "", disabled: false }, [Validators.required]),
});
this.displayNameForm = this.fb.group({
"displayName": new FormControl({ "value": this.auth.displayName, disabled: false }, [Validators.required])
});
};
/**
* @return {?}
*/
ProfileComponent.prototype.changePassword = /**
* @return {?}
*/
function () {
var _this = this;
if (typeof this.passwordForm.value["newPassword"] == "string")
this.passwordForm.controls["newPassword"].setValue(this.passwordForm.value["newPassword"].trim());
if (this.passwordForm.valid && !this.isLoading) {
this.isLoading = true;
this.afAuth.auth.signInWithEmailAndPassword(this.auth.email, this.passwordForm.value['previousPassword']).then((/**
* @param {?} res
* @return {?}
*/
function (res) {
/** @type {?} */
var user = _this.afAuth.auth.currentUser;
return user.updatePassword(_this.passwordForm.value["newPassword"]);
}))
.then((/**
* @param {?} res
* @return {?}
*/
function (res) {
_this.auth.log(" updated the password");
_this.message.success("Change the password");
_this.showChangePassword = !_this.showChangePassword;
}))
.catch((/**
* @param {?} err
* @return {?}
*/
function (err) {
_this.message.error(err);
}));
}
else {
this.passwordForm.controls["newPassword"].markAsDirty();
}
};
/**
* @return {?}
*/
ProfileComponent.prototype.changeDisplayName = /**
* @return {?}
*/
function () {
var _this = this;
if (typeof this.displayNameForm.value["displayName"] == "string")
this.displayNameForm.controls["displayName"].setValue(this.displayNameForm.value["displayName"].trim());
if (this.displayNameForm.valid && !this.isLoading) {
this.isLoading = true;
this.afs.collection("users").doc(this.auth.uid).update({
"displayName": this.displayNameForm.value["displayName"],
"uploadTime": firebase.firestore.FieldValue.serverTimestamp()
}).then((/**
* @param {?} res
* @return {?}
*/
function (res) {
_this.isLoading = false;
_this.showDisplayName = !_this.showDisplayName;
}));
}
else {
this.displayNameForm.controls["displayName"].markAsDirty();
}
};
/**
* @return {?}
*/
ProfileComponent.prototype.getProfilePic = /**
* @return {?}
*/
function () {
return (this.profileURL) ? { 'background-image': 'url(\'' + this.profileURL + '\')' } : {};
};
/**
* @param {?} e
* @return {?}
*/
ProfileComponent.prototype.keyboardEvent = /**
* @param {?} e
* @return {?}
*/
function (e) {
if (this.showChangePassword && e.key == 'Escape') {
this.notification.blank("ESC", "Escape modal");
this.showChangePassword = false;
}
if (this.showDisplayName && e.key == 'Escape') {
this.notification.blank("ESC", "Escape modal");
this.showDisplayName = false;
}
if (this.showChangePassword) {
if (e.ctrlKey && e.key == 'Enter') {
this.notification.blank("⌃ ENTER", "Form Submission");
this.changePassword();
}
}
if (this.showDisplayName && e.ctrlKey && e.key == 'Enter') {
this.notification.blank("⌃ ENTER", "Form Submission");
this.changeDisplayName();
}
};
ProfileComponent.decorators = [
{ type: Component, args: [{
selector: 'aq-profile',
template: "<aq-title-bar [data]=\"titlebar\"></aq-title-bar>\n\n<div class=\"container\">\n <h3>{{ (auth.user$ | async)?.displayName }}</h3>\n <p>Email: {{ (auth.user$ | async)?.email }}</p>\n <p>Roles: {{ (auth.user$ | async)?.roles }}</p>\n <p>Created on: {{ (auth.user$ | async)?.createdTime.toDate() | date: 'medium' }}</p>\n <p>Last login: {{ auth.lastLogin | date: 'medium' }}</p>\n\n <button class=\"m-r-10\" nz-tooltip nzTitle=\"Change Password\" nz-button (click)=\"showChangePassword=true\">\n <i nz-icon type=\"security-scan\" theme=\"outline\"></i> Password\n </button>\n\n <button class=\"m-r-10\" nz-tooltip nzTitle=\"Change Display Name\" nz-button (click)=\"showDisplayName=true\">\n <i nz-icon type=\"font-colors\" theme=\"outline\"></i> Display Name\n </button>\n\n <nz-upload class=\"m-r-10\" [nzBeforeUpload]=\"beforeUpload\" [nzCustomRequest]=\"uploadProfilePic\"\n [nzShowUploadList]=\"false\">\n <button #uploadButton nz-tooltip nzTitle=\"Change Profile Image\" nz-button>\n <i nz-icon type=\"picture\" theme=\"outline\"></i> Profile Image\n </button>\n </nz-upload>\n</div>\n\n<nz-drawer nzWidth=\"100%\" [nzVisible]=\"showChangePassword\" nzTitle=\"Change Password\" (nzOnClose)=\"showChangePassword = !showChangePassword\">\n <form nz-form [formGroup]=\"passwordForm\" (ngSubmit)=\"changePassword()\">\n <nz-form-item>\n <nz-form-control>\n <label>Previous Password</label>\n <input type=\"password\" nz-input formControlName=\"previousPassword\" placeholder=\"Previous Password\"\n autocomplete=\"password\" autofocus>\n <nz-form-explain\n *ngIf=\"passwordForm.get('previousPassword').dirty && passwordForm.get('previousPassword').errors\">\n Please input\n your previous password!</nz-form-explain>\n </nz-form-control>\n </nz-form-item>\n <nz-form-item>\n <nz-form-control>\n <label>New Password</label>\n <input type=\"password\" nz-input formControlName=\"newPassword\" placeholder=\"New Password\" autocomplete=\"password\" autofocus>\n <nz-form-explain\n *ngIf=\"passwordForm.get('newPassword').dirty && passwordForm.get('newPassword').errors\">Please input\n your new\n password!</nz-form-explain>\n </nz-form-control>\n </nz-form-item>\n </form>\n <div class=\"footer\">\n <button type=\"button\" (click)=\"changePassword()\" class=\"ant-btn ant-btn-primary\">Submit </button>\n <button type=\"button\" (click)=\"showChangePassword = !showChangePassword\" class=\"ant-btn\">Cancel </button>\n </div>\n</nz-drawer>\n\n<nz-drawer nzWidth=\"100%\" [nzVisible]=\"showDisplayName\" nzTitle=\"Change Display Name\" (nzOnClose)=\"showDisplayName = !showDisplayName\">\n <form nz-form [formGroup]=\"displayNameForm\" (ngSubmit)=\"changeDisplayName()\">\n <nz-form-item>\n <nz-form-control>\n <label>Your Display Name</label>\n <input type=\"text\" nz-input formControlName=\"displayName\" placeholder=\"Please enter your display name\"\n autocomplete=\"displayName\" autofocus>\n <nz-form-explain\n *ngIf=\"displayNameForm.get('displayName').dirty && displayNameForm.get('displayName').errors\">Please\n input\n your Display Name!</nz-form-explain>\n </nz-form-control>\n </nz-form-item>\n </form>\n <div class=\"footer\">\n <button type=\"button\" (click)=\"changeDisplayName()\" class=\"ant-btn ant-btn-primary\">Submit </button>\n <button type=\"button\" (click)=\"showDisplayName = !showDisplayName\" class=\"ant-btn\">Cancel </button>\n </div>\n</nz-drawer>\n",
styles: [".img-rounded{border-radius:50%;width:80%;position:relative}.img-rounded:hover{opacity:1}.footer{position:absolute;bottom:0;width:100%;border-top:1px solid #e8e8e8;padding:10px 16px;left:0;z-index:9999;background:#fff}.footer button{margin-left:10px}.m-r-10{margin-right:10px}.w-200{width:200px}.user-profile{width:200px;height:200px;background:0 0/cover #efefef;border-radius:50%}"]
}] }
];
/** @nocollapse */
ProfileComponent.ctorParameters = function () { return [
{ type: UnsubscriptionService },
{ type: AngularFireAuth },
{ type: AngularFirestore },
{ type: NzMessageService },
{ type: AngularFireStorage },
{ type: AuthService },
{ type: FormBuilder },
{ type: NzNotificationService },
{ type: HelperService }
]; };
ProfileComponent.propDecorators = {
uploadButton: [{ type: ViewChild, args: ['uploadButton',] }],
keyboardEvent: [{ type: HostListener, args: ['document:keydown', ['$event'],] }]
};
return ProfileComponent;
}());
export { ProfileComponent };
if (false) {
/** @type {?} */
ProfileComponent.prototype.uploadButton;
/** @type {?} */
ProfileComponent.prototype.titlebar;
/** @type {?} */
ProfileComponent.prototype.showChangePassword;
/** @type {?} */
ProfileComponent.prototype.passwordForm;
/** @type {?} */
ProfileComponent.prototype.displayNameForm;
/** @type {?} */
ProfileComponent.prototype.isLoading;
/** @type {?} */
ProfileComponent.prototype.showDisplayName;
/** @type {?} */
ProfileComponent.prototype.profileURL;
/** @type {?} */
ProfileComponent.prototype.sub;
/** @type {?} */
ProfileComponent.prototype.beforeUpload;
/** @type {?} */
ProfileComponent.prototype.uploadProfilePic;
/**
* @type {?}
* @private
*/
ProfileComponent.prototype.unsubscription;
/**
* @type {?}
* @private
*/
ProfileComponent.prototype.afAuth;
/**
* @type {?}
* @private
*/
ProfileComponent.prototype.afs;
/**
* @type {?}
* @private
*/
ProfileComponent.prototype.message;
/**
* @type {?}
* @private
*/
ProfileComponent.prototype.storage;
/** @type {?} */
ProfileComponent.prototype.auth;
/**
* @type {?}
* @private
*/
ProfileComponent.prototype.fb;
/**
* @type {?}
* @private
*/
ProfileComponent.prototype.notification;
/**
* @type {?}
* @private
*/
ProfileComponent.prototype.helper;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvZmlsZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9uZ3gtZmlyZWJhc2UtY21zLyIsInNvdXJjZXMiOlsibGliL2NvbXBvbmVudC9wcm9maWxlL3Byb2ZpbGUuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFVLFVBQVUsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRXZGLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLHNDQUFzQyxDQUFDO0FBQzdFLE9BQU8sRUFBYSxXQUFXLEVBQUUsV0FBVyxFQUFFLFVBQVUsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ2pGLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNyRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUscUJBQXFCLEVBQTZCLE1BQU0sZUFBZSxDQUFDO0FBQ25HLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQzNELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDN0QsT0FBTyxLQUFLLFFBQVEsTUFBTSxjQUFjLENBQUM7QUFFekMsT0FBTyxFQUFFLEVBQUUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMxQixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUczRDtJQTJCRSwwQkFDVSxjQUFxQyxFQUNyQyxNQUF1QixFQUN2QixHQUFxQixFQUNyQixPQUF5QixFQUN6QixPQUEyQixFQUM1QixJQUFpQixFQUNoQixFQUFlLEVBQ2YsWUFBbUMsRUFDbkMsTUFBcUI7UUFUL0IsaUJBVUs7UUFUSyxtQkFBYyxHQUFkLGNBQWMsQ0FBdUI7UUFDckMsV0FBTSxHQUFOLE1BQU0sQ0FBaUI7UUFDdkIsUUFBRyxHQUFILEdBQUcs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aXQsIEVsZW1lbnRSZWYsIFZpZXdDaGlsZCwgSG9zdExpc3RlbmVyIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBCcmVhZGNydW1iIH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlL2JyZWFkY3J1bWInO1xuaW1wb3J0IHsgVW5zdWJzY3JpcHRpb25TZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZS91bnN1YnNjcmlwdGlvbi5zZXJ2aWNlJztcbmltcG9ydCB7IEZvcm1Hcm91cCwgRm9ybUJ1aWxkZXIsIEZvcm1Db250cm9sLCBWYWxpZGF0b3JzIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgQW5ndWxhckZpcmVBdXRoIH0gZnJvbSAnQGFuZ3VsYXIvZmlyZS9hdXRoJztcbmltcG9ydCB7IE56TWVzc2FnZVNlcnZpY2UsIE56Tm90aWZpY2F0aW9uU2VydmljZSwgVXBsb2FkWEhSQXJncywgVXBsb2FkRmlsZSB9IGZyb20gJ25nLXpvcnJvLWFudGQnO1xuaW1wb3J0IHsgQW5ndWxhckZpcmVTdG9yYWdlIH0gZnJvbSAnQGFuZ3VsYXIvZmlyZS9zdG9yYWdlJztcbmltcG9ydCB7IEF1dGhTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZS9hdXRoLnNlcnZpY2UnO1xuaW1wb3J0IHsgSGVscGVyU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2UvaGVscGVyLnNlcnZpY2UnO1xuaW1wb3J0ICogYXMgZmlyZWJhc2UgZnJvbSAnZmlyZWJhc2UvYXBwJztcbmltcG9ydCB7IEh0dHBFdmVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7IG9mIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBBbmd1bGFyRmlyZXN0b3JlIH0gZnJvbSAnQGFuZ3VsYXIvZmlyZS9maXJlc3RvcmUnO1xuaW1wb3J0IHsgVGl0bGViYXIgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2UvdGl0bGViYXInO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhcS1wcm9maWxlJyxcbiAgdGVtcGxhdGVVcmw6ICcuL3Byb2ZpbGUuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9wcm9maWxlLmNvbXBvbmVudC5jc3MnXVxufSlcbmV4cG9ydCBjbGFzcyBQcm9maWxlQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgQFZpZXdDaGlsZCgndXBsb2FkQnV0dG9uJykgdXBsb2FkQnV0dG9uOiBFbGVtZW50UmVmXG5cbiAgdGl0bGViYXI6IFRpdGxlYmFyID0ge1xuICAgIHRpdGxlOiBcIlByb2ZpbGVcIixcbiAgICBkZXNjcmlwdGlvbjogXCJFZGl0IHlvdXIgcHJvZmlsZVwiLFxuICAgIGJyZWFkY3J1bWJzOiBbXG4gICAgICB7XG4gICAgICAgIHRpdGxlOiBcIlByb2ZpbGVcIixcbiAgICAgICAgaWNvbjogJ3RlYW0nXG4gICAgICB9XG4gICAgXVxuICB9XG5cbiAgc2hvd0NoYW5nZVBhc3N3b3JkID0gZmFsc2VcbiAgcGFzc3dvcmRGb3JtOiBGb3JtR3JvdXBcbiAgZGlzcGxheU5hbWVGb3JtOiBGb3JtR3JvdXBcbiAgaXNMb2FkaW5nID0gZmFsc2VcbiAgc2hvd0Rpc3BsYXlOYW1lID0gZmFsc2VcbiAgcHJvZmlsZVVSTCA9IG51bGxcbiAgc3ViXG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSB1bnN1YnNjcmlwdGlvbjogVW5zdWJzY3JpcHRpb25TZXJ2aWNlLFxuICAgIHByaXZhdGUgYWZBdXRoOiBBbmd1bGFyRmlyZUF1dGgsXG4gICAgcHJpdmF0ZSBhZnM6IEFuZ3VsYXJGaXJlc3RvcmUsXG4gICAgcHJpdmF0ZSBtZXNzYWdlOiBOek1lc3NhZ2VTZXJ2aWNlLFxuICAgIHByaXZhdGUgc3RvcmFnZTogQW5ndWxhckZpcmVTdG9yYWdlLFxuICAgIHB1YmxpYyBhdXRoOiBBdXRoU2VydmljZSxcbiAgICBwcml2YXRlIGZiOiBGb3JtQnVpbGRlcixcbiAgICBwcml2YXRlIG5vdGlmaWNhdGlvbjogTnpOb3RpZmljYXRpb25TZXJ2aWNlLFxuICAgIHByaXZhdGUgaGVscGVyOiBIZWxwZXJTZXJ2aWNlXG4gICkgeyB9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5zdWIgPSB0aGlzLmF1dGgudXNlciQuc3Vic2NyaWJlKHJlcyA9PiB7XG4gICAgICB0aGlzLnByb2ZpbGVVUkwgPSByZXMucHJvZmlsZVVSTFxuICAgIH0sIGVyciA9PiB7fSlcbiAgICB0aGlzLmluaXRGb3JtKClcbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMuc3ViLnVuc3Vic2NyaWJlKClcbiAgfVxuXG4gIGluaXRGb3JtKCkge1xuICAgIHRoaXMucGFzc3dvcmRGb3JtID0gdGhpcy5mYi5ncm91cCh7XG4gICAgICBcInByZXZpb3VzUGFzc3dvcmRcIjogbmV3IEZvcm1Db250cm9sKHsgdmFsdWU6IFwiXCIsIGRpc2FibGVkOiBmYWxzZSB9LCBbVmFsaWRhdG9ycy5yZXF1aXJlZF0pLFxuICAgICAgXCJuZXdQYXNzd29yZFwiOiBuZXcgRm9ybUNvbnRyb2woeyB2YWx1ZTogXCJcIiwgZGlzYWJsZWQ6IGZhbHNlIH0sIFtWYWxpZGF0b3JzLnJlcXVpcmVkXSksXG4gICAgfSlcbiAgICB0aGlzLmRpc3BsYXlOYW1lRm9ybSA9IHRoaXMuZmIuZ3JvdXAoe1xuICAgICAgXCJkaXNwbGF5TmFtZVwiOiBuZXcgRm9ybUNvbnRyb2woeyBcInZhbHVlXCI6IHRoaXMuYXV0aC5kaXNwbGF5TmFtZSwgZGlzYWJsZWQ6IGZhbHNlIH0sIFtWYWxpZGF0b3JzLnJlcXVpcmVkXSlcbiAgICB9KVxuICB9XG5cbiAgY2hhbmdlUGFzc3dvcmQoKSB7XG4gICAgaWYgKHR5cGVvZiB0aGlzLnBhc3N3b3JkRm9ybS52YWx1ZVtcIm5ld1Bhc3N3b3JkXCJdID09IFwic3RyaW5nXCIpIHRoaXMucGFzc3dvcmRGb3JtLmNvbnRyb2xzW1wibmV3UGFzc3dvcmRcIl0uc2V0VmFsdWUodGhpcy5wYXNzd29yZEZvcm0udmFsdWVbXCJuZXdQYXNzd29yZFwiXS50cmltKCkpXG4gICAgaWYgKHRoaXMucGFzc3dvcmRGb3JtLnZhbGlkICYmICF0aGlzLmlzTG9hZGluZykge1xuICAgICAgdGhpcy5pc0xvYWRpbmcgPSB0cnVlXG4gICAgICB0aGlzLmFmQXV0aC5hdXRoLnNpZ25JbldpdGhFbWFpbEFuZFBhc3N3b3JkKHRoaXMuYXV0aC5lbWFpbCwgdGhpcy5wYXNzd29yZEZvcm0udmFsdWVbJ3ByZXZpb3VzUGFzc3dvcmQnXSkudGhlbihyZXMgPT4ge1xuICAgICAgICBsZXQgdXNlciA9IHRoaXMuYWZBdXRoLmF1dGguY3VycmVudFVzZXJcbiAgICAgICAgcmV0dXJuIHVzZXIudXBkYXRlUGFzc3dvcmQodGhpcy5wYXNzd29yZEZvcm0udmFsdWVbXCJuZXdQYXNzd29yZFwiXSlcbiAgICAgIH0pXG4gICAgICAgIC50aGVuKHJlcyA9PiB7XG4gICAgICAgICAgdGhpcy5hdXRoLmxvZyhgIHVwZGF0ZWQgdGhlIHBhc3N3b3JkYClcbiAgICAgICAgICB0aGlzLm1lc3NhZ2Uuc3VjY2VzcyhgQ2hhbmdlIHRoZSBwYXNzd29yZGApXG4gICAgICAgICAgdGhpcy5zaG93Q2hhbmdlUGFzc3dvcmQgPSAhdGhpcy5zaG93Q2hhbmdlUGFzc3dvcmRcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVyciA9PiB7XG4gICAgICAgICAgdGhpcy5tZXNzYWdlLmVycm9yKGVycilcbiAgICAgICAgfSlcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5wYXNzd29yZEZvcm0uY29udHJvbHNbXCJuZXdQYXNzd29yZFwiXS5tYXJrQXNEaXJ0eSgpXG4gICAgfVxuICB9XG5cbiAgY2hhbmdlRGlzcGxheU5hbWUoKSB7XG4gICAgaWYgKHR5cGVvZiB0aGlzLmRpc3BsYXlOYW1lRm9ybS52YWx1ZVtcImRpc3BsYXlOYW1lXCJdID09IFwic3RyaW5nXCIpIHRoaXMuZGlzcGxheU5hbWVGb3JtLmNvbnRyb2xzW1wiZGlzcGxheU5hbWVcIl0uc2V0VmFsdWUodGhpcy5kaXNwbGF5TmFtZUZvcm0udmFsdWVbXCJkaXNwbGF5TmFtZVwiXS50cmltKCkpXG4gICAgaWYgKHRoaXMuZGlzcGxheU5hbWVGb3JtLnZhbGlkICYmICF0aGlzLmlzTG9hZGluZykge1xuICAgICAgdGhpcy5pc0xvYWRpbmcgPSB0cnVlXG4gICAgICB0aGlzLmFmcy5jb2xsZWN0aW9uKFwidXNlcnNcIikuZG9jKHRoaXMuYXV0aC51aWQpLnVwZGF0ZSh7XG4gICAgICAgIFwiZGlzcGxheU5hbWVcIjogdGhpcy5kaXNwbGF5TmFtZUZvcm0udmFsdWVbXCJkaXNwbGF5TmFtZVwiXSxcbiAgICAgICAgXCJ1cGxvYWRUaW1lXCI6IGZpcmViYXNlLmZpcmVzdG9yZS5GaWVsZFZhbHVlLnNlcnZlclRpbWVzdGFtcCgpXG4gICAgICB9KS50aGVuKHJlcyA9PiB7XG4gICAgICAgIHRoaXMuaXNMb2FkaW5nID0gZmFsc2VcbiAgICAgICAgdGhpcy5zaG93RGlzcGxheU5hbWUgPSAhdGhpcy5zaG93RGlzcGxheU5hbWVcbiAgICAgIH0pXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZGlzcGxheU5hbWVGb3JtLmNvbnRyb2xzW1wiZGlzcGxheU5hbWVcIl0ubWFya0FzRGlydHkoKVxuICAgIH1cbiAgfVxuXG4gIGJlZm9yZVVwbG9hZCA9IChmaWxlOiBVcGxvYWRGaWxlKTogYm9vbGVhbiA9PiB7XG4gICAgaWYgKGZpbGVbJ3R5cGUnXSAhPSBcImltYWdlL2pwZWdcIikge1xuICAgICAgdGhpcy5tZXNzYWdlLmVycm9yKFwiRmlsZSB0eXBlIHNob3VsZCBiZSBKUEVHXCIpXG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9IGVsc2UgaWYgKGZpbGVbJ3NpemUnXSAvIDEwMjQgLyAxMDI0ID4gMSkge1xuICAgICAgdGhpcy5tZXNzYWdlLmVycm9yKFwiRmlsZSBzaXplIHNob3VsZCBiZSBsZXNzIHRoYW4gMSBNYlwiKVxuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuICB9XG5cbiAgdXBsb2FkUHJvZmlsZVBpYyA9IChpdGVtOiBVcGxvYWRYSFJBcmdzKSA9PiB7XG4gICAgdGhpcy5tZXNzYWdlLnN1Y2Nlc3MoYEZpbGUgaXMgdXBsb2FkaW5nYClcbiAgICBsZXQgdGltZXN0YW1wID0gbmV3IERhdGUoKS52YWx1ZU9mKClcbiAgICBsZXQgZmlsZVBhdGggPSBgL3Byb2ZpbGUvJHt0aW1lc3RhbXB9LmpwZWdgXG4gICAgbGV0IGZpbGUgPSBpdGVtWydmaWxlJ11cbiAgICBjb25zdCB0YXNrID0gdGhpcy5zdG9yYWdlLnVwbG9hZChmaWxlUGF0aCwgZmlsZSlcbiAgICAgIC50aGVuKHJlcyA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0b3JhZ2UucmVmKGZpbGVQYXRoKS5nZXREb3dubG9hZFVSTCgpLnRvUHJvbWlzZSgpXG4gICAgICB9KVxuICAgICAgLnRoZW4ocmVzID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYWZzLmNvbGxlY3Rpb24oXCJ1c2Vyc1wiKS5kb2ModGhpcy5hdXRoLnVpZCkudXBkYXRlKHtcbiAgICAgICAgICBcInByb2ZpbGVVUkxcIjogcmVzLFxuICAgICAgICAgIFwidXBsb2FkVGltZVwiOiBmaXJlYmFzZS5maXJlc3RvcmUuRmllbGRWYWx1ZS5zZXJ2ZXJUaW1lc3RhbXAoKVxuICAgICAgICB9KVxuICAgICAgfSlcbiAgICAgIC50aGVuKHJlcyA9PiB7XG4gICAgICAgIHRoaXMuYXV0aC5sb2coYGNoYW5nZWQgcHJvZmlsZSBwaWMgJHt0aW1lc3RhbXB9LmpwZWdgKVxuICAgICAgICB0aGlzLm1lc3NhZ2Uuc3VjY2VzcyhcIkZpbGUgVXBsb2FkZWRcIilcbiAgICAgIH0pLmNhdGNoKGVyciA9PiB7XG4gICAgICAgIHRoaXMubWVzc2FnZS5lcnJvcihlcnIpXG4gICAgICB9KVxuICAgIHJldHVybiBvZigpLnN1YnNjcmliZSgoZXZlbnQ6IEh0dHBFdmVudDx7fT4pID0+IHtcbiAgICAgIGlmIChldmVudFsncGVyY2VudCddICE9IDEwMCkge1xuICAgICAgICBpdGVtLm9uUHJvZ3Jlc3MoZXZlbnQsIGl0ZW0uZmlsZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpdGVtLm9uU3VjY2VzcyhldmVudFsnYm9keSddLCBpdGVtLmZpbGUsIGV2ZW50KTtcbiAgICAgIH1cbiAgICB9LCAoZXJyKSA9PiB7XG4gICAgICBpdGVtLm9uRXJyb3IoZXJyLCBpdGVtLmZpbGUpO1xuICAgIH0pXG4gIH1cblxuICBnZXRQcm9maWxlUGljKCkge1xuICAgIHJldHVybiAodGhpcy5wcm9maWxlVVJMKSA/IHsgJ2JhY2tncm91bmQtaW1hZ2UnOiAndXJsKFxcJycgKyB0aGlzLnByb2ZpbGVVUkwgKyAnXFwnKScgfSA6IHt9XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDprZXlkb3duJywgWyckZXZlbnQnXSlcbiAga2V5Ym9hcmRFdmVudChlOiBLZXlib2FyZEV2ZW50KSB7XG4gICAgaWYgKHRoaXMuc2hvd0NoYW5nZVBhc3N3b3JkICYmIGUua2V5ID09ICdFc2NhcGUnKSB7XG4gICAgICB0aGlzLm5vdGlmaWNhdGlvbi5ibGFuayhcIkVTQ1wiLCBcIkVzY2FwZSBtb2RhbFwiKVxuICAgICAgdGhpcy5zaG93Q2hhbmdlUGFzc3dvcmQgPSBmYWxzZVxuICAgIH1cblxuICAgIGlmICh0aGlzLnNob3dEaXNwbGF5TmFtZSAmJiBlLmtleSA9PSAnRXNjYXBlJykge1xuICAgICAgdGhpcy5ub3RpZmljYXRpb24uYmxhbmsoXCJFU0NcIiwgXCJFc2NhcGUgbW9kYWxcIilcbiAgICAgIHRoaXMuc2hvd0Rpc3BsYXlOYW1lID0gZmFsc2VcbiAgICB9XG5cbiAgICBpZiAodGhpcy5zaG93Q2hhbmdlUGFzc3dvcmQpIHtcbiAgICAgIGlmIChlLmN0cmxLZXkgJiYgZS5rZXkgPT0gJ0VudGVyJykge1xuICAgICAgICB0aGlzLm5vdGlmaWNhdGlvbi5ibGFuayhcIuKMgyBFTlRFUlwiLCBcIkZvcm0gU3VibWlzc2lvblwiKVxuICAgICAgICB0aGlzLmNoYW5nZVBhc3N3b3JkKClcbiAgICAgIH1cbiAgICB9XG4gICAgXG4gICAgaWYgKHRoaXMuc2hvd0Rpc3BsYXlOYW1lICYmIGUuY3RybEtleSAmJiBlLmtleSA9PSAnRW50ZXInKSB7XG4gICAgICB0aGlzLm5vdGlmaWNhdGlvbi5ibGFuayhcIuKMgyBFTlRFUlwiLCBcIkZvcm0gU3VibWlzc2lvblwiKVxuICAgICAgdGhpcy5jaGFuZ2VEaXNwbGF5TmFtZSgpXG4gICAgfVxuICB9XG59XG4iXX0=