joopjs 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (259) hide show
  1. package/CHANGELOG.md +678 -0
  2. package/README.md +583 -0
  3. package/dist/a11y.service-C-DQQfgO.d.mts +143 -0
  4. package/dist/a11y.service-CauEJrJe.d.ts +143 -0
  5. package/dist/adapters-B6slG6hQ.d.mts +84 -0
  6. package/dist/adapters-B6slG6hQ.d.ts +84 -0
  7. package/dist/aes.service-CkoupAww.d.mts +95 -0
  8. package/dist/aes.service-CkoupAww.d.ts +95 -0
  9. package/dist/ai/index.d.mts +99 -0
  10. package/dist/ai/index.d.ts +99 -0
  11. package/dist/ai/index.js +307 -0
  12. package/dist/ai/index.js.map +1 -0
  13. package/dist/ai/index.mjs +304 -0
  14. package/dist/ai/index.mjs.map +1 -0
  15. package/dist/analytics/index.d.mts +42 -0
  16. package/dist/analytics/index.d.ts +42 -0
  17. package/dist/analytics/index.js +139 -0
  18. package/dist/analytics/index.js.map +1 -0
  19. package/dist/analytics/index.mjs +136 -0
  20. package/dist/analytics/index.mjs.map +1 -0
  21. package/dist/angular/index.d.mts +148 -0
  22. package/dist/angular/index.d.ts +148 -0
  23. package/dist/angular/index.js +122 -0
  24. package/dist/angular/index.js.map +1 -0
  25. package/dist/angular/index.mjs +101 -0
  26. package/dist/angular/index.mjs.map +1 -0
  27. package/dist/api/index.d.mts +128 -0
  28. package/dist/api/index.d.ts +128 -0
  29. package/dist/api/index.js +1358 -0
  30. package/dist/api/index.js.map +1 -0
  31. package/dist/api/index.mjs +1332 -0
  32. package/dist/api/index.mjs.map +1 -0
  33. package/dist/auth/index.d.mts +105 -0
  34. package/dist/auth/index.d.ts +105 -0
  35. package/dist/auth/index.js +989 -0
  36. package/dist/auth/index.js.map +1 -0
  37. package/dist/auth/index.mjs +979 -0
  38. package/dist/auth/index.mjs.map +1 -0
  39. package/dist/auth.service-DNVB-L4U.d.mts +16 -0
  40. package/dist/auth.service-PjUUSUIt.d.ts +16 -0
  41. package/dist/banking/index.d.mts +1530 -0
  42. package/dist/banking/index.d.ts +1530 -0
  43. package/dist/banking/index.js +4739 -0
  44. package/dist/banking/index.js.map +1 -0
  45. package/dist/banking/index.mjs +4661 -0
  46. package/dist/banking/index.mjs.map +1 -0
  47. package/dist/cache/index.d.mts +40 -0
  48. package/dist/cache/index.d.ts +40 -0
  49. package/dist/cache/index.js +174 -0
  50. package/dist/cache/index.js.map +1 -0
  51. package/dist/cache/index.mjs +172 -0
  52. package/dist/cache/index.mjs.map +1 -0
  53. package/dist/client-profile.service-BuPeXVp5.d.mts +28 -0
  54. package/dist/client-profile.service-D5bRRYQp.d.ts +28 -0
  55. package/dist/config.models-Cqg04fAQ.d.mts +84 -0
  56. package/dist/config.models-Cqg04fAQ.d.ts +84 -0
  57. package/dist/config.service-CrCvI-JS.d.ts +31 -0
  58. package/dist/config.service-Cz4QQLlf.d.mts +31 -0
  59. package/dist/core/index.d.mts +4 -0
  60. package/dist/core/index.d.ts +4 -0
  61. package/dist/core/index.js +631 -0
  62. package/dist/core/index.js.map +1 -0
  63. package/dist/core/index.mjs +619 -0
  64. package/dist/core/index.mjs.map +1 -0
  65. package/dist/crypto-utils-DriNhLdx.d.mts +30 -0
  66. package/dist/crypto-utils-DriNhLdx.d.ts +30 -0
  67. package/dist/data-storage.service-DT6xaTxE.d.ts +51 -0
  68. package/dist/data-storage.service-LvhGRCmw.d.mts +51 -0
  69. package/dist/deeplink/index.d.mts +39 -0
  70. package/dist/deeplink/index.d.ts +39 -0
  71. package/dist/deeplink/index.js +268 -0
  72. package/dist/deeplink/index.js.map +1 -0
  73. package/dist/deeplink/index.mjs +265 -0
  74. package/dist/deeplink/index.mjs.map +1 -0
  75. package/dist/deeplink.service-Ctd5u243.d.mts +35 -0
  76. package/dist/deeplink.service-uUuTnY9_.d.ts +35 -0
  77. package/dist/dev/index.d.mts +20 -0
  78. package/dist/dev/index.d.ts +20 -0
  79. package/dist/dev/index.js +51 -0
  80. package/dist/dev/index.js.map +1 -0
  81. package/dist/dev/index.mjs +49 -0
  82. package/dist/dev/index.mjs.map +1 -0
  83. package/dist/device/index.d.mts +108 -0
  84. package/dist/device/index.d.ts +108 -0
  85. package/dist/device/index.js +960 -0
  86. package/dist/device/index.js.map +1 -0
  87. package/dist/device/index.mjs +951 -0
  88. package/dist/device/index.mjs.map +1 -0
  89. package/dist/differential-privacy-BcAv1G80.d.mts +210 -0
  90. package/dist/differential-privacy-C8mAUjZr.d.ts +210 -0
  91. package/dist/encryption/index.d.mts +75 -0
  92. package/dist/encryption/index.d.ts +75 -0
  93. package/dist/encryption/index.js +605 -0
  94. package/dist/encryption/index.js.map +1 -0
  95. package/dist/encryption/index.mjs +598 -0
  96. package/dist/encryption/index.mjs.map +1 -0
  97. package/dist/form-validator-3tkmzr_o.d.mts +72 -0
  98. package/dist/form-validator-3tkmzr_o.d.ts +72 -0
  99. package/dist/forms/index.d.mts +59 -0
  100. package/dist/forms/index.d.ts +59 -0
  101. package/dist/forms/index.js +446 -0
  102. package/dist/forms/index.js.map +1 -0
  103. package/dist/forms/index.mjs +442 -0
  104. package/dist/forms/index.mjs.map +1 -0
  105. package/dist/i18n/index.d.mts +37 -0
  106. package/dist/i18n/index.d.ts +37 -0
  107. package/dist/i18n/index.js +147 -0
  108. package/dist/i18n/index.js.map +1 -0
  109. package/dist/i18n/index.mjs +145 -0
  110. package/dist/i18n/index.mjs.map +1 -0
  111. package/dist/idempotency.service-_6LqhivP.d.mts +372 -0
  112. package/dist/idempotency.service-eOKoISRD.d.ts +372 -0
  113. package/dist/index-B_ksKpS1.d.mts +202 -0
  114. package/dist/index-CqDKWTUP.d.mts +28 -0
  115. package/dist/index-CqDKWTUP.d.ts +28 -0
  116. package/dist/index-DFqEoX_l.d.ts +202 -0
  117. package/dist/index-Dz0gOur2.d.mts +36 -0
  118. package/dist/index-Dz0gOur2.d.ts +36 -0
  119. package/dist/index.d.mts +1336 -0
  120. package/dist/index.d.ts +1336 -0
  121. package/dist/index.js +19464 -0
  122. package/dist/index.js.map +1 -0
  123. package/dist/index.mjs +19155 -0
  124. package/dist/index.mjs.map +1 -0
  125. package/dist/india/index.d.mts +75 -0
  126. package/dist/india/index.d.ts +75 -0
  127. package/dist/india/index.js +325 -0
  128. package/dist/india/index.js.map +1 -0
  129. package/dist/india/index.mjs +303 -0
  130. package/dist/india/index.mjs.map +1 -0
  131. package/dist/joop-Bx7Iwj5p.d.mts +155 -0
  132. package/dist/joop-CA3DMeOO.d.ts +155 -0
  133. package/dist/native-bridge/index.d.mts +27 -0
  134. package/dist/native-bridge/index.d.ts +27 -0
  135. package/dist/native-bridge/index.js +98 -0
  136. package/dist/native-bridge/index.js.map +1 -0
  137. package/dist/native-bridge/index.mjs +96 -0
  138. package/dist/native-bridge/index.mjs.map +1 -0
  139. package/dist/network/index.d.mts +85 -0
  140. package/dist/network/index.d.ts +85 -0
  141. package/dist/network/index.js +454 -0
  142. package/dist/network/index.js.map +1 -0
  143. package/dist/network/index.mjs +451 -0
  144. package/dist/network/index.mjs.map +1 -0
  145. package/dist/network-monitor-BIwPSXme.d.mts +179 -0
  146. package/dist/network-monitor-Bqp2hvZr.d.ts +179 -0
  147. package/dist/notification.service-Dm4fvfZf.d.mts +25 -0
  148. package/dist/notification.service-tEMKatWJ.d.ts +25 -0
  149. package/dist/observability/index.d.mts +179 -0
  150. package/dist/observability/index.d.ts +179 -0
  151. package/dist/observability/index.js +559 -0
  152. package/dist/observability/index.js.map +1 -0
  153. package/dist/observability/index.mjs +552 -0
  154. package/dist/observability/index.mjs.map +1 -0
  155. package/dist/oidc-client-DIJcClmB.d.mts +190 -0
  156. package/dist/oidc-client-DxhyE59t.d.ts +190 -0
  157. package/dist/platform/index.d.mts +73 -0
  158. package/dist/platform/index.d.ts +73 -0
  159. package/dist/platform/index.js +127 -0
  160. package/dist/platform/index.js.map +1 -0
  161. package/dist/platform/index.mjs +125 -0
  162. package/dist/platform/index.mjs.map +1 -0
  163. package/dist/pwa/index.d.mts +31 -0
  164. package/dist/pwa/index.d.ts +31 -0
  165. package/dist/pwa/index.js +247 -0
  166. package/dist/pwa/index.js.map +1 -0
  167. package/dist/pwa/index.mjs +244 -0
  168. package/dist/pwa/index.mjs.map +1 -0
  169. package/dist/react/index.d.mts +133 -0
  170. package/dist/react/index.d.ts +133 -0
  171. package/dist/react/index.js +632 -0
  172. package/dist/react/index.js.map +1 -0
  173. package/dist/react/index.mjs +630 -0
  174. package/dist/react/index.mjs.map +1 -0
  175. package/dist/router/index.d.mts +39 -0
  176. package/dist/router/index.d.ts +39 -0
  177. package/dist/router/index.js +168 -0
  178. package/dist/router/index.js.map +1 -0
  179. package/dist/router/index.mjs +166 -0
  180. package/dist/router/index.mjs.map +1 -0
  181. package/dist/security/index.d.mts +206 -0
  182. package/dist/security/index.d.ts +206 -0
  183. package/dist/security/index.js +1297 -0
  184. package/dist/security/index.js.map +1 -0
  185. package/dist/security/index.mjs +1285 -0
  186. package/dist/security/index.mjs.map +1 -0
  187. package/dist/session/index.d.mts +115 -0
  188. package/dist/session/index.d.ts +115 -0
  189. package/dist/session/index.js +297 -0
  190. package/dist/session/index.js.map +1 -0
  191. package/dist/session/index.mjs +292 -0
  192. package/dist/session/index.mjs.map +1 -0
  193. package/dist/state/index.d.mts +43 -0
  194. package/dist/state/index.d.ts +43 -0
  195. package/dist/state/index.js +156 -0
  196. package/dist/state/index.js.map +1 -0
  197. package/dist/state/index.mjs +152 -0
  198. package/dist/state/index.mjs.map +1 -0
  199. package/dist/statement-parser-BHQtXwCM.d.ts +260 -0
  200. package/dist/statement-parser-C2qNmb49.d.mts +260 -0
  201. package/dist/storage/index.d.mts +40 -0
  202. package/dist/storage/index.d.ts +40 -0
  203. package/dist/storage/index.js +256 -0
  204. package/dist/storage/index.js.map +1 -0
  205. package/dist/storage/index.mjs +252 -0
  206. package/dist/storage/index.mjs.map +1 -0
  207. package/dist/sync/index.d.mts +69 -0
  208. package/dist/sync/index.d.ts +69 -0
  209. package/dist/sync/index.js +330 -0
  210. package/dist/sync/index.js.map +1 -0
  211. package/dist/sync/index.mjs +323 -0
  212. package/dist/sync/index.mjs.map +1 -0
  213. package/dist/sync-engine-DCIMRG5s.d.ts +61 -0
  214. package/dist/sync-engine-DZqyKHkK.d.mts +61 -0
  215. package/dist/theme/index.d.mts +53 -0
  216. package/dist/theme/index.d.ts +53 -0
  217. package/dist/theme/index.js +169 -0
  218. package/dist/theme/index.js.map +1 -0
  219. package/dist/theme/index.mjs +167 -0
  220. package/dist/theme/index.mjs.map +1 -0
  221. package/dist/ui/index.d.mts +66 -0
  222. package/dist/ui/index.d.ts +66 -0
  223. package/dist/ui/index.js +811 -0
  224. package/dist/ui/index.js.map +1 -0
  225. package/dist/ui/index.mjs +803 -0
  226. package/dist/ui/index.mjs.map +1 -0
  227. package/dist/utilities/index.d.mts +199 -0
  228. package/dist/utilities/index.d.ts +199 -0
  229. package/dist/utilities/index.js +1991 -0
  230. package/dist/utilities/index.js.map +1 -0
  231. package/dist/utilities/index.mjs +1923 -0
  232. package/dist/utilities/index.mjs.map +1 -0
  233. package/dist/validation/index.d.mts +60 -0
  234. package/dist/validation/index.d.ts +60 -0
  235. package/dist/validation/index.js +460 -0
  236. package/dist/validation/index.js.map +1 -0
  237. package/dist/validation/index.mjs +455 -0
  238. package/dist/validation/index.mjs.map +1 -0
  239. package/dist/vue/index.d.mts +135 -0
  240. package/dist/vue/index.d.ts +135 -0
  241. package/dist/vue/index.js +621 -0
  242. package/dist/vue/index.js.map +1 -0
  243. package/dist/vue/index.mjs +619 -0
  244. package/dist/vue/index.mjs.map +1 -0
  245. package/dist/watermark.service-Detur5tq.d.ts +235 -0
  246. package/dist/watermark.service-QNegMeQZ.d.mts +235 -0
  247. package/dist/workers/index.d.mts +42 -0
  248. package/dist/workers/index.d.ts +42 -0
  249. package/dist/workers/index.js +359 -0
  250. package/dist/workers/index.js.map +1 -0
  251. package/dist/workers/index.mjs +356 -0
  252. package/dist/workers/index.mjs.map +1 -0
  253. package/dist/workflow/index.d.mts +99 -0
  254. package/dist/workflow/index.d.ts +99 -0
  255. package/dist/workflow/index.js +282 -0
  256. package/dist/workflow/index.js.map +1 -0
  257. package/dist/workflow/index.mjs +279 -0
  258. package/dist/workflow/index.mjs.map +1 -0
  259. package/package.json +226 -0
