angular-instantsearch
Version:
Lightning-fast search for Angular apps, by Algolia.
184 lines (181 loc) • 18.9 kB
JavaScript
import { Component, Input, Output, EventEmitter, Inject, forwardRef, ViewChild, Optional, } from '@angular/core';
import { DOCUMENT } from '@angular/common';
import { connectSearchBox } from 'instantsearch.js/es/connectors';
import { TypedBaseWidget } from '../typed-base-widget';
import { NgAisInstantSearch } from '../instantsearch/instantsearch';
import { NgAisIndex } from '../index-widget/index-widget';
import { noop } from '../utils';
export class NgAisSearchBox extends TypedBaseWidget {
constructor(parentIndex, instantSearchInstance, injectedDocument) {
super('SearchBox');
this.parentIndex = parentIndex;
this.instantSearchInstance = instantSearchInstance;
this.injectedDocument = injectedDocument;
this.placeholder = 'Search';
this.submitTitle = 'Submit';
this.resetTitle = 'Reset';
this.searchAsYouType = true;
this.autofocus = false;
this.showLoadingIndicator = true;
// Output events
// form
this.submit = new EventEmitter();
this.reset = new EventEmitter();
// input
this.change = new EventEmitter();
this.focus = new EventEmitter();
this.blur = new EventEmitter();
this.query = '';
this.state = {
query: '',
refine: noop,
clear: noop,
isSearchStalled: false,
};
this.createWidget(connectSearchBox, {}, {
$$widgetType: 'ais.searchBox',
});
this.document = injectedDocument;
}
ngAfterViewInit() {
if (this.autofocus) {
this.searchBox.nativeElement.focus();
}
}
ngDoCheck() {
// We bypass the state update if the input is focused to avoid concurrent
// updates when typing.
if (this.query !== this.state.query &&
this.searchBox &&
this.searchBox.nativeElement &&
this.document.activeElement !== this.searchBox.nativeElement) {
this.query = this.state.query;
}
}
handleChange(query) {
this.change.emit(query);
if (this.searchAsYouType) {
this.state.refine(query);
}
}
handleSubmit(event) {
// send submit event to parent component
this.submit.emit(event);
event.preventDefault();
if (!this.searchAsYouType) {
this.state.refine(this.searchBox.nativeElement.value);
}
}
handleReset(event) {
// send reset event to parent component
this.reset.emit(event);
// reset search
this.state.refine('');
}
}
NgAisSearchBox.decorators = [
{ type: Component, args: [{
selector: 'ais-search-box',
template: `
<div [class]="cx()">
<form
[class]="cx('form')"
novalidate
(submit)="handleSubmit($event)"
>
<input
[class]="cx('input')"
autocapitalize="off"
autocorrect="off"
placeholder="{{placeholder}}"
role="textbox"
spellcheck="false"
type="text"
[value]="query"
(input)="handleChange($event.target.value)"
(focus)="focus.emit($event)"
(blur)="blur.emit($event)"
#searchBox
/>
<button
[class]="cx('submit')"
type="submit"
title="{{submitTitle}}"
>
<svg
[ngClass]="cx('submitIcon')"
viewBox="0 0 40 40"
width="40"
height="40"
>
<path d="M26.804 29.01c-2.832 2.34-6.465 3.746-10.426 3.746C7.333 32.756 0 25.424 0 16.378 0 7.333 7.333 0 16.378 0c9.046 0 16.378 7.333 16.378 16.378 0 3.96-1.406 7.594-3.746 10.426l10.534 10.534c.607.607.61 1.59-.004 2.202-.61.61-1.597.61-2.202.004L26.804 29.01zm-10.426.627c7.323 0 13.26-5.936 13.26-13.26 0-7.32-5.937-13.257-13.26-13.257C9.056 3.12 3.12 9.056 3.12 16.378c0 7.323 5.936 13.26 13.258 13.26z"></path>
</svg>
</button>
<button
[class]="cx('reset')"
type="reset"
title="{{resetTitle}}"
(click)="handleReset($event)"
[hidden]="!state.query || (state.query && !state.query.trim()) || (state.isSearchStalled && showLoadingIndicator)">
<svg
[ngClass]="cx('resetIcon')"
viewBox="0 0 20 20"
width="20"
height="20"
>
<path d="M8.114 10L.944 2.83 0 1.885 1.886 0l.943.943L10 8.113l7.17-7.17.944-.943L20 1.886l-.943.943-7.17 7.17 7.17 7.17.943.944L18.114 20l-.943-.943-7.17-7.17-7.17 7.17-.944.943L0 18.114l.943-.943L8.113 10z"></path>
</svg>
</button>
<span
[class]="cx('loadingIndicator')"
[hidden]="!showLoadingIndicator || !state.isSearchStalled"
>
<svg
width="16"
height="16"
viewBox="0 0 38 38"
stroke="#444"
[ngClass]="cx('loadingIcon')"
>
<g fill="none" fillRule="evenodd">
<g transform="translate(1 1)" strokeWidth="2">
<circle strokeOpacity=".5" cx="18" cy="18" r="18" />
<path d="M36 18c0-9.94-8.06-18-18-18">
<animateTransform
attributeName="transform"
type="rotate"
from="0 18 18"
to="360 18 18"
dur="1s"
repeatCount="indefinite"
/>
</path>
</g>
</g>
</svg>
</span>
</form>
</div>
`
},] }
];
NgAisSearchBox.ctorParameters = () => [
{ type: NgAisIndex, decorators: [{ type: Inject, args: [forwardRef(() => NgAisIndex),] }, { type: Optional }] },
{ type: NgAisInstantSearch, decorators: [{ type: Inject, args: [forwardRef(() => NgAisInstantSearch),] }] },
{ type: Document, decorators: [{ type: Inject, args: [DOCUMENT,] }] }
];
NgAisSearchBox.propDecorators = {
searchBox: [{ type: ViewChild, args: ['searchBox', { static: false },] }],
placeholder: [{ type: Input }],
submitTitle: [{ type: Input }],
resetTitle: [{ type: Input }],
searchAsYouType: [{ type: Input }],
autofocus: [{ type: Input }],
showLoadingIndicator: [{ type: Input }],
submit: [{ type: Output }],
reset: [{ type: Output }],
change: [{ type: Output }],
focus: [{ type: Output }],
blur: [{ type: Output }]
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VhcmNoLWJveC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9zZWFyY2gtYm94L3NlYXJjaC1ib3gudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFDVCxLQUFLLEVBQ0wsTUFBTSxFQUNOLFlBQVksRUFDWixNQUFNLEVBQ04sVUFBVSxFQUNWLFNBQVMsRUFHVCxRQUFRLEdBRVQsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRTNDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ2xFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUN2RCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNwRSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDMUQsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLFVBQVUsQ0FBQztBQThGaEMsTUFBTSxPQUFPLGNBQ1gsU0FBUSxlQUFxRTtJQWdDN0UsWUFHUyxXQUF1QixFQUV2QixxQkFBeUMsRUFDdEIsZ0JBQTBCO1FBRXBELEtBQUssQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUxaLGdCQUFXLEdBQVgsV0FBVyxDQUFZO1FBRXZCLDBCQUFxQixHQUFyQixxQkFBcUIsQ0FBb0I7UUFDdEIscUJBQWdCLEdBQWhCLGdCQUFnQixDQUFVO1FBbEN0QyxnQkFBVyxHQUFXLFFBQVEsQ0FBQztRQUMvQixnQkFBVyxHQUFXLFFBQVEsQ0FBQztRQUMvQixlQUFVLEdBQVcsT0FBTyxDQUFDO1FBQzdCLG9CQUFlLEdBQVksSUFBSSxDQUFDO1FBQ2hDLGNBQVMsR0FBWSxLQUFLLENBQUM7UUFDM0IseUJBQW9CLEdBQVksSUFBSSxDQUFDO1FBRXJELGdCQUFnQjtRQUNoQixPQUFPO1FBQ0csV0FBTSxHQUFHLElBQUks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Szt5QkFDTCxLQUFLOzhCQUNMLEtBQUs7d0JBQ0wsS0FBSzttQ0FDTCxLQUFLO3FCQUlMLE1BQU07b0JBQ04sTUFBTTtxQkFHTixNQUFNO29CQUNOLE1BQU07bUJBQ04sTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgSW5wdXQsXG4gIE91dHB1dCxcbiAgRXZlbnRFbWl0dGVyLFxuICBJbmplY3QsXG4gIGZvcndhcmRSZWYsXG4gIFZpZXdDaGlsZCxcbiAgQWZ0ZXJWaWV3SW5pdCxcbiAgRWxlbWVudFJlZixcbiAgT3B0aW9uYWwsXG4gIERvQ2hlY2ssXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRE9DVU1FTlQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuXG5pbXBvcnQgeyBjb25uZWN0U2VhcmNoQm94IH0gZnJvbSAnaW5zdGFudHNlYXJjaC5qcy9lcy9jb25uZWN0b3JzJztcbmltcG9ydCB7IFR5cGVkQmFzZVdpZGdldCB9IGZyb20gJy4uL3R5cGVkLWJhc2Utd2lkZ2V0JztcbmltcG9ydCB7IE5nQWlzSW5zdGFudFNlYXJjaCB9IGZyb20gJy4uL2luc3RhbnRzZWFyY2gvaW5zdGFudHNlYXJjaCc7XG5pbXBvcnQgeyBOZ0Fpc0luZGV4IH0gZnJvbSAnLi4vaW5kZXgtd2lkZ2V0L2luZGV4LXdpZGdldCc7XG5pbXBvcnQgeyBub29wIH0gZnJvbSAnLi4vdXRpbHMnO1xuaW1wb3J0IHtcbiAgU2VhcmNoQm94Q29ubmVjdG9yUGFyYW1zLFxuICBTZWFyY2hCb3hXaWRnZXREZXNjcmlwdGlvbixcbiAgU2VhcmNoQm94UmVuZGVyU3RhdGUsXG59IGZyb20gJ2luc3RhbnRzZWFyY2guanMvZXMvY29ubmVjdG9ycy9zZWFyY2gtYm94L2Nvbm5lY3RTZWFyY2hCb3gnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhaXMtc2VhcmNoLWJveCcsXG4gIHRlbXBsYXRlOiBgXG4gICAgPGRpdiBbY2xhc3NdPVwiY3goKVwiPlxuICAgICAgPGZvcm1cbiAgICAgICAgW2NsYXNzXT1cImN4KCdmb3JtJylcIlxuICAgICAgICBub3ZhbGlkYXRlXG4gICAgICAgIChzdWJtaXQpPVwiaGFuZGxlU3VibWl0KCRldmVudClcIlxuICAgICAgPlxuICAgICAgICA8aW5wdXRcbiAgICAgICAgICBbY2xhc3NdPVwiY3goJ2lucHV0JylcIlxuICAgICAgICAgIGF1dG9jYXBpdGFsaXplPVwib2ZmXCJcbiAgICAgICAgICBhdXRvY29ycmVjdD1cIm9mZlwiXG4gICAgICAgICAgcGxhY2Vob2xkZXI9XCJ7e3BsYWNlaG9sZGVyfX1cIlxuICAgICAgICAgIHJvbGU9XCJ0ZXh0Ym94XCJcbiAgICAgICAgICBzcGVsbGNoZWNrPVwiZmFsc2VcIlxuICAgICAgICAgIHR5cGU9XCJ0ZXh0XCJcbiAgICAgICAgICBbdmFsdWVdPVwicXVlcnlcIlxuICAgICAgICAgIChpbnB1dCk9XCJoYW5kbGVDaGFuZ2UoJGV2ZW50LnRhcmdldC52YWx1ZSlcIlxuICAgICAgICAgIChmb2N1cyk9XCJmb2N1cy5lbWl0KCRldmVudClcIlxuICAgICAgICAgIChibHVyKT1cImJsdXIuZW1pdCgkZXZlbnQpXCJcbiAgICAgICAgICAjc2VhcmNoQm94XG4gICAgICAgIC8+XG5cbiAgICAgICAgPGJ1dHRvblxuICAgICAgICAgIFtjbGFzc109XCJjeCgnc3VibWl0JylcIlxuICAgICAgICAgIHR5cGU9XCJzdWJtaXRcIlxuICAgICAgICAgIHRpdGxlPVwie3tzdWJtaXRUaXRsZX19XCJcbiAgICAgICAgPlxuICAgICAgICAgIDxzdmdcbiAgICAgICAgICAgIFtuZ0NsYXNzXT1cImN4KCdzdWJtaXRJY29uJylcIlxuICAgICAgICAgICAgdmlld0JveD1cIjAgMCA0MCA0MFwiXG4gICAgICAgICAgICB3aWR0aD1cIjQwXCJcbiAgICAgICAgICAgIGhlaWdodD1cIjQwXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8cGF0aCBkPVwiTTI2LjgwNCAyOS4wMWMtMi44MzIgMi4zNC02LjQ2NSAzLjc0Ni0xMC40MjYgMy43NDZDNy4zMzMgMzIuNzU2IDAgMjUuNDI0IDAgMTYuMzc4IDAgNy4zMzMgNy4zMzMgMCAxNi4zNzggMGM5LjA0NiAwIDE2LjM3OCA3LjMzMyAxNi4zNzggMTYuMzc4IDAgMy45Ni0xLjQwNiA3LjU5NC0zLjc0NiAxMC40MjZsMTAuNTM0IDEwLjUzNGMuNjA3LjYwNy42MSAxLjU5LS4wMDQgMi4yMDItLjYxLjYxLTEuNTk3LjYxLTIuMjAyLjAwNEwyNi44MDQgMjkuMDF6bS0xMC40MjYuNjI3YzcuMzIzIDAgMTMuMjYtNS45MzYgMTMuMjYtMTMuMjYgMC03LjMyLTUuOTM3LTEzLjI1Ny0xMy4yNi0xMy4yNTdDOS4wNTYgMy4xMiAzLjEyIDkuMDU2IDMuMTIgMTYuMzc4YzAgNy4zMjMgNS45MzYgMTMuMjYgMTMuMjU4IDEzLjI2elwiPjwvcGF0aD5cbiAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgPC9idXR0b24+XG5cbiAgICAgICAgPGJ1dHRvblxuICAgICAgICAgIFtjbGFzc109XCJjeCgncmVzZXQnKVwiXG4gICAgICAgICAgdHlwZT1cInJlc2V0XCJcbiAgICAgICAgICB0aXRsZT1cInt7cmVzZXRUaXRsZX19XCJcbiAgICAgICAgICAoY2xpY2spPVwiaGFuZGxlUmVzZXQoJGV2ZW50KVwiXG4gICAgICAgICAgW2hpZGRlbl09XCIhc3RhdGUucXVlcnkgfHwgKHN0YXRlLnF1ZXJ5ICYmICFzdGF0ZS5xdWVyeS50cmltKCkpIHx8IChzdGF0ZS5pc1NlYXJjaFN0YWxsZWQgJiYgc2hvd0xvYWRpbmdJbmRpY2F0b3IpXCI+XG4gICAgICAgICAgPHN2Z1xuICAgICAgICAgICAgW25nQ2xhc3NdPVwiY3goJ3Jlc2V0SWNvbicpXCJcbiAgICAgICAgICAgIHZpZXdCb3g9XCIwIDAgMjAgMjBcIlxuICAgICAgICAgICAgd2lkdGg9XCIyMFwiXG4gICAgICAgICAgICBoZWlnaHQ9XCIyMFwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPHBhdGggZD1cIk04LjExNCAxMEwuOTQ0IDIuODMgMCAxLjg4NSAxLjg4NiAwbC45NDMuOTQzTDEwIDguMTEzbDcuMTctNy4xNy45NDQtLjk0M0wyMCAxLjg4NmwtLjk0My45NDMtNy4xNyA3LjE3IDcuMTcgNy4xNy45NDMuOTQ0TDE4LjExNCAyMGwtLjk0My0uOTQzLTcuMTctNy4xNy03LjE3IDcuMTctLjk0NC45NDNMMCAxOC4xMTRsLjk0My0uOTQzTDguMTEzIDEwelwiPjwvcGF0aD5cbiAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgPC9idXR0b24+XG5cbiAgICAgICAgPHNwYW5cbiAgICAgICAgICBbY2xhc3NdPVwiY3goJ2xvYWRpbmdJbmRpY2F0b3InKVwiXG4gICAgICAgICAgW2hpZGRlbl09XCIhc2hvd0xvYWRpbmdJbmRpY2F0b3IgfHwgIXN0YXRlLmlzU2VhcmNoU3RhbGxlZFwiXG4gICAgICAgID5cbiAgICAgICAgICA8c3ZnXG4gICAgICAgICAgICB3aWR0aD1cIjE2XCJcbiAgICAgICAgICAgIGhlaWdodD1cIjE2XCJcbiAgICAgICAgICAgIHZpZXdCb3g9XCIwIDAgMzggMzhcIlxuICAgICAgICAgICAgc3Ryb2tlPVwiIzQ0NFwiXG4gICAgICAgICAgICBbbmdDbGFzc109XCJjeCgnbG9hZGluZ0ljb24nKVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPGcgZmlsbD1cIm5vbmVcIiBmaWxsUnVsZT1cImV2ZW5vZGRcIj5cbiAgICAgICAgICAgICAgPGcgdHJhbnNmb3JtPVwidHJhbnNsYXRlKDEgMSlcIiBzdHJva2VXaWR0aD1cIjJcIj5cbiAgICAgICAgICAgICAgICA8Y2lyY2xlIHN0cm9rZU9wYWNpdHk9XCIuNVwiIGN4PVwiMThcIiBjeT1cIjE4XCIgcj1cIjE4XCIgLz5cbiAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTM2IDE4YzAtOS45NC04LjA2LTE4LTE4LTE4XCI+XG4gICAgICAgICAgICAgICAgICA8YW5pbWF0ZVRyYW5zZm9ybVxuICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVOYW1lPVwidHJhbnNmb3JtXCJcbiAgICAgICAgICAgICAgICAgICAgdHlwZT1cInJvdGF0ZVwiXG4gICAgICAgICAgICAgICAgICAgIGZyb209XCIwIDE4IDE4XCJcbiAgICAgICAgICAgICAgICAgICAgdG89XCIzNjAgMTggMThcIlxuICAgICAgICAgICAgICAgICAgICBkdXI9XCIxc1wiXG4gICAgICAgICAgICAgICAgICAgIHJlcGVhdENvdW50PVwiaW5kZWZpbml0ZVwiXG4gICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgIDwvcGF0aD5cbiAgICAgICAgICAgICAgPC9nPlxuICAgICAgICAgICAgPC9nPlxuICAgICAgICAgIDwvc3ZnPlxuICAgICAgICA8L3NwYW4+XG4gICAgICA8L2Zvcm0+XG4gICAgPC9kaXY+XG4gIGAsXG59KVxuZXhwb3J0IGNsYXNzIE5nQWlzU2VhcmNoQm94XG4gIGV4dGVuZHMgVHlwZWRCYXNlV2lkZ2V0PFNlYXJjaEJveFdpZGdldERlc2NyaXB0aW9uLCBTZWFyY2hCb3hDb25uZWN0b3JQYXJhbXM+XG4gIGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgRG9DaGVjayB7XG4gIEBWaWV3Q2hpbGQoJ3NlYXJjaEJveCcsIHsgc3RhdGljOiBmYWxzZSB9KVxuICBzZWFyY2hCb3g6IEVsZW1lbnRSZWY7XG4gIEBJbnB1dCgpIHB1YmxpYyBwbGFjZWhvbGRlcjogc3RyaW5nID0gJ1NlYXJjaCc7XG4gIEBJbnB1dCgpIHB1YmxpYyBzdWJtaXRUaXRsZTogc3RyaW5nID0gJ1N1Ym1pdCc7XG4gIEBJbnB1dCgpIHB1YmxpYyByZXNldFRpdGxlOiBzdHJpbmcgPSAnUmVzZXQnO1xuICBASW5wdXQoKSBwdWJsaWMgc2VhcmNoQXNZb3VUeXBlOiBib29sZWFuID0gdHJ1ZTtcbiAgQElucHV0KCkgcHVibGljIGF1dG9mb2N1czogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSBwdWJsaWMgc2hvd0xvYWRpbmdJbmRpY2F0b3I6IGJvb2xlYW4gPSB0cnVlO1xuXG4gIC8vIE91dHB1dCBldmVudHNcbiAgLy8gZm9ybVxuICBAT3V0cHV0KCkgc3VibWl0ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBAT3V0cHV0KCkgcmVzZXQgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgLy8gaW5wdXRcbiAgQE91dHB1dCgpIGNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgQE91dHB1dCgpIGZvY3VzID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBAT3V0cHV0KCkgYmx1ciA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuICBwdWJsaWMgcXVlcnkgPSAnJztcblxuICBwdWJsaWMgc3RhdGU6IFNlYXJjaEJveFJlbmRlclN0YXRlID0ge1xuICAgIHF1ZXJ5OiAnJyxcbiAgICByZWZpbmU6IG5vb3AsXG4gICAgY2xlYXI6IG5vb3AsXG4gICAgaXNTZWFyY2hTdGFsbGVkOiBmYWxzZSxcbiAgfTtcblxuICBwcml2YXRlIGRvY3VtZW50OiBEb2N1bWVudDtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBASW5qZWN0KGZvcndhcmRSZWYoKCkgPT4gTmdBaXNJbmRleCkpXG4gICAgQE9wdGlvbmFsKClcbiAgICBwdWJsaWMgcGFyZW50SW5kZXg6IE5nQWlzSW5kZXgsXG4gICAgQEluamVjdChmb3J3YXJkUmVmKCgpID0+IE5nQWlzSW5zdGFudFNlYXJjaCkpXG4gICAgcHVibGljIGluc3RhbnRTZWFyY2hJbnN0YW5jZTogTmdBaXNJbnN0YW50U2VhcmNoLFxuICAgIEBJbmplY3QoRE9DVU1FTlQpIHByaXZhdGUgaW5qZWN0ZWREb2N1bWVudDogRG9jdW1lbnRcbiAgKSB7XG4gICAgc3VwZXIoJ1NlYXJjaEJveCcpO1xuICAgIHRoaXMuY3JlYXRlV2lkZ2V0KFxuICAgICAgY29ubmVjdFNlYXJjaEJveCxcbiAgICAgIHt9LFxuICAgICAge1xuICAgICAgICAkJHdpZGdldFR5cGU6ICdhaXMuc2VhcmNoQm94JyxcbiAgICAgIH1cbiAgICApO1xuICAgIHRoaXMuZG9jdW1lbnQgPSBpbmplY3RlZERvY3VtZW50O1xuICB9XG5cbiAgcHVibGljIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICBpZiAodGhpcy5hdXRvZm9jdXMpIHtcbiAgICAgIHRoaXMuc2VhcmNoQm94Lm5hdGl2ZUVsZW1lbnQuZm9jdXMoKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgbmdEb0NoZWNrKCkge1xuICAgIC8vIFdlIGJ5cGFzcyB0aGUgc3RhdGUgdXBkYXRlIGlmIHRoZSBpbnB1dCBpcyBmb2N1c2VkIHRvIGF2b2lkIGNvbmN1cnJlbnRcbiAgICAvLyB1cGRhdGVzIHdoZW4gdHlwaW5nLlxuICAgIGlmIChcbiAgICAgIHRoaXMucXVlcnkgIT09IHRoaXMuc3RhdGUucXVlcnkgJiZcbiAgICAgIHRoaXMuc2VhcmNoQm94ICYmXG4gICAgICB0aGlzLnNlYXJjaEJveC5uYXRpdmVFbGVtZW50ICYmXG4gICAgICB0aGlzLmRvY3VtZW50LmFjdGl2ZUVsZW1lbnQgIT09IHRoaXMuc2VhcmNoQm94Lm5hdGl2ZUVsZW1lbnRcbiAgICApIHtcbiAgICAgIHRoaXMucXVlcnkgPSB0aGlzLnN0YXRlLnF1ZXJ5O1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBoYW5kbGVDaGFuZ2UocXVlcnk6IHN0cmluZykge1xuICAgIHRoaXMuY2hhbmdlLmVtaXQocXVlcnkpO1xuICAgIGlmICh0aGlzLnNlYXJjaEFzWW91VHlwZSkge1xuICAgICAgdGhpcy5zdGF0ZS5yZWZpbmUocXVlcnkpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBoYW5kbGVTdWJtaXQoZXZlbnQ6IEV2ZW50KSB7XG4gICAgLy8gc2VuZCBzdWJtaXQgZXZlbnQgdG8gcGFyZW50IGNvbXBvbmVudFxuICAgIHRoaXMuc3VibWl0LmVtaXQoZXZlbnQpO1xuXG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuICAgIGlmICghdGhpcy5zZWFyY2hBc1lvdVR5cGUpIHtcbiAgICAgIHRoaXMuc3RhdGUucmVmaW5lKHRoaXMuc2VhcmNoQm94Lm5hdGl2ZUVsZW1lbnQudmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBoYW5kbGVSZXNldChldmVudDogTW91c2VFdmVudCkge1xuICAgIC8vIHNlbmQgcmVzZXQgZXZlbnQgdG8gcGFyZW50IGNvbXBvbmVudFxuICAgIHRoaXMucmVzZXQuZW1pdChldmVudCk7XG5cbiAgICAvLyByZXNldCBzZWFyY2hcbiAgICB0aGlzLnN0YXRlLnJlZmluZSgnJyk7XG4gIH1cbn1cbiJdfQ==