@pan-sec/notebooklm-mcp 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +289 -0
  3. package/SECURITY.md +539 -0
  4. package/dist/auth/auth-manager.d.ts +137 -0
  5. package/dist/auth/auth-manager.d.ts.map +1 -0
  6. package/dist/auth/auth-manager.js +984 -0
  7. package/dist/auth/auth-manager.js.map +1 -0
  8. package/dist/auth/mcp-auth.d.ts +102 -0
  9. package/dist/auth/mcp-auth.d.ts.map +1 -0
  10. package/dist/auth/mcp-auth.js +286 -0
  11. package/dist/auth/mcp-auth.js.map +1 -0
  12. package/dist/config.d.ts +89 -0
  13. package/dist/config.d.ts.map +1 -0
  14. package/dist/config.js +216 -0
  15. package/dist/config.js.map +1 -0
  16. package/dist/errors.d.ts +26 -0
  17. package/dist/errors.d.ts.map +1 -0
  18. package/dist/errors.js +41 -0
  19. package/dist/errors.js.map +1 -0
  20. package/dist/index.d.ts +32 -0
  21. package/dist/index.d.ts.map +1 -0
  22. package/dist/index.js +371 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/library/notebook-library.d.ts +70 -0
  25. package/dist/library/notebook-library.d.ts.map +1 -0
  26. package/dist/library/notebook-library.js +279 -0
  27. package/dist/library/notebook-library.js.map +1 -0
  28. package/dist/library/types.d.ts +67 -0
  29. package/dist/library/types.d.ts.map +1 -0
  30. package/dist/library/types.js +8 -0
  31. package/dist/library/types.js.map +1 -0
  32. package/dist/resources/resource-handlers.d.ts +22 -0
  33. package/dist/resources/resource-handlers.d.ts.map +1 -0
  34. package/dist/resources/resource-handlers.js +216 -0
  35. package/dist/resources/resource-handlers.js.map +1 -0
  36. package/dist/session/browser-session.d.ts +108 -0
  37. package/dist/session/browser-session.d.ts.map +1 -0
  38. package/dist/session/browser-session.js +621 -0
  39. package/dist/session/browser-session.js.map +1 -0
  40. package/dist/session/session-manager.d.ts +77 -0
  41. package/dist/session/session-manager.d.ts.map +1 -0
  42. package/dist/session/session-manager.js +314 -0
  43. package/dist/session/session-manager.js.map +1 -0
  44. package/dist/session/session-timeout.d.ts +122 -0
  45. package/dist/session/session-timeout.d.ts.map +1 -0
  46. package/dist/session/session-timeout.js +281 -0
  47. package/dist/session/session-timeout.js.map +1 -0
  48. package/dist/session/shared-context-manager.d.ts +107 -0
  49. package/dist/session/shared-context-manager.d.ts.map +1 -0
  50. package/dist/session/shared-context-manager.js +447 -0
  51. package/dist/session/shared-context-manager.js.map +1 -0
  52. package/dist/tools/definitions/ask-question.d.ts +8 -0
  53. package/dist/tools/definitions/ask-question.d.ts.map +1 -0
  54. package/dist/tools/definitions/ask-question.js +211 -0
  55. package/dist/tools/definitions/ask-question.js.map +1 -0
  56. package/dist/tools/definitions/notebook-management.d.ts +3 -0
  57. package/dist/tools/definitions/notebook-management.d.ts.map +1 -0
  58. package/dist/tools/definitions/notebook-management.js +243 -0
  59. package/dist/tools/definitions/notebook-management.js.map +1 -0
  60. package/dist/tools/definitions/session-management.d.ts +3 -0
  61. package/dist/tools/definitions/session-management.d.ts.map +1 -0
  62. package/dist/tools/definitions/session-management.js +41 -0
  63. package/dist/tools/definitions/session-management.js.map +1 -0
  64. package/dist/tools/definitions/system.d.ts +3 -0
  65. package/dist/tools/definitions/system.d.ts.map +1 -0
  66. package/dist/tools/definitions/system.js +143 -0
  67. package/dist/tools/definitions/system.js.map +1 -0
  68. package/dist/tools/definitions.d.ts +12 -0
  69. package/dist/tools/definitions.d.ts.map +1 -0
  70. package/dist/tools/definitions.js +26 -0
  71. package/dist/tools/definitions.js.map +1 -0
  72. package/dist/tools/handlers.d.ts +213 -0
  73. package/dist/tools/handlers.d.ts.map +1 -0
  74. package/dist/tools/handlers.js +813 -0
  75. package/dist/tools/handlers.js.map +1 -0
  76. package/dist/tools/index.d.ts +8 -0
  77. package/dist/tools/index.d.ts.map +1 -0
  78. package/dist/tools/index.js +8 -0
  79. package/dist/tools/index.js.map +1 -0
  80. package/dist/types.d.ts +82 -0
  81. package/dist/types.d.ts.map +1 -0
  82. package/dist/types.js +5 -0
  83. package/dist/types.js.map +1 -0
  84. package/dist/utils/audit-logger.d.ts +140 -0
  85. package/dist/utils/audit-logger.d.ts.map +1 -0
  86. package/dist/utils/audit-logger.js +361 -0
  87. package/dist/utils/audit-logger.js.map +1 -0
  88. package/dist/utils/cert-pinning.d.ts +97 -0
  89. package/dist/utils/cert-pinning.d.ts.map +1 -0
  90. package/dist/utils/cert-pinning.js +328 -0
  91. package/dist/utils/cert-pinning.js.map +1 -0
  92. package/dist/utils/cleanup-manager.d.ts +133 -0
  93. package/dist/utils/cleanup-manager.d.ts.map +1 -0
  94. package/dist/utils/cleanup-manager.js +673 -0
  95. package/dist/utils/cleanup-manager.js.map +1 -0
  96. package/dist/utils/cli-handler.d.ts +16 -0
  97. package/dist/utils/cli-handler.d.ts.map +1 -0
  98. package/dist/utils/cli-handler.js +102 -0
  99. package/dist/utils/cli-handler.js.map +1 -0
  100. package/dist/utils/crypto.d.ts +175 -0
  101. package/dist/utils/crypto.d.ts.map +1 -0
  102. package/dist/utils/crypto.js +612 -0
  103. package/dist/utils/crypto.js.map +1 -0
  104. package/dist/utils/logger.d.ts +61 -0
  105. package/dist/utils/logger.d.ts.map +1 -0
  106. package/dist/utils/logger.js +92 -0
  107. package/dist/utils/logger.js.map +1 -0
  108. package/dist/utils/page-utils.d.ts +54 -0
  109. package/dist/utils/page-utils.d.ts.map +1 -0
  110. package/dist/utils/page-utils.js +405 -0
  111. package/dist/utils/page-utils.js.map +1 -0
  112. package/dist/utils/response-validator.d.ts +98 -0
  113. package/dist/utils/response-validator.d.ts.map +1 -0
  114. package/dist/utils/response-validator.js +352 -0
  115. package/dist/utils/response-validator.js.map +1 -0
  116. package/dist/utils/secrets-scanner.d.ts +126 -0
  117. package/dist/utils/secrets-scanner.d.ts.map +1 -0
  118. package/dist/utils/secrets-scanner.js +443 -0
  119. package/dist/utils/secrets-scanner.js.map +1 -0
  120. package/dist/utils/secure-memory.d.ts +130 -0
  121. package/dist/utils/secure-memory.d.ts.map +1 -0
  122. package/dist/utils/secure-memory.js +279 -0
  123. package/dist/utils/secure-memory.js.map +1 -0
  124. package/dist/utils/security.d.ts +83 -0
  125. package/dist/utils/security.d.ts.map +1 -0
  126. package/dist/utils/security.js +272 -0
  127. package/dist/utils/security.js.map +1 -0
  128. package/dist/utils/settings-manager.d.ts +37 -0
  129. package/dist/utils/settings-manager.d.ts.map +1 -0
  130. package/dist/utils/settings-manager.js +125 -0
  131. package/dist/utils/settings-manager.js.map +1 -0
  132. package/dist/utils/stealth-utils.d.ts +135 -0
  133. package/dist/utils/stealth-utils.d.ts.map +1 -0
  134. package/dist/utils/stealth-utils.js +398 -0
  135. package/dist/utils/stealth-utils.js.map +1 -0
  136. package/dist/utils/tool-validation.d.ts +93 -0
  137. package/dist/utils/tool-validation.d.ts.map +1 -0
  138. package/dist/utils/tool-validation.js +277 -0
  139. package/dist/utils/tool-validation.js.map +1 -0
  140. package/docs/SECURITY_IMPLEMENTATION_PLAN.md +437 -0
  141. package/docs/configuration.md +94 -0
  142. package/docs/tools.md +34 -0
  143. package/docs/troubleshooting.md +59 -0
  144. package/docs/usage-guide.md +245 -0
  145. package/package.json +82 -0
