@ieeesa-npm/dashboard 0.0.0-stage → 0.0.1

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.
Files changed (63) hide show
  1. package/README.md +75 -3
  2. package/esm2022/ieeesa-npm-dashboard.mjs +5 -0
  3. package/esm2022/lib/assets/constants.json +141 -0
  4. package/esm2022/lib/assets/dashboard-mock.mjs +217 -0
  5. package/esm2022/lib/assets/dashboard-route-paths.mock.mjs +12 -0
  6. package/esm2022/lib/assets/dashboard-user-permissions.mock.mjs +23 -0
  7. package/esm2022/lib/assets/date-formats.mjs +28 -0
  8. package/esm2022/lib/components/event-group-card/event-group-card.component.mjs +277 -0
  9. package/esm2022/lib/components/meeting-attendance-row/meeting-attendance-row.component.mjs +181 -0
  10. package/esm2022/lib/components/member-level-badge/member-level-badge.component.mjs +79 -0
  11. package/esm2022/lib/components/upcoming-meetings-events/upcoming-meetings-events.component.mjs +163 -0
  12. package/esm2022/lib/components/welcome-header/dashboard-welcome-header.component.mjs +151 -0
  13. package/esm2022/lib/components/your-groups/your-groups.component.mjs +206 -0
  14. package/esm2022/lib/dashboard.component.mjs +377 -0
  15. package/esm2022/lib/dashboard.module.mjs +16 -0
  16. package/esm2022/lib/dashboard.routes.mjs +7 -0
  17. package/esm2022/lib/models/attendance-action-permissions.model.mjs +2 -0
  18. package/esm2022/lib/models/attendance-state.model.mjs +7 -0
  19. package/esm2022/lib/models/dashboard-list-response.model.mjs +2 -0
  20. package/esm2022/lib/models/dashboard-route-config.model.mjs +2 -0
  21. package/esm2022/lib/models/dashboard-section-state.model.mjs +9 -0
  22. package/esm2022/lib/models/dashboard-user-info.model.mjs +2 -0
  23. package/esm2022/lib/models/group-row.model.mjs +2 -0
  24. package/esm2022/lib/models/meeting-row.model.mjs +2 -0
  25. package/esm2022/lib/models/page-change.model.mjs +2 -0
  26. package/esm2022/lib/models/upcoming-event.model.mjs +2 -0
  27. package/esm2022/lib/services/attendance-reducers.mjs +54 -0
  28. package/esm2022/lib/services/dashboard.service.mjs +208 -0
  29. package/esm2022/lib/services/user-permissions.service.mjs +50 -0
  30. package/esm2022/lib/utils/attendance-action.util.mjs +53 -0
  31. package/esm2022/public-api.mjs +34 -0
  32. package/fesm2022/ieeesa-npm-dashboard.mjs +2234 -0
  33. package/fesm2022/ieeesa-npm-dashboard.mjs.map +1 -0
  34. package/index.d.ts +5 -0
  35. package/lib/assets/dashboard-mock.d.ts +31 -0
  36. package/lib/assets/dashboard-route-paths.mock.d.ts +2 -0
  37. package/lib/assets/dashboard-user-permissions.mock.d.ts +2 -0
  38. package/lib/assets/date-formats.d.ts +27 -0
  39. package/lib/components/event-group-card/event-group-card.component.d.ts +300 -0
  40. package/lib/components/meeting-attendance-row/meeting-attendance-row.component.d.ts +239 -0
  41. package/lib/components/member-level-badge/member-level-badge.component.d.ts +161 -0
  42. package/lib/components/upcoming-meetings-events/upcoming-meetings-events.component.d.ts +238 -0
  43. package/lib/components/welcome-header/dashboard-welcome-header.component.d.ts +98 -0
  44. package/lib/components/your-groups/your-groups.component.d.ts +110 -0
  45. package/lib/dashboard.component.d.ts +376 -0
  46. package/lib/dashboard.module.d.ts +7 -0
  47. package/lib/dashboard.routes.d.ts +2 -0
  48. package/lib/models/attendance-action-permissions.model.d.ts +4 -0
  49. package/lib/models/attendance-state.model.d.ts +4 -0
  50. package/lib/models/dashboard-list-response.model.d.ts +5 -0
  51. package/lib/models/dashboard-route-config.model.d.ts +7 -0
  52. package/lib/models/dashboard-section-state.model.d.ts +6 -0
  53. package/lib/models/dashboard-user-info.model.d.ts +5 -0
  54. package/lib/models/group-row.model.d.ts +8 -0
  55. package/lib/models/meeting-row.model.d.ts +12 -0
  56. package/lib/models/page-change.model.d.ts +4 -0
  57. package/lib/models/upcoming-event.model.d.ts +13 -0
  58. package/lib/services/attendance-reducers.d.ts +43 -0
  59. package/lib/services/dashboard.service.d.ts +119 -0
  60. package/lib/services/user-permissions.service.d.ts +31 -0
  61. package/lib/utils/attendance-action.util.d.ts +38 -0
  62. package/package.json +30 -3
  63. package/public-api.d.ts +24 -0
