@headless-lms/core 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (205) hide show
  1. package/dist/assets/events.d.ts +9 -9
  2. package/dist/assets/index.d.ts +3 -2
  3. package/dist/assets/index.js +2 -1
  4. package/dist/assets/jobs.d.ts +15 -0
  5. package/dist/assets/jobs.js +30 -0
  6. package/dist/assets/jobs.js.map +1 -0
  7. package/dist/assets/ports.d.ts +4 -3
  8. package/dist/assets/service.d.ts +0 -1
  9. package/dist/assets/service.js +0 -4
  10. package/dist/assets/service.js.map +1 -1
  11. package/dist/automations/actions.js +2 -63
  12. package/dist/automations/actions.js.map +1 -1
  13. package/dist/automations/catalog.d.ts +1 -2
  14. package/dist/automations/catalog.js +69 -62
  15. package/dist/automations/catalog.js.map +1 -1
  16. package/dist/automations/community-derivations.js +4 -4
  17. package/dist/automations/community-derivations.js.map +1 -1
  18. package/dist/automations/community-mail.d.ts +3 -17
  19. package/dist/automations/community-mail.js +1 -21
  20. package/dist/automations/community-mail.js.map +1 -1
  21. package/dist/automations/events.d.ts +0 -10
  22. package/dist/automations/index.d.ts +11 -4
  23. package/dist/automations/index.js +8 -1
  24. package/dist/automations/notifications/debounce.d.ts +25 -0
  25. package/dist/automations/notifications/debounce.js +93 -0
  26. package/dist/automations/notifications/debounce.js.map +1 -0
  27. package/dist/automations/notifications/defaults.d.ts +8 -0
  28. package/dist/automations/notifications/defaults.js +316 -0
  29. package/dist/automations/notifications/defaults.js.map +1 -0
  30. package/dist/automations/notifications/delivery.d.ts +28 -0
  31. package/dist/automations/notifications/delivery.js +88 -0
  32. package/dist/automations/notifications/delivery.js.map +1 -0
  33. package/dist/automations/notifications/processor.d.ts +64 -0
  34. package/dist/automations/notifications/processor.js +270 -0
  35. package/dist/automations/notifications/processor.js.map +1 -0
  36. package/dist/automations/notifications/rules/content.d.ts +6 -0
  37. package/dist/automations/notifications/rules/content.js +39 -0
  38. package/dist/automations/notifications/rules/content.js.map +1 -0
  39. package/dist/automations/notifications/rules/discussion.d.ts +7 -0
  40. package/dist/automations/notifications/rules/discussion.js +678 -0
  41. package/dist/automations/notifications/rules/discussion.js.map +1 -0
  42. package/dist/automations/notifications/rules/entitlements.d.ts +6 -0
  43. package/dist/automations/notifications/rules/entitlements.js +249 -0
  44. package/dist/automations/notifications/rules/entitlements.js.map +1 -0
  45. package/dist/automations/notifications/rules/index.d.ts +6 -0
  46. package/dist/automations/notifications/rules/index.js +15 -0
  47. package/dist/automations/notifications/rules/index.js.map +1 -0
  48. package/dist/automations/notifications/rules/organizations.d.ts +6 -0
  49. package/dist/automations/notifications/rules/organizations.js +28 -0
  50. package/dist/automations/notifications/rules/organizations.js.map +1 -0
  51. package/dist/automations/notifications/rules/recipients.d.ts +32 -0
  52. package/dist/automations/notifications/rules/recipients.js +99 -0
  53. package/dist/automations/notifications/rules/recipients.js.map +1 -0
  54. package/dist/automations/notifications/service.d.ts +27 -0
  55. package/dist/automations/notifications/service.js +45 -0
  56. package/dist/automations/notifications/service.js.map +1 -0
  57. package/dist/automations/notifications/types.d.ts +7 -0
  58. package/dist/automations/notifications/types.js +473 -0
  59. package/dist/automations/notifications/types.js.map +1 -0
  60. package/dist/automations/ports.d.ts +119 -5
  61. package/dist/automations/service.d.ts +10 -13
  62. package/dist/automations/service.js +21 -83
  63. package/dist/automations/service.js.map +1 -1
  64. package/dist/content/events.d.ts +130 -80
  65. package/dist/content/events.js +11 -0
  66. package/dist/content/events.js.map +1 -1
  67. package/dist/content/index.d.ts +6 -4
  68. package/dist/content/index.js +3 -1
  69. package/dist/content/model.d.ts +2 -2
  70. package/dist/content/notification-categories.d.ts +36 -0
  71. package/dist/content/notification-categories.js +64 -0
  72. package/dist/content/notification-categories.js.map +1 -0
  73. package/dist/content/ports.d.ts +25 -6
  74. package/dist/content/service.d.ts +4 -4
  75. package/dist/content/service.js +24 -8
  76. package/dist/content/service.js.map +1 -1
  77. package/dist/content/titles.d.ts +22 -0
  78. package/dist/content/titles.js +69 -0
  79. package/dist/content/titles.js.map +1 -0
  80. package/dist/content/types.d.ts +2 -2
  81. package/dist/discussion/chats.d.ts +9 -4
  82. package/dist/discussion/chats.js +80 -47
  83. package/dist/discussion/chats.js.map +1 -1
  84. package/dist/discussion/digests.d.ts +24 -0
  85. package/dist/discussion/digests.js +104 -0
  86. package/dist/discussion/digests.js.map +1 -0
  87. package/dist/discussion/events.d.ts +194 -28
  88. package/dist/discussion/events.js +74 -17
  89. package/dist/discussion/events.js.map +1 -1
  90. package/dist/discussion/index.d.ts +7 -2
  91. package/dist/discussion/index.js +6 -1
  92. package/dist/discussion/jobs.d.ts +16 -0
  93. package/dist/discussion/jobs.js +40 -0
  94. package/dist/discussion/jobs.js.map +1 -0
  95. package/dist/discussion/mentions.d.ts +11 -0
  96. package/dist/discussion/mentions.js +35 -0
  97. package/dist/discussion/mentions.js.map +1 -0
  98. package/dist/discussion/ports.d.ts +107 -24
  99. package/dist/discussion/ports.js.map +1 -1
  100. package/dist/discussion/posts.d.ts +18 -8
  101. package/dist/discussion/posts.js +207 -155
  102. package/dist/discussion/posts.js.map +1 -1
  103. package/dist/discussion/service.d.ts +17 -8
  104. package/dist/discussion/service.js +105 -41
  105. package/dist/discussion/service.js.map +1 -1
  106. package/dist/discussion/subscriptions.d.ts +37 -0
  107. package/dist/discussion/subscriptions.js +99 -0
  108. package/dist/discussion/subscriptions.js.map +1 -0
  109. package/dist/discussion/titles.d.ts +26 -0
  110. package/dist/discussion/titles.js +84 -0
  111. package/dist/discussion/titles.js.map +1 -0
  112. package/dist/entitlements/events.d.ts +20 -20
  113. package/dist/entitlements/index.d.ts +2 -1
  114. package/dist/entitlements/index.js +2 -1
  115. package/dist/entitlements/jobs.d.ts +12 -0
  116. package/dist/entitlements/jobs.js +18 -0
  117. package/dist/entitlements/jobs.js.map +1 -0
  118. package/dist/entitlements/ports.d.ts +7 -3
  119. package/dist/entitlements/service.d.ts +5 -2
  120. package/dist/entitlements/service.js +23 -3
  121. package/dist/entitlements/service.js.map +1 -1
  122. package/dist/identity/devices.d.ts +30 -0
  123. package/dist/identity/devices.js +107 -0
  124. package/dist/identity/devices.js.map +1 -0
  125. package/dist/identity/events.d.ts +2 -2
  126. package/dist/identity/index.d.ts +5 -4
  127. package/dist/identity/index.js +3 -2
  128. package/dist/identity/model.d.ts +2 -2
  129. package/dist/identity/notification-settings.d.ts +28 -0
  130. package/dist/identity/notification-settings.js +113 -0
  131. package/dist/identity/notification-settings.js.map +1 -0
  132. package/dist/identity/ports.d.ts +78 -54
  133. package/dist/integrations/events.d.ts +3 -3
  134. package/dist/organizations/events.d.ts +32 -32
  135. package/dist/organizations/index.d.ts +2 -1
  136. package/dist/organizations/index.js +2 -1
  137. package/dist/organizations/notification-categories.d.ts +32 -0
  138. package/dist/organizations/notification-categories.js +51 -0
  139. package/dist/organizations/notification-categories.js.map +1 -0
  140. package/dist/organizations/ports.d.ts +3 -0
  141. package/dist/organizations/service.d.ts +2 -0
  142. package/dist/organizations/service.js +7 -0
  143. package/dist/organizations/service.js.map +1 -1
  144. package/dist/progress/events.d.ts +14 -14
  145. package/dist/reporting/member/index.d.ts +2 -2
  146. package/dist/reporting/member/model.d.ts +56 -23
  147. package/dist/reporting/member/ports.d.ts +9 -6
  148. package/dist/reporting/member/service.d.ts +33 -14
  149. package/dist/reporting/member/service.js +138 -60
  150. package/dist/reporting/member/service.js.map +1 -1
  151. package/dist/shared/errors.d.ts +13 -1
  152. package/dist/shared/errors.js +18 -1
  153. package/dist/shared/errors.js.map +1 -1
  154. package/dist/shared/id.d.ts +3 -0
  155. package/dist/shared/id.js +4 -1
  156. package/dist/shared/id.js.map +1 -1
  157. package/dist/shared/mailer.d.ts +11 -1
  158. package/dist/shared/mailer.js +32 -5
  159. package/dist/shared/mailer.js.map +1 -1
  160. package/dist/shared/notification-categories.d.ts +16 -0
  161. package/dist/shared/notification-categories.js +94 -0
  162. package/dist/shared/notification-categories.js.map +1 -0
  163. package/dist/shared/notification-settings.d.ts +14 -0
  164. package/dist/shared/notification-settings.js +61 -0
  165. package/dist/shared/notification-settings.js.map +1 -0
  166. package/dist/shared/ports.d.ts +48 -2
  167. package/dist/shared/settings.d.ts +2 -1
  168. package/dist/shared/settings.js +1 -0
  169. package/dist/shared/settings.js.map +1 -1
  170. package/dist/types/automations.d.ts +8 -2
  171. package/dist/types/content.d.ts +2 -2
  172. package/dist/types/discussion.d.ts +2 -2
  173. package/dist/types/email-templates.d.ts +97 -3
  174. package/dist/types/identity.d.ts +2 -2
  175. package/dist/types/index.d.ts +7 -6
  176. package/dist/types/notifications.d.ts +157 -0
  177. package/dist/types/notifications.js +1 -0
  178. package/dist/types/schemas/automations.d.ts +1 -10
  179. package/dist/types/schemas/automations.js +1 -3
  180. package/dist/types/schemas/automations.js.map +1 -1
  181. package/dist/types/schemas/content.d.ts +62 -1
  182. package/dist/types/schemas/content.js +25 -3
  183. package/dist/types/schemas/content.js.map +1 -1
  184. package/dist/types/schemas/discussion.d.ts +85 -12
  185. package/dist/types/schemas/discussion.js +47 -13
  186. package/dist/types/schemas/discussion.js.map +1 -1
  187. package/dist/types/schemas/identity.d.ts +1 -85
  188. package/dist/types/schemas/identity.js +1 -42
  189. package/dist/types/schemas/identity.js.map +1 -1
  190. package/dist/types/schemas/index.d.ts +6 -5
  191. package/dist/types/schemas/index.js +6 -5
  192. package/dist/types/schemas/notifications.d.ts +95 -0
  193. package/dist/types/schemas/notifications.js +56 -0
  194. package/dist/types/schemas/notifications.js.map +1 -0
  195. package/dist/types/schemas/progress.d.ts +3 -3
  196. package/package.json +1 -1
  197. package/dist/automations/community-notifications.d.ts +0 -16
  198. package/dist/automations/community-notifications.js +0 -84
  199. package/dist/automations/community-notifications.js.map +0 -1
  200. package/dist/automations/seeds.d.ts +0 -17
  201. package/dist/automations/seeds.js +0 -235
  202. package/dist/automations/seeds.js.map +0 -1
  203. package/dist/identity/notifications.d.ts +0 -27
  204. package/dist/identity/notifications.js +0 -101
  205. package/dist/identity/notifications.js.map +0 -1
