@ieeesa-npm/dashboard 0.0.0-stage → 0.0.2
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/README.md +75 -3
- package/esm2022/ieeesa-npm-dashboard.mjs +5 -0
- package/esm2022/lib/assets/constants.json +158 -0
- package/esm2022/lib/assets/dashboard-mock.mjs +221 -0
- package/esm2022/lib/assets/dashboard-route-paths.mock.mjs +14 -0
- package/esm2022/lib/assets/dashboard-user-permissions.mock.mjs +23 -0
- package/esm2022/lib/assets/date-formats.mjs +28 -0
- package/esm2022/lib/components/event-group-card/event-group-card.component.mjs +414 -0
- package/esm2022/lib/components/meeting-attendance-row/meeting-attendance-row.component.mjs +182 -0
- package/esm2022/lib/components/member-level-badge/member-level-badge.component.mjs +79 -0
- package/esm2022/lib/components/upcoming-meetings-events/upcoming-meetings-events.component.mjs +261 -0
- package/esm2022/lib/components/welcome-header/dashboard-welcome-header.component.mjs +151 -0
- package/esm2022/lib/components/your-groups/your-groups.component.mjs +243 -0
- package/esm2022/lib/dashboard.component.mjs +417 -0
- package/esm2022/lib/dashboard.module.mjs +16 -0
- package/esm2022/lib/dashboard.routes.mjs +7 -0
- package/esm2022/lib/models/attendance-action-permissions.model.mjs +2 -0
- package/esm2022/lib/models/attendance-state.model.mjs +7 -0
- package/esm2022/lib/models/dashboard-list-response.model.mjs +2 -0
- package/esm2022/lib/models/dashboard-route-config.model.mjs +2 -0
- package/esm2022/lib/models/dashboard-section-state.model.mjs +9 -0
- package/esm2022/lib/models/dashboard-user-info.model.mjs +2 -0
- package/esm2022/lib/models/event-meeting-list-item.model.mjs +2 -0
- package/esm2022/lib/models/event-meeting-list-payload.model.mjs +8 -0
- package/esm2022/lib/models/group-row.model.mjs +2 -0
- package/esm2022/lib/models/meeting-row.model.mjs +2 -0
- package/esm2022/lib/models/my-groups-view.model.mjs +2 -0
- package/esm2022/lib/models/page-change.model.mjs +2 -0
- package/esm2022/lib/models/upcoming-event.model.mjs +13 -0
- package/esm2022/lib/services/attendance-reducers.mjs +54 -0
- package/esm2022/lib/services/dashboard.service.mjs +402 -0
- package/esm2022/lib/services/user-permissions.service.mjs +50 -0
- package/esm2022/lib/utils/attendance-action.util.mjs +53 -0
- package/esm2022/lib/utils/date-format.util.mjs +110 -0
- package/esm2022/lib/utils/event-meeting-mapper.util.mjs +96 -0
- package/esm2022/public-api.mjs +36 -0
- package/fesm2022/ieeesa-npm-dashboard.mjs +2981 -0
- package/fesm2022/ieeesa-npm-dashboard.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/lib/assets/dashboard-mock.d.ts +31 -0
- package/lib/assets/dashboard-route-paths.mock.d.ts +2 -0
- package/lib/assets/dashboard-user-permissions.mock.d.ts +2 -0
- package/lib/assets/date-formats.d.ts +27 -0
- package/lib/components/event-group-card/event-group-card.component.d.ts +268 -0
- package/lib/components/meeting-attendance-row/meeting-attendance-row.component.d.ts +115 -0
- package/lib/components/member-level-badge/member-level-badge.component.d.ts +177 -0
- package/lib/components/upcoming-meetings-events/upcoming-meetings-events.component.d.ts +175 -0
- package/lib/components/welcome-header/dashboard-welcome-header.component.d.ts +98 -0
- package/lib/components/your-groups/your-groups.component.d.ts +159 -0
- package/lib/dashboard.component.d.ts +414 -0
- package/lib/dashboard.module.d.ts +7 -0
- package/lib/dashboard.routes.d.ts +2 -0
- package/lib/models/attendance-action-permissions.model.d.ts +4 -0
- package/lib/models/attendance-state.model.d.ts +4 -0
- package/lib/models/dashboard-list-response.model.d.ts +5 -0
- package/lib/models/dashboard-route-config.model.d.ts +7 -0
- package/lib/models/dashboard-section-state.model.d.ts +6 -0
- package/lib/models/dashboard-user-info.model.d.ts +5 -0
- package/lib/models/event-meeting-list-item.model.d.ts +107 -0
- package/lib/models/event-meeting-list-payload.model.d.ts +40 -0
- package/lib/models/group-row.model.d.ts +33 -0
- package/lib/models/meeting-row.model.d.ts +28 -0
- package/lib/models/my-groups-view.model.d.ts +56 -0
- package/lib/models/page-change.model.d.ts +4 -0
- package/lib/models/upcoming-event.model.d.ts +51 -0
- package/lib/services/attendance-reducers.d.ts +43 -0
- package/lib/services/dashboard.service.d.ts +202 -0
- package/lib/services/user-permissions.service.d.ts +31 -0
- package/lib/utils/attendance-action.util.d.ts +38 -0
- package/lib/utils/date-format.util.d.ts +60 -0
- package/lib/utils/event-meeting-mapper.util.d.ts +50 -0
- package/package.json +30 -3
- package/public-api.d.ts +26 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Request payloads for the dashboard "events & meetings" backend calls. These
|
|
3
|
+
* mirror the `events-and-meetings` library's `GetEventsAndMeetingsPayload` /
|
|
4
|
+
* `GetMeetingsByEventIdPayload` so the dashboard reuses the exact contract the
|
|
5
|
+
* existing `view-events-meetings-list` screen posts.
|
|
6
|
+
*/
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXZlbnQtbWVldGluZy1saXN0LXBheWxvYWQubW9kZWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9kYXNoYm9hcmQvc3JjL2xpYi9tb2RlbHMvZXZlbnQtbWVldGluZy1saXN0LXBheWxvYWQubW9kZWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7O0dBS0ciLCJzb3VyY2VzQ29udGVudCI6WyIvKipcclxuICogUmVxdWVzdCBwYXlsb2FkcyBmb3IgdGhlIGRhc2hib2FyZCBcImV2ZW50cyAmIG1lZXRpbmdzXCIgYmFja2VuZCBjYWxscy4gVGhlc2VcclxuICogbWlycm9yIHRoZSBgZXZlbnRzLWFuZC1tZWV0aW5nc2AgbGlicmFyeSdzIGBHZXRFdmVudHNBbmRNZWV0aW5nc1BheWxvYWRgIC9cclxuICogYEdldE1lZXRpbmdzQnlFdmVudElkUGF5bG9hZGAgc28gdGhlIGRhc2hib2FyZCByZXVzZXMgdGhlIGV4YWN0IGNvbnRyYWN0IHRoZVxyXG4gKiBleGlzdGluZyBgdmlldy1ldmVudHMtbWVldGluZ3MtbGlzdGAgc2NyZWVuIHBvc3RzLlxyXG4gKi9cclxuXHJcbi8qKiBGaWx0ZXIgYmxvY2sgc2hhcmVkIGJ5IHRoZSBsaXN0IGFuZCBleHBhbmQgcGF5bG9hZHMuICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgRXZlbnRNZWV0aW5nRmlsdGVyIHtcclxuICAvKiogTGlmZWN5Y2xlIHN0YXR1c2VzIHRvIGluY2x1ZGUsIGUuZy4gW1wiSW4gUHJvZ3Jlc3NcIiwgXCJVcGNvbWluZ1wiXS4gKi9cclxuICBzdGF0dXM6IHN0cmluZ1tdO1xyXG4gIC8qKiBXaGV0aGVyIGV2ZXJ5IG1lZXRpbmcgKHJlZ2FyZGxlc3Mgb2YgbWVtYmVyc2hpcCkgc2hvdWxkIGJlIHJldHVybmVkLiAqL1xyXG4gIGlzQWxsTWVldGluZ1NlbGVjdGVkOiBib29sZWFuO1xyXG4gIC8qKiBPcHRpb25hbCBncm91cC1pZCBzY29wZS4gKi9cclxuICBncm91cElkcz86IHN0cmluZ1tdO1xyXG59XHJcblxyXG4vKiogUGF5bG9hZCBmb3IgYFBPU1Qge2FwaUJhc2VVcmx9L21lZXRpbmdzL2V2ZW50c0FuZE1lZXRpbmdzYCAodGhlIHNlY3Rpb24gbGlzdCkuICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgRXZlbnRNZWV0aW5nTGlzdFBheWxvYWQge1xyXG4gIHBheWxvYWQ6IHtcclxuICAgIC8qKiBOdWxsIGZvciB0aGUgdG9wLWxldmVsIGxpc3Q7IGFuIGV2ZW50IGlkIHdoZW4gc2NvcGluZyB0byBvbmUgZXZlbnQuICovXHJcbiAgICBldmVudElkOiBzdHJpbmcgfCBudWxsO1xyXG4gICAgc29ydENvbHVtbjogc3RyaW5nO1xyXG4gICAgYXNjZW5kaW5nT3JkZXI6IGJvb2xlYW47XHJcbiAgICBwYWdlOiBudW1iZXI7XHJcbiAgICBzaXplOiBudW1iZXI7XHJcbiAgICBzZWFyY2hUZXJtPzogc3RyaW5nIHwgbnVsbDtcclxuICAgIGZpbHRlcjogRXZlbnRNZWV0aW5nRmlsdGVyO1xyXG4gIH07XHJcbn1cclxuXHJcbi8qKiBQYXlsb2FkIGZvciBgUE9TVCB7YXBpQmFzZVVybH0vbWVldGluZ3MvbWVldGluZ3NEZXRhaWxzYCAocGVyLWV2ZW50IGV4cGFuZCkuICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgRXZlbnRNZWV0aW5nRGV0YWlsUGF5bG9hZCB7XHJcbiAgcGF5bG9hZDoge1xyXG4gICAgZXZlbnRJZDogc3RyaW5nO1xyXG4gICAgc29ydENvbHVtbjogc3RyaW5nO1xyXG4gICAgYXNjZW5kaW5nT3JkZXI6IGJvb2xlYW47XHJcbiAgICBwYWdlOiBudW1iZXI7XHJcbiAgICBzaXplOiBudW1iZXI7XHJcbiAgICBzZWFyY2hUZXJtPzogc3RyaW5nIHwgbnVsbDtcclxuICAgIGZpbHRlcjogRXZlbnRNZWV0aW5nRmlsdGVyO1xyXG4gIH07XHJcbn1cclxuIl19
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export {};
|
|
2
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3JvdXAtcm93Lm1vZGVsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZGFzaGJvYXJkL3NyYy9saWIvbW9kZWxzL2dyb3VwLXJvdy5tb2RlbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXHJcbiAqIEEgc2luZ2xlIG5vZGUgaW4gYSBncm91cCdzIGFuY2VzdG9yIGhpZXJhcmNoeSAocm9vdOKGkmxlYWYpLCBhcyByZXR1cm5lZCBieVxyXG4gKiBHRVQgL3YxL2dyb3Vwcy9teS1ncm91cHMuIFVzZWQgdG8gcmVuZGVyIHRoZSBleHBhbmRhYmxlIGhpZXJhcmNoeSByb3dzIGluIHRoZVxyXG4gKiBZb3VyIEdyb3VwcyB0YWJsZS5cclxuICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgR3JvdXBIaWVyYXJjaHlOb2RlIHtcclxuICBncm91cElkOiBzdHJpbmc7XHJcbiAgZ3JvdXBOYW1lOiBzdHJpbmc7XHJcbiAgZ3JvdXBTaG9ydE5hbWU/OiBzdHJpbmc7XHJcbiAgZ3JvdXBBY3JvbnltPzogc3RyaW5nO1xyXG4gIGdyb3VwTGV2ZWw/OiBudW1iZXI7XHJcbiAgZ3JvdXBQYXJlbnRJZD86IHN0cmluZyB8IG51bGw7XHJcbiAgZ3JvdXBUeXBlPzogc3RyaW5nO1xyXG4gIGdyb3VwVHlwZU5hbWU/OiBzdHJpbmcgfCBudWxsO1xyXG4gIGdyb3VwRGVzYz86IHN0cmluZyB8IG51bGw7XHJcbiAgaGFzQ2hpbGRyZW4/OiBib29sZWFuIHwgbnVsbDtcclxufVxyXG5cclxuLyoqXHJcbiAqIFRhYmxlLWZhY2luZyB2aWV3IG9mIGEgZ3JvdXAgaW4gdGhlIFlvdXIgR3JvdXBzIHNlY3Rpb24uIFRoZSBkaXNwbGF5IGZpZWxkc1xyXG4gKiBhcmUgbWFwcGVkIGZyb20gdGhlIGJhY2tlbmQ7IGBoaWVyYXJjaHlgIGNhcnJpZXMgdGhlIGdyb3VwJ3MgYW5jZXN0b3IgcGF0aCBzb1xyXG4gKiB0aGUgcm93IGNhbiBleHBhbmQgdG8gc2hvdyB0aGUgaGllcmFyY2h5IChtYXRjaGluZyB0aGUgTXkgUHJvZmlsZSBGaW5kIEdyb3Vwc1xyXG4gKiB0cmVlKS5cclxuICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgR3JvdXBSb3cge1xyXG4gIGdyb3VwSWQ6IHN0cmluZztcclxuICBncm91cDogc3RyaW5nO1xyXG4gIHR5cGU/OiBzdHJpbmc7XHJcbiAgb2ZmaWNlclJvbGU/OiBzdHJpbmc7XHJcbiAgYWZmaWxpYXRpb24/OiBzdHJpbmc7XHJcbiAgbWVtYmVyTGV2ZWw6IHN0cmluZztcclxuICAvKiogQW5jZXN0b3IgaGllcmFyY2h5IChyb2904oaSbGVhZikgZm9yIHRoZSBleHBhbmRhYmxlIGhpZXJhcmNoeSByb3dzLiAqL1xyXG4gIGhpZXJhcmNoeT86IEdyb3VwSGllcmFyY2h5Tm9kZVtdO1xyXG59XHJcbiJdfQ==
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export {};
|
|
2
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVldGluZy1yb3cubW9kZWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9kYXNoYm9hcmQvc3JjL2xpYi9tb2RlbHMvbWVldGluZy1yb3cubW9kZWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEF0dGVuZGFuY2VTdGF0ZSB9IGZyb20gJy4vYXR0ZW5kYW5jZS1zdGF0ZS5tb2RlbCc7XHJcblxyXG4vKipcclxuICogVmlldyBtb2RlbCBmb3IgYSBzaW5nbGUgbWVldGluZyByb3csIHVzZWQgYm90aCBmb3IgYW4gZXZlbnQncyBleHBhbmRlZCBjaGlsZFxyXG4gKiBtZWV0aW5ncyBhbmQgKHZpYSB7QGxpbmsgVXBjb21pbmdFdmVudH0pIGZvciBzdGFuZGFsb25lIG1lZXRpbmcgY2FyZHMuXHJcbiAqXHJcbiAqIGBzdGFydEVwb2NoTXNgIC8gYGVuZEVwb2NoTXNgIGNhcnJ5IHRoZSByYXcgZXBvY2gtbWlsbGlzZWNvbmRzIHZhbHVlcyBmcm9tIHRoZVxyXG4gKiBiYWNrZW5kIGFuZCBhcmUgZm9ybWF0dGVkIHdpdGggbHV4b24gYERhdGVUaW1lLmZyb21NaWxsaXNgLiBUaGUgbGVnYWN5IElTT1xyXG4gKiBgbWVldGluZ0RhdGVgIC8gYG1lZXRpbmdUaW1lYCBmaWVsZHMgYXJlIHJldGFpbmVkIGZvciBleGlzdGluZyBmaXh0dXJlcy90ZXN0cy5cclxuICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgTWVldGluZ1JvdyB7XHJcbiAgbWVldGluZ0lkOiBzdHJpbmc7XHJcbiAgbWVldGluZ05hbWU6IHN0cmluZztcclxuICBncm91cE9yQ29tbWl0dGVlPzogc3RyaW5nO1xyXG4gIHJvb21PckxvY2F0aW9uPzogc3RyaW5nO1xyXG4gIC8qKiBTdGFydCBkYXRlLXRpbWUgYXMgYW4gSVNPLTg2MDEgc3RyaW5nIChvciBlcG9jaCBtcyBmb3IgZml4dHVyZXMpLiAqL1xyXG4gIHN0YXJ0RGF0ZVRpbWU/OiBzdHJpbmcgfCBudW1iZXI7XHJcbiAgLyoqIEVuZCBkYXRlLXRpbWUgYXMgYW4gSVNPLTg2MDEgc3RyaW5nIChvciBlcG9jaCBtcyBmb3IgZml4dHVyZXMpLiAqL1xyXG4gIGVuZERhdGVUaW1lPzogc3RyaW5nIHwgbnVtYmVyO1xyXG4gIC8qKiBMZWdhY3kgSVNPIG1lZXRpbmcgZGF0ZSwgcmV0YWluZWQgZm9yIGZpeHR1cmVzL3Rlc3RzLiAqL1xyXG4gIG1lZXRpbmdEYXRlPzogc3RyaW5nO1xyXG4gIC8qKiBMZWdhY3kgSVNPIG1lZXRpbmcgdGltZSwgcmV0YWluZWQgZm9yIGZpeHR1cmVzL3Rlc3RzLiAqL1xyXG4gIG1lZXRpbmdUaW1lPzogc3RyaW5nO1xyXG4gIHRpbWV6b25lOiBzdHJpbmc7XHJcbiAgc3RhdHVzPzogc3RyaW5nO1xyXG4gIGlzTWVtYmVyT2ZHcm91cD86IGJvb2xlYW47XHJcbiAgaXNPcGVuRm9yQXR0ZW5kYW5jZT86IGJvb2xlYW47XHJcbiAgYXR0ZW5kYW5jZVN0YXRlPzogQXR0ZW5kYW5jZVN0YXRlO1xyXG59XHJcbiJdfQ==
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export {};
|
|
2
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXktZ3JvdXBzLXZpZXcubW9kZWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9kYXNoYm9hcmQvc3JjL2xpYi9tb2RlbHMvbXktZ3JvdXBzLXZpZXcubW9kZWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxyXG4gKiBSZWFkLW9ubHkgYWdncmVnYXRlIHZpZXcgcmV0dXJuZWQgYnkgR0VUIC92MS9ncm91cHMvbXktZ3JvdXBzLCBtaXJyb3JpbmcgdGhlXHJcbiAqIGdyb3Vwcy1hcGkgYE15R3JvdXBzVmlld2AgRFRPLiBUaGUgZGFzaGJvYXJkIFwiWW91ciBHcm91cHNcIiBzZWN0aW9uIGNvbnN1bWVzXHJcbiAqIHRoZSBgZ3JvdXBzYCBjb2xsZWN0aW9uOyBgaW50ZXJlc3RzYCBpcyBub3Qgc2hvd24gb24gdGhlIGRhc2hib2FyZC5cclxuICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgTXlHcm91cHNWaWV3IHtcclxuICBncm91cHM6IE15R3JvdXBWaWV3W107XHJcbiAgaW50ZXJlc3RzPzogTXlJbnRlcmVzdFZpZXdbXTtcclxufVxyXG5cclxuLyoqXHJcbiAqIEEgc2luZ2xlIG9mZmljZXIgcm9sZSB0aGUgdXNlciBob2xkcyBpbiBhIGdyb3VwLCBhcyByZXR1cm5lZCBpbiB0aGVcclxuICogYG9mZmljZXJgIGFycmF5IG9mIEdFVCAvdjEvZ3JvdXBzL215LWdyb3Vwcy5cclxuICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgR3JvdXBPZmZpY2VyIHtcclxuICBvZmZpY2VySWQ6IHN0cmluZztcclxuICBvZmZpY2VyTmFtZTogc3RyaW5nO1xyXG59XHJcblxyXG4vKipcclxuICogQSBzaW5nbGUgZ3JvdXAgdGhlIHVzZXIgaXMgYSByb3N0ZXIgbWVtYmVyIG9mLiBDYXJyaWVzIHRoZSBncm91cCdzIG5hbWUsXHJcbiAqIHR5cGUsIGFmZmlsaWF0aW9ucywgdGhlIHVzZXIncyBtZW1iZXIgbGV2ZWwsIGFuZCB0aGUgdXNlcidzIG9mZmljZXIgcm9sZShzKVxyXG4gKiBmb3IgdGhlIGdyb3VwICh0aGUgYG9mZmljZXJgIGFycmF5IOKAlCBlbXB0eSB3aGVuIHRoZSB1c2VyIGhvbGRzIG5vIG9mZmljZXJcclxuICogcm9sZSkuXHJcbiAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIE15R3JvdXBWaWV3IHtcclxuICBncm91cElkOiBzdHJpbmc7XHJcbiAgZ3JvdXBOYW1lOiBzdHJpbmc7XHJcbiAgZ3JvdXBUeXBlPzogc3RyaW5nO1xyXG4gIGdyb3VwVHlwZU5hbWU/OiBzdHJpbmcgfCBudWxsO1xyXG4gIC8qKiBBbmNlc3RvciBoaWVyYXJjaHkgKHJvb3TihpJsZWFmKSBvZiB0aGUgZ3JvdXAsIGZvciB0aGUgZXhwYW5kYWJsZSByb3dzLiAqL1xyXG4gIGhpZXJhcmNoeT86IE15R3JvdXBIaWVyYXJjaHlJdGVtW107XHJcbiAgYWZmaWxpYXRpb25zPzogc3RyaW5nW107XHJcbiAgbWVtYmVyTGV2ZWxJZD86IHN0cmluZyB8IG51bGw7XHJcbiAgbWVtYmVyTGV2ZWw/OiBzdHJpbmcgfCBudWxsO1xyXG4gIC8qKiBPZmZpY2VyIHJvbGVzIHRoZSB1c2VyIGhvbGRzIGluIHRoaXMgZ3JvdXAgKGUuZy4gXCJDaGFpclwiKTsgZW1wdHkgaWYgbm9uZS4gKi9cclxuICBvZmZpY2VyPzogR3JvdXBPZmZpY2VyW107XHJcbn1cclxuXHJcbi8qKiBBIHNpbmdsZSBub2RlIGluIGEgZ3JvdXAncyBhbmNlc3RvciBoaWVyYXJjaHkgKHJvb3TihpJsZWFmKS4gKi9cclxuZXhwb3J0IGludGVyZmFjZSBNeUdyb3VwSGllcmFyY2h5SXRlbSB7XHJcbiAgZ3JvdXBJZDogc3RyaW5nO1xyXG4gIGdyb3VwTmFtZTogc3RyaW5nO1xyXG4gIGdyb3VwU2hvcnROYW1lPzogc3RyaW5nO1xyXG4gIGdyb3VwQWNyb255bT86IHN0cmluZztcclxuICBncm91cExldmVsPzogbnVtYmVyO1xyXG4gIGdyb3VwUGFyZW50SWQ/OiBzdHJpbmcgfCBudWxsO1xyXG4gIGdyb3VwVHlwZT86IHN0cmluZztcclxuICBncm91cFR5cGVOYW1lPzogc3RyaW5nIHwgbnVsbDtcclxuICBncm91cERlc2M/OiBzdHJpbmcgfCBudWxsO1xyXG4gIGhhc0NoaWxkcmVuPzogYm9vbGVhbiB8IG51bGw7XHJcbn1cclxuXHJcbi8qKiBBIHNpbmdsZSBpbnRlcmVzdCB0aGUgdXNlciBoYXMgZXhwcmVzc2VkIChub3Qgc2hvd24gb24gdGhlIGRhc2hib2FyZCkuICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgTXlJbnRlcmVzdFZpZXcge1xyXG4gIGludGVyZXN0SWQ6IHN0cmluZztcclxuICBncm91cElkOiBzdHJpbmc7XHJcbiAgZ3JvdXBOYW1lOiBzdHJpbmc7XHJcbiAgc3RhdHVzOiBzdHJpbmc7XHJcbn1cclxuIl19
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export {};
|
|
2
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFnZS1jaGFuZ2UubW9kZWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9kYXNoYm9hcmQvc3JjL2xpYi9tb2RlbHMvcGFnZS1jaGFuZ2UubW9kZWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBpbnRlcmZhY2UgUGFnZUNoYW5nZSB7XHJcbiAgcGFnZUluZGV4OiBudW1iZXI7XHJcbiAgcGFnZVNpemU6IG51bWJlcjtcclxufVxyXG4iXX0=
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/* eslint-disable no-unused-vars */
|
|
2
|
+
/**
|
|
3
|
+
* Discriminates how a row in the "Upcoming Meetings & Events" list is rendered.
|
|
4
|
+
* EVENT rows render as an expandable event block that owns child meetings;
|
|
5
|
+
* STANDALONE_MEETING rows render as a single meeting card and always sort LAST
|
|
6
|
+
* within the list.
|
|
7
|
+
*/
|
|
8
|
+
export var UpcomingItemKind;
|
|
9
|
+
(function (UpcomingItemKind) {
|
|
10
|
+
UpcomingItemKind["EVENT"] = "EVENT";
|
|
11
|
+
UpcomingItemKind["STANDALONE_MEETING"] = "STANDALONE_MEETING";
|
|
12
|
+
})(UpcomingItemKind || (UpcomingItemKind = {}));
|
|
13
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXBjb21pbmctZXZlbnQubW9kZWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9kYXNoYm9hcmQvc3JjL2xpYi9tb2RlbHMvdXBjb21pbmctZXZlbnQubW9kZWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsbUNBQW1DO0FBQ25DOzs7OztHQUtHO0FBQ0gsTUFBTSxDQUFOLElBQVksZ0JBR1g7QUFIRCxXQUFZLGdCQUFnQjtJQUMxQixtQ0FBZSxDQUFBO0lBQ2YsNkRBQXlDLENBQUE7QUFDM0MsQ0FBQyxFQUhXLGdCQUFnQixLQUFoQixnQkFBZ0IsUUFHM0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBNZWV0aW5nUm93IH0gZnJvbSAnLi9tZWV0aW5nLXJvdy5tb2RlbCc7XHJcblxyXG4vKiBlc2xpbnQtZGlzYWJsZSBuby11bnVzZWQtdmFycyAqL1xyXG4vKipcclxuICogRGlzY3JpbWluYXRlcyBob3cgYSByb3cgaW4gdGhlIFwiVXBjb21pbmcgTWVldGluZ3MgJiBFdmVudHNcIiBsaXN0IGlzIHJlbmRlcmVkLlxyXG4gKiBFVkVOVCByb3dzIHJlbmRlciBhcyBhbiBleHBhbmRhYmxlIGV2ZW50IGJsb2NrIHRoYXQgb3ducyBjaGlsZCBtZWV0aW5ncztcclxuICogU1RBTkRBTE9ORV9NRUVUSU5HIHJvd3MgcmVuZGVyIGFzIGEgc2luZ2xlIG1lZXRpbmcgY2FyZCBhbmQgYWx3YXlzIHNvcnQgTEFTVFxyXG4gKiB3aXRoaW4gdGhlIGxpc3QuXHJcbiAqL1xyXG5leHBvcnQgZW51bSBVcGNvbWluZ0l0ZW1LaW5kIHtcclxuICBFVkVOVCA9ICdFVkVOVCcsXHJcbiAgU1RBTkRBTE9ORV9NRUVUSU5HID0gJ1NUQU5EQUxPTkVfTUVFVElORycsXHJcbn1cclxuLyogZXNsaW50LWVuYWJsZSBuby11bnVzZWQtdmFycyAqL1xyXG5cclxuLyoqXHJcbiAqIFZpZXcgbW9kZWwgZm9yIGEgc2luZ2xlIGVudHJ5IGluIHRoZSBcIlVwY29taW5nIE1lZXRpbmdzICYgRXZlbnRzXCIgc2VjdGlvbi5cclxuICpcclxuICogV2hlbiB7QGxpbmsga2luZH0gaXMgYEVWRU5UYCB0aGUgZW50cnkgcmVuZGVycyBhcyB0aGUgZXhwYW5kYWJsZSBldmVudCBibG9ja1xyXG4gKiAoaGVhZGVyIGJhZGdlLCB0aXRsZSwgXCJEYXkgWCBvZiBZXCIsIG1lZXRpbmctY291bnQgc3ViLWxpbmUsIGRhdGVzL3RpbWV6b25lLFxyXG4gKiBWaWV3IGJ1dHRvbiwgYW5kIHRoZSBzaG93L2hpZGUgY2hpbGQtbWVldGluZyBsaXN0KS4gV2hlbiBga2luZGAgaXNcclxuICogYFNUQU5EQUxPTkVfTUVFVElOR2AgdGhlIGVudHJ5IHJlbmRlcnMgYXMgYSBzaW5nbGUgc3RhbmRhbG9uZSBtZWV0aW5nIGNhcmRcclxuICogKHJlbmRlcmVkIGFmdGVyIGFsbCBldmVudHMpLlxyXG4gKlxyXG4gKiBgc3RhcnRFcG9jaE1zYCAvIGBlbmRFcG9jaE1zYCBjYXJyeSB0aGUgcmF3IGVwb2NoLW1pbGxpc2Vjb25kcyB2YWx1ZXMgZnJvbSB0aGVcclxuICogYmFja2VuZCBhbmQgYXJlIGZvcm1hdHRlZCB3aXRoIGx1eG9uIGBEYXRlVGltZS5mcm9tTWlsbGlzYC4gVGhlIGxlZ2FjeSBJU09cclxuICogYHN0YXJ0RGF0ZWAgLyBgZW5kRGF0ZWAgZmllbGRzIGFyZSByZXRhaW5lZCBmb3IgZXhpc3RpbmcgZml4dHVyZXMvdGVzdHMuXHJcbiAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIFVwY29taW5nRXZlbnQge1xyXG4gIGV2ZW50SWQ6IHN0cmluZztcclxuICAvKiogRVZFTlQgdnMuIFNUQU5EQUxPTkVfTUVFVElORyByZW5kZXIgZGlzY3JpbWluYXRvci4gKi9cclxuICBraW5kOiBVcGNvbWluZ0l0ZW1LaW5kO1xyXG4gIHRpdGxlOiBzdHJpbmc7XHJcbiAgc3RhdHVzOiBzdHJpbmc7XHJcbiAgZGF5SW5kaWNhdG9yPzogc3RyaW5nO1xyXG4gIG1lZXRpbmdDb3VudDogbnVtYmVyO1xyXG4gIG9wZW5Gb3JBdHRlbmRhbmNlQ291bnQ6IG51bWJlcjtcclxuICAvKiogU3RhcnQgZGF0ZS10aW1lIGFzIGFuIElTTy04NjAxIHN0cmluZyAob3IgZXBvY2ggbXMgZm9yIGZpeHR1cmVzKS4gKi9cclxuICBzdGFydERhdGVUaW1lPzogc3RyaW5nIHwgbnVtYmVyO1xyXG4gIC8qKiBFbmQgZGF0ZS10aW1lIGFzIGFuIElTTy04NjAxIHN0cmluZyAob3IgZXBvY2ggbXMgZm9yIGZpeHR1cmVzKS4gKi9cclxuICBlbmREYXRlVGltZT86IHN0cmluZyB8IG51bWJlcjtcclxuICAvKiogTGVnYWN5IElTTyBzdGFydCBkYXRlLCByZXRhaW5lZCBmb3IgZml4dHVyZXMvdGVzdHMuICovXHJcbiAgc3RhcnREYXRlPzogc3RyaW5nO1xyXG4gIC8qKiBMZWdhY3kgSVNPIGVuZCBkYXRlLCByZXRhaW5lZCBmb3IgZml4dHVyZXMvdGVzdHMuICovXHJcbiAgZW5kRGF0ZT86IHN0cmluZztcclxuICB0aW1lem9uZTogc3RyaW5nO1xyXG4gIC8qKiBPd25pbmcgZ3JvdXAgbGFiZWwsIHNob3duIG9uIHN0YW5kYWxvbmUtbWVldGluZyBjYXJkcy4gKi9cclxuICBncm91cE9yQ29tbWl0dGVlPzogc3RyaW5nO1xyXG4gIC8qKiBSb29tIC8gbG9jYXRpb24sIHNob3duIG9uIHN0YW5kYWxvbmUtbWVldGluZyBjYXJkcy4gKi9cclxuICByb29tT3JMb2NhdGlvbj86IHN0cmluZztcclxuICAvKiogVHJ1ZSB3aGVuIHRoZSB1c2VyIGlzIGEgbWVtYmVyIG9mIHRoZSBvd25pbmcgZ3JvdXAuICovXHJcbiAgaXNNZW1iZXJPZkdyb3VwPzogYm9vbGVhbjtcclxuICAvKiogVGhlIGV2ZW50J3MgY2hpbGQgbWVldGluZ3MgKGVtcHR5IC8gbGF6aWx5IGxvYWRlZCBmb3IgRVZFTlQgcm93cykuICovXHJcbiAgbWVldGluZ3M6IE1lZXRpbmdSb3dbXTtcclxufVxyXG4iXX0=
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { AttendanceState } from '../models/attendance-state.model';
|
|
2
|
+
/**
|
|
3
|
+
* Pure reducers for the dashboard attendance state. These functions never
|
|
4
|
+
* mutate their inputs; each returns a new object/set so they can be exercised
|
|
5
|
+
* directly by property tests and composed by the DashboardService.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Produce a new attendance-state map with the target meeting set to
|
|
9
|
+
* CURRENTLY_ATTENDING. Every other entry is copied unchanged (frame property).
|
|
10
|
+
*
|
|
11
|
+
* @param {Record<string, AttendanceState>} map The current attendance-state map (not mutated).
|
|
12
|
+
* @param {string} meetingId The meeting whose state transitions to CURRENTLY_ATTENDING.
|
|
13
|
+
* @return {Record<string, AttendanceState>} A new map reflecting the successful log-attendance action.
|
|
14
|
+
*/
|
|
15
|
+
export const applyLogAttendanceSuccess = (map, meetingId) => ({
|
|
16
|
+
...map,
|
|
17
|
+
[meetingId]: AttendanceState.CURRENTLY_ATTENDING,
|
|
18
|
+
});
|
|
19
|
+
/**
|
|
20
|
+
* Produce a new attendance-state map with the target meeting set to
|
|
21
|
+
* NOT_ATTENDING. Every other entry is copied unchanged (frame property).
|
|
22
|
+
*
|
|
23
|
+
* @param {Record<string, AttendanceState>} map The current attendance-state map (not mutated).
|
|
24
|
+
* @param {string} meetingId The meeting whose state transitions to NOT_ATTENDING.
|
|
25
|
+
* @return {Record<string, AttendanceState>} A new map reflecting the successful leave-meeting action.
|
|
26
|
+
*/
|
|
27
|
+
export const applyLeaveMeetingSuccess = (map, meetingId) => ({
|
|
28
|
+
...map,
|
|
29
|
+
[meetingId]: AttendanceState.NOT_ATTENDING,
|
|
30
|
+
});
|
|
31
|
+
/**
|
|
32
|
+
* Add a meeting to the in-flight set, returning a new set. Prior membership is
|
|
33
|
+
* retained so the displayed attendance state is preserved while the request
|
|
34
|
+
* resolves.
|
|
35
|
+
*
|
|
36
|
+
* @param {ReadonlySet<string>} set The current in-flight meeting-id set (not mutated).
|
|
37
|
+
* @param {string} meetingId The meeting whose attendance action has started.
|
|
38
|
+
* @return {Set<string>} A new set that additionally contains the meeting id.
|
|
39
|
+
*/
|
|
40
|
+
export const beginAttendanceAction = (set, meetingId) => new Set([...set, meetingId]);
|
|
41
|
+
/**
|
|
42
|
+
* Remove a meeting from the in-flight set, returning a new set. All other
|
|
43
|
+
* in-flight ids are retained.
|
|
44
|
+
*
|
|
45
|
+
* @param {ReadonlySet<string>} set The current in-flight meeting-id set (not mutated).
|
|
46
|
+
* @param {string} meetingId The meeting whose attendance action has resolved.
|
|
47
|
+
* @return {Set<string>} A new set that no longer contains the meeting id.
|
|
48
|
+
*/
|
|
49
|
+
export const endAttendanceAction = (set, meetingId) => {
|
|
50
|
+
const next = new Set(set);
|
|
51
|
+
next.delete(meetingId);
|
|
52
|
+
return next;
|
|
53
|
+
};
|
|
54
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXR0ZW5kYW5jZS1yZWR1Y2Vycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Rhc2hib2FyZC9zcmMvbGliL3NlcnZpY2VzL2F0dGVuZGFuY2UtcmVkdWNlcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBRW5FOzs7O0dBSUc7QUFFSDs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxDQUFDLE1BQU0seUJBQXlCLEdBQUcsQ0FDdkMsR0FBb0MsRUFDcEMsU0FBaUIsRUFDZ0IsRUFBRSxDQUFDLENBQUM7SUFDckMsR0FBRyxHQUFHO0lBQ04sQ0FBQyxTQUFTLENBQUMsRUFBRSxlQUFlLENBQUMsbUJBQW1CO0NBQ2pELENBQUMsQ0FBQztBQUVIOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLENBQUMsTUFBTSx3QkFBd0IsR0FBRyxDQUN0QyxHQUFvQyxFQUNwQyxTQUFpQixFQUNnQixFQUFFLENBQUMsQ0FBQztJQUNyQyxHQUFHLEdBQUc7SUFDTixDQUFDLFNBQVMsQ0FBQyxFQUFFLGVBQWUsQ0FBQyxhQUFhO0NBQzNDLENBQUMsQ0FBQztBQUVIOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxDQUFDLE1BQU0scUJBQXFCLEdBQUcsQ0FDbkMsR0FBd0IsRUFDeEIsU0FBaUIsRUFDSixFQUFFLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxHQUFHLEdBQUcsRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDO0FBRS9DOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLENBQUMsTUFBTSxtQkFBbUIsR0FBRyxDQUNqQyxHQUF3QixFQUN4QixTQUFpQixFQUNKLEVBQUU7SUFDZixNQUFNLElBQUksR0FBRyxJQUFJLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUMxQixJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3ZCLE9BQU8sSUFBSSxDQUFDO0FBQ2QsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQXR0ZW5kYW5jZVN0YXRlIH0gZnJvbSAnLi4vbW9kZWxzL2F0dGVuZGFuY2Utc3RhdGUubW9kZWwnO1xyXG5cclxuLyoqXHJcbiAqIFB1cmUgcmVkdWNlcnMgZm9yIHRoZSBkYXNoYm9hcmQgYXR0ZW5kYW5jZSBzdGF0ZS4gVGhlc2UgZnVuY3Rpb25zIG5ldmVyXHJcbiAqIG11dGF0ZSB0aGVpciBpbnB1dHM7IGVhY2ggcmV0dXJucyBhIG5ldyBvYmplY3Qvc2V0IHNvIHRoZXkgY2FuIGJlIGV4ZXJjaXNlZFxyXG4gKiBkaXJlY3RseSBieSBwcm9wZXJ0eSB0ZXN0cyBhbmQgY29tcG9zZWQgYnkgdGhlIERhc2hib2FyZFNlcnZpY2UuXHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIFByb2R1Y2UgYSBuZXcgYXR0ZW5kYW5jZS1zdGF0ZSBtYXAgd2l0aCB0aGUgdGFyZ2V0IG1lZXRpbmcgc2V0IHRvXHJcbiAqIENVUlJFTlRMWV9BVFRFTkRJTkcuIEV2ZXJ5IG90aGVyIGVudHJ5IGlzIGNvcGllZCB1bmNoYW5nZWQgKGZyYW1lIHByb3BlcnR5KS5cclxuICpcclxuICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBBdHRlbmRhbmNlU3RhdGU+fSBtYXAgVGhlIGN1cnJlbnQgYXR0ZW5kYW5jZS1zdGF0ZSBtYXAgKG5vdCBtdXRhdGVkKS5cclxuICogQHBhcmFtIHtzdHJpbmd9IG1lZXRpbmdJZCBUaGUgbWVldGluZyB3aG9zZSBzdGF0ZSB0cmFuc2l0aW9ucyB0byBDVVJSRU5UTFlfQVRURU5ESU5HLlxyXG4gKiBAcmV0dXJuIHtSZWNvcmQ8c3RyaW5nLCBBdHRlbmRhbmNlU3RhdGU+fSBBIG5ldyBtYXAgcmVmbGVjdGluZyB0aGUgc3VjY2Vzc2Z1bCBsb2ctYXR0ZW5kYW5jZSBhY3Rpb24uXHJcbiAqL1xyXG5leHBvcnQgY29uc3QgYXBwbHlMb2dBdHRlbmRhbmNlU3VjY2VzcyA9IChcclxuICBtYXA6IFJlY29yZDxzdHJpbmcsIEF0dGVuZGFuY2VTdGF0ZT4sXHJcbiAgbWVldGluZ0lkOiBzdHJpbmdcclxuKTogUmVjb3JkPHN0cmluZywgQXR0ZW5kYW5jZVN0YXRlPiA9PiAoe1xyXG4gIC4uLm1hcCxcclxuICBbbWVldGluZ0lkXTogQXR0ZW5kYW5jZVN0YXRlLkNVUlJFTlRMWV9BVFRFTkRJTkcsXHJcbn0pO1xyXG5cclxuLyoqXHJcbiAqIFByb2R1Y2UgYSBuZXcgYXR0ZW5kYW5jZS1zdGF0ZSBtYXAgd2l0aCB0aGUgdGFyZ2V0IG1lZXRpbmcgc2V0IHRvXHJcbiAqIE5PVF9BVFRFTkRJTkcuIEV2ZXJ5IG90aGVyIGVudHJ5IGlzIGNvcGllZCB1bmNoYW5nZWQgKGZyYW1lIHByb3BlcnR5KS5cclxuICpcclxuICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBBdHRlbmRhbmNlU3RhdGU+fSBtYXAgVGhlIGN1cnJlbnQgYXR0ZW5kYW5jZS1zdGF0ZSBtYXAgKG5vdCBtdXRhdGVkKS5cclxuICogQHBhcmFtIHtzdHJpbmd9IG1lZXRpbmdJZCBUaGUgbWVldGluZyB3aG9zZSBzdGF0ZSB0cmFuc2l0aW9ucyB0byBOT1RfQVRURU5ESU5HLlxyXG4gKiBAcmV0dXJuIHtSZWNvcmQ8c3RyaW5nLCBBdHRlbmRhbmNlU3RhdGU+fSBBIG5ldyBtYXAgcmVmbGVjdGluZyB0aGUgc3VjY2Vzc2Z1bCBsZWF2ZS1tZWV0aW5nIGFjdGlvbi5cclxuICovXHJcbmV4cG9ydCBjb25zdCBhcHBseUxlYXZlTWVldGluZ1N1Y2Nlc3MgPSAoXHJcbiAgbWFwOiBSZWNvcmQ8c3RyaW5nLCBBdHRlbmRhbmNlU3RhdGU+LFxyXG4gIG1lZXRpbmdJZDogc3RyaW5nXHJcbik6IFJlY29yZDxzdHJpbmcsIEF0dGVuZGFuY2VTdGF0ZT4gPT4gKHtcclxuICAuLi5tYXAsXHJcbiAgW21lZXRpbmdJZF06IEF0dGVuZGFuY2VTdGF0ZS5OT1RfQVRURU5ESU5HLFxyXG59KTtcclxuXHJcbi8qKlxyXG4gKiBBZGQgYSBtZWV0aW5nIHRvIHRoZSBpbi1mbGlnaHQgc2V0LCByZXR1cm5pbmcgYSBuZXcgc2V0LiBQcmlvciBtZW1iZXJzaGlwIGlzXHJcbiAqIHJldGFpbmVkIHNvIHRoZSBkaXNwbGF5ZWQgYXR0ZW5kYW5jZSBzdGF0ZSBpcyBwcmVzZXJ2ZWQgd2hpbGUgdGhlIHJlcXVlc3RcclxuICogcmVzb2x2ZXMuXHJcbiAqXHJcbiAqIEBwYXJhbSB7UmVhZG9ubHlTZXQ8c3RyaW5nPn0gc2V0IFRoZSBjdXJyZW50IGluLWZsaWdodCBtZWV0aW5nLWlkIHNldCAobm90IG11dGF0ZWQpLlxyXG4gKiBAcGFyYW0ge3N0cmluZ30gbWVldGluZ0lkIFRoZSBtZWV0aW5nIHdob3NlIGF0dGVuZGFuY2UgYWN0aW9uIGhhcyBzdGFydGVkLlxyXG4gKiBAcmV0dXJuIHtTZXQ8c3RyaW5nPn0gQSBuZXcgc2V0IHRoYXQgYWRkaXRpb25hbGx5IGNvbnRhaW5zIHRoZSBtZWV0aW5nIGlkLlxyXG4gKi9cclxuZXhwb3J0IGNvbnN0IGJlZ2luQXR0ZW5kYW5jZUFjdGlvbiA9IChcclxuICBzZXQ6IFJlYWRvbmx5U2V0PHN0cmluZz4sXHJcbiAgbWVldGluZ0lkOiBzdHJpbmdcclxuKTogU2V0PHN0cmluZz4gPT4gbmV3IFNldChbLi4uc2V0LCBtZWV0aW5nSWRdKTtcclxuXHJcbi8qKlxyXG4gKiBSZW1vdmUgYSBtZWV0aW5nIGZyb20gdGhlIGluLWZsaWdodCBzZXQsIHJldHVybmluZyBhIG5ldyBzZXQuIEFsbCBvdGhlclxyXG4gKiBpbi1mbGlnaHQgaWRzIGFyZSByZXRhaW5lZC5cclxuICpcclxuICogQHBhcmFtIHtSZWFkb25seVNldDxzdHJpbmc+fSBzZXQgVGhlIGN1cnJlbnQgaW4tZmxpZ2h0IG1lZXRpbmctaWQgc2V0IChub3QgbXV0YXRlZCkuXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBtZWV0aW5nSWQgVGhlIG1lZXRpbmcgd2hvc2UgYXR0ZW5kYW5jZSBhY3Rpb24gaGFzIHJlc29sdmVkLlxyXG4gKiBAcmV0dXJuIHtTZXQ8c3RyaW5nPn0gQSBuZXcgc2V0IHRoYXQgbm8gbG9uZ2VyIGNvbnRhaW5zIHRoZSBtZWV0aW5nIGlkLlxyXG4gKi9cclxuZXhwb3J0IGNvbnN0IGVuZEF0dGVuZGFuY2VBY3Rpb24gPSAoXHJcbiAgc2V0OiBSZWFkb25seVNldDxzdHJpbmc+LFxyXG4gIG1lZXRpbmdJZDogc3RyaW5nXHJcbik6IFNldDxzdHJpbmc+ID0+IHtcclxuICBjb25zdCBuZXh0ID0gbmV3IFNldChzZXQpO1xyXG4gIG5leHQuZGVsZXRlKG1lZXRpbmdJZCk7XHJcbiAgcmV0dXJuIG5leHQ7XHJcbn07XHJcbiJdfQ==
|
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
import { Injectable } from '@angular/core';
|
|
2
|
+
import { BehaviorSubject, catchError, map, of, } from 'rxjs';
|
|
3
|
+
import { AttendanceState } from '../models/attendance-state.model';
|
|
4
|
+
import { DashboardSectionState } from '../models/dashboard-section-state.model';
|
|
5
|
+
import { UpcomingItemKind, } from '../models/upcoming-event.model';
|
|
6
|
+
import { mapEventMeetingDetails, mapEventMeetingList, } from '../utils/event-meeting-mapper.util';
|
|
7
|
+
import { applyLeaveMeetingSuccess, applyLogAttendanceSuccess, beginAttendanceAction, endAttendanceAction, } from './attendance-reducers';
|
|
8
|
+
import * as i0 from "@angular/core";
|
|
9
|
+
import * as i1 from "@ieeesa-npm/utility";
|
|
10
|
+
/** Fallback label for an empty group type / member level, matching the My Groups tab. */
|
|
11
|
+
const UNASSIGNED_LABEL = 'Unassigned';
|
|
12
|
+
/** Placeholder for an empty cell value. */
|
|
13
|
+
const EMPTY_VALUE = '-';
|
|
14
|
+
/** Statuses included in the upcoming section, matching the view-events-meetings-list screen. */
|
|
15
|
+
const UPCOMING_STATUSES = ['In Progress', 'Upcoming'];
|
|
16
|
+
/** Sort column used for the top-level events & meetings list. */
|
|
17
|
+
const UPCOMING_SORT_COLUMN = 'startDateTime';
|
|
18
|
+
/** Sort column used for an event's expanded child-meeting list (meetingsDetails). */
|
|
19
|
+
const EVENT_MEETINGS_SORT_COLUMN = 'meetingStDate';
|
|
20
|
+
/** Default page size for the top-level upcoming section list. */
|
|
21
|
+
const UPCOMING_PAGE_SIZE = 10;
|
|
22
|
+
/** Default page size for an event's expanded child-meeting list. */
|
|
23
|
+
const EVENT_MEETINGS_PAGE_SIZE = 5;
|
|
24
|
+
/** Large page size used by the eager count prefetch to capture the full set. */
|
|
25
|
+
const EVENT_COUNT_PAGE_SIZE = 200;
|
|
26
|
+
/**
|
|
27
|
+
* DashboardService is the single source of truth for the dashboard landing
|
|
28
|
+
* page's data and attendance state. It mirrors the `events-and-meetings`
|
|
29
|
+
* service conventions: it is a `providedIn: 'root'` singleton, holds the host
|
|
30
|
+
* `apiBaseUrl` / `userPermissions` set via {@link setAppConfig}, owns its state
|
|
31
|
+
* via `BehaviorSubject`s exposed as observables, and reaches the backend only
|
|
32
|
+
* through the shared `HttpService` from `@ieeesa-npm/utility` (never
|
|
33
|
+
* `HttpClient` directly).
|
|
34
|
+
*
|
|
35
|
+
* The upcoming-events load calls the real `POST /meetings/eventsAndMeetings`
|
|
36
|
+
* endpoint (child meetings are lazily loaded per-event via
|
|
37
|
+
* `POST /meetings/meetingsDetails`); the groups load calls `GET
|
|
38
|
+
* /groups/my-groups`. The attendance actions compose the pure reducers from
|
|
39
|
+
* `attendance-reducers.ts` so the displayed `AttendanceState` only advances on a
|
|
40
|
+
* successful resolution and the prior state is retained on failure.
|
|
41
|
+
* @export
|
|
42
|
+
* @class DashboardService
|
|
43
|
+
*/
|
|
44
|
+
export class DashboardService {
|
|
45
|
+
constructor(
|
|
46
|
+
// eslint-disable-next-line no-unused-vars
|
|
47
|
+
httpService // eslint-disable-next-line no-empty-function
|
|
48
|
+
) {
|
|
49
|
+
this.httpService = httpService;
|
|
50
|
+
this.upcomingEvents = new BehaviorSubject([]);
|
|
51
|
+
this.groups = new BehaviorSubject([]);
|
|
52
|
+
this.upcomingState = new BehaviorSubject(DashboardSectionState.LOADING);
|
|
53
|
+
this.groupsState = new BehaviorSubject(DashboardSectionState.LOADING);
|
|
54
|
+
this.attendanceStates = new BehaviorSubject({});
|
|
55
|
+
this.inFlightMeetingIds = new BehaviorSubject(new Set());
|
|
56
|
+
/** Emits the list of the user's upcoming events. */
|
|
57
|
+
this.upcomingEvents$ = this.upcomingEvents.asObservable();
|
|
58
|
+
/** Emits the list of the user's groups. */
|
|
59
|
+
this.groups$ = this.groups.asObservable();
|
|
60
|
+
/** Emits the load/empty/error state of the upcoming-events section. */
|
|
61
|
+
this.upcomingState$ = this.upcomingState.asObservable();
|
|
62
|
+
/** Emits the load/empty/error state of the groups section. */
|
|
63
|
+
this.groupsState$ = this.groupsState.asObservable();
|
|
64
|
+
/** Emits the per-meeting attendance-state map. */
|
|
65
|
+
this.attendanceStates$ = this.attendanceStates.asObservable();
|
|
66
|
+
/** Emits the set of meeting ids with an attendance action in flight. */
|
|
67
|
+
this.inFlightMeetingIds$ = this.inFlightMeetingIds.asObservable();
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Stores the host-supplied API base URL and user permissions used to build
|
|
71
|
+
* request URLs and gate permission-controlled actions. Mirrors the
|
|
72
|
+
* `events-and-meetings` service `setAppConfig`.
|
|
73
|
+
* @param {string} apiBaseURL - The host application's API base URL.
|
|
74
|
+
* @param {UserPermission[]} userPermissions - The signed-in user's permissions.
|
|
75
|
+
* @return {void}
|
|
76
|
+
* @memberof DashboardService
|
|
77
|
+
*/
|
|
78
|
+
setAppConfig(apiBaseURL, userPermissions) {
|
|
79
|
+
this.apiBaseUrl = apiBaseURL;
|
|
80
|
+
this.userPermissions = userPermissions;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Loads the user's upcoming events & meetings from the real backend via
|
|
84
|
+
* `POST {apiBaseUrl}/meetings/eventsAndMeetings`, the same endpoint the
|
|
85
|
+
* `view-events-meetings-list` screen uses. The response is mapped into the
|
|
86
|
+
* dashboard view models (with STANDALONE_MEETING rows ordered last), the
|
|
87
|
+
* per-meeting attendance-state map is seeded, and the section advances through
|
|
88
|
+
* LOADING → LOADED/EMPTY on success, leaving the caller to set ERROR on
|
|
89
|
+
* failure. Follows the shared `pipe(map, catchError(throw))` pattern.
|
|
90
|
+
* @return {Observable<EventMeetingListResponse>} The upcoming events & meetings response envelope.
|
|
91
|
+
* @memberof DashboardService
|
|
92
|
+
*/
|
|
93
|
+
loadUpcomingEvents() {
|
|
94
|
+
this.upcomingState.next(DashboardSectionState.LOADING);
|
|
95
|
+
const payload = {
|
|
96
|
+
payload: {
|
|
97
|
+
eventId: null,
|
|
98
|
+
sortColumn: UPCOMING_SORT_COLUMN,
|
|
99
|
+
ascendingOrder: true,
|
|
100
|
+
page: 1,
|
|
101
|
+
size: UPCOMING_PAGE_SIZE,
|
|
102
|
+
filter: {
|
|
103
|
+
status: UPCOMING_STATUSES,
|
|
104
|
+
isAllMeetingSelected: false,
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
return this.httpService
|
|
109
|
+
.postData(`${this.apiBaseUrl}/meetings/eventsAndMeetings`, payload)
|
|
110
|
+
.pipe(map((response) => {
|
|
111
|
+
const events = mapEventMeetingList(response?.body?.eventMeetingList ?? []);
|
|
112
|
+
this.upcomingEvents.next(events);
|
|
113
|
+
this.seedAttendanceStates(events);
|
|
114
|
+
this.upcomingState.next(events.length > 0
|
|
115
|
+
? DashboardSectionState.LOADED
|
|
116
|
+
: DashboardSectionState.EMPTY);
|
|
117
|
+
// Eagerly fetch each EVENT's meeting count so the "{n} meetings" and
|
|
118
|
+
// "{n} open for attendance" summaries are correct before expanding.
|
|
119
|
+
this.loadEventCounts(events);
|
|
120
|
+
return response;
|
|
121
|
+
}), catchError((error) => {
|
|
122
|
+
this.upcomingState.next(DashboardSectionState.ERROR);
|
|
123
|
+
throw error;
|
|
124
|
+
}));
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Lazily loads (and paginates) the child meetings of an EVENT row via
|
|
128
|
+
* `POST {apiBaseUrl}/meetings/meetingsDetails` — the per-event expand endpoint
|
|
129
|
+
* used by the reference screen. On success the loaded meetings are mapped and
|
|
130
|
+
* merged onto the matching event in the `upcomingEvents` list (with its
|
|
131
|
+
* `meetingCount` / `openForAttendanceCount` refreshed), and the per-meeting
|
|
132
|
+
* attendance-state map is extended. Each event paginates independently.
|
|
133
|
+
* @param {string} eventId - The event whose meetings to load.
|
|
134
|
+
* @param {number} [page=1] - The one-based page to request.
|
|
135
|
+
* @param {number} [size=EVENT_MEETINGS_PAGE_SIZE] - The page size.
|
|
136
|
+
* @return {Observable<EventMeetingDetailResponse>} The child-meetings response envelope.
|
|
137
|
+
* @memberof DashboardService
|
|
138
|
+
*/
|
|
139
|
+
loadEventMeetings(eventId, page = 1, size = EVENT_MEETINGS_PAGE_SIZE) {
|
|
140
|
+
return this.fetchEventMeetingsPage(eventId, page, size).pipe(map((response) => {
|
|
141
|
+
const meetings = mapEventMeetingDetails(response?.body?.meetings ?? []);
|
|
142
|
+
const total = response?.body?.totalRecords ?? meetings.length;
|
|
143
|
+
// Prefer the already-known full open count on the event; fall back to
|
|
144
|
+
// the current page's open count when it hasn't been prefetched.
|
|
145
|
+
const existing = this.upcomingEvents.value.find((event) => event.eventId === eventId);
|
|
146
|
+
const pageOpenCount = meetings.filter((meeting) => meeting.isOpenForAttendance).length;
|
|
147
|
+
const openForAttendanceCount = existing?.openForAttendanceCount || pageOpenCount;
|
|
148
|
+
this.mergeEventMeetings(eventId, meetings, total, openForAttendanceCount);
|
|
149
|
+
this.seedAttendanceStatesFromMeetings(meetings);
|
|
150
|
+
return response;
|
|
151
|
+
}), catchError((error) => {
|
|
152
|
+
throw error;
|
|
153
|
+
}));
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Merges a freshly loaded page of child meetings onto the matching event in
|
|
157
|
+
* the `upcomingEvents` list, refreshing the event's `meetings`,
|
|
158
|
+
* `meetingCount` (from the backend `totalRecords`), and
|
|
159
|
+
* `openForAttendanceCount`. Leaves all other events untouched.
|
|
160
|
+
* @param {string} eventId - The event to merge meetings onto.
|
|
161
|
+
* @param {MeetingRow[]} meetings - The mapped child meetings for the page.
|
|
162
|
+
* @param {number} totalRecords - The event's total meeting count from the backend.
|
|
163
|
+
* @return {void}
|
|
164
|
+
* @memberof DashboardService
|
|
165
|
+
*/
|
|
166
|
+
mergeEventMeetings(eventId, meetings, totalRecords, openForAttendanceCount) {
|
|
167
|
+
const next = this.upcomingEvents.value.map((event) => {
|
|
168
|
+
if (event.eventId !== eventId) {
|
|
169
|
+
return event;
|
|
170
|
+
}
|
|
171
|
+
return {
|
|
172
|
+
...event,
|
|
173
|
+
meetings,
|
|
174
|
+
meetingCount: totalRecords,
|
|
175
|
+
openForAttendanceCount,
|
|
176
|
+
};
|
|
177
|
+
});
|
|
178
|
+
this.upcomingEvents.next(next);
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Eagerly fetches each EVENT's total meeting count and open-for-attendance
|
|
182
|
+
* count by requesting a large first page of its child meetings, then merging
|
|
183
|
+
* only the counts (not the rows) so the collapsed card summaries are accurate
|
|
184
|
+
* before the user expands. Standalone meetings are skipped. Failures per event
|
|
185
|
+
* are swallowed so one failing count never breaks the list.
|
|
186
|
+
* @param {UpcomingEvent[]} events - The loaded events to fetch counts for.
|
|
187
|
+
* @return {void}
|
|
188
|
+
* @memberof DashboardService
|
|
189
|
+
*/
|
|
190
|
+
loadEventCounts(events) {
|
|
191
|
+
events
|
|
192
|
+
.filter((event) => event.kind === UpcomingItemKind.EVENT && event.eventId)
|
|
193
|
+
.forEach((event) => {
|
|
194
|
+
this.fetchEventMeetingsPage(event.eventId, 1, EVENT_COUNT_PAGE_SIZE)
|
|
195
|
+
.pipe(catchError(() => of(null)))
|
|
196
|
+
.subscribe((response) => {
|
|
197
|
+
if (!response) {
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
const meetings = mapEventMeetingDetails(response?.body?.meetings ?? []);
|
|
201
|
+
const total = response?.body?.totalRecords ?? meetings.length;
|
|
202
|
+
const openCount = meetings.filter((meeting) => meeting.isOpenForAttendance).length;
|
|
203
|
+
this.mergeEventCounts(event.eventId, total, openCount);
|
|
204
|
+
this.seedAttendanceStatesFromMeetings(meetings);
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Merges only the meeting counts onto the matching event, leaving its
|
|
210
|
+
* `meetings` rows untouched (used by the eager count prefetch).
|
|
211
|
+
* @param {string} eventId - The event to update.
|
|
212
|
+
* @param {number} totalRecords - The event's total meeting count.
|
|
213
|
+
* @param {number} openForAttendanceCount - The open-for-attendance count.
|
|
214
|
+
* @return {void}
|
|
215
|
+
* @memberof DashboardService
|
|
216
|
+
*/
|
|
217
|
+
mergeEventCounts(eventId, totalRecords, openForAttendanceCount) {
|
|
218
|
+
const next = this.upcomingEvents.value.map((event) => event.eventId === eventId
|
|
219
|
+
? { ...event, meetingCount: totalRecords, openForAttendanceCount }
|
|
220
|
+
: event);
|
|
221
|
+
this.upcomingEvents.next(next);
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Builds and posts the `meetingsDetails` request for a single event page,
|
|
225
|
+
* returning the raw response envelope. Shared by {@link loadEventMeetings} and
|
|
226
|
+
* the eager count prefetch.
|
|
227
|
+
* @param {string} eventId - The event whose meetings to fetch.
|
|
228
|
+
* @param {number} page - The one-based page to request.
|
|
229
|
+
* @param {number} size - The page size.
|
|
230
|
+
* @return {Observable<EventMeetingDetailResponse>} The child-meetings response.
|
|
231
|
+
* @memberof DashboardService
|
|
232
|
+
*/
|
|
233
|
+
fetchEventMeetingsPage(eventId, page, size) {
|
|
234
|
+
const payload = {
|
|
235
|
+
payload: {
|
|
236
|
+
eventId,
|
|
237
|
+
sortColumn: EVENT_MEETINGS_SORT_COLUMN,
|
|
238
|
+
ascendingOrder: true,
|
|
239
|
+
page,
|
|
240
|
+
size,
|
|
241
|
+
filter: {
|
|
242
|
+
status: UPCOMING_STATUSES,
|
|
243
|
+
isAllMeetingSelected: false,
|
|
244
|
+
},
|
|
245
|
+
},
|
|
246
|
+
};
|
|
247
|
+
return this.httpService.postData(`${this.apiBaseUrl}/meetings/meetingsDetails`, payload);
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Loads the user's groups, driving the groups section through
|
|
251
|
+
* LOADING → LOADED/EMPTY on success and leaving the caller to set ERROR on
|
|
252
|
+
* failure. Follows the `pipe(map, catchError(throw))` pattern.
|
|
253
|
+
*
|
|
254
|
+
* TODO: Replace mock with real API call when BE is ready
|
|
255
|
+
* @return {Observable<DashboardListResponse<GroupRow[]>>} The groups response envelope.
|
|
256
|
+
* @memberof DashboardService
|
|
257
|
+
*/
|
|
258
|
+
loadGroups() {
|
|
259
|
+
this.groupsState.next(DashboardSectionState.LOADING);
|
|
260
|
+
return this.httpService
|
|
261
|
+
.getData(`${this.apiBaseUrl}/groups/my-groups`)
|
|
262
|
+
.pipe(map((response) => {
|
|
263
|
+
const groups = (response?.body?.groups ?? []).map((group) => this.mapGroup(group));
|
|
264
|
+
this.groups.next(groups);
|
|
265
|
+
this.groupsState.next(groups.length > 0
|
|
266
|
+
? DashboardSectionState.LOADED
|
|
267
|
+
: DashboardSectionState.EMPTY);
|
|
268
|
+
return response;
|
|
269
|
+
}), catchError((error) => {
|
|
270
|
+
this.groupsState.next(DashboardSectionState.ERROR);
|
|
271
|
+
throw error;
|
|
272
|
+
}));
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Maps a backend {@link MyGroupView} to the table-facing {@link GroupRow}.
|
|
276
|
+
* Mirrors the My Groups profile tab: the type falls back to "Unassigned" when
|
|
277
|
+
* `groupTypeName` is null, affiliations are comma-joined, empty officer role /
|
|
278
|
+
* affiliation render as a placeholder, and a blank member level becomes
|
|
279
|
+
* "Unassigned" (rendered as the warning pill by the Your Groups component).
|
|
280
|
+
* @param {MyGroupView} group - The backend group view.
|
|
281
|
+
* @return {GroupRow}
|
|
282
|
+
* @memberof DashboardService
|
|
283
|
+
*/
|
|
284
|
+
mapGroup(group) {
|
|
285
|
+
// The backend returns officer roles as an `officer` array of
|
|
286
|
+
// { officerId, officerName }. Join the names for the Officer Role column
|
|
287
|
+
// (e.g. "Chair" or "Chair, Vice Chair"); show the placeholder when empty.
|
|
288
|
+
const officerRole = (group.officer ?? [])
|
|
289
|
+
.map((officer) => officer?.officerName?.trim())
|
|
290
|
+
.filter((name) => !!name)
|
|
291
|
+
.join(', ') || EMPTY_VALUE;
|
|
292
|
+
return {
|
|
293
|
+
groupId: group.groupId,
|
|
294
|
+
group: group.groupName,
|
|
295
|
+
type: group.groupTypeName || group.groupType || UNASSIGNED_LABEL,
|
|
296
|
+
officerRole,
|
|
297
|
+
affiliation: group.affiliations?.join(', ') || EMPTY_VALUE,
|
|
298
|
+
memberLevel: group.memberLevel?.trim() || UNASSIGNED_LABEL,
|
|
299
|
+
// Carry the ancestor hierarchy through for the expandable hierarchy rows.
|
|
300
|
+
hierarchy: group.hierarchy ?? [],
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Logs attendance for a meeting. Marks the meeting in-flight (retaining the
|
|
305
|
+
* prior displayed state), posts through `HttpService`, applies the
|
|
306
|
+
* log-attendance-success reducer on success, clears the in-flight flag on
|
|
307
|
+
* completion, and rethrows while retaining prior state on failure.
|
|
308
|
+
* @param {string} meetingId - The meeting to log attendance for.
|
|
309
|
+
* @return {Observable<DashboardListResponse<unknown>>} The attendance response envelope.
|
|
310
|
+
* @memberof DashboardService
|
|
311
|
+
*/
|
|
312
|
+
logAttendance(meetingId) {
|
|
313
|
+
this.inFlightMeetingIds.next(beginAttendanceAction(this.inFlightMeetingIds.value, meetingId));
|
|
314
|
+
return this.httpService
|
|
315
|
+
.postData(`${this.apiBaseUrl}/meetings/attendance/log`, { meetingId })
|
|
316
|
+
.pipe(map((response) => {
|
|
317
|
+
this.attendanceStates.next(applyLogAttendanceSuccess(this.attendanceStates.value, meetingId));
|
|
318
|
+
this.inFlightMeetingIds.next(endAttendanceAction(this.inFlightMeetingIds.value, meetingId));
|
|
319
|
+
return response;
|
|
320
|
+
}), catchError((error) => {
|
|
321
|
+
// Retain prior attendance state; only clear the in-flight flag.
|
|
322
|
+
this.inFlightMeetingIds.next(endAttendanceAction(this.inFlightMeetingIds.value, meetingId));
|
|
323
|
+
throw error;
|
|
324
|
+
}));
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Leaves a meeting. Marks the meeting in-flight (retaining the prior
|
|
328
|
+
* displayed state), posts through `HttpService`, applies the
|
|
329
|
+
* leave-meeting-success reducer on success, clears the in-flight flag on
|
|
330
|
+
* completion, and rethrows while retaining prior state on failure.
|
|
331
|
+
* @param {string} meetingId - The meeting to leave.
|
|
332
|
+
* @return {Observable<DashboardListResponse<unknown>>} The attendance response envelope.
|
|
333
|
+
* @memberof DashboardService
|
|
334
|
+
*/
|
|
335
|
+
leaveMeeting(meetingId) {
|
|
336
|
+
this.inFlightMeetingIds.next(beginAttendanceAction(this.inFlightMeetingIds.value, meetingId));
|
|
337
|
+
return this.httpService
|
|
338
|
+
.postData(`${this.apiBaseUrl}/meetings/attendance/leave`, { meetingId })
|
|
339
|
+
.pipe(map((response) => {
|
|
340
|
+
this.attendanceStates.next(applyLeaveMeetingSuccess(this.attendanceStates.value, meetingId));
|
|
341
|
+
this.inFlightMeetingIds.next(endAttendanceAction(this.inFlightMeetingIds.value, meetingId));
|
|
342
|
+
return response;
|
|
343
|
+
}), catchError((error) => {
|
|
344
|
+
// Retain prior attendance state; only clear the in-flight flag.
|
|
345
|
+
this.inFlightMeetingIds.next(endAttendanceAction(this.inFlightMeetingIds.value, meetingId));
|
|
346
|
+
throw error;
|
|
347
|
+
}));
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Returns a synchronous snapshot of the per-meeting attendance-state map.
|
|
351
|
+
* @return {Record<string, AttendanceState>} The current attendance-state map.
|
|
352
|
+
* @memberof DashboardService
|
|
353
|
+
*/
|
|
354
|
+
getAttendanceStatesSnapshot() {
|
|
355
|
+
return this.attendanceStates.value;
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Seeds the attendance-state map from a freshly loaded list of events, using
|
|
359
|
+
* each meeting's `attendanceState` (defaulting to `NOT_ATTENDING`). Keeps the
|
|
360
|
+
* displayed state in sync with the data load without overwriting ids that are
|
|
361
|
+
* not present in the new list.
|
|
362
|
+
* @param {UpcomingEvent[]} events - The loaded upcoming events.
|
|
363
|
+
* @return {void}
|
|
364
|
+
* @memberof DashboardService
|
|
365
|
+
*/
|
|
366
|
+
seedAttendanceStates(events) {
|
|
367
|
+
const meetings = events.flatMap((event) => event.meetings ?? []);
|
|
368
|
+
this.seedAttendanceStatesFromMeetings(meetings);
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Seeds the attendance-state map from a list of meeting rows, using each
|
|
372
|
+
* meeting's `attendanceState` (defaulting to `NOT_ATTENDING`) without
|
|
373
|
+
* overwriting ids absent from the new list. Shared by the list load and the
|
|
374
|
+
* per-event expand so freshly loaded child meetings pick up their state.
|
|
375
|
+
* @param {MeetingRow[]} meetings - The meeting rows to seed from.
|
|
376
|
+
* @return {void}
|
|
377
|
+
* @memberof DashboardService
|
|
378
|
+
*/
|
|
379
|
+
seedAttendanceStatesFromMeetings(meetings) {
|
|
380
|
+
const next = {
|
|
381
|
+
...this.attendanceStates.value,
|
|
382
|
+
};
|
|
383
|
+
meetings.forEach((meeting) => {
|
|
384
|
+
if (meeting.meetingId) {
|
|
385
|
+
next[meeting.meetingId] =
|
|
386
|
+
meeting.attendanceState ??
|
|
387
|
+
next[meeting.meetingId] ??
|
|
388
|
+
AttendanceState.NOT_ATTENDING;
|
|
389
|
+
}
|
|
390
|
+
});
|
|
391
|
+
this.attendanceStates.next(next);
|
|
392
|
+
}
|
|
393
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DashboardService, deps: [{ token: i1.HttpService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
394
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DashboardService, providedIn: 'root' }); }
|
|
395
|
+
}
|
|
396
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DashboardService, decorators: [{
|
|
397
|
+
type: Injectable,
|
|
398
|
+
args: [{
|
|
399
|
+
providedIn: 'root',
|
|
400
|
+
}]
|
|
401
|
+
}], ctorParameters: function () { return [{ type: i1.HttpService }]; } });
|
|
402
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGFzaGJvYXJkLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9kYXNoYm9hcmQvc3JjL2xpYi9zZXJ2aWNlcy9kYXNoYm9hcmQuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFDTCxlQUFlLEVBRWYsVUFBVSxFQUNWLEdBQUcsRUFDSCxFQUFFLEdBQ0gsTUFBTSxNQUFNLENBQUM7QUFHZCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFFbkUsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFNaEYsT0FBTyxFQUVMLGdCQUFnQixHQUNqQixNQUFNLGdDQUFnQyxDQUFDO0FBU3hDLE9BQU8sRUFDTCxzQkFBc0IsRUFDdEIsbUJBQW1CLEdBQ3BCLE1BQU0sb0NBQW9DLENBQUM7QUFtQjVDLE9BQU8sRUFDTCx3QkFBd0IsRUFDeEIseUJBQXlCLEVBQ3pCLHFCQUFxQixFQUNyQixtQkFBbUIsR0FDcEIsTUFBTSx1QkFBdUIsQ0FBQzs7O0FBckIvQix5RkFBeUY7QUFDekYsTUFBTSxnQkFBZ0IsR0FBRyxZQUFZLENBQUM7QUFDdEMsMkNBQTJDO0FBQzNDLE1BQU0sV0FBVyxHQUFHLEdBQUcsQ0FBQztBQUN4QixnR0FBZ0c7QUFDaEcsTUFBTSxpQkFBaUIsR0FBRyxDQUFDLGFBQWEsRUFBRSxVQUFVLENBQUMsQ0FBQztBQUN0RCxpRUFBaUU7QUFDakUsTUFBTSxvQkFBb0IsR0FBRyxlQUFlLENBQUM7QUFDN0MscUZBQXFGO0FBQ3JGLE1BQU0sMEJBQTBCLEdBQUcsZUFBZSxDQUFDO0FBQ25ELGlFQUFpRTtBQUNqRSxNQUFNLGtCQUFrQixHQUFHLEVBQUUsQ0FBQztBQUM5QixvRUFBb0U7QUFDcEUsTUFBTSx3QkFBd0IsR0FBRyxDQUFDLENBQUM7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LENBQUMsS0FBSztTQUMvQixDQUFDO1FBQ0YsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFO1lBQzNCLElBQUksT0FBTyxDQUFDLFNBQVMsRUFBRTtnQkFDckIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUM7b0JBQ3JCLE9BQU8sQ0FBQyxlQUFlO3dCQUN2QixJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQzt3QkFDdkIsZUFBZSxDQUFDLGFBQWEsQ0FBQzthQUNqQztRQUNILENBQUMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNuQyxDQUFDOytHQTFjVSxnQkFBZ0I7bUhBQWhCLGdCQUFnQixjQUZmLE1BQU07OzRGQUVQLGdCQUFnQjtrQkFINUIsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7XHJcbiAgQmVoYXZpb3JTdWJqZWN0LFxyXG4gIE9ic2VydmFibGUsXHJcbiAgY2F0Y2hFcnJvcixcclxuICBtYXAsXHJcbiAgb2YsXHJcbn0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IEh0dHBTZXJ2aWNlIH0gZnJvbSAnQGllZWVzYS1ucG0vdXRpbGl0eSc7XHJcbmltcG9ydCB7IFVzZXJQZXJtaXNzaW9uIH0gZnJvbSAnQGllZWVzYS1ucG0vbW9kZWxzJztcclxuaW1wb3J0IHsgQXR0ZW5kYW5jZVN0YXRlIH0gZnJvbSAnLi4vbW9kZWxzL2F0dGVuZGFuY2Utc3RhdGUubW9kZWwnO1xyXG5pbXBvcnQgeyBEYXNoYm9hcmRMaXN0UmVzcG9uc2UgfSBmcm9tICcuLi9tb2RlbHMvZGFzaGJvYXJkLWxpc3QtcmVzcG9uc2UubW9kZWwnO1xyXG5pbXBvcnQgeyBEYXNoYm9hcmRTZWN0aW9uU3RhdGUgfSBmcm9tICcuLi9tb2RlbHMvZGFzaGJvYXJkLXNlY3Rpb24tc3RhdGUubW9kZWwnO1xyXG5pbXBvcnQgeyBHcm91cFJvdyB9IGZyb20gJy4uL21vZGVscy9ncm91cC1yb3cubW9kZWwnO1xyXG5pbXBvcnQge1xyXG4gIE15R3JvdXBzVmlldyxcclxuICBNeUdyb3VwVmlldyxcclxufSBmcm9tICcuLi9tb2RlbHMvbXktZ3JvdXBzLXZpZXcubW9kZWwnO1xyXG5pbXBvcnQge1xyXG4gIFVwY29taW5nRXZlbnQsXHJcbiAgVXBjb21pbmdJdGVtS2luZCxcclxufSBmcm9tICcuLi9tb2RlbHMvdXBjb21pbmctZXZlbnQubW9kZWwnO1xyXG5pbXBvcnQge1xyXG4gIEV2ZW50TWVldGluZ0RldGFpbFBheWxvYWQsXHJcbiAgRXZlbnRNZWV0aW5nTGlzdFBheWxvYWQsXHJcbn0gZnJvbSAnLi4vbW9kZWxzL2V2ZW50LW1lZXRpbmctbGlzdC1wYXlsb2FkLm1vZGVsJztcclxuaW1wb3J0IHtcclxuICBFdmVudE1lZXRpbmdEZXRhaWxSZXNwb25zZSxcclxuICBFdmVudE1lZXRpbmdMaXN0UmVzcG9uc2UsXHJcbn0gZnJvbSAnLi4vbW9kZWxzL2V2ZW50LW1lZXRpbmctbGlzdC1pdGVtLm1vZGVsJztcclxuaW1wb3J0IHtcclxuICBtYXBFdmVudE1lZXRpbmdEZXRhaWxzLFxyXG4gIG1hcEV2ZW50TWVldGluZ0xpc3QsXHJcbn0gZnJvbSAnLi4vdXRpbHMvZXZlbnQtbWVldGluZy1tYXBwZXIudXRpbCc7XHJcbmltcG9ydCB7IE1lZXRpbmdSb3cgfSBmcm9tICcuLi9tb2RlbHMvbWVldGluZy1yb3cubW9kZWwnO1xyXG5cclxuLyoqIEZhbGxiYWNrIGxhYmVsIGZvciBhbiBlbXB0eSBncm91cCB0eXBlIC8gbWVtYmVyIGxldmVsLCBtYXRjaGluZyB0aGUgTXkgR3JvdXBzIHRhYi4gKi9cclxuY29uc3QgVU5BU1NJR05FRF9MQUJFTCA9ICdVbmFzc2lnbmVkJztcclxuLyoqIFBsYWNlaG9sZGVyIGZvciBhbiBlbXB0eSBjZWxsIHZhbHVlLiAqL1xyXG5jb25zdCBFTVBUWV9WQUxVRSA9ICctJztcclxuLyoqIFN0YXR1c2VzIGluY2x1ZGVkIGluIHRoZSB1cGNvbWluZyBzZWN0aW9uLCBtYXRjaGluZyB0aGUgdmlldy1ldmVudHMtbWVldGluZ3MtbGlzdCBzY3JlZW4uICovXHJcbmNvbnN0IFVQQ09NSU5HX1NUQVRVU0VTID0gWydJbiBQcm9ncmVzcycsICdVcGNvbWluZyddO1xyXG4vKiogU29ydCBjb2x1bW4gdXNlZCBmb3IgdGhlIHRvcC1sZXZlbCBldmVudHMgJiBtZWV0aW5ncyBsaXN0LiAqL1xyXG5jb25zdCBVUENPTUlOR19TT1JUX0NPTFVNTiA9ICdzdGFydERhdGVUaW1lJztcclxuLyoqIFNvcnQgY29sdW1uIHVzZWQgZm9yIGFuIGV2ZW50J3MgZXhwYW5kZWQgY2hpbGQtbWVldGluZyBsaXN0IChtZWV0aW5nc0RldGFpbHMpLiAqL1xyXG5jb25zdCBFVkVOVF9NRUVUSU5HU19TT1JUX0NPTFVNTiA9ICdtZWV0aW5nU3REYXRlJztcclxuLyoqIERlZmF1bHQgcGFnZSBzaXplIGZvciB0aGUgdG9wLWxldmVsIHVwY29taW5nIHNlY3Rpb24gbGlzdC4gKi9cclxuY29uc3QgVVBDT01JTkdfUEFHRV9TSVpFID0gMTA7XHJcbi8qKiBEZWZhdWx0IHBhZ2Ugc2l6ZSBmb3IgYW4gZXZlbnQncyBleHBhbmRlZCBjaGlsZC1tZWV0aW5nIGxpc3QuICovXHJcbmNvbnN0IEVWRU5UX01FRVRJTkdTX1BBR0VfU0laRSA9IDU7XHJcbi8qKiBMYXJnZSBwYWdlIHNpemUgdXNlZCBieSB0aGUgZWFnZXIgY291bnQgcHJlZmV0Y2ggdG8gY2FwdHVyZSB0aGUgZnVsbCBzZXQuICovXHJcbmNvbnN0IEVWRU5UX0NPVU5UX1BBR0VfU0laRSA9IDIwMDtcclxuaW1wb3J0IHtcclxuICBhcHBseUxlYXZlTWVldGluZ1N1Y2Nlc3MsXHJcbiAgYXBwbHlMb2dBdHRlbmRhbmNlU3VjY2VzcyxcclxuICBiZWdpbkF0dGVuZGFuY2VBY3Rpb24sXHJcbiAgZW5kQXR0ZW5kYW5jZUFjdGlvbixcclxufSBmcm9tICcuL2F0dGVuZGFuY2UtcmVkdWNlcnMnO1xyXG5cclxuLyoqXHJcbiAqIERhc2hib2FyZFNlcnZpY2UgaXMgdGhlIHNpbmdsZSBzb3VyY2Ugb2YgdHJ1dGggZm9yIHRoZSBkYXNoYm9hcmQgbGFuZGluZ1xyXG4gKiBwYWdlJ3MgZGF0YSBhbmQgYXR0ZW5kYW5jZSBzdGF0ZS4gSXQgbWlycm9ycyB0aGUgYGV2ZW50cy1hbmQtbWVldGluZ3NgXHJcbiAqIHNlcnZpY2UgY29udmVudGlvbnM6IGl0IGlzIGEgYHByb3ZpZGVkSW46ICdyb290J2Agc2luZ2xldG9uLCBob2xkcyB0aGUgaG9zdFxyXG4gKiBgYXBpQmFzZVVybGAgLyBgdXNlclBlcm1pc3Npb25zYCBzZXQgdmlhIHtAbGluayBzZXRBcHBDb25maWd9LCBvd25zIGl0cyBzdGF0ZVxyXG4gKiB2aWEgYEJlaGF2aW9yU3ViamVjdGBzIGV4cG9zZWQgYXMgb2JzZXJ2YWJsZXMsIGFuZCByZWFjaGVzIHRoZSBiYWNrZW5kIG9ubHlcclxuICogdGhyb3VnaCB0aGUgc2hhcmVkIGBIdHRwU2VydmljZWAgZnJvbSBgQGllZWVzYS1ucG0vdXRpbGl0eWAgKG5ldmVyXHJcbiAqIGBIdHRwQ2xpZW50YCBkaXJlY3RseSkuXHJcbiAqXHJcbiAqIFRoZSB1cGNvbWluZy1ldmVudHMgbG9hZCBjYWxscyB0aGUgcmVhbCBgUE9TVCAvbWVldGluZ3MvZXZlbnRzQW5kTWVldGluZ3NgXHJcbiAqIGVuZHBvaW50IChjaGlsZCBtZWV0aW5ncyBhcmUgbGF6aWx5IGxvYWRlZCBwZXItZXZlbnQgdmlhXHJcbiAqIGBQT1NUIC9tZWV0aW5ncy9tZWV0aW5nc0RldGFpbHNgKTsgdGhlIGdyb3VwcyBsb2FkIGNhbGxzIGBHRVRcclxuICogL2dyb3Vwcy9teS1ncm91cHNgLiBUaGUgYXR0ZW5kYW5jZSBhY3Rpb25zIGNvbXBvc2UgdGhlIHB1cmUgcmVkdWNlcnMgZnJvbVxyXG4gKiBgYXR0ZW5kYW5jZS1yZWR1Y2Vycy50c2Agc28gdGhlIGRpc3BsYXllZCBgQXR0ZW5kYW5jZVN0YXRlYCBvbmx5IGFkdmFuY2VzIG9uIGFcclxuICogc3VjY2Vzc2Z1bCByZXNvbHV0aW9uIGFuZCB0aGUgcHJpb3Igc3RhdGUgaXMgcmV0YWluZWQgb24gZmFpbHVyZS5cclxuICogQGV4cG9ydFxyXG4gKiBAY2xhc3MgRGFzaGJvYXJkU2VydmljZVxyXG4gKi9cclxuQEluamVjdGFibGUoe1xyXG4gIHByb3ZpZGVkSW46ICdyb290JyxcclxufSlcclxuZXhwb3J0IGNsYXNzIERhc2hib2FyZFNlcnZpY2Uge1xyXG4gIGFwaUJhc2VVcmwhOiBzdHJpbmc7XHJcbiAgdXNlclBlcm1pc3Npb25zITogVXNlclBlcm1pc3Npb25bXTtcclxuXHJcbiAgcHJpdmF0ZSByZWFkb25seSB1cGNvbWluZ0V2ZW50cyA9IG5ldyBCZWhhdmlvclN1YmplY3Q8VXBjb21pbmdFdmVudFtdPihbXSk7XHJcbiAgcHJpdmF0ZSByZWFkb25seSBncm91cHMgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PEdyb3VwUm93W10+KFtdKTtcclxuICBwcml2YXRlIHJlYWRvbmx5IHVwY29taW5nU3RhdGUgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PERhc2hib2FyZFNlY3Rpb25TdGF0ZT4oXHJcbiAgICBEYXNoYm9hcmRTZWN0aW9uU3RhdGUuTE9BRElOR1xyXG4gICk7XHJcbiAgcHJpdmF0ZSByZWFkb25seSBncm91cHNTdGF0ZSA9IG5ldyBCZWhhdmlvclN1YmplY3Q8RGFzaGJvYXJkU2VjdGlvblN0YXRlPihcclxuICAgIERhc2hib2FyZFNlY3Rpb25TdGF0ZS5MT0FESU5HXHJcbiAgKTtcclxuICBwcml2YXRlIHJlYWRvbmx5IGF0dGVuZGFuY2VTdGF0ZXMgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFxyXG4gICAgUmVjb3JkPHN0cmluZywgQXR0ZW5kYW5jZVN0YXRlPlxyXG4gID4oe30pO1xyXG4gIHByaXZhdGUgcmVhZG9ubHkgaW5GbGlnaHRNZWV0aW5nSWRzID0gbmV3IEJlaGF2aW9yU3ViamVjdDxcclxuICAgIFJlYWRvbmx5U2V0PHN0cmluZz5cclxuICA+KG5ldyBTZXQ8c3RyaW5nPigpKTtcclxuXHJcbiAgLyoqIEVtaXRzIHRoZSBsaXN0IG9mIHRoZSB1c2VyJ3MgdXBjb21pbmcgZXZlbnRzLiAqL1xyXG4gIHVwY29taW5nRXZlbnRzJDogT2JzZXJ2YWJsZTxVcGNvbWluZ0V2ZW50W10+ID1cclxuICAgIHRoaXMudXBjb21pbmdFdmVudHMuYXNPYnNlcnZhYmxlKCk7XHJcbiAgLyoqIEVtaXRzIHRoZSBsaXN0IG9mIHRoZSB1c2VyJ3MgZ3JvdXBzLiAqL1xyXG4gIGdyb3VwcyQ6IE9ic2VydmFibGU8R3JvdXBSb3dbXT4gPSB0aGlzLmdyb3Vwcy5hc09ic2VydmFibGUoKTtcclxuICAvKiogRW1pdHMgdGhlIGxvYWQvZW1wdHkvZXJyb3Igc3RhdGUgb2YgdGhlIHVwY29taW5nLWV2ZW50cyBzZWN0aW9uLiAqL1xyXG4gIHVwY29taW5nU3RhdGUkOiBPYnNlcnZhYmxlPERhc2hib2FyZFNlY3Rpb25TdGF0ZT4gPVxyXG4gICAgdGhpcy51cGNvbWluZ1N0YXRlLmFzT2JzZXJ2YWJsZSgpO1xyXG4gIC8qKiBFbWl0cyB0aGUgbG9hZC9lbXB0eS9lcnJvciBzdGF0ZSBvZiB0aGUgZ3JvdXBzIHNlY3Rpb24uICovXHJcbiAgZ3JvdXBzU3RhdGUkOiBPYnNlcnZhYmxlPERhc2hib2FyZFNlY3Rpb25TdGF0ZT4gPVxyXG4gICAgdGhpcy5ncm91cHNTdGF0ZS5hc09ic2VydmFibGUoKTtcclxuICAvKiogRW1pdHMgdGhlIHBlci1tZWV0aW5nIGF0dGVuZGFuY2Utc3RhdGUgbWFwLiAqL1xyXG4gIGF0dGVuZGFuY2VTdGF0ZXMkOiBPYnNlcnZhYmxlPFJlY29yZDxzdHJpbmcsIEF0dGVuZGFuY2VTdGF0ZT4+ID1cclxuICAgIHRoaXMuYXR0ZW5kYW5jZVN0YXRlcy5hc09ic2VydmFibGUoKTtcclxuICAvKiogRW1pdHMgdGhlIHNldCBvZiBtZWV0aW5nIGlkcyB3aXRoIGFuIGF0dGVuZGFuY2UgYWN0aW9uIGluIGZsaWdodC4gKi9cclxuICBpbkZsaWdodE1lZXRpbmdJZHMkOiBPYnNlcnZhYmxlPFJlYWRvbmx5U2V0PHN0cmluZz4+ID1cclxuICAgIHRoaXMuaW5GbGlnaHRNZWV0aW5nSWRzLmFzT2JzZXJ2YWJsZSgpO1xyXG5cclxuICBjb25zdHJ1Y3RvcihcclxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtdmFyc1xyXG4gICAgcHJpdmF0ZSBodHRwU2VydmljZTogSHR0cFNlcnZpY2UgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWVtcHR5LWZ1bmN0aW9uXHJcbiAgKSB7fVxyXG5cclxuICAvKipcclxuICAgKiBTdG9yZXMgdGhlIGhvc3Qtc3VwcGxpZWQgQVBJIGJhc2UgVVJMIGFuZCB1c2VyIHBlcm1pc3Npb25zIHVzZWQgdG8gYnVpbGRcclxuICAgKiByZXF1ZXN0IFVSTHMgYW5kIGdhdGUgcGVybWlzc2lvbi1jb250cm9sbGVkIGFjdGlvbnMuIE1pcnJvcnMgdGhlXHJcbiAgICogYGV2ZW50cy1hbmQtbWVldGluZ3NgIHNlcnZpY2UgYHNldEFwcENvbmZpZ2AuXHJcbiAgICogQHBhcmFtIHtzdHJpbmd9IGFwaUJhc2VVUkwgLSBUaGUgaG9zdCBhcHBsaWNhdGlvbidzIEFQSSBiYXNlIFVSTC5cclxuICAgKiBAcGFyYW0ge1VzZXJQZXJtaXNzaW9uW119IHVzZXJQZXJtaXNzaW9ucyAtIFRoZSBzaWduZWQtaW4gdXNlcidzIHBlcm1pc3Npb25zLlxyXG4gICAqIEByZXR1cm4ge3ZvaWR9XHJcbiAgICogQG1lbWJlcm9mIERhc2hib2FyZFNlcnZpY2VcclxuICAgKi9cclxuICBzZXRBcHBDb25maWcoYXBpQmFzZVVSTDogc3RyaW5nLCB1c2VyUGVybWlzc2lvbnM6IFVzZXJQZXJtaXNzaW9uW10pOiB2b2lkIHtcclxuICAgIHRoaXMuYXBpQmFzZVVybCA9IGFwaUJhc2VVUkw7XHJcbiAgICB0aGlzLnVzZXJQZXJtaXNzaW9ucyA9IHVzZXJQZXJtaXNzaW9ucztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIExvYWRzIHRoZSB1c2VyJ3MgdXBjb21pbmcgZXZlbnRzICYgbWVldGluZ3MgZnJvbSB0aGUgcmVhbCBiYWNrZW5kIHZpYVxyXG4gICAqIGBQT1NUIHthcGlCYXNlVXJsfS9tZWV0aW5ncy9ldmVudHNBbmRNZWV0aW5nc2AsIHRoZSBzYW1lIGVuZHBvaW50IHRoZVxyXG4gICAqIGB2aWV3LWV2ZW50cy1tZWV0aW5ncy1saXN0YCBzY3JlZW4gdXNlcy4gVGhlIHJlc3BvbnNlIGlzIG1hcHBlZCBpbnRvIHRoZVxyXG4gICAqIGRhc2hib2FyZCB2aWV3IG1vZGVscyAod2l0aCBTVEFOREFMT05FX01FRVRJTkcgcm93cyBvcmRlcmVkIGxhc3QpLCB0aGVcclxuICAgKiBwZXItbWVldGluZyBhdHRlbmRhbmNlLXN0YXRlIG1hcCBpcyBzZWVkZWQsIGFuZCB0aGUgc2VjdGlvbiBhZHZhbmNlcyB0aHJvdWdoXHJcbiAgICogTE9BRElORyDihpIgTE9BREVEL0VNUFRZIG9uIHN1Y2Nlc3MsIGxlYXZpbmcgdGhlIGNhbGxlciB0byBzZXQgRVJST1Igb25cclxuICAgKiBmYWlsdXJlLiBGb2xsb3dzIHRoZSBzaGFyZWQgYHBpcGUobWFwLCBjYXRjaEVycm9yKHRocm93KSlgIHBhdHRlcm4uXHJcbiAgICogQHJldHVybiB7T2JzZXJ2YWJsZTxFdmVudE1lZXRpbmdMaXN0UmVzcG9uc2U+fSBUaGUgdXBjb21pbmcgZXZlbnRzICYgbWVldGluZ3MgcmVzcG9uc2UgZW52ZWxvcGUuXHJcbiAgICogQG1lbWJlcm9mIERhc2hib2FyZFNlcnZpY2VcclxuICAgKi9cclxuICBsb2FkVXBjb21pbmdFdmVudHMoKTogT2JzZXJ2YWJsZTxFdmVudE1lZXRpbmdMaXN0UmVzcG9uc2U+IHtcclxuICAgIHRoaXMudXBjb21pbmdTdGF0ZS5uZXh0KERhc2hib2FyZFNlY3Rpb25TdGF0ZS5MT0FESU5HKTtcclxuICAgIGNvbnN0IHBheWxvYWQ6IEV2ZW50TWVldGluZ0xpc3RQYXlsb2FkID0ge1xyXG4gICAgICBwYXlsb2FkOiB7XHJcbiAgICAgICAgZXZlbnRJZDogbnVsbCxcclxuICAgICAgICBzb3J0Q29sdW1uOiBVUENPTUlOR19TT1JUX0NPTFVNTixcclxuICAgICAgICBhc2NlbmRpbmdPcmRlcjogdHJ1ZSxcclxuICAgICAgICBwYWdlOiAxLFxyXG4gICAgICAgIHNpemU6IFVQQ09NSU5HX1BBR0VfU0laRSxcclxuICAgICAgICBmaWx0ZXI6IHtcclxuICAgICAgICAgIHN0YXR1czogVVBDT01JTkdfU1RBVFVTRVMsXHJcbiAgICAgICAgICBpc0FsbE1lZXRpbmdTZWxlY3RlZDogZmFsc2UsXHJcbiAgICAgICAgfSxcclxuICAgICAgfSxcclxuICAgIH07XHJcbiAgICByZXR1cm4gdGhpcy5odHRwU2VydmljZVxyXG4gICAgICAucG9zdERhdGEoYCR7dGhpcy5hcGlCYXNlVXJsfS9tZWV0aW5ncy9ldmVudHNBbmRNZWV0aW5nc2AsIHBheWxvYWQpXHJcbiAgICAgIC5waXBlKFxyXG4gICAgICAgIG1hcCgocmVzcG9uc2U6IEV2ZW50TWVldGluZ0xpc3RSZXNwb25zZSkgPT4ge1xyXG4gICAgICAgICAgY29uc3QgZXZlbnRzID0gbWFwRXZlbnRNZWV0aW5nTGlzdChcclxuICAgICAgICAgICAgcmVzcG9uc2U/LmJvZHk/LmV2ZW50TWVldGluZ0xpc3QgPz8gW11cclxuICAgICAgICAgICk7XHJcbiAgICAgICAgICB0aGlzLnVwY29taW5nRXZlbnRzLm5leHQoZXZlbnRzKTtcclxuICAgICAgICAgIHRoaXMuc2VlZEF0dGVuZGFuY2VTdGF0ZXMoZXZlbnRzKTtcclxuICAgICAgICAgIHRoaXMudXBjb21pbmdTdGF0ZS5uZXh0KFxyXG4gICAgICAgICAgICBldmVudHMubGVuZ3RoID4gMFxyXG4gICAgICAgICAgICAgID8gRGFzaGJvYXJkU2VjdGlvblN0YXRlLkxPQURFRFxyXG4gICAgICAgICAgICAgIDogRGFzaGJvYXJkU2VjdGlvblN0YXRlLkVNUFRZXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgLy8gRWFnZXJseSBmZXRjaCBlYWNoIEVWRU5UJ3MgbWVldGluZyBjb3VudCBzbyB0aGUgXCJ7bn0gbWVldGluZ3NcIiBhbmRcclxuICAgICAgICAgIC8vIFwie259IG9wZW4gZm9yIGF0dGVuZGFuY2VcIiBzdW1tYXJpZXMgYXJlIGNvcnJlY3QgYmVmb3JlIGV4cGFuZGluZy5cclxuICAgICAgICAgIHRoaXMubG9hZEV2ZW50Q291bnRzKGV2ZW50cyk7XHJcbiAgICAgICAgICByZXR1cm4gcmVzcG9uc2U7XHJcbiAgICAgICAgfSksXHJcbiAgICAgICAgY2F0Y2hFcnJvcigoZXJyb3IpID0+IHtcclxuICAgICAgICAgIHRoaXMudXBjb21pbmdTdGF0ZS5uZXh0KERhc2hib2FyZFNlY3Rpb25TdGF0ZS5FUlJPUik7XHJcbiAgICAgICAgICB0aHJvdyBlcnJvcjtcclxuICAgICAgICB9KVxyXG4gICAgICApO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTGF6aWx5IGxvYWRzIChhbmQgcGFnaW5hdGVzKSB0aGUgY2hpbGQgbWVldGluZ3Mgb2YgYW4gRVZFTlQgcm93IHZpYVxyXG4gICAqIGBQT1NUIHthcGlCYXNlVXJsfS9tZWV0aW5ncy9tZWV0aW5nc0RldGFpbHNgIOKAlCB0aGUgcGVyLWV2ZW50IGV4cGFuZCBlbmRwb2ludFxyXG4gICAqIHVzZWQgYnkgdGhlIHJlZmVyZW5jZSBzY3JlZW4uIE9uIHN1Y2Nlc3MgdGhlIGxvYWRlZCBtZWV0aW5ncyBhcmUgbWFwcGVkIGFuZFxyXG4gICAqIG1lcmdlZCBvbnRvIHRoZSBtYXRjaGluZyBldmVudCBpbiB0aGUgYHVwY29taW5nRXZlbnRzYCBsaXN0ICh3aXRoIGl0c1xyXG4gICAqIGBtZWV0aW5nQ291bnRgIC8gYG9wZW5Gb3JBdHRlbmRhbmNlQ291bnRgIHJlZnJlc2hlZCksIGFuZCB0aGUgcGVyLW1lZXRpbmdcclxuICAgKiBhdHRlbmRhbmNlLXN0YXRlIG1hcCBpcyBleHRlbmRlZC4gRWFjaCBldmVudCBwYWdpbmF0ZXMgaW5kZXBlbmRlbnRseS5cclxuICAgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRJZCAtIFRoZSBldmVudCB3aG9zZSBtZWV0aW5ncyB0byBsb2FkLlxyXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbcGFnZT0xXSAtIFRoZSBvbmUtYmFzZWQgcGFnZSB0byByZXF1ZXN0LlxyXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbc2l6ZT1FVkVOVF9NRUVUSU5HU19QQUdFX1NJWkVdIC0gVGhlIHBhZ2Ugc2l6ZS5cclxuICAgKiBAcmV0dXJuIHtPYnNlcnZhYmxlPEV2ZW50TWVldGluZ0RldGFpbFJlc3BvbnNlPn0gVGhlIGNoaWxkLW1lZXRpbmdzIHJlc3BvbnNlIGVudmVsb3BlLlxyXG4gICAqIEBtZW1iZXJvZiBEYXNoYm9hcmRTZXJ2aWNlXHJcbiAgICovXHJcbiAgbG9hZEV2ZW50TWVldGluZ3MoXHJcbiAgICBldmVudElkOiBzdHJpbmcsXHJcbiAgICBwYWdlID0gMSxcclxuICAgIHNpemUgPSBFVkVOVF9NRUVUSU5HU19QQUdFX1NJWkVcclxuICApOiBPYnNlcnZhYmxlPEV2ZW50TWVldGluZ0RldGFpbFJlc3BvbnNlPiB7XHJcbiAgICByZXR1cm4gdGhpcy5mZXRjaEV2ZW50TWVldGluZ3NQYWdlKGV2ZW50SWQsIHBhZ2UsIHNpemUpLnBpcGUoXHJcbiAgICAgIG1hcCgocmVzcG9uc2U6IEV2ZW50TWVldGluZ0RldGFpbFJlc3BvbnNlKSA9PiB7XHJcbiAgICAgICAgY29uc3QgbWVldGluZ3MgPSBtYXBFdmVudE1lZXRpbmdEZXRhaWxzKFxyXG4gICAgICAgICAgcmVzcG9uc2U/LmJvZHk/Lm1lZXRpbmdzID8/IFtdXHJcbiAgICAgICAgKTtcclxuICAgICAgICBjb25zdCB0b3RhbCA9IHJlc3BvbnNlPy5ib2R5Py50b3RhbFJlY29yZHMgPz8gbWVldGluZ3MubGVuZ3RoO1xyXG4gICAgICAgIC8vIFByZWZlciB0aGUgYWxyZWFkeS1rbm93biBmdWxsIG9wZW4gY291bnQgb24gdGhlIGV2ZW50OyBmYWxsIGJhY2sgdG9cclxuICAgICAgICAvLyB0aGUgY3VycmVudCBwYWdlJ3Mgb3BlbiBjb3VudCB3aGVuIGl0IGhhc24ndCBiZWVuIHByZWZldGNoZWQuXHJcbiAgICAgICAgY29uc3QgZXhpc3RpbmcgPSB0aGlzLnVwY29taW5nRXZlbnRzLnZhbHVlLmZpbmQoXHJcbiAgICAgICAgICAoZXZlbnQpID0+IGV2ZW50LmV2ZW50SWQgPT09IGV2ZW50SWRcclxuICAgICAgICApO1xyXG4gICAgICAgIGNvbnN0IHBhZ2VPcGVuQ291bnQgPSBtZWV0aW5ncy5maWx0ZXIoXHJcbiAgICAgICAgICAobWVldGluZykgPT4gbWVldGluZy5pc09wZW5Gb3JBdHRlbmRhbmNlXHJcbiAgICAgICAgKS5sZW5ndGg7XHJcbiAgICAgICAgY29uc3Qgb3BlbkZvckF0dGVuZGFuY2VDb3VudCA9XHJcbiAgICAgICAgICBleGlzdGluZz8ub3BlbkZvckF0dGVuZGFuY2VDb3VudCB8fCBwYWdlT3BlbkNvdW50O1xyXG4gICAgICAgIHRoaXMubWVyZ2VFdmVudE1lZXRpbmdzKGV2ZW50SWQsIG1lZXRpbmdzLCB0b3RhbCwgb3BlbkZvckF0dGVuZGFuY2VDb3VudCk7XHJcbiAgICAgICAgdGhpcy5zZWVkQXR0ZW5kYW5jZVN0YXRlc0Zyb21NZWV0aW5ncyhtZWV0aW5ncyk7XHJcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICB9KSxcclxuICAgICAgY2F0Y2hFcnJvcigoZXJyb3IpID0+IHtcclxuICAgICAgICB0aHJvdyBlcnJvcjtcclxuICAgICAgfSlcclxuICAgICk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBNZXJnZXMgYSBmcmVzaGx5IGxvYWRlZCBwYWdlIG9mIGNoaWxkIG1lZXRpbmdzIG9udG8gdGhlIG1hdGNoaW5nIGV2ZW50IGluXHJcbiAgICogdGhlIGB1cGNvbWluZ0V2ZW50c2AgbGlzdCwgcmVmcmVzaGluZyB0aGUgZXZlbnQncyBgbWVldGluZ3NgLFxyXG4gICAqIGBtZWV0aW5nQ291bnRgIChmcm9tIHRoZSBiYWNrZW5kIGB0b3RhbFJlY29yZHNgKSwgYW5kXHJcbiAgICogYG9wZW5Gb3JBdHRlbmRhbmNlQ291bnRgLiBMZWF2ZXMgYWxsIG90aGVyIGV2ZW50cyB1bnRvdWNoZWQuXHJcbiAgICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50SWQgLSBUaGUgZXZlbnQgdG8gbWVyZ2UgbWVldGluZ3Mgb250by5cclxuICAgKiBAcGFyYW0ge01lZXRpbmdSb3dbXX0gbWVldGluZ3MgLSBUaGUgbWFwcGVkIGNoaWxkIG1lZXRpbmdzIGZvciB0aGUgcGFnZS5cclxuICAgKiBAcGFyYW0ge251bWJlcn0gdG90YWxSZWNvcmRzIC0gVGhlIGV2ZW50J3MgdG90YWwgbWVldGluZyBjb3VudCBmcm9tIHRoZSBiYWNrZW5kLlxyXG4gICAqIEByZXR1cm4ge3ZvaWR9XHJcbiAgICogQG1lbWJlcm9mIERhc2hib2FyZFNlcnZpY2VcclxuICAgKi9cclxuICBwcml2YXRlIG1lcmdlRXZlbnRNZWV0aW5ncyhcclxuICAgIGV2ZW50SWQ6IHN0cmluZyxcclxuICAgIG1lZXRpbmdzOiBNZWV0aW5nUm93W10sXHJcbiAgICB0b3RhbFJlY29yZHM6IG51bWJlcixcclxuICAgIG9wZW5Gb3JBdHRlbmRhbmNlQ291bnQ6IG51bWJlclxyXG4gICk6IHZvaWQge1xyXG4gICAgY29uc3QgbmV4dCA9IHRoaXMudXBjb21pbmdFdmVudHMudmFsdWUubWFwKChldmVudCkgPT4ge1xyXG4gICAgICBpZiAoZXZlbnQuZXZlbnRJZCAhPT0gZXZlbnRJZCkge1xyXG4gICAgICAgIHJldHVybiBldmVudDtcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIC4uLmV2ZW50LFxyXG4gICAgICAgIG1lZXRpbmdzLFxyXG4gICAgICAgIG1lZXRpbmdDb3VudDogdG90YWxSZWNvcmRzLFxyXG4gICAgICAgIG9wZW5Gb3JBdHRlbmRhbmNlQ291bnQsXHJcbiAgICAgIH07XHJcbiAgICB9KTtcclxuICAgIHRoaXMudXBjb21pbmdFdmVudHMubmV4dChuZXh0KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEVhZ2VybHkgZmV0Y2hlcyBlYWNoIEVWRU5UJ3MgdG90YWwgbWVldGluZyBjb3VudCBhbmQgb3Blbi1mb3ItYXR0ZW5kYW5jZVxyXG4gICAqIGNvdW50IGJ5IHJlcXVlc3RpbmcgYSBsYXJnZSBmaXJzdCBwYWdlIG9mIGl0cyBjaGlsZCBtZWV0aW5ncywgdGhlbiBtZXJnaW5nXHJcbiAgICogb25seSB0aGUgY291bnRzIChub3QgdGhlIHJvd3MpIHNvIHRoZSBjb2xsYXBzZWQgY2FyZCBzdW1tYXJpZXMgYXJlIGFjY3VyYXRlXHJcbiAgICogYmVmb3JlIHRoZSB1c2VyIGV4cGFuZHMuIFN0YW5kYWxvbmUgbWVldGluZ3MgYXJlIHNraXBwZWQuIEZhaWx1cmVzIHBlciBldmVudFxyXG4gICAqIGFyZSBzd2FsbG93ZWQgc28gb25lIGZhaWxpbmcgY291bnQgbmV2ZXIgYnJlYWtzIHRoZSBsaXN0LlxyXG4gICAqIEBwYXJhbSB7VXBjb21pbmdFdmVudFtdfSBldmVudHMgLSBUaGUgbG9hZGVkIGV2ZW50cyB0byBmZXRjaCBjb3VudHMgZm9yLlxyXG4gICAqIEByZXR1cm4ge3ZvaWR9XHJcbiAgICogQG1lbWJlcm9mIERhc2hib2FyZFNlcnZpY2VcclxuICAgKi9cclxuICBwcml2YXRlIGxvYWRFdmVudENvdW50cyhldmVudHM6IFVwY29taW5nRXZlbnRbXSk6IHZvaWQge1xyXG4gICAgZXZlbnRzXHJcbiAgICAgIC5maWx0ZXIoKGV2ZW50KSA9PiBldmVudC5raW5kID09PSBVcGNvbWluZ0l0ZW1LaW5kLkVWRU5UICYmIGV2ZW50LmV2ZW50SWQpXHJcbiAgICAgIC5mb3JFYWNoKChldmVudCkgPT4ge1xyXG4gICAgICAgIHRoaXMuZmV0Y2hFdmVudE1lZXRpbmdzUGFnZShldmVudC5ldmVudElkLCAxLCBFVkVOVF9DT1VOVF9QQUdFX1NJWkUpXHJcbiAgICAgICAgICAucGlwZShcclxuICAgICAgICAgICAgY2F0Y2hFcnJvcigoKSA9PiBvZihudWxsKSlcclxuICAgICAgICAgIClcclxuICAgICAgICAgIC5zdWJzY3JpYmUoKHJlc3BvbnNlKSA9PiB7XHJcbiAgICAgICAgICAgIGlmICghcmVzcG9uc2UpIHtcclxuICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY29uc3QgbWVldGluZ3MgPSBtYXBFdmVudE1lZXRpbmdEZXRhaWxzKFxyXG4gICAgICAgICAgICAgIHJlc3BvbnNlPy5ib2R5Py5tZWV0aW5ncyA/PyBbXVxyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgICAgICBjb25zdCB0b3RhbCA9IHJlc3BvbnNlPy5ib2R5Py50b3RhbFJlY29yZHMgPz8gbWVldGluZ3MubGVuZ3RoO1xyXG4gICAgICAgICAgICBjb25zdCBvcGVuQ291bnQgPSBtZWV0aW5ncy5maWx0ZXIoXHJcbiAgICAgICAgICAgICAgKG1lZXRpbmcpID0+IG1lZXRpbmcuaXNPcGVuRm9yQXR0ZW5kYW5jZVxyXG4gICAgICAgICAgICApLmxlbmd0aDtcclxuICAgICAgICAgICAgdGhpcy5tZXJnZUV2ZW50Q291bnRzKGV2ZW50LmV2ZW50SWQsIHRvdGFsLCBvcGVuQ291bnQpO1xyXG4gICAgICAgICAgICB0aGlzLnNlZWRBdHRlbmRhbmNlU3RhdGVzRnJvbU1lZXRpbmdzKG1lZXRpbmdzKTtcclxuICAgICAgICAgIH0pO1xyXG4gICAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIE1lcmdlcyBvbmx5IHRoZSBtZWV0aW5nIGNvdW50cyBvbnRvIHRoZSBtYXRjaGluZyBldmVudCwgbGVhdmluZyBpdHNcclxuICAgKiBgbWVldGluZ3NgIHJvd3MgdW50b3VjaGVkICh1c2VkIGJ5IHRoZSBlYWdlciBjb3VudCBwcmVmZXRjaCkuXHJcbiAgICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50SWQgLSBUaGUgZXZlbnQgdG8gdXBkYXRlLlxyXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB0b3RhbFJlY29yZHMgLSBUaGUgZXZlbnQncyB0b3RhbCBtZWV0aW5nIGNvdW50LlxyXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvcGVuRm9yQXR0ZW5kYW5jZUNvdW50IC0gVGhlIG9wZW4tZm9yLWF0dGVuZGFuY2UgY291bnQuXHJcbiAgICogQHJldHVybiB7dm9pZH1cclxuICAgKiBAbWVtYmVyb2YgRGFzaGJvYXJkU2VydmljZVxyXG4gICAqL1xyXG4gIHByaXZhdGUgbWVyZ2VFdmVudENvdW50cyhcclxuICAgIGV2ZW50SWQ6IHN0cmluZyxcclxuICAgIHRvdGFsUmVjb3JkczogbnVtYmVyLFxyXG4gICAgb3BlbkZvckF0dGVuZGFuY2VDb3VudDogbnVtYmVyXHJcbiAgKTogdm9pZCB7XHJcbiAgICBjb25zdCBuZXh0ID0gdGhpcy51cGNvbWluZ0V2ZW50cy52YWx1ZS5tYXAoKGV2ZW50KSA9PlxyXG4gICAgICBldmVudC5ldmVudElkID09PSBldmVudElkXHJcbiAgICAgICAgPyB7IC4uLmV2ZW50LCBtZWV0aW5nQ291bnQ6IHRvdGFsUmVjb3Jkcywgb3BlbkZvckF0dGVuZGFuY2VDb3VudCB9XHJcbiAgICAgICAgOiBldmVudFxyXG4gICAgKTtcclxuICAgIHRoaXMudXBjb21pbmdFdmVudHMubmV4dChuZXh0KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEJ1aWxkcyBhbmQgcG9zdHMgdGhlIGBtZWV0aW5nc0RldGFpbHNgIHJlcXVlc3QgZm9yIGEgc2luZ2xlIGV2ZW50IHBhZ2UsXHJcbiAgICogcmV0dXJuaW5nIHRoZSByYXcgcmVzcG9uc2UgZW52ZWxvcGUuIFNoYXJlZCBieSB7QGxpbmsgbG9hZEV2ZW50TWVldGluZ3N9IGFuZFxyXG4gICAqIHRoZSBlYWdlciBjb3VudCBwcmVmZXRjaC5cclxuICAgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRJZCAtIFRoZSBldmVudCB3aG9zZSBtZWV0aW5ncyB0byBmZXRjaC5cclxuICAgKiBAcGFyYW0ge251bWJlcn0gcGFnZSAtIFRoZSBvbmUtYmFzZWQgcGFnZSB0byByZXF1ZXN0LlxyXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBzaXplIC0gVGhlIHBhZ2Ugc2l6ZS5cclxuICAgKiBAcmV0dXJuIHtPYnNlcnZhYmxlPEV2ZW50TWVldGluZ0RldGFpbFJlc3BvbnNlPn0gVGhlIGNoaWxkLW1lZXRpbmdzIHJlc3BvbnNlLlxyXG4gICAqIEBtZW1iZXJvZiBEYXNoYm9hcmRTZXJ2aWNlXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBmZXRjaEV2ZW50TWVldGluZ3NQYWdlKFxyXG4gICAgZXZlbnRJZDogc3RyaW5nLFxyXG4gICAgcGFnZTogbnVtYmVyLFxyXG4gICAgc2l6ZTogbnVtYmVyXHJcbiAgKTogT2JzZXJ2YWJsZTxFdmVudE1lZXRpbmdEZXRhaWxSZXNwb25zZT4ge1xyXG4gICAgY29uc3QgcGF5bG9hZDogRXZlbnRNZWV0aW5nRGV0YWlsUGF5bG9hZCA9IHtcclxuICAgICAgcGF5bG9hZDoge1xyXG4gICAgICAgIGV2ZW50SWQsXHJcbiAgICAgICAgc29ydENvbHVtbjogRVZFTlRfTUVFVElOR1NfU09SVF9DT0xVTU4sXHJcbiAgICAgICAgYXNjZW5kaW5nT3JkZXI6IHRydWUsXHJcbiAgICAgICAgcGFnZSxcclxuICAgICAgICBzaXplLFxyXG4gICAgICAgIGZpbHRlcjoge1xyXG4gICAgICAgICAgc3RhdHVzOiBVUENPTUlOR19TVEFUVVNFUyxcclxuICAgICAgICAgIGlzQWxsTWVldGluZ1NlbGVjdGVkOiBmYWxzZSxcclxuICAgICAgICB9LFxyXG4gICAgICB9LFxyXG4gICAgfTtcclxuICAgIHJldHVybiB0aGlzLmh0dHBTZXJ2aWNlLnBvc3REYXRhKFxyXG4gICAgICBgJHt0aGlzLmFwaUJhc2VVcmx9L21lZXRpbmdzL21lZXRpbmdzRGV0YWlsc2AsXHJcbiAgICAgIHBheWxvYWRcclxuICAgICk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBMb2FkcyB0aGUgdXNlcidzIGdyb3VwcywgZHJpdmluZyB0aGUgZ3JvdXBzIHNlY3Rpb24gdGhyb3VnaFxyXG4gICAqIExPQURJTkcg4oaSIExPQURFRC9FTVBUWSBvbiBzdWNjZXNzIGFuZCBsZWF2aW5nIHRoZSBjYWxsZXIgdG8gc2V0IEVSUk9SIG9uXHJcbiAgICogZmFpbHVyZS4gRm9sbG93cyB0aGUgYHBpcGUobWFwLCBjYXRjaEVycm9yKHRocm93KSlgIHBhdHRlcm4uXHJcbiAgICpcclxuICAgKiBUT0RPOiBSZXBsYWNlIG1vY2sgd2l0aCByZWFsIEFQSSBjYWxsIHdoZW4gQkUgaXMgcmVhZHlcclxuICAgKiBAcmV0dXJuIHtPYnNlcnZhYmxlPERhc2hib2FyZExpc3RSZXNwb25zZTxHcm91cFJvd1tdPj59IFRoZSBncm91cHMgcmVzcG9uc2UgZW52ZWxvcGUuXHJcbiAgICogQG1lbWJlcm9mIERhc2hib2FyZFNlcnZpY2VcclxuICAgKi9cclxuICBsb2FkR3JvdXBzKCk6IE9ic2VydmFibGU8RGFzaGJvYXJkTGlzdFJlc3BvbnNlPE15R3JvdXBzVmlldz4+IHtcclxuICAgIHRoaXMuZ3JvdXBzU3RhdGUubmV4dChEYXNoYm9hcmRTZWN0aW9uU3RhdGUuTE9BRElORyk7XHJcbiAgICByZXR1cm4gdGhpcy5odHRwU2VydmljZVxyXG4gICAgICAuZ2V0RGF0YShgJHt0aGlzLmFwaUJhc2VVcmx9L2dyb3Vwcy9teS1ncm91cHNgKVxyXG4gICAgICAucGlwZShcclxuICAgICAgICBtYXAoKHJlc3BvbnNlOiBEYXNoYm9hcmRMaXN0UmVzcG9uc2U8TXlHcm91cHNWaWV3PikgPT4ge1xyXG4gICAgICAgICAgY29uc3QgZ3JvdXBzID0gKHJlc3BvbnNlPy5ib2R5Py5ncm91cHMgPz8gW10pLm1hcCgoZ3JvdXApID0+XHJcbiAgICAgICAgICAgIHRoaXMubWFwR3JvdXAoZ3JvdXApXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgdGhpcy5ncm91cHMubmV4dChncm91cHMpO1xyXG4gICAgICAgICAgdGhpcy5ncm91cHNTdGF0ZS5uZXh0KFxyXG4gICAgICAgICAgICBncm91cHMubGVuZ3RoID4gMFxyXG4gICAgICAgICAgICAgID8gRGFzaGJvYXJkU2VjdGlvblN0YXRlLkxPQURFRFxyXG4gICAgICAgICAgICAgIDogRGFzaGJvYXJkU2VjdGlvblN0YXRlLkVNUFRZXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICAgIH0pLFxyXG4gICAgICAgIGNhdGNoRXJyb3IoKGVycm9yKSA9PiB7XHJcbiAgICAgICAgICB0aGlzLmdyb3Vwc1N0YXRlLm5leHQoRGFzaGJvYXJkU2VjdGlvblN0YXRlLkVSUk9SKTtcclxuICAgICAgICAgIHRocm93IGVycm9yO1xyXG4gICAgICAgIH0pXHJcbiAgICAgICk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBNYXBzIGEgYmFja2VuZCB7QGxpbmsgTXlHcm91cFZpZXd9IHRvIHRoZSB0YWJsZS1mYWNpbmcge0BsaW5rIEdyb3VwUm93fS5cclxuICAgKiBNaXJyb3JzIHRoZSBNeSBHcm91cHMgcHJvZmlsZSB0YWI6IHRoZSB0eXBlIGZhbGxzIGJhY2sgdG8gXCJVbmFzc2lnbmVkXCIgd2hlblxyXG4gICAqIGBncm91cFR5cGVOYW1lYCBpcyBudWxsLCBhZmZpbGlhdGlvbnMgYXJlIGNvbW1hLWpvaW5lZCwgZW1wdHkgb2ZmaWNlciByb2xlIC9cclxuICAgKiBhZmZpbGlhdGlvbiByZW5kZXIgYXMgYSBwbGFjZWhvbGRlciwgYW5kIGEgYmxhbmsgbWVtYmVyIGxldmVsIGJlY29tZXNcclxuICAgKiBcIlVuYXNzaWduZWRcIiAocmVuZGVyZWQgYXMgdGhlIHdhcm5pbmcgcGlsbCBieSB0aGUgWW91ciBHcm91cHMgY29tcG9uZW50KS5cclxuICAgKiBAcGFyYW0ge015R3JvdXBWaWV3fSBncm91cCAtIFRoZSBiYWNrZW5kIGdyb3VwIHZpZXcuXHJcbiAgICogQHJldHVybiB7R3JvdXBSb3d9XHJcbiAgICogQG1lbWJlcm9mIERhc2hib2FyZFNlcnZpY2VcclxuICAgKi9cclxuICBwcml2YXRlIG1hcEdyb3VwKGdyb3VwOiBNeUdyb3VwVmlldyk6IEdyb3VwUm93IHtcclxuICAgIC8vIFRoZSBiYWNrZW5kIHJldHVybnMgb2ZmaWNlciByb2xlcyBhcyBhbiBgb2ZmaWNlcmAgYXJyYXkgb2ZcclxuICAgIC8vIHsgb2ZmaWNlcklkLCBvZmZpY2VyTmFtZSB9LiBKb2luIHRoZSBuYW1lcyBmb3IgdGhlIE9mZmljZXIgUm9sZSBjb2x1bW5cclxuICAgIC8vIChlLmcuIFwiQ2hhaXJcIiBvciBcIkNoYWlyLCBWaWNlIENoYWlyXCIpOyBzaG93IHRoZSBwbGFjZWhvbGRlciB3aGVuIGVtcHR5LlxyXG4gICAgY29uc3Qgb2ZmaWNlclJvbGUgPVxyXG4gICAgICAoZ3JvdXAub2ZmaWNlciA/PyBbXSlcclxuICAgICAgICAubWFwKChvZmZpY2VyKSA9PiBvZmZpY2VyPy5vZmZpY2VyTmFtZT8udHJpbSgpKVxyXG4gICAgICAgIC5maWx0ZXIoKG5hbWUpID0+ICEhbmFtZSlcclxuICAgICAgICAuam9pbignLCAnKSB8fCBFTVBUWV9WQUxVRTtcclxuXHJcbiAgICByZXR1cm4ge1xyXG4gICAgICBncm91cElkOiBncm91cC5ncm91cElkLFxyXG4gICAgICBncm91cDogZ3JvdXAuZ3JvdXBOYW1lLFxyXG4gICAgICB0eXBlOiBncm91cC5ncm91cFR5cGVOYW1lIHx8IGdyb3VwLmdyb3VwVHlwZSB8fCBVTkFTU0lHTkVEX0xBQkVMLFxyXG4gICAgICBvZmZpY2VyUm9sZSxcclxuICAgICAgYWZmaWxpYXRpb246IGdyb3VwLmFmZmlsaWF0aW9ucz8uam9pbignLCAnKSB8fCBFTVBUWV9WQUxVRSxcclxuICAgICAgbWVtYmVyTGV2ZWw6IGdyb3VwLm1lbWJlckxldmVsPy50cmltKCkgfHwgVU5BU1NJR05FRF9MQUJFTCxcclxuICAgICAgLy8gQ2FycnkgdGhlIGFuY2VzdG9yIGhpZXJhcmNoeSB0aHJvdWdoIGZvciB0aGUgZXhwYW5kYWJsZSBoaWVyYXJjaHkgcm93cy5cclxuICAgICAgaGllcmFyY2h5OiBncm91cC5oaWVyYXJjaHkgPz8gW10sXHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTG9ncyBhdHRlbmRhbmNlIGZvciBhIG1lZXRpbmcuIE1hcmtzIHRoZSBtZWV0aW5nIGluLWZsaWdodCAocmV0YWluaW5nIHRoZVxyXG4gICAqIHByaW9yIGRpc3BsYXllZCBzdGF0ZSksIHBvc3RzIHRocm91Z2ggYEh0dHBTZXJ2aWNlYCwgYXBwbGllcyB0aGVcclxuICAgKiBsb2ctYXR0ZW5kYW5jZS1zdWNjZXNzIHJlZHVjZXIgb24gc3VjY2VzcywgY2xlYXJzIHRoZSBpbi1mbGlnaHQgZmxhZyBvblxyXG4gICAqIGNvbXBsZXRpb24sIGFuZCByZXRocm93cyB3aGlsZSByZXRhaW5pbmcgcHJpb3Igc3RhdGUgb24gZmFpbHVyZS5cclxuICAgKiBAcGFyYW0ge3N0cmluZ30gbWVldGluZ0lkIC0gVGhlIG1lZXRpbmcgdG8gbG9nIGF0dGVuZGFuY2UgZm9yLlxyXG4gICAqIEByZXR1cm4ge09ic2VydmFibGU8RGFzaGJvYXJkTGlzdFJlc3BvbnNlPHVua25vd24+Pn0gVGhlIGF0dGVuZGFuY2UgcmVzcG9uc2UgZW52ZWxvcGUuXHJcbiAgICogQG1lbWJlcm9mIERhc2hib2FyZFNlcnZpY2VcclxuICAgKi9cclxuICBsb2dBdHRlbmRhbmNlKFxyXG4gICAgbWVldGluZ0lkOiBzdHJpbmdcclxuICApOiBPYnNlcnZhYmxlPERhc2hib2FyZExpc3RSZXNwb25zZTx1bmtub3duPj4ge1xyXG4gICAgdGhpcy5pbkZsaWdodE1lZXRpbmdJZHMubmV4dChcclxuICAgICAgYmVnaW5BdHRlbmRhbmNlQWN0aW9uKHRoaXMuaW5GbGlnaHRNZWV0aW5nSWRzLnZhbHVlLCBtZWV0aW5nSWQpXHJcbiAgICApO1xyXG4gICAgcmV0dXJuIHRoaXMuaHR0cFNlcnZpY2VcclxuICAgICAgLnBvc3REYXRhKGAke3RoaXMuYXBpQmFzZVVybH0vbWVldGluZ3MvYXR0ZW5kYW5jZS9sb2dgLCB7IG1lZXRpbmdJZCB9KVxyXG4gICAgICAucGlwZShcclxuICAgICAgICBtYXAoKHJlc3BvbnNlKSA9PiB7XHJcbiAgICAgICAgICB0aGlzLmF0dGVuZGFuY2VTdGF0ZXMubmV4dChcclxuICAgICAgICAgICAgYXBwbHlMb2dBdHRlbmRhbmNlU3VjY2Vzcyh0aGlzLmF0dGVuZGFuY2VTdGF0ZXMudmFsdWUsIG1lZXRpbmdJZClcclxuICAgICAgICAgICk7XHJcbiAgICAgICAgICB0aGlzLmluRmxpZ2h0TWVldGluZ0lkcy5uZXh0KFxyXG4gICAgICAgICAgICBlbmRBdHRlbmRhbmNlQWN0aW9uKHRoaXMuaW5GbGlnaHRNZWV0aW5nSWRzLnZhbHVlLCBtZWV0aW5nSWQpXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICAgIH0pLFxyXG4gICAgICAgIGNhdGNoRXJyb3IoKGVycm9yKSA9PiB7XHJcbiAgICAgICAgICAvLyBSZXRhaW4gcHJpb3IgYXR0ZW5kYW5jZSBzdGF0ZTsgb25seSBjbGVhciB0aGUgaW4tZmxpZ2h0IGZsYWcuXHJcbiAgICAgICAgICB0aGlzLmluRmxpZ2h0TWVldGluZ0lkcy5uZXh0KFxyXG4gICAgICAgICAgICBlbmRBdHRlbmRhbmNlQWN0aW9uKHRoaXMuaW5GbGlnaHRNZWV0aW5nSWRzLnZhbHVlLCBtZWV0aW5nSWQpXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgdGhyb3cgZXJyb3I7XHJcbiAgICAgICAgfSlcclxuICAgICAgKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIExlYXZlcyBhIG1lZXRpbmcuIE1hcmtzIHRoZSBtZWV0aW5nIGluLWZsaWdodCAocmV0YWluaW5nIHRoZSBwcmlvclxyXG4gICAqIGRpc3BsYXllZCBzdGF0ZSksIHBvc3RzIHRocm91Z2ggYEh0dHBTZXJ2aWNlYCwgYXBwbGllcyB0aGVcclxuICAgKiBsZWF2ZS1tZWV0aW5nLXN1Y2Nlc3MgcmVkdWNlciBvbiBzdWNjZXNzLCBjbGVhcnMgdGhlIGluLWZsaWdodCBmbGFnIG9uXHJcbiAgICogY29tcGxldGlvbiwgYW5kIHJldGhyb3dzIHdoaWxlIHJldGFpbmluZyBwcmlvciBzdGF0ZSBvbiBmYWlsdXJlLlxyXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtZWV0aW5nSWQgLSBUaGUgbWVldGluZyB0byBsZWF2ZS5cclxuICAgKiBAcmV0dXJuIHtPYnNlcnZhYmxlPERhc2hib2FyZExpc3RSZXNwb25zZTx1bmtub3duPj59IFRoZSBhdHRlbmRhbmNlIHJlc3BvbnNlIGVudmVsb3BlLlxyXG4gICAqIEBtZW1iZXJvZiBEYXNoYm9hcmRTZXJ2aWNlXHJcbiAgICovXHJcbiAgbGVhdmVNZWV0aW5nKFxyXG4gICAgbWVldGluZ0lkOiBzdHJpbmdcclxuICApOiBPYnNlcnZhYmxlPERhc2hib2FyZExpc3RSZXNwb25zZTx1bmtub3duPj4ge1xyXG4gICAgdGhpcy5pbkZsaWdodE1lZXRpbmdJZHMubmV4dChcclxuICAgICAgYmVnaW5BdHRlbmRhbmNlQWN0aW9uKHRoaXMuaW5GbGlnaHRNZWV0aW5nSWRzLnZhbHVlLCBtZWV0aW5nSWQpXHJcbiAgICApO1xyXG4gICAgcmV0dXJuIHRoaXMuaHR0cFNlcnZpY2VcclxuICAgICAgLnBvc3REYXRhKGAke3RoaXMuYXBpQmFzZVVybH0vbWVldGluZ3MvYXR0ZW5kYW5jZS9sZWF2ZWAsIHsgbWVldGluZ0lkIH0pXHJcbiAgICAgIC5waXBlKFxyXG4gICAgICAgIG1hcCgocmVzcG9uc2UpID0+IHtcclxuICAgICAgICAgIHRoaXMuYXR0ZW5kYW5jZVN0YXRlcy5uZXh0KFxyXG4gICAgICAgICAgICBhcHBseUxlYXZlTWVldGluZ1N1Y2Nlc3ModGhpcy5hdHRlbmRhbmNlU3RhdGVzLnZhbHVlLCBtZWV0aW5nSWQpXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgdGhpcy5pbkZsaWdodE1lZXRpbmdJZHMubmV4dChcclxuICAgICAgICAgICAgZW5kQXR0ZW5kYW5jZUFjdGlvbih0aGlzLmluRmxpZ2h0TWVldGluZ0lkcy52YWx1ZSwgbWVldGluZ0lkKVxyXG4gICAgICAgICAgKTtcclxuICAgICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgICB9KSxcclxuICAgICAgICBjYXRjaEVycm9yKChlcnJvcikgPT4ge1xyXG4gICAgICAgICAgLy8gUmV0YWluIHByaW9yIGF0dGVuZGFuY2Ugc3RhdGU7IG9ubHkgY2xlYXIgdGhlIGluLWZsaWdodCBmbGFnLlxyXG4gICAgICAgICAgdGhpcy5pbkZsaWdodE1lZXRpbmdJZHMubmV4dChcclxuICAgICAgICAgICAgZW5kQXR0ZW5kYW5jZUFjdGlvbih0aGlzLmluRmxpZ2h0TWVldGluZ0lkcy52YWx1ZSwgbWVldGluZ0lkKVxyXG4gICAgICAgICAgKTtcclxuICAgICAgICAgIHRocm93IGVycm9yO1xyXG4gICAgICAgIH0pXHJcbiAgICAgICk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZXR1cm5zIGEgc3luY2hyb25vdXMgc25hcHNob3Qgb2YgdGhlIHBlci1tZWV0aW5nIGF0dGVuZGFuY2Utc3RhdGUgbWFwLlxyXG4gICAqIEByZXR1cm4ge1JlY29yZDxzdHJpbmcsIEF0dGVuZGFuY2VTdGF0ZT59IFRoZSBjdXJyZW50IGF0dGVuZGFuY2Utc3RhdGUgbWFwLlxyXG4gICAqIEBtZW1iZXJvZiBEYXNoYm9hcmRTZXJ2aWNlXHJcbiAgICovXHJcbiAgZ2V0QXR0ZW5kYW5jZVN0YXRlc1NuYXBzaG90KCk6IFJlY29yZDxzdHJpbmcsIEF0dGVuZGFuY2VTdGF0ZT4ge1xyXG4gICAgcmV0dXJuIHRoaXMuYXR0ZW5kYW5jZVN0YXRlcy52YWx1ZTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFNlZWRzIHRoZSBhdHRlbmRhbmNlLXN0YXRlIG1hcCBmcm9tIGEgZnJlc2hseSBsb2FkZWQgbGlzdCBvZiBldmVudHMsIHVzaW5nXHJcbiAgICogZWFjaCBtZWV0aW5nJ3MgYGF0dGVuZGFuY2VTdGF0ZWAgKGRlZmF1bHRpbmcgdG8gYE5PVF9BVFRFTkRJTkdgKS4gS2VlcHMgdGhlXHJcbiAgICogZGlzcGxheWVkIHN0YXRlIGluIHN5bmMgd2l0aCB0aGUgZGF0YSBsb2FkIHdpdGhvdXQgb3ZlcndyaXRpbmcgaWRzIHRoYXQgYXJlXHJcbiAgICogbm90IHByZXNlbnQgaW4gdGhlIG5ldyBsaXN0LlxyXG4gICAqIEBwYXJhbSB7VXBjb21pbmdFdmVudFtdfSBldmVudHMgLSBUaGUgbG9hZGVkIHVwY29taW5nIGV2ZW50cy5cclxuICAgKiBAcmV0dXJuIHt2b2lkfVxyXG4gICAqIEBtZW1iZXJvZiBEYXNoYm9hcmRTZXJ2aWNlXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBzZWVkQXR0ZW5kYW5jZVN0YXRlcyhldmVudHM6IFVwY29taW5nRXZlbnRbXSk6IHZvaWQge1xyXG4gICAgY29uc3QgbWVldGluZ3MgPSBldmVudHMuZmxhdE1hcCgoZXZlbnQpID0+IGV2ZW50Lm1lZXRpbmdzID8/IFtdKTtcclxuICAgIHRoaXMuc2VlZEF0dGVuZGFuY2VTdGF0ZXNGcm9tTWVldGluZ3MobWVldGluZ3MpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogU2VlZHMgdGhlIGF0dGVuZGFuY2Utc3RhdGUgbWFwIGZyb20gYSBsaXN0IG9mIG1lZXRpbmcgcm93cywgdXNpbmcgZWFjaFxyXG4gICAqIG1lZXRpbmcncyBgYXR0ZW5kYW5jZVN0YXRlYCAoZGVmYXVsdGluZyB0byBgTk9UX0FUVEVORElOR2ApIHdpdGhvdXRcclxuICAgKiBvdmVyd3JpdGluZyBpZHMgYWJzZW50IGZyb20gdGhlIG5ldyBsaXN0LiBTaGFyZWQgYnkgdGhlIGxpc3QgbG9hZCBhbmQgdGhlXHJcbiAgICogcGVyLWV2ZW50IGV4cGFuZCBzbyBmcmVzaGx5IGxvYWRlZCBjaGlsZCBtZWV0aW5ncyBwaWNrIHVwIHRoZWlyIHN0YXRlLlxyXG4gICAqIEBwYXJhbSB7TWVldGluZ1Jvd1tdfSBtZWV0aW5ncyAtIFRoZSBtZWV0aW5nIHJvd3MgdG8gc2VlZCBmcm9tLlxyXG4gICAqIEByZXR1cm4ge3ZvaWR9XHJcbiAgICogQG1lbWJlcm9mIERhc2hib2FyZFNlcnZpY2VcclxuICAgKi9cclxuICBwcml2YXRlIHNlZWRBdHRlbmRhbmNlU3RhdGVzRnJvbU1lZXRpbmdzKG1lZXRpbmdzOiBNZWV0aW5nUm93W10pOiB2b2lkIHtcclxuICAgIGNvbnN0IG5leHQ6IFJlY29yZDxzdHJpbmcsIEF0dGVuZGFuY2VTdGF0ZT4gPSB7XHJcbiAgICAgIC4uLnRoaXMuYXR0ZW5kYW5jZVN0YXRlcy52YWx1ZSxcclxuICAgIH07XHJcbiAgICBtZWV0aW5ncy5mb3JFYWNoKChtZWV0aW5nKSA9PiB7XHJcbiAgICAgIGlmIChtZWV0aW5nLm1lZXRpbmdJZCkge1xyXG4gICAgICAgIG5leHRbbWVldGluZy5tZWV0aW5nSWRdID1cclxuICAgICAgICAgIG1lZXRpbmcuYXR0ZW5kYW5jZVN0YXRlID8/XHJcbiAgICAgICAgICBuZXh0W21lZXRpbmcubWVldGluZ0lkXSA/P1xyXG4gICAgICAgICAgQXR0ZW5kYW5jZVN0YXRlLk5PVF9BVFRFTkRJTkc7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gICAgdGhpcy5hdHRlbmRhbmNlU3RhdGVzLm5leHQobmV4dCk7XHJcbiAgfVxyXG59XHJcbiJdfQ==
|