@revivejs/ng-multiselect-dropdown 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
File without changes
package/README.md ADDED
@@ -0,0 +1,229 @@
1
+ # @revivejs/ng-multiselect-dropdown
2
+
3
+ > A polished **Angular 16 multi-select dropdown** for template-driven and reactive forms, with search, single or multiple selection, custom data binding, and theme support.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/%40revivejs%2Fng-multiselect-dropdown.svg?style=flat-square)](https://www.npmjs.com/package/@revivejs/ng-multiselect-dropdown)
6
+ [![npm downloads](https://img.shields.io/npm/dt/%40revivejs%2Fng-multiselect-dropdown.svg?style=flat-square)](https://www.npmjs.com/package/@revivejs/ng-multiselect-dropdown)
7
+ [![npm monthly](https://img.shields.io/npm/dm/%40revivejs%2Fng-multiselect-dropdown.svg?style=flat-square)](https://www.npmjs.com/package/@revivejs/ng-multiselect-dropdown)
8
+ [![license](https://img.shields.io/npm/l/%40revivejs%2Fng-multiselect-dropdown.svg?style=flat-square)](https://github.com/alexandroit/ng-multiselect-dropdown/blob/master/LICENSE)
9
+ [![Angular 16](https://img.shields.io/badge/Angular-16-red?style=flat-square&logo=angular)](https://angular.io)
10
+ [![TypeScript](https://img.shields.io/badge/TypeScript-4.9-blue?style=flat-square&logo=typescript)](https://www.typescriptlang.org)
11
+ [![GitHub stars](https://img.shields.io/github/stars/alexandroit/ng-multiselect-dropdown.svg?style=flat-square)](https://github.com/alexandroit/ng-multiselect-dropdown/stargazers)
12
+
13
+ **[Documentation & Demo](https://alexandroit.github.io/ng-multiselect-dropdown/)** | **[Repository](https://github.com/alexandroit/ng-multiselect-dropdown)** | **[npm](https://www.npmjs.com/package/@revivejs/ng-multiselect-dropdown)** | **[Changelog](https://github.com/alexandroit/ng-multiselect-dropdown/blob/master/CHANGELOG.md)** | **[Custom Theme Guide](https://github.com/alexandroit/ng-multiselect-dropdown/blob/master/custom-theme.md)**
14
+
15
+ ---
16
+
17
+ > **Credits:** This package is maintained and published from the official repository at [alexandroit/ng-multiselect-dropdown](https://github.com/alexandroit/ng-multiselect-dropdown). Historical credit remains with the original upstream authors who inspired and started the library line.
18
+
19
+ ---
20
+
21
+ ## Why this library?
22
+
23
+ `@revivejs/ng-multiselect-dropdown` is the actively maintained scoped continuation of this component, prepared for modern Angular 16 applications and first-class npm publishing under the `@revivejs` scope.
24
+
25
+ ## Features
26
+
27
+ | Feature | Supported |
28
+ | :--- | :---: |
29
+ | Angular 16 release line | ✅ |
30
+ | Single and multiple selection | ✅ |
31
+ | Search and filter | ✅ |
32
+ | Template-driven forms (`ngModel`) | ✅ |
33
+ | Reactive forms support | ✅ |
34
+ | Custom text and placeholders | ✅ |
35
+ | Select all and clear all | ✅ |
36
+ | Item selection limit | ✅ |
37
+ | Disabled items | ✅ |
38
+ | Remote search trigger (`allowRemoteDataSearch`) | ✅ |
39
+ | Custom theme support | ✅ |
40
+
41
+ ## Table of Contents
42
+
43
+ 1. [Angular Version Compatibility](#angular-version-compatibility)
44
+ 2. [Installation](#installation)
45
+ 3. [Setup](#setup)
46
+ 4. [Basic Usage](#basic-usage)
47
+ 5. [Settings](#settings)
48
+ 6. [Events](#events)
49
+ 7. [Theming](#theming)
50
+ 8. [Run Locally](#run-locally)
51
+ 9. [Publishing](#publishing)
52
+ 10. [License](#license)
53
+
54
+ ## Angular Version Compatibility
55
+
56
+ | Package | Angular | TypeScript | RxJS |
57
+ | :--- | :---: | :---: | :---: |
58
+ | `@revivejs/ng-multiselect-dropdown@1.x` | `16.x` | `4.9.x` | `7.x` |
59
+
60
+ ## Installation
61
+
62
+ ```bash
63
+ npm install @revivejs/ng-multiselect-dropdown
64
+ ```
65
+
66
+ ## Setup
67
+
68
+ ### 1. Import the module
69
+
70
+ ```ts
71
+ import { NgModule } from '@angular/core';
72
+ import { BrowserModule } from '@angular/platform-browser';
73
+ import { FormsModule } from '@angular/forms';
74
+ import { NgMultiSelectDropDownModule } from '@revivejs/ng-multiselect-dropdown';
75
+
76
+ @NgModule({
77
+ imports: [
78
+ BrowserModule,
79
+ FormsModule,
80
+ NgMultiSelectDropDownModule.forRoot()
81
+ ]
82
+ })
83
+ export class AppModule {}
84
+ ```
85
+
86
+ ### 2. Optional theme setup
87
+
88
+ ```json
89
+ "styles": [
90
+ "node_modules/@revivejs/ng-multiselect-dropdown/themes/ng-multiselect-dropdown.theme.scss"
91
+ ]
92
+ ```
93
+
94
+ ### 3. Use the package from the official repository
95
+
96
+ Repository URL:
97
+
98
+ ```text
99
+ https://github.com/alexandroit/ng-multiselect-dropdown
100
+ ```
101
+
102
+ ## Basic Usage
103
+
104
+ ```ts
105
+ import { Component, OnInit } from '@angular/core';
106
+ import { IDropdownSettings } from '@revivejs/ng-multiselect-dropdown';
107
+
108
+ @Component({
109
+ selector: 'app-root',
110
+ templateUrl: './app.component.html'
111
+ })
112
+ export class AppComponent implements OnInit {
113
+ dropdownList = [];
114
+ selectedItems = [];
115
+ dropdownSettings: IDropdownSettings = {};
116
+
117
+ ngOnInit(): void {
118
+ this.dropdownList = [
119
+ { item_id: 1, item_text: 'Mumbai' },
120
+ { item_id: 2, item_text: 'Bangalore' },
121
+ { item_id: 3, item_text: 'Pune' },
122
+ { item_id: 4, item_text: 'Navsari' },
123
+ { item_id: 5, item_text: 'New Delhi' }
124
+ ];
125
+
126
+ this.selectedItems = [
127
+ { item_id: 3, item_text: 'Pune' },
128
+ { item_id: 4, item_text: 'Navsari' }
129
+ ];
130
+
131
+ this.dropdownSettings = {
132
+ singleSelection: false,
133
+ idField: 'item_id',
134
+ textField: 'item_text',
135
+ selectAllText: 'Select All',
136
+ unSelectAllText: 'UnSelect All',
137
+ itemsShowLimit: 3,
138
+ allowSearchFilter: true
139
+ };
140
+ }
141
+
142
+ onItemSelect(item: unknown): void {
143
+ console.log(item);
144
+ }
145
+
146
+ onSelectAll(items: unknown): void {
147
+ console.log(items);
148
+ }
149
+ }
150
+ ```
151
+
152
+ ```html
153
+ <ng-multiselect-dropdown
154
+ [placeholder]="'Select options'"
155
+ [settings]="dropdownSettings"
156
+ [data]="dropdownList"
157
+ [(ngModel)]="selectedItems"
158
+ (onSelect)="onItemSelect($event)"
159
+ (onSelectAll)="onSelectAll($event)">
160
+ </ng-multiselect-dropdown>
161
+ ```
162
+
163
+ ## Settings
164
+
165
+ | Setting | Type | Description | Default |
166
+ | :--- | :--- | :--- | :--- |
167
+ | `singleSelection` | `boolean` | Enables single-selection mode. | `false` |
168
+ | `placeholder` | `string` | Placeholder text shown when nothing is selected. | `'Select'` |
169
+ | `disabled` | `boolean` | Disables the dropdown. | `false` |
170
+ | `data` | `Array<any>` | Data source for the dropdown. | `[]` |
171
+ | `idField` | `string` | Field used as the item identifier. | `'id'` |
172
+ | `textField` | `string` | Field used as the item label. | `'text'` |
173
+ | `disabledField` | `string` | Field used to mark disabled items. | `'isDisabled'` |
174
+ | `enableCheckAll` | `boolean` | Shows the select-all option. | `true` |
175
+ | `selectAllText` | `string` | Label for the select-all option. | `'Select All'` |
176
+ | `unSelectAllText` | `string` | Label for the clear-all option. | `'UnSelect All'` |
177
+ | `allowSearchFilter` | `boolean` | Enables the search box. | `false` |
178
+ | `searchPlaceholderText` | `string` | Search input placeholder text. | `'Search'` |
179
+ | `clearSearchFilter` | `boolean` | Clears search text when the dropdown closes. | `true` |
180
+ | `maxHeight` | `number` | Max dropdown list height in pixels. | `197` |
181
+ | `itemsShowLimit` | `number` | Limits how many selected items appear in the control. | `999999999999` |
182
+ | `limitSelection` | `number` | Maximum allowed selected items. | `-1` |
183
+ | `noDataAvailablePlaceholderText` | `string` | Message shown when there is no data. | `'No data available'` |
184
+ | `noFilteredDataAvailablePlaceholderText` | `string` | Message shown when search returns no results. | `'No filtered data available'` |
185
+ | `closeDropDownOnSelection` | `boolean` | Closes the dropdown after selection in single mode. | `false` |
186
+ | `showSelectedItemsAtTop` | `boolean` | Moves selected items to the top of the list. | `false` |
187
+ | `defaultOpen` | `boolean` | Opens the dropdown by default. | `false` |
188
+ | `allowRemoteDataSearch` | `boolean` | Keeps remote search available even when data is empty. | `false` |
189
+
190
+ ## Events
191
+
192
+ - `onSelect`: Fires when one item is selected.
193
+ - `onDeSelect`: Fires when one item is deselected.
194
+ - `onSelectAll`: Fires when all visible items are selected.
195
+ - `onDeSelectAll`: Fires when all items are deselected.
196
+ - `onFilterChange`: Fires when the search text changes.
197
+ - `onDropDownClose`: Fires when the dropdown closes.
198
+
199
+ ## Theming
200
+
201
+ The package ships with a theme file at:
202
+
203
+ ```text
204
+ node_modules/@revivejs/ng-multiselect-dropdown/themes/ng-multiselect-dropdown.theme.scss
205
+ ```
206
+
207
+ For step-by-step theme customization, see [custom-theme.md](https://github.com/alexandroit/ng-multiselect-dropdown/blob/master/custom-theme.md).
208
+
209
+ ## Run Locally
210
+
211
+ ```bash
212
+ npm install
213
+ npm start
214
+ ```
215
+
216
+ The local demo runs at `http://localhost:4201/`.
217
+
218
+ ## Publishing
219
+
220
+ ```bash
221
+ npm run build:package
222
+ npm run pack:check
223
+ ```
224
+
225
+ This prepares the publishable package in `dist-lib/` with the scoped package name `@revivejs/ng-multiselect-dropdown` and performs a dry-run tarball check without publishing.
226
+
227
+ ## License
228
+
229
+ MIT License.
@@ -0,0 +1,32 @@
1
+ import { Directive, Output, EventEmitter, HostListener } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ export class ClickOutsideDirective {
4
+ _elementRef;
5
+ constructor(_elementRef) {
6
+ this._elementRef = _elementRef;
7
+ }
8
+ clickOutside = new EventEmitter();
9
+ onClick(event, targetElement) {
10
+ if (!targetElement) {
11
+ return;
12
+ }
13
+ const clickedInside = this._elementRef.nativeElement.contains(targetElement);
14
+ if (!clickedInside) {
15
+ this.clickOutside.emit(event);
16
+ }
17
+ }
18
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ClickOutsideDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
19
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.1.7", type: ClickOutsideDirective, selector: "[clickOutside]", outputs: { clickOutside: "clickOutside" }, host: { listeners: { "document:click": "onClick($event,$event.target)" } }, ngImport: i0 });
20
+ }
21
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ClickOutsideDirective, decorators: [{
22
+ type: Directive,
23
+ args: [{
24
+ selector: '[clickOutside]'
25
+ }]
26
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { clickOutside: [{
27
+ type: Output
28
+ }], onClick: [{
29
+ type: HostListener,
30
+ args: ['document:click', ['$event', '$event.target']]
31
+ }] } });
32
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpY2stb3V0c2lkZS5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbmctbXVsdGlzZWxlY3QtZHJvcGRvd24vc3JjL2NsaWNrLW91dHNpZGUuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBQyxTQUFTLEVBQWMsTUFBTSxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUMsTUFBTSxlQUFlLENBQUM7O0FBS3hGLE1BQU0sT0FBTyxxQkFBcUI7SUFDVjtJQUFwQixZQUFvQixXQUF1QjtRQUF2QixnQkFBVyxHQUFYLFdBQVcsQ0FBWTtJQUMzQyxDQUFDO0lBR00sWUFBWSxHQUFHLElBQUksWUFBWSxFQUFjLENBQUM7SUFHOUMsT0FBTyxDQUFDLEtBQWlCLEVBQUUsYUFBMEI7UUFDeEQsSUFBSSxDQUFDLGFBQWEsRUFBRTtZQUNoQixPQUFPO1NBQ1Y7UUFFRCxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDN0UsSUFBSSxDQUFDLGFBQWEsRUFBRTtZQUNoQixJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztTQUNqQztJQUNMLENBQUM7dUdBakJRLHFCQUFxQjsyRkFBckIscUJBQXFCOzsyRkFBckIscUJBQXFCO2tCQUhqQyxTQUFTO21CQUFDO29CQUNQLFFBQVEsRUFBRSxnQkFBZ0I7aUJBQzdCO2lHQU1VLFlBQVk7c0JBRGxCLE1BQU07Z0JBSUEsT0FBTztzQkFEYixZQUFZO3VCQUFDLGdCQUFnQixFQUFFLENBQUMsUUFBUSxFQUFFLGVBQWUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7RGlyZWN0aXZlLCBFbGVtZW50UmVmLCBPdXRwdXQsIEV2ZW50RW1pdHRlciwgSG9zdExpc3RlbmVyfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuQERpcmVjdGl2ZSh7XG4gICAgc2VsZWN0b3I6ICdbY2xpY2tPdXRzaWRlXSdcbn0pXG5leHBvcnQgY2xhc3MgQ2xpY2tPdXRzaWRlRGlyZWN0aXZlIHtcbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIF9lbGVtZW50UmVmOiBFbGVtZW50UmVmKSB7XG4gICAgfVxuXG4gICAgQE91dHB1dCgpXG4gICAgcHVibGljIGNsaWNrT3V0c2lkZSA9IG5ldyBFdmVudEVtaXR0ZXI8TW91c2VFdmVudD4oKTtcblxuICAgIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50OmNsaWNrJywgWyckZXZlbnQnLCAnJGV2ZW50LnRhcmdldCddKVxuICAgIHB1YmxpYyBvbkNsaWNrKGV2ZW50OiBNb3VzZUV2ZW50LCB0YXJnZXRFbGVtZW50OiBIVE1MRWxlbWVudCk6IHZvaWQge1xuICAgICAgICBpZiAoIXRhcmdldEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGNsaWNrZWRJbnNpZGUgPSB0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuY29udGFpbnModGFyZ2V0RWxlbWVudCk7XG4gICAgICAgIGlmICghY2xpY2tlZEluc2lkZSkge1xuICAgICAgICAgICAgdGhpcy5jbGlja091dHNpZGUuZW1pdChldmVudCk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iXX0=
@@ -0,0 +1,28 @@
1
+ import { Pipe } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ export class ListFilterPipe {
4
+ transform(items, filter) {
5
+ if (!items || !filter) {
6
+ return items;
7
+ }
8
+ return items.filter((item) => this.applyFilter(item, filter));
9
+ }
10
+ applyFilter(item, filter) {
11
+ if (typeof item.text === 'string' && typeof filter.text === 'string') {
12
+ return !(filter.text && item.text && item.text.toLowerCase().indexOf(filter.text.toLowerCase()) === -1);
13
+ }
14
+ else {
15
+ return !(filter.text && item.text && item.text.toString().toLowerCase().indexOf(filter.text.toString().toLowerCase()) === -1);
16
+ }
17
+ }
18
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ListFilterPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
19
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "16.1.7", ngImport: i0, type: ListFilterPipe, name: "multiSelectFilter", pure: false });
20
+ }
21
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ListFilterPipe, decorators: [{
22
+ type: Pipe,
23
+ args: [{
24
+ name: 'multiSelectFilter',
25
+ pure: false
26
+ }]
27
+ }] });
28
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlzdC1maWx0ZXIucGlwZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9uZy1tdWx0aXNlbGVjdC1kcm9wZG93bi9zcmMvbGlzdC1maWx0ZXIucGlwZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsSUFBSSxFQUFpQixNQUFNLGVBQWUsQ0FBQzs7QUFRcEQsTUFBTSxPQUFPLGNBQWM7SUFDdkIsU0FBUyxDQUFDLEtBQWlCLEVBQUUsTUFBZ0I7UUFDekMsSUFBSSxDQUFDLEtBQUssSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUNuQixPQUFPLEtBQUssQ0FBQztTQUNoQjtRQUNELE9BQU8sS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQWMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQztJQUM1RSxDQUFDO0lBRUQsV0FBVyxDQUFDLElBQWMsRUFBRSxNQUFnQjtRQUN4QyxJQUFJLE9BQU8sSUFBSSxDQUFDLElBQUksS0FBSyxRQUFRLElBQUksT0FBTyxNQUFNLENBQUMsSUFBSSxLQUFLLFFBQVEsRUFBRTtZQUNsRSxPQUFPLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxJQUFJLElBQUksQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDM0c7YUFBTTtZQUNILE9BQU8sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLFdBQVcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLFdBQVcsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUNqSTtJQUNMLENBQUM7dUdBZFEsY0FBYztxR0FBZCxjQUFjOzsyRkFBZCxjQUFjO2tCQUoxQixJQUFJO21CQUFDO29CQUNGLElBQUksRUFBRSxtQkFBbUI7b0JBQ3pCLElBQUksRUFBRSxLQUFLO2lCQUNkIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgUGlwZSwgUGlwZVRyYW5zZm9ybSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQgeyBMaXN0SXRlbSB9IGZyb20gJy4vbXVsdGlzZWxlY3QubW9kZWwnO1xuXG5AUGlwZSh7XG4gICAgbmFtZTogJ211bHRpU2VsZWN0RmlsdGVyJyxcbiAgICBwdXJlOiBmYWxzZVxufSlcbmV4cG9ydCBjbGFzcyBMaXN0RmlsdGVyUGlwZSBpbXBsZW1lbnRzIFBpcGVUcmFuc2Zvcm0ge1xuICAgIHRyYW5zZm9ybShpdGVtczogTGlzdEl0ZW1bXSwgZmlsdGVyOiBMaXN0SXRlbSk6IExpc3RJdGVtW10ge1xuICAgICAgICBpZiAoIWl0ZW1zIHx8ICFmaWx0ZXIpIHtcbiAgICAgICAgICAgIHJldHVybiBpdGVtcztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaXRlbXMuZmlsdGVyKChpdGVtOiBMaXN0SXRlbSkgPT4gdGhpcy5hcHBseUZpbHRlcihpdGVtLCBmaWx0ZXIpKTtcbiAgICB9XG5cbiAgICBhcHBseUZpbHRlcihpdGVtOiBMaXN0SXRlbSwgZmlsdGVyOiBMaXN0SXRlbSk6IGJvb2xlYW4ge1xuICAgICAgICBpZiAodHlwZW9mIGl0ZW0udGV4dCA9PT0gJ3N0cmluZycgJiYgdHlwZW9mIGZpbHRlci50ZXh0ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgcmV0dXJuICEoZmlsdGVyLnRleHQgJiYgaXRlbS50ZXh0ICYmIGl0ZW0udGV4dC50b0xvd2VyQ2FzZSgpLmluZGV4T2YoZmlsdGVyLnRleHQudG9Mb3dlckNhc2UoKSkgPT09IC0xKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiAhKGZpbHRlci50ZXh0ICYmIGl0ZW0udGV4dCAmJiBpdGVtLnRleHQudG9TdHJpbmcoKS50b0xvd2VyQ2FzZSgpLmluZGV4T2YoZmlsdGVyLnRleHQudG9TdHJpbmcoKS50b0xvd2VyQ2FzZSgpKSA9PT0gLTEpO1xuICAgICAgICB9XG4gICAgfVxufVxuIl19