@@ -1,27 +0,0 @@
1
- import { Logger } from "../types/ports.js";
2
- import { Notification, NotificationKind, NotificationPreference } from "../types/schemas/identity.js";
3
- import "../shared/ports.js";
4
- import "./model.js";
5
- import { NewNotification, NotificationPage, NotificationService, NotificationsQuery, NotificationsRepository } from "./ports.js";
6
- //#region src/identity/notifications.d.ts
7
- declare function defaultPreference(kind: NotificationKind): NotificationPreference;
8
- declare class NotificationServiceImpl implements NotificationService {
9
- private readonly repo;
10
- private readonly logger;
11
- constructor(params: {
12
- repo: NotificationsRepository;
13
- logger?: Logger;
14
- });
15
- notify(orgId: string, notifications: NewNotification[]): Promise<void>;
16
- preferencesFor(orgId: string, userIds: string[], kind: NotificationKind): Promise<Record<string, NotificationPreference>>;
17
- listNotifications(orgId: string, userId: string, query: NotificationsQuery): Promise<NotificationPage>;
18
- markNotificationRead(orgId: string, userId: string, notificationId: string): Promise<Notification>;
19
- markAllNotificationsRead(orgId: string, userId: string): Promise<{
20
- updated: number;
21
- }>;
22
- notificationPreferences(orgId: string, userId: string): Promise<NotificationPreference[]>;
23
- setNotificationPreferences(orgId: string, userId: string, preferences: NotificationPreference[]): Promise<NotificationPreference[]>;
24
- }
25
- //#endregion
26
- export { NotificationServiceImpl, defaultPreference };
27
- //# sourceMappingURL=notifications.d.ts.map
@@ -1,101 +0,0 @@
1
- import { notificationKindSchema } from "../types/schemas/identity.js";
2
- import { genId } from "../shared/id.js";
3
- import { NotFoundError } from "../shared/errors.js";
4
- import { noopLogger } from "../shared/logger.js";
5
- //#region src/identity/notifications.ts
6
- function defaultPreference(kind) {
7
- return {
8
- kind,
9
- inApp: true,
10
- email: true
11
- };
12
- }
13
- var NotificationServiceImpl = class {
14
- repo;
15
- logger;
16
- constructor(params) {
17
- this.repo = params.repo;
18
- this.logger = params.logger ?? noopLogger;
19
- }
20
- async notify(orgId, notifications) {
21
- if (notifications.length === 0) return;
22
- const now = /* @__PURE__ */ new Date();
23
- const rows = notifications.map((notification) => ({
24
- ...notification,
25
- orgId,
26
- id: genId("notification"),
27
- createdAt: now,
28
- readAt: null
29
- }));
30
- await this.repo.insert(orgId, rows);
31
- this.logger.info("notifications added", {
32
- orgId,
33
- kinds: [...new Set(rows.map((row) => row.kind))],
34
- count: rows.length
35
- });
36
- }
37
- async preferencesFor(orgId, userIds, kind) {
38
- const unique = [...new Set(userIds)];
39
- const stored = await this.repo.preferences(orgId, unique);
40
- const result = {};
41
- for (const userId of unique) result[userId] = defaultPreference(kind);
42
- for (const row of stored) if (row.kind === kind) result[row.userId] = {
43
- kind,
44
- inApp: row.inApp,
45
- email: row.email
46
- };
47
- return result;
48
- }
49
- async listNotifications(orgId, userId, query) {
50
- const page = await this.repo.page(orgId, userId, query);
51
- this.logger.debug("notifications listed", {
52
- orgId,
53
- userId,
54
- count: page.rows.length
55
- });
56
- return {
57
- ...page,
58
- page: query.page,
59
- pageSize: query.pageSize
60
- };
61
- }
62
- async markNotificationRead(orgId, userId, notificationId) {
63
- const row = await this.repo.markRead(orgId, userId, notificationId, /* @__PURE__ */ new Date());
64
- if (!row) throw new NotFoundError("Notification", notificationId);
65
- return row;
66
- }
67
- async markAllNotificationsRead(orgId, userId) {
68
- const updated = await this.repo.markAllRead(orgId, userId, /* @__PURE__ */ new Date());
69
- this.logger.debug("notifications marked read", {
70
- orgId,
71
- userId,
72
- updated
73
- });
74
- return { updated };
75
- }
76
- async notificationPreferences(orgId, userId) {
77
- const stored = await this.repo.preferences(orgId, [userId]);
78
- const byKind = new Map(stored.map((row) => [row.kind, row]));
79
- return notificationKindSchema.options.map((kind) => {
80
- const row = byKind.get(kind);
81
- return row ? {
82
- kind,
83
- inApp: row.inApp,
84
- email: row.email
85
- } : defaultPreference(kind);
86
- });
87
- }
88
- async setNotificationPreferences(orgId, userId, preferences) {
89
- await this.repo.upsertPreferences(orgId, userId, preferences);
90
- this.logger.info("notification preferences updated", {
91
- orgId,
92
- userId,
93
- kinds: preferences.map((pref) => pref.kind)
94
- });
95
- return this.notificationPreferences(orgId, userId);
96
- }
97
- };
98
- //#endregion
99
- export { NotificationServiceImpl, defaultPreference };
100
-
101
- //# sourceMappingURL=notifications.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"notifications.js","names":[],"sources":["../../src/identity/notifications.ts"],"sourcesContent":["import { NotFoundError } from '../shared/errors.js';\nimport { genId } from '../shared/id.js';\nimport { noopLogger } from '../shared/logger.js';\nimport type { Logger } from '../shared/ports.js';\nimport { notificationKindSchema } from '../types/schemas/identity.js';\nimport type { Notification, NotificationKind, NotificationPreference } from './model.js';\nimport type {\n NewNotification,\n NotificationPage,\n NotificationService,\n NotificationsQuery,\n NotificationsRepository,\n} from './ports.js';\n\nexport function defaultPreference(kind: NotificationKind): NotificationPreference {\n return { kind, inApp: true, email: true };\n}\n\nexport class NotificationServiceImpl implements NotificationService {\n private readonly repo: NotificationsRepository;\n private readonly logger: Logger;\n\n constructor(params: { repo: NotificationsRepository; logger?: Logger }) {\n this.repo = params.repo;\n this.logger = params.logger ?? noopLogger;\n }\n\n async notify(orgId: string, notifications: NewNotification[]): Promise<void> {\n if (notifications.length === 0) {\n return;\n }\n const now = new Date();\n const rows: Notification[] = notifications.map((notification) => ({\n ...notification,\n orgId,\n id: genId('notification'),\n createdAt: now,\n readAt: null,\n }));\n await this.repo.insert(orgId, rows);\n this.logger.info('notifications added', {\n orgId,\n kinds: [...new Set(rows.map((row) => row.kind))],\n count: rows.length,\n });\n }\n\n async preferencesFor(\n orgId: string,\n userIds: string[],\n kind: NotificationKind,\n ): Promise<Record<string, NotificationPreference>> {\n const unique = [...new Set(userIds)];\n const stored = await this.repo.preferences(orgId, unique);\n const result: Record<string, NotificationPreference> = {};\n for (const userId of unique) {\n result[userId] = defaultPreference(kind);\n }\n for (const row of stored) {\n if (row.kind === kind) {\n result[row.userId] = { kind, inApp: row.inApp, email: row.email };\n }\n }\n return result;\n }\n\n async listNotifications(\n orgId: string,\n userId: string,\n query: NotificationsQuery,\n ): Promise<NotificationPage> {\n const page = await this.repo.page(orgId, userId, query);\n this.logger.debug('notifications listed', { orgId, userId, count: page.rows.length });\n return { ...page, page: query.page, pageSize: query.pageSize };\n }\n\n async markNotificationRead(\n orgId: string,\n userId: string,\n notificationId: string,\n ): Promise<Notification> {\n const row = await this.repo.markRead(orgId, userId, notificationId, new Date());\n if (!row) {\n throw new NotFoundError('Notification', notificationId);\n }\n return row;\n }\n\n async markAllNotificationsRead(orgId: string, userId: string): Promise<{ updated: number }> {\n const updated = await this.repo.markAllRead(orgId, userId, new Date());\n this.logger.debug('notifications marked read', { orgId, userId, updated });\n return { updated };\n }\n\n async notificationPreferences(orgId: string, userId: string): Promise<NotificationPreference[]> {\n const stored = await this.repo.preferences(orgId, [userId]);\n const byKind = new Map(stored.map((row) => [row.kind, row]));\n return notificationKindSchema.options.map((kind) => {\n const row = byKind.get(kind);\n return row ? { kind, inApp: row.inApp, email: row.email } : defaultPreference(kind);\n });\n }\n\n async setNotificationPreferences(\n orgId: string,\n userId: string,\n preferences: NotificationPreference[],\n ): Promise<NotificationPreference[]> {\n await this.repo.upsertPreferences(orgId, userId, preferences);\n this.logger.info('notification preferences updated', {\n orgId,\n userId,\n kinds: preferences.map((pref) => pref.kind),\n });\n return this.notificationPreferences(orgId, userId);\n }\n}\n"],"mappings":";;;;;AAcA,SAAgB,kBAAkB,MAAgD;CAChF,OAAO;EAAE;EAAM,OAAO;EAAM,OAAO;CAAK;AAC1C;AAEA,IAAa,0BAAb,MAAoE;CAClE;CACA;CAEA,YAAY,QAA4D;EACtE,KAAK,OAAO,OAAO;EACnB,KAAK,SAAS,OAAO,UAAU;CACjC;CAEA,MAAM,OAAO,OAAe,eAAiD;EAC3E,IAAI,cAAc,WAAW,GAC3B;EAEF,MAAM,sBAAM,IAAI,KAAK;EACrB,MAAM,OAAuB,cAAc,KAAK,kBAAkB;GAChE,GAAG;GACH;GACA,IAAI,MAAM,cAAc;GACxB,WAAW;GACX,QAAQ;EACV,EAAE;EACF,MAAM,KAAK,KAAK,OAAO,OAAO,IAAI;EAClC,KAAK,OAAO,KAAK,uBAAuB;GACtC;GACA,OAAO,CAAC,GAAG,IAAI,IAAI,KAAK,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC;GAC/C,OAAO,KAAK;EACd,CAAC;CACH;CAEA,MAAM,eACJ,OACA,SACA,MACiD;EACjD,MAAM,SAAS,CAAC,GAAG,IAAI,IAAI,OAAO,CAAC;EACnC,MAAM,SAAS,MAAM,KAAK,KAAK,YAAY,OAAO,MAAM;EACxD,MAAM,SAAiD,CAAC;EACxD,KAAK,MAAM,UAAU,QACnB,OAAO,UAAU,kBAAkB,IAAI;EAEzC,KAAK,MAAM,OAAO,QAChB,IAAI,IAAI,SAAS,MACf,OAAO,IAAI,UAAU;GAAE;GAAM,OAAO,IAAI;GAAO,OAAO,IAAI;EAAM;EAGpE,OAAO;CACT;CAEA,MAAM,kBACJ,OACA,QACA,OAC2B;EAC3B,MAAM,OAAO,MAAM,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK;EACtD,KAAK,OAAO,MAAM,wBAAwB;GAAE;GAAO;GAAQ,OAAO,KAAK,KAAK;EAAO,CAAC;EACpF,OAAO;GAAE,GAAG;GAAM,MAAM,MAAM;GAAM,UAAU,MAAM;EAAS;CAC/D;CAEA,MAAM,qBACJ,OACA,QACA,gBACuB;EACvB,MAAM,MAAM,MAAM,KAAK,KAAK,SAAS,OAAO,QAAQ,gCAAgB,IAAI,KAAK,CAAC;EAC9E,IAAI,CAAC,KACH,MAAM,IAAI,cAAc,gBAAgB,cAAc;EAExD,OAAO;CACT;CAEA,MAAM,yBAAyB,OAAe,QAA8C;EAC1F,MAAM,UAAU,MAAM,KAAK,KAAK,YAAY,OAAO,wBAAQ,IAAI,KAAK,CAAC;EACrE,KAAK,OAAO,MAAM,6BAA6B;GAAE;GAAO;GAAQ;EAAQ,CAAC;EACzE,OAAO,EAAE,QAAQ;CACnB;CAEA,MAAM,wBAAwB,OAAe,QAAmD;EAC9F,MAAM,SAAS,MAAM,KAAK,KAAK,YAAY,OAAO,CAAC,MAAM,CAAC;EAC1D,MAAM,SAAS,IAAI,IAAI,OAAO,KAAK,QAAQ,CAAC,IAAI,MAAM,GAAG,CAAC,CAAC;EAC3D,OAAO,uBAAuB,QAAQ,KAAK,SAAS;GAClD,MAAM,MAAM,OAAO,IAAI,IAAI;GAC3B,OAAO,MAAM;IAAE;IAAM,OAAO,IAAI;IAAO,OAAO,IAAI;GAAM,IAAI,kBAAkB,IAAI;EACpF,CAAC;CACH;CAEA,MAAM,2BACJ,OACA,QACA,aACmC;EACnC,MAAM,KAAK,KAAK,kBAAkB,OAAO,QAAQ,WAAW;EAC5D,KAAK,OAAO,KAAK,oCAAoC;GACnD;GACA;GACA,OAAO,YAAY,KAAK,SAAS,KAAK,IAAI;EAC5C,CAAC;EACD,OAAO,KAAK,wBAAwB,OAAO,MAAM;CACnD;AACF"}