@@ -0,0 +1,559 @@
1
+ 'use strict';
2
+
3
+ // src/events/index.ts
4
+ var JoopSubject = class {
5
+ _listeners = [];
6
+ subscribe(listener) {
7
+ this._listeners.push(listener);
8
+ return () => {
9
+ this._listeners = this._listeners.filter((l) => l !== listener);
10
+ };
11
+ }
12
+ next(value) {
13
+ for (const listener of this._listeners) {
14
+ listener(value);
15
+ }
16
+ }
17
+ asObservable() {
18
+ return new JoopObservable((listener) => this.subscribe(listener));
19
+ }
20
+ };
21
+ var JoopBehaviorSubject = class extends JoopSubject {
22
+ _value;
23
+ constructor(initialValue) {
24
+ super();
25
+ this._value = initialValue;
26
+ }
27
+ getValue() {
28
+ return this._value;
29
+ }
30
+ next(value) {
31
+ this._value = value;
32
+ super.next(value);
33
+ }
34
+ subscribe(listener) {
35
+ listener(this._value);
36
+ return super.subscribe(listener);
37
+ }
38
+ asObservable() {
39
+ return new JoopObservable((listener) => this.subscribe(listener));
40
+ }
41
+ };
42
+ var JoopObservable = class {
43
+ constructor(_subscribeFn) {
44
+ this._subscribeFn = _subscribeFn;
45
+ }
46
+ _subscribeFn;
47
+ subscribe(listener) {
48
+ return this._subscribeFn(listener);
49
+ }
50
+ /** Returns the current value without subscribing (only meaningful for BehaviorSubject-backed observables). */
51
+ getOnce() {
52
+ let result;
53
+ const unsub = this.subscribe((v) => {
54
+ result = v;
55
+ });
56
+ unsub();
57
+ return result;
58
+ }
59
+ };
60
+
61
+ // src/observability/web-vitals.ts
62
+ var THRESHOLDS = {
63
+ lcp: [2500, 4e3],
64
+ fid: [100, 300],
65
+ inp: [200, 500],
66
+ cls: [0.1, 0.25],
67
+ ttfb: [800, 1800],
68
+ fcp: [1800, 3e3]
69
+ };
70
+ var JoopWebVitals = class {
71
+ _vitals = {};
72
+ _vitals$ = new JoopSubject();
73
+ _snapshot$ = new JoopBehaviorSubject(this._buildSnapshot());
74
+ _observers = [];
75
+ _running = false;
76
+ start() {
77
+ if (this._running || typeof PerformanceObserver === "undefined") return;
78
+ this._running = true;
79
+ this._observeLCP();
80
+ this._observeFID();
81
+ this._observeINP();
82
+ this._observeCLS();
83
+ this._observeTTFB();
84
+ this._observeFCP();
85
+ }
86
+ stop() {
87
+ this._running = false;
88
+ for (const obs of this._observers) {
89
+ try {
90
+ obs.disconnect();
91
+ } catch {
92
+ }
93
+ }
94
+ this._observers = [];
95
+ }
96
+ snapshot() {
97
+ return this._buildSnapshot();
98
+ }
99
+ vitals$() {
100
+ return this._vitals$.asObservable();
101
+ }
102
+ snapshot$() {
103
+ return this._snapshot$.asObservable();
104
+ }
105
+ getLCP() {
106
+ return this._vitals.lcp ?? null;
107
+ }
108
+ getCLS() {
109
+ return this._vitals.cls ?? null;
110
+ }
111
+ getINP() {
112
+ return this._vitals.inp ?? null;
113
+ }
114
+ getTTFB() {
115
+ return this._vitals.ttfb ?? null;
116
+ }
117
+ getFCP() {
118
+ return this._vitals.fcp ?? null;
119
+ }
120
+ getFID() {
121
+ return this._vitals.fid ?? null;
122
+ }
123
+ getRating(metric) {
124
+ const value = this._vitals[metric];
125
+ return _rate(metric, value ?? null);
126
+ }
127
+ _record(metric, value) {
128
+ this._vitals[metric] = value;
129
+ const rating = _rate(metric, value);
130
+ this._vitals$.next({ metric, value, rating });
131
+ this._snapshot$.next(this._buildSnapshot());
132
+ }
133
+ _observe(types, callback) {
134
+ try {
135
+ const obs = new PerformanceObserver(callback);
136
+ obs.observe({ type: types[0], buffered: true });
137
+ this._observers.push(obs);
138
+ } catch {
139
+ }
140
+ }
141
+ _observeLCP() {
142
+ this._observe(["largest-contentful-paint"], (list) => {
143
+ const entries = list.getEntries();
144
+ if (entries.length) this._record("lcp", entries[entries.length - 1].renderTime || entries[entries.length - 1].loadTime || entries[entries.length - 1].startTime);
145
+ });
146
+ }
147
+ _observeFID() {
148
+ this._observe(["first-input"], (list) => {
149
+ const e = list.getEntries()[0];
150
+ if (e && e.processingStart) this._record("fid", e.processingStart - e.startTime);
151
+ });
152
+ }
153
+ _observeINP() {
154
+ this._observe(["event"], (list) => {
155
+ let max = this._vitals.inp ?? 0;
156
+ for (const e of list.getEntries()) {
157
+ const entry = e;
158
+ if (entry.processingEnd) max = Math.max(max, entry.processingEnd - entry.startTime);
159
+ }
160
+ if (max > 0) this._record("inp", max);
161
+ });
162
+ }
163
+ _observeCLS() {
164
+ let clsValue = 0;
165
+ let sessionStart = 0;
166
+ let lastEntry = 0;
167
+ this._observe(["layout-shift"], (list) => {
168
+ for (const e of list.getEntries()) {
169
+ const entry = e;
170
+ if (entry.hadRecentInput) continue;
171
+ if (lastEntry > 0 && entry.startTime - lastEntry > 1e3) {
172
+ if (entry.startTime - sessionStart > 5e3) {
173
+ clsValue = 0;
174
+ sessionStart = entry.startTime;
175
+ }
176
+ }
177
+ if (lastEntry === 0) sessionStart = entry.startTime;
178
+ clsValue += entry.value ?? 0;
179
+ lastEntry = entry.startTime;
180
+ this._record("cls", clsValue);
181
+ }
182
+ });
183
+ }
184
+ _observeTTFB() {
185
+ const nav = performance.getEntriesByType?.("navigation")?.[0];
186
+ if (nav?.responseStart) this._record("ttfb", nav.responseStart);
187
+ this._observe(["navigation"], (list) => {
188
+ const e = list.getEntries()[0];
189
+ if (e?.responseStart) this._record("ttfb", e.responseStart);
190
+ });
191
+ }
192
+ _observeFCP() {
193
+ this._observe(["paint"], (list) => {
194
+ const e = list.getEntries().find((e2) => e2.name === "first-contentful-paint");
195
+ if (e) this._record("fcp", e.startTime);
196
+ });
197
+ }
198
+ _buildSnapshot() {
199
+ return {
200
+ lcp: this._vitals.lcp ?? null,
201
+ fid: this._vitals.fid ?? null,
202
+ inp: this._vitals.inp ?? null,
203
+ cls: this._vitals.cls ?? null,
204
+ ttfb: this._vitals.ttfb ?? null,
205
+ fcp: this._vitals.fcp ?? null,
206
+ capturedAt: Date.now()
207
+ };
208
+ }
209
+ };
210
+ function _rate(metric, value) {
211
+ if (value === null) return "good";
212
+ const [good, poor] = THRESHOLDS[metric] ?? [Infinity, Infinity];
213
+ return value <= good ? "good" : value <= poor ? "needs-improvement" : "poor";
214
+ }
215
+
216
+ // src/observability/session-recorder.ts
217
+ var JoopSessionRecorder = class {
218
+ _events = [];
219
+ _running = false;
220
+ _paused = false;
221
+ _startedAt = 0;
222
+ _opts = {
223
+ maskSelectors: [],
224
+ ignoreSelectors: [],
225
+ redactInputs: true,
226
+ maxEvents: 1e4,
227
+ captureScroll: true,
228
+ captureResize: true
229
+ };
230
+ _cleanup = [];
231
+ _mutationObserver = null;
232
+ _scrollTimer = null;
233
+ start(options = {}) {
234
+ if (this._running) return;
235
+ this._opts = { ...this._opts, ...options };
236
+ this._running = true;
237
+ this._paused = false;
238
+ this._events = [];
239
+ this._startedAt = Date.now();
240
+ this._attachListeners();
241
+ }
242
+ pause() {
243
+ this._paused = true;
244
+ }
245
+ resume() {
246
+ this._paused = false;
247
+ }
248
+ stop() {
249
+ this._running = false;
250
+ this._paused = false;
251
+ this._detach();
252
+ return {
253
+ startedAt: this._startedAt,
254
+ stoppedAt: Date.now(),
255
+ events: [...this._events],
256
+ url: typeof location !== "undefined" ? location.href : "",
257
+ userAgent: typeof navigator !== "undefined" ? navigator.userAgent : ""
258
+ };
259
+ }
260
+ events() {
261
+ return [...this._events];
262
+ }
263
+ export(format = "json") {
264
+ const record = {
265
+ startedAt: this._startedAt,
266
+ stoppedAt: Date.now(),
267
+ events: this._events,
268
+ url: typeof location !== "undefined" ? location.href : "",
269
+ userAgent: typeof navigator !== "undefined" ? navigator.userAgent : ""
270
+ };
271
+ const json = JSON.stringify(record);
272
+ if (format === "compressed") {
273
+ try {
274
+ return btoa(json);
275
+ } catch {
276
+ return json;
277
+ }
278
+ }
279
+ return json;
280
+ }
281
+ addEvent(type, data) {
282
+ this._push({ type, timestamp: Date.now(), data });
283
+ }
284
+ _push(event) {
285
+ if (!this._running || this._paused) return;
286
+ if (this._events.length >= this._opts.maxEvents) this._events.shift();
287
+ this._events.push(event);
288
+ }
289
+ _attachListeners() {
290
+ this._mutationObserver = new MutationObserver((mutations) => {
291
+ for (const m of mutations) {
292
+ if (this._shouldIgnore(m.target)) continue;
293
+ this._push({ type: "dom-mutation", timestamp: Date.now(), selector: _selector(m.target), data: { addedNodes: m.addedNodes.length, removedNodes: m.removedNodes.length, type: m.type } });
294
+ }
295
+ });
296
+ this._mutationObserver.observe(document.documentElement, { childList: true, subtree: true, attributes: true, characterData: false, attributeFilter: ["class", "style", "hidden", "disabled"] });
297
+ const onClick = (e) => {
298
+ const el = e.target;
299
+ if (this._shouldIgnore(el)) return;
300
+ this._push({ type: "click", timestamp: Date.now(), selector: _selector(el) });
301
+ };
302
+ document.addEventListener("click", onClick, { capture: true });
303
+ this._cleanup.push(() => document.removeEventListener("click", onClick, { capture: true }));
304
+ const onInput = (e) => {
305
+ const el = e.target;
306
+ if (this._shouldIgnore(el)) return;
307
+ const redact = this._opts.redactInputs && (el.type === "password" || el.dataset?.pii !== void 0 || this._opts.maskSelectors.some((s) => el.matches(s)));
308
+ this._push({ type: "input", timestamp: Date.now(), selector: _selector(el), value: redact ? "***" : void 0 });
309
+ };
310
+ document.addEventListener("input", onInput, { capture: true });
311
+ this._cleanup.push(() => document.removeEventListener("input", onInput, { capture: true }));
312
+ if (this._opts.captureScroll) {
313
+ const onScroll = () => {
314
+ if (this._scrollTimer) return;
315
+ this._scrollTimer = setTimeout(() => {
316
+ this._scrollTimer = null;
317
+ this._push({ type: "scroll", timestamp: Date.now(), data: { x: window.scrollX, y: window.scrollY } });
318
+ }, 250);
319
+ };
320
+ window.addEventListener("scroll", onScroll, { passive: true });
321
+ this._cleanup.push(() => window.removeEventListener("scroll", onScroll));
322
+ }
323
+ if (this._opts.captureResize) {
324
+ let resizeTimer = null;
325
+ const onResize = () => {
326
+ if (resizeTimer) return;
327
+ resizeTimer = setTimeout(() => {
328
+ resizeTimer = null;
329
+ this._push({ type: "resize", timestamp: Date.now(), data: { w: window.innerWidth, h: window.innerHeight } });
330
+ }, 250);
331
+ };
332
+ window.addEventListener("resize", onResize, { passive: true });
333
+ this._cleanup.push(() => window.removeEventListener("resize", onResize));
334
+ }
335
+ const onPop = () => this._push({ type: "navigation", timestamp: Date.now(), data: { url: location.href } });
336
+ window.addEventListener("popstate", onPop);
337
+ this._cleanup.push(() => window.removeEventListener("popstate", onPop));
338
+ }
339
+ _detach() {
340
+ this._mutationObserver?.disconnect();
341
+ this._mutationObserver = null;
342
+ for (const fn of this._cleanup) fn();
343
+ this._cleanup = [];
344
+ }
345
+ _shouldIgnore(el) {
346
+ if (!el) return false;
347
+ return this._opts.ignoreSelectors.some((s) => {
348
+ try {
349
+ return el.matches?.(s);
350
+ } catch {
351
+ return false;
352
+ }
353
+ });
354
+ }
355
+ };
356
+ function _selector(el) {
357
+ if (!el) return "";
358
+ const parts = [];
359
+ let current = el;
360
+ while (current && current !== document.body && parts.length < 4) {
361
+ let part = current.tagName.toLowerCase();
362
+ if (current.id) {
363
+ parts.unshift(`#${current.id}`);
364
+ break;
365
+ }
366
+ if (current.className) part += "." + Array.from(current.classList).slice(0, 2).join(".");
367
+ parts.unshift(part);
368
+ current = current.parentElement;
369
+ }
370
+ return parts.join(" > ");
371
+ }
372
+
373
+ // src/observability/correlation.service.ts
374
+ var JoopCorrelationService = class {
375
+ _correlationId = "";
376
+ _requestId = "";
377
+ newCorrelation() {
378
+ this._correlationId = crypto.randomUUID();
379
+ return this._correlationId;
380
+ }
381
+ newRequest() {
382
+ this._requestId = crypto.randomUUID();
383
+ return this._requestId;
384
+ }
385
+ getCorrelationId() {
386
+ return this._correlationId;
387
+ }
388
+ getRequestId() {
389
+ return this._requestId;
390
+ }
391
+ headers() {
392
+ const h = {};
393
+ if (this._correlationId) h["X-Correlation-ID"] = this._correlationId;
394
+ if (this._requestId) h["X-Request-ID"] = this._requestId;
395
+ return h;
396
+ }
397
+ clear() {
398
+ this._correlationId = "";
399
+ this._requestId = "";
400
+ }
401
+ };
402
+
403
+ // src/observability/audit-log.service.ts
404
+ var JoopAuditLog = class {
405
+ constructor(_maxEntries = 500) {
406
+ this._maxEntries = _maxEntries;
407
+ }
408
+ _maxEntries;
409
+ _entries = [];
410
+ _listeners = [];
411
+ record(action, options = {}) {
412
+ const entry = {
413
+ id: crypto.randomUUID(),
414
+ action,
415
+ timestamp: Date.now(),
416
+ success: options.success ?? true,
417
+ ...options
418
+ };
419
+ this._entries.push(entry);
420
+ if (this._entries.length > this._maxEntries) this._entries = this._entries.slice(-this._maxEntries);
421
+ this._listeners.forEach((l) => l(entry));
422
+ return entry;
423
+ }
424
+ getAll() {
425
+ return [...this._entries];
426
+ }
427
+ getByAction(action) {
428
+ return this._entries.filter((e) => e.action === action);
429
+ }
430
+ getBySession(sessionId) {
431
+ return this._entries.filter((e) => e.sessionId === sessionId);
432
+ }
433
+ getByUser(userId) {
434
+ return this._entries.filter((e) => e.userId === userId);
435
+ }
436
+ onRecord(listener) {
437
+ this._listeners.push(listener);
438
+ return () => {
439
+ this._listeners = this._listeners.filter((l) => l !== listener);
440
+ };
441
+ }
442
+ clear() {
443
+ this._entries = [];
444
+ }
445
+ export() {
446
+ return JSON.stringify(this._entries, null, 2);
447
+ }
448
+ };
449
+
450
+ // src/observability/performance.service.ts
451
+ var JoopPerformanceService = class {
452
+ _marks = /* @__PURE__ */ new Map();
453
+ _completed = [];
454
+ mark(name, metadata) {
455
+ this._marks.set(name, { name, startTime: performance.now(), metadata });
456
+ }
457
+ measure(name) {
458
+ const mark = this._marks.get(name);
459
+ if (!mark) return null;
460
+ const endTime = performance.now();
461
+ const entry = { ...mark, endTime, duration: endTime - mark.startTime };
462
+ this._marks.delete(name);
463
+ this._completed.push(entry);
464
+ return entry;
465
+ }
466
+ async timeAsync(name, fn) {
467
+ this.mark(name);
468
+ try {
469
+ const result = await fn();
470
+ this.measure(name);
471
+ return result;
472
+ } catch (err) {
473
+ this.measure(name);
474
+ throw err;
475
+ }
476
+ }
477
+ timeSync(name, fn) {
478
+ this.mark(name);
479
+ try {
480
+ const result = fn();
481
+ this.measure(name);
482
+ return result;
483
+ } catch (err) {
484
+ this.measure(name);
485
+ throw err;
486
+ }
487
+ }
488
+ getCompleted() {
489
+ return [...this._completed];
490
+ }
491
+ getByName(name) {
492
+ return this._completed.filter((m) => m.name === name);
493
+ }
494
+ getAverage(name) {
495
+ const entries = this._completed.filter((m) => m.name === name && m.duration !== void 0);
496
+ if (!entries.length) return null;
497
+ return entries.reduce((sum, m) => sum + m.duration, 0) / entries.length;
498
+ }
499
+ clear() {
500
+ this._marks.clear();
501
+ this._completed = [];
502
+ }
503
+ };
504
+
505
+ // src/observability/error-reporter.service.ts
506
+ var JoopErrorReporter = class {
507
+ _handlers = [];
508
+ _userId = "";
509
+ _sessionId = "";
510
+ _context = {};
511
+ setUser(userId) {
512
+ this._userId = userId;
513
+ }
514
+ setSession(sessionId) {
515
+ this._sessionId = sessionId;
516
+ }
517
+ setContext(ctx) {
518
+ this._context = { ...this._context, ...ctx };
519
+ }
520
+ addHandler(handler) {
521
+ this._handlers.push(handler);
522
+ return () => {
523
+ this._handlers = this._handlers.filter((h) => h !== handler);
524
+ };
525
+ }
526
+ capture(error, extra) {
527
+ const err = error instanceof Error ? error : new Error(String(error));
528
+ const report = {
529
+ id: crypto.randomUUID(),
530
+ message: err.message,
531
+ stack: err.stack,
532
+ context: { ...this._context, ...extra },
533
+ timestamp: Date.now(),
534
+ ...this._userId ? { userId: this._userId } : {},
535
+ ...this._sessionId ? { sessionId: this._sessionId } : {}
536
+ };
537
+ this._handlers.forEach((h) => Promise.resolve(h(report)).catch(() => {
538
+ }));
539
+ return report;
540
+ }
541
+ captureMessage(message, extra) {
542
+ return this.capture(new Error(message), extra);
543
+ }
544
+ clear() {
545
+ this._handlers = [];
546
+ this._userId = "";
547
+ this._sessionId = "";
548
+ this._context = {};
549
+ }
550
+ };
551
+
552
+ exports.JoopAuditLog = JoopAuditLog;
553
+ exports.JoopCorrelationService = JoopCorrelationService;
554
+ exports.JoopErrorReporter = JoopErrorReporter;
555
+ exports.JoopPerformanceService = JoopPerformanceService;
556
+ exports.JoopSessionRecorder = JoopSessionRecorder;
557
+ exports.JoopWebVitals = JoopWebVitals;
558
+ //# sourceMappingURL=index.js.map
559
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/events/index.ts","../../src/observability/web-vitals.ts","../../src/observability/session-recorder.ts","../../src/observability/correlation.service.ts","../../src/observability/audit-log.service.ts","../../src/observability/performance.service.ts","../../src/observability/error-reporter.service.ts"],"names":["e"],"mappings":";;;AAOO,IAAM,cAAN,MAAqB;AAAA,EAClB,aAA4B,EAAC;AAAA,EAErC,UAAU,QAAA,EAAoC;AAC5C,IAAA,IAAA,CAAK,UAAA,CAAW,KAAK,QAAQ,CAAA;AAC7B,IAAA,OAAO,MAAM;AACX,MAAA,IAAA,CAAK,aAAa,IAAA,CAAK,UAAA,CAAW,MAAA,CAAO,CAAA,CAAA,KAAK,MAAM,QAAQ,CAAA;AAAA,IAC9D,CAAA;AAAA,EACF;AAAA,EAEA,KAAK,KAAA,EAAgB;AACnB,IAAA,KAAA,MAAW,QAAA,IAAY,KAAK,UAAA,EAAY;AACtC,MAAA,QAAA,CAAS,KAAK,CAAA;AAAA,IAChB;AAAA,EACF;AAAA,EAEA,YAAA,GAAkC;AAChC,IAAA,OAAO,IAAI,cAAA,CAAkB,CAAA,QAAA,KAAY,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAC,CAAA;AAAA,EACnE;AACF,CAAA;AAMO,IAAM,mBAAA,GAAN,cAAqC,WAAA,CAAe;AAAA,EACjD,MAAA;AAAA,EAER,YAAY,YAAA,EAAiB;AAC3B,IAAA,KAAA,EAAM;AACN,IAAA,IAAA,CAAK,MAAA,GAAS,YAAA;AAAA,EAChB;AAAA,EAEA,QAAA,GAAc;AACZ,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EACd;AAAA,EAES,KAAK,KAAA,EAAgB;AAC5B,IAAA,IAAA,CAAK,MAAA,GAAS,KAAA;AACd,IAAA,KAAA,CAAM,KAAK,KAAK,CAAA;AAAA,EAClB;AAAA,EAES,UAAU,QAAA,EAAoC;AACrD,IAAA,QAAA,CAAS,KAAK,MAAM,CAAA;AACpB,IAAA,OAAO,KAAA,CAAM,UAAU,QAAQ,CAAA;AAAA,EACjC;AAAA,EAES,YAAA,GAAkC;AACzC,IAAA,OAAO,IAAI,cAAA,CAAkB,CAAA,QAAA,KAAY,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAC,CAAA;AAAA,EACnE;AACF,CAAA;AAKO,IAAM,iBAAN,MAAwB;AAAA,EAC7B,YAAoB,YAAA,EAAsD;AAAtD,IAAA,IAAA,CAAA,YAAA,GAAA,YAAA;AAAA,EAAuD;AAAA,EAAvD,YAAA;AAAA,EAEpB,UAAU,QAAA,EAAoC;AAC5C,IAAA,OAAO,IAAA,CAAK,aAAa,QAAQ,CAAA;AAAA,EACnC;AAAA;AAAA,EAGA,OAAA,GAAyB;AACvB,IAAA,IAAI,MAAA;AACJ,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,SAAA,CAAU,CAAA,CAAA,KAAK;AAAE,MAAA,MAAA,GAAS,CAAA;AAAA,IAAG,CAAC,CAAA;AACjD,IAAA,KAAA,EAAM;AACN,IAAA,OAAO,MAAA;AAAA,EACT;AACF,CAAA;;;ACzDA,IAAM,UAAA,GAA+C;AAAA,EACnD,GAAA,EAAM,CAAC,IAAA,EAAM,GAAI,CAAA;AAAA,EACjB,GAAA,EAAM,CAAC,GAAA,EAAK,GAAG,CAAA;AAAA,EACf,GAAA,EAAM,CAAC,GAAA,EAAK,GAAG,CAAA;AAAA,EACf,GAAA,EAAM,CAAC,GAAA,EAAK,IAAI,CAAA;AAAA,EAChB,IAAA,EAAM,CAAC,GAAA,EAAK,IAAI,CAAA;AAAA,EAChB,GAAA,EAAM,CAAC,IAAA,EAAM,GAAI;AACnB,CAAA;AAEO,IAAM,gBAAN,MAAoB;AAAA,EACjB,UAAuC,EAAC;AAAA,EACxC,QAAA,GAAW,IAAI,WAAA,EAA6B;AAAA,EAC5C,UAAA,GAAa,IAAI,mBAAA,CAAwC,IAAA,CAAK,gBAAgB,CAAA;AAAA,EAC9E,aAAoC,EAAC;AAAA,EACrC,QAAA,GAAW,KAAA;AAAA,EAEnB,KAAA,GAAc;AACZ,IAAA,IAAI,IAAA,CAAK,QAAA,IAAY,OAAO,mBAAA,KAAwB,WAAA,EAAa;AACjE,IAAA,IAAA,CAAK,QAAA,GAAW,IAAA;AAChB,IAAA,IAAA,CAAK,WAAA,EAAY;AACjB,IAAA,IAAA,CAAK,WAAA,EAAY;AACjB,IAAA,IAAA,CAAK,WAAA,EAAY;AACjB,IAAA,IAAA,CAAK,WAAA,EAAY;AACjB,IAAA,IAAA,CAAK,YAAA,EAAa;AAClB,IAAA,IAAA,CAAK,WAAA,EAAY;AAAA,EACnB;AAAA,EAEA,IAAA,GAAa;AACX,IAAA,IAAA,CAAK,QAAA,GAAW,KAAA;AAChB,IAAA,KAAA,MAAW,GAAA,IAAO,KAAK,UAAA,EAAY;AAAE,MAAA,IAAI;AAAE,QAAA,GAAA,CAAI,UAAA,EAAW;AAAA,MAAG,CAAA,CAAA,MAAQ;AAAA,MAAC;AAAA,IAAE;AACxE,IAAA,IAAA,CAAK,aAAa,EAAC;AAAA,EACrB;AAAA,EAEA,QAAA,GAA+B;AAAE,IAAA,OAAO,KAAK,cAAA,EAAe;AAAA,EAAG;AAAA,EAC/D,OAAA,GAAU;AAAE,IAAA,OAAO,IAAA,CAAK,SAAS,YAAA,EAAa;AAAA,EAAG;AAAA,EACjD,SAAA,GAAY;AAAE,IAAA,OAAO,IAAA,CAAK,WAAW,YAAA,EAAa;AAAA,EAAG;AAAA,EAErD,MAAA,GAAwB;AAAE,IAAA,OAAO,IAAA,CAAK,QAAQ,GAAA,IAAO,IAAA;AAAA,EAAM;AAAA,EAC3D,MAAA,GAAwB;AAAE,IAAA,OAAO,IAAA,CAAK,QAAQ,GAAA,IAAO,IAAA;AAAA,EAAM;AAAA,EAC3D,MAAA,GAAwB;AAAE,IAAA,OAAO,IAAA,CAAK,QAAQ,GAAA,IAAO,IAAA;AAAA,EAAM;AAAA,EAC3D,OAAA,GAAyB;AAAE,IAAA,OAAO,IAAA,CAAK,QAAQ,IAAA,IAAQ,IAAA;AAAA,EAAM;AAAA,EAC7D,MAAA,GAAwB;AAAE,IAAA,OAAO,IAAA,CAAK,QAAQ,GAAA,IAAO,IAAA;AAAA,EAAM;AAAA,EAC3D,MAAA,GAAwB;AAAE,IAAA,OAAO,IAAA,CAAK,QAAQ,GAAA,IAAO,IAAA;AAAA,EAAM;AAAA,EAE3D,UAAU,MAAA,EAAuD;AAC/D,IAAA,MAAM,KAAA,GAAS,IAAA,CAAK,OAAA,CAA0C,MAAM,CAAA;AACpE,IAAA,OAAO,KAAA,CAAM,MAAA,EAAQ,KAAA,IAAS,IAAI,CAAA;AAAA,EACpC;AAAA,EAEQ,OAAA,CAAQ,QAAsD,KAAA,EAAqB;AACzF,IAAC,IAAA,CAAK,OAAA,CAAmC,MAAM,CAAA,GAAI,KAAA;AACnD,IAAA,MAAM,MAAA,GAAS,KAAA,CAAM,MAAA,EAAkB,KAAK,CAAA;AAC5C,IAAA,IAAA,CAAK,SAAS,IAAA,CAAK,EAAE,MAAA,EAAQ,KAAA,EAAO,QAAQ,CAAA;AAC5C,IAAA,IAAA,CAAK,UAAA,CAAW,IAAA,CAAK,IAAA,CAAK,cAAA,EAAgB,CAAA;AAAA,EAC5C;AAAA,EAEQ,QAAA,CAAS,OAAiB,QAAA,EAA8D;AAC9F,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,IAAI,mBAAA,CAAoB,QAAQ,CAAA;AAC5C,MAAA,GAAA,CAAI,OAAA,CAAQ,EAAE,IAAA,EAAM,KAAA,CAAM,CAAC,CAAA,EAAG,QAAA,EAAU,MAAM,CAAA;AAC9C,MAAA,IAAA,CAAK,UAAA,CAAW,KAAK,GAAG,CAAA;AAAA,IAC1B,CAAA,CAAA,MAAQ;AAAA,IAAC;AAAA,EACX;AAAA,EAEQ,WAAA,GAAoB;AAC1B,IAAA,IAAA,CAAK,QAAA,CAAS,CAAC,0BAA0B,CAAA,EAAG,CAAA,IAAA,KAAQ;AAClD,MAAA,MAAM,OAAA,GAAU,KAAK,UAAA,EAAW;AAChC,MAAA,IAAI,OAAA,CAAQ,QAAQ,IAAA,CAAK,OAAA,CAAQ,OAAQ,OAAA,CAAQ,OAAA,CAAQ,MAAA,GAAS,CAAC,CAAA,CAAoE,UAAA,IAAe,QAAQ,OAAA,CAAQ,MAAA,GAAS,CAAC,CAAA,CAAoE,QAAA,IAAY,QAAQ,OAAA,CAAQ,MAAA,GAAS,CAAC,CAAA,CAAE,SAAS,CAAA;AAAA,IACvS,CAAC,CAAA;AAAA,EACH;AAAA,EAEQ,WAAA,GAAoB;AAC1B,IAAA,IAAA,CAAK,QAAA,CAAS,CAAC,aAAa,CAAA,EAAG,CAAA,IAAA,KAAQ;AACrC,MAAA,MAAM,CAAA,GAAI,IAAA,CAAK,UAAA,EAAW,CAAE,CAAC,CAAA;AAC7B,MAAA,IAAI,CAAA,IAAK,EAAE,eAAA,EAAiB,IAAA,CAAK,QAAQ,KAAA,EAAO,CAAA,CAAE,eAAA,GAAkB,CAAA,CAAE,SAAS,CAAA;AAAA,IACjF,CAAC,CAAA;AAAA,EACH;AAAA,EAEQ,WAAA,GAAoB;AAC1B,IAAA,IAAA,CAAK,QAAA,CAAS,CAAC,OAAO,CAAA,EAAG,CAAA,IAAA,KAAQ;AAC/B,MAAA,IAAI,GAAA,GAAM,IAAA,CAAK,OAAA,CAAQ,GAAA,IAAO,CAAA;AAC9B,MAAA,KAAA,MAAW,CAAA,IAAK,IAAA,CAAK,UAAA,EAAW,EAAG;AACjC,QAAA,MAAM,KAAA,GAAQ,CAAA;AACd,QAAA,IAAI,KAAA,CAAM,eAAe,GAAA,GAAM,IAAA,CAAK,IAAI,GAAA,EAAK,KAAA,CAAM,aAAA,GAAgB,KAAA,CAAM,SAAS,CAAA;AAAA,MACpF;AACA,MAAA,IAAI,GAAA,GAAM,CAAA,EAAG,IAAA,CAAK,OAAA,CAAQ,OAAO,GAAG,CAAA;AAAA,IACtC,CAAC,CAAA;AAAA,EACH;AAAA,EAEQ,WAAA,GAAoB;AAC1B,IAAA,IAAI,QAAA,GAAW,CAAA;AACf,IAAA,IAAI,YAAA,GAAe,CAAA;AACnB,IAAA,IAAI,SAAA,GAAY,CAAA;AAChB,IAAA,IAAA,CAAK,QAAA,CAAS,CAAC,cAAc,CAAA,EAAG,CAAA,IAAA,KAAQ;AACtC,MAAA,KAAA,MAAW,CAAA,IAAK,IAAA,CAAK,UAAA,EAAW,EAAG;AACjC,QAAA,MAAM,KAAA,GAAQ,CAAA;AACd,QAAA,IAAI,MAAM,cAAA,EAAgB;AAC1B,QAAA,IAAI,SAAA,GAAY,CAAA,IAAM,KAAA,CAAM,SAAA,GAAY,YAAa,GAAA,EAAM;AACzD,UAAA,IAAI,KAAA,CAAM,SAAA,GAAY,YAAA,GAAe,GAAA,EAAM;AAAE,YAAA,QAAA,GAAW,CAAA;AAAG,YAAA,YAAA,GAAe,KAAA,CAAM,SAAA;AAAA,UAAW;AAAA,QAC7F;AACA,QAAA,IAAI,SAAA,KAAc,CAAA,EAAG,YAAA,GAAe,KAAA,CAAM,SAAA;AAC1C,QAAA,QAAA,IAAY,MAAM,KAAA,IAAS,CAAA;AAC3B,QAAA,SAAA,GAAY,KAAA,CAAM,SAAA;AAClB,QAAA,IAAA,CAAK,OAAA,CAAQ,OAAO,QAAQ,CAAA;AAAA,MAC9B;AAAA,IACF,CAAC,CAAA;AAAA,EACH;AAAA,EAEQ,YAAA,GAAqB;AAC3B,IAAA,MAAM,GAAA,GAAM,WAAA,CAAY,gBAAA,GAAmB,YAAY,IAAI,CAAC,CAAA;AAC5D,IAAA,IAAI,KAAK,aAAA,EAAe,IAAA,CAAK,OAAA,CAAQ,MAAA,EAAQ,IAAI,aAAa,CAAA;AAC9D,IAAA,IAAA,CAAK,QAAA,CAAS,CAAC,YAAY,CAAA,EAAG,CAAA,IAAA,KAAQ;AACpC,MAAA,MAAM,CAAA,GAAI,IAAA,CAAK,UAAA,EAAW,CAAE,CAAC,CAAA;AAC7B,MAAA,IAAI,GAAG,aAAA,EAAe,IAAA,CAAK,OAAA,CAAQ,MAAA,EAAQ,EAAE,aAAa,CAAA;AAAA,IAC5D,CAAC,CAAA;AAAA,EACH;AAAA,EAEQ,WAAA,GAAoB;AAC1B,IAAA,IAAA,CAAK,QAAA,CAAS,CAAC,OAAO,CAAA,EAAG,CAAA,IAAA,KAAQ;AAC/B,MAAA,MAAM,CAAA,GAAI,KAAK,UAAA,EAAW,CAAE,KAAK,CAAAA,EAAAA,KAAKA,EAAAA,CAAE,IAAA,KAAS,wBAAwB,CAAA;AACzE,MAAA,IAAI,CAAA,EAAG,IAAA,CAAK,OAAA,CAAQ,KAAA,EAAO,EAAE,SAAS,CAAA;AAAA,IACxC,CAAC,CAAA;AAAA,EACH;AAAA,EAEQ,cAAA,GAAqC;AAC3C,IAAA,OAAO;AAAA,MACL,GAAA,EAAK,IAAA,CAAK,OAAA,CAAQ,GAAA,IAAO,IAAA;AAAA,MACzB,GAAA,EAAK,IAAA,CAAK,OAAA,CAAQ,GAAA,IAAO,IAAA;AAAA,MACzB,GAAA,EAAK,IAAA,CAAK,OAAA,CAAQ,GAAA,IAAO,IAAA;AAAA,MACzB,GAAA,EAAK,IAAA,CAAK,OAAA,CAAQ,GAAA,IAAO,IAAA;AAAA,MACzB,IAAA,EAAM,IAAA,CAAK,OAAA,CAAQ,IAAA,IAAQ,IAAA;AAAA,MAC3B,GAAA,EAAK,IAAA,CAAK,OAAA,CAAQ,GAAA,IAAO,IAAA;AAAA,MACzB,UAAA,EAAY,KAAK,GAAA;AAAI,KACvB;AAAA,EACF;AACF;AAEA,SAAS,KAAA,CAAM,QAAgB,KAAA,EAA6D;AAC1F,EAAA,IAAI,KAAA,KAAU,MAAM,OAAO,MAAA;AAC3B,EAAA,MAAM,CAAC,MAAM,IAAI,CAAA,GAAI,WAAW,MAAM,CAAA,IAAK,CAAC,QAAA,EAAU,QAAQ,CAAA;AAC9D,EAAA,OAAO,KAAA,IAAS,IAAA,GAAO,MAAA,GAAS,KAAA,IAAS,OAAO,mBAAA,GAAsB,MAAA;AACxE;;;ACrIO,IAAM,sBAAN,MAA0B;AAAA,EACvB,UAA+B,EAAC;AAAA,EAChC,QAAA,GAAW,KAAA;AAAA,EACX,OAAA,GAAU,KAAA;AAAA,EACV,UAAA,GAAa,CAAA;AAAA,EACb,KAAA,GAA8C;AAAA,IACpD,eAAe,EAAC;AAAA,IAAG,iBAAiB,EAAC;AAAA,IACrC,YAAA,EAAc,IAAA;AAAA,IAAM,SAAA,EAAW,GAAA;AAAA,IAC/B,aAAA,EAAe,IAAA;AAAA,IAAM,aAAA,EAAe;AAAA,GACtC;AAAA,EACQ,WAA8B,EAAC;AAAA,EAC/B,iBAAA,GAA6C,IAAA;AAAA,EAC7C,YAAA,GAAqD,IAAA;AAAA,EAE7D,KAAA,CAAM,OAAA,GAAsC,EAAC,EAAS;AACpD,IAAA,IAAI,KAAK,QAAA,EAAU;AACnB,IAAA,IAAA,CAAK,QAAQ,EAAE,GAAG,IAAA,CAAK,KAAA,EAAO,GAAG,OAAA,EAAQ;AACzC,IAAA,IAAA,CAAK,QAAA,GAAW,IAAA;AAAM,IAAA,IAAA,CAAK,OAAA,GAAU,KAAA;AACrC,IAAA,IAAA,CAAK,UAAU,EAAC;AAAG,IAAA,IAAA,CAAK,UAAA,GAAa,KAAK,GAAA,EAAI;AAC9C,IAAA,IAAA,CAAK,gBAAA,EAAiB;AAAA,EACxB;AAAA,EAEA,KAAA,GAAc;AAAE,IAAA,IAAA,CAAK,OAAA,GAAU,IAAA;AAAA,EAAM;AAAA,EACrC,MAAA,GAAe;AAAE,IAAA,IAAA,CAAK,OAAA,GAAU,KAAA;AAAA,EAAO;AAAA,EAEvC,IAAA,GAA0B;AACxB,IAAA,IAAA,CAAK,QAAA,GAAW,KAAA;AAAO,IAAA,IAAA,CAAK,OAAA,GAAU,KAAA;AACtC,IAAA,IAAA,CAAK,OAAA,EAAQ;AACb,IAAA,OAAO;AAAA,MACL,WAAW,IAAA,CAAK,UAAA;AAAA,MAAY,SAAA,EAAW,KAAK,GAAA,EAAI;AAAA,MAChD,MAAA,EAAQ,CAAC,GAAG,IAAA,CAAK,OAAO,CAAA;AAAA,MACxB,GAAA,EAAK,OAAO,QAAA,KAAa,WAAA,GAAc,SAAS,IAAA,GAAO,EAAA;AAAA,MACvD,SAAA,EAAW,OAAO,SAAA,KAAc,WAAA,GAAc,UAAU,SAAA,GAAY;AAAA,KACtE;AAAA,EACF;AAAA,EAEA,MAAA,GAA8B;AAAE,IAAA,OAAO,CAAC,GAAG,IAAA,CAAK,OAAO,CAAA;AAAA,EAAG;AAAA,EAE1D,MAAA,CAAO,SAAgC,MAAA,EAAgB;AACrD,IAAA,MAAM,MAAA,GAA4B;AAAA,MAChC,WAAW,IAAA,CAAK,UAAA;AAAA,MAAY,SAAA,EAAW,KAAK,GAAA,EAAI;AAAA,MAChD,QAAQ,IAAA,CAAK,OAAA;AAAA,MAAS,GAAA,EAAK,OAAO,QAAA,KAAa,WAAA,GAAc,SAAS,IAAA,GAAO,EAAA;AAAA,MAAI,SAAA,EAAW,OAAO,SAAA,KAAc,WAAA,GAAc,UAAU,SAAA,GAAY;AAAA,KACvJ;AACA,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,SAAA,CAAU,MAAM,CAAA;AAClC,IAAA,IAAI,WAAW,YAAA,EAAc;AAC3B,MAAA,IAAI;AAAE,QAAA,OAAO,KAAK,IAAI,CAAA;AAAA,MAAG,CAAA,CAAA,MAAQ;AAAE,QAAA,OAAO,IAAA;AAAA,MAAM;AAAA,IAClD;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,QAAA,CAAS,MAA6B,IAAA,EAAsC;AAC1E,IAAA,IAAA,CAAK,KAAA,CAAM,EAAE,IAAA,EAAM,SAAA,EAAW,KAAK,GAAA,EAAI,EAAG,MAAM,CAAA;AAAA,EAClD;AAAA,EAEQ,MAAM,KAAA,EAAgC;AAC5C,IAAA,IAAI,CAAC,IAAA,CAAK,QAAA,IAAY,IAAA,CAAK,OAAA,EAAS;AACpC,IAAA,IAAI,IAAA,CAAK,QAAQ,MAAA,IAAU,IAAA,CAAK,MAAM,SAAA,EAAW,IAAA,CAAK,QAAQ,KAAA,EAAM;AACpE,IAAA,IAAA,CAAK,OAAA,CAAQ,KAAK,KAAK,CAAA;AAAA,EACzB;AAAA,EAEQ,gBAAA,GAAyB;AAE/B,IAAA,IAAA,CAAK,iBAAA,GAAoB,IAAI,gBAAA,CAAiB,CAAA,SAAA,KAAa;AACzD,MAAA,KAAA,MAAW,KAAK,SAAA,EAAW;AACzB,QAAA,IAAI,IAAA,CAAK,aAAA,CAAc,CAAA,CAAE,MAAiB,CAAA,EAAG;AAC7C,QAAA,IAAA,CAAK,KAAA,CAAM,EAAE,IAAA,EAAM,cAAA,EAAgB,SAAA,EAAW,IAAA,CAAK,GAAA,EAAI,EAAG,QAAA,EAAU,SAAA,CAAU,CAAA,CAAE,MAAiB,CAAA,EAAG,IAAA,EAAM,EAAE,UAAA,EAAY,CAAA,CAAE,UAAA,CAAW,MAAA,EAAQ,YAAA,EAAc,CAAA,CAAE,YAAA,CAAa,MAAA,EAAQ,IAAA,EAAM,CAAA,CAAE,IAAA,EAAK,EAAG,CAAA;AAAA,MACpM;AAAA,IACF,CAAC,CAAA;AACD,IAAA,IAAA,CAAK,iBAAA,CAAkB,QAAQ,QAAA,CAAS,eAAA,EAAiB,EAAE,SAAA,EAAW,IAAA,EAAM,SAAS,IAAA,EAAM,UAAA,EAAY,MAAM,aAAA,EAAe,KAAA,EAAO,iBAAiB,CAAC,OAAA,EAAS,SAAS,QAAA,EAAU,UAAU,GAAG,CAAA;AAG9L,IAAA,MAAM,OAAA,GAAU,CAAC,CAAA,KAAkB;AACjC,MAAA,MAAM,KAAK,CAAA,CAAE,MAAA;AACb,MAAA,IAAI,IAAA,CAAK,aAAA,CAAc,EAAE,CAAA,EAAG;AAC5B,MAAA,IAAA,CAAK,KAAA,CAAM,EAAE,IAAA,EAAM,OAAA,EAAS,SAAA,EAAW,IAAA,CAAK,GAAA,EAAI,EAAG,QAAA,EAAU,SAAA,CAAU,EAAE,CAAA,EAAG,CAAA;AAAA,IAC9E,CAAA;AACA,IAAA,QAAA,CAAS,iBAAiB,OAAA,EAAS,OAAA,EAAS,EAAE,OAAA,EAAS,MAAM,CAAA;AAC7D,IAAA,IAAA,CAAK,QAAA,CAAS,IAAA,CAAK,MAAM,QAAA,CAAS,mBAAA,CAAoB,OAAA,EAAS,OAAA,EAAS,EAAE,OAAA,EAAS,IAAA,EAAM,CAAC,CAAA;AAG1F,IAAA,MAAM,OAAA,GAAU,CAAC,CAAA,KAAa;AAC5B,MAAA,MAAM,KAAK,CAAA,CAAE,MAAA;AACb,MAAA,IAAI,IAAA,CAAK,aAAA,CAAc,EAAE,CAAA,EAAG;AAC5B,MAAA,MAAM,SAAS,IAAA,CAAK,KAAA,CAAM,iBAAiB,EAAA,CAAG,IAAA,KAAS,cAAc,EAAA,CAAG,OAAA,EAAS,QAAQ,MAAA,IAAa,IAAA,CAAK,MAAM,aAAA,CAAc,IAAA,CAAK,OAAK,EAAA,CAAG,OAAA,CAAQ,CAAC,CAAC,CAAA,CAAA;AACtJ,MAAA,IAAA,CAAK,MAAM,EAAE,IAAA,EAAM,OAAA,EAAS,SAAA,EAAW,KAAK,GAAA,EAAI,EAAG,QAAA,EAAU,SAAA,CAAU,EAAE,CAAA,EAAG,KAAA,EAAO,MAAA,GAAS,KAAA,GAAQ,QAAW,CAAA;AAAA,IACjH,CAAA;AACA,IAAA,QAAA,CAAS,iBAAiB,OAAA,EAAS,OAAA,EAAS,EAAE,OAAA,EAAS,MAAM,CAAA;AAC7D,IAAA,IAAA,CAAK,QAAA,CAAS,IAAA,CAAK,MAAM,QAAA,CAAS,mBAAA,CAAoB,OAAA,EAAS,OAAA,EAAS,EAAE,OAAA,EAAS,IAAA,EAAM,CAAC,CAAA;AAG1F,IAAA,IAAI,IAAA,CAAK,MAAM,aAAA,EAAe;AAC5B,MAAA,MAAM,WAAW,MAAM;AACrB,QAAA,IAAI,KAAK,YAAA,EAAc;AACvB,QAAA,IAAA,CAAK,YAAA,GAAe,WAAW,MAAM;AACnC,UAAA,IAAA,CAAK,YAAA,GAAe,IAAA;AACpB,UAAA,IAAA,CAAK,MAAM,EAAE,IAAA,EAAM,QAAA,EAAU,SAAA,EAAW,KAAK,GAAA,EAAI,EAAG,IAAA,EAAM,EAAE,GAAG,MAAA,CAAO,OAAA,EAAS,GAAG,MAAA,CAAO,OAAA,IAAW,CAAA;AAAA,QACtG,GAAG,GAAG,CAAA;AAAA,MACR,CAAA;AACA,MAAA,MAAA,CAAO,iBAAiB,QAAA,EAAU,QAAA,EAAU,EAAE,OAAA,EAAS,MAAM,CAAA;AAC7D,MAAA,IAAA,CAAK,SAAS,IAAA,CAAK,MAAM,OAAO,mBAAA,CAAoB,QAAA,EAAU,QAAQ,CAAC,CAAA;AAAA,IACzE;AAGA,IAAA,IAAI,IAAA,CAAK,MAAM,aAAA,EAAe;AAC5B,MAAA,IAAI,WAAA,GAAoD,IAAA;AACxD,MAAA,MAAM,WAAW,MAAM;AACrB,QAAA,IAAI,WAAA,EAAa;AACjB,QAAA,WAAA,GAAc,WAAW,MAAM;AAC7B,UAAA,WAAA,GAAc,IAAA;AACd,UAAA,IAAA,CAAK,MAAM,EAAE,IAAA,EAAM,QAAA,EAAU,SAAA,EAAW,KAAK,GAAA,EAAI,EAAG,IAAA,EAAM,EAAE,GAAG,MAAA,CAAO,UAAA,EAAY,GAAG,MAAA,CAAO,WAAA,IAAe,CAAA;AAAA,QAC7G,GAAG,GAAG,CAAA;AAAA,MACR,CAAA;AACA,MAAA,MAAA,CAAO,iBAAiB,QAAA,EAAU,QAAA,EAAU,EAAE,OAAA,EAAS,MAAM,CAAA;AAC7D,MAAA,IAAA,CAAK,SAAS,IAAA,CAAK,MAAM,OAAO,mBAAA,CAAoB,QAAA,EAAU,QAAQ,CAAC,CAAA;AAAA,IACzE;AAGA,IAAA,MAAM,QAAQ,MAAM,IAAA,CAAK,KAAA,CAAM,EAAE,MAAM,YAAA,EAAc,SAAA,EAAW,IAAA,CAAK,GAAA,IAAO,IAAA,EAAM,EAAE,KAAK,QAAA,CAAS,IAAA,IAAQ,CAAA;AAC1G,IAAA,MAAA,CAAO,gBAAA,CAAiB,YAAY,KAAK,CAAA;AACzC,IAAA,IAAA,CAAK,SAAS,IAAA,CAAK,MAAM,OAAO,mBAAA,CAAoB,UAAA,EAAY,KAAK,CAAC,CAAA;AAAA,EACxE;AAAA,EAEQ,OAAA,GAAgB;AACtB,IAAA,IAAA,CAAK,mBAAmB,UAAA,EAAW;AAAG,IAAA,IAAA,CAAK,iBAAA,GAAoB,IAAA;AAC/D,IAAA,KAAA,MAAW,EAAA,IAAM,IAAA,CAAK,QAAA,EAAU,EAAA,EAAG;AACnC,IAAA,IAAA,CAAK,WAAW,EAAC;AAAA,EACnB;AAAA,EAEQ,cAAc,EAAA,EAA6B;AACjD,IAAA,IAAI,CAAC,IAAI,OAAO,KAAA;AAChB,IAAA,OAAO,IAAA,CAAK,KAAA,CAAM,eAAA,CAAgB,IAAA,CAAK,CAAA,CAAA,KAAK;AAAE,MAAA,IAAI;AAAE,QAAA,OAAO,EAAA,CAAG,UAAU,CAAC,CAAA;AAAA,MAAG,CAAA,CAAA,MAAQ;AAAE,QAAA,OAAO,KAAA;AAAA,MAAO;AAAA,IAAE,CAAC,CAAA;AAAA,EACzG;AACF;AAEA,SAAS,UAAU,EAAA,EAA4B;AAC7C,EAAA,IAAI,CAAC,IAAI,OAAO,EAAA;AAChB,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,IAAI,OAAA,GAA0B,EAAA;AAC9B,EAAA,OAAO,WAAW,OAAA,KAAY,QAAA,CAAS,IAAA,IAAQ,KAAA,CAAM,SAAS,CAAA,EAAG;AAC/D,IAAA,IAAI,IAAA,GAAO,OAAA,CAAQ,OAAA,CAAQ,WAAA,EAAY;AACvC,IAAA,IAAI,QAAQ,EAAA,EAAI;AAAE,MAAA,KAAA,CAAM,OAAA,CAAQ,CAAA,CAAA,EAAI,OAAA,CAAQ,EAAE,CAAA,CAAE,CAAA;AAAG,MAAA;AAAA,IAAO;AAC1D,IAAA,IAAI,OAAA,CAAQ,SAAA,EAAW,IAAA,IAAQ,GAAA,GAAM,MAAM,IAAA,CAAK,OAAA,CAAQ,SAAS,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA,CAAE,KAAK,GAAG,CAAA;AACvF,IAAA,KAAA,CAAM,QAAQ,IAAI,CAAA;AAClB,IAAA,OAAA,GAAU,OAAA,CAAQ,aAAA;AAAA,EACpB;AACA,EAAA,OAAO,KAAA,CAAM,KAAK,KAAK,CAAA;AACzB;;;AC7KO,IAAM,yBAAN,MAA6B;AAAA,EAC1B,cAAA,GAAiB,EAAA;AAAA,EACjB,UAAA,GAAa,EAAA;AAAA,EAErB,cAAA,GAAyB;AACvB,IAAA,IAAA,CAAK,cAAA,GAAiB,OAAO,UAAA,EAAW;AACxC,IAAA,OAAO,IAAA,CAAK,cAAA;AAAA,EACd;AAAA,EAEA,UAAA,GAAqB;AACnB,IAAA,IAAA,CAAK,UAAA,GAAa,OAAO,UAAA,EAAW;AACpC,IAAA,OAAO,IAAA,CAAK,UAAA;AAAA,EACd;AAAA,EAEA,gBAAA,GAA2B;AAAE,IAAA,OAAO,IAAA,CAAK,cAAA;AAAA,EAAgB;AAAA,EACzD,YAAA,GAAuB;AAAE,IAAA,OAAO,IAAA,CAAK,UAAA;AAAA,EAAY;AAAA,EAEjD,OAAA,GAAkC;AAChC,IAAA,MAAM,IAA4B,EAAC;AACnC,IAAA,IAAI,IAAA,CAAK,cAAA,EAAgB,CAAA,CAAE,kBAAkB,IAAI,IAAA,CAAK,cAAA;AACtD,IAAA,IAAI,IAAA,CAAK,UAAA,EAAY,CAAA,CAAE,cAAc,IAAI,IAAA,CAAK,UAAA;AAC9C,IAAA,OAAO,CAAA;AAAA,EACT;AAAA,EAEA,KAAA,GAAc;AAAE,IAAA,IAAA,CAAK,cAAA,GAAiB,EAAA;AAAI,IAAA,IAAA,CAAK,UAAA,GAAa,EAAA;AAAA,EAAI;AAClE;;;ACJO,IAAM,eAAN,MAAmB;AAAA,EAIxB,WAAA,CAAoB,cAAc,GAAA,EAAK;AAAnB,IAAA,IAAA,CAAA,WAAA,GAAA,WAAA;AAAA,EAAoB;AAAA,EAApB,WAAA;AAAA,EAHZ,WAA6B,EAAC;AAAA,EAC9B,aAAkC,EAAC;AAAA,EAI3C,MAAA,CAAO,MAAA,EAAyB,OAAA,GAM5B,EAAC,EAAmB;AACtB,IAAA,MAAM,KAAA,GAAwB;AAAA,MAC5B,EAAA,EAAI,OAAO,UAAA,EAAW;AAAA,MACtB,MAAA;AAAA,MACA,SAAA,EAAW,KAAK,GAAA,EAAI;AAAA,MACpB,OAAA,EAAS,QAAQ,OAAA,IAAW,IAAA;AAAA,MAC5B,GAAG;AAAA,KACL;AACA,IAAA,IAAA,CAAK,QAAA,CAAS,KAAK,KAAK,CAAA;AACxB,IAAA,IAAI,IAAA,CAAK,QAAA,CAAS,MAAA,GAAS,IAAA,CAAK,WAAA,EAAa,IAAA,CAAK,QAAA,GAAW,IAAA,CAAK,QAAA,CAAS,KAAA,CAAM,CAAC,IAAA,CAAK,WAAW,CAAA;AAClG,IAAA,IAAA,CAAK,UAAA,CAAW,OAAA,CAAQ,CAAA,CAAA,KAAK,CAAA,CAAE,KAAK,CAAC,CAAA;AACrC,IAAA,OAAO,KAAA;AAAA,EACT;AAAA,EAEA,MAAA,GAA2B;AAAE,IAAA,OAAO,CAAC,GAAG,IAAA,CAAK,QAAQ,CAAA;AAAA,EAAG;AAAA,EACxD,YAAY,MAAA,EAA2C;AAAE,IAAA,OAAO,KAAK,QAAA,CAAS,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,CAAE,WAAW,MAAM,CAAA;AAAA,EAAG;AAAA,EAChH,aAAa,SAAA,EAAqC;AAAE,IAAA,OAAO,KAAK,QAAA,CAAS,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,CAAE,cAAc,SAAS,CAAA;AAAA,EAAG;AAAA,EACjH,UAAU,MAAA,EAAkC;AAAE,IAAA,OAAO,KAAK,QAAA,CAAS,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,CAAE,WAAW,MAAM,CAAA;AAAA,EAAG;AAAA,EAErG,SAAS,QAAA,EAAyC;AAChD,IAAA,IAAA,CAAK,UAAA,CAAW,KAAK,QAAQ,CAAA;AAC7B,IAAA,OAAO,MAAM;AAAE,MAAA,IAAA,CAAK,aAAa,IAAA,CAAK,UAAA,CAAW,MAAA,CAAO,CAAA,CAAA,KAAK,MAAM,QAAQ,CAAA;AAAA,IAAG,CAAA;AAAA,EAChF;AAAA,EAEA,KAAA,GAAc;AAAE,IAAA,IAAA,CAAK,WAAW,EAAC;AAAA,EAAG;AAAA,EACpC,MAAA,GAAiB;AAAE,IAAA,OAAO,IAAA,CAAK,SAAA,CAAU,IAAA,CAAK,QAAA,EAAU,MAAM,CAAC,CAAA;AAAA,EAAG;AACpE;;;ACnDO,IAAM,yBAAN,MAA6B;AAAA,EAC1B,MAAA,uBAAa,GAAA,EAA0B;AAAA,EACvC,aAA6B,EAAC;AAAA,EAEtC,IAAA,CAAK,MAAc,QAAA,EAA0C;AAC3D,IAAA,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,IAAA,EAAM,EAAE,IAAA,EAAM,WAAW,WAAA,CAAY,GAAA,EAAI,EAAG,QAAA,EAAU,CAAA;AAAA,EACxE;AAAA,EAEA,QAAQ,IAAA,EAAmC;AACzC,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,IAAI,CAAA;AACjC,IAAA,IAAI,CAAC,MAAM,OAAO,IAAA;AAClB,IAAA,MAAM,OAAA,GAAU,YAAY,GAAA,EAAI;AAChC,IAAA,MAAM,KAAA,GAAsB,EAAE,GAAG,IAAA,EAAM,SAAS,QAAA,EAAU,OAAA,GAAU,KAAK,SAAA,EAAU;AACnF,IAAA,IAAA,CAAK,MAAA,CAAO,OAAO,IAAI,CAAA;AACvB,IAAA,IAAA,CAAK,UAAA,CAAW,KAAK,KAAK,CAAA;AAC1B,IAAA,OAAO,KAAA;AAAA,EACT;AAAA,EAEA,MAAM,SAAA,CAAa,IAAA,EAAc,EAAA,EAAkC;AACjE,IAAA,IAAA,CAAK,KAAK,IAAI,CAAA;AACd,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,EAAA,EAAG;AACxB,MAAA,IAAA,CAAK,QAAQ,IAAI,CAAA;AACjB,MAAA,OAAO,MAAA;AAAA,IACT,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA,CAAK,QAAQ,IAAI,CAAA;AACjB,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF;AAAA,EAEA,QAAA,CAAY,MAAc,EAAA,EAAgB;AACxC,IAAA,IAAA,CAAK,KAAK,IAAI,CAAA;AACd,IAAA,IAAI;AACF,MAAA,MAAM,SAAS,EAAA,EAAG;AAClB,MAAA,IAAA,CAAK,QAAQ,IAAI,CAAA;AACjB,MAAA,OAAO,MAAA;AAAA,IACT,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA,CAAK,QAAQ,IAAI,CAAA;AACjB,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF;AAAA,EAEA,YAAA,GAA+B;AAAE,IAAA,OAAO,CAAC,GAAG,IAAA,CAAK,UAAU,CAAA;AAAA,EAAG;AAAA,EAC9D,UAAU,IAAA,EAA8B;AAAE,IAAA,OAAO,KAAK,UAAA,CAAW,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,CAAE,SAAS,IAAI,CAAA;AAAA,EAAG;AAAA,EAE/F,WAAW,IAAA,EAA6B;AACtC,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,UAAA,CAAW,MAAA,CAAO,CAAA,CAAA,KAAK,EAAE,IAAA,KAAS,IAAA,IAAQ,CAAA,CAAE,QAAA,KAAa,MAAS,CAAA;AACvF,IAAA,IAAI,CAAC,OAAA,CAAQ,MAAA,EAAQ,OAAO,IAAA;AAC5B,IAAA,OAAO,OAAA,CAAQ,MAAA,CAAO,CAAC,GAAA,EAAK,CAAA,KAAM,MAAM,CAAA,CAAE,QAAA,EAAW,CAAC,CAAA,GAAI,OAAA,CAAQ,MAAA;AAAA,EACpE;AAAA,EAEA,KAAA,GAAc;AAAE,IAAA,IAAA,CAAK,OAAO,KAAA,EAAM;AAAG,IAAA,IAAA,CAAK,aAAa,EAAC;AAAA,EAAG;AAC7D;;;AChDO,IAAM,oBAAN,MAAwB;AAAA,EACrB,YAAgC,EAAC;AAAA,EACjC,OAAA,GAAU,EAAA;AAAA,EACV,UAAA,GAAa,EAAA;AAAA,EACb,WAAoC,EAAC;AAAA,EAE7C,QAAQ,MAAA,EAAsB;AAAE,IAAA,IAAA,CAAK,OAAA,GAAU,MAAA;AAAA,EAAQ;AAAA,EACvD,WAAW,SAAA,EAAyB;AAAE,IAAA,IAAA,CAAK,UAAA,GAAa,SAAA;AAAA,EAAW;AAAA,EACnE,WAAW,GAAA,EAAoC;AAAE,IAAA,IAAA,CAAK,WAAW,EAAE,GAAG,IAAA,CAAK,QAAA,EAAU,GAAG,GAAA,EAAI;AAAA,EAAG;AAAA,EAE/F,WAAW,OAAA,EAAuC;AAChD,IAAA,IAAA,CAAK,SAAA,CAAU,KAAK,OAAO,CAAA;AAC3B,IAAA,OAAO,MAAM;AAAE,MAAA,IAAA,CAAK,YAAY,IAAA,CAAK,SAAA,CAAU,MAAA,CAAO,CAAA,CAAA,KAAK,MAAM,OAAO,CAAA;AAAA,IAAG,CAAA;AAAA,EAC7E;AAAA,EAEA,OAAA,CAAQ,OAAgB,KAAA,EAAkD;AACxE,IAAA,MAAM,GAAA,GAAM,iBAAiB,KAAA,GAAQ,KAAA,GAAQ,IAAI,KAAA,CAAM,MAAA,CAAO,KAAK,CAAC,CAAA;AACpE,IAAA,MAAM,MAAA,GAA0B;AAAA,MAC9B,EAAA,EAAI,OAAO,UAAA,EAAW;AAAA,MACtB,SAAS,GAAA,CAAI,OAAA;AAAA,MACb,OAAO,GAAA,CAAI,KAAA;AAAA,MACX,SAAS,EAAE,GAAG,IAAA,CAAK,QAAA,EAAU,GAAG,KAAA,EAAM;AAAA,MACtC,SAAA,EAAW,KAAK,GAAA,EAAI;AAAA,MACpB,GAAI,KAAK,OAAA,GAAU,EAAE,QAAQ,IAAA,CAAK,OAAA,KAAY,EAAC;AAAA,MAC/C,GAAI,KAAK,UAAA,GAAa,EAAE,WAAW,IAAA,CAAK,UAAA,KAAe;AAAC,KAC1D;AACA,IAAA,IAAA,CAAK,SAAA,CAAU,OAAA,CAAQ,CAAA,CAAA,KAAK,OAAA,CAAQ,OAAA,CAAQ,EAAE,MAAM,CAAC,CAAA,CAAE,KAAA,CAAM,MAAM;AAAA,IAAC,CAAC,CAAC,CAAA;AACtE,IAAA,OAAO,MAAA;AAAA,EACT;AAAA,EAEA,cAAA,CAAe,SAAiB,KAAA,EAAkD;AAChF,IAAA,OAAO,KAAK,OAAA,CAAQ,IAAI,KAAA,CAAM,OAAO,GAAG,KAAK,CAAA;AAAA,EAC/C;AAAA,EAEA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,YAAY,EAAC;AAClB,IAAA,IAAA,CAAK,OAAA,GAAU,EAAA;AACf,IAAA,IAAA,CAAK,UAAA,GAAa,EAAA;AAClB,IAAA,IAAA,CAAK,WAAW,EAAC;AAAA,EACnB;AACF","file":"index.js","sourcesContent":["export type Unsubscribe = () => void;\nexport type Listener<T> = (value: T) => void;\n\n/**\n * Lightweight pub/sub subject — emits to all current subscribers.\n * Replaces RxJS Subject without pulling in the full RxJS dependency.\n */\nexport class JoopSubject<T> {\n private _listeners: Listener<T>[] = [];\n\n subscribe(listener: Listener<T>): Unsubscribe {\n this._listeners.push(listener);\n return () => {\n this._listeners = this._listeners.filter(l => l !== listener);\n };\n }\n\n next(value: T): void {\n for (const listener of this._listeners) {\n listener(value);\n }\n }\n\n asObservable(): JoopObservable<T> {\n return new JoopObservable<T>(listener => this.subscribe(listener));\n }\n}\n\n/**\n * Stateful subject — replays the current value to any new subscriber immediately.\n * Replaces RxJS BehaviorSubject.\n */\nexport class JoopBehaviorSubject<T> extends JoopSubject<T> {\n private _value: T;\n\n constructor(initialValue: T) {\n super();\n this._value = initialValue;\n }\n\n getValue(): T {\n return this._value;\n }\n\n override next(value: T): void {\n this._value = value;\n super.next(value);\n }\n\n override subscribe(listener: Listener<T>): Unsubscribe {\n listener(this._value);\n return super.subscribe(listener);\n }\n\n override asObservable(): JoopObservable<T> {\n return new JoopObservable<T>(listener => this.subscribe(listener));\n }\n}\n\n/**\n * Read-only observable handle returned from asObservable().\n */\nexport class JoopObservable<T> {\n constructor(private _subscribeFn: (listener: Listener<T>) => Unsubscribe) {}\n\n subscribe(listener: Listener<T>): Unsubscribe {\n return this._subscribeFn(listener);\n }\n\n /** Returns the current value without subscribing (only meaningful for BehaviorSubject-backed observables). */\n getOnce(): T | undefined {\n let result: T | undefined;\n const unsub = this.subscribe(v => { result = v; });\n unsub();\n return result;\n }\n}\n","import { JoopBehaviorSubject, JoopSubject } from '../events';\n\nexport interface JoopVitalsSnapshot {\n lcp: number | null; // Largest Contentful Paint (ms)\n fid: number | null; // First Input Delay (ms) — deprecated, use INP\n inp: number | null; // Interaction to Next Paint (ms)\n cls: number | null; // Cumulative Layout Shift (score)\n ttfb: number | null; // Time to First Byte (ms)\n fcp: number | null; // First Contentful Paint (ms)\n capturedAt: number;\n}\n\nexport interface JoopVitalUpdate {\n metric: keyof Omit<JoopVitalsSnapshot, 'capturedAt'>;\n value: number;\n rating: 'good' | 'needs-improvement' | 'poor';\n}\n\n// Thresholds per https://web.dev/vitals/\nconst THRESHOLDS: Record<string, [number, number]> = {\n lcp: [2500, 4000],\n fid: [100, 300],\n inp: [200, 500],\n cls: [0.1, 0.25],\n ttfb: [800, 1800],\n fcp: [1800, 3000],\n};\n\nexport class JoopWebVitals {\n private _vitals: Partial<JoopVitalsSnapshot> = {};\n private _vitals$ = new JoopSubject<JoopVitalUpdate>();\n private _snapshot$ = new JoopBehaviorSubject<JoopVitalsSnapshot>(this._buildSnapshot());\n private _observers: PerformanceObserver[] = [];\n private _running = false;\n\n start(): void {\n if (this._running || typeof PerformanceObserver === 'undefined') return;\n this._running = true;\n this._observeLCP();\n this._observeFID();\n this._observeINP();\n this._observeCLS();\n this._observeTTFB();\n this._observeFCP();\n }\n\n stop(): void {\n this._running = false;\n for (const obs of this._observers) { try { obs.disconnect(); } catch {} }\n this._observers = [];\n }\n\n snapshot(): JoopVitalsSnapshot { return this._buildSnapshot(); }\n vitals$() { return this._vitals$.asObservable(); }\n snapshot$() { return this._snapshot$.asObservable(); }\n\n getLCP(): number | null { return this._vitals.lcp ?? null; }\n getCLS(): number | null { return this._vitals.cls ?? null; }\n getINP(): number | null { return this._vitals.inp ?? null; }\n getTTFB(): number | null { return this._vitals.ttfb ?? null; }\n getFCP(): number | null { return this._vitals.fcp ?? null; }\n getFID(): number | null { return this._vitals.fid ?? null; }\n\n getRating(metric: string): 'good' | 'needs-improvement' | 'poor' {\n const value = (this._vitals as Record<string, number | null>)[metric];\n return _rate(metric, value ?? null);\n }\n\n private _record(metric: keyof Omit<JoopVitalsSnapshot, 'capturedAt'>, value: number): void {\n (this._vitals as Record<string, number>)[metric] = value;\n const rating = _rate(metric as string, value);\n this._vitals$.next({ metric, value, rating });\n this._snapshot$.next(this._buildSnapshot());\n }\n\n private _observe(types: string[], callback: (list: PerformanceObserverEntryList) => void): void {\n try {\n const obs = new PerformanceObserver(callback);\n obs.observe({ type: types[0], buffered: true });\n this._observers.push(obs);\n } catch {}\n }\n\n private _observeLCP(): void {\n this._observe(['largest-contentful-paint'], list => {\n const entries = list.getEntries();\n if (entries.length) this._record('lcp', (entries[entries.length - 1] as PerformanceEntry & { renderTime?: number; loadTime?: number }).renderTime || (entries[entries.length - 1] as PerformanceEntry & { renderTime?: number; loadTime?: number }).loadTime || entries[entries.length - 1].startTime);\n });\n }\n\n private _observeFID(): void {\n this._observe(['first-input'], list => {\n const e = list.getEntries()[0] as PerformanceEntry & { processingStart?: number };\n if (e && e.processingStart) this._record('fid', e.processingStart - e.startTime);\n });\n }\n\n private _observeINP(): void {\n this._observe(['event'], list => {\n let max = this._vitals.inp ?? 0;\n for (const e of list.getEntries()) {\n const entry = e as PerformanceEntry & { processingEnd?: number };\n if (entry.processingEnd) max = Math.max(max, entry.processingEnd - entry.startTime);\n }\n if (max > 0) this._record('inp', max);\n });\n }\n\n private _observeCLS(): void {\n let clsValue = 0;\n let sessionStart = 0;\n let lastEntry = 0;\n this._observe(['layout-shift'], list => {\n for (const e of list.getEntries()) {\n const entry = e as PerformanceEntry & { hadRecentInput?: boolean; value?: number };\n if (entry.hadRecentInput) continue;\n if (lastEntry > 0 && (entry.startTime - lastEntry) > 1000) {\n if (entry.startTime - sessionStart > 5000) { clsValue = 0; sessionStart = entry.startTime; }\n }\n if (lastEntry === 0) sessionStart = entry.startTime;\n clsValue += entry.value ?? 0;\n lastEntry = entry.startTime;\n this._record('cls', clsValue);\n }\n });\n }\n\n private _observeTTFB(): void {\n const nav = performance.getEntriesByType?.('navigation')?.[0] as PerformanceEntry & { responseStart?: number };\n if (nav?.responseStart) this._record('ttfb', nav.responseStart);\n this._observe(['navigation'], list => {\n const e = list.getEntries()[0] as PerformanceEntry & { responseStart?: number };\n if (e?.responseStart) this._record('ttfb', e.responseStart);\n });\n }\n\n private _observeFCP(): void {\n this._observe(['paint'], list => {\n const e = list.getEntries().find(e => e.name === 'first-contentful-paint');\n if (e) this._record('fcp', e.startTime);\n });\n }\n\n private _buildSnapshot(): JoopVitalsSnapshot {\n return {\n lcp: this._vitals.lcp ?? null,\n fid: this._vitals.fid ?? null,\n inp: this._vitals.inp ?? null,\n cls: this._vitals.cls ?? null,\n ttfb: this._vitals.ttfb ?? null,\n fcp: this._vitals.fcp ?? null,\n capturedAt: Date.now(),\n };\n }\n}\n\nfunction _rate(metric: string, value: number | null): 'good' | 'needs-improvement' | 'poor' {\n if (value === null) return 'good';\n const [good, poor] = THRESHOLDS[metric] ?? [Infinity, Infinity];\n return value <= good ? 'good' : value <= poor ? 'needs-improvement' : 'poor';\n}\n","export type JoopRecordedEventType = 'dom-mutation' | 'click' | 'input' | 'scroll' | 'resize' | 'navigation' | 'custom';\n\nexport interface JoopRecordedEvent {\n type: JoopRecordedEventType;\n timestamp: number;\n selector?: string;\n value?: string;\n data?: Record<string, unknown>;\n}\n\nexport interface JoopSessionRecord {\n startedAt: number;\n stoppedAt: number;\n events: JoopRecordedEvent[];\n url: string;\n userAgent: string;\n}\n\nexport interface JoopSessionRecorderOptions {\n maskSelectors?: string[]; // CSS selectors to mask (replace with ***)\n ignoreSelectors?: string[]; // CSS selectors to ignore entirely\n redactInputs?: boolean; // auto-redact password + [data-pii] inputs\n maxEvents?: number;\n captureScroll?: boolean;\n captureResize?: boolean;\n}\n\nexport class JoopSessionRecorder {\n private _events: JoopRecordedEvent[] = [];\n private _running = false;\n private _paused = false;\n private _startedAt = 0;\n private _opts: Required<JoopSessionRecorderOptions> = {\n maskSelectors: [], ignoreSelectors: [],\n redactInputs: true, maxEvents: 10000,\n captureScroll: true, captureResize: true,\n };\n private _cleanup: Array<() => void> = [];\n private _mutationObserver: MutationObserver | null = null;\n private _scrollTimer: ReturnType<typeof setTimeout> | null = null;\n\n start(options: JoopSessionRecorderOptions = {}): void {\n if (this._running) return;\n this._opts = { ...this._opts, ...options };\n this._running = true; this._paused = false;\n this._events = []; this._startedAt = Date.now();\n this._attachListeners();\n }\n\n pause(): void { this._paused = true; }\n resume(): void { this._paused = false; }\n\n stop(): JoopSessionRecord {\n this._running = false; this._paused = false;\n this._detach();\n return {\n startedAt: this._startedAt, stoppedAt: Date.now(),\n events: [...this._events],\n url: typeof location !== 'undefined' ? location.href : '',\n userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : '',\n };\n }\n\n events(): JoopRecordedEvent[] { return [...this._events]; }\n\n export(format: 'json' | 'compressed' = 'json'): string {\n const record: JoopSessionRecord = {\n startedAt: this._startedAt, stoppedAt: Date.now(),\n events: this._events, url: typeof location !== 'undefined' ? location.href : '', userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : '',\n };\n const json = JSON.stringify(record);\n if (format === 'compressed') {\n try { return btoa(json); } catch { return json; }\n }\n return json;\n }\n\n addEvent(type: JoopRecordedEventType, data?: Record<string, unknown>): void {\n this._push({ type, timestamp: Date.now(), data });\n }\n\n private _push(event: JoopRecordedEvent): void {\n if (!this._running || this._paused) return;\n if (this._events.length >= this._opts.maxEvents) this._events.shift();\n this._events.push(event);\n }\n\n private _attachListeners(): void {\n // DOM mutations\n this._mutationObserver = new MutationObserver(mutations => {\n for (const m of mutations) {\n if (this._shouldIgnore(m.target as Element)) continue;\n this._push({ type: 'dom-mutation', timestamp: Date.now(), selector: _selector(m.target as Element), data: { addedNodes: m.addedNodes.length, removedNodes: m.removedNodes.length, type: m.type } });\n }\n });\n this._mutationObserver.observe(document.documentElement, { childList: true, subtree: true, attributes: true, characterData: false, attributeFilter: ['class', 'style', 'hidden', 'disabled'] });\n\n // Click\n const onClick = (e: MouseEvent) => {\n const el = e.target as Element;\n if (this._shouldIgnore(el)) return;\n this._push({ type: 'click', timestamp: Date.now(), selector: _selector(el) });\n };\n document.addEventListener('click', onClick, { capture: true });\n this._cleanup.push(() => document.removeEventListener('click', onClick, { capture: true }));\n\n // Input\n const onInput = (e: Event) => {\n const el = e.target as HTMLInputElement;\n if (this._shouldIgnore(el)) return;\n const redact = this._opts.redactInputs && (el.type === 'password' || el.dataset?.pii !== undefined || this._opts.maskSelectors.some(s => el.matches(s)));\n this._push({ type: 'input', timestamp: Date.now(), selector: _selector(el), value: redact ? '***' : undefined });\n };\n document.addEventListener('input', onInput, { capture: true });\n this._cleanup.push(() => document.removeEventListener('input', onInput, { capture: true }));\n\n // Scroll (throttled)\n if (this._opts.captureScroll) {\n const onScroll = () => {\n if (this._scrollTimer) return;\n this._scrollTimer = setTimeout(() => {\n this._scrollTimer = null;\n this._push({ type: 'scroll', timestamp: Date.now(), data: { x: window.scrollX, y: window.scrollY } });\n }, 250);\n };\n window.addEventListener('scroll', onScroll, { passive: true });\n this._cleanup.push(() => window.removeEventListener('scroll', onScroll));\n }\n\n // Resize (throttled)\n if (this._opts.captureResize) {\n let resizeTimer: ReturnType<typeof setTimeout> | null = null;\n const onResize = () => {\n if (resizeTimer) return;\n resizeTimer = setTimeout(() => {\n resizeTimer = null;\n this._push({ type: 'resize', timestamp: Date.now(), data: { w: window.innerWidth, h: window.innerHeight } });\n }, 250);\n };\n window.addEventListener('resize', onResize, { passive: true });\n this._cleanup.push(() => window.removeEventListener('resize', onResize));\n }\n\n // Navigation\n const onPop = () => this._push({ type: 'navigation', timestamp: Date.now(), data: { url: location.href } });\n window.addEventListener('popstate', onPop);\n this._cleanup.push(() => window.removeEventListener('popstate', onPop));\n }\n\n private _detach(): void {\n this._mutationObserver?.disconnect(); this._mutationObserver = null;\n for (const fn of this._cleanup) fn();\n this._cleanup = [];\n }\n\n private _shouldIgnore(el: Element | null): boolean {\n if (!el) return false;\n return this._opts.ignoreSelectors.some(s => { try { return el.matches?.(s); } catch { return false; } });\n }\n}\n\nfunction _selector(el: Element | null): string {\n if (!el) return '';\n const parts: string[] = [];\n let current: Element | null = el;\n while (current && current !== document.body && parts.length < 4) {\n let part = current.tagName.toLowerCase();\n if (current.id) { parts.unshift(`#${current.id}`); break; }\n if (current.className) part += '.' + Array.from(current.classList).slice(0, 2).join('.');\n parts.unshift(part);\n current = current.parentElement;\n }\n return parts.join(' > ');\n}\n","export class JoopCorrelationService {\n private _correlationId = '';\n private _requestId = '';\n\n newCorrelation(): string {\n this._correlationId = crypto.randomUUID();\n return this._correlationId;\n }\n\n newRequest(): string {\n this._requestId = crypto.randomUUID();\n return this._requestId;\n }\n\n getCorrelationId(): string { return this._correlationId; }\n getRequestId(): string { return this._requestId; }\n\n headers(): Record<string, string> {\n const h: Record<string, string> = {};\n if (this._correlationId) h['X-Correlation-ID'] = this._correlationId;\n if (this._requestId) h['X-Request-ID'] = this._requestId;\n return h;\n }\n\n clear(): void { this._correlationId = ''; this._requestId = ''; }\n}\n","export type JoopAuditAction =\n | 'login' | 'logout' | 'session-timeout' | 'session-extended'\n | 'transfer-initiated' | 'transfer-confirmed' | 'transfer-failed'\n | 'profile-updated' | 'password-changed' | 'settings-changed'\n | 'document-viewed' | 'statement-downloaded' | 'otp-sent' | 'otp-verified'\n | 'biometric-registered' | 'biometric-authenticated'\n | string;\n\nexport interface JoopAuditEntry {\n id: string;\n action: JoopAuditAction;\n timestamp: number;\n userId?: string;\n sessionId?: string;\n correlationId?: string;\n metadata?: Record<string, unknown>;\n success: boolean;\n}\n\nexport type JoopAuditListener = (entry: JoopAuditEntry) => void;\n\nexport class JoopAuditLog {\n private _entries: JoopAuditEntry[] = [];\n private _listeners: JoopAuditListener[] = [];\n\n constructor(private _maxEntries = 500) {}\n\n record(action: JoopAuditAction, options: {\n userId?: string;\n sessionId?: string;\n correlationId?: string;\n metadata?: Record<string, unknown>;\n success?: boolean;\n } = {}): JoopAuditEntry {\n const entry: JoopAuditEntry = {\n id: crypto.randomUUID(),\n action,\n timestamp: Date.now(),\n success: options.success ?? true,\n ...options,\n };\n this._entries.push(entry);\n if (this._entries.length > this._maxEntries) this._entries = this._entries.slice(-this._maxEntries);\n this._listeners.forEach(l => l(entry));\n return entry;\n }\n\n getAll(): JoopAuditEntry[] { return [...this._entries]; }\n getByAction(action: JoopAuditAction): JoopAuditEntry[] { return this._entries.filter(e => e.action === action); }\n getBySession(sessionId: string): JoopAuditEntry[] { return this._entries.filter(e => e.sessionId === sessionId); }\n getByUser(userId: string): JoopAuditEntry[] { return this._entries.filter(e => e.userId === userId); }\n\n onRecord(listener: JoopAuditListener): () => void {\n this._listeners.push(listener);\n return () => { this._listeners = this._listeners.filter(l => l !== listener); };\n }\n\n clear(): void { this._entries = []; }\n export(): string { return JSON.stringify(this._entries, null, 2); }\n}\n","export interface JoopPerfMark {\n name: string;\n startTime: number;\n endTime?: number;\n duration?: number;\n metadata?: Record<string, unknown>;\n}\n\nexport class JoopPerformanceService {\n private _marks = new Map<string, JoopPerfMark>();\n private _completed: JoopPerfMark[] = [];\n\n mark(name: string, metadata?: Record<string, unknown>): void {\n this._marks.set(name, { name, startTime: performance.now(), metadata });\n }\n\n measure(name: string): JoopPerfMark | null {\n const mark = this._marks.get(name);\n if (!mark) return null;\n const endTime = performance.now();\n const entry: JoopPerfMark = { ...mark, endTime, duration: endTime - mark.startTime };\n this._marks.delete(name);\n this._completed.push(entry);\n return entry;\n }\n\n async timeAsync<T>(name: string, fn: () => Promise<T>): Promise<T> {\n this.mark(name);\n try {\n const result = await fn();\n this.measure(name);\n return result;\n } catch (err) {\n this.measure(name);\n throw err;\n }\n }\n\n timeSync<T>(name: string, fn: () => T): T {\n this.mark(name);\n try {\n const result = fn();\n this.measure(name);\n return result;\n } catch (err) {\n this.measure(name);\n throw err;\n }\n }\n\n getCompleted(): JoopPerfMark[] { return [...this._completed]; }\n getByName(name: string): JoopPerfMark[] { return this._completed.filter(m => m.name === name); }\n\n getAverage(name: string): number | null {\n const entries = this._completed.filter(m => m.name === name && m.duration !== undefined);\n if (!entries.length) return null;\n return entries.reduce((sum, m) => sum + m.duration!, 0) / entries.length;\n }\n\n clear(): void { this._marks.clear(); this._completed = []; }\n}\n","export interface JoopErrorReport {\n id: string;\n message: string;\n stack?: string;\n context?: Record<string, unknown>;\n timestamp: number;\n userId?: string;\n sessionId?: string;\n}\n\nexport type JoopErrorHandler = (report: JoopErrorReport) => void | Promise<void>;\n\nexport class JoopErrorReporter {\n private _handlers: JoopErrorHandler[] = [];\n private _userId = '';\n private _sessionId = '';\n private _context: Record<string, unknown> = {};\n\n setUser(userId: string): void { this._userId = userId; }\n setSession(sessionId: string): void { this._sessionId = sessionId; }\n setContext(ctx: Record<string, unknown>): void { this._context = { ...this._context, ...ctx }; }\n\n addHandler(handler: JoopErrorHandler): () => void {\n this._handlers.push(handler);\n return () => { this._handlers = this._handlers.filter(h => h !== handler); };\n }\n\n capture(error: unknown, extra?: Record<string, unknown>): JoopErrorReport {\n const err = error instanceof Error ? error : new Error(String(error));\n const report: JoopErrorReport = {\n id: crypto.randomUUID(),\n message: err.message,\n stack: err.stack,\n context: { ...this._context, ...extra },\n timestamp: Date.now(),\n ...(this._userId ? { userId: this._userId } : {}),\n ...(this._sessionId ? { sessionId: this._sessionId } : {}),\n };\n this._handlers.forEach(h => Promise.resolve(h(report)).catch(() => {}));\n return report;\n }\n\n captureMessage(message: string, extra?: Record<string, unknown>): JoopErrorReport {\n return this.capture(new Error(message), extra);\n }\n\n clear(): void {\n this._handlers = [];\n this._userId = '';\n this._sessionId = '';\n this._context = {};\n }\n}\n"]}