@tellaro/tql 0.1.0 → 0.1.2

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.
@@ -0,0 +1,242 @@
1
+ import { parseTql as y } from "./parser.js";
2
+ import { analyzeComplexity as p } from "./complexityAnalyzer.js";
3
+ class u {
4
+ /**
5
+ * Generate a complete preview for a TQL query
6
+ */
7
+ generatePreview(t) {
8
+ const r = y(t), i = p(t), n = [], s = {};
9
+ if (!r.ast)
10
+ return {
11
+ fields: [],
12
+ logicTree: null,
13
+ complexity: i,
14
+ fieldCount: 0,
15
+ uniqueFields: [],
16
+ operatorSummary: {}
17
+ };
18
+ this.extractFieldUsage(r.ast, n, s);
19
+ const a = this.buildLogicTree(r.ast), c = [...new Set(n.map((l) => l.name))];
20
+ return {
21
+ fields: n,
22
+ logicTree: a,
23
+ complexity: i,
24
+ fieldCount: n.length,
25
+ uniqueFields: c,
26
+ operatorSummary: s
27
+ };
28
+ }
29
+ /**
30
+ * Extract field usage information from an expression
31
+ */
32
+ extractFieldUsage(t, r, i) {
33
+ switch (t.type) {
34
+ case "binary":
35
+ this.extractFromBinary(t, r, i);
36
+ break;
37
+ case "unary":
38
+ this.extractFromUnary(t, r, i);
39
+ break;
40
+ case "comparison":
41
+ this.extractFromComparison(t, r, i);
42
+ break;
43
+ case "group":
44
+ this.extractFromGroup(t, r, i);
45
+ break;
46
+ }
47
+ }
48
+ extractFromBinary(t, r, i) {
49
+ i[t.operator] = (i[t.operator] || 0) + 1, this.extractFieldUsage(t.left, r, i), this.extractFieldUsage(t.right, r, i);
50
+ }
51
+ extractFromUnary(t, r, i) {
52
+ i[t.operator] = (i[t.operator] || 0) + 1, this.extractFieldUsage(t.operand, r, i);
53
+ }
54
+ extractFromGroup(t, r, i) {
55
+ this.extractFieldUsage(t.expression, r, i);
56
+ }
57
+ extractFromComparison(t, r, i) {
58
+ const n = t.operator.toLowerCase();
59
+ i[n] = (i[n] || 0) + 1;
60
+ const s = this.getFieldInfo(t.field), a = this.determineMatchType(n, t.value), c = this.extractValue(t.value);
61
+ r.push({
62
+ name: s.name,
63
+ operator: n,
64
+ value: c,
65
+ matchType: a,
66
+ mutators: s.mutators,
67
+ start: t.start,
68
+ end: t.end
69
+ });
70
+ }
71
+ /**
72
+ * Get field name and mutators from field reference or mutator expression
73
+ */
74
+ getFieldInfo(t) {
75
+ if (t.type === "field")
76
+ return {
77
+ name: t.name,
78
+ mutators: t.mutators
79
+ };
80
+ const r = [t.mutator];
81
+ let i = t.field;
82
+ for (; i.type === "mutator"; )
83
+ r.unshift(i.mutator), i = i.field;
84
+ return {
85
+ name: i.name,
86
+ mutators: r
87
+ };
88
+ }
89
+ /**
90
+ * Determine the match type based on operator and value
91
+ */
92
+ determineMatchType(t, r) {
93
+ if (t === "exists" || t === "not_exists")
94
+ return "existence";
95
+ if (t === "is" || t === "is_not")
96
+ return "null_check";
97
+ if (t === "cidr" || t === "not_cidr")
98
+ return "cidr";
99
+ if (t === "regexp" || t === "regex" || t === "matches" || t === "not_regexp" || t === "not_matches")
100
+ return "regex";
101
+ if (t === "between" || t === "not_between" || t === "gt" || t === "gte" || t === "lt" || t === "lte")
102
+ return "range";
103
+ const i = Array.isArray(r) ? r : [r];
104
+ for (const n of i)
105
+ if (n.valueType === "string" && typeof n.value == "string" && n.value.includes("*"))
106
+ return "wildcard";
107
+ return "exact";
108
+ }
109
+ /**
110
+ * Extract the actual value(s) from literal(s)
111
+ */
112
+ extractValue(t) {
113
+ return Array.isArray(t) ? t.map((r) => r.value) : t.value;
114
+ }
115
+ /**
116
+ * Build a logic tree from the AST
117
+ */
118
+ buildLogicTree(t) {
119
+ switch (t.type) {
120
+ case "binary":
121
+ return this.buildBinaryNode(t);
122
+ case "unary":
123
+ return this.buildUnaryNode(t);
124
+ case "comparison":
125
+ return this.buildComparisonNode(t);
126
+ case "group":
127
+ return this.buildGroupNode(t);
128
+ default:
129
+ return {
130
+ type: "comparison",
131
+ start: t.start,
132
+ end: t.end
133
+ };
134
+ }
135
+ }
136
+ buildBinaryNode(t) {
137
+ return {
138
+ type: t.operator,
139
+ children: [
140
+ this.buildLogicTree(t.left),
141
+ this.buildLogicTree(t.right)
142
+ ],
143
+ start: t.start,
144
+ end: t.end
145
+ };
146
+ }
147
+ buildUnaryNode(t) {
148
+ return {
149
+ type: "NOT",
150
+ children: [this.buildLogicTree(t.operand)],
151
+ start: t.start,
152
+ end: t.end
153
+ };
154
+ }
155
+ buildComparisonNode(t) {
156
+ const r = this.getFieldInfo(t.field), i = this.extractValue(t.value);
157
+ return {
158
+ type: "comparison",
159
+ field: r.name,
160
+ operator: t.operator,
161
+ value: i,
162
+ mutators: r.mutators,
163
+ start: t.start,
164
+ end: t.end
165
+ };
166
+ }
167
+ buildGroupNode(t) {
168
+ return {
169
+ type: "group",
170
+ children: [this.buildLogicTree(t.expression)],
171
+ start: t.start,
172
+ end: t.end
173
+ };
174
+ }
175
+ }
176
+ function b(e) {
177
+ return new u().generatePreview(e);
178
+ }
179
+ function F(e) {
180
+ return new u().generatePreview(e).fields;
181
+ }
182
+ function N(e) {
183
+ return new u().generatePreview(e).logicTree;
184
+ }
185
+ function P(e) {
186
+ return new u().generatePreview(e).uniqueFields;
187
+ }
188
+ function U(e) {
189
+ return new u().generatePreview(e).operatorSummary;
190
+ }
191
+ function g(e) {
192
+ var t, r, i;
193
+ if (e.type === "comparison") {
194
+ const n = (t = e.mutators) != null && t.length ? ` | ${e.mutators.join(" | ")}` : "", s = m(e.value);
195
+ return `${e.field}${n} ${e.operator} ${s}`;
196
+ }
197
+ return e.type === "NOT" && ((r = e.children) == null ? void 0 : r.length) === 1 ? `NOT (${g(e.children[0])})` : e.type === "group" && ((i = e.children) == null ? void 0 : i.length) === 1 ? `(${g(e.children[0])})` : (e.type === "AND" || e.type === "OR") && e.children ? e.children.map(g).join(` ${e.type} `) : "";
198
+ }
199
+ function m(e) {
200
+ return e === null ? "null" : e === void 0 ? "" : typeof e == "string" ? `"${e}"` : Array.isArray(e) ? `[${e.map(m).join(", ")}]` : String(e);
201
+ }
202
+ function L(e, t = "") {
203
+ if (!e)
204
+ return "(empty)";
205
+ const r = [];
206
+ return o(e, r, "", !0), r.join(`
207
+ `);
208
+ }
209
+ function o(e, t, r, i) {
210
+ var a, c, l;
211
+ const n = i ? "└── " : "├── ", s = i ? " " : "│ ";
212
+ if (e.type === "comparison") {
213
+ const h = (a = e.mutators) != null && a.length ? ` | ${e.mutators.join(" | ")}` : "", f = m(e.value);
214
+ t.push(`${r}${n}${e.field}${h} ${e.operator} ${f}`);
215
+ } else e.type === "NOT" ? (t.push(`${r}${n}NOT`), (c = e.children) != null && c.length && o(e.children[0], t, r + s, !0)) : e.type === "group" ? (t.push(`${r}${n}GROUP`), (l = e.children) != null && l.length && o(e.children[0], t, r + s, !0)) : e.children && (t.push(`${r}${n}${e.type}`), e.children.forEach((h, f) => {
216
+ const d = f === e.children.length - 1;
217
+ o(h, t, r + s, d);
218
+ }));
219
+ }
220
+ function w(e) {
221
+ return e ? e.type === "comparison" ? [e] : e.children ? e.children.flatMap(w) : [] : [];
222
+ }
223
+ function T(e) {
224
+ if (!e)
225
+ return 0;
226
+ if (!e.children || e.children.length === 0)
227
+ return 1;
228
+ const t = e.children.map(T);
229
+ return 1 + Math.max(...t);
230
+ }
231
+ export {
232
+ u as SemanticPreview,
233
+ w as flattenLogicTree,
234
+ L as formatLogicTreeAscii,
235
+ g as formatLogicTreeNode,
236
+ b as generatePreview,
237
+ F as getFieldUsage,
238
+ N as getLogicTree,
239
+ T as getLogicTreeDepth,
240
+ U as getOperatorSummary,
241
+ P as getUniqueFields
242
+ };
@@ -154,6 +154,10 @@ export interface TqlCompletionItem {
154
154
  sortOrder: number;
155
155
  filterText?: string;
156
156
  commitCharacters?: string[];
157
+ /** Match score from fuzzy matching (higher is better) */
158
+ matchScore?: number;
159
+ /** Indices of matched characters for highlighting */
160
+ matchedIndices?: number[];
157
161
  }
