UNPKG

@microsoft/windows-admin-center-sdk

Version:

Microsoft - Windows Admin Center Shell

232 lines 28.9 kB
import { Directive, EventEmitter, HostListener, Injector, Input, Output } from '@angular/core'; import { CoreBaseComponent } from '../../controls/common/base.component'; import * as i0 from "@angular/core"; export var Unicode; (function (Unicode) { Unicode["HorizontalEllipsis"] = "\u2026"; })(Unicode || (Unicode = {})); const breakAllClass = 'sme-arrange-word-break-all'; /** * * @smeDoc {@label Clamp @id sme-clamp-directive} * * @overview * @file {@filepath ./examples/clamp-overview.md} * * @example {@label Basic Usage @id basic-usage} * @file {@filename component.html @filepath ./examples/basic-usage.component.html} * @file {@filename component.ts @filepath ./examples/basic-usage.component.ts} * * @example {@label Clamp with auto lines @id auto-lines} * @file {@filename component.html @filepath ./examples/auto-lines-clamp.component.html} * @file {@filename component.ts @filepath ./examples/auto-lines-clamp.component.ts} * */ export class ClampDirective extends CoreBaseComponent { /** * Constructs a new instance of the ClampDirective * @param injector The injector for the sme base component */ constructor(injector) { super(injector); /** * Event that outputs a value indicating whether the content is clamped or not */ this.clamped = new EventEmitter(); } /** * The source name to use for logging */ get logSourceName() { return 'ClampDirective'; } /** * The number of lines to clamp to */ get lineCount() { // get the lineCount let lineCount = MsftSme.isNumber(this.smeClampLines) ? this.smeClampLines : 'auto'; // calc line count if it is auto if (lineCount === 'auto') { lineCount = this.hostElement.nativeElement.offsetHeight / this.lineHeight; } // make sure line count is at least 1 line return Math.max(lineCount, 1); } /** * The height that the clamp should be contained within */ get clampHeight() { return this.lineCount * this.lineHeight; } /** * The line height of this element */ get lineHeight() { return parseInt(window.getComputedStyle(this.hostElement.nativeElement).lineHeight, 10); } /** * Indicates that content overflows the desired height of the clamp */ get needsClamping() { return this.hostElement.nativeElement.scrollHeight > this.clampHeight; } get renderedLines() { return this.hostElement.nativeElement.scrollHeight / this.lineHeight; } get breakWords() { return this.hostElement.nativeElement.classList.contains(breakAllClass); } /** * Host listener for page resize event. */ onResize() { // reset initial content state this.resetClampContent(); if (this.needsClamping) { this.clamp(this.hostElement.nativeElement); } } /** * Implementation of angular OnChanges interface * On every input change, we recalculate the clamp. */ ngOnChanges(changes) { super.ngOnChanges(changes); if (changes.smeClamp) { // reset initial content state this.resetClampContent(); } // if the input changes require clamping again, then re-clamp if (this.needsClamping) { this.clamp(this.hostElement.nativeElement); } } setBreakWords() { const element = this.hostElement.nativeElement; if (!element.classList.contains(breakAllClass)) { element.classList.add(breakAllClass); } } removeBreakWords() { const element = this.hostElement.nativeElement; if (element.classList.contains(breakAllClass)) { element.classList.remove(breakAllClass); } } resetClampContent() { // reset initial content state this.removeBreakWords(); this.hostElement.nativeElement.innerHTML = this.smeClamp || ''; // whenever this changes, we need to measure and output whether the content will be clamped. this.clamped.emit({ clamped: this.needsClamping }); } /** * Gets the initial host classes to be applied to this element */ getInitialHostClasses() { return super.getInitialHostClasses().concat([ 'sme-arrange-line-clamp' ]); } /** * Clamps the text of a node by doing a last child first process of * eliminating text until the host element fits in the clamp height. * while this method should support HTML content, our input to this directive is a string for now. * @param node The node to clamp * @returns true if the node was successfully clamped */ clamp(node) { // Process the children of the node we want to clamp, starting with the last node for (let i = node.childNodes.length - 1; i > -1; i--) { const child = node.childNodes[i]; // We only care about text and element nodes. let isClamped = false; if (child.nodeType === Node.ELEMENT_NODE) { // dive into element nodes recursively isClamped = this.clamp(child); } else if (child.nodeType === Node.TEXT_NODE) { // When we find a text node, try clamping it. let text = node.textContent; const originalText = text; // first trim words until the content fits while (text.length > 1) { // remove the last word from the text node.textContent = this.trimLastWord(text); if (this.renderedLines < this.lineCount) { // We went too far there must be a big word here, add back the last word and break node.textContent = text; if (!this.breakWords) { this.setBreakWords(); text = originalText; continue; } break; } // Stop if we are down to one word (trim didn't change text) or we are short enough to not need clamping if (node.textContent === text || !this.needsClamping) { // make sure text and node content are the same (in the case clamping is no longer needed) text = node.textContent; break; } // we still have more words to trim text = node.textContent; } // now that we are trimmed down on words, remove characters until the text fits with the ellipsis while (text.length > 1) { // Trim off one trailing character and any trailing whitespace. text = text.substring(0, text.length - 1).trimRight(); // set the node content to our text, plus a unicode ellipses node.textContent = `${text}${Unicode.HorizontalEllipsis}`; // Stop if no more clamping is needed. if (!this.needsClamping) { // We successfully clamped the text isClamped = true; break; } } } // We are done if the clamp is satisfied if (isClamped) { return true; } else { // if the current node does not satisfy the clamp, remove it as it is to big to fit. node.removeChild(child); } } return false; } /** * Trims the last word from the string, or returns the original string if there is only one word * @param text the text to trim */ trimLastWord(text) { const lastSpace = text.lastIndexOf(' '); if (lastSpace === -1) { return text; } return text.substring(0, lastSpace); } } /** @nocollapse */ ClampDirective.ɵfac = function ClampDirective_Factory(t) { return new (t || ClampDirective)(i0.ɵɵdirectiveInject(i0.Injector)); }; /** @nocollapse */ ClampDirective.ɵdir = /** @pureOrBreakMyCode */ i0.ɵɵdefineDirective({ type: ClampDirective, selectors: [["", "smeClamp", ""]], hostBindings: function ClampDirective_HostBindings(rf, ctx) { if (rf & 1) { i0.ɵɵlistener("resize", function ClampDirective_resize_HostBindingHandler() { return ctx.onResize(); }, false, i0.ɵɵresolveWindow); } }, inputs: { smeClamp: "smeClamp", smeClampLines: "smeClampLines" }, outputs: { clamped: "clamped" }, features: [i0.ɵɵInheritDefinitionFeature, i0.ɵɵNgOnChangesFeature] }); (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ClampDirective, [{ type: Directive, args: [{ selector: '[smeClamp]' }] }], function () { return [{ type: i0.Injector }]; }, { smeClamp: [{ type: Input }], smeClampLines: [{ type: Input }], clamped: [{ type: Output }], onResize: [{ type: HostListener, args: ['window:resize'] }] }); })(); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhbXAuZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vYW5ndWxhci9zcmMvZGlyZWN0aXZlcy9jbGFtcC9jbGFtcC5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsWUFBWSxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQWEsTUFBTSxFQUFpQixNQUFNLGVBQWUsQ0FBQztBQUN6SCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxzQ0FBc0MsQ0FBQzs7QUFFekUsTUFBTSxDQUFOLElBQVksT0FFWDtBQUZELFdBQVksT0FBTztJQUNmLHdDQUE2QixDQUFBO0FBQ2pDLENBQUMsRUFGVyxPQUFPLEtBQVAsT0FBTyxRQUVsQjtBQVNELE1BQU0sYUFBYSxHQUFHLDRCQUE0QixDQUFDO0FBRW5EOzs7Ozs7Ozs7Ozs7Ozs7R0FlRztBQUtILE1BQU0sT0FBTyxjQUFlLFNBQVEsaUJBQWlCO0lBcUVqRDs7O09BR0c7SUFDSCxZQUFZLFFBQWtCO1FBQzFCLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztRQXhEcEI7O1dBRUc7UUFFSSxZQUFPLEdBQUcsSUFBSSxZQUFZLEVBQWdCLENBQUM7SUFxRGxELENBQUM7SUF6RUQ7O09BRUc7SUFDSCxJQUFjLGFBQWE7UUFDdkIsT0FBTyxnQkFBZ0IsQ0FBQztJQUM1QixDQUFDO0lBaUJEOztPQUVHO0lBQ0gsSUFBWSxTQUFTO1FBQ2pCLG9CQUFvQjtRQUNwQixJQUFJLFNBQVMsR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDO1FBRW5GLGdDQUFnQztRQUNoQyxJQUFJLFNBQVMsS0FBSyxNQUFNLEVBQUU7WUFDdEIsU0FBUyxHQUFHLElBQUksQ0FBQyxXQUFX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SUFBSSxDQUFDO1NBQ2Y7UUFDRCxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFDO0lBQ3hDLENBQUM7OytGQWhPUSxjQUFjO2dHQUFkLGNBQWM7NkZBQWQsY0FBVTs7dUZBQVYsY0FBYztjQUgxQixTQUFTO2VBQUM7Z0JBQ1AsUUFBUSxFQUFFLFlBQVk7YUFDekI7MkRBWW1CLFFBQVE7a0JBQXZCLEtBQUs7WUFLVSxhQUFhO2tCQUE1QixLQUFLO1lBTUMsT0FBTztrQkFEYixNQUFNO1lBNERBLFFBQVE7a0JBRGQsWUFBWTttQkFBQyxlQUFlIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRGlyZWN0aXZlLCBFdmVudEVtaXR0ZXIsIEhvc3RMaXN0ZW5lciwgSW5qZWN0b3IsIElucHV0LCBPbkNoYW5nZXMsIE91dHB1dCwgU2ltcGxlQ2hhbmdlcyB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBDb3JlQmFzZUNvbXBvbmVudCB9IGZyb20gJy4uLy4uL2NvbnRyb2xzL2NvbW1vbi9iYXNlLmNvbXBvbmVudCc7XHJcblxyXG5leHBvcnQgZW51bSBVbmljb2RlIHtcclxuICAgIEhvcml6b250YWxFbGxpcHNpcyA9ICdcXHUyMDI2J1xyXG59XHJcblxyXG4vKipcclxuICogRGVzY3JpYmVzIHRoZSBjbGFtcGVkIGV2ZW50IG9mIHRoZSBDbGFtcERpcmVjdGl2ZVxyXG4gKi9cclxuZXhwb3J0IGludGVyZmFjZSBDbGFtcGVkRXZlbnQge1xyXG4gICAgY2xhbXBlZDogYm9vbGVhbjtcclxufVxyXG5cclxuY29uc3QgYnJlYWtBbGxDbGFzcyA9ICdzbWUtYXJyYW5nZS13b3JkLWJyZWFrLWFsbCc7XHJcblxyXG4vKipcclxuICpcclxuICogQHNtZURvYyB7QGxhYmVsIENsYW1wIEBpZCBzbWUtY2xhbXAtZGlyZWN0aXZlfVxyXG4gKlxyXG4gKiBAb3ZlcnZpZXdcclxuICogQGZpbGUge0BmaWxlcGF0aCAuL2V4YW1wbGVzL2NsYW1wLW92ZXJ2aWV3Lm1kfVxyXG4gKlxyXG4gKiBAZXhhbXBsZSB7QGxhYmVsIEJhc2ljIFVzYWdlIEBpZCBiYXNpYy11c2FnZX1cclxuICogQGZpbGUge0BmaWxlbmFtZSBjb21wb25lbnQuaHRtbCBAZmlsZXBhdGggLi9leGFtcGxlcy9iYXNpYy11c2FnZS5jb21wb25lbnQuaHRtbH1cclxuICogQGZpbGUge0BmaWxlbmFtZSBjb21wb25lbnQudHMgQGZpbGVwYXRoIC4vZXhhbXBsZXMvYmFzaWMtdXNhZ2UuY29tcG9uZW50LnRzfVxyXG4gKlxyXG4gKiBAZXhhbXBsZSB7QGxhYmVsIENsYW1wIHdpdGggYXV0byBsaW5lcyBAaWQgYXV0by1saW5lc31cclxuICogQGZpbGUge0BmaWxlbmFtZSBjb21wb25lbnQuaHRtbCBAZmlsZXBhdGggLi9leGFtcGxlcy9hdXRvLWxpbmVzLWNsYW1wLmNvbXBvbmVudC5odG1sfVxyXG4gKiBAZmlsZSB7QGZpbGVuYW1lIGNvbXBvbmVudC50cyBAZmlsZXBhdGggLi9leGFtcGxlcy9hdXRvLWxpbmVzLWNsYW1wLmNvbXBvbmVudC50c31cclxuICpcclxuICovXHJcblxyXG5ARGlyZWN0aXZlKHtcclxuICAgIHNlbGVjdG9yOiAnW3NtZUNsYW1wXSdcclxufSlcclxuZXhwb3J0IGNsYXNzIENsYW1wRGlyZWN0aXZlIGV4dGVuZHMgQ29yZUJhc2VDb21wb25lbnQgaW1wbGVtZW50cyBPbkNoYW5nZXMge1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIHNvdXJjZSBuYW1lIHRvIHVzZSBmb3IgbG9nZ2luZ1xyXG4gICAgICovXHJcbiAgICBwcm90ZWN0ZWQgZ2V0IGxvZ1NvdXJjZU5hbWUoKSB7XHJcbiAgICAgICAgcmV0dXJuICdDbGFtcERpcmVjdGl2ZSc7XHJcbiAgICB9XHJcbiAgICAvKipcclxuICAgICAqIFRoZSBjb250ZW50IHRvIGNsYW1wLlxyXG4gICAgICovXHJcbiAgICBASW5wdXQoKSBwdWJsaWMgc21lQ2xhbXA7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgbnVtYmVyIG9mIGxpbmVzIHRvIGNsYW1wLCBvciBhdXRvIHRvIGNsYW1wIHdoYXRldmVyIHdpbGwgZml0IGluIHRoZSBlbGVtZW50XHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpIHB1YmxpYyBzbWVDbGFtcExpbmVzOiBudW1iZXIgfCAnYXV0byc7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBFdmVudCB0aGF0IG91dHB1dHMgYSB2YWx1ZSBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIGNvbnRlbnQgaXMgY2xhbXBlZCBvciBub3RcclxuICAgICAqL1xyXG4gICAgQE91dHB1dCgpXHJcbiAgICBwdWJsaWMgY2xhbXBlZCA9IG5ldyBFdmVudEVtaXR0ZXI8Q2xhbXBlZEV2ZW50PigpO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIG51bWJlciBvZiBsaW5lcyB0byBjbGFtcCB0b1xyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGdldCBsaW5lQ291bnQoKTogbnVtYmVyIHtcclxuICAgICAgICAvLyBnZXQgdGhlIGxpbmVDb3VudFxyXG4gICAgICAgIGxldCBsaW5lQ291bnQgPSBNc2Z0U21lLmlzTnVtYmVyKHRoaXMuc21lQ2xhbXBMaW5lcykgPyB0aGlzLnNtZUNsYW1wTGluZXMgOiAnYXV0byc7XHJcblxyXG4gICAgICAgIC8vIGNhbGMgbGluZSBjb3VudCBpZiBpdCBpcyBhdXRvXHJcbiAgICAgICAgaWYgKGxpbmVDb3VudCA9PT0gJ2F1dG8nKSB7XHJcbiAgICAgICAgICAgIGxpbmVDb3VudCA9IHRoaXMuaG9zdEVsZW1lbnQubmF0aXZlRWxlbWVudC5vZmZzZXRIZWlnaHQgLyB0aGlzLmxpbmVIZWlnaHQ7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBtYWtlIHN1cmUgbGluZSBjb3VudCBpcyBhdCBsZWFzdCAxIGxpbmVcclxuICAgICAgICByZXR1cm4gTWF0aC5tYXgobGluZUNvdW50LCAxKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBoZWlnaHQgdGhhdCB0aGUgY2xhbXAgc2hvdWxkIGJlIGNvbnRhaW5lZCB3aXRoaW5cclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBnZXQgY2xhbXBIZWlnaHQoKTogbnVtYmVyIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5saW5lQ291bnQgKiB0aGlzLmxpbmVIZWlnaHQ7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgbGluZSBoZWlnaHQgb2YgdGhpcyBlbGVtZW50XHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgZ2V0IGxpbmVIZWlnaHQoKTogbnVtYmVyIHtcclxuICAgICAgICByZXR1cm4gcGFyc2VJbnQod2luZG93LmdldENvbXB1dGVkU3R5bGUodGhpcy5ob3N0RWxlbWVudC5uYXRpdmVFbGVtZW50KS5saW5lSGVpZ2h0LCAxMCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJbmRpY2F0ZXMgdGhhdCBjb250ZW50IG92ZXJmbG93cyB0aGUgZGVzaXJlZCBoZWlnaHQgb2YgdGhlIGNsYW1wXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgZ2V0IG5lZWRzQ2xhbXBpbmcoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuaG9zdEVsZW1lbnQubmF0aXZlRWxlbWVudC5zY3JvbGxIZWlnaHQgPiB0aGlzLmNsYW1wSGVpZ2h0O1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgZ2V0IHJlbmRlcmVkTGluZXMoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuaG9zdEVsZW1lbnQubmF0aXZlRWxlbWVudC5zY3JvbGxIZWlnaHQgLyB0aGlzLmxpbmVIZWlnaHQ7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBnZXQgYnJlYWtXb3JkcygpIHtcclxuICAgICAgICByZXR1cm4gKDxIVE1MRWxlbWVudD50aGlzLmhvc3RFbGVtZW50Lm5hdGl2ZUVsZW1lbnQpLmNsYXNzTGlzdC5jb250YWlucyhicmVha0FsbENsYXNzKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIENsYW1wRGlyZWN0aXZlXHJcbiAgICAgKiBAcGFyYW0gaW5qZWN0b3IgVGhlIGluamVjdG9yIGZvciB0aGUgc21lIGJhc2UgY29tcG9uZW50XHJcbiAgICAgKi9cclxuICAgIGNvbnN0cnVjdG9yKGluamVjdG9yOiBJbmplY3Rvcikge1xyXG4gICAgICAgIHN1cGVyKGluamVjdG9yKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEhvc3QgbGlzdGVuZXIgZm9yIHBhZ2UgcmVzaXplIGV2ZW50LlxyXG4gICAgICovXHJcbiAgICBASG9zdExpc3RlbmVyKCd3aW5kb3c6cmVzaXplJylcclxuICAgIHB1YmxpYyBvblJlc2l6ZSgpIHtcclxuICAgICAgICAvLyByZXNldCBpbml0aWFsIGNvbnRlbnQgc3RhdGVcclxuICAgICAgICB0aGlzLnJlc2V0Q2xhbXBDb250ZW50KCk7XHJcbiAgICAgICAgaWYgKHRoaXMubmVlZHNDbGFtcGluZykge1xyXG4gICAgICAgICAgICB0aGlzLmNsYW1wKHRoaXMuaG9zdEVsZW1lbnQubmF0aXZlRWxlbWVudCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogSW1wbGVtZW50YXRpb24gb2YgYW5ndWxhciBPbkNoYW5nZXMgaW50ZXJmYWNlXHJcbiAgICAgKiBPbiBldmVyeSBpbnB1dCBjaGFuZ2UsIHdlIHJlY2FsY3VsYXRlIHRoZSBjbGFtcC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpIHtcclxuICAgICAgICBzdXBlci5uZ09uQ2hhbmdlcyhjaGFuZ2VzKTtcclxuICAgICAgICBpZiAoY2hhbmdlcy5zbWVDbGFtcCkge1xyXG4gICAgICAgICAgICAvLyByZXNldCBpbml0aWFsIGNvbnRlbnQgc3RhdGVcclxuICAgICAgICAgICAgdGhpcy5yZXNldENsYW1wQ29udGVudCgpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gaWYgdGhlIGlucHV0IGNoYW5nZXMgcmVxdWlyZSBjbGFtcGluZyBhZ2FpbiwgdGhlbiByZS1jbGFtcFxyXG4gICAgICAgIGlmICh0aGlzLm5lZWRzQ2xhbXBpbmcpIHtcclxuICAgICAgICAgICAgdGhpcy5jbGFtcCh0aGlzLmhvc3RFbGVtZW50Lm5hdGl2ZUVsZW1lbnQpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHNldEJyZWFrV29yZHMoKSB7XHJcbiAgICAgICAgY29uc3QgZWxlbWVudCA9ICg8SFRNTEVsZW1lbnQ+dGhpcy5ob3N0RWxlbWVudC5uYXRpdmVFbGVtZW50KTtcclxuICAgICAgICBpZiAoIWVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKGJyZWFrQWxsQ2xhc3MpKSB7XHJcbiAgICAgICAgICAgIGVsZW1lbnQuY2xhc3NMaXN0LmFkZChicmVha0FsbENsYXNzKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSByZW1vdmVCcmVha1dvcmRzKCkge1xyXG4gICAgICAgIGNvbnN0IGVsZW1lbnQgPSAoPEhUTUxFbGVtZW50PnRoaXMuaG9zdEVsZW1lbnQubmF0aXZlRWxlbWVudCk7XHJcbiAgICAgICAgaWYgKGVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKGJyZWFrQWxsQ2xhc3MpKSB7XHJcbiAgICAgICAgICAgIGVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShicmVha0FsbENsYXNzKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSByZXNldENsYW1wQ29udGVudCgpIHtcclxuICAgICAgICAvLyByZXNldCBpbml0aWFsIGNvbnRlbnQgc3RhdGVcclxuICAgICAgICB0aGlzLnJlbW92ZUJyZWFrV29yZHMoKTtcclxuICAgICAgICB0aGlzLmhvc3RFbGVtZW50Lm5hdGl2ZUVsZW1lbnQuaW5uZXJIVE1MID0gdGhpcy5zbWVDbGFtcCB8fCAnJztcclxuICAgICAgICAvLyB3aGVuZXZlciB0aGlzIGNoYW5nZXMsIHdlIG5lZWQgdG8gbWVhc3VyZSBhbmQgb3V0cHV0IHdoZXRoZXIgdGhlIGNvbnRlbnQgd2lsbCBiZSBjbGFtcGVkLlxyXG4gICAgICAgIHRoaXMuY2xhbXBlZC5lbWl0KHsgY2xhbXBlZDogdGhpcy5uZWVkc0NsYW1waW5nIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgaW5pdGlhbCBob3N0IGNsYXNzZXMgdG8gYmUgYXBwbGllZCB0byB0aGlzIGVsZW1lbnRcclxuICAgICAqL1xyXG4gICAgcHJvdGVjdGVkIGdldEluaXRpYWxIb3N0Q2xhc3NlcygpIHtcclxuICAgICAgICByZXR1cm4gc3VwZXIuZ2V0SW5pdGlhbEhvc3RDbGFzc2VzKCkuY29uY2F0KFtcclxuICAgICAgICAgICAgJ3NtZS1hcnJhbmdlLWxpbmUtY2xhbXAnXHJcbiAgICAgICAgXSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDbGFtcHMgdGhlIHRleHQgb2YgYSBub2RlIGJ5IGRvaW5nIGEgbGFzdCBjaGlsZCBmaXJzdCBwcm9jZXNzIG9mXHJcbiAgICAgKiBlbGltaW5hdGluZyB0ZXh0IHVudGlsIHRoZSBob3N0IGVsZW1lbnQgZml0cyBpbiB0aGUgY2xhbXAgaGVpZ2h0LlxyXG4gICAgICogd2hpbGUgdGhpcyBtZXRob2Qgc2hvdWxkIHN1cHBvcnQgSFRNTCBjb250ZW50LCBvdXIgaW5wdXQgdG8gdGhpcyBkaXJlY3RpdmUgaXMgYSBzdHJpbmcgZm9yIG5vdy5cclxuICAgICAqIEBwYXJhbSBub2RlIFRoZSBub2RlIHRvIGNsYW1wXHJcbiAgICAgKiBAcmV0dXJucyB0cnVlIGlmIHRoZSBub2RlIHdhcyBzdWNjZXNzZnVsbHkgY2xhbXBlZFxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGNsYW1wKG5vZGU6IE5vZGUpOiBib29sZWFuIHtcclxuICAgICAgICAvLyBQcm9jZXNzIHRoZSBjaGlsZHJlbiBvZiB0aGUgbm9kZSB3ZSB3YW50IHRvIGNsYW1wLCBzdGFydGluZyB3aXRoIHRoZSBsYXN0IG5vZGVcclxuICAgICAgICBmb3IgKGxldCBpID0gbm9kZS5jaGlsZE5vZGVzLmxlbmd0aCAtIDE7IGkgPiAtMTsgaS0tKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGNoaWxkID0gbm9kZS5jaGlsZE5vZGVzW2ldO1xyXG5cclxuICAgICAgICAgICAgLy8gV2Ugb25seSBjYXJlIGFib3V0IHRleHQgYW5kIGVsZW1lbnQgbm9kZXMuXHJcbiAgICAgICAgICAgIGxldCBpc0NsYW1wZWQgPSBmYWxzZTtcclxuICAgICAgICAgICAgaWYgKGNoaWxkLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERSkge1xyXG4gICAgICAgICAgICAgICAgLy8gZGl2ZSBpbnRvIGVsZW1lbnQgbm9kZXMgcmVjdXJzaXZlbHlcclxuICAgICAgICAgICAgICAgIGlzQ2xhbXBlZCA9IHRoaXMuY2xhbXAoY2hpbGQpO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNoaWxkLm5vZGVUeXBlID09PSBOb2RlLlRFWFRfTk9ERSkge1xyXG4gICAgICAgICAgICAgICAgLy8gIFdoZW4gd2UgZmluZCBhIHRleHQgbm9kZSwgdHJ5IGNsYW1waW5nIGl0LlxyXG4gICAgICAgICAgICAgICAgbGV0IHRleHQgPSBub2RlLnRleHRDb250ZW50O1xyXG4gICAgICAgICAgICAgICAgY29uc3Qgb3JpZ2luYWxUZXh0ID0gdGV4dDtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBmaXJzdCB0cmltIHdvcmRzIHVudGlsIHRoZSBjb250ZW50IGZpdHNcclxuICAgICAgICAgICAgICAgIHdoaWxlICh0ZXh0Lmxlbmd0aCA+IDEpIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyByZW1vdmUgdGhlIGxhc3Qgd29yZCBmcm9tIHRoZSB0ZXh0XHJcbiAgICAgICAgICAgICAgICAgICAgbm9kZS50ZXh0Q29udGVudCA9IHRoaXMudHJpbUxhc3RXb3JkKHRleHQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5yZW5kZXJlZExpbmVzIDwgdGhpcy5saW5lQ291bnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gV2Ugd2VudCB0b28gZmFyIHRoZXJlIG11c3QgYmUgYSBiaWcgd29yZCBoZXJlLCBhZGQgYmFjayB0aGUgbGFzdCB3b3JkIGFuZCBicmVha1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBub2RlLnRleHRDb250ZW50ID0gdGV4dDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLmJyZWFrV29yZHMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0QnJlYWtXb3JkcygpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dCA9IG9yaWdpbmFsVGV4dDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gU3RvcCBpZiB3ZSBhcmUgZG93biB0byBvbmUgd29yZCAodHJpbSBkaWRuJ3QgY2hhbmdlIHRleHQpIG9yIHdlIGFyZSBzaG9ydCBlbm91Z2ggdG8gbm90IG5lZWQgY2xhbXBpbmdcclxuICAgICAgICAgICAgICAgICAgICBpZiAobm9kZS50ZXh0Q29udGVudCA9PT0gdGV4dCB8fCAhdGhpcy5uZWVkc0NsYW1waW5nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1ha2Ugc3VyZSB0ZXh0IGFuZCBub2RlIGNvbnRlbnQgYXJlIHRoZSBzYW1lIChpbiB0aGUgY2FzZSBjbGFtcGluZyBpcyBubyBsb25nZXIgbmVlZGVkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0ZXh0ID0gbm9kZS50ZXh0Q29udGVudDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAvLyB3ZSBzdGlsbCBoYXZlIG1vcmUgd29yZHMgdG8gdHJpbVxyXG4gICAgICAgICAgICAgICAgICAgIHRleHQgPSBub2RlLnRleHRDb250ZW50O1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8vIG5vdyB0aGF0IHdlIGFyZSB0cmltbWVkIGRvd24gb24gd29yZHMsIHJlbW92ZSBjaGFyYWN0ZXJzIHVudGlsIHRoZSB0ZXh0IGZpdHMgd2l0aCB0aGUgZWxsaXBzaXNcclxuICAgICAgICAgICAgICAgIHdoaWxlICh0ZXh0Lmxlbmd0aCA+IDEpIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBUcmltIG9mZiBvbmUgdHJhaWxpbmcgY2hhcmFjdGVyIGFuZCBhbnkgdHJhaWxpbmcgd2hpdGVzcGFjZS5cclxuICAgICAgICAgICAgICAgICAgICB0ZXh0ID0gPHN0cmluZz4oPGFueT50ZXh0LnN1YnN0cmluZygwLCB0ZXh0Lmxlbmd0aCAtIDEpKS50cmltUmlnaHQoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gc2V0IHRoZSBub2RlIGNvbnRlbnQgdG8gb3VyIHRleHQsIHBsdXMgYSB1bmljb2RlIGVsbGlwc2VzXHJcbiAgICAgICAgICAgICAgICAgICAgbm9kZS50ZXh0Q29udGVudCA9IGAke3RleHR9JHtVbmljb2RlLkhvcml6b250YWxFbGxpcHNpc31gO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvLyBTdG9wIGlmIG5vIG1vcmUgY2xhbXBpbmcgaXMgbmVlZGVkLlxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5uZWVkc0NsYW1waW5nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdlIHN1Y2Nlc3NmdWxseSBjbGFtcGVkIHRoZSB0ZXh0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlzQ2xhbXBlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gV2UgYXJlIGRvbmUgaWYgdGhlIGNsYW1wIGlzIHNhdGlzZmllZFxyXG4gICAgICAgICAgICBpZiAoaXNDbGFtcGVkKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIC8vIGlmIHRoZSBjdXJyZW50IG5vZGUgZG9lcyBub3Qgc2F0aXNmeSB0aGUgY2xhbXAsIHJlbW92ZSBpdCBhcyBpdCBpcyB0byBiaWcgdG8gZml0LlxyXG4gICAgICAgICAgICAgICAgbm9kZS5yZW1vdmVDaGlsZChjaGlsZCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVHJpbXMgdGhlIGxhc3Qgd29yZCBmcm9tIHRoZSBzdHJpbmcsIG9yIHJldHVybnMgdGhlIG9yaWdpbmFsIHN0cmluZyBpZiB0aGVyZSBpcyBvbmx5IG9uZSB3b3JkXHJcbiAgICAgKiBAcGFyYW0gdGV4dCB0aGUgdGV4dCB0byB0cmltXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgdHJpbUxhc3RXb3JkKHRleHQ6IHN0cmluZykge1xyXG4gICAgICAgIGNvbnN0IGxhc3RTcGFjZSA9IHRleHQubGFzdEluZGV4T2YoJyAnKTtcclxuICAgICAgICBpZiAobGFzdFNwYWNlID09PSAtMSkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGV4dDtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRleHQuc3Vic3RyaW5nKDAsIGxhc3RTcGFjZSk7XHJcbiAgICB9XHJcbn1cclxuIl19