@@ -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,208 @@
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 { DashboardGroupsMock, DashboardUpcomingEventsMock, } from '../assets/dashboard-mock';
6
+ import { applyLeaveMeetingSuccess, applyLogAttendanceSuccess, beginAttendanceAction, endAttendanceAction, } from './attendance-reducers';
7
+ import * as i0 from "@angular/core";
8
+ import * as i1 from "@ieeesa-npm/utility";
9
+ /**
10
+ * DashboardService is the single source of truth for the dashboard landing
11
+ * page's data and attendance state. It mirrors the `events-and-meetings`
12
+ * service conventions: it is a `providedIn: 'root'` singleton, holds the host
13
+ * `apiBaseUrl` / `userPermissions` set via {@link setAppConfig}, owns its state
14
+ * via `BehaviorSubject`s exposed as observables, and reaches the backend only
15
+ * through the shared `HttpService` from `@ieeesa-npm/utility` (never
16
+ * `HttpClient` directly).
17
+ *
18
+ * The upcoming-events and groups loads currently return annotated mock data
19
+ * because their endpoints are not yet available; the attendance actions compose
20
+ * the pure reducers from `attendance-reducers.ts` so the displayed
21
+ * `AttendanceState` only advances on a successful resolution and the prior
22
+ * state is retained on failure.
23
+ * @export
24
+ * @class DashboardService
25
+ */
26
+ export class DashboardService {
27
+ constructor(
28
+ // eslint-disable-next-line no-unused-vars
29
+ httpService // eslint-disable-next-line no-empty-function
30
+ ) {
31
+ this.httpService = httpService;
32
+ this.upcomingEvents = new BehaviorSubject([]);
33
+ this.groups = new BehaviorSubject([]);
34
+ this.upcomingState = new BehaviorSubject(DashboardSectionState.LOADING);
35
+ this.groupsState = new BehaviorSubject(DashboardSectionState.LOADING);
36
+ this.attendanceStates = new BehaviorSubject({});
37
+ this.inFlightMeetingIds = new BehaviorSubject(new Set());
38
+ /** Emits the list of the user's upcoming events. */
39
+ this.upcomingEvents$ = this.upcomingEvents.asObservable();
40
+ /** Emits the list of the user's groups. */
41
+ this.groups$ = this.groups.asObservable();
42
+ /** Emits the load/empty/error state of the upcoming-events section. */
43
+ this.upcomingState$ = this.upcomingState.asObservable();
44
+ /** Emits the load/empty/error state of the groups section. */
45
+ this.groupsState$ = this.groupsState.asObservable();
46
+ /** Emits the per-meeting attendance-state map. */
47
+ this.attendanceStates$ = this.attendanceStates.asObservable();
48
+ /** Emits the set of meeting ids with an attendance action in flight. */
49
+ this.inFlightMeetingIds$ = this.inFlightMeetingIds.asObservable();
50
+ }
51
+ /**
52
+ * Stores the host-supplied API base URL and user permissions used to build
53
+ * request URLs and gate permission-controlled actions. Mirrors the
54
+ * `events-and-meetings` service `setAppConfig`.
55
+ * @param {string} apiBaseURL - The host application's API base URL.
56
+ * @param {UserPermission[]} userPermissions - The signed-in user's permissions.
57
+ * @return {void}
58
+ * @memberof DashboardService
59
+ */
60
+ setAppConfig(apiBaseURL, userPermissions) {
61
+ this.apiBaseUrl = apiBaseURL;
62
+ this.userPermissions = userPermissions;
63
+ }
64
+ /**
65
+ * Loads the user's upcoming events, driving the upcoming section through
66
+ * LOADING → LOADED/EMPTY on success and leaving the caller to set ERROR on
67
+ * failure. Follows the `pipe(map, catchError(throw))` pattern and seeds the
68
+ * per-meeting attendance-state map from the loaded meetings.
69
+ *
70
+ * TODO: Replace mock with real API call when BE is ready
71
+ * @return {Observable<DashboardListResponse<UpcomingEvent[]>>} The upcoming-events response envelope.
72
+ * @memberof DashboardService
73
+ */
74
+ loadUpcomingEvents() {
75
+ this.upcomingState.next(DashboardSectionState.LOADING);
76
+ // TODO: Replace mock with real API call when BE is ready
77
+ const response$ = of({
78
+ status: true,
79
+ body: DashboardUpcomingEventsMock,
80
+ });
81
+ return response$.pipe(map((response) => {
82
+ const events = response?.body ?? [];
83
+ this.upcomingEvents.next(events);
84
+ this.seedAttendanceStates(events);
85
+ this.upcomingState.next(events.length > 0
86
+ ? DashboardSectionState.LOADED
87
+ : DashboardSectionState.EMPTY);
88
+ return response;
89
+ }), catchError((error) => {
90
+ this.upcomingState.next(DashboardSectionState.ERROR);
91
+ throw error;
92
+ }));
93
+ }
94
+ /**
95
+ * Loads the user's groups, driving the groups section through
96
+ * LOADING → LOADED/EMPTY on success and leaving the caller to set ERROR on
97
+ * failure. Follows the `pipe(map, catchError(throw))` pattern.
98
+ *
99
+ * TODO: Replace mock with real API call when BE is ready
100
+ * @return {Observable<DashboardListResponse<GroupRow[]>>} The groups response envelope.
101
+ * @memberof DashboardService
102
+ */
103
+ loadGroups() {
104
+ this.groupsState.next(DashboardSectionState.LOADING);
105
+ // TODO: Replace mock with real API call when BE is ready
106
+ const response$ = of({
107
+ status: true,
108
+ body: DashboardGroupsMock,
109
+ });
110
+ return response$.pipe(map((response) => {
111
+ const groups = response?.body ?? [];
112
+ this.groups.next(groups);
113
+ this.groupsState.next(groups.length > 0
114
+ ? DashboardSectionState.LOADED
115
+ : DashboardSectionState.EMPTY);
116
+ return response;
117
+ }), catchError((error) => {
118
+ this.groupsState.next(DashboardSectionState.ERROR);
119
+ throw error;
120
+ }));
121
+ }
122
+ /**
123
+ * Logs attendance for a meeting. Marks the meeting in-flight (retaining the
124
+ * prior displayed state), posts through `HttpService`, applies the
125
+ * log-attendance-success reducer on success, clears the in-flight flag on
126
+ * completion, and rethrows while retaining prior state on failure.
127
+ * @param {string} meetingId - The meeting to log attendance for.
128
+ * @return {Observable<DashboardListResponse<unknown>>} The attendance response envelope.
129
+ * @memberof DashboardService
130
+ */
131
+ logAttendance(meetingId) {
132
+ this.inFlightMeetingIds.next(beginAttendanceAction(this.inFlightMeetingIds.value, meetingId));
133
+ return this.httpService
134
+ .postData(`${this.apiBaseUrl}/meetings/attendance/log`, { meetingId })
135
+ .pipe(map((response) => {
136
+ this.attendanceStates.next(applyLogAttendanceSuccess(this.attendanceStates.value, meetingId));
137
+ this.inFlightMeetingIds.next(endAttendanceAction(this.inFlightMeetingIds.value, meetingId));
138
+ return response;
139
+ }), catchError((error) => {
140
+ // Retain prior attendance state; only clear the in-flight flag.
141
+ this.inFlightMeetingIds.next(endAttendanceAction(this.inFlightMeetingIds.value, meetingId));
142
+ throw error;
143
+ }));
144
+ }
145
+ /**
146
+ * Leaves a meeting. Marks the meeting in-flight (retaining the prior
147
+ * displayed state), posts through `HttpService`, applies the
148
+ * leave-meeting-success reducer on success, clears the in-flight flag on
149
+ * completion, and rethrows while retaining prior state on failure.
150
+ * @param {string} meetingId - The meeting to leave.
151
+ * @return {Observable<DashboardListResponse<unknown>>} The attendance response envelope.
152
+ * @memberof DashboardService
153
+ */
154
+ leaveMeeting(meetingId) {
155
+ this.inFlightMeetingIds.next(beginAttendanceAction(this.inFlightMeetingIds.value, meetingId));
156
+ return this.httpService
157
+ .postData(`${this.apiBaseUrl}/meetings/attendance/leave`, { meetingId })
158
+ .pipe(map((response) => {
159
+ this.attendanceStates.next(applyLeaveMeetingSuccess(this.attendanceStates.value, meetingId));
160
+ this.inFlightMeetingIds.next(endAttendanceAction(this.inFlightMeetingIds.value, meetingId));
161
+ return response;
162
+ }), catchError((error) => {
163
+ // Retain prior attendance state; only clear the in-flight flag.
164
+ this.inFlightMeetingIds.next(endAttendanceAction(this.inFlightMeetingIds.value, meetingId));
165
+ throw error;
166
+ }));
167
+ }
168
+ /**
169
+ * Returns a synchronous snapshot of the per-meeting attendance-state map.
170
+ * @return {Record<string, AttendanceState>} The current attendance-state map.
171
+ * @memberof DashboardService
172
+ */
173
+ getAttendanceStatesSnapshot() {
174
+ return this.attendanceStates.value;
175
+ }
176
+ /**
177
+ * Seeds the attendance-state map from a freshly loaded list of events, using
178
+ * each meeting's `attendanceState` (defaulting to `NOT_ATTENDING`). Keeps the
179
+ * displayed state in sync with the data load without overwriting ids that are
180
+ * not present in the new list.
181
+ * @param {UpcomingEvent[]} events - The loaded upcoming events.
182
+ * @return {void}
183
+ * @memberof DashboardService
184
+ */
185
+ seedAttendanceStates(events) {
186
+ const next = {
187
+ ...this.attendanceStates.value,
188
+ };
189
+ events.forEach((event) => {
190
+ event.meetings?.forEach((meeting) => {
191
+ if (meeting.meetingId) {
192
+ next[meeting.meetingId] =
193
+ meeting.attendanceState ?? AttendanceState.NOT_ATTENDING;
194
+ }
195
+ });
196
+ });
197
+ this.attendanceStates.next(next);
198
+ }
199
+ 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 }); }
200
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DashboardService, providedIn: 'root' }); }
201
+ }
202
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DashboardService, decorators: [{
203
+ type: Injectable,
204
+ args: [{
205
+ providedIn: 'root',
206
+ }]
207
+ }], ctorParameters: function () { return [{ type: i1.HttpService }]; } });
208
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGFzaGJvYXJkLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9kYXNoYm9hcmQvc3JjL2xpYi9zZXJ2aWNlcy9kYXNoYm9hcmQuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFDTCxlQUFlLEVBRWYsVUFBVSxFQUNWLEdBQUcsRUFDSCxFQUFFLEdBQ0gsTUFBTSxNQUFNLENBQUM7QUFHZCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFFbkUsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFHaEYsT0FBTyxFQUNMLG1CQUFtQixFQUNuQiwyQkFBMkIsR0FDNUIsTUFBTSwwQkFBMEIsQ0FBQztBQUNsQyxPQUFPLEVBQ0wsd0JBQXdCLEVBQ3hCLHlCQUF5QixFQUN6QixxQkFBcUIsRUFDckIsbUJBQW1CLEdBQ3BCLE1BQU0sdUJBQXVCLENBQUM7OztBQUUvQjs7Ozs7Ozs7Ozs7Ozs7OztHQWdCRztBQUlILE1BQU0sT0FBTyxnQkFBZ0I7SUFxQzNCO0lBQ0UsMENBQTBDO0lBQ2xDLFdBQXdCLENBQUMsNkNBQTZDOztRQUF0RSxnQkFBVyxHQUFYLFdBQVcsQ0FBYTtRQW5DakIsbUJBQWMsR0FBRyxJQUFJLGVBQWUsQ0FBa0IsRUFBRSxDQUFDLENBQUM7UUFDMUQsV0FBTSxHQUFHLElBQUksZUFBZSxDQUFhLEVBQUUsQ0FBQyxDQUFDO1FBQzdDLGtCQUFhLEdBQUcsSUFBSSxlQUFlLENBQ2xELHFCQUFxQixDQUFDLE9BQU8sQ0FDOUIsQ0FBQztRQUNlLGdCQUFXLEdBQUcsSUFBSSxlQUFlLENBQ2hELHFCQUFxQixDQUFDLE9BQU8sQ0FDOUIsQ0FBQztRQUNlLHFCQUFnQixHQUFHLElBQUksZUFBZSxDQUVyRCxFQUFFLENBQUMsQ0FBQztRQUNX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LElBQUksR0FBb0M7WUFDNUMsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsS0FBSztTQUMvQixDQUFDO1FBQ0YsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFO1lBQ3ZCLEtBQUssQ0FBQyxRQUFRLEVBQUUsT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUU7Z0JBQ2xDLElBQUksT0FBTyxDQUFDLFNBQVMsRUFBRTtvQkFDckIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUM7d0JBQ3JCLE9BQU8sQ0FBQyxlQUFlLElBQUksZUFBZSxDQUFDLGFBQWEsQ0FBQztpQkFDNUQ7WUFDSCxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNuQyxDQUFDOytHQXZPVSxnQkFBZ0I7bUhBQWhCLGdCQUFnQixjQUZmLE1BQU07OzRGQUVQLGdCQUFnQjtrQkFINUIsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7XHJcbiAgQmVoYXZpb3JTdWJqZWN0LFxyXG4gIE9ic2VydmFibGUsXHJcbiAgY2F0Y2hFcnJvcixcclxuICBtYXAsXHJcbiAgb2YsXHJcbn0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IEh0dHBTZXJ2aWNlIH0gZnJvbSAnQGllZWVzYS1ucG0vdXRpbGl0eSc7XHJcbmltcG9ydCB7IFVzZXJQZXJtaXNzaW9uIH0gZnJvbSAnQGllZWVzYS1ucG0vbW9kZWxzJztcclxuaW1wb3J0IHsgQXR0ZW5kYW5jZVN0YXRlIH0gZnJvbSAnLi4vbW9kZWxzL2F0dGVuZGFuY2Utc3RhdGUubW9kZWwnO1xyXG5pbXBvcnQgeyBEYXNoYm9hcmRMaXN0UmVzcG9uc2UgfSBmcm9tICcuLi9tb2RlbHMvZGFzaGJvYXJkLWxpc3QtcmVzcG9uc2UubW9kZWwnO1xyXG5pbXBvcnQgeyBEYXNoYm9hcmRTZWN0aW9uU3RhdGUgfSBmcm9tICcuLi9tb2RlbHMvZGFzaGJvYXJkLXNlY3Rpb24tc3RhdGUubW9kZWwnO1xyXG5pbXBvcnQgeyBHcm91cFJvdyB9IGZyb20gJy4uL21vZGVscy9ncm91cC1yb3cubW9kZWwnO1xyXG5pbXBvcnQgeyBVcGNvbWluZ0V2ZW50IH0gZnJvbSAnLi4vbW9kZWxzL3VwY29taW5nLWV2ZW50Lm1vZGVsJztcclxuaW1wb3J0IHtcclxuICBEYXNoYm9hcmRHcm91cHNNb2NrLFxyXG4gIERhc2hib2FyZFVwY29taW5nRXZlbnRzTW9jayxcclxufSBmcm9tICcuLi9hc3NldHMvZGFzaGJvYXJkLW1vY2snO1xyXG5pbXBvcnQge1xyXG4gIGFwcGx5TGVhdmVNZWV0aW5nU3VjY2VzcyxcclxuICBhcHBseUxvZ0F0dGVuZGFuY2VTdWNjZXNzLFxyXG4gIGJlZ2luQXR0ZW5kYW5jZUFjdGlvbixcclxuICBlbmRBdHRlbmRhbmNlQWN0aW9uLFxyXG59IGZyb20gJy4vYXR0ZW5kYW5jZS1yZWR1Y2Vycyc7XHJcblxyXG4vKipcclxuICogRGFzaGJvYXJkU2VydmljZSBpcyB0aGUgc2luZ2xlIHNvdXJjZSBvZiB0cnV0aCBmb3IgdGhlIGRhc2hib2FyZCBsYW5kaW5nXHJcbiAqIHBhZ2UncyBkYXRhIGFuZCBhdHRlbmRhbmNlIHN0YXRlLiBJdCBtaXJyb3JzIHRoZSBgZXZlbnRzLWFuZC1tZWV0aW5nc2BcclxuICogc2VydmljZSBjb252ZW50aW9uczogaXQgaXMgYSBgcHJvdmlkZWRJbjogJ3Jvb3QnYCBzaW5nbGV0b24sIGhvbGRzIHRoZSBob3N0XHJcbiAqIGBhcGlCYXNlVXJsYCAvIGB1c2VyUGVybWlzc2lvbnNgIHNldCB2aWEge0BsaW5rIHNldEFwcENvbmZpZ30sIG93bnMgaXRzIHN0YXRlXHJcbiAqIHZpYSBgQmVoYXZpb3JTdWJqZWN0YHMgZXhwb3NlZCBhcyBvYnNlcnZhYmxlcywgYW5kIHJlYWNoZXMgdGhlIGJhY2tlbmQgb25seVxyXG4gKiB0aHJvdWdoIHRoZSBzaGFyZWQgYEh0dHBTZXJ2aWNlYCBmcm9tIGBAaWVlZXNhLW5wbS91dGlsaXR5YCAobmV2ZXJcclxuICogYEh0dHBDbGllbnRgIGRpcmVjdGx5KS5cclxuICpcclxuICogVGhlIHVwY29taW5nLWV2ZW50cyBhbmQgZ3JvdXBzIGxvYWRzIGN1cnJlbnRseSByZXR1cm4gYW5ub3RhdGVkIG1vY2sgZGF0YVxyXG4gKiBiZWNhdXNlIHRoZWlyIGVuZHBvaW50cyBhcmUgbm90IHlldCBhdmFpbGFibGU7IHRoZSBhdHRlbmRhbmNlIGFjdGlvbnMgY29tcG9zZVxyXG4gKiB0aGUgcHVyZSByZWR1Y2VycyBmcm9tIGBhdHRlbmRhbmNlLXJlZHVjZXJzLnRzYCBzbyB0aGUgZGlzcGxheWVkXHJcbiAqIGBBdHRlbmRhbmNlU3RhdGVgIG9ubHkgYWR2YW5jZXMgb24gYSBzdWNjZXNzZnVsIHJlc29sdXRpb24gYW5kIHRoZSBwcmlvclxyXG4gKiBzdGF0ZSBpcyByZXRhaW5lZCBvbiBmYWlsdXJlLlxyXG4gKiBAZXhwb3J0XHJcbiAqIEBjbGFzcyBEYXNoYm9hcmRTZXJ2aWNlXHJcbiAqL1xyXG5ASW5qZWN0YWJsZSh7XHJcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgRGFzaGJvYXJkU2VydmljZSB7XHJcbiAgYXBpQmFzZVVybCE6IHN0cmluZztcclxuICB1c2VyUGVybWlzc2lvbnMhOiBVc2VyUGVybWlzc2lvbltdO1xyXG5cclxuICBwcml2YXRlIHJlYWRvbmx5IHVwY29taW5nRXZlbnRzID0gbmV3IEJlaGF2aW9yU3ViamVjdDxVcGNvbWluZ0V2ZW50W10+KFtdKTtcclxuICBwcml2YXRlIHJlYWRvbmx5IGdyb3VwcyA9IG5ldyBCZWhhdmlvclN1YmplY3Q8R3JvdXBSb3dbXT4oW10pO1xyXG4gIHByaXZhdGUgcmVhZG9ubHkgdXBjb21pbmdTdGF0ZSA9IG5ldyBCZWhhdmlvclN1YmplY3Q8RGFzaGJvYXJkU2VjdGlvblN0YXRlPihcclxuICAgIERhc2hib2FyZFNlY3Rpb25TdGF0ZS5MT0FESU5HXHJcbiAgKTtcclxuICBwcml2YXRlIHJlYWRvbmx5IGdyb3Vwc1N0YXRlID0gbmV3IEJlaGF2aW9yU3ViamVjdDxEYXNoYm9hcmRTZWN0aW9uU3RhdGU+KFxyXG4gICAgRGFzaGJvYXJkU2VjdGlvblN0YXRlLkxPQURJTkdcclxuICApO1xyXG4gIHByaXZhdGUgcmVhZG9ubHkgYXR0ZW5kYW5jZVN0YXRlcyA9IG5ldyBCZWhhdmlvclN1YmplY3Q8XHJcbiAgICBSZWNvcmQ8c3RyaW5nLCBBdHRlbmRhbmNlU3RhdGU+XHJcbiAgPih7fSk7XHJcbiAgcHJpdmF0ZSByZWFkb25seSBpbkZsaWdodE1lZXRpbmdJZHMgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFxyXG4gICAgUmVhZG9ubHlTZXQ8c3RyaW5nPlxyXG4gID4obmV3IFNldDxzdHJpbmc+KCkpO1xyXG5cclxuICAvKiogRW1pdHMgdGhlIGxpc3Qgb2YgdGhlIHVzZXIncyB1cGNvbWluZyBldmVudHMuICovXHJcbiAgdXBjb21pbmdFdmVudHMkOiBPYnNlcnZhYmxlPFVwY29taW5nRXZlbnRbXT4gPVxyXG4gICAgdGhpcy51cGNvbWluZ0V2ZW50cy5hc09ic2VydmFibGUoKTtcclxuICAvKiogRW1pdHMgdGhlIGxpc3Qgb2YgdGhlIHVzZXIncyBncm91cHMuICovXHJcbiAgZ3JvdXBzJDogT2JzZXJ2YWJsZTxHcm91cFJvd1tdPiA9IHRoaXMuZ3JvdXBzLmFzT2JzZXJ2YWJsZSgpO1xyXG4gIC8qKiBFbWl0cyB0aGUgbG9hZC9lbXB0eS9lcnJvciBzdGF0ZSBvZiB0aGUgdXBjb21pbmctZXZlbnRzIHNlY3Rpb24uICovXHJcbiAgdXBjb21pbmdTdGF0ZSQ6IE9ic2VydmFibGU8RGFzaGJvYXJkU2VjdGlvblN0YXRlPiA9XHJcbiAgICB0aGlzLnVwY29taW5nU3RhdGUuYXNPYnNlcnZhYmxlKCk7XHJcbiAgLyoqIEVtaXRzIHRoZSBsb2FkL2VtcHR5L2Vycm9yIHN0YXRlIG9mIHRoZSBncm91cHMgc2VjdGlvbi4gKi9cclxuICBncm91cHNTdGF0ZSQ6IE9ic2VydmFibGU8RGFzaGJvYXJkU2VjdGlvblN0YXRlPiA9XHJcbiAgICB0aGlzLmdyb3Vwc1N0YXRlLmFzT2JzZXJ2YWJsZSgpO1xyXG4gIC8qKiBFbWl0cyB0aGUgcGVyLW1lZXRpbmcgYXR0ZW5kYW5jZS1zdGF0ZSBtYXAuICovXHJcbiAgYXR0ZW5kYW5jZVN0YXRlcyQ6IE9ic2VydmFibGU8UmVjb3JkPHN0cmluZywgQXR0ZW5kYW5jZVN0YXRlPj4gPVxyXG4gICAgdGhpcy5hdHRlbmRhbmNlU3RhdGVzLmFzT2JzZXJ2YWJsZSgpO1xyXG4gIC8qKiBFbWl0cyB0aGUgc2V0IG9mIG1lZXRpbmcgaWRzIHdpdGggYW4gYXR0ZW5kYW5jZSBhY3Rpb24gaW4gZmxpZ2h0LiAqL1xyXG4gIGluRmxpZ2h0TWVldGluZ0lkcyQ6IE9ic2VydmFibGU8UmVhZG9ubHlTZXQ8c3RyaW5nPj4gPVxyXG4gICAgdGhpcy5pbkZsaWdodE1lZXRpbmdJZHMuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVudXNlZC12YXJzXHJcbiAgICBwcml2YXRlIGh0dHBTZXJ2aWNlOiBIdHRwU2VydmljZSAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tZW1wdHktZnVuY3Rpb25cclxuICApIHt9XHJcblxyXG4gIC8qKlxyXG4gICAqIFN0b3JlcyB0aGUgaG9zdC1zdXBwbGllZCBBUEkgYmFzZSBVUkwgYW5kIHVzZXIgcGVybWlzc2lvbnMgdXNlZCB0byBidWlsZFxyXG4gICAqIHJlcXVlc3QgVVJMcyBhbmQgZ2F0ZSBwZXJtaXNzaW9uLWNvbnRyb2xsZWQgYWN0aW9ucy4gTWlycm9ycyB0aGVcclxuICAgKiBgZXZlbnRzLWFuZC1tZWV0aW5nc2Agc2VydmljZSBgc2V0QXBwQ29uZmlnYC5cclxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXBpQmFzZVVSTCAtIFRoZSBob3N0IGFwcGxpY2F0aW9uJ3MgQVBJIGJhc2UgVVJMLlxyXG4gICAqIEBwYXJhbSB7VXNlclBlcm1pc3Npb25bXX0gdXNlclBlcm1pc3Npb25zIC0gVGhlIHNpZ25lZC1pbiB1c2VyJ3MgcGVybWlzc2lvbnMuXHJcbiAgICogQHJldHVybiB7dm9pZH1cclxuICAgKiBAbWVtYmVyb2YgRGFzaGJvYXJkU2VydmljZVxyXG4gICAqL1xyXG4gIHNldEFwcENvbmZpZyhhcGlCYXNlVVJMOiBzdHJpbmcsIHVzZXJQZXJtaXNzaW9uczogVXNlclBlcm1pc3Npb25bXSk6IHZvaWQge1xyXG4gICAgdGhpcy5hcGlCYXNlVXJsID0gYXBpQmFzZVVSTDtcclxuICAgIHRoaXMudXNlclBlcm1pc3Npb25zID0gdXNlclBlcm1pc3Npb25zO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTG9hZHMgdGhlIHVzZXIncyB1cGNvbWluZyBldmVudHMsIGRyaXZpbmcgdGhlIHVwY29taW5nIHNlY3Rpb24gdGhyb3VnaFxyXG4gICAqIExPQURJTkcg4oaSIExPQURFRC9FTVBUWSBvbiBzdWNjZXNzIGFuZCBsZWF2aW5nIHRoZSBjYWxsZXIgdG8gc2V0IEVSUk9SIG9uXHJcbiAgICogZmFpbHVyZS4gRm9sbG93cyB0aGUgYHBpcGUobWFwLCBjYXRjaEVycm9yKHRocm93KSlgIHBhdHRlcm4gYW5kIHNlZWRzIHRoZVxyXG4gICAqIHBlci1tZWV0aW5nIGF0dGVuZGFuY2Utc3RhdGUgbWFwIGZyb20gdGhlIGxvYWRlZCBtZWV0aW5ncy5cclxuICAgKlxyXG4gICAqIFRPRE86IFJlcGxhY2UgbW9jayB3aXRoIHJlYWwgQVBJIGNhbGwgd2hlbiBCRSBpcyByZWFkeVxyXG4gICAqIEByZXR1cm4ge09ic2VydmFibGU8RGFzaGJvYXJkTGlzdFJlc3BvbnNlPFVwY29taW5nRXZlbnRbXT4+fSBUaGUgdXBjb21pbmctZXZlbnRzIHJlc3BvbnNlIGVudmVsb3BlLlxyXG4gICAqIEBtZW1iZXJvZiBEYXNoYm9hcmRTZXJ2aWNlXHJcbiAgICovXHJcbiAgbG9hZFVwY29taW5nRXZlbnRzKCk6IE9ic2VydmFibGU8RGFzaGJvYXJkTGlzdFJlc3BvbnNlPFVwY29taW5nRXZlbnRbXT4+IHtcclxuICAgIHRoaXMudXBjb21pbmdTdGF0ZS5uZXh0KERhc2hib2FyZFNlY3Rpb25TdGF0ZS5MT0FESU5HKTtcclxuICAgIC8vIFRPRE86IFJlcGxhY2UgbW9jayB3aXRoIHJlYWwgQVBJIGNhbGwgd2hlbiBCRSBpcyByZWFkeVxyXG4gICAgY29uc3QgcmVzcG9uc2UkOiBPYnNlcnZhYmxlPERhc2hib2FyZExpc3RSZXNwb25zZTxVcGNvbWluZ0V2ZW50W10+PiA9IG9mKHtcclxuICAgICAgc3RhdHVzOiB0cnVlLFxyXG4gICAgICBib2R5OiBEYXNoYm9hcmRVcGNvbWluZ0V2ZW50c01vY2ssXHJcbiAgICB9KTtcclxuICAgIHJldHVybiByZXNwb25zZSQucGlwZShcclxuICAgICAgbWFwKChyZXNwb25zZSkgPT4ge1xyXG4gICAgICAgIGNvbnN0IGV2ZW50cyA9IHJlc3BvbnNlPy5ib2R5ID8/IFtdO1xyXG4gICAgICAgIHRoaXMudXBjb21pbmdFdmVudHMubmV4dChldmVudHMpO1xyXG4gICAgICAgIHRoaXMuc2VlZEF0dGVuZGFuY2VTdGF0ZXMoZXZlbnRzKTtcclxuICAgICAgICB0aGlzLnVwY29taW5nU3RhdGUubmV4dChcclxuICAgICAgICAgIGV2ZW50cy5sZW5ndGggPiAwXHJcbiAgICAgICAgICAgID8gRGFzaGJvYXJkU2VjdGlvblN0YXRlLkxPQURFRFxyXG4gICAgICAgICAgICA6IERhc2hib2FyZFNlY3Rpb25TdGF0ZS5FTVBUWVxyXG4gICAgICAgICk7XHJcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICB9KSxcclxuICAgICAgY2F0Y2hFcnJvcigoZXJyb3IpID0+IHtcclxuICAgICAgICB0aGlzLnVwY29taW5nU3RhdGUubmV4dChEYXNoYm9hcmRTZWN0aW9uU3RhdGUuRVJST1IpO1xyXG4gICAgICAgIHRocm93IGVycm9yO1xyXG4gICAgICB9KVxyXG4gICAgKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIExvYWRzIHRoZSB1c2VyJ3MgZ3JvdXBzLCBkcml2aW5nIHRoZSBncm91cHMgc2VjdGlvbiB0aHJvdWdoXHJcbiAgICogTE9BRElORyDihpIgTE9BREVEL0VNUFRZIG9uIHN1Y2Nlc3MgYW5kIGxlYXZpbmcgdGhlIGNhbGxlciB0byBzZXQgRVJST1Igb25cclxuICAgKiBmYWlsdXJlLiBGb2xsb3dzIHRoZSBgcGlwZShtYXAsIGNhdGNoRXJyb3IodGhyb3cpKWAgcGF0dGVybi5cclxuICAgKlxyXG4gICAqIFRPRE86IFJlcGxhY2UgbW9jayB3aXRoIHJlYWwgQVBJIGNhbGwgd2hlbiBCRSBpcyByZWFkeVxyXG4gICAqIEByZXR1cm4ge09ic2VydmFibGU8RGFzaGJvYXJkTGlzdFJlc3BvbnNlPEdyb3VwUm93W10+Pn0gVGhlIGdyb3VwcyByZXNwb25zZSBlbnZlbG9wZS5cclxuICAgKiBAbWVtYmVyb2YgRGFzaGJvYXJkU2VydmljZVxyXG4gICAqL1xyXG4gIGxvYWRHcm91cHMoKTogT2JzZXJ2YWJsZTxEYXNoYm9hcmRMaXN0UmVzcG9uc2U8R3JvdXBSb3dbXT4+IHtcclxuICAgIHRoaXMuZ3JvdXBzU3RhdGUubmV4dChEYXNoYm9hcmRTZWN0aW9uU3RhdGUuTE9BRElORyk7XHJcbiAgICAvLyBUT0RPOiBSZXBsYWNlIG1vY2sgd2l0aCByZWFsIEFQSSBjYWxsIHdoZW4gQkUgaXMgcmVhZHlcclxuICAgIGNvbnN0IHJlc3BvbnNlJDogT2JzZXJ2YWJsZTxEYXNoYm9hcmRMaXN0UmVzcG9uc2U8R3JvdXBSb3dbXT4+ID0gb2Yoe1xyXG4gICAgICBzdGF0dXM6IHRydWUsXHJcbiAgICAgIGJvZHk6IERhc2hib2FyZEdyb3Vwc01vY2ssXHJcbiAgICB9KTtcclxuICAgIHJldHVybiByZXNwb25zZSQucGlwZShcclxuICAgICAgbWFwKChyZXNwb25zZSkgPT4ge1xyXG4gICAgICAgIGNvbnN0IGdyb3VwcyA9IHJlc3BvbnNlPy5ib2R5ID8/IFtdO1xyXG4gICAgICAgIHRoaXMuZ3JvdXBzLm5leHQoZ3JvdXBzKTtcclxuICAgICAgICB0aGlzLmdyb3Vwc1N0YXRlLm5leHQoXHJcbiAgICAgICAgICBncm91cHMubGVuZ3RoID4gMFxyXG4gICAgICAgICAgICA/IERhc2hib2FyZFNlY3Rpb25TdGF0ZS5MT0FERURcclxuICAgICAgICAgICAgOiBEYXNoYm9hcmRTZWN0aW9uU3RhdGUuRU1QVFlcclxuICAgICAgICApO1xyXG4gICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgfSksXHJcbiAgICAgIGNhdGNoRXJyb3IoKGVycm9yKSA9PiB7XHJcbiAgICAgICAgdGhpcy5ncm91cHNTdGF0ZS5uZXh0KERhc2hib2FyZFNlY3Rpb25TdGF0ZS5FUlJPUik7XHJcbiAgICAgICAgdGhyb3cgZXJyb3I7XHJcbiAgICAgIH0pXHJcbiAgICApO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTG9ncyBhdHRlbmRhbmNlIGZvciBhIG1lZXRpbmcuIE1hcmtzIHRoZSBtZWV0aW5nIGluLWZsaWdodCAocmV0YWluaW5nIHRoZVxyXG4gICAqIHByaW9yIGRpc3BsYXllZCBzdGF0ZSksIHBvc3RzIHRocm91Z2ggYEh0dHBTZXJ2aWNlYCwgYXBwbGllcyB0aGVcclxuICAgKiBsb2ctYXR0ZW5kYW5jZS1zdWNjZXNzIHJlZHVjZXIgb24gc3VjY2VzcywgY2xlYXJzIHRoZSBpbi1mbGlnaHQgZmxhZyBvblxyXG4gICAqIGNvbXBsZXRpb24sIGFuZCByZXRocm93cyB3aGlsZSByZXRhaW5pbmcgcHJpb3Igc3RhdGUgb24gZmFpbHVyZS5cclxuICAgKiBAcGFyYW0ge3N0cmluZ30gbWVldGluZ0lkIC0gVGhlIG1lZXRpbmcgdG8gbG9nIGF0dGVuZGFuY2UgZm9yLlxyXG4gICAqIEByZXR1cm4ge09ic2VydmFibGU8RGFzaGJvYXJkTGlzdFJlc3BvbnNlPHVua25vd24+Pn0gVGhlIGF0dGVuZGFuY2UgcmVzcG9uc2UgZW52ZWxvcGUuXHJcbiAgICogQG1lbWJlcm9mIERhc2hib2FyZFNlcnZpY2VcclxuICAgKi9cclxuICBsb2dBdHRlbmRhbmNlKFxyXG4gICAgbWVldGluZ0lkOiBzdHJpbmdcclxuICApOiBPYnNlcnZhYmxlPERhc2hib2FyZExpc3RSZXNwb25zZTx1bmtub3duPj4ge1xyXG4gICAgdGhpcy5pbkZsaWdodE1lZXRpbmdJZHMubmV4dChcclxuICAgICAgYmVnaW5BdHRlbmRhbmNlQWN0aW9uKHRoaXMuaW5GbGlnaHRNZWV0aW5nSWRzLnZhbHVlLCBtZWV0aW5nSWQpXHJcbiAgICApO1xyXG4gICAgcmV0dXJuIHRoaXMuaHR0cFNlcnZpY2VcclxuICAgICAgLnBvc3REYXRhKGAke3RoaXMuYXBpQmFzZVVybH0vbWVldGluZ3MvYXR0ZW5kYW5jZS9sb2dgLCB7IG1lZXRpbmdJZCB9KVxyXG4gICAgICAucGlwZShcclxuICAgICAgICBtYXAoKHJlc3BvbnNlKSA9PiB7XHJcbiAgICAgICAgICB0aGlzLmF0dGVuZGFuY2VTdGF0ZXMubmV4dChcclxuICAgICAgICAgICAgYXBwbHlMb2dBdHRlbmRhbmNlU3VjY2Vzcyh0aGlzLmF0dGVuZGFuY2VTdGF0ZXMudmFsdWUsIG1lZXRpbmdJZClcclxuICAgICAgICAgICk7XHJcbiAgICAgICAgICB0aGlzLmluRmxpZ2h0TWVldGluZ0lkcy5uZXh0KFxyXG4gICAgICAgICAgICBlbmRBdHRlbmRhbmNlQWN0aW9uKHRoaXMuaW5GbGlnaHRNZWV0aW5nSWRzLnZhbHVlLCBtZWV0aW5nSWQpXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICAgIH0pLFxyXG4gICAgICAgIGNhdGNoRXJyb3IoKGVycm9yKSA9PiB7XHJcbiAgICAgICAgICAvLyBSZXRhaW4gcHJpb3IgYXR0ZW5kYW5jZSBzdGF0ZTsgb25seSBjbGVhciB0aGUgaW4tZmxpZ2h0IGZsYWcuXHJcbiAgICAgICAgICB0aGlzLmluRmxpZ2h0TWVldGluZ0lkcy5uZXh0KFxyXG4gICAgICAgICAgICBlbmRBdHRlbmRhbmNlQWN0aW9uKHRoaXMuaW5GbGlnaHRNZWV0aW5nSWRzLnZhbHVlLCBtZWV0aW5nSWQpXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgdGhyb3cgZXJyb3I7XHJcbiAgICAgICAgfSlcclxuICAgICAgKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIExlYXZlcyBhIG1lZXRpbmcuIE1hcmtzIHRoZSBtZWV0aW5nIGluLWZsaWdodCAocmV0YWluaW5nIHRoZSBwcmlvclxyXG4gICAqIGRpc3BsYXllZCBzdGF0ZSksIHBvc3RzIHRocm91Z2ggYEh0dHBTZXJ2aWNlYCwgYXBwbGllcyB0aGVcclxuICAgKiBsZWF2ZS1tZWV0aW5nLXN1Y2Nlc3MgcmVkdWNlciBvbiBzdWNjZXNzLCBjbGVhcnMgdGhlIGluLWZsaWdodCBmbGFnIG9uXHJcbiAgICogY29tcGxldGlvbiwgYW5kIHJldGhyb3dzIHdoaWxlIHJldGFpbmluZyBwcmlvciBzdGF0ZSBvbiBmYWlsdXJlLlxyXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtZWV0aW5nSWQgLSBUaGUgbWVldGluZyB0byBsZWF2ZS5cclxuICAgKiBAcmV0dXJuIHtPYnNlcnZhYmxlPERhc2hib2FyZExpc3RSZXNwb25zZTx1bmtub3duPj59IFRoZSBhdHRlbmRhbmNlIHJlc3BvbnNlIGVudmVsb3BlLlxyXG4gICAqIEBtZW1iZXJvZiBEYXNoYm9hcmRTZXJ2aWNlXHJcbiAgICovXHJcbiAgbGVhdmVNZWV0aW5nKFxyXG4gICAgbWVldGluZ0lkOiBzdHJpbmdcclxuICApOiBPYnNlcnZhYmxlPERhc2hib2FyZExpc3RSZXNwb25zZTx1bmtub3duPj4ge1xyXG4gICAgdGhpcy5pbkZsaWdodE1lZXRpbmdJZHMubmV4dChcclxuICAgICAgYmVnaW5BdHRlbmRhbmNlQWN0aW9uKHRoaXMuaW5GbGlnaHRNZWV0aW5nSWRzLnZhbHVlLCBtZWV0aW5nSWQpXHJcbiAgICApO1xyXG4gICAgcmV0dXJuIHRoaXMuaHR0cFNlcnZpY2VcclxuICAgICAgLnBvc3REYXRhKGAke3RoaXMuYXBpQmFzZVVybH0vbWVldGluZ3MvYXR0ZW5kYW5jZS9sZWF2ZWAsIHsgbWVldGluZ0lkIH0pXHJcbiAgICAgIC5waXBlKFxyXG4gICAgICAgIG1hcCgocmVzcG9uc2UpID0+IHtcclxuICAgICAgICAgIHRoaXMuYXR0ZW5kYW5jZVN0YXRlcy5uZXh0KFxyXG4gICAgICAgICAgICBhcHBseUxlYXZlTWVldGluZ1N1Y2Nlc3ModGhpcy5hdHRlbmRhbmNlU3RhdGVzLnZhbHVlLCBtZWV0aW5nSWQpXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgdGhpcy5pbkZsaWdodE1lZXRpbmdJZHMubmV4dChcclxuICAgICAgICAgICAgZW5kQXR0ZW5kYW5jZUFjdGlvbih0aGlzLmluRmxpZ2h0TWVldGluZ0lkcy52YWx1ZSwgbWVldGluZ0lkKVxyXG4gICAgICAgICAgKTtcclxuICAgICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgICB9KSxcclxuICAgICAgICBjYXRjaEVycm9yKChlcnJvcikgPT4ge1xyXG4gICAgICAgICAgLy8gUmV0YWluIHByaW9yIGF0dGVuZGFuY2Ugc3RhdGU7IG9ubHkgY2xlYXIgdGhlIGluLWZsaWdodCBmbGFnLlxyXG4gICAgICAgICAgdGhpcy5pbkZsaWdodE1lZXRpbmdJZHMubmV4dChcclxuICAgICAgICAgICAgZW5kQXR0ZW5kYW5jZUFjdGlvbih0aGlzLmluRmxpZ2h0TWVldGluZ0lkcy52YWx1ZSwgbWVldGluZ0lkKVxyXG4gICAgICAgICAgKTtcclxuICAgICAgICAgIHRocm93IGVycm9yO1xyXG4gICAgICAgIH0pXHJcbiAgICAgICk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZXR1cm5zIGEgc3luY2hyb25vdXMgc25hcHNob3Qgb2YgdGhlIHBlci1tZWV0aW5nIGF0dGVuZGFuY2Utc3RhdGUgbWFwLlxyXG4gICAqIEByZXR1cm4ge1JlY29yZDxzdHJpbmcsIEF0dGVuZGFuY2VTdGF0ZT59IFRoZSBjdXJyZW50IGF0dGVuZGFuY2Utc3RhdGUgbWFwLlxyXG4gICAqIEBtZW1iZXJvZiBEYXNoYm9hcmRTZXJ2aWNlXHJcbiAgICovXHJcbiAgZ2V0QXR0ZW5kYW5jZVN0YXRlc1NuYXBzaG90KCk6IFJlY29yZDxzdHJpbmcsIEF0dGVuZGFuY2VTdGF0ZT4ge1xyXG4gICAgcmV0dXJuIHRoaXMuYXR0ZW5kYW5jZVN0YXRlcy52YWx1ZTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFNlZWRzIHRoZSBhdHRlbmRhbmNlLXN0YXRlIG1hcCBmcm9tIGEgZnJlc2hseSBsb2FkZWQgbGlzdCBvZiBldmVudHMsIHVzaW5nXHJcbiAgICogZWFjaCBtZWV0aW5nJ3MgYGF0dGVuZGFuY2VTdGF0ZWAgKGRlZmF1bHRpbmcgdG8gYE5PVF9BVFRFTkRJTkdgKS4gS2VlcHMgdGhlXHJcbiAgICogZGlzcGxheWVkIHN0YXRlIGluIHN5bmMgd2l0aCB0aGUgZGF0YSBsb2FkIHdpdGhvdXQgb3ZlcndyaXRpbmcgaWRzIHRoYXQgYXJlXHJcbiAgICogbm90IHByZXNlbnQgaW4gdGhlIG5ldyBsaXN0LlxyXG4gICAqIEBwYXJhbSB7VXBjb21pbmdFdmVudFtdfSBldmVudHMgLSBUaGUgbG9hZGVkIHVwY29taW5nIGV2ZW50cy5cclxuICAgKiBAcmV0dXJuIHt2b2lkfVxyXG4gICAqIEBtZW1iZXJvZiBEYXNoYm9hcmRTZXJ2aWNlXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBzZWVkQXR0ZW5kYW5jZVN0YXRlcyhldmVudHM6IFVwY29taW5nRXZlbnRbXSk6IHZvaWQge1xyXG4gICAgY29uc3QgbmV4dDogUmVjb3JkPHN0cmluZywgQXR0ZW5kYW5jZVN0YXRlPiA9IHtcclxuICAgICAgLi4udGhpcy5hdHRlbmRhbmNlU3RhdGVzLnZhbHVlLFxyXG4gICAgfTtcclxuICAgIGV2ZW50cy5mb3JFYWNoKChldmVudCkgPT4ge1xyXG4gICAgICBldmVudC5tZWV0aW5ncz8uZm9yRWFjaCgobWVldGluZykgPT4ge1xyXG4gICAgICAgIGlmIChtZWV0aW5nLm1lZXRpbmdJZCkge1xyXG4gICAgICAgICAgbmV4dFttZWV0aW5nLm1lZXRpbmdJZF0gPVxyXG4gICAgICAgICAgICBtZWV0aW5nLmF0dGVuZGFuY2VTdGF0ZSA/PyBBdHRlbmRhbmNlU3RhdGUuTk9UX0FUVEVORElORztcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gICAgfSk7XHJcbiAgICB0aGlzLmF0dGVuZGFuY2VTdGF0ZXMubmV4dChuZXh0KTtcclxuICB9XHJcbn1cclxuIl19
@@ -0,0 +1,50 @@
1
+ import { Injectable } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ /**
4
+ * Permission identifiers (by name) that gate the dashboard attendance actions.
5
+ * Mirrors the permission-type pattern used by the `events-and-meetings` and
6
+ * `groups` user-permissions services.
7
+ */
8
+ /* eslint-disable no-unused-vars */
9
+ export var DashboardPermissionType;
10
+ (function (DashboardPermissionType) {
11
+ DashboardPermissionType["LOG_ATTENDANCE"] = "Log Attendance";
12
+ DashboardPermissionType["LEAVE_MEETING"] = "Leave Meeting";
13
+ })(DashboardPermissionType || (DashboardPermissionType = {}));
14
+ /* eslint-enable no-unused-vars */
15
+ export class UserPermissionsService {
16
+ /**
17
+ * Returns access provision for the passed action/feature based on whether the signed in user has appropriate permission.
18
+ * @param {DashboardPermissionType} permission
19
+ * @param {UserPermission[]} userPermissions
20
+ * @return {boolean}
21
+ * @memberof UserPermissionsService
22
+ */
23
+ validateAccessPermission(permission, userPermissions) {
24
+ const isPermitted = userPermissions?.length > 0
25
+ ? userPermissions?.some(({ permissionName }) => permissionName === permission)
26
+ : false;
27
+ return isPermitted;
28
+ }
29
+ /**
30
+ * Maps the host-supplied user permissions to the attendance-action permissions consumed by the dashboard rows.
31
+ * @param {UserPermission[]} userPermissions
32
+ * @return {AttendanceActionPermissions}
33
+ * @memberof UserPermissionsService
34
+ */
35
+ mapToAttendanceActionPermissions(userPermissions) {
36
+ return {
37
+ canLogAttendance: this.validateAccessPermission(DashboardPermissionType.LOG_ATTENDANCE, userPermissions),
38
+ canLeaveMeeting: this.validateAccessPermission(DashboardPermissionType.LEAVE_MEETING, userPermissions),
39
+ };
40
+ }
41
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: UserPermissionsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
42
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: UserPermissionsService, providedIn: 'root' }); }
43
+ }
44
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: UserPermissionsService, decorators: [{
45
+ type: Injectable,
46
+ args: [{
47
+ providedIn: 'root',
48
+ }]
49
+ }] });
50
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlci1wZXJtaXNzaW9ucy5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZGFzaGJvYXJkL3NyYy9saWIvc2VydmljZXMvdXNlci1wZXJtaXNzaW9ucy5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7O0FBSTNDOzs7O0dBSUc7QUFDSCxtQ0FBbUM7QUFDbkMsTUFBTSxDQUFOLElBQVksdUJBR1g7QUFIRCxXQUFZLHVCQUF1QjtJQUNqQyw0REFBaUMsQ0FBQTtJQUNqQywwREFBK0IsQ0FBQTtBQUNqQyxDQUFDLEVBSFcsdUJBQXVCLEtBQXZCLHVCQUF1QixRQUdsQztBQUNELGtDQUFrQztBQUtsQyxNQUFNLE9BQU8sc0JBQXNCO0lBQ2pDOzs7Ozs7T0FNRztJQUNILHdCQUF3QixDQUN0QixVQUFtQyxFQUNuQyxlQUFpQztRQUVqQyxNQUFNLFdBQVcsR0FDZixlQUFlLEVBQUUsTUFBTSxHQUFHLENBQUM7WUFDekIsQ0FBQyxDQUFDLGVBQWUsRUFBRSxJQUFJLENBQ25CLENBQUMsRUFBRSxjQUFjLEVBQUUsRUFBRSxFQUFFLENBQUMsY0FBYyxLQUFLLFVBQVUsQ0FDdEQ7WUFDSCxDQUFDLENBQUMsS0FBSyxDQUFDO1FBQ1osT0FBTyxXQUFXLENBQUM7SUFDckIsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsZ0NBQWdDLENBQzlCLGVBQWlDO1FBRWpDLE9BQU87WUFDTCxnQkFBZ0IsRUFBRSxJQUFJLENBQUMsd0JBQXdCLENBQzdDLHVCQUF1QixDQUFDLGNBQWMsRUFDdEMsZUFBZSxDQUNoQjtZQUNELGVBQWUsRUFBRSxJQUFJLENBQUMsd0JBQXdCLENBQzVDLHVCQUF1QixDQUFDLGFBQWEsRUFDckMsZUFBZSxDQUNoQjtTQUNGLENBQUM7SUFDSixDQUFDOytHQXhDVSxzQkFBc0I7bUhBQXRCLHNCQUFzQixjQUZyQixNQUFNOzs0RkFFUCxzQkFBc0I7a0JBSGxDLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBVc2VyUGVybWlzc2lvbiB9IGZyb20gJ0BpZWVlc2EtbnBtL21vZGVscyc7XHJcbmltcG9ydCB7IEF0dGVuZGFuY2VBY3Rpb25QZXJtaXNzaW9ucyB9IGZyb20gJy4uL21vZGVscy9hdHRlbmRhbmNlLWFjdGlvbi1wZXJtaXNzaW9ucy5tb2RlbCc7XHJcblxyXG4vKipcclxuICogUGVybWlzc2lvbiBpZGVudGlmaWVycyAoYnkgbmFtZSkgdGhhdCBnYXRlIHRoZSBkYXNoYm9hcmQgYXR0ZW5kYW5jZSBhY3Rpb25zLlxyXG4gKiBNaXJyb3JzIHRoZSBwZXJtaXNzaW9uLXR5cGUgcGF0dGVybiB1c2VkIGJ5IHRoZSBgZXZlbnRzLWFuZC1tZWV0aW5nc2AgYW5kXHJcbiAqIGBncm91cHNgIHVzZXItcGVybWlzc2lvbnMgc2VydmljZXMuXHJcbiAqL1xyXG4vKiBlc2xpbnQtZGlzYWJsZSBuby11bnVzZWQtdmFycyAqL1xyXG5leHBvcnQgZW51bSBEYXNoYm9hcmRQZXJtaXNzaW9uVHlwZSB7XHJcbiAgTE9HX0FUVEVOREFOQ0UgPSAnTG9nIEF0dGVuZGFuY2UnLFxyXG4gIExFQVZFX01FRVRJTkcgPSAnTGVhdmUgTWVldGluZycsXHJcbn1cclxuLyogZXNsaW50LWVuYWJsZSBuby11bnVzZWQtdmFycyAqL1xyXG5cclxuQEluamVjdGFibGUoe1xyXG4gIHByb3ZpZGVkSW46ICdyb290JyxcclxufSlcclxuZXhwb3J0IGNsYXNzIFVzZXJQZXJtaXNzaW9uc1NlcnZpY2Uge1xyXG4gIC8qKlxyXG4gICAqIFJldHVybnMgYWNjZXNzIHByb3Zpc2lvbiBmb3IgdGhlIHBhc3NlZCBhY3Rpb24vZmVhdHVyZSBiYXNlZCBvbiB3aGV0aGVyIHRoZSBzaWduZWQgaW4gdXNlciBoYXMgYXBwcm9wcmlhdGUgcGVybWlzc2lvbi5cclxuICAgKiBAcGFyYW0ge0Rhc2hib2FyZFBlcm1pc3Npb25UeXBlfSBwZXJtaXNzaW9uXHJcbiAgICogQHBhcmFtIHtVc2VyUGVybWlzc2lvbltdfSB1c2VyUGVybWlzc2lvbnNcclxuICAgKiBAcmV0dXJuIHtib29sZWFufVxyXG4gICAqIEBtZW1iZXJvZiBVc2VyUGVybWlzc2lvbnNTZXJ2aWNlXHJcbiAgICovXHJcbiAgdmFsaWRhdGVBY2Nlc3NQZXJtaXNzaW9uKFxyXG4gICAgcGVybWlzc2lvbjogRGFzaGJvYXJkUGVybWlzc2lvblR5cGUsXHJcbiAgICB1c2VyUGVybWlzc2lvbnM6IFVzZXJQZXJtaXNzaW9uW11cclxuICApOiBib29sZWFuIHtcclxuICAgIGNvbnN0IGlzUGVybWl0dGVkID1cclxuICAgICAgdXNlclBlcm1pc3Npb25zPy5sZW5ndGggPiAwXHJcbiAgICAgICAgPyB1c2VyUGVybWlzc2lvbnM/LnNvbWUoXHJcbiAgICAgICAgICAgICh7IHBlcm1pc3Npb25OYW1lIH0pID0+IHBlcm1pc3Npb25OYW1lID09PSBwZXJtaXNzaW9uXHJcbiAgICAgICAgICApXHJcbiAgICAgICAgOiBmYWxzZTtcclxuICAgIHJldHVybiBpc1Blcm1pdHRlZDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIE1hcHMgdGhlIGhvc3Qtc3VwcGxpZWQgdXNlciBwZXJtaXNzaW9ucyB0byB0aGUgYXR0ZW5kYW5jZS1hY3Rpb24gcGVybWlzc2lvbnMgY29uc3VtZWQgYnkgdGhlIGRhc2hib2FyZCByb3dzLlxyXG4gICAqIEBwYXJhbSB7VXNlclBlcm1pc3Npb25bXX0gdXNlclBlcm1pc3Npb25zXHJcbiAgICogQHJldHVybiB7QXR0ZW5kYW5jZUFjdGlvblBlcm1pc3Npb25zfVxyXG4gICAqIEBtZW1iZXJvZiBVc2VyUGVybWlzc2lvbnNTZXJ2aWNlXHJcbiAgICovXHJcbiAgbWFwVG9BdHRlbmRhbmNlQWN0aW9uUGVybWlzc2lvbnMoXHJcbiAgICB1c2VyUGVybWlzc2lvbnM6IFVzZXJQZXJtaXNzaW9uW11cclxuICApOiBBdHRlbmRhbmNlQWN0aW9uUGVybWlzc2lvbnMge1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgY2FuTG9nQXR0ZW5kYW5jZTogdGhpcy52YWxpZGF0ZUFjY2Vzc1Blcm1pc3Npb24oXHJcbiAgICAgICAgRGFzaGJvYXJkUGVybWlzc2lvblR5cGUuTE9HX0FUVEVOREFOQ0UsXHJcbiAgICAgICAgdXNlclBlcm1pc3Npb25zXHJcbiAgICAgICksXHJcbiAgICAgIGNhbkxlYXZlTWVldGluZzogdGhpcy52YWxpZGF0ZUFjY2Vzc1Blcm1pc3Npb24oXHJcbiAgICAgICAgRGFzaGJvYXJkUGVybWlzc2lvblR5cGUuTEVBVkVfTUVFVElORyxcclxuICAgICAgICB1c2VyUGVybWlzc2lvbnNcclxuICAgICAgKSxcclxuICAgIH07XHJcbiAgfVxyXG59XHJcbiJdfQ==
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Pure helpers for the per-meeting attendance action state machine. No Angular /
3
+ * service dependencies so they are trivially testable (property-tested as
4
+ * Property 1) and reusable by `MeetingAttendanceRowComponent`.
5
+ *
6
+ * The handler is the single source of truth for what a meeting row's action
7
+ * button should emit when activated. The displayed `AttendanceState` only
8
+ * advances on a successful resolution (handled by the service reducers), so this
9
+ * function is a pure mapping from the current inputs to the action to emit.
10
+ */
11
+ import { AttendanceState } from '../models/attendance-state.model';
12
+ /* eslint-disable no-unused-vars */
13
+ /**
14
+ * The action a meeting row's action button should emit when activated.
15
+ * `NONE` means the activation is non-actionable (empty id or in-flight) and the
16
+ * row must emit no `logAttendance` / `leaveMeeting` / navigation event.
17
+ */
18
+ export var AttendanceAction;
19
+ (function (AttendanceAction) {
20
+ AttendanceAction["LOG_ATTENDANCE"] = "LOG_ATTENDANCE";
21
+ AttendanceAction["LEAVE_MEETING"] = "LEAVE_MEETING";
22
+ AttendanceAction["NONE"] = "NONE";
23
+ })(AttendanceAction || (AttendanceAction = {}));
24
+ /* eslint-enable no-unused-vars */
25
+ /**
26
+ * Resolves the attendance action to emit for a meeting row, following the
27
+ * attendance action state machine (see design: Attendance Action State Machine).
28
+ *
29
+ * Behavior:
30
+ * - Returns `NONE` when `meetingId` is empty or undefined (non-actionable row).
31
+ * - Returns `NONE` while the row is in-flight (re-entrancy guard — no further
32
+ * event is emitted until the current action resolves).
33
+ * - Returns `LEAVE_MEETING` when the state is `CURRENTLY_ATTENDING`.
34
+ * - Returns `LOG_ATTENDANCE` when the state is `NOT_ATTENDING` or undefined.
35
+ *
36
+ * @param {AttendanceState | undefined} attendanceState The row's current attendance state.
37
+ * @param {boolean} isInFlight Whether an attendance action for this row is awaiting resolution.
38
+ * @param {string | undefined} meetingId The row's meeting identifier.
39
+ * @return {AttendanceAction} The action to emit, or `NONE` when non-actionable.
40
+ */
41
+ export function resolveAttendanceAction(attendanceState, isInFlight, meetingId) {
42
+ if (!meetingId) {
43
+ return AttendanceAction.NONE;
44
+ }
45
+ if (isInFlight) {
46
+ return AttendanceAction.NONE;
47
+ }
48
+ if (attendanceState === AttendanceState.CURRENTLY_ATTENDING) {
49
+ return AttendanceAction.LEAVE_MEETING;
50
+ }
51
+ return AttendanceAction.LOG_ATTENDANCE;
52
+ }
53
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXR0ZW5kYW5jZS1hY3Rpb24udXRpbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Rhc2hib2FyZC9zcmMvbGliL3V0aWxzL2F0dGVuZGFuY2UtYWN0aW9uLnV0aWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7OztHQVNHO0FBQ0gsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBRW5FLG1DQUFtQztBQUNuQzs7OztHQUlHO0FBQ0gsTUFBTSxDQUFOLElBQVksZ0JBSVg7QUFKRCxXQUFZLGdCQUFnQjtJQUMxQixxREFBaUMsQ0FBQTtJQUNqQyxtREFBK0IsQ0FBQTtJQUMvQixpQ0FBYSxDQUFBO0FBQ2YsQ0FBQyxFQUpXLGdCQUFnQixLQUFoQixnQkFBZ0IsUUFJM0I7QUFDRCxrQ0FBa0M7QUFFbEM7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBQ0gsTUFBTSxVQUFVLHVCQUF1QixDQUNyQyxlQUE0QyxFQUM1QyxVQUFtQixFQUNuQixTQUE2QjtJQUU3QixJQUFJLENBQUMsU0FBUyxFQUFFO1FBQ2QsT0FBTyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUM7S0FDOUI7SUFFRCxJQUFJLFVBQVUsRUFBRTtRQUNkLE9BQU8sZ0JBQWdCLENBQUMsSUFBSSxDQUFDO0tBQzlCO0lBRUQsSUFBSSxlQUFlLEtBQUssZUFBZSxDQUFDLG1CQUFtQixFQUFFO1FBQzNELE9BQU8sZ0JBQWdCLENBQUMsYUFBYSxDQUFDO0tBQ3ZDO0lBRUQsT0FBTyxnQkFBZ0IsQ0FBQyxjQUFjLENBQUM7QUFDekMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxyXG4gKiBQdXJlIGhlbHBlcnMgZm9yIHRoZSBwZXItbWVldGluZyBhdHRlbmRhbmNlIGFjdGlvbiBzdGF0ZSBtYWNoaW5lLiBObyBBbmd1bGFyIC9cclxuICogc2VydmljZSBkZXBlbmRlbmNpZXMgc28gdGhleSBhcmUgdHJpdmlhbGx5IHRlc3RhYmxlIChwcm9wZXJ0eS10ZXN0ZWQgYXNcclxuICogUHJvcGVydHkgMSkgYW5kIHJldXNhYmxlIGJ5IGBNZWV0aW5nQXR0ZW5kYW5jZVJvd0NvbXBvbmVudGAuXHJcbiAqXHJcbiAqIFRoZSBoYW5kbGVyIGlzIHRoZSBzaW5nbGUgc291cmNlIG9mIHRydXRoIGZvciB3aGF0IGEgbWVldGluZyByb3cncyBhY3Rpb25cclxuICogYnV0dG9uIHNob3VsZCBlbWl0IHdoZW4gYWN0aXZhdGVkLiBUaGUgZGlzcGxheWVkIGBBdHRlbmRhbmNlU3RhdGVgIG9ubHlcclxuICogYWR2YW5jZXMgb24gYSBzdWNjZXNzZnVsIHJlc29sdXRpb24gKGhhbmRsZWQgYnkgdGhlIHNlcnZpY2UgcmVkdWNlcnMpLCBzbyB0aGlzXHJcbiAqIGZ1bmN0aW9uIGlzIGEgcHVyZSBtYXBwaW5nIGZyb20gdGhlIGN1cnJlbnQgaW5wdXRzIHRvIHRoZSBhY3Rpb24gdG8gZW1pdC5cclxuICovXHJcbmltcG9ydCB7IEF0dGVuZGFuY2VTdGF0ZSB9IGZyb20gJy4uL21vZGVscy9hdHRlbmRhbmNlLXN0YXRlLm1vZGVsJztcclxuXHJcbi8qIGVzbGludC1kaXNhYmxlIG5vLXVudXNlZC12YXJzICovXHJcbi8qKlxyXG4gKiBUaGUgYWN0aW9uIGEgbWVldGluZyByb3cncyBhY3Rpb24gYnV0dG9uIHNob3VsZCBlbWl0IHdoZW4gYWN0aXZhdGVkLlxyXG4gKiBgTk9ORWAgbWVhbnMgdGhlIGFjdGl2YXRpb24gaXMgbm9uLWFjdGlvbmFibGUgKGVtcHR5IGlkIG9yIGluLWZsaWdodCkgYW5kIHRoZVxyXG4gKiByb3cgbXVzdCBlbWl0IG5vIGBsb2dBdHRlbmRhbmNlYCAvIGBsZWF2ZU1lZXRpbmdgIC8gbmF2aWdhdGlvbiBldmVudC5cclxuICovXHJcbmV4cG9ydCBlbnVtIEF0dGVuZGFuY2VBY3Rpb24ge1xyXG4gIExPR19BVFRFTkRBTkNFID0gJ0xPR19BVFRFTkRBTkNFJyxcclxuICBMRUFWRV9NRUVUSU5HID0gJ0xFQVZFX01FRVRJTkcnLFxyXG4gIE5PTkUgPSAnTk9ORScsXHJcbn1cclxuLyogZXNsaW50LWVuYWJsZSBuby11bnVzZWQtdmFycyAqL1xyXG5cclxuLyoqXHJcbiAqIFJlc29sdmVzIHRoZSBhdHRlbmRhbmNlIGFjdGlvbiB0byBlbWl0IGZvciBhIG1lZXRpbmcgcm93LCBmb2xsb3dpbmcgdGhlXHJcbiAqIGF0dGVuZGFuY2UgYWN0aW9uIHN0YXRlIG1hY2hpbmUgKHNlZSBkZXNpZ246IEF0dGVuZGFuY2UgQWN0aW9uIFN0YXRlIE1hY2hpbmUpLlxyXG4gKlxyXG4gKiBCZWhhdmlvcjpcclxuICogLSBSZXR1cm5zIGBOT05FYCB3aGVuIGBtZWV0aW5nSWRgIGlzIGVtcHR5IG9yIHVuZGVmaW5lZCAobm9uLWFjdGlvbmFibGUgcm93KS5cclxuICogLSBSZXR1cm5zIGBOT05FYCB3aGlsZSB0aGUgcm93IGlzIGluLWZsaWdodCAocmUtZW50cmFuY3kgZ3VhcmQg4oCUIG5vIGZ1cnRoZXJcclxuICogICBldmVudCBpcyBlbWl0dGVkIHVudGlsIHRoZSBjdXJyZW50IGFjdGlvbiByZXNvbHZlcykuXHJcbiAqIC0gUmV0dXJucyBgTEVBVkVfTUVFVElOR2Agd2hlbiB0aGUgc3RhdGUgaXMgYENVUlJFTlRMWV9BVFRFTkRJTkdgLlxyXG4gKiAtIFJldHVybnMgYExPR19BVFRFTkRBTkNFYCB3aGVuIHRoZSBzdGF0ZSBpcyBgTk9UX0FUVEVORElOR2Agb3IgdW5kZWZpbmVkLlxyXG4gKlxyXG4gKiBAcGFyYW0ge0F0dGVuZGFuY2VTdGF0ZSB8IHVuZGVmaW5lZH0gYXR0ZW5kYW5jZVN0YXRlIFRoZSByb3cncyBjdXJyZW50IGF0dGVuZGFuY2Ugc3RhdGUuXHJcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gaXNJbkZsaWdodCBXaGV0aGVyIGFuIGF0dGVuZGFuY2UgYWN0aW9uIGZvciB0aGlzIHJvdyBpcyBhd2FpdGluZyByZXNvbHV0aW9uLlxyXG4gKiBAcGFyYW0ge3N0cmluZyB8IHVuZGVmaW5lZH0gbWVldGluZ0lkIFRoZSByb3cncyBtZWV0aW5nIGlkZW50aWZpZXIuXHJcbiAqIEByZXR1cm4ge0F0dGVuZGFuY2VBY3Rpb259IFRoZSBhY3Rpb24gdG8gZW1pdCwgb3IgYE5PTkVgIHdoZW4gbm9uLWFjdGlvbmFibGUuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZUF0dGVuZGFuY2VBY3Rpb24oXHJcbiAgYXR0ZW5kYW5jZVN0YXRlOiBBdHRlbmRhbmNlU3RhdGUgfCB1bmRlZmluZWQsXHJcbiAgaXNJbkZsaWdodDogYm9vbGVhbixcclxuICBtZWV0aW5nSWQ6IHN0cmluZyB8IHVuZGVmaW5lZFxyXG4pOiBBdHRlbmRhbmNlQWN0aW9uIHtcclxuICBpZiAoIW1lZXRpbmdJZCkge1xyXG4gICAgcmV0dXJuIEF0dGVuZGFuY2VBY3Rpb24uTk9ORTtcclxuICB9XHJcblxyXG4gIGlmIChpc0luRmxpZ2h0KSB7XHJcbiAgICByZXR1cm4gQXR0ZW5kYW5jZUFjdGlvbi5OT05FO1xyXG4gIH1cclxuXHJcbiAgaWYgKGF0dGVuZGFuY2VTdGF0ZSA9PT0gQXR0ZW5kYW5jZVN0YXRlLkNVUlJFTlRMWV9BVFRFTkRJTkcpIHtcclxuICAgIHJldHVybiBBdHRlbmRhbmNlQWN0aW9uLkxFQVZFX01FRVRJTkc7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gQXR0ZW5kYW5jZUFjdGlvbi5MT0dfQVRURU5EQU5DRTtcclxufVxyXG4iXX0=
@@ -0,0 +1,34 @@
1
+ /*
2
+ * Public API Surface of dashboard
3
+ */
4
+ // Container component + navigation intent type (DashboardComponent, DashboardNavigationIntent)
5
+ export * from './lib/dashboard.component';
6
+ // Child components
7
+ export * from './lib/components/welcome-header/dashboard-welcome-header.component';
8
+ export * from './lib/components/upcoming-meetings-events/upcoming-meetings-events.component';
9
+ export * from './lib/components/event-group-card/event-group-card.component';
10
+ export * from './lib/components/meeting-attendance-row/meeting-attendance-row.component';
11
+ export * from './lib/components/your-groups/your-groups.component';
12
+ export * from './lib/components/member-level-badge/member-level-badge.component';
13
+ // Module + routes
14
+ export * from './lib/dashboard.module';
15
+ export * from './lib/dashboard.routes';
16
+ // Models
17
+ export * from './lib/models/dashboard-route-config.model';
18
+ export * from './lib/models/attendance-state.model';
19
+ export * from './lib/models/dashboard-section-state.model';
20
+ export * from './lib/models/page-change.model';
21
+ export * from './lib/models/dashboard-user-info.model';
22
+ export * from './lib/models/meeting-row.model';
23
+ export * from './lib/models/upcoming-event.model';
24
+ export * from './lib/models/group-row.model';
25
+ export * from './lib/models/attendance-action-permissions.model';
26
+ export * from './lib/models/dashboard-list-response.model';
27
+ // Services
28
+ export * from './lib/services/dashboard.service';
29
+ export * from './lib/services/user-permissions.service';
30
+ // Asset mocks consumed by the demo app
31
+ export * from './lib/assets/dashboard-route-paths.mock';
32
+ export * from './lib/assets/dashboard-user-permissions.mock';
33
+ export * from './lib/assets/dashboard-mock';
34
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljLWFwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Byb2plY3RzL2Rhc2hib2FyZC9zcmMvcHVibGljLWFwaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUVILCtGQUErRjtBQUMvRixjQUFjLDJCQUEyQixDQUFDO0FBRTFDLG1CQUFtQjtBQUNuQixjQUFjLG9FQUFvRSxDQUFDO0FBQ25GLGNBQWMsOEVBQThFLENBQUM7QUFDN0YsY0FBYyw4REFBOEQsQ0FBQztBQUM3RSxjQUFjLDBFQUEwRSxDQUFDO0FBQ3pGLGNBQWMsb0RBQW9ELENBQUM7QUFDbkUsY0FBYyxrRUFBa0UsQ0FBQztBQUVqRixrQkFBa0I7QUFDbEIsY0FBYyx3QkFBd0IsQ0FBQztBQUN2QyxjQUFjLHdCQUF3QixDQUFDO0FBRXZDLFNBQVM7QUFDVCxjQUFjLDJDQUEyQyxDQUFDO0FBQzFELGNBQWMscUNBQXFDLENBQUM7QUFDcEQsY0FBYyw0Q0FBNEMsQ0FBQztBQUMzRCxjQUFjLGdDQUFnQyxDQUFDO0FBQy9DLGNBQWMsd0NBQXdDLENBQUM7QUFDdkQsY0FBYyxnQ0FBZ0MsQ0FBQztBQUMvQyxjQUFjLG1DQUFtQyxDQUFDO0FBQ2xELGNBQWMsOEJBQThCLENBQUM7QUFDN0MsY0FBYyxrREFBa0QsQ0FBQztBQUNqRSxjQUFjLDRDQUE0QyxDQUFDO0FBRTNELFdBQVc7QUFDWCxjQUFjLGtDQUFrQyxDQUFDO0FBQ2pELGNBQWMseUNBQXlDLENBQUM7QUFFeEQsdUNBQXVDO0FBQ3ZDLGNBQWMseUNBQXlDLENBQUM7QUFDeEQsY0FBYyw4Q0FBOEMsQ0FBQztBQUM3RCxjQUFjLDZCQUE2QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLypcclxuICogUHVibGljIEFQSSBTdXJmYWNlIG9mIGRhc2hib2FyZFxyXG4gKi9cclxuXHJcbi8vIENvbnRhaW5lciBjb21wb25lbnQgKyBuYXZpZ2F0aW9uIGludGVudCB0eXBlIChEYXNoYm9hcmRDb21wb25lbnQsIERhc2hib2FyZE5hdmlnYXRpb25JbnRlbnQpXHJcbmV4cG9ydCAqIGZyb20gJy4vbGliL2Rhc2hib2FyZC5jb21wb25lbnQnO1xyXG5cclxuLy8gQ2hpbGQgY29tcG9uZW50c1xyXG5leHBvcnQgKiBmcm9tICcuL2xpYi9jb21wb25lbnRzL3dlbGNvbWUtaGVhZGVyL2Rhc2hib2FyZC13ZWxjb21lLWhlYWRlci5jb21wb25lbnQnO1xyXG5leHBvcnQgKiBmcm9tICcuL2xpYi9jb21wb25lbnRzL3VwY29taW5nLW1lZXRpbmdzLWV2ZW50cy91cGNvbWluZy1tZWV0aW5ncy1ldmVudHMuY29tcG9uZW50JztcclxuZXhwb3J0ICogZnJvbSAnLi9saWIvY29tcG9uZW50cy9ldmVudC1ncm91cC1jYXJkL2V2ZW50LWdyb3VwLWNhcmQuY29tcG9uZW50JztcclxuZXhwb3J0ICogZnJvbSAnLi9saWIvY29tcG9uZW50cy9tZWV0aW5nLWF0dGVuZGFuY2Utcm93L21lZXRpbmctYXR0ZW5kYW5jZS1yb3cuY29tcG9uZW50JztcclxuZXhwb3J0ICogZnJvbSAnLi9saWIvY29tcG9uZW50cy95b3VyLWdyb3Vwcy95b3VyLWdyb3Vwcy5jb21wb25lbnQnO1xyXG5leHBvcnQgKiBmcm9tICcuL2xpYi9jb21wb25lbnRzL21lbWJlci1sZXZlbC1iYWRnZS9tZW1iZXItbGV2ZWwtYmFkZ2UuY29tcG9uZW50JztcclxuXHJcbi8vIE1vZHVsZSArIHJvdXRlc1xyXG5leHBvcnQgKiBmcm9tICcuL2xpYi9kYXNoYm9hcmQubW9kdWxlJztcclxuZXhwb3J0ICogZnJvbSAnLi9saWIvZGFzaGJvYXJkLnJvdXRlcyc7XHJcblxyXG4vLyBNb2RlbHNcclxuZXhwb3J0ICogZnJvbSAnLi9saWIvbW9kZWxzL2Rhc2hib2FyZC1yb3V0ZS1jb25maWcubW9kZWwnO1xyXG5leHBvcnQgKiBmcm9tICcuL2xpYi9tb2RlbHMvYXR0ZW5kYW5jZS1zdGF0ZS5tb2RlbCc7XHJcbmV4cG9ydCAqIGZyb20gJy4vbGliL21vZGVscy9kYXNoYm9hcmQtc2VjdGlvbi1zdGF0ZS5tb2RlbCc7XHJcbmV4cG9ydCAqIGZyb20gJy4vbGliL21vZGVscy9wYWdlLWNoYW5nZS5tb2RlbCc7XHJcbmV4cG9ydCAqIGZyb20gJy4vbGliL21vZGVscy9kYXNoYm9hcmQtdXNlci1pbmZvLm1vZGVsJztcclxuZXhwb3J0ICogZnJvbSAnLi9saWIvbW9kZWxzL21lZXRpbmctcm93Lm1vZGVsJztcclxuZXhwb3J0ICogZnJvbSAnLi9saWIvbW9kZWxzL3VwY29taW5nLWV2ZW50Lm1vZGVsJztcclxuZXhwb3J0ICogZnJvbSAnLi9saWIvbW9kZWxzL2dyb3VwLXJvdy5tb2RlbCc7XHJcbmV4cG9ydCAqIGZyb20gJy4vbGliL21vZGVscy9hdHRlbmRhbmNlLWFjdGlvbi1wZXJtaXNzaW9ucy5tb2RlbCc7XHJcbmV4cG9ydCAqIGZyb20gJy4vbGliL21vZGVscy9kYXNoYm9hcmQtbGlzdC1yZXNwb25zZS5tb2RlbCc7XHJcblxyXG4vLyBTZXJ2aWNlc1xyXG5leHBvcnQgKiBmcm9tICcuL2xpYi9zZXJ2aWNlcy9kYXNoYm9hcmQuc2VydmljZSc7XHJcbmV4cG9ydCAqIGZyb20gJy4vbGliL3NlcnZpY2VzL3VzZXItcGVybWlzc2lvbnMuc2VydmljZSc7XHJcblxyXG4vLyBBc3NldCBtb2NrcyBjb25zdW1lZCBieSB0aGUgZGVtbyBhcHBcclxuZXhwb3J0ICogZnJvbSAnLi9saWIvYXNzZXRzL2Rhc2hib2FyZC1yb3V0ZS1wYXRocy5tb2NrJztcclxuZXhwb3J0ICogZnJvbSAnLi9saWIvYXNzZXRzL2Rhc2hib2FyZC11c2VyLXBlcm1pc3Npb25zLm1vY2snO1xyXG5leHBvcnQgKiBmcm9tICcuL2xpYi9hc3NldHMvZGFzaGJvYXJkLW1vY2snO1xyXG4iXX0=