ngx-firebase-cms
Version:
Angular Content Management System using Google Firebase (Authentication, Storage & Firestore)
374 lines • 38.4 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { Component, EventEmitter, Output, ViewChild, ElementRef, Renderer2, Inject } from '@angular/core';
import { EditorService } from '../../service/editor.service';
import { DOCUMENT } from '@angular/common';
import { NzMessageService } from 'ng-zorro-antd';
import { AngularFireStorage } from '@angular/fire/storage';
export class EditorToolbarComponent {
/**
* @param {?} storage
* @param {?} message
* @param {?} _renderer
* @param {?} editorService
* @param {?} _document
*/
constructor(storage, message, _renderer, editorService, _document) {
this.storage = storage;
this.message = message;
this._renderer = _renderer;
this.editorService = editorService;
this._document = _document;
this.id = '';
this.htmlMode = false;
this.showToolbar = true;
this.block = 'default';
this.fontId = 0;
this.fontSize = '5';
this.customClassId = -1;
this.tagMap = {
BLOCKQUOTE: "indent",
A: "link"
};
this.select = ["H1", "H2", "H3", "H4", "H5", "H6", "P", "PRE", "DIV"];
this.buttons = ["bold", "italic", "underline", "strikeThrough", "subscript", "superscript", "justifyLeft", "justifyCenter", "justifyRight", "justifyFull", "indent", "outdent", "insertUnorderedList", "insertOrderedList", "link"];
this.execute = new EventEmitter();
}
/**
* @return {?}
*/
ngOnInit() {
}
/**
* @param {?} command
* @return {?}
*/
triggerCommand(command) {
this.execute.emit(command);
}
/**
* @return {?}
*/
triggerButtons() {
if (!this.showToolbar) {
return;
}
this.buttons.forEach((/**
* @param {?} e
* @return {?}
*/
e => {
/** @type {?} */
const result = this._document.queryCommandState(e);
/** @type {?} */
const elementById = this._document.getElementById(e + '-' + this.id);
if (result) {
this._renderer.addClass(elementById, "active");
}
else {
this._renderer.removeClass(elementById, "active");
}
}));
}
/**
* @param {?} nodes
* @return {?}
*/
triggerBlocks(nodes) {
if (!this.showToolbar) {
return;
}
/** @type {?} */
let found = false;
this.select.forEach((/**
* @param {?} y
* @return {?}
*/
y => {
/** @type {?} */
const node = nodes.find((/**
* @param {?} x
* @return {?}
*/
x => x.nodeName === y));
if (node !== undefined && y === node.nodeName) {
if (found === false) {
this.block = node.nodeName.toLowerCase();
found = true;
}
}
else if (found === false) {
this.block = 'default';
}
}));
found = false;
if (this.fonts) {
this.fonts.forEach((/**
* @param {?} y
* @param {?} index
* @return {?}
*/
(y, index) => {
/** @type {?} */
const node = nodes.find((/**
* @param {?} x
* @return {?}
*/
x => {
if (x instanceof HTMLFontElement) {
return x.face === y.name;
}
}));
if (node !== undefined) {
if (found === false) {
this.fontId = index;
found = true;
}
}
else if (found === false) {
this.fontId = this.defaultFontId;
}
}));
}
found = false;
if (this.customClasses) {
this.customClasses.forEach((/**
* @param {?} y
* @param {?} index
* @return {?}
*/
(y, index) => {
/** @type {?} */
const node = nodes.find((/**
* @param {?} x
* @return {?}
*/
x => {
if (x instanceof Element) {
return x.className === y.class;
}
}));
if (node !== undefined) {
if (found === false) {
this.customClassId = index;
found = true;
}
}
else if (found === false) {
this.customClassId = -1;
}
}));
}
Object.keys(this.tagMap).map((/**
* @param {?} e
* @return {?}
*/
e => {
/** @type {?} */
const elementById = this._document.getElementById(this.tagMap[e] + '-' + this.id);
/** @type {?} */
const node = nodes.find((/**
* @param {?} x
* @return {?}
*/
x => x.nodeName === e));
if (node !== undefined && e === node.nodeName) {
this._renderer.addClass(elementById, "active");
}
else {
this._renderer.removeClass(elementById, "active");
}
}));
}
/**
* @return {?}
*/
insertUrl() {
/** @type {?} */
const url = prompt("Insert URL link", 'http:\/\/');
if (url && url !== '' && url !== 'http://') {
this.editorService.createLink(url);
}
}
/**
* @param {?} color
* @param {?} where
* @return {?}
*/
insertColor(color, where) {
this.editorService.insertColor(color, where);
this.execute.emit("");
}
/**
* @param {?} fontId
* @return {?}
*/
setFontName(fontId) {
this.editorService.setFontName(this.fonts[fontId].name);
this.execute.emit("");
}
/**
* @param {?} fontSize
* @return {?}
*/
setFontSize(fontSize) {
this.editorService.setFontSize(fontSize);
this.execute.emit("");
}
/**
* @param {?} m
* @return {?}
*/
setEditorMode(m) {
/** @type {?} */
const toggleEditorModeButton = this._document.getElementById("toggleEditorMode" + '-' + this.id);
if (m) {
this._renderer.addClass(toggleEditorModeButton, "active");
}
else {
this._renderer.removeClass(toggleEditorModeButton, "active");
}
this.htmlMode = m;
}
/**
* @param {?} event
* @return {?}
*/
onFileChanged(event) {
/** @type {?} */
const file = event.target.files[0];
console.log(file.type);
if (file.type !== "image/jpeg") {
this.message.error("File type should be JPEG");
this.fileReset();
return false;
}
else if (file.size / 1024 / 1024 > 1) {
this.message.error("File size should be less than 1 Mb");
this.fileReset();
return false;
}
else {
/** @type {?} */
let timestamp = new Date().valueOf();
/** @type {?} */
let filePath = `/media/${timestamp}.jpeg`;
this.storage.upload(filePath, file)
.then((/**
* @param {?} res
* @return {?}
*/
res => {
return this.storage.ref(filePath).getDownloadURL().toPromise();
}))
.then((/**
* @param {?} url
* @return {?}
*/
url => {
this.message.success("Image uploaded");
this.editorService.insertImage(url);
this.fileReset();
}))
.catch((/**
* @param {?} err
* @return {?}
*/
err => {
this.message.error(err);
}));
}
}
/**
* @return {?}
*/
fileReset() {
this.myInputFile.nativeElement.value = "";
}
/**
* @param {?} classId
* @return {?}
*/
setCustomClass(classId) {
this.editorService.createCustomClass(this.customClasses[classId]);
}
}
EditorToolbarComponent.decorators = [
{ type: Component, args: [{
selector: 'aq-editor-toolbar',
template: "<div class=\"angular-editor-toolbar\" *ngIf=\"showToolbar\">\n <nz-button-group>\n <button nzSize=\"large\" nz-tooltip nz-button type=\"button\" (click)=\"triggerCommand('undo')\" nzTitle=\"Undo\" tabindex=\"-1\">\n <i nz-icon nzType=\"undo\" nzTheme=\"outline\"></i>\n </button>\n <button nzSize=\"large\" nz-tooltip nz-button type=\"button\" (click)=\"triggerCommand('redo')\" nzTitle=\"Redo\" tabindex=\"-1\">\n <i nz-icon nzType=\"redo\" nzTheme=\"outline\"></i>\n </button>\n </nz-button-group>\n <nz-button-group>\n <button nzSize=\"large\" nz-tooltip nz-button type=\"button\" [id]=\"'bold-'+id\" (click)=\"triggerCommand('bold')\" nzTitle=\"Bold\" tabindex=\"-1\" [disabled]=\"htmlMode\">\n <i nz-icon nzType=\"bold\" nzTheme=\"outline\"></i>\n </button>\n <button nzSize=\"large\" nz-tooltip nz-button type=\"button\" [id]=\"'italic-'+id\" (click)=\"triggerCommand('italic')\" nzTitle=\"Italic\" tabindex=\"-1\" [disabled]=\"htmlMode\">\n <i nz-icon nzType=\"italic\" nzTheme=\"outline\"></i>\n </button>\n <button nzSize=\"large\" nz-tooltip nz-button type=\"button\" [id]=\"'underline-'+id\" (click)=\"triggerCommand('underline')\" nzTitle=\"Underline\" tabindex=\"-1\" [disabled]=\"htmlMode\">\n <i nz-icon nzType=\"underline\" nzTheme=\"outline\"></i>\n </button>\n <button nzSize=\"large\" nz-tooltip nz-button type=\"button\" [id]=\"'strikeThrough-'+id\" (click)=\"triggerCommand('strikeThrough')\" nzTitle=\"Strike Through\" tabindex=\"-1\" [disabled]=\"htmlMode\">\n <i nz-icon nzType=\"strikethrough\" nzTheme=\"outline\"></i>\n </button>\n <button nzSize=\"large\" nz-tooltip nz-button type=\"button\" [id]=\"'subscript-'+id\" (click)=\"triggerCommand('subscript')\" nzTitle=\"subscript\" tabindex=\"-1\" [disabled]=\"htmlMode\">\n x<sub>2</sub>\n </button>\n <button nzSize=\"large\" nz-tooltip nz-button type=\"button\" [id]=\"'superscript-'+id\" (click)=\"triggerCommand('superscript')\" nzTitle=\"superscript\" tabindex=\"-1\" [disabled]=\"htmlMode\">\n x<sup>2</sup>\n </button>\n </nz-button-group>\n\n <nz-button-group>\n <button nzSize=\"large\" [id]=\"'justifyLeft-'+id\" type=\"button\" nz-tooltip nzTitle=\"Justify Left\" nz-button (click)=\"triggerCommand('justifyLeft')\" [disabled]=\"htmlMode\" tabindex=\"-1\">\n <i nz-icon nzType=\"align-left\" nzTheme=\"outline\"></i>\n </button>\n <button nzSize=\"large\" [id]=\"'justifyCenter-'+id\" type=\"button\" nz-tooltip nzTitle=\"Justify Center\" nz-button (click)=\"triggerCommand('justifyCenter')\" [disabled]=\"htmlMode\" tabindex=\"-1\">\n <i nz-icon nzType=\"align-center\" nzTheme=\"outline\"></i>\n </button>\n <button nzSize=\"large\" [id]=\"'justifyRight-'+id\" type=\"button\" nz-tooltip nzTitle=\"Justify Right\" nz-button (click)=\"triggerCommand('justifyRight')\" [disabled]=\"htmlMode\" tabindex=\"-1\">\n <i nz-icon nzType=\"align-right\" nzTheme=\"outline\"></i>\n </button>\n <button nzSize=\"large\" [id]=\"'justifyFull-'+id\" type=\"button\" nz-tooltip nzTitle=\"Justify Full\" nz-button (click)=\"triggerCommand('justifyFull')\" [disabled]=\"htmlMode\" tabindex=\"-1\">\n <i nz-icon nzType=\"bars\" nzTheme=\"outline\"></i>\n </button>\n </nz-button-group>\n\n <nz-button-group>\n <button nzSize=\"large\" [id]=\"'indent-'+id\" type=\"button\" nz-tooltip nzTitle=\"Indent\" nz-button (click)=\"triggerCommand('indent')\" [disabled]=\"htmlMode\" tabindex=\"-1\">\n <i nz-icon nzType=\"menu-unfold\" nzTheme=\"outline\"></i>\n </button>\n <button nzSize=\"large\" [id]=\"'outdent-'+id\" type=\"button\" nz-tooltip nzTitle=\"Outdent\" nz-button (click)=\"triggerCommand('outdent')\" [disabled]=\"htmlMode\" tabindex=\"-1\">\n <i nz-icon nzType=\"menu-fold\" nzTheme=\"outline\"></i>\n </button>\n </nz-button-group>\n <nz-button-group>\n <button nzSize=\"large\" [id]=\"'insertUnorderedList-'+id\" type=\"button\" nz-tooltip nzTitle=\"Unordered List\" nz-button (click)=\"triggerCommand('insertUnorderedList')\" [disabled]=\"htmlMode\" tabindex=\"-1\">\n <i nz-icon nzType=\"unordered-list\" nzTheme=\"outline\"></i>\n </button>\n <button nzSize=\"large\" [id]=\"'insertOrderedList-'+id\" type=\"button\" nz-tooltip nzTitle=\"Ordered List\" nz-button (click)=\"triggerCommand('insertOrderedList')\" [disabled]=\"htmlMode\" tabindex=\"-1\">\n <i nz-icon nzType=\"ordered-list\" nzTheme=\"outline\"></i>\n </button>\n </nz-button-group>\n <nz-input-group nzCompact>\n <nz-select nzSize=\"large\" style=\"width:auto;\" nz-tooltip nzTitle=\"Formatting\" [id]=\"'heading-'+id\" nzPlaceHolder=\"Formatting\" class=\"select-heading\" [(ngModel)]=\"block\" (ngModelChange)=\"triggerCommand(block)\" [disabled]=\"htmlMode\" tabindex=\"-1\">\n <nz-option class=\"h1\" nzValue=\"h1\" nzLabel=\"H1\"></nz-option>\n <nz-option class=\"h2\" nzValue=\"h2\" nzLabel=\"H2\"></nz-option>\n <nz-option class=\"h3\" nzValue=\"h3\" nzLabel=\"H3\"></nz-option>\n <nz-option class=\"h4\" nzValue=\"h4\" nzLabel=\"H4\"></nz-option>\n <nz-option class=\"h5\" nzValue=\"h5\" nzLabel=\"H5\"></nz-option>\n <nz-option class=\"h6\" nzValue=\"h6\" nzLabel=\"H6\"></nz-option>\n <nz-option class=\"p\" nzValue=\"p\" nzLabel=\"P\"></nz-option>\n <nz-option class=\"pre\" nzValue=\"pre\" nzLabel=\"Pre\"></nz-option>\n <nz-option class=\"div\" nzValue=\"div\" nzLabel=\"Div\"></nz-option>\n <nz-option class=\"default\" nzValue=\"default\" nzLabel=\"Default\"></nz-option>\n </nz-select>\n \n <nz-select nzSize=\"large\" style=\"width:auto;\" nz-tooltip nzTitle=\"Font Name\" nzPlaceHolder=\"Font Name\" [id]=\"'fontSelector-'+id\" class=\"select-font\" [(ngModel)]=\"fontId\" (ngModelChange)=\"setFontName(fontId)\" [disabled]=\"htmlMode\" tabindex=\"-1\">\n <nz-option *ngFor=\"let item of fonts; let i = index\" [class]=\"item.class\" [nzValue]=\"i\" [nzLabel]=\"item.name\"></nz-option>\n </nz-select>\n \n <nz-select nzSize=\"large\" style=\"width:auto;\" nz-tooltip nzTitle=\"Font Size\" nzPlaceHolder=\"Font Sizing\" [id]=\"'fontSizeSelector-'+id\" class=\"select-font-size\" [(ngModel)]=\"fontSize\" (ngModelChange)=\"setFontSize(fontSize)\" [disabled]=\"htmlMode\" tabindex=\"-1\">\n <nz-option class=\"size1\" nzValue=\"1\" nzLabel=\"1\"></nz-option>\n <nz-option class=\"size2\" nzValue=\"2\" nzLabel=\"2\"></nz-option>\n <nz-option class=\"size3\" nzValue=\"3\" nzLabel=\"3\"></nz-option>\n <nz-option class=\"size4\" nzValue=\"4\" nzLabel=\"4\"></nz-option>\n <nz-option class=\"size5\" nzValue=\"5\" nzLabel=\"5\"></nz-option>\n <nz-option class=\"size6\" nzValue=\"6\" nzLabel=\"6\"></nz-option>\n <nz-option class=\"size7\" nzValue=\"7\" nzLabel=\"7\"></nz-option>\n </nz-select>\n \n <nz-select nzSize=\"large\" style=\"width:auto;margin-right:4px;\" nz-tooltip nzTitle=\"Custom Style\" nzPlaceHolder=\"Custom Class\" [id]=\"'customClassSelector-'+id\" class=\"select-custom-style\" [(ngModel)]=\"customClassId\" (ngModelChange)=\"setCustomClass(customClassId)\" [disabled]=\"htmlMode\" tabindex=\"-1\">\n <nz-option class=\"\" [nzValue]=\"-1\" nzLabel=\"Clear Class\"></nz-option>\n <nz-option *ngFor=\"let item of customClasses; let i = index\" [class]=\"item.class\" [nzValue]=\"i\" [nzLabel]=\"item.name\"></nz-option>\n </nz-select>\n\n <button nzSize=\"large\" [id]=\"'foregroundColorPicker-'+id\" type=\"button\" nz-button (click)=\"fgInput.click()\" nz-tooltip nzTitle=\"Text Color\" [disabled]=\"htmlMode\" tabindex=\"-1\">\n <span class=\"color-label foreground\">\n <i nz-icon nzType=\"font-colors\" nzTheme=\"outline\"></i>\n </span>\n </button> \n\n <button nzSize=\"large\" [id]=\"'backgroundColorPicker-'+id\" type=\"button\" nz-button (click)=\"bgInput.click()\" nz-tooltip nzTitle=\"Background Color\" [disabled]=\"htmlMode\" tabindex=\"-1\">\n <span class=\"color-label background\">\n <i nz-icon nzType=\"bg-colors\" nzTheme=\"outline\"></i>\n </span>\n </button>\n\n <button nzSize=\"large\" [id]=\"'link-'+id\" type=\"button\" nz-button (click)=\"insertUrl()\" nz-tooltip nzTitle=\"Insert Link\" [disabled]=\"htmlMode\" tabindex=\"-1\">\n <i nz-icon nzType=\"link\" nzTheme=\"outline\"></i>\n </button>\n\n <button nzSize=\"large\" type=\"button\" nz-button (click)=\"triggerCommand('unlink')\" nz-tooltip nzTitle=\"Unlink\" [disabled]=\"htmlMode\" tabindex=\"-1\">\n <i nz-icon nzType=\"disconnect\" nzTheme=\"outline\"></i>\n </button>\n\n <button nzSize=\"large\" type=\"button\" nz-button (click)=\"fileInput.click()\" nz-tooltip nzTitle=\"Insert Image\" [disabled]=\"htmlMode\" tabindex=\"-1\">\n <i nz-icon nzType=\"picture\" nzTheme=\"outline\"></i>\n </button>\n\n <button nzSize=\"large\" type=\"button\" nz-tooltip nzTitle=\"Horizontal Line\" nz-button (click)=\"triggerCommand('insertHorizontalRule')\" [disabled]=\"htmlMode\" tabindex=\"-1\">\n <i nz-icon nzType=\"minus\" nzTheme=\"outline\"></i>\n </button>\n\n <button nzSize=\"large\" type=\"button\" nz-tooltip nzTitle=\"Clear Formatting\" nz-button (click)=\"triggerCommand('removeFormat')\" [disabled]=\"htmlMode\" tabindex=\"-1\">\n <i nz-icon nzType=\"delete\" nzTheme=\"outline\"></i>\n </button>\n \n <button nzSize=\"large\" [id]=\"'toggleEditorMode-'+id\" type=\"button\" nz-tooltip nzTitle=\"HTML Code\" nz-button (click)=\"triggerCommand('toggleEditorMode')\" tabindex=\"-1\">\n <i nz-icon nzType=\"code\" nzTheme=\"outline\"></i>\n </button>\n </nz-input-group>\n \n <input style=\"display: none\" type=\"color\" (change)=\"insertColor(fgInput.value, 'textColor')\" #fgInput>\n <input style=\"display: none\" type=\"color\" (change)=\"insertColor(bgInput.value, 'backgroundColor')\" #bgInput>\n <input style=\"display: none\" accept=\"image/*\" type=\"file\" (change)=\"onFileChanged($event)\" #fileInput>\n</div>",
styles: [".ant-btn:not(.ant-btn-circle):not(.ant-btn-circle-outline).ant-btn-icon-only{padding:0 15px}.ant-btn-group{margin-right:4px;margin-bottom:4px}.select{width:100px;margin-right:4px;margin-bottom:4px}"]
}] }
];
/** @nocollapse */
EditorToolbarComponent.ctorParameters = () => [
{ type: AngularFireStorage },
{ type: NzMessageService },
{ type: Renderer2 },
{ type: EditorService },
{ type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] }
];
EditorToolbarComponent.propDecorators = {
execute: [{ type: Output }],
myInputFile: [{ type: ViewChild, args: ['fileInput',] }]
};
if (false) {
/** @type {?} */
EditorToolbarComponent.prototype.id;
/** @type {?} */
EditorToolbarComponent.prototype.htmlMode;
/** @type {?} */
EditorToolbarComponent.prototype.showToolbar;
/** @type {?} */
EditorToolbarComponent.prototype.block;
/** @type {?} */
EditorToolbarComponent.prototype.defaultFontId;
/** @type {?} */
EditorToolbarComponent.prototype.fontId;
/** @type {?} */
EditorToolbarComponent.prototype.fontSize;
/** @type {?} */
EditorToolbarComponent.prototype.fonts;
/** @type {?} */
EditorToolbarComponent.prototype.customClassId;
/** @type {?} */
EditorToolbarComponent.prototype.customClasses;
/** @type {?} */
EditorToolbarComponent.prototype.tagMap;
/** @type {?} */
EditorToolbarComponent.prototype.select;
/** @type {?} */
EditorToolbarComponent.prototype.buttons;
/** @type {?} */
EditorToolbarComponent.prototype.execute;
/** @type {?} */
EditorToolbarComponent.prototype.myInputFile;
/**
* @type {?}
* @private
*/
EditorToolbarComponent.prototype.storage;
/**
* @type {?}
* @private
*/
EditorToolbarComponent.prototype.message;
/**
* @type {?}
* @private
*/
EditorToolbarComponent.prototype._renderer;
/**
* @type {?}
* @private
*/
EditorToolbarComponent.prototype.editorService;
/**
* @type {?}
* @private
*/
EditorToolbarComponent.prototype._document;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRpdG9yLXRvb2xiYXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vbmd4LWZpcmViYXNlLWNtcy8iLCJzb3VyY2VzIjpbImxpYi9kaXJlY3RpdmUvZWRpdG9yLXRvb2xiYXIvZWRpdG9yLXRvb2xiYXIuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFVLFlBQVksRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRWxILE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUM3RCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0MsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2pELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBUzNELE1BQU0sT0FBTyxzQkFBc0I7Ozs7Ozs7O0lBMEJqQyxZQUNVLE9BQTJCLEVBQzNCLE9BQXlCLEVBQ3pCLFNBQW9CLEVBQ3BCLGFBQTRCLEVBQ1YsU0FBYztRQUpoQyxZQUFPLEdBQVAsT0FBTyxDQUFvQjtRQUMzQixZQUFPLEdBQVAsT0FBTyxDQUFrQjtRQUN6QixjQUFTLEdBQVQsU0FBUyxDQUFXO1FBQ3BCLGtCQUFhLEdBQWIsYUFBYSxDQUFlO1FBQ1YsY0FBUyxHQUFULFNBQVMsQ0FBSztRQTdCMUMsT0FBRSxHQUFHLEVBQUUsQ0FBQztRQUNSLGFBQVEsR0FBRyxLQUFLLENBQUM7UUFDakIsZ0JBQVcsR0FBRyxJQUFJLENBQUM7UUFFbkIsVUFBSyxHQUFHLFNBQVMsQ0FBQztRQUVsQixXQUFNLEdBQUcsQ0FBQyxDQUFDO1FBQ1gsYUFBUSxHQUFHLEdBQUcsQ0FBQztRQUdmLGtCQUFhLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFHbkIsV0FBTSxHQUFHO1lBQ1AsVUFBVSxF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QyxRQUFROzs7c0JBUmpCLE1BQU07MEJBQ04sU0FBUyxTQUFDLFdBQVc7Ozs7SUF0QnRCLG9DQUFROztJQUNSLDBDQUFpQjs7SUFDakIsNkNBQW1COztJQUVuQix1Q0FBa0I7O0lBQ2xCLCtDQUFjOztJQUNkLHdDQUFXOztJQUNYLDBDQUFlOztJQUNmLHVDQUFjOztJQUVkLCtDQUFtQjs7SUFDbkIsK0NBQTZCOztJQUU3Qix3Q0FHRTs7SUFFRix3Q0FBZ0U7O0lBQ2hFLHlDQUE4Tjs7SUFFOU4seUNBQW9FOztJQUNwRSw2Q0FBK0M7Ozs7O0lBRzdDLHlDQUFtQzs7Ozs7SUFDbkMseUNBQWlDOzs7OztJQUNqQywyQ0FBNEI7Ozs7O0lBQzVCLCtDQUFvQzs7Ozs7SUFDcEMsMkNBQXdDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBPbkluaXQsIEV2ZW50RW1pdHRlciwgT3V0cHV0LCBWaWV3Q2hpbGQsIEVsZW1lbnRSZWYsIFJlbmRlcmVyMiwgSW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBGb250LCBDdXN0b21DbGFzcyB9IGZyb20gJy4uLy4uL2ludGVyZmFjZS9lZGl0b3InO1xuaW1wb3J0IHsgRWRpdG9yU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2UvZWRpdG9yLnNlcnZpY2UnO1xuaW1wb3J0IHsgRE9DVU1FTlQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgTnpNZXNzYWdlU2VydmljZSB9IGZyb20gJ25nLXpvcnJvLWFudGQnO1xuaW1wb3J0IHsgQW5ndWxhckZpcmVTdG9yYWdlIH0gZnJvbSAnQGFuZ3VsYXIvZmlyZS9zdG9yYWdlJztcbmltcG9ydCB7IG9mIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBIdHRwRXZlbnQgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2FxLWVkaXRvci10b29sYmFyJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2VkaXRvci10b29sYmFyLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vZWRpdG9yLXRvb2xiYXIuY29tcG9uZW50LmNzcyddXG59KVxuZXhwb3J0IGNsYXNzIEVkaXRvclRvb2xiYXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuXG4gIGlkID0gJyc7XG4gIGh0bWxNb2RlID0gZmFsc2U7XG4gIHNob3dUb29sYmFyID0gdHJ1ZTtcblxuICBibG9jayA9ICdkZWZhdWx0JztcbiAgZGVmYXVsdEZvbnRJZDtcbiAgZm9udElkID0gMDtcbiAgZm9udFNpemUgPSAnNSc7XG4gIGZvbnRzOiBGb250W107XG5cbiAgY3VzdG9tQ2xhc3NJZCA9IC0xO1xuICBjdXN0b21DbGFzc2VzOiBDdXN0b21DbGFzc1tdO1xuXG4gIHRhZ01hcCA9IHtcbiAgICBCTE9DS1FVT1RFOiBcImluZGVudFwiLFxuICAgIEE6IFwibGlua1wiXG4gIH07XG5cbiAgc2VsZWN0ID0gW1wiSDFcIiwgXCJIMlwiLCBcIkgzXCIsIFwiSDRcIiwgXCJINVwiLCBcIkg2XCIsIFwiUFwiLCBcIlBSRVwiLCBcIkRJVlwiXVxuICBidXR0b25zID0gW1wiYm9sZFwiLCBcIml0YWxpY1wiLCBcInVuZGVybGluZVwiLCBcInN0cmlrZVRocm91Z2hcIiwgXCJzdWJzY3JpcHRcIiwgXCJzdXBlcnNjcmlwdFwiLCBcImp1c3RpZnlMZWZ0XCIsIFwianVzdGlmeUNlbnRlclwiLCBcImp1c3RpZnlSaWdodFwiLCBcImp1c3RpZnlGdWxsXCIsIFwiaW5kZW50XCIsIFwib3V0ZGVudFwiLCBcImluc2VydFVub3JkZXJlZExpc3RcIiwgXCJpbnNlcnRPcmRlcmVkTGlzdFwiLCBcImxpbmtcIl1cblxuICBAT3V0cHV0KCkgZXhlY3V0ZTogRXZlbnRFbWl0dGVyPHN0cmluZz4gPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKVxuICBAVmlld0NoaWxkKCdmaWxlSW5wdXQnKSBteUlucHV0RmlsZTogRWxlbWVudFJlZlxuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgc3RvcmFnZTogQW5ndWxhckZpcmVTdG9yYWdlLFxuICAgIHByaXZhdGUgbWVzc2FnZTogTnpNZXNzYWdlU2VydmljZSxcbiAgICBwcml2YXRlIF9yZW5kZXJlcjogUmVuZGVyZXIyLFxuICAgIHByaXZhdGUgZWRpdG9yU2VydmljZTogRWRpdG9yU2VydmljZSwgXG4gICAgQEluamVjdChET0NVTUVOVCkgcHJpdmF0ZSBfZG9jdW1lbnQ6IGFueVxuICApIHtcbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIFxuICB9XG5cbiAgdHJpZ2dlckNvbW1hbmQoY29tbWFuZDogc3RyaW5nKSB7XG4gICAgdGhpcy5leGVjdXRlLmVtaXQoY29tbWFuZCk7XG4gIH1cblxuICB0cmlnZ2VyQnV0dG9ucygpIHtcbiAgICBpZiAoIXRoaXMuc2hvd1Rvb2xiYXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5idXR0b25zLmZvckVhY2goZSA9PiB7XG4gICAgICBjb25zdCByZXN1bHQgPSB0aGlzLl9kb2N1bWVudC5xdWVyeUNvbW1hbmRTdGF0ZShlKTtcbiAgICAgIGNvbnN0IGVsZW1lbnRCeUlkID0gdGhpcy5fZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoZSArICctJyArIHRoaXMuaWQpO1xuICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICB0aGlzLl9yZW5kZXJlci5hZGRDbGFzcyhlbGVtZW50QnlJZCwgXCJhY3RpdmVcIik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9yZW5kZXJlci5yZW1vdmVDbGFzcyhlbGVtZW50QnlJZCwgXCJhY3RpdmVcIik7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICB0cmlnZ2VyQmxvY2tzKG5vZGVzOiBOb2RlW10pIHtcbiAgICBpZiAoIXRoaXMuc2hvd1Rvb2xiYXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgbGV0IGZvdW5kID0gZmFsc2U7XG4gICAgdGhpcy5zZWxlY3QuZm9yRWFjaCh5ID0+IHtcbiAgICAgIGNvbnN0IG5vZGUgPSBub2Rlcy5maW5kKHggPT4geC5ub2RlTmFtZSA9PT0geSk7XG4gICAgICBpZiAobm9kZSAhPT0gdW5kZWZpbmVkICYmIHkgPT09IG5vZGUubm9kZU5hbWUpIHtcbiAgICAgICAgaWYgKGZvdW5kID09PSBmYWxzZSkge1xuICAgICAgICAgIHRoaXMuYmxvY2sgPSBub2RlLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgICAgZm91bmQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGZvdW5kID09PSBmYWxzZSkge1xuICAgICAgICB0aGlzLmJsb2NrID0gJ2RlZmF1bHQnO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgZm91bmQgPSBmYWxzZTtcbiAgICBpZiAodGhpcy5mb250cykge1xuICAgICAgdGhpcy5mb250cy5mb3JFYWNoKCh5LCBpbmRleCkgPT4ge1xuICAgICAgICBjb25zdCBub2RlID0gbm9kZXMuZmluZCh4ID0+IHtcbiAgICAgICAgICBpZiAoeCBpbnN0YW5jZW9mIEhUTUxGb250RWxlbWVudCkge1xuICAgICAgICAgICAgcmV0dXJuIHguZmFjZSA9PT0geS5uYW1lO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChub2RlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBpZiAoZm91bmQgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICB0aGlzLmZvbnRJZCA9IGluZGV4O1xuICAgICAgICAgICAgZm91bmQgPSB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChmb3VuZCA9PT0gZmFsc2UpIHtcbiAgICAgICAgICB0aGlzLmZvbnRJZCA9IHRoaXMuZGVmYXVsdEZvbnRJZDtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgZm91bmQgPSBmYWxzZTtcbiAgICBpZiAodGhpcy5jdXN0b21DbGFzc2VzKSB7XG4gICAgICB0aGlzLmN1c3RvbUNsYXNzZXMuZm9yRWFjaCgoeSwgaW5kZXgpID0+IHtcbiAgICAgICAgY29uc3Qgbm9kZSA9IG5vZGVzLmZpbmQoeCA9PiB7XG4gICAgICAgICAgaWYgKHggaW5zdGFuY2VvZiBFbGVtZW50KSB7XG4gICAgICAgICAgICByZXR1cm4geC5jbGFzc05hbWUgPT09IHkuY2xhc3M7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKG5vZGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGlmIChmb3VuZCA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHRoaXMuY3VzdG9tQ2xhc3NJZCA9IGluZGV4O1xuICAgICAgICAgICAgZm91bmQgPSB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChmb3VuZCA9PT0gZmFsc2UpIHtcbiAgICAgICAgICB0aGlzLmN1c3RvbUNsYXNzSWQgPSAtMTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgT2JqZWN0LmtleXModGhpcy50YWdNYXApLm1hcChlID0+IHtcbiAgICAgIGNvbnN0IGVsZW1lbnRCeUlkID0gdGhpcy5fZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGhpcy50YWdNYXBbZV0gKyAnLScgKyB0aGlzLmlkKTtcbiAgICAgIGNvbnN0IG5vZGUgPSBub2Rlcy5maW5kKHggPT4geC5ub2RlTmFtZSA9PT0gZSk7XG4gICAgICBpZiAobm9kZSAhPT0gdW5kZWZpbmVkICYmIGUgPT09IG5vZGUubm9kZU5hbWUpIHtcbiAgICAgICAgdGhpcy5fcmVuZGVyZXIuYWRkQ2xhc3MoZWxlbWVudEJ5SWQsIFwiYWN0aXZlXCIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5fcmVuZGVyZXIucmVtb3ZlQ2xhc3MoZWxlbWVudEJ5SWQsIFwiYWN0aXZlXCIpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgaW5zZXJ0VXJsKCkge1xuICAgIGNvbnN0IHVybCA9IHByb21wdChcIkluc2VydCBVUkwgbGlua1wiLCAnaHR0cDpcXC9cXC8nKTtcbiAgICBpZiAodXJsICYmIHVybCAhPT0gJycgJiYgdXJsICE9PSAnaHR0cDovLycpIHtcbiAgICAgIHRoaXMuZWRpdG9yU2VydmljZS5jcmVhdGVMaW5rKHVybCk7XG4gICAgfVxuICB9XG5cbiAgaW5zZXJ0Q29sb3IoY29sb3I6IHN0cmluZywgd2hlcmU6IHN0cmluZykge1xuICAgIHRoaXMuZWRpdG9yU2VydmljZS5pbnNlcnRDb2xvcihjb2xvciwgd2hlcmUpO1xuICAgIHRoaXMuZXhlY3V0ZS5lbWl0KFwiXCIpO1xuICB9XG5cbiAgc2V0Rm9udE5hbWUoZm9udElkOiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLmVkaXRvclNlcnZpY2Uuc2V0Rm9udE5hbWUodGhpcy5mb250c1tmb250SWRdLm5hbWUpO1xuICAgIHRoaXMuZXhlY3V0ZS5lbWl0KFwiXCIpO1xuICB9XG5cbiAgc2V0Rm9udFNpemUoZm9udFNpemU6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuZWRpdG9yU2VydmljZS5zZXRGb250U2l6ZShmb250U2l6ZSk7XG4gICAgdGhpcy5leGVjdXRlLmVtaXQoXCJcIik7XG4gIH1cblxuICBzZXRFZGl0b3JNb2RlKG06IGJvb2xlYW4pIHtcbiAgICBjb25zdCB0b2dnbGVFZGl0b3JNb2RlQnV0dG9uID0gdGhpcy5fZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJ0b2dnbGVFZGl0b3JNb2RlXCIgKyAnLScgKyB0aGlzLmlkKTtcbiAgICBpZiAobSkge1xuICAgICAgdGhpcy5fcmVuZGVyZXIuYWRkQ2xhc3ModG9nZ2xlRWRpdG9yTW9kZUJ1dHRvbiwgXCJhY3RpdmVcIik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX3JlbmRlcmVyLnJlbW92ZUNsYXNzKHRvZ2dsZUVkaXRvck1vZGVCdXR0b24sIFwiYWN0aXZlXCIpO1xuICAgIH1cbiAgICB0aGlzLmh0bWxNb2RlID0gbTtcbiAgfVxuXG4gIG9uRmlsZUNoYW5nZWQoZXZlbnQpIHtcbiAgICBjb25zdCBmaWxlID0gZXZlbnQudGFyZ2V0LmZpbGVzWzBdXG4gICAgY29uc29sZS5sb2coZmlsZS50eXBlKVxuICAgIGlmKGZpbGUudHlwZSAhPT0gXCJpbWFnZS9qcGVnXCIpIHtcbiAgICAgIHRoaXMubWVzc2FnZS5lcnJvcihcIkZpbGUgdHlwZSBzaG91bGQgYmUgSlBFR1wiKVxuICAgICAgdGhpcy5maWxlUmVzZXQoKVxuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfSBlbHNlIGlmIChmaWxlLnNpemUvMTAyNC8xMDI0ID4gMSkge1xuICAgICAgdGhpcy5tZXNzYWdlLmVycm9yKFwiRmlsZSBzaXplIHNob3VsZCBiZSBsZXNzIHRoYW4gMSBNYlwiKVxuICAgICAgdGhpcy5maWxlUmVzZXQoKVxuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfSBlbHNlIHtcbiAgICAgIGxldCB0aW1lc3RhbXAgPSBuZXcgRGF0ZSgpLnZhbHVlT2YoKVxuICAgICAgbGV0IGZpbGVQYXRoID0gYC9tZWRpYS8ke3RpbWVzdGFtcH0uanBlZ2BcbiAgICAgIHRoaXMuc3RvcmFnZS51cGxvYWQoZmlsZVBhdGgsIGZpbGUpXG4gICAgICAgIC50aGVuKHJlcyA9PiB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuc3RvcmFnZS5yZWYoZmlsZVBhdGgpLmdldERvd25sb2FkVVJMKCkudG9Qcm9taXNlKClcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4odXJsID0+IHtcbiAgICAgICAgICB0aGlzLm1lc3NhZ2Uuc3VjY2VzcyhcIkltYWdlIHVwbG9hZGVkXCIpXG4gICAgICAgICAgdGhpcy5lZGl0b3JTZXJ2aWNlLmluc2VydEltYWdlKHVybClcbiAgICAgICAgICB0aGlzLmZpbGVSZXNldCgpXG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnIgPT4ge1xuICAgICAgICAgIHRoaXMubWVzc2FnZS5lcnJvcihlcnIpXG4gICAgICAgIH0pXG4gICAgfVxuICB9XG5cbiAgZmlsZVJlc2V0KCkge1xuICAgIHRoaXMubXlJbnB1dEZpbGUubmF0aXZlRWxlbWVudC52YWx1ZSA9IFwiXCI7XG4gIH1cblxuICBzZXRDdXN0b21DbGFzcyhjbGFzc0lkOiBudW1iZXIpIHtcbiAgICB0aGlzLmVkaXRvclNlcnZpY2UuY3JlYXRlQ3VzdG9tQ2xhc3ModGhpcy5jdXN0b21DbGFzc2VzW2NsYXNzSWRdKTtcbiAgfVxufSJdfQ==