UNPKG

@edugouvfr/ngx-dsfr-ext

Version:

NgxDsfrExt est une extension au package @edugouvfr/ngx-dsfr (portage Angular des éléments DSFR)

166 lines 22.1 kB
/** * TreeFocusManager a pour objectif de : * - Gérer le focus dans un arbre lié aux événements clavier de navigation, * - Gérer l'ouverture la fermeture des nœuds */ export class TreeFocusManager { constructor(treeFocusable) { this.treeFocusable = treeFocusable; } /** * Initialise le tabindex du 1er élément sur lequel placer un focus */ initTabindex() { const elements = this.treeFocusable.findVisibleNodesElt(); if (elements && elements.length > 0) { elements[0].tabIndex = 0; this.firstNodeElt = elements[0]; // Notre composant prend le focus. Est-ce ce que l'on veut par défaut ? this.firstNodeElt.focus({ preventScroll: true }); this.setAriaActiveDescendant(this.firstNodeElt); } } /** Ouvre tous les nœuds de l'arborescence. */ expandAll(nodes) { this.setNodesExpanded(nodes, true); } /** Ferme tous les nœuds de l'arborescence. */ collapseAll(nodes) { this.setNodesExpanded(nodes, false); } /** * Répond à un événement clavier. * @param currentNode nœud courant (qui possède le focus) * @event event événement clavier */ doKeyEvent(currentNode, event, isParentSelectable) { switch (event.code) { case 'Space': case 'Enter': if (!currentNode.disabled && (!currentNode.children || isParentSelectable)) this.treeFocusable.doNodeDefaultAction(currentNode, event); break; case 'ArrowLeft': this.doCollapseNode(currentNode); break; case 'ArrowRight': this.doExpandNode(currentNode); break; case 'ArrowDown': this.doFocusNext(); break; case 'ArrowUp': this.doFocusPrevious(); break; case 'Home': this.doFocusFirst(); break; case 'End': this.doFocusLast(); break; default: return; // no prevent Default on others cases } event.preventDefault(); event.stopPropagation(); } /** Bascule l'état ouvert / fermé du nœud. */ doToggleExpand(node) { node.expanded = !node.expanded; } /** * Gestion du scroll dans la liste lors de la navigation clavier avec virtualScroll activé * @param viewport composant de virtualScroll CDK */ scrollForVirtualScroll(viewport) { const prevOffset = this.currentElt?.offsetTop ?? 0; if (!this.currentElt?.offsetTop || prevOffset > this.currentElt?.offsetTop) { viewport.scrollToOffset(prevOffset); } else { this.currentElt?.scrollIntoView({ behavior: 'smooth', block: 'center' }); } this.currentElt = this.treeFocusable.findFocusElement(); this.currentElt?.focus(); } /** Place le focus sur le 1er élément visible. */ doFocusFirst() { const elements = this.treeFocusable.findVisibleNodesElt(); const count = elements.length; if (count > 0) { elements[0].focus(); this.setAriaActiveDescendant(elements[0]); } } /** Place le focus sur le dernier élément visible. */ doFocusLast() { const elements = this.treeFocusable.findVisibleNodesElt(); const count = elements.length; if (count > 0) { elements[count - 1].focus(); this.setAriaActiveDescendant(elements[count - 1]); } } /** Place le focus sur l'élément suivant l'élément courant. */ doFocusNext() { const elements = this.treeFocusable.findVisibleNodesElt(); this.currentElt = this.treeFocusable.findFocusElement(); const index = elements.findIndex((elt) => elt === this.currentElt); // Si on est déjà sur le dernier élément, on y reste const nextIndex = index === elements.length - 1 ? index : index + 1; const nextElt = elements[nextIndex]; if (this.currentElt) this.currentElt.tabIndex = -1; if (nextElt && nextElt !== this.currentElt) { nextElt.tabIndex = 0; nextElt.focus(); this.setAriaActiveDescendant(nextElt); } } /** Place le focus sur l'élément précédant le nœud courant. */ doFocusPrevious() { const elements = this.treeFocusable.findVisibleNodesElt(); if (!elements) return; this.currentElt = this.treeFocusable.findFocusElement(); const index = elements.findIndex((elt) => elt === this.currentElt); // Si on est déjà sur le premier élément, on y reste const prevIndex = index === 0 ? index : index - 1; const prevElt = elements[prevIndex]; if (this.currentElt) this.currentElt.tabIndex = -1; if (prevElt && prevElt !== this.currentElt) { prevElt.tabIndex = 0; prevElt?.focus(); this.setAriaActiveDescendant(prevElt); } } /** Ferme le nœud. */ doCollapseNode(node) { node.expanded = false; } /** Ouvre le nœud. */ doExpandNode(node) { node.expanded = true; } /** * Ouvre / ferme récursivement tous les nœuds nodes et leurs descendants * @param nodes Liste de nœuds à ouvrir * @param expand true : ouverture des nœuds, false : fermeture */ setNodesExpanded(nodes, expand) { nodes.forEach((node) => { if (node.children) { node.expanded = expand; this.setNodesExpanded(node.children, expand); } }); } /** Set focus on element and add aria-activedescendant attribute to parent */ setAriaActiveDescendant(optionEl) { const optionId = optionEl.getAttribute('id'); if (optionId) optionEl.closest('ul')?.setAttribute('aria-activedescendant', optionId); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJlZS1mb2N1cy1tYW5hZ2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWRzZnItZXh0L3NyYy9saWIvc2hhcmVkL3V0aWxzL3RyZWUvdHJlZS1mb2N1cy1tYW5hZ2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQTJCQTs7OztHQUlHO0FBQ0gsTUFBTSxPQUFPLGdCQUFnQjtJQVEzQixZQUFZLGFBQTRCO1FBQ3RDLElBQUksQ0FBQyxhQUFhLEdBQUcsYUFBYSxDQUFDO0lBQ3JDLENBQUM7SUFFRDs7T0FFRztJQUNJLFlBQVk7UUFDakIsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1FBQzFELElBQUksUUFBUSxJQUFJLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDcEMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsR0FBRyxDQUFDLENBQUM7WUFDekIsSUFBSSxDQUFDLFlBQVksR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDaEMsdUVBQXVFO1lBQ3ZFLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLEVBQUUsYUFBYSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7WUFDakQsSUFBSSxDQUFDLHVCQUF1QixDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUNsRCxDQUFDO0lBQ0gsQ0FBQztJQUVELDhDQUE4QztJQUN2QyxTQUFTLENBQUMsS0FBaUI7UUFDaEMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQztJQUNyQyxDQUFDO0lBRUQsOENBQThDO0lBQ3ZDLFdBQVcsQ0FBQyxLQUFpQjtRQUNsQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ3RDLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ksVUFB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Q0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQy9DLENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCw2RUFBNkU7SUFDckUsdUJBQXVCLENBQUMsUUFBcUI7UUFDbkQsTUFBTSxRQUFRLEdBQThCLFFBQVEsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDeEUsSUFBSSxRQUFRO1lBQUUsUUFBUSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRSxZQUFZLENBQUMsdUJBQXVCLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDeEYsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2RrVmlydHVhbFNjcm9sbFZpZXdwb3J0IH0gZnJvbSAnQGFuZ3VsYXIvY2RrL3Njcm9sbGluZyc7XG5pbXBvcnQgeyBEc2ZyTm9kZSB9IGZyb20gJy4vdHJlZS5tb2RlbCc7XG5cbi8qKlxuICogSW50ZXJmYWNlIHV0aWxpc8OpZSBwYXIgVHJlZUZvY3VzTWFuYWdlclxuICovXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXG5leHBvcnQgaW50ZXJmYWNlIFRyZWVGb2N1c2FibGUge1xuICAvKiogUmV0b3VybmUgbGEgc3RydWN0dXJlIGFyYm9yZXNjZW50ZSBkdSBjb21wb3NhbnQuICovXG4gIGdldCBub2RlcygpOiBEc2ZyTm9kZVtdO1xuXG4gIC8qKiBPdXZyZSB0b3VzIGxlcyBuxZN1ZHMgZGUgbCdhcmJvcmVzY2VuY2UuICovXG4gIGV4cGFuZEFsbCgpOiB2b2lkO1xuXG4gIC8qKiBGZXJtZSB0b3VzIGxlcyBuxZN1ZHMgZGUgbCdhcmJvcmVzY2VuY2UuICovXG4gIGNvbGxhcHNlQWxsKCk6IHZvaWQ7XG5cbiAgLyoqIEVmZmVjdHVlIGwnYWN0aW9uIHBhciBkw6lmYXV0IChzw6lsZWN0aW9uIC8gZMOpc2VsZWN0aW9uKSBzdXIgbGUgbsWTdWQgY291cmFudC4gKi9cbiAgZG9Ob2RlRGVmYXVsdEFjdGlvbihub2RlOiBEc2ZyTm9kZSwgZXZlbnQ6IEV2ZW50KTogdm9pZDtcblxuICAvKiogUmVjaGVyY2hlIGxhIGxpc3RlIGRlcyBuxZN1ZHMgdmlzaWJsZXMsIGNlIHNvbnQgbGVzIMOpbMOpbWVudHMgcXVpIHBvc3PDqWRlcm9udCBsZSB0YWJpbmRleCAqL1xuICBmaW5kVmlzaWJsZU5vZGVzRWx0KCk6IEhUTUxFbGVtZW50W107XG5cbiAgLyoqIFJldG91cm5lIGwnw6lsw6ltZW50IGF2ZWMgZm9jdXMgb3UgdW5kZWZpbmVkLiAqL1xuICBmaW5kRm9jdXNFbGVtZW50KCk6IEhUTUxFbGVtZW50IHwgdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIFRyZWVGb2N1c01hbmFnZXIgYSBwb3VyIG9iamVjdGlmIGRlIDpcbiAqIC0gR8OpcmVyIGxlIGZvY3VzIGRhbnMgdW4gYXJicmUgbGnDqSBhdXggw6l2w6luZW1lbnRzIGNsYXZpZXIgZGUgbmF2aWdhdGlvbixcbiAqIC0gR8OpcmVyIGwnb3V2ZXJ0dXJlIGxhIGZlcm1ldHVyZSBkZXMgbsWTdWRzXG4gKi9cbmV4cG9ydCBjbGFzcyBUcmVlRm9jdXNNYW5hZ2VyIHtcbiAgY3VycmVudEVsdDogSFRNTEVsZW1lbnQgfCB1bmRlZmluZWQ7XG5cbiAgLyoqIENvbXBvc2FudCBnw6lyw6kgcGFyIGxlIG1hbmFnZXIuICovXG4gIHByaXZhdGUgdHJlZUZvY3VzYWJsZTogVHJlZUZvY3VzYWJsZTtcblxuICBwcml2YXRlIGZpcnN0Tm9kZUVsdDogSFRNTEVsZW1lbnQ7XG5cbiAgY29uc3RydWN0b3IodHJlZUZvY3VzYWJsZTogVHJlZUZvY3VzYWJsZSkge1xuICAgIHRoaXMudHJlZUZvY3VzYWJsZSA9IHRyZWVGb2N1c2FibGU7XG4gIH1cblxuICAvKipcbiAgICogSW5pdGlhbGlzZSBsZSB0YWJpbmRleCBkdSAxZXIgw6lsw6ltZW50IHN1ciBsZXF1ZWwgcGxhY2VyIHVuIGZvY3VzXG4gICAqL1xuICBwdWJsaWMgaW5pdFRhYmluZGV4KCk6IHZvaWQge1xuICAgIGNvbnN0IGVsZW1lbnRzID0gdGhpcy50cmVlRm9jdXNhYmxlLmZpbmRWaXNpYmxlTm9kZXNFbHQoKTtcbiAgICBpZiAoZWxlbWVudHMgJiYgZWxlbWVudHMubGVuZ3RoID4gMCkge1xuICAgICAgZWxlbWVudHNbMF0udGFiSW5kZXggPSAwO1xuICAgICAgdGhpcy5maXJzdE5vZGVFbHQgPSBlbGVtZW50c1swXTtcbiAgICAgIC8vIE5vdHJlIGNvbXBvc2FudCBwcmVuZCBsZSBmb2N1cy4gRXN0LWNlIGNlIHF1ZSBsJ29uIHZldXQgcGFyIGTDqWZhdXQgP1xuICAgICAgdGhpcy5maXJzdE5vZGVFbHQuZm9jdXMoeyBwcmV2ZW50U2Nyb2xsOiB0cnVlIH0pO1xuICAgICAgdGhpcy5zZXRBcmlhQWN0aXZlRGVzY2VuZGFudCh0aGlzLmZpcnN0Tm9kZUVsdCk7XG4gICAgfVxuICB9XG5cbiAgLyoqIE91dnJlIHRvdXMgbGVzIG7Fk3VkcyBkZSBsJ2FyYm9yZXNjZW5jZS4gKi9cbiAgcHVibGljIGV4cGFuZEFsbChub2RlczogRHNmck5vZGVbXSk6IHZvaWQge1xuICAgIHRoaXMuc2V0Tm9kZXNFeHBhbmRlZChub2RlcywgdHJ1ZSk7XG4gIH1cblxuICAvKiogRmVybWUgdG91cyBsZXMgbsWTdWRzIGRlIGwnYXJib3Jlc2NlbmNlLiAqL1xuICBwdWJsaWMgY29sbGFwc2VBbGwobm9kZXM6IERzZnJOb2RlW10pOiB2b2lkIHtcbiAgICB0aGlzLnNldE5vZGVzRXhwYW5kZWQobm9kZXMsIGZhbHNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSw6lwb25kIMOgIHVuIMOpdsOpbmVtZW50IGNsYXZpZXIuXG4gICAqIEBwYXJhbSBjdXJyZW50Tm9kZSBuxZN1ZCBjb3VyYW50IChxdWkgcG9zc8OoZGUgbGUgZm9jdXMpXG4gICAqIEBldmVudCBldmVudCDDqXbDqW5lbWVudCBjbGF2aWVyXG4gICAqL1xuICBwdWJsaWMgZG9LZXlFdmVudChjdXJyZW50Tm9kZTogRHNmck5vZGUsIGV2ZW50OiBLZXlib2FyZEV2ZW50LCBpc1BhcmVudFNlbGVjdGFibGU6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBzd2l0Y2ggKGV2ZW50LmNvZGUpIHtcbiAgICAgIGNhc2UgJ1NwYWNlJzpcbiAgICAgIGNhc2UgJ0VudGVyJzpcbiAgICAgICAgaWYgKCFjdXJyZW50Tm9kZS5kaXNhYmxlZCAmJiAoIWN1cnJlbnROb2RlLmNoaWxkcmVuIHx8IGlzUGFyZW50U2VsZWN0YWJsZSkpXG4gICAgICAgICAgdGhpcy50cmVlRm9jdXNhYmxlLmRvTm9kZURlZmF1bHRBY3Rpb24oY3VycmVudE5vZGUsIGV2ZW50KTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ0Fycm93TGVmdCc6XG4gICAgICAgIHRoaXMuZG9Db2xsYXBzZU5vZGUoY3VycmVudE5vZGUpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnQXJyb3dSaWdodCc6XG4gICAgICAgIHRoaXMuZG9FeHBhbmROb2RlKGN1cnJlbnROb2RlKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ0Fycm93RG93bic6XG4gICAgICAgIHRoaXMuZG9Gb2N1c05leHQoKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ0Fycm93VXAnOlxuICAgICAgICB0aGlzLmRvRm9jdXNQcmV2aW91cygpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnSG9tZSc6XG4gICAgICAgIHRoaXMuZG9Gb2N1c0ZpcnN0KCk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdFbmQnOlxuICAgICAgICB0aGlzLmRvRm9jdXNMYXN0KCk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm47IC8vIG5vIHByZXZlbnQgRGVmYXVsdCBvbiBvdGhlcnMgY2FzZXNcbiAgICB9XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgfVxuXG4gIC8qKiBCYXNjdWxlIGwnw6l0YXQgb3V2ZXJ0IC8gZmVybcOpIGR1IG7Fk3VkLiAqL1xuICBkb1RvZ2dsZUV4cGFuZChub2RlOiBEc2ZyTm9kZSkge1xuICAgIG5vZGUuZXhwYW5kZWQgPSAhbm9kZS5leHBhbmRlZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXN0aW9uIGR1IHNjcm9sbCBkYW5zIGxhIGxpc3RlIGxvcnMgZGUgbGEgbmF2aWdhdGlvbiBjbGF2aWVyIGF2ZWMgdmlydHVhbFNjcm9sbCBhY3RpdsOpXG4gICAqIEBwYXJhbSB2aWV3cG9ydCBjb21wb3NhbnQgZGUgdmlydHVhbFNjcm9sbCBDREtcbiAgICovXG4gIHB1YmxpYyBzY3JvbGxGb3JWaXJ0dWFsU2Nyb2xsKHZpZXdwb3J0OiBDZGtWaXJ0dWFsU2Nyb2xsVmlld3BvcnQpOiB2b2lkIHtcbiAgICBjb25zdCBwcmV2T2Zmc2V0ID0gdGhpcy5jdXJyZW50RWx0Py5vZmZzZXRUb3AgPz8gMDtcblxuICAgIGlmICghdGhpcy5jdXJyZW50RWx0Py5vZmZzZXRUb3AgfHwgcHJldk9mZnNldCA+IHRoaXMuY3VycmVudEVsdD8ub2Zmc2V0VG9wKSB7XG4gICAgICB2aWV3cG9ydC5zY3JvbGxUb09mZnNldChwcmV2T2Zmc2V0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5jdXJyZW50RWx0Py5zY3JvbGxJbnRvVmlldyh7IGJlaGF2aW9yOiAnc21vb3RoJywgYmxvY2s6ICdjZW50ZXInIH0pO1xuICAgIH1cblxuICAgIHRoaXMuY3VycmVudEVsdCA9IHRoaXMudHJlZUZvY3VzYWJsZS5maW5kRm9jdXNFbGVtZW50KCk7XG4gICAgdGhpcy5jdXJyZW50RWx0Py5mb2N1cygpO1xuICB9XG5cbiAgLyoqIFBsYWNlIGxlIGZvY3VzIHN1ciBsZSAxZXIgw6lsw6ltZW50IHZpc2libGUuICovXG4gIHByaXZhdGUgZG9Gb2N1c0ZpcnN0KCk6IHZvaWQge1xuICAgIGNvbnN0IGVsZW1lbnRzID0gdGhpcy50cmVlRm9jdXNhYmxlLmZpbmRWaXNpYmxlTm9kZXNFbHQoKTtcbiAgICBjb25zdCBjb3VudCA9IGVsZW1lbnRzLmxlbmd0aDtcbiAgICBpZiAoY291bnQgPiAwKSB7XG4gICAgICBlbGVtZW50c1swXS5mb2N1cygpO1xuICAgICAgdGhpcy5zZXRBcmlhQWN0aXZlRGVzY2VuZGFudChlbGVtZW50c1swXSk7XG4gICAgfVxuICB9XG5cbiAgLyoqIFBsYWNlIGxlIGZvY3VzIHN1ciBsZSBkZXJuaWVyIMOpbMOpbWVudCB2aXNpYmxlLiAqL1xuICBwcml2YXRlIGRvRm9jdXNMYXN0KCk6IHZvaWQge1xuICAgIGNvbnN0IGVsZW1lbnRzID0gdGhpcy50cmVlRm9jdXNhYmxlLmZpbmRWaXNpYmxlTm9kZXNFbHQoKTtcbiAgICBjb25zdCBjb3VudCA9IGVsZW1lbnRzLmxlbmd0aDtcbiAgICBpZiAoY291bnQgPiAwKSB7XG4gICAgICBlbGVtZW50c1tjb3VudCAtIDFdLmZvY3VzKCk7XG4gICAgICB0aGlzLnNldEFyaWFBY3RpdmVEZXNjZW5kYW50KGVsZW1lbnRzW2NvdW50IC0gMV0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBQbGFjZSBsZSBmb2N1cyBzdXIgbCfDqWzDqW1lbnQgc3VpdmFudCBsJ8OpbMOpbWVudCBjb3VyYW50LiAqL1xuICBwcml2YXRlIGRvRm9jdXNOZXh0KCk6IHZvaWQge1xuICAgIGNvbnN0IGVsZW1lbnRzID0gdGhpcy50cmVlRm9jdXNhYmxlLmZpbmRWaXNpYmxlTm9kZXNFbHQoKTtcbiAgICB0aGlzLmN1cnJlbnRFbHQgPSB0aGlzLnRyZWVGb2N1c2FibGUuZmluZEZvY3VzRWxlbWVudCgpO1xuICAgIGNvbnN0IGluZGV4ID0gZWxlbWVudHMuZmluZEluZGV4KChlbHQ6IEhUTUxFbGVtZW50KSA9PiBlbHQgPT09IHRoaXMuY3VycmVudEVsdCk7XG5cbiAgICAvLyBTaSBvbiBlc3QgZMOpasOgIHN1ciBsZSBkZXJuaWVyIMOpbMOpbWVudCwgb24geSByZXN0ZVxuICAgIGNvbnN0IG5leHRJbmRleCA9IGluZGV4ID09PSBlbGVtZW50cy5sZW5ndGggLSAxID8gaW5kZXggOiBpbmRleCArIDE7XG4gICAgY29uc3QgbmV4dEVsdCA9IGVsZW1lbnRzW25leHRJbmRleF07XG4gICAgaWYgKHRoaXMuY3VycmVudEVsdCkgdGhpcy5jdXJyZW50RWx0LnRhYkluZGV4ID0gLTE7XG5cbiAgICBpZiAobmV4dEVsdCAmJiBuZXh0RWx0ICE9PSB0aGlzLmN1cnJlbnRFbHQpIHtcbiAgICAgIG5leHRFbHQudGFiSW5kZXggPSAwO1xuICAgICAgbmV4dEVsdC5mb2N1cygpO1xuICAgICAgdGhpcy5zZXRBcmlhQWN0aXZlRGVzY2VuZGFudChuZXh0RWx0KTtcbiAgICB9XG4gIH1cblxuICAvKiogUGxhY2UgbGUgZm9jdXMgc3VyIGwnw6lsw6ltZW50IHByw6ljw6lkYW50IGxlIG7Fk3VkIGNvdXJhbnQuICovXG4gIHByaXZhdGUgZG9Gb2N1c1ByZXZpb3VzKCk6IHZvaWQge1xuICAgIGNvbnN0IGVsZW1lbnRzID0gdGhpcy50cmVlRm9jdXNhYmxlLmZpbmRWaXNpYmxlTm9kZXNFbHQoKTtcbiAgICBpZiAoIWVsZW1lbnRzKSByZXR1cm47XG4gICAgdGhpcy5jdXJyZW50RWx0ID0gdGhpcy50cmVlRm9jdXNhYmxlLmZpbmRGb2N1c0VsZW1lbnQoKTtcbiAgICBjb25zdCBpbmRleCA9IGVsZW1lbnRzLmZpbmRJbmRleCgoZWx0OiBIVE1MRWxlbWVudCkgPT4gZWx0ID09PSB0aGlzLmN1cnJlbnRFbHQpO1xuICAgIC8vIFNpIG9uIGVzdCBkw6lqw6Agc3VyIGxlIHByZW1pZXIgw6lsw6ltZW50LCBvbiB5IHJlc3RlXG4gICAgY29uc3QgcHJldkluZGV4ID0gaW5kZXggPT09IDAgPyBpbmRleCA6IGluZGV4IC0gMTtcbiAgICBjb25zdCBwcmV2RWx0ID0gZWxlbWVudHNbcHJldkluZGV4XTtcblxuICAgIGlmICh0aGlzLmN1cnJlbnRFbHQpIHRoaXMuY3VycmVudEVsdC50YWJJbmRleCA9IC0xO1xuXG4gICAgaWYgKHByZXZFbHQgJiYgcHJldkVsdCAhPT0gdGhpcy5jdXJyZW50RWx0KSB7XG4gICAgICBwcmV2RWx0LnRhYkluZGV4ID0gMDtcbiAgICAgIHByZXZFbHQ/LmZvY3VzKCk7XG4gICAgICB0aGlzLnNldEFyaWFBY3RpdmVEZXNjZW5kYW50KHByZXZFbHQpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBGZXJtZSBsZSBuxZN1ZC4gKi9cbiAgcHJpdmF0ZSBkb0NvbGxhcHNlTm9kZShub2RlOiBEc2ZyTm9kZSk6IHZvaWQge1xuICAgIG5vZGUuZXhwYW5kZWQgPSBmYWxzZTtcbiAgfVxuXG4gIC8qKiBPdXZyZSBsZSBuxZN1ZC4gKi9cbiAgcHJpdmF0ZSBkb0V4cGFuZE5vZGUobm9kZTogRHNmck5vZGUpOiB2b2lkIHtcbiAgICBub2RlLmV4cGFuZGVkID0gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBPdXZyZSAvIGZlcm1lIHLDqWN1cnNpdmVtZW50IHRvdXMgbGVzIG7Fk3VkcyBub2RlcyBldCBsZXVycyBkZXNjZW5kYW50c1xuICAgKiBAcGFyYW0gbm9kZXMgTGlzdGUgZGUgbsWTdWRzIMOgIG91dnJpclxuICAgKiBAcGFyYW0gZXhwYW5kIHRydWUgOiBvdXZlcnR1cmUgZGVzIG7Fk3VkcywgZmFsc2UgOiBmZXJtZXR1cmVcbiAgICovXG4gIHByaXZhdGUgc2V0Tm9kZXNFeHBhbmRlZChub2RlczogRHNmck5vZGVbXSwgZXhwYW5kOiBib29sZWFuKTogdm9pZCB7XG4gICAgbm9kZXMuZm9yRWFjaCgobm9kZSkgPT4ge1xuICAgICAgaWYgKG5vZGUuY2hpbGRyZW4pIHtcbiAgICAgICAgbm9kZS5leHBhbmRlZCA9IGV4cGFuZDtcbiAgICAgICAgdGhpcy5zZXROb2Rlc0V4cGFuZGVkKG5vZGUuY2hpbGRyZW4sIGV4cGFuZCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKiogU2V0IGZvY3VzIG9uIGVsZW1lbnQgYW5kIGFkZCBhcmlhLWFjdGl2ZWRlc2NlbmRhbnQgYXR0cmlidXRlIHRvIHBhcmVudCAqL1xuICBwcml2YXRlIHNldEFyaWFBY3RpdmVEZXNjZW5kYW50KG9wdGlvbkVsOiBIVE1MRWxlbWVudCk6IHZvaWQge1xuICAgIGNvbnN0IG9wdGlvbklkOiBzdHJpbmcgfCB1bmRlZmluZWQgfCBudWxsID0gb3B0aW9uRWwuZ2V0QXR0cmlidXRlKCdpZCcpO1xuICAgIGlmIChvcHRpb25JZCkgb3B0aW9uRWwuY2xvc2VzdCgndWwnKT8uc2V0QXR0cmlidXRlKCdhcmlhLWFjdGl2ZWRlc2NlbmRhbnQnLCBvcHRpb25JZCk7XG4gIH1cbn1cbiJdfQ==