@agentuity/analytics 3.0.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,116 @@
1
+ # @agentuity/analytics
2
+
3
+ Browser analytics for Agentuity applications. Track page views, Web Vitals, custom events, and more.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @agentuity/analytics
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ### Auto-init (Drop-in)
14
+
15
+ Set configuration via server-side injection, then import the beacon:
16
+
17
+ ```html
18
+ <script>
19
+ window.__AGENTUITY_ANALYTICS__ = {
20
+ enabled: true,
21
+ orgId: 'your-org-id',
22
+ projectId: 'your-project-id',
23
+ };
24
+ </script>
25
+ <script type="module" src="/path/to/analytics/beacon.js"></script>
26
+ ```
27
+
28
+ Or in a bundler:
29
+
30
+ ```typescript
31
+ import '@agentuity/analytics/beacon';
32
+ ```
33
+
34
+ ### Programmatic
35
+
36
+ ```typescript
37
+ import { init, track, identify, flush } from '@agentuity/analytics';
38
+
39
+ // Initialize
40
+ init({
41
+ orgId: 'your-org-id',
42
+ projectId: 'your-project-id',
43
+ });
44
+
45
+ // Track events
46
+ track('button_click', { button: 'signup' });
47
+
48
+ // Identify user
49
+ identify('user-123', { email: 'user@example.com' });
50
+
51
+ // Flush pending events
52
+ flush();
53
+ ```
54
+
55
+ ## Features
56
+
57
+ - **Page Views** - Automatic tracking with URL, referrer, title
58
+ - **Web Vitals** - FCP, LCP, CLS, INP metrics
59
+ - **Scroll Depth** - Tracks 25%, 50%, 75%, 100% milestones
60
+ - **SPA Navigation** - Tracks route changes in single-page apps
61
+ - **Click Tracking** - Via `[data-analytics]` attributes
62
+ - **Error Tracking** - JS errors and unhandled rejections
63
+ - **Custom Events** - Track any user action
64
+
65
+ ## Configuration
66
+
67
+ | Option | Type | Default | Description |
68
+ |--------|------|---------|-------------|
69
+ | `enabled` | boolean | `true` | Enable/disable tracking |
70
+ | `orgId` | string | - | Organization ID |
71
+ | `projectId` | string | - | Project ID |
72
+ | `isDevmode` | boolean | `false` | Development mode (logs to console) |
73
+ | `trackClicks` | boolean | `true` | Track `[data-analytics]` clicks |
74
+ | `trackScroll` | boolean | `true` | Track scroll depth |
75
+ | `trackWebVitals` | boolean | `true` | Track Core Web Vitals |
76
+ | `trackErrors` | boolean | `true` | Track JS errors |
77
+ | `trackSPANavigation` | boolean | `true` | Track SPA route changes |
78
+ | `sampleRate` | number | `1` | Sampling rate (0-1) |
79
+ | `endpoint` | string | `/_agentuity/webanalytics/collect` | Collect endpoint |
80
+
81
+ ## Data Collected
82
+
83
+ The beacon collects:
84
+
85
+ - **Page**: URL, path, referrer, title
86
+ - **Device**: Screen size, viewport, device pixel ratio, user agent
87
+ - **Performance**: TTFB, DOM ready, load time, Web Vitals
88
+ - **Engagement**: Scroll depth, time on page
89
+ - **Context**: Language, timezone, UTM parameters
90
+ - **Geo**: Country, region, city (from IP, cached)
91
+
92
+ ## Privacy
93
+
94
+ - Query strings are stripped from URLs to prevent sensitive data leakage
95
+ - No cookies used (uses localStorage for visitor ID)
96
+ - Geo data cached in sessionStorage
97
+ - User opt-out supported via `setOptOut(true)`
98
+
99
+ ## Server Integration
100
+
101
+ The beacon sends data to `/_agentuity/webanalytics/collect` by default. Configure your server to:
102
+
103
+ 1. Inject `window.__AGENTUITY_ANALYTICS__` config
104
+ 2. Handle POST requests to the collect endpoint
105
+
106
+ ## Framework Support
107
+
108
+ Works with any frontend framework:
109
+
110
+ - React
111
+ - Vue
112
+ - Svelte
113
+ - Solid
114
+ - Vanilla JS
115
+
116
+ No framework-specific code required.
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Analytics beacon - auto-initializing script
3
+ *
4
+ * Import this module to automatically start tracking:
5
+ * ```typescript
6
+ * import '@agentuity/analytics/beacon';
7
+ * ```
8
+ *
9
+ * Requires window.__AGENTUITY_ANALYTICS__ to be set by server.
10
+ */
11
+ export {};
12
+ //# sourceMappingURL=beacon.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"beacon.d.ts","sourceRoot":"","sources":["../src/beacon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG"}
package/dist/beacon.js ADDED
@@ -0,0 +1,300 @@
1
+ /**
2
+ * Analytics beacon - auto-initializing script
3
+ *
4
+ * Import this module to automatically start tracking:
5
+ * ```typescript
6
+ * import '@agentuity/analytics/beacon';
7
+ * ```
8
+ *
9
+ * Requires window.__AGENTUITY_ANALYTICS__ to be set by server.
10
+ */
11
+ import { isEnabled, getConfig, isDevmode } from './config';
12
+ import { initClient, updatePageView, resetSession, send, track, setupGlobal, getPageView, } from './client';
13
+ import { generateId, stripQueryString, getUTMParams, fetchGeo } from './util';
14
+ // Track if already initialized
15
+ let initialized = false;
16
+ /**
17
+ * Initialize page view data
18
+ */
19
+ function initPageView() {
20
+ const pv = {
21
+ id: generateId(),
22
+ timestamp: Date.now(),
23
+ timezone_offset: new Date().getTimezoneOffset(),
24
+ url: stripQueryString(location.href),
25
+ path: location.pathname,
26
+ referrer: stripQueryString(document.referrer),
27
+ title: document.title || '',
28
+ screen_width: screen.width || 0,
29
+ screen_height: screen.height || 0,
30
+ viewport_width: innerWidth || 0,
31
+ viewport_height: innerHeight || 0,
32
+ device_pixel_ratio: devicePixelRatio || 1,
33
+ user_agent: navigator.userAgent || '',
34
+ language: navigator.language || '',
35
+ scroll_depth: 0,
36
+ time_on_page: 0,
37
+ scroll_events: [],
38
+ custom_events: [],
39
+ };
40
+ // Add UTM params
41
+ const utm = getUTMParams();
42
+ for (const k in utm) {
43
+ pv[k] = utm[k];
44
+ }
45
+ // Capture navigation timing
46
+ if (typeof performance !== 'undefined' && performance.getEntriesByType) {
47
+ const nav = performance.getEntriesByType('navigation')[0];
48
+ if (nav) {
49
+ pv.dom_ready = Math.round(nav.domContentLoadedEventEnd - nav.startTime);
50
+ pv.ttfb = Math.round(nav.responseStart - nav.requestStart);
51
+ if (nav.loadEventEnd > 0) {
52
+ pv.load_time = Math.round(nav.loadEventEnd - nav.startTime);
53
+ }
54
+ else {
55
+ // Defer reading loadEventEnd
56
+ setTimeout(() => {
57
+ const navAfter = performance.getEntriesByType('navigation')[0];
58
+ if (navAfter && navAfter.loadEventEnd > 0) {
59
+ updatePageView({
60
+ load_time: Math.round(navAfter.loadEventEnd - navAfter.startTime),
61
+ });
62
+ }
63
+ }, 0);
64
+ }
65
+ }
66
+ }
67
+ return pv;
68
+ }
69
+ /**
70
+ * Set up visibility change handlers
71
+ */
72
+ function setupVisibilityHandlers() {
73
+ document.addEventListener('visibilitychange', () => {
74
+ if (document.visibilityState === 'hidden') {
75
+ send();
76
+ }
77
+ else if (document.visibilityState === 'visible') {
78
+ // User returned - start new attention session
79
+ resetSession();
80
+ }
81
+ });
82
+ window.addEventListener('pagehide', () => send());
83
+ window.addEventListener('beforeunload', () => send());
84
+ }
85
+ /**
86
+ * Set up scroll tracking
87
+ */
88
+ function setupScrollTracking() {
89
+ const config = getConfig();
90
+ if (config?.trackScroll === false)
91
+ return;
92
+ const scrolled = new Set();
93
+ function getScrollDepth() {
94
+ const st = window.scrollY || document.documentElement.scrollTop;
95
+ const sh = document.documentElement.scrollHeight - document.documentElement.clientHeight;
96
+ return sh <= 0 ? 100 : Math.min(100, Math.round((st / sh) * 100));
97
+ }
98
+ window.addEventListener('scroll', () => {
99
+ const depth = getScrollDepth();
100
+ updatePageView({ scroll_depth: depth });
101
+ for (const m of [25, 50, 75, 100]) {
102
+ if (depth >= m && !scrolled.has(m)) {
103
+ scrolled.add(m);
104
+ const pv = getPageView();
105
+ if (pv) {
106
+ pv.scroll_events.push({
107
+ depth: m,
108
+ timestamp: Date.now(),
109
+ });
110
+ }
111
+ }
112
+ }
113
+ }, { passive: true });
114
+ }
115
+ /**
116
+ * Set up Web Vitals tracking
117
+ */
118
+ function setupWebVitals() {
119
+ const config = getConfig();
120
+ if (config?.trackWebVitals === false)
121
+ return;
122
+ if (typeof PerformanceObserver === 'undefined')
123
+ return;
124
+ // FCP
125
+ try {
126
+ const fcpObs = new PerformanceObserver((list) => {
127
+ for (const entry of list.getEntries()) {
128
+ if (entry.name === 'first-contentful-paint') {
129
+ updatePageView({ fcp: Math.round(entry.startTime) });
130
+ fcpObs.disconnect();
131
+ }
132
+ }
133
+ });
134
+ fcpObs.observe({ type: 'paint', buffered: true });
135
+ }
136
+ catch {
137
+ /* Not supported */
138
+ }
139
+ // LCP
140
+ try {
141
+ new PerformanceObserver((list) => {
142
+ const entries = list.getEntries();
143
+ const last = entries[entries.length - 1];
144
+ if (last) {
145
+ updatePageView({ lcp: Math.round(last.startTime) });
146
+ }
147
+ }).observe({ type: 'largest-contentful-paint', buffered: true });
148
+ }
149
+ catch {
150
+ /* Not supported */
151
+ }
152
+ // CLS
153
+ try {
154
+ let clsValue = 0;
155
+ new PerformanceObserver((list) => {
156
+ for (const entry of list.getEntries()) {
157
+ const shift = entry;
158
+ if (!shift.hadRecentInput && shift.value) {
159
+ clsValue += shift.value;
160
+ }
161
+ }
162
+ updatePageView({ cls: Math.round(clsValue * 1000) / 1000 });
163
+ }).observe({ type: 'layout-shift', buffered: true });
164
+ }
165
+ catch {
166
+ /* Not supported */
167
+ }
168
+ // INP
169
+ try {
170
+ let inpValue = 0;
171
+ new PerformanceObserver((list) => {
172
+ for (const entry of list.getEntries()) {
173
+ const event = entry;
174
+ if (event.duration && event.duration > inpValue) {
175
+ inpValue = event.duration;
176
+ }
177
+ }
178
+ updatePageView({ inp: Math.round(inpValue) });
179
+ }).observe({ type: 'event', buffered: true });
180
+ }
181
+ catch {
182
+ /* Not supported */
183
+ }
184
+ }
185
+ /**
186
+ * Set up SPA navigation tracking
187
+ */
188
+ function setupSPANavigation() {
189
+ const config = getConfig();
190
+ if (config?.trackSPANavigation === false)
191
+ return;
192
+ let currentPath = location.pathname + location.search;
193
+ let lastHref = location.href;
194
+ function handleNav() {
195
+ const newPath = location.pathname + location.search;
196
+ if (newPath !== currentPath) {
197
+ send(true); // Force send on SPA nav
198
+ currentPath = newPath;
199
+ lastHref = location.href;
200
+ initClient(initPageView());
201
+ }
202
+ }
203
+ // Monkey-patch history
204
+ const origPush = history.pushState;
205
+ const origReplace = history.replaceState;
206
+ history.pushState = function (...args) {
207
+ origPush.apply(this, args);
208
+ setTimeout(handleNav, 0);
209
+ };
210
+ history.replaceState = function (...args) {
211
+ origReplace.apply(this, args);
212
+ setTimeout(handleNav, 0);
213
+ };
214
+ window.addEventListener('popstate', handleNav);
215
+ // Fallback: poll for URL changes
216
+ setInterval(() => {
217
+ if (location.href !== lastHref) {
218
+ lastHref = location.href;
219
+ handleNav();
220
+ }
221
+ }, 200);
222
+ }
223
+ /**
224
+ * Set up click tracking
225
+ */
226
+ function setupClickTracking() {
227
+ const config = getConfig();
228
+ if (config?.trackClicks === false)
229
+ return;
230
+ document.addEventListener('click', (e) => {
231
+ const target = e.target;
232
+ if (!target)
233
+ return;
234
+ const el = target.closest('[data-analytics]');
235
+ if (!el)
236
+ return;
237
+ const name = 'click:' + el.getAttribute('data-analytics');
238
+ track(name);
239
+ }, true);
240
+ }
241
+ /**
242
+ * Set up error tracking
243
+ */
244
+ function setupErrorTracking() {
245
+ const config = getConfig();
246
+ if (config?.trackErrors === false)
247
+ return;
248
+ window.addEventListener('error', (e) => {
249
+ track('error:js_error', {
250
+ message: e.message || 'Unknown',
251
+ filename: e.filename || '',
252
+ lineno: e.lineno || 0,
253
+ });
254
+ });
255
+ window.addEventListener('unhandledrejection', (e) => {
256
+ track('error:unhandled_rejection', {
257
+ message: e.reason instanceof Error ? e.reason.message : String(e.reason),
258
+ });
259
+ });
260
+ }
261
+ /**
262
+ * Initialize the beacon
263
+ */
264
+ function init() {
265
+ if (initialized)
266
+ return;
267
+ if (!isEnabled())
268
+ return;
269
+ initialized = true;
270
+ // Init page view
271
+ const pv = initPageView();
272
+ initClient(pv);
273
+ // Fetch geo (async)
274
+ fetchGeo();
275
+ // Set up all tracking
276
+ setupVisibilityHandlers();
277
+ setupScrollTracking();
278
+ setupWebVitals();
279
+ setupSPANavigation();
280
+ setupClickTracking();
281
+ setupErrorTracking();
282
+ // Set up global API
283
+ setupGlobal();
284
+ // Init on load if not ready
285
+ if (document.readyState === 'complete') {
286
+ // Already loaded
287
+ }
288
+ else {
289
+ window.addEventListener('load', () => {
290
+ // Re-capture timing after load
291
+ updatePageView(initPageView());
292
+ });
293
+ }
294
+ if (isDevmode()) {
295
+ console.debug('[Agentuity Analytics] Beacon initialized');
296
+ }
297
+ }
298
+ // Auto-initialize on import
299
+ init();
300
+ //# sourceMappingURL=beacon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"beacon.js","sourceRoot":"","sources":["../src/beacon.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Analytics client - programmatic API
3
+ */
4
+ import type { AnalyticsClient, PageViewData } from './types';
5
+ /**
6
+ * Initialize client with page view data
7
+ * Called by beacon or can be called manually
8
+ */
9
+ export declare function initClient(pv: PageViewData): void;
10
+ /**
11
+ * Update page view data
12
+ */
13
+ export declare function updatePageView(updates: Partial<PageViewData>): void;
14
+ /**
15
+ * Get current page view data
16
+ */
17
+ export declare function getPageView(): PageViewData | null;
18
+ /**
19
+ * Reset session (keep page-level metrics, reset session metrics)
20
+ */
21
+ export declare function resetSession(): void;
22
+ /**
23
+ * Send analytics data
24
+ */
25
+ export declare function send(force?: boolean): void;
26
+ /**
27
+ * Track a custom event
28
+ */
29
+ export declare function track(name: string, properties?: Record<string, unknown>): void;
30
+ /**
31
+ * Identify a user
32
+ */
33
+ export declare function identify(id: string, traits?: Record<string, unknown>): void;
34
+ /**
35
+ * Flush pending events
36
+ */
37
+ export declare function flush(): void;
38
+ /**
39
+ * Get the analytics client
40
+ */
41
+ export declare function getClient(): AnalyticsClient;
42
+ /**
43
+ * Set up client as window.global
44
+ */
45
+ export declare function setupGlobal(): void;
46
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAoB,MAAM,SAAS,CAAC;AAoB/E;;;GAGG;AACH,wBAAgB,UAAU,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAKjD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,IAAI,CAInE;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,YAAY,GAAG,IAAI,CAEjD;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,IAAI,CAWnC;AA0BD;;GAEG;AACH,wBAAgB,IAAI,CAAC,KAAK,UAAQ,GAAG,IAAI,CAsCxC;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAS9E;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAQ3E;AAED;;GAEG;AACH,wBAAgB,KAAK,IAAI,IAAI,CAE5B;AAED;;GAEG;AACH,wBAAgB,SAAS,IAAI,eAAe,CAM3C;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,IAAI,CAIlC"}
package/dist/client.js ADDED
@@ -0,0 +1,171 @@
1
+ /**
2
+ * Analytics client - programmatic API
3
+ */
4
+ import { isEnabled, getConfig, getEndpoint } from './config';
5
+ import { generateId, safeStringify, getVisitorId } from './util';
6
+ /** Pending custom events */
7
+ let customEvents = [];
8
+ /** Current user ID */
9
+ let userId = '';
10
+ /** Current user traits */
11
+ let userTraits = {};
12
+ /** Current page view data */
13
+ let pageView = null;
14
+ /** Whether current page view was sent */
15
+ let sent = false;
16
+ /** Page view start time */
17
+ let pageStart = Date.now();
18
+ /**
19
+ * Initialize client with page view data
20
+ * Called by beacon or can be called manually
21
+ */
22
+ export function initClient(pv) {
23
+ pageView = pv;
24
+ customEvents = [];
25
+ sent = false;
26
+ pageStart = Date.now();
27
+ }
28
+ /**
29
+ * Update page view data
30
+ */
31
+ export function updatePageView(updates) {
32
+ if (pageView) {
33
+ Object.assign(pageView, updates);
34
+ }
35
+ }
36
+ /**
37
+ * Get current page view data
38
+ */
39
+ export function getPageView() {
40
+ return pageView;
41
+ }
42
+ /**
43
+ * Reset session (keep page-level metrics, reset session metrics)
44
+ */
45
+ export function resetSession() {
46
+ if (pageView) {
47
+ pageView.id = generateId();
48
+ pageView.timestamp = Date.now();
49
+ pageView.scroll_events = [];
50
+ pageView.custom_events = customEvents;
51
+ pageView.scroll_depth = 0;
52
+ pageView.time_on_page = 0;
53
+ }
54
+ sent = false;
55
+ pageStart = Date.now();
56
+ }
57
+ /**
58
+ * Build payload for sending
59
+ */
60
+ function buildPayload() {
61
+ if (!pageView)
62
+ return null;
63
+ const config = getConfig();
64
+ if (!config)
65
+ return null;
66
+ return {
67
+ org_id: config.orgId,
68
+ project_id: config.projectId,
69
+ visitor_id: getVisitorId(),
70
+ user_id: userId,
71
+ user_traits: userTraits,
72
+ is_devmode: config.isDevmode ?? false,
73
+ pageview: {
74
+ ...pageView,
75
+ custom_events: customEvents,
76
+ time_on_page: Date.now() - pageStart,
77
+ },
78
+ };
79
+ }
80
+ /**
81
+ * Send analytics data
82
+ */
83
+ export function send(force = false) {
84
+ if (sent && !force)
85
+ return;
86
+ if (!isEnabled())
87
+ return;
88
+ const config = getConfig();
89
+ if (!config)
90
+ return;
91
+ // Check sample rate
92
+ if (config.sampleRate !== undefined && config.sampleRate < 1) {
93
+ if (Math.random() > config.sampleRate)
94
+ return;
95
+ }
96
+ sent = true;
97
+ const payload = buildPayload();
98
+ if (!payload)
99
+ return;
100
+ // Dev mode: just log
101
+ if (config.isDevmode) {
102
+ console.debug('[Agentuity Analytics]', JSON.stringify(payload, null, 2));
103
+ return;
104
+ }
105
+ // Production: send to endpoint
106
+ const body = JSON.stringify(payload);
107
+ const endpoint = getEndpoint();
108
+ if (navigator.sendBeacon) {
109
+ navigator.sendBeacon(endpoint, body);
110
+ }
111
+ else {
112
+ fetch(endpoint, {
113
+ method: 'POST',
114
+ body,
115
+ keepalive: true,
116
+ }).catch(() => {
117
+ // Silent failure
118
+ });
119
+ }
120
+ }
121
+ /**
122
+ * Track a custom event
123
+ */
124
+ export function track(name, properties) {
125
+ if (!isEnabled())
126
+ return;
127
+ if (customEvents.length >= 1000)
128
+ return;
129
+ customEvents.push({
130
+ timestamp: Date.now(),
131
+ name,
132
+ data: safeStringify(properties),
133
+ });
134
+ }
135
+ /**
136
+ * Identify a user
137
+ */
138
+ export function identify(id, traits) {
139
+ userId = id;
140
+ if (traits) {
141
+ userTraits = {};
142
+ for (const [key, value] of Object.entries(traits)) {
143
+ userTraits[key] = String(value);
144
+ }
145
+ }
146
+ }
147
+ /**
148
+ * Flush pending events
149
+ */
150
+ export function flush() {
151
+ send(true);
152
+ }
153
+ /**
154
+ * Get the analytics client
155
+ */
156
+ export function getClient() {
157
+ return {
158
+ track,
159
+ identify,
160
+ flush,
161
+ };
162
+ }
163
+ /**
164
+ * Set up client as window.global
165
+ */
166
+ export function setupGlobal() {
167
+ if (typeof window !== 'undefined') {
168
+ window.agentuityAnalytics = getClient();
169
+ }
170
+ }
171
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAGjE,4BAA4B;AAC5B,IAAI,YAAY,GAA6D,EAAE,CAAC;AAEhF,sBAAsB;AACtB,IAAI,MAAM,GAAG,EAAE,CAAC;AAEhB,0BAA0B;AAC1B,IAAI,UAAU,GAA2B,EAAE,CAAC;AAE5C,6BAA6B;AAC7B,IAAI,QAAQ,GAAwB,IAAI,CAAC;AAEzC,yCAAyC;AACzC,IAAI,IAAI,GAAG,KAAK,CAAC;AAEjB,2BAA2B;AAC3B,IAAI,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;AAE3B;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,EAAgB;IAC1C,QAAQ,GAAG,EAAE,CAAC;IACd,YAAY,GAAG,EAAE,CAAC;IAClB,IAAI,GAAG,KAAK,CAAC;IACb,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;AACxB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,OAA8B;IAC5D,IAAI,QAAQ,EAAE,CAAC;QACd,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAClC,CAAC;AACF,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW;IAC1B,OAAO,QAAQ,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY;IAC3B,IAAI,QAAQ,EAAE,CAAC;QACd,QAAQ,CAAC,EAAE,GAAG,UAAU,EAAE,CAAC;QAC3B,QAAQ,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAChC,QAAQ,CAAC,aAAa,GAAG,EAAE,CAAC;QAC5B,QAAQ,CAAC,aAAa,GAAG,YAAY,CAAC;QACtC,QAAQ,CAAC,YAAY,GAAG,CAAC,CAAC;QAC1B,QAAQ,CAAC,YAAY,GAAG,CAAC,CAAC;IAC3B,CAAC;IACD,IAAI,GAAG,KAAK,CAAC;IACb,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;AACxB,CAAC;AAED;;GAEG;AACH,SAAS,YAAY;IACpB,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAE3B,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAEzB,OAAO;QACN,MAAM,EAAE,MAAM,CAAC,KAAK;QACpB,UAAU,EAAE,MAAM,CAAC,SAAS;QAC5B,UAAU,EAAE,YAAY,EAAE;QAC1B,OAAO,EAAE,MAAM;QACf,WAAW,EAAE,UAAU;QACvB,UAAU,EAAE,MAAM,CAAC,SAAS,IAAI,KAAK;QACrC,QAAQ,EAAE;YACT,GAAG,QAAQ;YACX,aAAa,EAAE,YAAY;YAC3B,YAAY,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;SACpC;KACD,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,IAAI,CAAC,KAAK,GAAG,KAAK;IACjC,IAAI,IAAI,IAAI,CAAC,KAAK;QAAE,OAAO;IAC3B,IAAI,CAAC,SAAS,EAAE;QAAE,OAAO;IAEzB,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,IAAI,CAAC,MAAM;QAAE,OAAO;IAEpB,oBAAoB;IACpB,IAAI,MAAM,CAAC,UAAU,KAAK,SAAS,IAAI,MAAM,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC;QAC9D,IAAI,IAAI,CAAC,MAAM,EAAE,GAAG,MAAM,CAAC,UAAU;YAAE,OAAO;IAC/C,CAAC;IAED,IAAI,GAAG,IAAI,CAAC;IAEZ,MAAM,OAAO,GAAG,YAAY,EAAE,CAAC;IAC/B,IAAI,CAAC,OAAO;QAAE,OAAO;IAErB,qBAAqB;IACrB,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;QACtB,OAAO,CAAC,KAAK,CAAC,uBAAuB,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACzE,OAAO;IACR,CAAC;IAED,+BAA+B;IAC/B,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACrC,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAE/B,IAAI,SAAS,CAAC,UAAU,EAAE,CAAC;QAC1B,SAAS,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IACtC,CAAC;SAAM,CAAC;QACP,KAAK,CAAC,QAAQ,EAAE;YACf,MAAM,EAAE,MAAM;YACd,IAAI;YACJ,SAAS,EAAE,IAAI;SACf,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;YACb,iBAAiB;QAClB,CAAC,CAAC,CAAC;IACJ,CAAC;AACF,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,KAAK,CAAC,IAAY,EAAE,UAAoC;IACvE,IAAI,CAAC,SAAS,EAAE;QAAE,OAAO;IACzB,IAAI,YAAY,CAAC,MAAM,IAAI,IAAI;QAAE,OAAO;IAExC,YAAY,CAAC,IAAI,CAAC;QACjB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;QACrB,IAAI;QACJ,IAAI,EAAE,aAAa,CAAC,UAAU,CAAC;KAC/B,CAAC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,QAAQ,CAAC,EAAU,EAAE,MAAgC;IACpE,MAAM,GAAG,EAAE,CAAC;IACZ,IAAI,MAAM,EAAE,CAAC;QACZ,UAAU,GAAG,EAAE,CAAC;QAChB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACnD,UAAU,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QACjC,CAAC;IACF,CAAC;AACF,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,KAAK;IACpB,IAAI,CAAC,IAAI,CAAC,CAAC;AACZ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS;IACxB,OAAO;QACN,KAAK;QACL,QAAQ;QACR,KAAK;KACL,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW;IAC1B,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;QACnC,MAAM,CAAC,kBAAkB,GAAG,SAAS,EAAE,CAAC;IACzC,CAAC;AACF,CAAC"}