158
162
  export type TqlCompletionKind = "field" | "operator" | "value" | "keyword" | "snippet" | "mutator" | "aggregation" | "logicalOp" | "typeHint" | "visualization";
159
163
  export interface TqlCompletionContext {
@@ -171,6 +175,10 @@ export interface TqlCompletionOptions {
171
175
  includeVisualizations?: boolean;
172
176
  maxItems?: number;
173
177
  fieldValues?: Record<string, string[]>;
178
+ /** Enable fuzzy matching for filtering completions (default: true) */
179
+ fuzzyMatching?: boolean;
180
+ /** Minimum fuzzy match score to include (default: 0) */
181
+ minFuzzyScore?: number;
174
182
  }
175
183
  export interface TqlFieldSchema {
176
184
  name: string;
@@ -197,11 +205,30 @@ export interface TqlInputProps {
197
205
  validateOnInput?: boolean;
198
206
  debounceMs?: number;
199
207
  fieldSchema?: TqlFieldSchema[];
208
+ fieldValues?: Record<string, string[]>;
200
209
  modelName?: string;
201
210
  snippets?: TqlSnippet[];
202
211
  showSnippetButton?: boolean;
203
212
  autocomplete?: boolean;
204
213
  syntaxHighlighting?: boolean;
214
+ /** Always show validation errors instead of requiring click on icon. Defaults to true. */
215
+ alwaysShowErrors?: boolean;
216
+ /** Allow textarea to be resized (only applies when multiline is true) */
217
+ resizable?: boolean;
218
+ /** Minimum height for the input */
219
+ minHeight?: string;
220
+ /** Show complexity badge and warnings (default: false) */
221
+ showComplexity?: boolean;
222
+ /** Show query history dropdown (default: false) */
223
+ showHistory?: boolean;
224
+ /** Show logic tree preview panel (default: false) */
225
+ showPreview?: boolean;
226
+ /** Custom complexity thresholds */
227
+ complexityThresholds?: ComplexityThresholds;
228
+ /** Query history options */
229
+ historyOptions?: UseQueryHistoryOptions;
230
+ /** Storage key for history (default: 'tql-history') */
231
+ historyStorageKey?: string;
205
232
  }
206
233
  export interface TqlInputEmits {
207
234
  (e: "update:modelValue", value: string): void;
@@ -219,3 +246,97 @@ export interface TqlInputExpose {
219
246
  getCursorPosition(): number;
220
247
  setCursorPosition(pos: number): void;
221
248
  }
249
+ export type ComplexityScore = "low" | "medium" | "high";
250
+ export interface ComplexityWarning {
251
+ type: ComplexityWarningType;
252
+ message: string;
253
+ severity: "info" | "warning" | "error";
254
+ location?: {
255
+ start: number;
256
+ end: number;
257
+ };
258
+ }
259
+ export type ComplexityWarningType = "leading_wildcard" | "multiple_wildcards" | "deep_nesting" | "multiple_regex" | "large_in_list" | "post_processing_mutator" | "complex_or_chain" | "nested_negation";
260
+ export interface ComplexityMetrics {
261
+ depth: number;
262
+ operatorCount: number;
263
+ wildcardCount: number;
264
+ leadingWildcardCount: number;
265
+ regexCount: number;
266
+ mutatorCount: number;
267
+ postProcessingMutatorCount: number;
268
+ inListMaxSize: number;
269
+ orChainLength: number;
270
+ andChainLength: number;
271
+ negationDepth: number;
272
+ }
273
+ export interface ComplexityResult {
274
+ score: ComplexityScore;
275
+ warnings: ComplexityWarning[];
276
+ suggestions: string[];
277
+ metrics: ComplexityMetrics;
278
+ }
279
+ export interface ComplexityThresholds {
280
+ /** Depth at which to warn (default: 5) */
281
+ maxDepth?: number;
282
+ /** Number of regex operators to warn (default: 3) */
283
+ maxRegex?: number;
284
+ /** Size of in-list to warn (default: 100) */
285
+ maxInListSize?: number;
286
+ /** Length of OR chain to warn (default: 10) */
287
+ maxOrChainLength?: number;
288
+ /** Number of leading wildcards to warn (default: 2) */
289
+ maxLeadingWildcards?: number;
290
+ }
291
+ export type MatchType = "exact" | "wildcard" | "range" | "regex" | "existence" | "null_check" | "cidr";
292
+ export interface FieldUsage {
293
+ name: string;
294
+ operator: string;
295
+ value: unknown;
296
+ matchType: MatchType;
297
+ mutators?: string[];
298
+ start: number;
299
+ end: number;
300
+ }
301
+ export type LogicTreeNodeType = "AND" | "OR" | "NOT" | "comparison" | "group";
302
+ export interface LogicTreeNode {
303
+ type: LogicTreeNodeType;
304
+ children?: LogicTreeNode[];
305
+ field?: string;
306
+ operator?: string;
307
+ value?: unknown;
308
+ mutators?: string[];
309
+ start: number;
310
+ end: number;
311
+ }
312
+ export interface PreviewResult {
313
+ fields: FieldUsage[];
314
+ logicTree: LogicTreeNode | null;
315
+ complexity: ComplexityResult;
316
+ fieldCount: number;
317
+ uniqueFields: string[];
318
+ operatorSummary: Record<string, number>;
319
+ }
320
+ export interface QueryHistoryEntry {
321
+ id: string;
322
+ query: string;
323
+ timestamp: number;
324
+ label?: string;
325
+ isFavorite: boolean;
326
+ metadata?: {
327
+ index?: string;
328
+ resultCount?: number;
329
+ executionTime?: number;
330
+ [key: string]: unknown;
331
+ };
332
+ }
333
+ export interface UseQueryHistoryOptions {
334
+ /** Maximum number of history entries to keep (default: 100) */
335
+ maxHistory?: number;
336
+ /** Storage key for localStorage (default: 'tql-history') */
337
+ storageKey?: string;
338
+ /** Custom storage implementation (default: localStorage) */
339
+ storage?: Storage;
340
+ /** Auto-deduplicate identical queries (default: true) */
341
+ deduplicate?: boolean;
342
+ }
package/dist/style.css CHANGED
@@ -1 +1 @@
1
- .tql-autocomplete-dropdown[data-v-6381bbdd]{position:fixed;top:var(--dropdown-top);left:var(--dropdown-left);z-index:9999;min-width:280px;max-width:450px;max-height:var(--dropdown-max-height);background:var(--surface-overlay, #fff);border:1px solid var(--surface-border, #ddd);border-radius:var(--border-radius, 6px);box-shadow:0 4px 16px #00000026;overflow:hidden;display:flex;flex-direction:column}.tql-completion-list[data-v-6381bbdd]{overflow-y:auto;max-height:calc(var(--dropdown-max-height) - 60px)}.tql-completion-item[data-v-6381bbdd]{display:flex;align-items:center;gap:.5rem;padding:.5rem .75rem;cursor:pointer;transition:background-color .15s}.tql-completion-item[data-v-6381bbdd]:hover,.tql-completion-item.selected[data-v-6381bbdd]{background:var(--highlight-bg, #f0f0f0)}.tql-completion-icon[data-v-6381bbdd]{display:flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;border-radius:4px;font-size:.75rem}.tql-completion-icon.tql-completion-kind-field[data-v-6381bbdd]{background:var(--blue-100, #e3f2fd);color:var(--blue-600, #1e88e5)}.tql-completion-icon.tql-completion-kind-operator[data-v-6381bbdd]{background:var(--pink-100, #fce4ec);color:var(--pink-600, #d81b60)}.tql-completion-icon.tql-completion-kind-value[data-v-6381bbdd]{background:var(--green-100, #e8f5e9);color:var(--green-600, #43a047)}.tql-completion-icon.tql-completion-kind-keyword[data-v-6381bbdd]{background:var(--purple-100, #f3e5f5);color:var(--purple-600, #8e24aa)}.tql-completion-icon.tql-completion-kind-snippet[data-v-6381bbdd]{background:var(--orange-100, #fff3e0);color:var(--orange-600, #fb8c00)}.tql-completion-icon.tql-completion-kind-mutator[data-v-6381bbdd]{background:var(--cyan-100, #e0f7fa);color:var(--cyan-600, #00acc1)}.tql-completion-icon.tql-completion-kind-aggregation[data-v-6381bbdd]{background:var(--indigo-100, #e8eaf6);color:var(--indigo-600, #3949ab)}.tql-completion-icon.tql-completion-kind-logicalOp[data-v-6381bbdd]{background:var(--yellow-100, #fffde7);color:var(--yellow-700, #fbc02d)}.tql-completion-icon.tql-completion-kind-typeHint[data-v-6381bbdd]{background:var(--teal-100, #e0f2f1);color:var(--teal-600, #00897b)}.tql-completion-icon.tql-completion-kind-visualization[data-v-6381bbdd]{background:var(--red-100, #ffebee);color:var(--red-600, #e53935)}.tql-completion-content[data-v-6381bbdd]{flex:1;display:flex;flex-direction:column;min-width:0}.tql-completion-label[data-v-6381bbdd]{font-family:Courier New,monospace;font-size:.875rem;font-weight:500;color:var(--text-color, #333);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.tql-completion-detail[data-v-6381bbdd]{font-size:.75rem;color:var(--text-color-secondary, #666);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.tql-completion-kind-badge[data-v-6381bbdd]{font-size:.625rem;padding:.125rem .375rem;background:var(--surface-100, #f5f5f5);border-radius:3px;color:var(--text-color-secondary, #666);text-transform:uppercase;letter-spacing:.025em}.tql-completion-docs[data-v-6381bbdd]{padding:.5rem .75rem;border-top:1px solid var(--surface-border, #ddd);background:var(--surface-50, #fafafa);font-size:.75rem;color:var(--text-color-secondary, #666);max-height:60px;overflow-y:auto}.tql-input-wrapper[data-v-c0e226bb]{position:relative;display:flex;align-items:flex-start;border:1px solid var(--surface-border, #ddd);border-radius:var(--border-radius, 6px);background:var(--surface-ground, #fff);transition:border-color .2s,box-shadow .2s}.tql-input-wrapper.tql-input-focused[data-v-c0e226bb]{border-color:var(--primary-color, #3b82f6);box-shadow:0 0 0 2px var(--primary-100, rgba(59, 130, 246, .2))}.tql-input-wrapper.tql-input-invalid[data-v-c0e226bb]{border-color:var(--red-500, #ef4444)}.tql-input-wrapper.tql-input-invalid.tql-input-focused[data-v-c0e226bb]{box-shadow:0 0 0 2px var(--red-100, rgba(239, 68, 68, .2))}.tql-input-wrapper.tql-input-disabled[data-v-c0e226bb]{opacity:.6;cursor:not-allowed}.tql-highlight-layer[data-v-c0e226bb]{position:absolute;top:0;left:0;right:0;bottom:0;padding:.5rem .75rem;pointer-events:none;white-space:pre-wrap;word-wrap:break-word;font-family:Courier New,monospace;font-size:.875rem;line-height:1.5;overflow:hidden}.tql-input-multiline .tql-highlight-layer[data-v-c0e226bb]{overflow-y:auto}.tql-input[data-v-c0e226bb]{flex:1;width:100%;padding:.5rem 2.5rem .5rem .75rem;border:none;background:transparent;font-family:Courier New,monospace;font-size:.875rem;line-height:1.5;color:var(--text-color, #333);outline:none;resize:none}.tql-input.tql-input-highlighted[data-v-c0e226bb]{color:transparent;caret-color:var(--text-color, #333)}.tql-input[data-v-c0e226bb]::placeholder{color:var(--text-color-secondary, #666);opacity:.7}.tql-input[data-v-c0e226bb]:disabled{cursor:not-allowed}.tql-token-field[data-v-c0e226bb]{color:var(--tql-field-color, var(--blue-600, #2563eb))}.tql-token-operator[data-v-c0e226bb]{color:var(--tql-operator-color, var(--pink-600, #db2777));font-weight:500}.tql-token-logicalOp[data-v-c0e226bb]{color:var(--tql-logical-color, var(--purple-600, #9333ea));font-weight:600}.tql-token-collectionOp[data-v-c0e226bb]{color:var(--tql-collection-color, var(--indigo-600, #4f46e5));font-weight:600}.tql-token-string[data-v-c0e226bb]{color:var(--tql-string-color, var(--green-600, #16a34a))}.tql-token-number[data-v-c0e226bb]{color:var(--tql-number-color, var(--orange-600, #ea580c))}.tql-token-boolean[data-v-c0e226bb]{color:var(--tql-boolean-color, var(--cyan-600, #0891b2))}.tql-token-null[data-v-c0e226bb]{color:var(--tql-null-color, var(--gray-500, #6b7280));font-style:italic}.tql-token-mutator[data-v-c0e226bb]{color:var(--tql-mutator-color, var(--teal-600, #0d9488));font-style:italic}.tql-token-aggregation[data-v-c0e226bb]{color:var(--tql-aggregation-color, var(--indigo-600, #4f46e5))}.tql-token-keyword[data-v-c0e226bb]{color:var(--tql-keyword-color, var(--purple-500, #a855f7))}.tql-token-typeHint[data-v-c0e226bb]{color:var(--tql-typehint-color, var(--teal-500, #14b8a6))}.tql-token-visualization[data-v-c0e226bb]{color:var(--tql-viz-color, var(--red-500, #ef4444))}.tql-token-arrow[data-v-c0e226bb]{color:var(--tql-arrow-color, var(--gray-600, #4b5563));font-weight:600}.tql-token-doubleColon[data-v-c0e226bb]{color:var(--tql-colon-color, var(--gray-500, #6b7280))}.tql-token-paren[data-v-c0e226bb],.tql-token-bracket[data-v-c0e226bb]{color:var(--tql-bracket-color, var(--gray-600, #4b5563))}.tql-token-error[data-v-c0e226bb]{color:var(--tql-error-color, var(--red-600, #dc2626));text-decoration:wavy underline;text-decoration-color:var(--red-400, #f87171)}.tql-token-error-range[data-v-c0e226bb]{background-color:var(--red-50, #fef2f2)}.tql-token-unknown[data-v-c0e226bb]{color:var(--text-color-secondary, #666)}.tql-validation-icon[data-v-c0e226bb]{position:absolute;right:.5rem;top:50%;transform:translateY(-50%);display:flex;align-items:center;justify-content:center}.tql-input-multiline .tql-validation-icon[data-v-c0e226bb]{top:.75rem;transform:none}.tql-icon-valid[data-v-c0e226bb]{color:var(--green-500, #22c55e)}.tql-icon-invalid[data-v-c0e226bb]{color:var(--red-500, #ef4444)}.tql-icon-clickable[data-v-c0e226bb]{cursor:pointer;transition:transform .2s}.tql-icon-clickable[data-v-c0e226bb]:hover{transform:scale(1.2)}.tql-icon-clickable[data-v-c0e226bb]:focus{outline:2px solid var(--primary-color, #3b82f6);outline-offset:2px;border-radius:50%}.tql-snippet-button[data-v-c0e226bb]{position:absolute;right:2rem;top:50%;transform:translateY(-50%);padding:.25rem;border:none;background:transparent;color:var(--text-color-secondary, #666);cursor:pointer;border-radius:var(--border-radius, 6px);transition:color .2s,background-color .2s}.tql-snippet-button[data-v-c0e226bb]:hover{color:var(--primary-color, #3b82f6);background:var(--surface-100, #f5f5f5)}.tql-input-multiline .tql-snippet-button[data-v-c0e226bb]{top:.75rem;transform:none}.tql-validation-messages[data-v-c0e226bb]{position:absolute;top:100%;left:0;right:0;margin-top:.25rem;background:var(--surface-overlay, #fff);border:1px solid var(--red-200, #fecaca);border-radius:var(--border-radius, 6px);padding:.5rem;z-index:10;box-shadow:0 2px 8px #0000001a}.tql-error-message[data-v-c0e226bb]{display:flex;align-items:flex-start;gap:.5rem;padding:.25rem 0;font-size:.75rem;color:var(--red-600, #dc2626)}.tql-error-message i[data-v-c0e226bb]{margin-top:.125rem;font-size:.75rem}.tql-error-suggestion[data-v-c0e226bb]{display:block;color:var(--text-color-secondary, #666);font-style:italic;margin-left:1.25rem}
1
+ .tql-autocomplete-dropdown[data-v-3df9a4be]{position:fixed;top:var(--dropdown-top);left:var(--dropdown-left);z-index:9999;min-width:280px;max-width:450px;max-height:var(--dropdown-max-height);background:var(--surface-overlay, #fff);border:1px solid var(--surface-border, #ddd);border-radius:var(--border-radius, 6px);box-shadow:0 4px 16px #00000026;overflow:hidden;display:flex;flex-direction:column}.tql-completion-list[data-v-3df9a4be]{overflow-y:auto;max-height:calc(var(--dropdown-max-height) - 60px)}.tql-completion-item[data-v-3df9a4be]{display:flex;align-items:center;gap:.5rem;padding:.5rem .75rem;cursor:pointer;transition:background-color .15s}.tql-completion-item[data-v-3df9a4be]:hover,.tql-completion-item.selected[data-v-3df9a4be]{background:var(--highlight-bg, #f0f0f0)}.tql-completion-icon[data-v-3df9a4be]{display:flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;border-radius:4px;font-size:.75rem}.tql-completion-icon.tql-completion-kind-field[data-v-3df9a4be]{background:var(--blue-100, #e3f2fd);color:var(--blue-600, #1e88e5)}.tql-completion-icon.tql-completion-kind-operator[data-v-3df9a4be]{background:var(--pink-100, #fce4ec);color:var(--pink-600, #d81b60)}.tql-completion-icon.tql-completion-kind-value[data-v-3df9a4be]{background:var(--green-100, #e8f5e9);color:var(--green-600, #43a047)}.tql-completion-icon.tql-completion-kind-keyword[data-v-3df9a4be]{background:var(--purple-100, #f3e5f5);color:var(--purple-600, #8e24aa)}.tql-completion-icon.tql-completion-kind-snippet[data-v-3df9a4be]{background:var(--orange-100, #fff3e0);color:var(--orange-600, #fb8c00)}.tql-completion-icon.tql-completion-kind-mutator[data-v-3df9a4be]{background:var(--cyan-100, #e0f7fa);color:var(--cyan-600, #00acc1)}.tql-completion-icon.tql-completion-kind-aggregation[data-v-3df9a4be]{background:var(--indigo-100, #e8eaf6);color:var(--indigo-600, #3949ab)}.tql-completion-icon.tql-completion-kind-logicalOp[data-v-3df9a4be]{background:var(--yellow-100, #fffde7);color:var(--yellow-700, #fbc02d)}.tql-completion-icon.tql-completion-kind-typeHint[data-v-3df9a4be]{background:var(--teal-100, #e0f2f1);color:var(--teal-600, #00897b)}.tql-completion-icon.tql-completion-kind-visualization[data-v-3df9a4be]{background:var(--red-100, #ffebee);color:var(--red-600, #e53935)}.tql-completion-content[data-v-3df9a4be]{flex:1;display:flex;flex-direction:column;min-width:0}.tql-completion-label[data-v-3df9a4be]{font-family:Courier New,monospace;font-size:.875rem;font-weight:500;color:var(--text-color, #333);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.tql-completion-detail[data-v-3df9a4be]{font-size:.75rem;color:var(--text-color-secondary, #666);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.tql-completion-kind-badge[data-v-3df9a4be]{font-size:.625rem;padding:.125rem .375rem;background:var(--surface-100, #f5f5f5);border-radius:3px;color:var(--text-color-secondary, #666);text-transform:uppercase;letter-spacing:.025em}.tql-completion-docs[data-v-3df9a4be]{padding:.5rem .75rem;border-top:1px solid var(--surface-border, #ddd);background:var(--surface-50, #fafafa);font-size:.75rem;color:var(--text-color-secondary, #666);max-height:60px;overflow-y:auto}.tql-preview[data-v-bae811e6]{font-family:ui-monospace,monospace;font-size:13px;line-height:1.5;padding:12px;border:1px solid var(--tql-preview-border, #e0e0e0);border-radius:6px;background:var(--tql-preview-bg, #fafafa)}.tql-preview--compact[data-v-bae811e6]{padding:8px;font-size:12px}.tql-preview--empty[data-v-bae811e6]{color:var(--tql-preview-muted, #888)}.tql-preview__empty[data-v-bae811e6]{text-align:center;padding:20px}.tql-preview__complexity[data-v-bae811e6]{display:flex;align-items:center;gap:12px;margin-bottom:12px}.tql-preview__complexity-badge[data-v-bae811e6]{padding:2px 8px;border-radius:4px;font-size:11px;font-weight:600;text-transform:uppercase}.tql-preview--low .tql-preview__complexity-badge[data-v-bae811e6]{background:var(--tql-preview-low-bg, #e8f5e9);color:var(--tql-preview-low-text, #2e7d32)}.tql-preview--medium .tql-preview__complexity-badge[data-v-bae811e6]{background:var(--tql-preview-medium-bg, #fff3e0);color:var(--tql-preview-medium-text, #e65100)}.tql-preview--high .tql-preview__complexity-badge[data-v-bae811e6]{background:var(--tql-preview-high-bg, #ffebee);color:var(--tql-preview-high-text, #c62828)}.tql-preview__field-count[data-v-bae811e6]{color:var(--tql-preview-muted, #666);font-size:12px}.tql-preview__warnings[data-v-bae811e6]{margin-bottom:12px}.tql-preview__warning[data-v-bae811e6]{display:flex;align-items:flex-start;gap:8px;padding:6px 8px;border-radius:4px;margin-bottom:4px}.tql-preview__warning--info[data-v-bae811e6]{background:var(--tql-preview-info-bg, #e3f2fd);color:var(--tql-preview-info-text, #1565c0)}.tql-preview__warning--warning[data-v-bae811e6]{background:var(--tql-preview-warning-bg, #fff3e0);color:var(--tql-preview-warning-text, #e65100)}.tql-preview__warning--error[data-v-bae811e6]{background:var(--tql-preview-error-bg, #ffebee);color:var(--tql-preview-error-text, #c62828)}.tql-preview__warning-icon[data-v-bae811e6]{font-weight:700;width:16px;text-align:center}.tql-preview__warning-text[data-v-bae811e6]{flex:1}.tql-preview__suggestions[data-v-bae811e6]{margin-bottom:12px;padding:8px;background:var(--tql-preview-suggestion-bg, #f5f5f5);border-radius:4px}.tql-preview__suggestions-header[data-v-bae811e6]{font-weight:600;margin-bottom:4px;color:var(--tql-preview-header, #333)}.tql-preview__suggestions-list[data-v-bae811e6]{margin:0;padding-left:20px}.tql-preview__suggestion[data-v-bae811e6]{color:var(--tql-preview-muted, #666);margin:2px 0}.tql-preview__tree[data-v-bae811e6]{margin-bottom:12px}.tql-preview__tree-header[data-v-bae811e6],.tql-preview__fields-header[data-v-bae811e6],.tql-preview__operators-header[data-v-bae811e6]{font-weight:600;margin-bottom:8px;color:var(--tql-preview-header, #333);font-size:12px;text-transform:uppercase;letter-spacing:.5px}.tql-preview__tree-content[data-v-bae811e6]{border:1px solid var(--tql-preview-tree-border, #e0e0e0);border-radius:4px;background:var(--tql-preview-tree-bg, #fff);padding:8px}.tql-preview__node[data-v-bae811e6]{margin:2px 0}.tql-preview__node-content[data-v-bae811e6]{display:flex;align-items:center;gap:4px;padding:2px 4px;border-radius:3px;cursor:pointer}.tql-preview__node-content[data-v-bae811e6]:hover{background:var(--tql-preview-node-hover, #f0f0f0)}.tql-preview__node-toggle[data-v-bae811e6]{width:16px;height:16px;border:none;background:var(--tql-preview-toggle-bg, #e0e0e0);border-radius:3px;cursor:pointer;font-size:12px;line-height:1;display:flex;align-items:center;justify-content:center}.tql-preview__node-toggle[data-v-bae811e6]:hover{background:var(--tql-preview-toggle-hover, #d0d0d0)}.tql-preview__node-toggle--leaf[data-v-bae811e6]{visibility:hidden}.tql-preview__node-type[data-v-bae811e6]{font-weight:600;color:var(--tql-preview-node-type, #666)}.tql-preview__node--and .tql-preview__node-type[data-v-bae811e6]{color:var(--tql-preview-and, #1976d2)}.tql-preview__node--or .tql-preview__node-type[data-v-bae811e6]{color:var(--tql-preview-or, #7b1fa2)}.tql-preview__node--not .tql-preview__node-type[data-v-bae811e6]{color:var(--tql-preview-not, #c62828)}.tql-preview__node--group .tql-preview__node-type[data-v-bae811e6]{color:var(--tql-preview-group, #666)}.tql-preview__node-label[data-v-bae811e6]{flex:1}.tql-preview__fields-list[data-v-bae811e6]{display:flex;flex-direction:column;gap:4px}.tql-preview__field[data-v-bae811e6]{display:flex;align-items:center;gap:6px;padding:4px 8px;background:var(--tql-preview-field-bg, #fff);border:1px solid var(--tql-preview-field-border, #e0e0e0);border-radius:4px;cursor:pointer}.tql-preview__field[data-v-bae811e6]:hover{background:var(--tql-preview-field-hover, #f5f5f5)}.tql-preview__field-name[data-v-bae811e6]{font-weight:600;color:var(--tql-preview-field-name, #1976d2)}.tql-preview__field-mutators[data-v-bae811e6]{color:var(--tql-preview-mutator, #7b1fa2)}.tql-preview__field-operator[data-v-bae811e6]{color:var(--tql-preview-operator, #666)}.tql-preview__field-value[data-v-bae811e6]{color:var(--tql-preview-value, #2e7d32)}.tql-preview__match-type[data-v-bae811e6]{margin-left:auto;padding:1px 4px;border-radius:3px;font-size:10px;font-weight:600;background:var(--tql-preview-match-bg, #f0f0f0)}.tql-preview__match-type--exact[data-v-bae811e6]{background:var(--tql-preview-match-exact-bg, #e8f5e9);color:var(--tql-preview-match-exact, #2e7d32)}.tql-preview__match-type--wildcard[data-v-bae811e6]{background:var(--tql-preview-match-wildcard-bg, #fff3e0);color:var(--tql-preview-match-wildcard, #e65100)}.tql-preview__match-type--regex[data-v-bae811e6]{background:var(--tql-preview-match-regex-bg, #fce4ec);color:var(--tql-preview-match-regex, #c2185b)}.tql-preview__match-type--range[data-v-bae811e6]{background:var(--tql-preview-match-range-bg, #e3f2fd);color:var(--tql-preview-match-range, #1565c0)}.tql-preview__match-type--cidr[data-v-bae811e6]{background:var(--tql-preview-match-cidr-bg, #f3e5f5);color:var(--tql-preview-match-cidr, #7b1fa2)}.tql-preview__operators-list[data-v-bae811e6]{display:flex;flex-wrap:wrap;gap:8px}.tql-preview__operator[data-v-bae811e6]{padding:2px 6px;background:var(--tql-preview-op-bg, #f0f0f0);border-radius:3px;font-size:11px}.tql-input-wrapper[data-v-46f86043]{position:relative;display:flex;align-items:flex-start;border:1px solid var(--surface-border, #ddd);border-radius:var(--border-radius, 6px);background:var(--surface-ground, #fff);transition:border-color .2s,box-shadow .2s}.tql-input-wrapper.tql-input-focused[data-v-46f86043]{border-color:var(--primary-color, #3b82f6);box-shadow:0 0 0 2px var(--primary-100, rgba(59, 130, 246, .2))}.tql-input-wrapper.tql-input-invalid[data-v-46f86043]{border-color:var(--red-500, #ef4444)}.tql-input-wrapper.tql-input-invalid.tql-input-focused[data-v-46f86043]{box-shadow:0 0 0 2px var(--red-100, rgba(239, 68, 68, .2))}.tql-input-wrapper.tql-input-disabled[data-v-46f86043]{opacity:.6;cursor:not-allowed}.tql-highlight-layer[data-v-46f86043]{position:absolute;top:0;left:0;right:0;bottom:0;padding:.5rem .75rem;pointer-events:none;white-space:pre-wrap;word-wrap:break-word;font-family:Courier New,monospace;font-size:.875rem;line-height:1.5;overflow:hidden}.tql-input-multiline .tql-highlight-layer[data-v-46f86043]{overflow-y:auto}.tql-input[data-v-46f86043]{flex:1;width:100%;padding:.5rem 8rem .5rem .75rem;border:none;background:transparent;font-family:Courier New,monospace;font-size:.875rem;line-height:1.5;color:var(--text-color, #333);outline:none;resize:none}.tql-input.tql-input-highlighted[data-v-46f86043]{color:transparent;caret-color:var(--text-color, #333)}.tql-input[data-v-46f86043]::placeholder{color:var(--text-color-secondary, #666);opacity:.7}.tql-input[data-v-46f86043]:disabled{cursor:not-allowed}.tql-token-field[data-v-46f86043]{color:var(--tql-field-color, var(--blue-600, #2563eb))}.tql-token-operator[data-v-46f86043]{color:var(--tql-operator-color, var(--pink-600, #db2777));font-weight:500}.tql-token-logicalOp[data-v-46f86043]{color:var(--tql-logical-color, var(--purple-600, #9333ea));font-weight:600}.tql-token-collectionOp[data-v-46f86043]{color:var(--tql-collection-color, var(--indigo-600, #4f46e5));font-weight:600}.tql-token-string[data-v-46f86043]{color:var(--tql-string-color, var(--green-600, #16a34a))}.tql-token-number[data-v-46f86043]{color:var(--tql-number-color, var(--orange-600, #ea580c))}.tql-token-boolean[data-v-46f86043]{color:var(--tql-boolean-color, var(--cyan-600, #0891b2))}.tql-token-null[data-v-46f86043]{color:var(--tql-null-color, var(--gray-500, #6b7280));font-style:italic}.tql-token-mutator[data-v-46f86043]{color:var(--tql-mutator-color, var(--teal-600, #0d9488));font-style:italic}.tql-token-aggregation[data-v-46f86043]{color:var(--tql-aggregation-color, var(--indigo-600, #4f46e5))}.tql-token-keyword[data-v-46f86043]{color:var(--tql-keyword-color, var(--purple-500, #a855f7))}.tql-token-typeHint[data-v-46f86043]{color:var(--tql-typehint-color, var(--teal-500, #14b8a6))}.tql-token-visualization[data-v-46f86043]{color:var(--tql-viz-color, var(--red-500, #ef4444))}.tql-token-arrow[data-v-46f86043]{color:var(--tql-arrow-color, var(--gray-600, #4b5563));font-weight:600}.tql-token-doubleColon[data-v-46f86043]{color:var(--tql-colon-color, var(--gray-500, #6b7280))}.tql-token-paren[data-v-46f86043],.tql-token-bracket[data-v-46f86043]{color:var(--tql-bracket-color, var(--gray-600, #4b5563))}.tql-token-error[data-v-46f86043]{color:var(--tql-error-color, var(--red-600, #dc2626));text-decoration:wavy underline;text-decoration-color:var(--red-400, #f87171)}.tql-token-error-range[data-v-46f86043]{background-color:var(--red-50, #fef2f2)}.tql-token-unknown[data-v-46f86043]{color:var(--text-color-secondary, #666)}.tql-validation-icon[data-v-46f86043]{position:absolute;right:.5rem;top:50%;transform:translateY(-50%);display:flex;align-items:center;justify-content:center}.tql-input-multiline .tql-validation-icon[data-v-46f86043]{top:.75rem;transform:none}.tql-icon-valid[data-v-46f86043]{color:var(--green-500, #22c55e)}.tql-icon-invalid[data-v-46f86043]{color:var(--red-500, #ef4444)}.tql-icon-clickable[data-v-46f86043]{cursor:pointer;transition:transform .2s}.tql-icon-clickable[data-v-46f86043]:hover{transform:scale(1.2)}.tql-icon-clickable[data-v-46f86043]:focus{outline:2px solid var(--primary-color, #3b82f6);outline-offset:2px;border-radius:50%}.tql-snippet-button[data-v-46f86043]{position:absolute;right:2rem;top:50%;transform:translateY(-50%);padding:.25rem;border:none;background:transparent;color:var(--text-color-secondary, #666);cursor:pointer;border-radius:var(--border-radius, 6px);transition:color .2s,background-color .2s}.tql-snippet-button[data-v-46f86043]:hover{color:var(--primary-color, #3b82f6);background:var(--surface-100, #f5f5f5)}.tql-input-multiline .tql-snippet-button[data-v-46f86043]{top:.75rem;transform:none}.tql-input-resizable-textarea[data-v-46f86043]{resize:vertical;min-height:80px}.tql-input-wrapper.tql-input-resizable[data-v-46f86043]{height:auto}.tql-input-wrapper.tql-input-resizable .tql-highlight-layer[data-v-46f86043]{height:100%}.tql-validation-messages[data-v-46f86043]{position:absolute;top:100%;left:0;right:0;margin-top:.25rem;background:var(--surface-overlay, #fff);border:1px solid var(--red-200, #fecaca);border-radius:var(--border-radius, 6px);padding:.5rem;z-index:10;box-shadow:0 2px 8px #0000001a}.tql-input-autocomplete-active .tql-validation-messages[data-v-46f86043],.tql-input-autocomplete-active .tql-complexity-warnings[data-v-46f86043],.tql-input-autocomplete-active .tql-history-dropdown[data-v-46f86043],.tql-input-autocomplete-active .tql-preview-panel[data-v-46f86043]{display:none!important}.tql-error-message[data-v-46f86043]{display:flex;align-items:flex-start;gap:.5rem;padding:.25rem 0;font-size:.75rem;color:var(--red-600, #dc2626)}.tql-error-message i[data-v-46f86043]{margin-top:.125rem;font-size:.75rem}.tql-error-suggestion[data-v-46f86043]{display:block;color:var(--text-color-secondary, #666);font-style:italic;margin-left:1.25rem}.sr-only[data-v-46f86043]{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.tql-toolbar[data-v-46f86043]{position:absolute;right:.5rem;top:50%;transform:translateY(-50%);display:flex;align-items:center;gap:.25rem}.tql-input-multiline .tql-toolbar[data-v-46f86043]{top:.5rem;transform:none}.tql-toolbar-button[data-v-46f86043]{padding:.25rem;border:none;background:transparent;color:var(--text-color-secondary, #666);cursor:pointer;border-radius:var(--border-radius, 4px);transition:color .2s,background-color .2s;display:flex;align-items:center;justify-content:center}.tql-toolbar-button[data-v-46f86043]:hover{color:var(--primary-color, #3b82f6);background:var(--surface-100, #f5f5f5)}.tql-toolbar-button--active[data-v-46f86043]{color:var(--primary-color, #3b82f6);background:var(--primary-100, rgba(59, 130, 246, .1))}.tql-validation-status[data-v-46f86043]{display:flex;align-items:center}.tql-complexity-badge[data-v-46f86043]{display:flex;align-items:center;gap:.25rem;padding:.125rem .5rem;border-radius:9999px;font-size:.625rem;font-weight:600;text-transform:uppercase;letter-spacing:.025em}.tql-complexity-low[data-v-46f86043]{background:var(--green-100, #dcfce7);color:var(--green-700, #15803d)}.tql-complexity-medium[data-v-46f86043]{background:var(--yellow-100, #fef9c3);color:var(--yellow-700, #a16207)}.tql-complexity-high[data-v-46f86043]{background:var(--red-100, #fee2e2);color:var(--red-700, #b91c1c)}.tql-complexity-count[data-v-46f86043]{display:inline-flex;align-items:center;justify-content:center;min-width:1rem;height:1rem;padding:0 .25rem;border-radius:9999px;background:currentColor;color:#fff;font-size:.5rem}.tql-complexity-low .tql-complexity-count[data-v-46f86043]{background:var(--green-600, #16a34a)}.tql-complexity-medium .tql-complexity-count[data-v-46f86043]{background:var(--yellow-600, #ca8a04)}.tql-complexity-high .tql-complexity-count[data-v-46f86043]{background:var(--red-600, #dc2626)}.tql-complexity-warnings[data-v-46f86043]{position:absolute;top:100%;left:0;right:0;margin-top:.25rem;background:var(--surface-overlay, #fff);border:1px solid var(--surface-border, #e0e0e0);border-radius:var(--border-radius, 6px);padding:.5rem;z-index:9;box-shadow:0 2px 8px #0000001a}.tql-complexity-warning[data-v-46f86043]{display:flex;align-items:flex-start;gap:.5rem;padding:.25rem 0;font-size:.75rem}.tql-complexity-warning i[data-v-46f86043]{margin-top:.125rem;font-size:.75rem}.tql-complexity-warning--info[data-v-46f86043]{color:var(--blue-600, #2563eb)}.tql-complexity-warning--warning[data-v-46f86043]{color:var(--yellow-600, #ca8a04)}.tql-complexity-warning--error[data-v-46f86043]{color:var(--red-600, #dc2626)}.tql-complexity-suggestions[data-v-46f86043]{margin-top:.5rem;padding-top:.5rem;border-top:1px solid var(--surface-border, #e0e0e0)}.tql-complexity-suggestion[data-v-46f86043]{display:flex;align-items:flex-start;gap:.5rem;padding:.25rem 0;font-size:.75rem;color:var(--text-color-secondary, #666)}.tql-complexity-suggestion i[data-v-46f86043]{color:var(--yellow-500, #eab308)}.tql-history-dropdown[data-v-46f86043]{position:absolute;top:100%;left:0;right:0;margin-top:.25rem;background:var(--surface-overlay, #fff);border:1px solid var(--surface-border, #e0e0e0);border-radius:var(--border-radius, 6px);z-index:20;box-shadow:0 4px 12px #00000026;max-height:300px;overflow:hidden;display:flex;flex-direction:column}.tql-history-header[data-v-46f86043]{padding:.5rem;border-bottom:1px solid var(--surface-border, #e0e0e0)}.tql-history-search[data-v-46f86043]{width:100%;padding:.375rem .5rem;border:1px solid var(--surface-border, #e0e0e0);border-radius:var(--border-radius, 4px);font-size:.75rem;outline:none}.tql-history-search[data-v-46f86043]:focus{border-color:var(--primary-color, #3b82f6)}.tql-history-list[data-v-46f86043]{overflow-y:auto;flex:1}.tql-history-item[data-v-46f86043]{display:flex;align-items:flex-start;gap:.5rem;padding:.5rem;cursor:pointer;border-bottom:1px solid var(--surface-50, #f9fafb);transition:background-color .15s}.tql-history-item[data-v-46f86043]:hover{background:var(--surface-100, #f5f5f5)}.tql-history-item--favorite[data-v-46f86043]{background:var(--yellow-50, #fefce8)}.tql-history-item--favorite[data-v-46f86043]:hover{background:var(--yellow-100, #fef9c3)}.tql-history-favorite[data-v-46f86043]{padding:.125rem;border:none;background:transparent;color:var(--text-color-secondary, #999);cursor:pointer;flex-shrink:0}.tql-history-favorite[data-v-46f86043]:hover,.tql-history-item--favorite .tql-history-favorite[data-v-46f86043]{color:var(--yellow-500, #eab308)}.tql-history-content[data-v-46f86043]{flex:1;min-width:0}.tql-history-label[data-v-46f86043]{font-size:.6875rem;font-weight:600;color:var(--text-color, #333);margin-bottom:.125rem}.tql-history-query[data-v-46f86043]{font-family:Courier New,monospace;font-size:.6875rem;color:var(--text-color-secondary, #666);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.tql-history-time[data-v-46f86043]{font-size:.625rem;color:var(--text-color-secondary, #999);flex-shrink:0}.tql-history-empty[data-v-46f86043]{padding:1rem;text-align:center;color:var(--text-color-secondary, #666);font-size:.75rem}.tql-preview-panel[data-v-46f86043]{position:absolute;top:100%;left:0;right:0;margin-top:.25rem;background:var(--surface-overlay, #fff);border:1px solid var(--surface-border, #e0e0e0);border-radius:var(--border-radius, 6px);z-index:15;box-shadow:0 4px 12px #00000026;max-height:400px;overflow:hidden;display:flex;flex-direction:column}.tql-preview-header[data-v-46f86043]{display:flex;align-items:center;justify-content:space-between;padding:.5rem .75rem;border-bottom:1px solid var(--surface-border, #e0e0e0);font-size:.75rem;font-weight:600;color:var(--text-color, #333)}.tql-preview-close[data-v-46f86043]{padding:.125rem;border:none;background:transparent;color:var(--text-color-secondary, #666);cursor:pointer;border-radius:var(--border-radius, 4px)}.tql-preview-close[data-v-46f86043]:hover{background:var(--surface-100, #f5f5f5);color:var(--text-color, #333)}.tql-preview-panel[data-v-46f86043] .tql-preview{border:none;border-radius:0;max-height:350px;overflow-y:auto}.tql-validation-messages-portal{background:var(--surface-overlay, #fff);border:2px solid var(--red-500, #ef4444);border-radius:var(--border-radius, 6px);padding:.5rem;box-shadow:0 4px 12px #00000026}.tql-validation-messages-portal .tql-error-message{display:flex;align-items:flex-start;gap:.5rem;padding:.25rem 0;font-size:.75rem;color:var(--red-600, #dc2626)}.tql-validation-messages-portal .tql-error-message i{margin-top:.125rem;font-size:.75rem}.tql-validation-messages-portal .tql-error-suggestion{display:block;color:var(--text-color-secondary, #6b7280);font-style:italic;margin-left:1.25rem}
@@ -1,7 +1,7 @@
1
1
  import o from "./TqlAutocomplete.vue2.js";
2
2
  /* empty css */
3
3
  import t from "../_virtual/_plugin-vue_export-helper.js";
4
- const e = /* @__PURE__ */ t(o, [["__scopeId", "data-v-6381bbdd"]]);
4
+ const r = /* @__PURE__ */ t(o, [["__scopeId", "data-v-3df9a4be"]]);
5
5
  export {
6
- e as default
6
+ r as default
7
7
  };
@@ -1,56 +1,57 @@
1
- import { defineComponent as C, ref as y, watch as $, nextTick as D, computed as L, onMounted as T, onUnmounted as S, openBlock as l, createBlock as B, Teleport as z, createElementBlock as s, normalizeStyle as A, createElementVNode as d, Fragment as H, renderList as I, normalizeClass as k, toDisplayString as p, createCommentVNode as u } from "vue";
2
- const K = { class: "tql-completion-list" }, M = ["aria-selected", "onClick", "onMouseenter"], U = { class: "tql-completion-content" }, V = { class: "tql-completion-label" }, N = {
1
+ import { defineComponent as C, ref as w, watch as D, nextTick as L, computed as T, onMounted as S, onUnmounted as B, openBlock as l, createBlock as M, Teleport as z, createElementBlock as s, withModifiers as A, normalizeStyle as H, createElementVNode as u, Fragment as I, renderList as K, normalizeClass as f, toDisplayString as m, createCommentVNode as v } from "vue";
2
+ const U = ["id", "aria-activedescendant"], V = { class: "tql-completion-list" }, _ = ["id", "aria-selected", "onClick", "onMouseenter"], N = { class: "tql-completion-content" }, O = { class: "tql-completion-label" }, R = {
3
3
  key: 0,
4
4
  class: "tql-completion-detail"
5
- }, O = {
5
+ }, F = {
6
6
  key: 0,
7
7
  class: "tql-completion-kind-badge"
8
- }, R = {
8
+ }, P = {
9
9
  key: 0,
10
10
  class: "tql-completion-docs"
11
- }, Q = /* @__PURE__ */ C({
11
+ }, j = /* @__PURE__ */ C({
12
12
  __name: "TqlAutocomplete",
13
13
  props: {
14
+ id: {},
14
15
  items: {},
15
16
  visible: { type: Boolean },
16
17
  position: {},
17
18
  maxHeight: {}
18
19
  },
19
20
  emits: ["select", "close"],
20
- setup(i, { expose: w, emit: b }) {
21
- const t = i, a = b, e = y(0), c = y(null);
22
- $(
21
+ setup(o, { expose: y, emit: b }) {
22
+ const t = o, a = b, e = w(0), c = w(null);
23
+ D(
23
24
  () => t.items,
24
25
  () => {
25
- e.value = 0, r();
26
+ e.value = 0, d();
26
27
  }
27
28
  );
28
- function r() {
29
- D(() => {
29
+ function d() {
30
+ L(() => {
30
31
  if (!c.value) return;
31
- const o = c.value.querySelector(".tql-completion-item.selected");
32
- o && o.scrollIntoView({ block: "nearest" });
32
+ const i = c.value.querySelector(".tql-completion-item.selected");
33
+ i && i.scrollIntoView({ block: "nearest" });
33
34
  });
34
35
  }
35
- function f(o) {
36
+ function k(i) {
36
37
  if (!(!t.visible || t.items.length === 0))
37
- switch (o.key) {
38
+ switch (i.key) {
38
39
  case "ArrowDown":
39
- o.preventDefault(), e.value = (e.value + 1) % t.items.length, r();
40
+ i.preventDefault(), e.value = (e.value + 1) % t.items.length, d();
40
41
  break;
41
42
  case "ArrowUp":
42
- o.preventDefault(), e.value = (e.value - 1 + t.items.length) % t.items.length, r();
43
+ i.preventDefault(), e.value = (e.value - 1 + t.items.length) % t.items.length, d();
43
44
  break;
44
45
  case "Enter":
45
46
  case "Tab":
46
- o.preventDefault(), t.items[e.value] && a("select", t.items[e.value]);
47
+ i.preventDefault(), t.items[e.value] && a("select", t.items[e.value]);
47
48
  break;
48
49
  case "Escape":
49
- o.preventDefault(), a("close");
50
+ i.preventDefault(), a("close");
50
51
  break;
51
52
  }
52
53
  }
53
- function q(o) {
54
+ function q(i) {
54
55
  return {
55
56
  field: "pi pi-tag",
56
57
  operator: "pi pi-code",
@@ -62,75 +63,80 @@ const K = { class: "tql-completion-list" }, M = ["aria-selected", "onClick", "on
62
63
  logicalOp: "pi pi-sitemap",
63
64
  typeHint: "pi pi-info-circle",
64
65
  visualization: "pi pi-chart-line"
65
- }[o] || "pi pi-circle";
66
+ }[i] || "pi pi-circle";
66
67
  }
67
- function _(o) {
68
- return `tql-completion-kind-${o}`;
68
+ function $(i) {
69
+ return `tql-completion-kind-${i}`;
69
70
  }
70
- const x = L(() => ({
71
+ const x = T(() => ({
71
72
  "--dropdown-top": `${t.position.top}px`,
72
73
  "--dropdown-left": `${t.position.left}px`,
73
74
  "--dropdown-max-height": `${t.maxHeight || 300}px`
74
75
  }));
75
- function h(o) {
76
- const m = o.target;
77
- c.value && !c.value.contains(m) && a("close");
76
+ function h(i) {
77
+ const r = i.target;
78
+ c.value && !c.value.contains(r) && a("close");
78
79
  }
79
- return T(() => {
80
- document.addEventListener("keydown", f), document.addEventListener("mousedown", h);
81
- }), S(() => {
82
- document.removeEventListener("keydown", f), document.removeEventListener("mousedown", h);
83
- }), w({
80
+ return S(() => {
81
+ document.addEventListener("keydown", k), document.addEventListener("mousedown", h);
82
+ }), B(() => {
83
+ document.removeEventListener("keydown", k), document.removeEventListener("mousedown", h);
84
+ }), y({
84
85
  selectCurrent: () => {
85
86
  t.items[e.value] && a("select", t.items[e.value]);
86
87
  },
87
88
  moveUp: () => {
88
- e.value = (e.value - 1 + t.items.length) % t.items.length, r();
89
+ e.value = (e.value - 1 + t.items.length) % t.items.length, d();
89
90
  },
90
91
  moveDown: () => {
91
- e.value = (e.value + 1) % t.items.length, r();
92
+ e.value = (e.value + 1) % t.items.length, d();
92
93
  }
93
- }), (o, m) => {
94
+ }), (i, r) => {
94
95
  var g;
95
- return l(), B(z, { to: "body" }, [
96
- i.visible && i.items.length > 0 ? (l(), s("div", {
96
+ return l(), M(z, { to: "body" }, [
97
+ o.visible && o.items.length > 0 ? (l(), s("div", {
97
98
  key: 0,
99
+ id: o.id,
98
100
  ref_key: "listRef",
99
101
  ref: c,
100
102
  class: "tql-autocomplete-dropdown",
101
- style: A(x.value),
103
+ style: H(x.value),
102
104
  role: "listbox",
103
- "aria-label": "TQL completions"
105
+ "aria-label": "TQL completions",
106
+ "aria-activedescendant": o.items[e.value] ? `${o.id}-option-${e.value}` : void 0,
107
+ onPointerdown: r[0] || (r[0] = A(() => {
108
+ }, ["stop"]))
104
109
  }, [
105
- d("div", K, [
106
- (l(!0), s(H, null, I(i.items, (n, v) => (l(), s("div", {
110
+ u("div", V, [
111
+ (l(!0), s(I, null, K(o.items, (n, p) => (l(), s("div", {
112
+ id: `${o.id}-option-${p}`,
107
113
  key: `${n.kind}-${n.label}`,
108
- class: k(["tql-completion-item", { selected: v === e.value }]),
114
+ class: f(["tql-completion-item", { selected: p === e.value }]),
109
115
  role: "option",
110
- "aria-selected": v === e.value,
116
+ "aria-selected": p === e.value,
111
117
  onClick: (E) => a("select", n),
112
- onMouseenter: (E) => e.value = v
118
+ onMouseenter: (E) => e.value = p
113
119
  }, [
114
- d("span", {
115
- class: k(["tql-completion-icon", _(n.kind)])
120
+ u("span", {
121
+ class: f(["tql-completion-icon", $(n.kind)])
116
122
  }, [
117
- d("i", {
118
- class: k(q(n.kind))
123
+ u("i", {
124
+ class: f(q(n.kind))
119
125
  }, null, 2)
120
126
  ], 2),
121
- d("span", U, [
122
- d("span", V, p(n.label), 1),
123
- n.detail ? (l(), s("span", N, p(n.detail), 1)) : u("", !0)
127
+ u("span", N, [
128
+ u("span", O, m(n.label), 1),
129
+ n.detail ? (l(), s("span", R, m(n.detail), 1)) : v("", !0)
124
130
  ]),
125
- n.kind ? (l(), s("span", O, p(n.kind), 1)) : u("", !0)
126
- ], 42, M))), 128))
131
+ n.kind ? (l(), s("span", F, m(n.kind), 1)) : v("", !0)
132
+ ], 42, _))), 128))
127
133
  ]),
128
- (g = i.items[e.value]) != null && g.documentation ? (l(), s("div", R, p(i.items[e.value].documentation), 1)) : u("", !0)
129
- ], 4)) : u("", !0)
134
+ (g = o.items[e.value]) != null && g.documentation ? (l(), s("div", P, m(o.items[e.value].documentation), 1)) : v("", !0)
135
+ ], 44, U)) : v("", !0)
130
136
  ]);
131
137
  };
132
138
  }
133
139
  });
134
140
  export {
135
- Q as default
141
+ j as default
136
142
  };