@edugouvfr/ngx-dsfr-ext
Version:
NgxDsfrExt est une extension au package @edugouvfr/ngx-dsfr (portage Angular des éléments DSFR)
180 lines • 33 kB
JavaScript
import { CommonModule } from '@angular/common';
import { Component, CUSTOM_ELEMENTS_SCHEMA, inject, Input, ViewEncapsulation, } from '@angular/core';
// eslint-disable-next-line @typescript-eslint/naming-convention
import Quill from 'quill';
import { DsfrI18nService, DsfrSeverityConst } from '@edugouvfr/ngx-dsfr';
// eslint-disable-next-line @typescript-eslint/naming-convention
import Emitter from 'quill/core/emitter';
import { DsfrEditorService } from '../../editor.service';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
export class EduEditorContentComponent {
constructor() {
/**
* L'identifiant du tag hôte pour le composant éditeur.
*
* Attention : cet input est statique et doit être connu à l'initialisation du composant.
*/
this.editorId = 'editor';
/**
* Active la lecure seule.
*/
this.readOnly = false;
/**
* Dev/debug : permet d'afficher le code HTML interne de l'éditeur (i.e. celui qui sert pour l'affichage WYSIWYG).
*/
this.showEditorHtmlDebugPanel = false;
/**
* Dev/debug : permet d'afficher le code HTML qui sera récupéré en sortie.
*/
this.showSemanticHtmlDebugPanel = false;
/** @internal */
this.i18n = inject(DsfrI18nService);
/**
* Pour pouvoir utiliser DsfrSeverityConst côté template.
*/
this.severityConst = DsfrSeverityConst;
/**
* Options de configuration de l'éditeur Quill.
*/
this._options = {
readOnly: this.readOnly,
modules: {
toolbar: false,
},
placeholder: this.i18n.t('editor.placeholder'),
theme: 'snow',
};
this._subscriptions = [];
this.editorService = inject(DsfrEditorService);
}
ngAfterViewInit() {
this._quill = new Quill('#' + this.editorId, this._options);
this._quill.root.setAttribute('role', 'textbox');
this._quill.root.setAttribute('aria-multiline', 'true');
this._quill.root.setAttribute('spellcheck', 'false');
// fix a11y : par défaut, le key-binding Quill sur la touche Tab empêche de sortir de l'éditeur en utilisant Tab
delete this._quill.getModule('keyboard')?.bindings['Tab'];
if (this.ariaLabelledBy && this.ariaLabelledBy.length) {
this._quill.root.setAttribute('aria-labelledby', this.ariaLabelledBy);
}
if (this.message && this.message.length && this.messagesGroupId && this.messagesGroupId.length) {
this._quill.root.setAttribute('aria-describedby', this.messagesGroupId);
}
// On se met à l'écoute de la sélection utilisateur
this._editorSelectionHandler = this._quill.on(Emitter.events.SELECTION_CHANGE, (range) => this._onEditorSelectionChange(range));
// Détecte le changement de contenu de l'éditeur.
this._editorChangeHandler = this._quill.on(Emitter.events.EDITOR_CHANGE, (eventName, delta, oldContents, source) => this._onEditorChange(eventName, delta, oldContents, source));
this._subscriptions.push(this.editorService.formattingRequest$.subscribe((req) => {
const range = this._quill.getSelection();
if (req === undefined) {
if (range) {
// remove formatting
this._quill.removeFormat(range.index, range.length);
}
}
else if ('image' === req.action) {
// perform special image format
if (range) {
this._quill.uploader.upload(range, req.value);
}
}
else {
// perform standart formatting
this._quill.format(req.action, req.value);
}
this.editorService.setCurrentFormatting(this._getCurrentFormatting());
}));
// Écoute les mises à jour du modèle externe.
this._subscriptions.push(this.editorService.modelChange$.subscribe((newValue) => {
this.setEditorContent(newValue);
}));
// Écoute les demandes de prise de focus
this._subscriptions.push(this.editorService.focusOnEditorRequest$.subscribe(() => {
this._quill.focus();
}));
}
ngOnDestroy() {
this._subscriptions.forEach((s) => s.unsubscribe());
this._quill.off(Emitter.events.SELECTION_CHANGE, this._editorSelectionHandler.off);
this._quill.off(Emitter.events.EDITOR_CHANGE, this._editorChangeHandler.off);
}
ngOnChanges({ ariaLabelledBy, message, messagesGroupId }) {
if (ariaLabelledBy) {
if (this.ariaLabelledBy && this.ariaLabelledBy.length) {
this._quill?.root.setAttribute('aria-labelledby', this.ariaLabelledBy);
}
else {
this._quill?.root.removeAttribute('aria-labelledby');
}
}
if (message || messagesGroupId) {
if (this.message && this.message.length && this.messagesGroupId && this.messagesGroupId.length) {
this._quill?.root.setAttribute('aria-describedby', this.messagesGroupId);
}
else {
this._quill?.root.removeAttribute('aria-describedby');
}
}
}
hasMessage(severity) {
return !this.isStringEmptyOrNull(this.message) && severity === this.messageSeverity;
}
setEditorContent(newValue) {
this._quill.setContents(this._quill.clipboard.convert({ html: newValue }), 'silent');
}
//FIXME: utiliser les utils de la lib ngx-dsfr
isStringEmptyOrNull(s) {
return !s || s.trim() === '';
}
_onEditorSelectionChange(range) {
// RPA: vu avec SAB le 25/09/2024 : on considère que la toolbar reflète l'état courant relatif à la position du
// curseur et/ou la sélection active dans l'éditeur
// si on change d'avis et qu'on on veut conserver l'état de la toolbar correspondant à la dernière position du
// curseur avant une perte de focus de l'éditeur alors il ne faut pas émettre d'event si range==null
this.editorService.setCurrentFormatting(this._getCurrentFormatting());
}
/**
* Permet de se mettre à l'écoute du contenu de l'éditeur afin de reset la toolbar si l'éditeur est vidé.
*/
_onEditorChange(eventName, delta, oldContents, source) {
if (eventName === 'text-change') {
// Note even when Quill is empty, there is still a blank line represented by '\n', so getLength will return 1.
if (this._quill.getLength() === 1) {
this.editorService.setCurrentFormatting(undefined);
}
else {
this.editorService.setCurrentFormatting(this._getCurrentFormatting());
}
// on signale le changement à l'extérieur
this.editorService.emitEditorChange(this._quill.getSemanticHTML());
}
}
_getCurrentFormatting() {
const range = this._quill.getSelection();
return range ? this._quill.getFormat(range.index, range.length) : undefined;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: EduEditorContentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: EduEditorContentComponent, isStandalone: true, selector: "edu-editor-content", inputs: { editorId: "editorId", ariaLabelledBy: "ariaLabelledBy", readOnly: "readOnly", message: "message", messageSeverity: "messageSeverity", messagesGroupId: "messagesGroupId", showEditorHtmlDebugPanel: "showEditorHtmlDebugPanel", showSemanticHtmlDebugPanel: "showSemanticHtmlDebugPanel" }, usesOnChanges: true, ngImport: i0, template: "<div id=\"{{ editorId }}\"></div>\n\n<div class=\"fr-messages-group\" [id]=\"messagesGroupId\" aria-live=\"polite\">\n @if (message) {\n <p\n class=\"fr-message\"\n [ngClass]=\"{\n 'fr-message--error': hasMessage(severityConst.ERROR),\n 'fr-message--valid': hasMessage(severityConst.SUCCESS),\n 'fr-message--info': hasMessage(severityConst.INFO)\n }\">\n {{ message }}\n </p>\n }\n</div>\n\n@if (showEditorHtmlDebugPanel) {\n <div class=\"debug-panel\">\n <p>Editor source</p>\n <code>{{ _quill?.root?.innerHTML }}</code>\n </div>\n}\n\n@if (showSemanticHtmlDebugPanel) {\n <div class=\"debug-panel\">\n <p>HTML output</p>\n <code>{{ _quill?.getSemanticHTML() }}</code>\n </div>\n}\n", styles: ["edu-editor-content .ql-container{font-family:Marianne,sans-serif;margin-top:.4375rem}edu-editor-content .ql-editor ol{list-style-type:unset;padding-inline-start:unset;counter-reset:unset}edu-editor-content .ql-editor ol>li{counter-increment:unset}edu-editor-content .ql-editor ol>li::marker{content:unset;font-size:unset;font-weight:unset}edu-editor-content .debug-panel{margin-top:1rem;border:1px solid lightgray;background-color:#f9f9f9}edu-editor-content .debug-panel>p:first-child{display:inline-block;position:absolute;color:#5c5b5b;background-color:#d3d3d3;border:1px solid lightgray;border-bottom-right-radius:6px;font-size:.8em;font-weight:700;padding:0 .5rem;margin-bottom:0;height:1.6rem;width:6.6rem}edu-editor-content .debug-panel code{display:block;padding:2rem .7rem .7rem;font-family:monospace monospace;color:#505050;font-size:.9em}edu-editor-content .fr-messages-group{margin-top:1rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: EduEditorContentComponent, decorators: [{
type: Component,
args: [{ selector: 'edu-editor-content', encapsulation: ViewEncapsulation.None, standalone: true, imports: [CommonModule], schemas: [CUSTOM_ELEMENTS_SCHEMA], template: "<div id=\"{{ editorId }}\"></div>\n\n<div class=\"fr-messages-group\" [id]=\"messagesGroupId\" aria-live=\"polite\">\n @if (message) {\n <p\n class=\"fr-message\"\n [ngClass]=\"{\n 'fr-message--error': hasMessage(severityConst.ERROR),\n 'fr-message--valid': hasMessage(severityConst.SUCCESS),\n 'fr-message--info': hasMessage(severityConst.INFO)\n }\">\n {{ message }}\n </p>\n }\n</div>\n\n@if (showEditorHtmlDebugPanel) {\n <div class=\"debug-panel\">\n <p>Editor source</p>\n <code>{{ _quill?.root?.innerHTML }}</code>\n </div>\n}\n\n@if (showSemanticHtmlDebugPanel) {\n <div class=\"debug-panel\">\n <p>HTML output</p>\n <code>{{ _quill?.getSemanticHTML() }}</code>\n </div>\n}\n", styles: ["edu-editor-content .ql-container{font-family:Marianne,sans-serif;margin-top:.4375rem}edu-editor-content .ql-editor ol{list-style-type:unset;padding-inline-start:unset;counter-reset:unset}edu-editor-content .ql-editor ol>li{counter-increment:unset}edu-editor-content .ql-editor ol>li::marker{content:unset;font-size:unset;font-weight:unset}edu-editor-content .debug-panel{margin-top:1rem;border:1px solid lightgray;background-color:#f9f9f9}edu-editor-content .debug-panel>p:first-child{display:inline-block;position:absolute;color:#5c5b5b;background-color:#d3d3d3;border:1px solid lightgray;border-bottom-right-radius:6px;font-size:.8em;font-weight:700;padding:0 .5rem;margin-bottom:0;height:1.6rem;width:6.6rem}edu-editor-content .debug-panel code{display:block;padding:2rem .7rem .7rem;font-family:monospace monospace;color:#505050;font-size:.9em}edu-editor-content .fr-messages-group{margin-top:1rem}\n"] }]
}], ctorParameters: () => [], propDecorators: { editorId: [{
type: Input
}], ariaLabelledBy: [{
type: Input
}], readOnly: [{
type: Input
}], message: [{
type: Input
}], messageSeverity: [{
type: Input
}], messagesGroupId: [{
type: Input
}], showEditorHtmlDebugPanel: [{
type: Input
}], showSemanticHtmlDebugPanel: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRpdG9yLWNvbnRlbnQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWRzZnItZXh0L2VkaXRvci9zcmMvbGliL2NvbXBvbmVudHMvY29udGVudC9lZGl0b3ItY29udGVudC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtZHNmci1leHQvZWRpdG9yL3NyYy9saWIvY29tcG9uZW50cy9jb250ZW50L2VkaXRvci1jb250ZW50LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBRUwsU0FBUyxFQUNULHNCQUFzQixFQUN0QixNQUFNLEVBQ04sS0FBSyxFQUlMLGlCQUFpQixHQUNsQixNQUFNLGVBQWUsQ0FBQztBQUV2QixnRUFBZ0U7QUFDaEUsT0FBTyxLQUE4QixNQUFNLE9BQU8sQ0FBQztBQUVuRCxPQUFPLEVBQUUsZUFBZSxFQUFnQixpQkFBaUIsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRXZGLGdFQUFnRTtBQUNoRSxPQUFPLE9BQU8sTUFBTSxvQkFBb0IsQ0FBQztBQUV6QyxPQUFPLEVBQUUsaUJBQWlCLEVBQXFCLE1BQU0sc0JBQXNCLENBQUM7OztBQWM1RSxNQUFNLE9BQU8seUJBQXlCO0lBNkVwQztRQTVFQTs7OztXQUlHO1FBQ00sYUFBUSxHQUFHLFFBQVEsQ0FBQztRQU83Qjs7V0FFRztRQUNNLGFBQVEsR0FBRyxLQUFLLENBQUM7UUFrQjFCOztXQUVHO1FBQ00sNkJBQXdCLEdBQUcsS0FBSyxDQUFDO1FBRTFDOztXQUVHO1FBQ00sK0JBQTBCLEdBQUcsS0FBSyxDQUFDO1FBRTVDLGdCQUFnQjtRQUNULFNBQUksR0FBRyxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUM7UUFPdEM7O1dBRUc7UUFDZ0Isa0JB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QyxJQUFJLENBQUMsTUFBTSxDQUFDLGVBQWUsRUFBRSxDQUFDLENBQUM7UUFDckUsQ0FBQztJQUNILENBQUM7SUFFTyxxQkFBcUI7UUFDM0IsTUFBTSxLQUFLLEdBQWlCLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDdkQsT0FBTyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7SUFDOUUsQ0FBQzsrR0F6TVUseUJBQXlCO21HQUF6Qix5QkFBeUIseVlDbkN0Qyw4dUJBNkJBLGk4QkRFWSxZQUFZOzs0RkFJWCx5QkFBeUI7a0JBVnJDLFNBQVM7K0JBQ0Usb0JBQW9CLGlCQUNmLGlCQUFpQixDQUFDLElBQUksY0FHekIsSUFBSSxXQUNQLENBQUMsWUFBWSxDQUFDLFdBRWQsQ0FBQyxzQkFBc0IsQ0FBQzt3REFReEIsUUFBUTtzQkFBaEIsS0FBSztnQkFLRyxjQUFjO3NCQUF0QixLQUFLO2dCQUtHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBS0csT0FBTztzQkFBZixLQUFLO2dCQUtHLGVBQWU7c0JBQXZCLEtBQUs7Z0JBTUcsZUFBZTtzQkFBdkIsS0FBSztnQkFLRyx3QkFBd0I7c0JBQWhDLEtBQUs7Z0JBS0csMEJBQTBCO3NCQUFsQyxLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG4gIEFmdGVyVmlld0luaXQsXG4gIENvbXBvbmVudCxcbiAgQ1VTVE9NX0VMRU1FTlRTX1NDSEVNQSxcbiAgaW5qZWN0LFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLFxuICBPbkRlc3Ryb3ksXG4gIFNpbXBsZUNoYW5nZXMsXG4gIFZpZXdFbmNhcHN1bGF0aW9uLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxuaW1wb3J0IFF1aWxsLCB7IFF1aWxsT3B0aW9ucywgUmFuZ2UgfSBmcm9tICdxdWlsbCc7XG5cbmltcG9ydCB7IERzZnJJMThuU2VydmljZSwgRHNmclNldmVyaXR5LCBEc2ZyU2V2ZXJpdHlDb25zdCB9IGZyb20gJ0BlZHVnb3V2ZnIvbmd4LWRzZnInO1xuaW1wb3J0IHsgRGVsdGEgfSBmcm9tICdxdWlsbC9jb3JlJztcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cbmltcG9ydCBFbWl0dGVyIGZyb20gJ3F1aWxsL2NvcmUvZW1pdHRlcic7XG5pbXBvcnQgeyBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IERzZnJFZGl0b3JTZXJ2aWNlLCBGb3JtYXR0aW5nUmVxdWVzdCB9IGZyb20gJy4uLy4uL2VkaXRvci5zZXJ2aWNlJztcblxuZGVjbGFyZSB0eXBlIEZvcm1hdHRpbmcgPSB7IFtmb3JtYXQ6IHN0cmluZ106IHVua25vd24gfTtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnZWR1LWVkaXRvci1jb250ZW50JyxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgdGVtcGxhdGVVcmw6ICcuL2VkaXRvci1jb250ZW50LmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vZWRpdG9yLWNvbnRlbnQuY29tcG9uZW50LnNjc3MnXSxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0NvbW1vbk1vZHVsZV0sXG5cbiAgc2NoZW1hczogW0NVU1RPTV9FTEVNRU5UU19TQ0hFTUFdLFxufSlcbmV4cG9ydCBjbGFzcyBFZHVFZGl0b3JDb250ZW50Q29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95LCBPbkNoYW5nZXMge1xuICAvKipcbiAgICogTCdpZGVudGlmaWFudCBkdSB0YWcgaMO0dGUgcG91ciBsZSBjb21wb3NhbnQgw6lkaXRldXIuXG4gICAqXG4gICAqIEF0dGVudGlvbiA6IGNldCBpbnB1dCBlc3Qgc3RhdGlxdWUgZXQgZG9pdCDDqnRyZSBjb25udSDDoCBsJ2luaXRpYWxpc2F0aW9uIGR1IGNvbXBvc2FudC5cbiAgICovXG4gIEBJbnB1dCgpIGVkaXRvcklkID0gJ2VkaXRvcic7XG5cbiAgLyoqXG4gICAqIFJlbnNlaWduZXIgY2V0dGUgcHJvcHJpdMOpIHBvc2l0aW9ubmUgdW4gYXR0cmlidXQgYXJpYS1sYWJlbGxlZGJ5IHN1ciBsJ8OpbMOpbWVudCBow7R0ZSBkZSBsJ8OpZGl0ZXVyLlxuICAgKi9cbiAgQElucHV0KCkgYXJpYUxhYmVsbGVkQnk6IHN0cmluZztcblxuICAvKipcbiAgICogQWN0aXZlIGxhIGxlY3VyZSBzZXVsZS5cbiAgICovXG4gIEBJbnB1dCgpIHJlYWRPbmx5ID0gZmFsc2U7XG5cbiAgLyoqXG4gICAqIE1lc3NhZ2UgZCdpbmZvcm1hdGlvbiBhc3NvY2nDqSBhdSBjb21wb3NhbnQuXG4gICAqL1xuICBASW5wdXQoKSBtZXNzYWdlOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFJlcHLDqXNlbnRlIGxhIHPDqXbDqXJpdMOpIGR1IG1lc3NhZ2UuXG4gICAqL1xuICBASW5wdXQoKSBtZXNzYWdlU2V2ZXJpdHk6IERzZnJTZXZlcml0eTtcblxuICAvKipcbiAgICogSWQgZGUgbCfDqWzDqW1lbnQgYWZmaWNoYW50IGxlcyBtZXNzYWdlcyBhc3NvY2nDqSDDoCBsJ8OpZGl0ZXVyLiBBIHJlbnNlaWduZXIgc2kgdm91cyBzb3VoYWl0ZXogcG9zaXRpb25uZXIgdW4gYXR0cmlidXRcbiAgICogYGFyaWEtZGVzY3JpYmVkYnlgIHLDqWbDqXJlbsOnYW50IHZvdHJlIG1lc3NhZ2UgYXUgbml2ZWF1IGRlIGwnw6lsw6ltZW50IGjDtHRlIGRlIGwnw6lkaXRldXIuXG4gICAqL1xuICBASW5wdXQoKSBtZXNzYWdlc0dyb3VwSWQ6IHN0cmluZztcblxuICAvKipcbiAgICogRGV2L2RlYnVnIDogcGVybWV0IGQnYWZmaWNoZXIgbGUgY29kZSBIVE1MIGludGVybmUgZGUgbCfDqWRpdGV1ciAoaS5lLiBjZWx1aSBxdWkgc2VydCBwb3VyIGwnYWZmaWNoYWdlIFdZU0lXWUcpLlxuICAgKi9cbiAgQElucHV0KCkgc2hvd0VkaXRvckh0bWxEZWJ1Z1BhbmVsID0gZmFsc2U7XG5cbiAgLyoqXG4gICAqIERldi9kZWJ1ZyA6IHBlcm1ldCBkJ2FmZmljaGVyIGxlIGNvZGUgSFRNTCBxdWkgc2VyYSByw6ljdXDDqXLDqSBlbiBzb3J0aWUuXG4gICAqL1xuICBASW5wdXQoKSBzaG93U2VtYW50aWNIdG1sRGVidWdQYW5lbCA9IGZhbHNlO1xuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgcHVibGljIGkxOG4gPSBpbmplY3QoRHNmckkxOG5TZXJ2aWNlKTtcblxuICAvKipcbiAgICogSW5zdGFuY2UgUXVpbGwuXG4gICAqL1xuICBwcm90ZWN0ZWQgX3F1aWxsOiBRdWlsbDtcblxuICAvKipcbiAgICogUG91ciBwb3V2b2lyIHV0aWxpc2VyIERzZnJTZXZlcml0eUNvbnN0IGPDtHTDqSB0ZW1wbGF0ZS5cbiAgICovXG4gIHByb3RlY3RlZCByZWFkb25seSBzZXZlcml0eUNvbnN0ID0gRHNmclNldmVyaXR5Q29uc3Q7XG5cbiAgLyoqXG4gICAqIE9wdGlvbnMgZGUgY29uZmlndXJhdGlvbiBkZSBsJ8OpZGl0ZXVyIFF1aWxsLlxuICAgKi9cbiAgcHJpdmF0ZSBfb3B0aW9uczogUXVpbGxPcHRpb25zID0ge1xuICAgIHJlYWRPbmx5OiB0aGlzLnJlYWRPbmx5LFxuICAgIG1vZHVsZXM6IHtcbiAgICAgIHRvb2xiYXI6IGZhbHNlLFxuICAgIH0sXG4gICAgcGxhY2Vob2xkZXI6IHRoaXMuaTE4bi50KCdlZGl0b3IucGxhY2Vob2xkZXInKSxcbiAgICB0aGVtZTogJ3Nub3cnLFxuICB9O1xuXG4gIHByaXZhdGUgX3N1YnNjcmlwdGlvbnM6IFN1YnNjcmlwdGlvbltdID0gW107XG5cbiAgcHJpdmF0ZSBfZWRpdG9yU2VsZWN0aW9uSGFuZGxlcjogRW1pdHRlcjtcblxuICBwcml2YXRlIF9lZGl0b3JDaGFuZ2VIYW5kbGVyOiBFbWl0dGVyO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgZWRpdG9yU2VydmljZSA9IGluamVjdChEc2ZyRWRpdG9yU2VydmljZSk7XG5cbiAgY29uc3RydWN0b3IoKSB7fVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLl9xdWlsbCA9IG5ldyBRdWlsbCgnIycgKyB0aGlzLmVkaXRvcklkLCB0aGlzLl9vcHRpb25zKTtcbiAgICB0aGlzLl9xdWlsbC5yb290LnNldEF0dHJpYnV0ZSgncm9sZScsICd0ZXh0Ym94Jyk7XG4gICAgdGhpcy5fcXVpbGwucm9vdC5zZXRBdHRyaWJ1dGUoJ2FyaWEtbXVsdGlsaW5lJywgJ3RydWUnKTtcbiAgICB0aGlzLl9xdWlsbC5yb290LnNldEF0dHJpYnV0ZSgnc3BlbGxjaGVjaycsICdmYWxzZScpO1xuICAgIC8vIGZpeCBhMTF5IDogcGFyIGTDqWZhdXQsIGxlIGtleS1iaW5kaW5nIFF1aWxsIHN1ciBsYSB0b3VjaGUgVGFiIGVtcMOqY2hlIGRlIHNvcnRpciBkZSBsJ8OpZGl0ZXVyIGVuIHV0aWxpc2FudCBUYWJcbiAgICBkZWxldGUgKHRoaXMuX3F1aWxsLmdldE1vZHVsZSgna2V5Ym9hcmQnKSBhcyBhbnkpPy5iaW5kaW5nc1snVGFiJ107XG5cbiAgICBpZiAodGhpcy5hcmlhTGFiZWxsZWRCeSAmJiB0aGlzLmFyaWFMYWJlbGxlZEJ5Lmxlbmd0aCkge1xuICAgICAgdGhpcy5fcXVpbGwucm9vdC5zZXRBdHRyaWJ1dGUoJ2FyaWEtbGFiZWxsZWRieScsIHRoaXMuYXJpYUxhYmVsbGVkQnkpO1xuICAgIH1cbiAgICBpZiAodGhpcy5tZXNzYWdlICYmIHRoaXMubWVzc2FnZS5sZW5ndGggJiYgdGhpcy5tZXNzYWdlc0dyb3VwSWQgJiYgdGhpcy5tZXNzYWdlc0dyb3VwSWQubGVuZ3RoKSB7XG4gICAgICB0aGlzLl9xdWlsbC5yb290LnNldEF0dHJpYnV0ZSgnYXJpYS1kZXNjcmliZWRieScsIHRoaXMubWVzc2FnZXNHcm91cElkKTtcbiAgICB9XG4gICAgLy8gT24gc2UgbWV0IMOgIGwnw6ljb3V0ZSBkZSBsYSBzw6lsZWN0aW9uIHV0aWxpc2F0ZXVyXG4gICAgdGhpcy5fZWRpdG9yU2VsZWN0aW9uSGFuZGxlciA9IHRoaXMuX3F1aWxsLm9uKEVtaXR0ZXIuZXZlbnRzLlNFTEVDVElPTl9DSEFOR0UsIChyYW5nZSkgPT5cbiAgICAgIHRoaXMuX29uRWRpdG9yU2VsZWN0aW9uQ2hhbmdlKHJhbmdlKSxcbiAgICApO1xuICAgIC8vIETDqXRlY3RlIGxlIGNoYW5nZW1lbnQgZGUgY29udGVudSBkZSBsJ8OpZGl0ZXVyLlxuICAgIHRoaXMuX2VkaXRvckNoYW5nZUhhbmRsZXIgPSB0aGlzLl9xdWlsbC5vbihcbiAgICAgIEVtaXR0ZXIuZXZlbnRzLkVESVRPUl9DSEFOR0UsXG4gICAgICAoZXZlbnROYW1lOiBhbnksIGRlbHRhOiBEZWx0YSwgb2xkQ29udGVudHM6IERlbHRhLCBzb3VyY2U6IHN0cmluZykgPT5cbiAgICAgICAgdGhpcy5fb25FZGl0b3JDaGFuZ2UoZXZlbnROYW1lLCBkZWx0YSwgb2xkQ29udGVudHMsIHNvdXJjZSksXG4gICAgKTtcblxuICAgIHRoaXMuX3N1YnNjcmlwdGlvbnMucHVzaChcbiAgICAgIHRoaXMuZWRpdG9yU2VydmljZS5mb3JtYXR0aW5nUmVxdWVzdCQuc3Vic2NyaWJlKChyZXE6IEZvcm1hdHRpbmdSZXF1ZXN0KSA9PiB7XG4gICAgICAgIGNvbnN0IHJhbmdlID0gdGhpcy5fcXVpbGwuZ2V0U2VsZWN0aW9uKCk7XG4gICAgICAgIGlmIChyZXEgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGlmIChyYW5nZSkge1xuICAgICAgICAgICAgLy8gcmVtb3ZlIGZvcm1hdHRpbmdcbiAgICAgICAgICAgIHRoaXMuX3F1aWxsLnJlbW92ZUZvcm1hdChyYW5nZS5pbmRleCwgcmFuZ2UubGVuZ3RoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoJ2ltYWdlJyA9PT0gcmVxLmFjdGlvbikge1xuICAgICAgICAgIC8vIHBlcmZvcm0gc3BlY2lhbCBpbWFnZSBmb3JtYXRcbiAgICAgICAgICBpZiAocmFuZ2UpIHtcbiAgICAgICAgICAgIHRoaXMuX3F1aWxsLnVwbG9hZGVyLnVwbG9hZChyYW5nZSwgcmVxLnZhbHVlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gcGVyZm9ybSBzdGFuZGFydCBmb3JtYXR0aW5nXG4gICAgICAgICAgdGhpcy5fcXVpbGwuZm9ybWF0KHJlcS5hY3Rpb24sIHJlcS52YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5lZGl0b3JTZXJ2aWNlLnNldEN1cnJlbnRGb3JtYXR0aW5nKHRoaXMuX2dldEN1cnJlbnRGb3JtYXR0aW5nKCkpO1xuICAgICAgfSksXG4gICAgKTtcbiAgICAvLyDDiWNvdXRlIGxlcyBtaXNlcyDDoCBqb3VyIGR1IG1vZMOobGUgZXh0ZXJuZS5cbiAgICB0aGlzLl9zdWJzY3JpcHRpb25zLnB1c2goXG4gICAgICB0aGlzLmVkaXRvclNlcnZpY2UubW9kZWxDaGFuZ2UkLnN1YnNjcmliZSgobmV3VmFsdWU6IHN0cmluZykgPT4ge1xuICAgICAgICB0aGlzLnNldEVkaXRvckNvbnRlbnQobmV3VmFsdWUpO1xuICAgICAgfSksXG4gICAgKTtcbiAgICAvLyDDiWNvdXRlIGxlcyBkZW1hbmRlcyBkZSBwcmlzZSBkZSBmb2N1c1xuICAgIHRoaXMuX3N1YnNjcmlwdGlvbnMucHVzaChcbiAgICAgIHRoaXMuZWRpdG9yU2VydmljZS5mb2N1c09uRWRpdG9yUmVxdWVzdCQuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgdGhpcy5fcXVpbGwuZm9jdXMoKTtcbiAgICAgIH0pLFxuICAgICk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLl9zdWJzY3JpcHRpb25zLmZvckVhY2goKHMpID0+IHMudW5zdWJzY3JpYmUoKSk7XG4gICAgdGhpcy5fcXVpbGwub2ZmKEVtaXR0ZXIuZXZlbnRzLlNFTEVDVElPTl9DSEFOR0UsIHRoaXMuX2VkaXRvclNlbGVjdGlvbkhhbmRsZXIub2ZmKTtcbiAgICB0aGlzLl9xdWlsbC5vZmYoRW1pdHRlci5ldmVudHMuRURJVE9SX0NIQU5HRSwgdGhpcy5fZWRpdG9yQ2hhbmdlSGFuZGxlci5vZmYpO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoeyBhcmlhTGFiZWxsZWRCeSwgbWVzc2FnZSwgbWVzc2FnZXNHcm91cElkIH06IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBpZiAoYXJpYUxhYmVsbGVkQnkpIHtcbiAgICAgIGlmICh0aGlzLmFyaWFMYWJlbGxlZEJ5ICYmIHRoaXMuYXJpYUxhYmVsbGVkQnkubGVuZ3RoKSB7XG4gICAgICAgIHRoaXMuX3F1aWxsPy5yb290LnNldEF0dHJpYnV0ZSgnYXJpYS1sYWJlbGxlZGJ5JywgdGhpcy5hcmlhTGFiZWxsZWRCeSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9xdWlsbD8ucm9vdC5yZW1vdmVBdHRyaWJ1dGUoJ2FyaWEtbGFiZWxsZWRieScpO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAobWVzc2FnZSB8fCBtZXNzYWdlc0dyb3VwSWQpIHtcbiAgICAgIGlmICh0aGlzLm1lc3NhZ2UgJiYgdGhpcy5tZXNzYWdlLmxlbmd0aCAmJiB0aGlzLm1lc3NhZ2VzR3JvdXBJZCAmJiB0aGlzLm1lc3NhZ2VzR3JvdXBJZC5sZW5ndGgpIHtcbiAgICAgICAgdGhpcy5fcXVpbGw/LnJvb3Quc2V0QXR0cmlidXRlKCdhcmlhLWRlc2NyaWJlZGJ5JywgdGhpcy5tZXNzYWdlc0dyb3VwSWQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5fcXVpbGw/LnJvb3QucmVtb3ZlQXR0cmlidXRlKCdhcmlhLWRlc2NyaWJlZGJ5Jyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIGhhc01lc3NhZ2Uoc2V2ZXJpdHk6IERzZnJTZXZlcml0eSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhdGhpcy5pc1N0cmluZ0VtcHR5T3JOdWxsKHRoaXMubWVzc2FnZSkgJiYgc2V2ZXJpdHkgPT09IHRoaXMubWVzc2FnZVNldmVyaXR5O1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRFZGl0b3JDb250ZW50KG5ld1ZhbHVlOiBzdHJpbmcpIHtcbiAgICB0aGlzLl9xdWlsbC5zZXRDb250ZW50cyh0aGlzLl9xdWlsbC5jbGlwYm9hcmQuY29udmVydCh7IGh0bWw6IG5ld1ZhbHVlIH0pLCAnc2lsZW50Jyk7XG4gIH1cblxuICAvL0ZJWE1FOiB1dGlsaXNlciBsZXMgdXRpbHMgZGUgbGEgbGliIG5neC1kc2ZyXG4gIHByaXZhdGUgaXNTdHJpbmdFbXB0eU9yTnVsbChzOiBzdHJpbmcgfCBudWxsIHwgdW5kZWZpbmVkKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICFzIHx8IHMudHJpbSgpID09PSAnJztcbiAgfVxuXG4gIHByaXZhdGUgX29uRWRpdG9yU2VsZWN0aW9uQ2hhbmdlKHJhbmdlOiB7IGluZGV4OiBudW1iZXI7IGxlbmd0aDogbnVtYmVyIH0pIHtcbiAgICAvLyBSUEE6IHZ1IGF2ZWMgU0FCIGxlIDI1LzA5LzIwMjQgOiBvbiBjb25zaWTDqHJlIHF1ZSBsYSB0b29sYmFyIHJlZmzDqHRlIGwnw6l0YXQgY291cmFudCByZWxhdGlmIMOgIGxhIHBvc2l0aW9uIGR1XG4gICAgLy8gY3Vyc2V1ciBldC9vdSBsYSBzw6lsZWN0aW9uIGFjdGl2ZSBkYW5zIGwnw6lkaXRldXJcbiAgICAvLyBzaSBvbiBjaGFuZ2UgZCdhdmlzIGV0IHF1J29uIG9uIHZldXQgY29uc2VydmVyIGwnw6l0YXQgZGUgbGEgdG9vbGJhciBjb3JyZXNwb25kYW50IMOgIGxhIGRlcm5pw6hyZSBwb3NpdGlvbiBkdVxuICAgIC8vIGN1cnNldXIgYXZhbnQgdW5lIHBlcnRlIGRlIGZvY3VzIGRlIGwnw6lkaXRldXIgYWxvcnMgaWwgbmUgZmF1dCBwYXMgw6ltZXR0cmUgZCdldmVudCBzaSByYW5nZT09bnVsbFxuICAgIHRoaXMuZWRpdG9yU2VydmljZS5zZXRDdXJyZW50Rm9ybWF0dGluZyh0aGlzLl9nZXRDdXJyZW50Rm9ybWF0dGluZygpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQZXJtZXQgZGUgc2UgbWV0dHJlIMOgIGwnw6ljb3V0ZSBkdSBjb250ZW51IGRlIGwnw6lkaXRldXIgYWZpbiBkZSByZXNldCBsYSB0b29sYmFyIHNpIGwnw6lkaXRldXIgZXN0IHZpZMOpLlxuICAgKi9cbiAgcHJpdmF0ZSBfb25FZGl0b3JDaGFuZ2UoZXZlbnROYW1lOiBzdHJpbmcsIGRlbHRhOiBEZWx0YSwgb2xkQ29udGVudHM6IERlbHRhLCBzb3VyY2U6IHN0cmluZykge1xuICAgIGlmIChldmVudE5hbWUgPT09ICd0ZXh0LWNoYW5nZScpIHtcbiAgICAgIC8vIE5vdGUgZXZlbiB3aGVuIFF1aWxsIGlzIGVtcHR5LCB0aGVyZSBpcyBzdGlsbCBhIGJsYW5rIGxpbmUgcmVwcmVzZW50ZWQgYnkgJ1xcbicsIHNvIGdldExlbmd0aCB3aWxsIHJldHVybiAxLlxuICAgICAgaWYgKHRoaXMuX3F1aWxsLmdldExlbmd0aCgpID09PSAxKSB7XG4gICAgICAgIHRoaXMuZWRpdG9yU2VydmljZS5zZXRDdXJyZW50Rm9ybWF0dGluZyh1bmRlZmluZWQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5lZGl0b3JTZXJ2aWNlLnNldEN1cnJlbnRGb3JtYXR0aW5nKHRoaXMuX2dldEN1cnJlbnRGb3JtYXR0aW5nKCkpO1xuICAgICAgfVxuICAgICAgLy8gb24gc2lnbmFsZSBsZSBjaGFuZ2VtZW50IMOgIGwnZXh0w6lyaWV1clxuICAgICAgdGhpcy5lZGl0b3JTZXJ2aWNlLmVtaXRFZGl0b3JDaGFuZ2UodGhpcy5fcXVpbGwuZ2V0U2VtYW50aWNIVE1MKCkpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX2dldEN1cnJlbnRGb3JtYXR0aW5nKCk6IEZvcm1hdHRpbmcgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IHJhbmdlOiBSYW5nZSB8IG51bGwgPSB0aGlzLl9xdWlsbC5nZXRTZWxlY3Rpb24oKTtcbiAgICByZXR1cm4gcmFuZ2UgPyB0aGlzLl9xdWlsbC5nZXRGb3JtYXQocmFuZ2UuaW5kZXgsIHJhbmdlLmxlbmd0aCkgOiB1bmRlZmluZWQ7XG4gIH1cbn1cbiIsIjxkaXYgaWQ9XCJ7eyBlZGl0b3JJZCB9fVwiPjwvZGl2PlxuXG48ZGl2IGNsYXNzPVwiZnItbWVzc2FnZXMtZ3JvdXBcIiBbaWRdPVwibWVzc2FnZXNHcm91cElkXCIgYXJpYS1saXZlPVwicG9saXRlXCI+XG4gIEBpZiAobWVzc2FnZSkge1xuICAgIDxwXG4gICAgICBjbGFzcz1cImZyLW1lc3NhZ2VcIlxuICAgICAgW25nQ2xhc3NdPVwie1xuICAgICAgICAnZnItbWVzc2FnZS0tZXJyb3InOiBoYXNNZXNzYWdlKHNldmVyaXR5Q29uc3QuRVJST1IpLFxuICAgICAgICAnZnItbWVzc2FnZS0tdmFsaWQnOiBoYXNNZXNzYWdlKHNldmVyaXR5Q29uc3QuU1VDQ0VTUyksXG4gICAgICAgICdmci1tZXNzYWdlLS1pbmZvJzogaGFzTWVzc2FnZShzZXZlcml0eUNvbnN0LklORk8pXG4gICAgICB9XCI+XG4gICAgICB7eyBtZXNzYWdlIH19XG4gICAgPC9wPlxuICB9XG48L2Rpdj5cblxuQGlmIChzaG93RWRpdG9ySHRtbERlYnVnUGFuZWwpIHtcbiAgPGRpdiBjbGFzcz1cImRlYnVnLXBhbmVsXCI+XG4gICAgPHA+RWRpdG9yIHNvdXJjZTwvcD5cbiAgICA8Y29kZT57eyBfcXVpbGw/LnJvb3Q/LmlubmVySFRNTCB9fTwvY29kZT5cbiAgPC9kaXY+XG59XG5cbkBpZiAoc2hvd1NlbWFudGljSHRtbERlYnVnUGFuZWwpIHtcbiAgPGRpdiBjbGFzcz1cImRlYnVnLXBhbmVsXCI+XG4gICAgPHA+SFRNTCBvdXRwdXQ8L3A+XG4gICAgPGNvZGU+e3sgX3F1aWxsPy5nZXRTZW1hbnRpY0hUTUwoKSB9fTwvY29kZT5cbiAgPC9kaXY+XG59XG4iXX0=