@@ -0,0 +1,281 @@
1
+ /**
2
+ * Session Timeout Manager for NotebookLM MCP Server
3
+ *
4
+ * Provides configurable session timeout enforcement:
5
+ * - Hard timeout: Maximum session lifetime (default: 8 hours)
6
+ * - Inactivity timeout: Auto-logout after idle period (default: 30 minutes)
7
+ * - Warning callbacks before timeout
8
+ * - Memory scrubbing on timeout
9
+ *
10
+ * Added by Pantheon Security for hardened fork.
11
+ */
12
+ import { audit } from "../utils/audit-logger.js";
13
+ import { log } from "../utils/logger.js";
14
+ /**
15
+ * Get timeout configuration from environment
16
+ */
17
+ function getDefaultConfig() {
18
+ const maxLifetimeSec = parseInt(process.env.NLMCP_SESSION_MAX_LIFETIME || "28800", 10); // 8 hours
19
+ const inactivitySec = parseInt(process.env.NLMCP_SESSION_INACTIVITY_TIMEOUT || "1800", 10); // 30 minutes
20
+ const warningBeforeSec = parseInt(process.env.NLMCP_SESSION_WARNING_BEFORE || "300", 10); // 5 minutes
21
+ return {
22
+ maxLifetimeMs: maxLifetimeSec * 1000,
23
+ inactivityTimeoutMs: inactivitySec * 1000,
24
+ warningBeforeMs: warningBeforeSec * 1000,
25
+ enableHardTimeout: process.env.NLMCP_SESSION_HARD_TIMEOUT !== "false",
26
+ enableInactivityTimeout: process.env.NLMCP_SESSION_INACTIVITY !== "false",
27
+ };
28
+ }
29
+ /**
30
+ * Session Timeout Manager
31
+ *
32
+ * Manages session timeouts with configurable lifetime and inactivity limits.
33
+ */
34
+ export class SessionTimeoutManager {
35
+ config;
36
+ sessions = new Map();
37
+ checkInterval = null;
38
+ onTimeout = null;
39
+ onWarning = null;
40
+ constructor(config) {
41
+ this.config = { ...getDefaultConfig(), ...config };
42
+ // Start periodic check
43
+ this.startPeriodicCheck();
44
+ log.info(`🕐 Session timeout manager initialized`);
45
+ log.info(` Max lifetime: ${this.formatDuration(this.config.maxLifetimeMs)}`);
46
+ log.info(` Inactivity timeout: ${this.formatDuration(this.config.inactivityTimeoutMs)}`);
47
+ }
48
+ /**
49
+ * Format duration for logging
50
+ */
51
+ formatDuration(ms) {
52
+ const seconds = Math.floor(ms / 1000);
53
+ const minutes = Math.floor(seconds / 60);
54
+ const hours = Math.floor(minutes / 60);
55
+ if (hours > 0) {
56
+ return `${hours}h ${minutes % 60}m`;
57
+ }
58
+ else if (minutes > 0) {
59
+ return `${minutes}m ${seconds % 60}s`;
60
+ }
61
+ else {
62
+ return `${seconds}s`;
63
+ }
64
+ }
65
+ /**
66
+ * Register a new session
67
+ */
68
+ startSession(sessionId) {
69
+ const now = Date.now();
70
+ this.sessions.set(sessionId, {
71
+ sessionId,
72
+ createdAt: now,
73
+ lastActivity: now,
74
+ warningIssued: false,
75
+ inactivityWarningIssued: false,
76
+ });
77
+ log.info(`🕐 Session ${sessionId} registered with timeout manager`);
78
+ audit.session("session_timeout_started", sessionId, {
79
+ max_lifetime_ms: this.config.maxLifetimeMs,
80
+ inactivity_timeout_ms: this.config.inactivityTimeoutMs,
81
+ });
82
+ }
83
+ /**
84
+ * Update session activity (reset inactivity timer)
85
+ */
86
+ touchSession(sessionId) {
87
+ const state = this.sessions.get(sessionId);
88
+ if (state) {
89
+ state.lastActivity = Date.now();
90
+ state.inactivityWarningIssued = false; // Reset warning after activity
91
+ }
92
+ }
93
+ /**
94
+ * Remove a session from tracking
95
+ */
96
+ removeSession(sessionId) {
97
+ this.sessions.delete(sessionId);
98
+ log.info(`🕐 Session ${sessionId} removed from timeout manager`);
99
+ }
100
+ /**
101
+ * Check if a session has expired
102
+ */
103
+ isExpired(sessionId) {
104
+ const state = this.sessions.get(sessionId);
105
+ if (!state) {
106
+ return { expired: false };
107
+ }
108
+ const now = Date.now();
109
+ // Check hard timeout (max lifetime)
110
+ if (this.config.enableHardTimeout) {
111
+ const age = now - state.createdAt;
112
+ if (age >= this.config.maxLifetimeMs) {
113
+ return { expired: true, reason: "lifetime" };
114
+ }
115
+ }
116
+ // Check inactivity timeout
117
+ if (this.config.enableInactivityTimeout) {
118
+ const inactive = now - state.lastActivity;
119
+ if (inactive >= this.config.inactivityTimeoutMs) {
120
+ return { expired: true, reason: "inactivity" };
121
+ }
122
+ }
123
+ return { expired: false };
124
+ }
125
+ /**
126
+ * Get time remaining for a session
127
+ */
128
+ getTimeRemaining(sessionId) {
129
+ const state = this.sessions.get(sessionId);
130
+ if (!state) {
131
+ return null;
132
+ }
133
+ const now = Date.now();
134
+ const lifetimeRemaining = this.config.enableHardTimeout
135
+ ? Math.max(0, this.config.maxLifetimeMs - (now - state.createdAt))
136
+ : Infinity;
137
+ const inactivityRemaining = this.config.enableInactivityTimeout
138
+ ? Math.max(0, this.config.inactivityTimeoutMs - (now - state.lastActivity))
139
+ : Infinity;
140
+ return {
141
+ lifetime: lifetimeRemaining,
142
+ inactivity: inactivityRemaining,
143
+ };
144
+ }
145
+ /**
146
+ * Get session info for all tracked sessions
147
+ */
148
+ getAllSessionsInfo() {
149
+ const now = Date.now();
150
+ const results = [];
151
+ for (const state of this.sessions.values()) {
152
+ const remaining = this.getTimeRemaining(state.sessionId);
153
+ results.push({
154
+ sessionId: state.sessionId,
155
+ createdAt: state.createdAt,
156
+ lastActivity: state.lastActivity,
157
+ ageMs: now - state.createdAt,
158
+ inactiveMs: now - state.lastActivity,
159
+ lifetimeRemainingMs: remaining?.lifetime ?? 0,
160
+ inactivityRemainingMs: remaining?.inactivity ?? 0,
161
+ });
162
+ }
163
+ return results;
164
+ }
165
+ /**
166
+ * Set callback for when a session times out
167
+ */
168
+ setTimeoutCallback(callback) {
169
+ this.onTimeout = callback;
170
+ }
171
+ /**
172
+ * Set callback for timeout warnings
173
+ */
174
+ setWarningCallback(callback) {
175
+ this.onWarning = callback;
176
+ }
177
+ /**
178
+ * Start periodic timeout check
179
+ */
180
+ startPeriodicCheck() {
181
+ // Check every 30 seconds
182
+ this.checkInterval = setInterval(() => {
183
+ this.checkAllSessions();
184
+ }, 30000);
185
+ // Don't prevent process exit
186
+ this.checkInterval.unref();
187
+ }
188
+ /**
189
+ * Check all sessions for expiry and warnings
190
+ */
191
+ async checkAllSessions() {
192
+ const now = Date.now();
193
+ for (const state of this.sessions.values()) {
194
+ // Check for expiry
195
+ const expiry = this.isExpired(state.sessionId);
196
+ if (expiry.expired && expiry.reason) {
197
+ log.warning(`🕐 Session ${state.sessionId} expired due to ${expiry.reason}`);
198
+ await audit.session("session_timeout_expired", state.sessionId, {
199
+ reason: expiry.reason,
200
+ age_ms: now - state.createdAt,
201
+ inactive_ms: now - state.lastActivity,
202
+ });
203
+ if (this.onTimeout) {
204
+ await this.onTimeout(state.sessionId, expiry.reason);
205
+ }
206
+ this.sessions.delete(state.sessionId);
207
+ continue;
208
+ }
209
+ // Check for warnings
210
+ const remaining = this.getTimeRemaining(state.sessionId);
211
+ if (!remaining)
212
+ continue;
213
+ // Lifetime warning
214
+ if (this.config.enableHardTimeout &&
215
+ !state.warningIssued &&
216
+ remaining.lifetime <= this.config.warningBeforeMs) {
217
+ state.warningIssued = true;
218
+ log.warning(`🕐 Session ${state.sessionId} will expire in ${this.formatDuration(remaining.lifetime)} (max lifetime)`);
219
+ if (this.onWarning) {
220
+ this.onWarning(state.sessionId, "lifetime", remaining.lifetime);
221
+ }
222
+ await audit.session("session_timeout_warning", state.sessionId, {
223
+ reason: "lifetime",
224
+ remaining_ms: remaining.lifetime,
225
+ });
226
+ }
227
+ // Inactivity warning
228
+ if (this.config.enableInactivityTimeout &&
229
+ !state.inactivityWarningIssued &&
230
+ remaining.inactivity <= this.config.warningBeforeMs) {
231
+ state.inactivityWarningIssued = true;
232
+ log.warning(`🕐 Session ${state.sessionId} will expire in ${this.formatDuration(remaining.inactivity)} (inactivity)`);
233
+ if (this.onWarning) {
234
+ this.onWarning(state.sessionId, "inactivity", remaining.inactivity);
235
+ }
236
+ await audit.session("session_timeout_warning", state.sessionId, {
237
+ reason: "inactivity",
238
+ remaining_ms: remaining.inactivity,
239
+ });
240
+ }
241
+ }
242
+ }
243
+ /**
244
+ * Stop the timeout manager
245
+ */
246
+ stop() {
247
+ if (this.checkInterval) {
248
+ clearInterval(this.checkInterval);
249
+ this.checkInterval = null;
250
+ }
251
+ this.sessions.clear();
252
+ log.info(`🕐 Session timeout manager stopped`);
253
+ }
254
+ /**
255
+ * Get configuration
256
+ */
257
+ getConfig() {
258
+ return { ...this.config };
259
+ }
260
+ /**
261
+ * Update configuration
262
+ */
263
+ updateConfig(config) {
264
+ this.config = { ...this.config, ...config };
265
+ log.info(`🕐 Session timeout config updated`);
266
+ }
267
+ }
268
+ /**
269
+ * Global timeout manager instance
270
+ */
271
+ let globalTimeoutManager = null;
272
+ /**
273
+ * Get or create the global timeout manager
274
+ */
275
+ export function getSessionTimeoutManager() {
276
+ if (!globalTimeoutManager) {
277
+ globalTimeoutManager = new SessionTimeoutManager();
278
+ }
279
+ return globalTimeoutManager;
280
+ }
281
+ //# sourceMappingURL=session-timeout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-timeout.js","sourceRoot":"","sources":["../../src/session/session-timeout.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Shared Context Manager with Persistent Chrome Profile
3
+ *
4
+ * Manages ONE global persistent BrowserContext for ALL sessions.
5
+ * This is critical for avoiding bot detection:
6
+ *
7
+ * - Google tracks browser fingerprints (Canvas, WebGL, Audio, Fonts, etc.)
8
+ * - Multiple contexts = Multiple fingerprints = Suspicious!
9
+ * - ONE persistent context = ONE consistent fingerprint = Normal user
10
+ * - Persistent user_data_dir = SAME fingerprint across all app restarts!
11
+ *
12
+ * Based on the Python implementation from shared_context_manager.py
13
+ */
14
+ import type { BrowserContext } from "patchright";
15
+ import { AuthManager } from "../auth/auth-manager.js";
16
+ /**
17
+ * Shared Context Manager
18
+ *
19
+ * Benefits:
20
+ * 1. ONE consistent browser fingerprint for all sessions
21
+ * 2. Fingerprint persists across app restarts (user_data_dir)
22
+ * 3. Mimics real user behavior (one browser, multiple tabs)
23
+ * 4. Google sees: "Same browser since day 1"
24
+ */
25
+ export declare class SharedContextManager {
26
+ private authManager;
27
+ private globalContext;
28
+ private contextCreatedAt;
29
+ private currentProfileDir;
30
+ private isIsolatedProfile;
31
+ private currentHeadlessMode;
32
+ constructor(authManager: AuthManager);
33
+ /**
34
+ * Get the global shared persistent context, or create new if needed
35
+ *
36
+ * Context is recreated only when:
37
+ * - First time (no context exists in this app instance)
38
+ * - Context was closed/invalid
39
+ *
40
+ * Note: Auth expiry does NOT recreate context - we reuse the SAME
41
+ * fingerprint and just re-login!
42
+ *
43
+ * @param overrideHeadless Optional override for headless mode (true = show browser)
44
+ */
45
+ getOrCreateContext(overrideHeadless?: boolean): Promise<BrowserContext>;
46
+ /**
47
+ * Check if global context needs to be recreated
48
+ */
49
+ private needsRecreation;
50
+ /**
51
+ * Create/Load the global PERSISTENT context with Chrome user_data_dir
52
+ *
53
+ * This is THE KEY to fingerprint persistence!
54
+ *
55
+ * First time:
56
+ * - Chrome creates new profile in user_data_dir
57
+ * - Generates fingerprint (Canvas, WebGL, Audio, etc.)
58
+ * - Saves everything to disk
59
+ *
60
+ * Subsequent starts:
61
+ * - Chrome loads profile from user_data_dir
62
+ * - SAME fingerprint as before! ✅
63
+ * - Google sees: "Same browser since day 1"
64
+ *
65
+ * @param overrideHeadless Optional override for headless mode (true = show browser)
66
+ */
67
+ private recreateContext;
68
+ /**
69
+ * Manually close the global context (e.g., on shutdown)
70
+ *
71
+ * Note: This closes the context for ALL sessions!
72
+ * Chrome will save everything to user_data_dir automatically.
73
+ */
74
+ closeContext(): Promise<void>;
75
+ private prepareIsolatedProfileDir;
76
+ private pruneIsolatedProfiles;
77
+ private safeRemoveIsolatedProfile;
78
+ /**
79
+ * Get information about the global persistent context
80
+ */
81
+ getContextInfo(): {
82
+ exists: boolean;
83
+ age_seconds?: number;
84
+ age_hours?: number;
85
+ fingerprint_id?: string;
86
+ user_data_dir: string;
87
+ persistent: boolean;
88
+ };
89
+ /**
90
+ * Get the current headless mode of the browser context
91
+ *
92
+ * @returns boolean | null - true if headless, false if visible, null if no context exists
93
+ */
94
+ getCurrentHeadlessMode(): boolean | null;
95
+ /**
96
+ * Check if the browser context needs to be recreated due to headless mode change
97
+ *
98
+ * @param overrideHeadless - Optional override for headless mode (true = show browser)
99
+ * @returns boolean - true if context needs to be recreated with new mode
100
+ */
101
+ needsHeadlessModeChange(overrideHeadless?: boolean): boolean;
102
+ /**
103
+ * Get context ID for logging
104
+ */
105
+ private getContextId;
106
+ }
107
+ //# sourceMappingURL=shared-context-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared-context-manager.d.ts","sourceRoot":"","sources":["../../src/session/shared-context-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAIjD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAItD;;;;;;;;GAQG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,aAAa,CAA+B;IACpD,OAAO,CAAC,gBAAgB,CAAuB;IAC/C,OAAO,CAAC,iBAAiB,CAAuB;IAChD,OAAO,CAAC,iBAAiB,CAAkB;IAC3C,OAAO,CAAC,mBAAmB,CAAwB;gBAEvC,WAAW,EAAE,WAAW;IAapC;;;;;;;;;;;OAWG;IACG,kBAAkB,CAAC,gBAAgB,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC;IAkB7E;;OAEG;YACW,eAAe;IAqB7B;;;;;;;;;;;;;;;;OAgBG;YACW,eAAe;IA+H7B;;;;;OAKG;IACG,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;YAkCrB,yBAAyB;YA2BzB,qBAAqB;YAwDrB,yBAAyB;IAgBvC;;OAEG;IACH,cAAc,IAAI;QAChB,MAAM,EAAE,OAAO,CAAC;QAChB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,aAAa,EAAE,MAAM,CAAC;QACtB,UAAU,EAAE,OAAO,CAAC;KACrB;IAwBD;;;;OAIG;IACH,sBAAsB,IAAI,OAAO,GAAG,IAAI;IAIxC;;;;;OAKG;IACH,uBAAuB,CAAC,gBAAgB,CAAC,EAAE,OAAO,GAAG,OAAO;IAuB5D;;OAEG;IACH,OAAO,CAAC,YAAY;CAOrB"}