@aivue/tabular-intelligence 1.5.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +430 -17
- package/dist/advanced/automl.d.ts +29 -0
- package/dist/advanced/automl.d.ts.map +1 -0
- package/dist/advanced/explainability.d.ts +31 -0
- package/dist/advanced/explainability.d.ts.map +1 -0
- package/dist/advanced/featureEngineering.d.ts +28 -0
- package/dist/advanced/featureEngineering.d.ts.map +1 -0
- package/dist/advanced/index.d.ts +16 -0
- package/dist/advanced/index.d.ts.map +1 -0
- package/dist/advanced/multitable.d.ts +28 -0
- package/dist/advanced/multitable.d.ts.map +1 -0
- package/dist/advanced/privacy.d.ts +17 -0
- package/dist/advanced/privacy.d.ts.map +1 -0
- package/dist/advanced/reporting.d.ts +21 -0
- package/dist/advanced/reporting.d.ts.map +1 -0
- package/dist/advanced/statistical.d.ts +28 -0
- package/dist/advanced/statistical.d.ts.map +1 -0
- package/dist/advanced/streaming.d.ts +41 -0
- package/dist/advanced/streaming.d.ts.map +1 -0
- package/dist/advanced/timeseries.d.ts +36 -0
- package/dist/advanced/timeseries.d.ts.map +1 -0
- package/dist/advanced/versioning.d.ts +34 -0
- package/dist/advanced/versioning.d.ts.map +1 -0
- package/dist/advanced/visualization.d.ts +23 -0
- package/dist/advanced/visualization.d.ts.map +1 -0
- package/dist/index.d.ts +15 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +75 -47
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2374 -662
- package/dist/index.mjs.map +1 -1
- package/dist/preprocessing/imputation.d.ts +9 -0
- package/dist/preprocessing/imputation.d.ts.map +1 -0
- package/dist/preprocessing/outliers.d.ts +10 -0
- package/dist/preprocessing/outliers.d.ts.map +1 -0
- package/dist/quality/profiling.d.ts +22 -0
- package/dist/quality/profiling.d.ts.map +1 -0
- package/dist/types/index.d.ts +573 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -1,86 +1,86 @@
|
|
|
1
|
-
import { ref as
|
|
2
|
-
function
|
|
3
|
-
if (
|
|
1
|
+
import { ref as x, defineComponent as K, createElementBlock as C, openBlock as A, createElementVNode as b, createCommentVNode as T, withDirectives as ge, withKeys as X, withModifiers as Y, vModelText as ye, toDisplayString as M, normalizeClass as we, createTextVNode as ve, Fragment as F, renderList as j, computed as be } from "vue";
|
|
2
|
+
function _(s, e) {
|
|
3
|
+
if (s.length === 0)
|
|
4
4
|
return { columns: [], rowCount: 0, name: e };
|
|
5
|
-
const
|
|
5
|
+
const t = s[0];
|
|
6
6
|
return {
|
|
7
|
-
columns: Object.keys(
|
|
8
|
-
const
|
|
7
|
+
columns: Object.keys(t).map((o) => {
|
|
8
|
+
const a = te(s, o);
|
|
9
9
|
return {
|
|
10
|
-
name:
|
|
11
|
-
type:
|
|
12
|
-
nullable:
|
|
10
|
+
name: o,
|
|
11
|
+
type: a,
|
|
12
|
+
nullable: s.some((i) => i[o] == null)
|
|
13
13
|
};
|
|
14
14
|
}),
|
|
15
|
-
rowCount:
|
|
15
|
+
rowCount: s.length,
|
|
16
16
|
name: e
|
|
17
17
|
};
|
|
18
18
|
}
|
|
19
|
-
function
|
|
20
|
-
const
|
|
21
|
-
if (
|
|
22
|
-
if (
|
|
19
|
+
function te(s, e) {
|
|
20
|
+
const t = s.map((o) => o[e]).filter((o) => o != null);
|
|
21
|
+
if (t.length === 0) return "string";
|
|
22
|
+
if (t.every((o) => typeof o == "number" || !isNaN(Number(o))))
|
|
23
23
|
return "number";
|
|
24
|
-
if (
|
|
24
|
+
if (t.every((o) => typeof o == "boolean" || o === "true" || o === "false"))
|
|
25
25
|
return "boolean";
|
|
26
|
-
if (
|
|
26
|
+
if (t.every((o) => !isNaN(Date.parse(o))))
|
|
27
27
|
return "date";
|
|
28
|
-
const
|
|
29
|
-
return
|
|
28
|
+
const n = new Set(t);
|
|
29
|
+
return n.size < t.length * 0.5 && n.size < 20 ? "categorical" : "string";
|
|
30
30
|
}
|
|
31
|
-
function
|
|
32
|
-
const
|
|
31
|
+
function ne(s, e, t) {
|
|
32
|
+
const n = s.map((r) => r[e]).filter((r) => r != null), o = n.length, a = s.length - o, i = {
|
|
33
33
|
column: e,
|
|
34
|
-
count:
|
|
35
|
-
nullCount:
|
|
34
|
+
count: o,
|
|
35
|
+
nullCount: a
|
|
36
36
|
};
|
|
37
|
-
if (
|
|
38
|
-
const
|
|
39
|
-
if (
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
25:
|
|
45
|
-
50:
|
|
46
|
-
75:
|
|
47
|
-
90:
|
|
37
|
+
if (t === "number") {
|
|
38
|
+
const r = n.map(Number).filter((c) => !isNaN(c));
|
|
39
|
+
if (r.length > 0) {
|
|
40
|
+
const c = [...r].sort((m, d) => m - d), l = r.reduce((m, d) => m + d, 0);
|
|
41
|
+
i.mean = l / r.length, i.median = c[Math.floor(c.length / 2)], i.min = c[0], i.max = c[c.length - 1];
|
|
42
|
+
const u = r.reduce((m, d) => m + Math.pow(d - i.mean, 2), 0) / r.length;
|
|
43
|
+
i.std = Math.sqrt(u), i.percentiles = {
|
|
44
|
+
25: c[Math.floor(c.length * 0.25)],
|
|
45
|
+
50: i.median,
|
|
46
|
+
75: c[Math.floor(c.length * 0.75)],
|
|
47
|
+
90: c[Math.floor(c.length * 0.9)]
|
|
48
48
|
};
|
|
49
49
|
}
|
|
50
50
|
} else {
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
const m = String(
|
|
56
|
-
|
|
51
|
+
const r = new Set(n);
|
|
52
|
+
i.uniqueValues = r.size;
|
|
53
|
+
const c = {};
|
|
54
|
+
n.forEach((u) => {
|
|
55
|
+
const m = String(u);
|
|
56
|
+
c[m] = (c[m] || 0) + 1;
|
|
57
57
|
});
|
|
58
|
-
const
|
|
59
|
-
|
|
58
|
+
const l = Math.max(...Object.values(c));
|
|
59
|
+
i.mode = Object.keys(c).find((u) => c[u] === l);
|
|
60
60
|
}
|
|
61
|
-
return
|
|
61
|
+
return i;
|
|
62
62
|
}
|
|
63
|
-
function
|
|
64
|
-
const
|
|
65
|
-
return e.forEach((
|
|
66
|
-
const
|
|
67
|
-
if (
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
if (
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
rowIndex:
|
|
74
|
-
row:
|
|
63
|
+
function Ce(s, e, t = 0.5) {
|
|
64
|
+
const n = [], o = 1.5 + (1 - t) * 1.5;
|
|
65
|
+
return e.forEach((a) => {
|
|
66
|
+
const i = s.map((f, h) => ({ value: Number(f[a]), idx: h })).filter((f) => !isNaN(f.value));
|
|
67
|
+
if (i.length === 0) return;
|
|
68
|
+
const r = [...i].sort((f, h) => f.value - h.value), c = r[Math.floor(r.length * 0.25)].value, l = r[Math.floor(r.length * 0.75)].value, u = l - c, m = c - o * u, d = l + o * u;
|
|
69
|
+
i.forEach(({ value: f, idx: h }) => {
|
|
70
|
+
if (f < m || f > d) {
|
|
71
|
+
const p = n.find((g) => g.rowIndex === h), w = f < m ? `${a}: ${f.toFixed(2)} < ${m.toFixed(2)}` : `${a}: ${f.toFixed(2)} > ${d.toFixed(2)}`;
|
|
72
|
+
p ? (p.reasons.push(w), p.affectedColumns.push(a), p.score = Math.min(1, p.score + 0.2)) : n.push({
|
|
73
|
+
rowIndex: h,
|
|
74
|
+
row: s[h],
|
|
75
75
|
score: 0.7,
|
|
76
|
-
reasons: [
|
|
77
|
-
affectedColumns: [
|
|
76
|
+
reasons: [w],
|
|
77
|
+
affectedColumns: [a]
|
|
78
78
|
});
|
|
79
79
|
}
|
|
80
80
|
});
|
|
81
|
-
}),
|
|
81
|
+
}), n.sort((a, i) => i.score - a.score);
|
|
82
82
|
}
|
|
83
|
-
class
|
|
83
|
+
class Z {
|
|
84
84
|
constructor(e) {
|
|
85
85
|
this.config = {
|
|
86
86
|
maxTokens: 1e3,
|
|
@@ -92,171 +92,171 @@ class U {
|
|
|
92
92
|
* Answer a question about the table data
|
|
93
93
|
*/
|
|
94
94
|
async answerQuestion(e) {
|
|
95
|
-
const
|
|
95
|
+
const t = Date.now();
|
|
96
96
|
try {
|
|
97
|
-
const { question:
|
|
98
|
-
if (!
|
|
97
|
+
const { question: n, schema: o, data: a, sampleSize: i = 100, includeAggregates: r = !0 } = e;
|
|
98
|
+
if (!a || !Array.isArray(a) || a.length === 0)
|
|
99
99
|
throw new Error("No data available. Please load data first.");
|
|
100
|
-
if (!
|
|
100
|
+
if (!o || !o.columns || !Array.isArray(o.columns))
|
|
101
101
|
throw new Error("Invalid schema. Please ensure data has a valid schema.");
|
|
102
|
-
const
|
|
102
|
+
const c = a.length > i ? this.sampleData(a, i) : a, l = r ? this.calculateAggregates(a, o) : void 0, u = this.buildPrompt(n, o, c, l, a.length), m = await this.callLLM(u);
|
|
103
103
|
return {
|
|
104
|
-
answer: this.parseResponse(m,
|
|
105
|
-
processingTime: Date.now() -
|
|
104
|
+
answer: this.parseResponse(m, n, a.length > i),
|
|
105
|
+
processingTime: Date.now() - t
|
|
106
106
|
};
|
|
107
|
-
} catch (
|
|
108
|
-
return console.error("Q&A error:",
|
|
107
|
+
} catch (n) {
|
|
108
|
+
return console.error("Q&A error:", n), {
|
|
109
109
|
answer: {
|
|
110
110
|
questionId: this.generateId(),
|
|
111
111
|
text: "I encountered an error while processing your question. Please try again.",
|
|
112
112
|
timestamp: /* @__PURE__ */ new Date(),
|
|
113
113
|
confidence: 0,
|
|
114
114
|
cannotAnswer: !0,
|
|
115
|
-
reason:
|
|
115
|
+
reason: n instanceof Error ? n.message : "Unknown error"
|
|
116
116
|
},
|
|
117
|
-
processingTime: Date.now() -
|
|
117
|
+
processingTime: Date.now() - t
|
|
118
118
|
};
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
121
|
/**
|
|
122
122
|
* Sample data for large datasets
|
|
123
123
|
*/
|
|
124
|
-
sampleData(e,
|
|
124
|
+
sampleData(e, t) {
|
|
125
125
|
if (!e || !Array.isArray(e) || e.length === 0)
|
|
126
126
|
return [];
|
|
127
|
-
if (e.length <=
|
|
127
|
+
if (e.length <= t)
|
|
128
128
|
return e;
|
|
129
|
-
const
|
|
130
|
-
for (let
|
|
131
|
-
|
|
132
|
-
return
|
|
129
|
+
const n = Math.floor(e.length / t), o = [];
|
|
130
|
+
for (let a = 0; a < e.length && o.length < t; a += n)
|
|
131
|
+
o.push(e[a]);
|
|
132
|
+
return o;
|
|
133
133
|
}
|
|
134
134
|
/**
|
|
135
135
|
* Calculate aggregates for numeric columns
|
|
136
136
|
*/
|
|
137
|
-
calculateAggregates(e,
|
|
138
|
-
const
|
|
139
|
-
if (!e || !Array.isArray(e) || e.length === 0 || !
|
|
140
|
-
return
|
|
141
|
-
for (const
|
|
142
|
-
if (
|
|
137
|
+
calculateAggregates(e, t) {
|
|
138
|
+
const n = {};
|
|
139
|
+
if (!e || !Array.isArray(e) || e.length === 0 || !t || !t.columns || !Array.isArray(t.columns))
|
|
140
|
+
return n;
|
|
141
|
+
for (const o of t.columns)
|
|
142
|
+
if (o.type === "number" && e.length > 0)
|
|
143
143
|
try {
|
|
144
|
-
const
|
|
145
|
-
|
|
146
|
-
mean:
|
|
147
|
-
median:
|
|
148
|
-
min:
|
|
149
|
-
max:
|
|
150
|
-
count:
|
|
144
|
+
const a = ne(e, o.name, "number");
|
|
145
|
+
n[o.name] = {
|
|
146
|
+
mean: a.mean,
|
|
147
|
+
median: a.median,
|
|
148
|
+
min: a.min,
|
|
149
|
+
max: a.max,
|
|
150
|
+
count: a.count
|
|
151
151
|
};
|
|
152
152
|
} catch {
|
|
153
153
|
}
|
|
154
|
-
else if (
|
|
155
|
-
const
|
|
156
|
-
|
|
157
|
-
uniqueCount:
|
|
158
|
-
totalCount:
|
|
159
|
-
topValues: this.getTopValues(
|
|
154
|
+
else if (o.type === "categorical" || o.type === "string") {
|
|
155
|
+
const a = e.map((r) => r[o.name]).filter((r) => r != null), i = new Set(a);
|
|
156
|
+
n[o.name] = {
|
|
157
|
+
uniqueCount: i.size,
|
|
158
|
+
totalCount: a.length,
|
|
159
|
+
topValues: this.getTopValues(a, 5)
|
|
160
160
|
};
|
|
161
161
|
}
|
|
162
|
-
return
|
|
162
|
+
return n;
|
|
163
163
|
}
|
|
164
164
|
/**
|
|
165
165
|
* Get top N most frequent values
|
|
166
166
|
*/
|
|
167
|
-
getTopValues(e,
|
|
168
|
-
const
|
|
169
|
-
for (const
|
|
170
|
-
|
|
171
|
-
return Array.from(
|
|
167
|
+
getTopValues(e, t) {
|
|
168
|
+
const n = /* @__PURE__ */ new Map();
|
|
169
|
+
for (const o of e)
|
|
170
|
+
n.set(o, (n.get(o) || 0) + 1);
|
|
171
|
+
return Array.from(n.entries()).map(([o, a]) => ({ value: o, count: a })).sort((o, a) => a.count - o.count).slice(0, t);
|
|
172
172
|
}
|
|
173
173
|
/**
|
|
174
174
|
* Build prompt for LLM
|
|
175
175
|
*/
|
|
176
|
-
buildPrompt(e,
|
|
177
|
-
const
|
|
178
|
-
let
|
|
176
|
+
buildPrompt(e, t, n, o, a) {
|
|
177
|
+
const i = a && a > n.length;
|
|
178
|
+
let r = `You are a data analyst assistant. Answer the following question about a table dataset.
|
|
179
179
|
|
|
180
180
|
`;
|
|
181
|
-
|
|
182
|
-
`,
|
|
183
|
-
`,
|
|
181
|
+
r += `**Table Schema:**
|
|
182
|
+
`, r += `Table: ${t.name}
|
|
183
|
+
`, r += `Columns:
|
|
184
184
|
`;
|
|
185
|
-
for (const
|
|
186
|
-
|
|
185
|
+
for (const c of t.columns)
|
|
186
|
+
r += `- ${c.name} (${c.type})
|
|
187
187
|
`;
|
|
188
|
-
return
|
|
189
|
-
`,
|
|
190
|
-
`,
|
|
188
|
+
return r += `
|
|
189
|
+
`, o && Object.keys(o).length > 0 && (r += `**Summary Statistics:**
|
|
190
|
+
`, r += JSON.stringify(o, null, 2), r += `
|
|
191
191
|
|
|
192
|
-
`),
|
|
193
|
-
`,
|
|
192
|
+
`), r += `**Sample Data** (${n.length} rows${i ? ` out of ${a} total` : ""}):
|
|
193
|
+
`, r += JSON.stringify(n.slice(0, 10), null, 2), r += `
|
|
194
194
|
|
|
195
|
-
`,
|
|
195
|
+
`, r += `**Question:** ${e}
|
|
196
196
|
|
|
197
|
-
`,
|
|
198
|
-
`,
|
|
199
|
-
`,
|
|
200
|
-
`,
|
|
201
|
-
`,
|
|
202
|
-
`,
|
|
203
|
-
`,
|
|
204
|
-
`,
|
|
205
|
-
`,
|
|
206
|
-
`,
|
|
207
|
-
`,
|
|
208
|
-
`,
|
|
209
|
-
`,
|
|
210
|
-
`,
|
|
211
|
-
`,
|
|
212
|
-
`,
|
|
213
|
-
`,
|
|
214
|
-
`,
|
|
215
|
-
`,
|
|
216
|
-
`,
|
|
217
|
-
`,
|
|
218
|
-
`,
|
|
197
|
+
`, r += `**Instructions:**
|
|
198
|
+
`, r += `1. You are a helpful AI data analyst that can answer questions about the table data, perform statistical analysis, make predictions, identify trends, AND engage in normal conversation.
|
|
199
|
+
`, r += `2. For data questions (e.g., "how many rows?", "what's the average?"), answer based on the data provided above.
|
|
200
|
+
`, r += `3. For statistical analysis requests (e.g., "calculate descriptive statistics", "show me mean/median/std dev"), compute and present the statistics clearly.
|
|
201
|
+
`, r += `4. For anomaly detection requests (e.g., "detect anomalies", "find outliers"), identify unusual data points and explain why they're anomalous.
|
|
202
|
+
`, r += `5. For clustering requests (e.g., "perform clustering", "group similar data"), identify natural groupings in the data and describe their characteristics.
|
|
203
|
+
`, r += `6. For correlation analysis requests (e.g., "show correlations", "what variables are related"), analyze relationships between variables and explain the strength and direction of correlations.
|
|
204
|
+
`, r += `7. For predictive questions (e.g., "predict future trends", "what will happen next?", "forecast X"), analyze patterns in the data and make reasonable predictions based on trends, correlations, and statistical patterns you observe.
|
|
205
|
+
`, r += `8. For analytical questions (e.g., "what insights?", "any patterns?", "recommendations?"), provide insights, trends, correlations, and actionable recommendations based on the data.
|
|
206
|
+
`, r += `9. For conversational questions (e.g., "hi", "hello", "what can you do?"), respond naturally and mention your capabilities.
|
|
207
|
+
`, r += `10. If a question is completely unrelated to data analysis (e.g., "what's the weather?"), politely explain you can only help with data analysis.
|
|
208
|
+
`, r += `11. Provide clear, concise answers with specific numbers and examples.
|
|
209
|
+
`, r += `12. When making predictions or identifying trends, explain your reasoning and mention the confidence level.
|
|
210
|
+
`, r += `13. If the answer is based on sampled data, mention that it's an approximation.
|
|
211
|
+
`, r += `14. Format your response as JSON with the following structure:
|
|
212
|
+
`, r += `{
|
|
213
|
+
`, r += ` "answer": "Your answer text here",
|
|
214
|
+
`, r += ` "confidence": 0.0-1.0,
|
|
215
|
+
`, r += ` "cannotAnswer": false,
|
|
216
|
+
`, r += ` "isApproximate": ${i},
|
|
217
|
+
`, r += ` "supportingData": { "key": "value" } // optional
|
|
218
|
+
`, r += `}
|
|
219
219
|
|
|
220
|
-
`,
|
|
221
|
-
`,
|
|
222
|
-
`,
|
|
223
|
-
`,
|
|
224
|
-
`,
|
|
225
|
-
`,
|
|
226
|
-
`,
|
|
227
|
-
`,
|
|
228
|
-
`,
|
|
229
|
-
`,
|
|
230
|
-
`,
|
|
220
|
+
`, r += `Examples:
|
|
221
|
+
`, r += `- Question: "hi" → Answer: "Hello! I'm your AI data analyst. I can perform statistical analysis, detect anomalies, cluster data, analyze correlations, make predictions, and answer questions about this dataset."
|
|
222
|
+
`, r += `- Question: "how many rows?" → Answer: "There are ${a || n.length} rows in the dataset."
|
|
223
|
+
`, r += `- Question: "calculate descriptive statistics" → Answer: "Descriptive Statistics:\\n- Mean: 45.2\\n- Median: 42.0\\n- Std Dev: 12.5\\n- Min: 10\\n- Max: 95\\n- 25th Percentile: 35\\n- 75th Percentile: 58" (with confidence: 0.95)
|
|
224
|
+
`, r += `- Question: "detect anomalies" → Answer: "I found 3 anomalies in the dataset:\\n1. Row 15: Value 250 is 3.5 standard deviations above the mean\\n2. Row 42: Value -10 is unusually low\\n3. Row 88: Value 300 is an extreme outlier" (with confidence: 0.85)
|
|
225
|
+
`, r += `- Question: "perform clustering" → Answer: "I identified 3 natural clusters in the data:\\n- Cluster 1 (40%): Low values, avg 25\\n- Cluster 2 (35%): Medium values, avg 50\\n- Cluster 3 (25%): High values, avg 85" (with confidence: 0.8)
|
|
226
|
+
`, r += `- Question: "show correlation analysis" → Answer: "Correlation Analysis:\\n- Price & Quantity: -0.65 (strong negative)\\n- Revenue & Price: 0.82 (strong positive)\\n- Quantity & Revenue: 0.45 (moderate positive)" (with confidence: 0.9)
|
|
227
|
+
`, r += `- Question: "predict future sales" → Answer: "Based on the trend in the data, sales are increasing by 15% monthly. If this continues, next month's sales could reach approximately $50,000." (with confidence: 0.7)
|
|
228
|
+
`, r += `- Question: "what insights can you give?" → Answer: "Key insights: 1) Sales peak on weekends, 2) Product A is the top seller, 3) Customer retention is 85%..."
|
|
229
|
+
`, r += `- Question: "what's the weather?" → Answer: "I cannot answer this question as it's not related to the dataset. I can only help with questions about this data."
|
|
230
|
+
`, r;
|
|
231
231
|
}
|
|
232
232
|
/**
|
|
233
233
|
* Call LLM API
|
|
234
234
|
*/
|
|
235
235
|
async callLLM(e) {
|
|
236
|
-
const { provider:
|
|
237
|
-
if (!
|
|
236
|
+
const { provider: t, apiKey: n, baseUrl: o, model: a, maxTokens: i, temperature: r } = this.config;
|
|
237
|
+
if (!n && t !== "custom")
|
|
238
238
|
return this.fallbackResponse(e);
|
|
239
|
-
if (
|
|
240
|
-
return this.callOpenAI(e,
|
|
241
|
-
if (
|
|
242
|
-
return this.callAnthropic(e,
|
|
243
|
-
if (
|
|
244
|
-
return this.callCustomAPI(e,
|
|
245
|
-
throw new Error(`Unsupported provider: ${
|
|
239
|
+
if (t === "openai")
|
|
240
|
+
return this.callOpenAI(e, n, a || "gpt-4-turbo-preview", i, r);
|
|
241
|
+
if (t === "anthropic")
|
|
242
|
+
return this.callAnthropic(e, n, a || "claude-3-5-sonnet-20241022", i, r);
|
|
243
|
+
if (t === "custom" && o)
|
|
244
|
+
return this.callCustomAPI(e, o, n);
|
|
245
|
+
throw new Error(`Unsupported provider: ${t}`);
|
|
246
246
|
}
|
|
247
247
|
/**
|
|
248
248
|
* Fallback response when no API key is available
|
|
249
249
|
*/
|
|
250
250
|
fallbackResponse(e) {
|
|
251
|
-
const
|
|
252
|
-
if (/^(hi|hello|hey|greetings|good morning|good afternoon|good evening)/.test(
|
|
251
|
+
const t = e.match(/\*\*Question:\*\* (.+)/), o = (t ? t[1].trim() : "").toLowerCase();
|
|
252
|
+
if (/^(hi|hello|hey|greetings|good morning|good afternoon|good evening)/.test(o))
|
|
253
253
|
return JSON.stringify({
|
|
254
254
|
answer: "Hello! 👋 I'm your data analysis assistant. I can help you explore and understand this dataset. Try asking questions like 'How many rows are there?', 'What columns do we have?', or 'Show me a summary of the data'. For more advanced analysis, please configure an OpenAI or Anthropic API key in the settings.",
|
|
255
255
|
confidence: 1,
|
|
256
256
|
cannotAnswer: !1,
|
|
257
257
|
isApproximate: !1
|
|
258
258
|
});
|
|
259
|
-
if (/what (can|do) you|help|capabilities|features/.test(
|
|
259
|
+
if (/what (can|do) you|help|capabilities|features/.test(o))
|
|
260
260
|
return JSON.stringify({
|
|
261
261
|
answer: `I can help you analyze tabular data! You can ask me questions like:
|
|
262
262
|
• 'How many rows/columns are there?'
|
|
@@ -279,60 +279,60 @@ Please add your API key in the AI Chatbot Configuration section for advanced fea
|
|
|
279
279
|
cannotAnswer: !1,
|
|
280
280
|
isApproximate: !1
|
|
281
281
|
});
|
|
282
|
-
const
|
|
283
|
-
if (/how many (rows|records|entries|items)/.test(
|
|
282
|
+
const a = e.match(/\*\*Sample Data\*\* \((\d+) rows/), i = e.match(/out of (\d+) total/), r = e.match(/Columns:\n((?:- .+\n)+)/), c = a ? parseInt(a[1]) : 0, l = i ? parseInt(i[1]) : c;
|
|
283
|
+
if (/how many (rows|records|entries|items)/.test(o))
|
|
284
284
|
return JSON.stringify({
|
|
285
|
-
answer: `There are ${
|
|
285
|
+
answer: `There are ${l} rows in the dataset.`,
|
|
286
286
|
confidence: 1,
|
|
287
287
|
cannotAnswer: !1,
|
|
288
288
|
isApproximate: !1
|
|
289
289
|
});
|
|
290
|
-
if (/how many columns|what columns|column names|list columns/.test(
|
|
291
|
-
const
|
|
290
|
+
if (/how many columns|what columns|column names|list columns/.test(o) && r) {
|
|
291
|
+
const u = r[1].trim().split(`
|
|
292
292
|
`).map((m) => m.replace(/^- /, "").split(" (")[0]);
|
|
293
293
|
return JSON.stringify({
|
|
294
|
-
answer: `The dataset has ${
|
|
294
|
+
answer: `The dataset has ${u.length} columns: ${u.join(", ")}.`,
|
|
295
295
|
confidence: 1,
|
|
296
296
|
cannotAnswer: !1,
|
|
297
297
|
isApproximate: !1
|
|
298
298
|
});
|
|
299
299
|
}
|
|
300
|
-
if (/summary|overview|describe|what.*data|tell me about/.test(
|
|
301
|
-
const
|
|
300
|
+
if (/summary|overview|describe|what.*data|tell me about/.test(o) && r) {
|
|
301
|
+
const u = r[1].trim().split(`
|
|
302
302
|
`).map((m) => m.replace(/^- /, "").split(" (")[0]);
|
|
303
303
|
return JSON.stringify({
|
|
304
|
-
answer: `This dataset contains ${
|
|
304
|
+
answer: `This dataset contains ${l} rows and ${u.length} columns. The columns are: ${u.join(", ")}. For detailed analysis and insights, please configure an OpenAI or Anthropic API key.`,
|
|
305
305
|
confidence: 0.8,
|
|
306
306
|
cannotAnswer: !1,
|
|
307
307
|
isApproximate: !1
|
|
308
308
|
});
|
|
309
309
|
}
|
|
310
|
-
return /descriptive statistics|calculate statistics|mean|median|std dev|standard deviation|percentile/.test(
|
|
310
|
+
return /descriptive statistics|calculate statistics|mean|median|std dev|standard deviation|percentile/.test(o) ? JSON.stringify({
|
|
311
311
|
answer: "I can calculate descriptive statistics with an OpenAI or Anthropic API key! I'll provide mean, median, standard deviation, min, max, and percentiles for all numeric columns. Please add your API key in the 'AI Chatbot Configuration' section above.",
|
|
312
312
|
confidence: 0.3,
|
|
313
313
|
cannotAnswer: !0,
|
|
314
314
|
reason: "Statistical analysis requires AI. Please configure an API key."
|
|
315
|
-
}) : /anomaly|anomalies|outlier|outliers|detect anomal|find outlier/.test(
|
|
315
|
+
}) : /anomaly|anomalies|outlier|outliers|detect anomal|find outlier/.test(o) ? JSON.stringify({
|
|
316
316
|
answer: "I can detect anomalies and outliers with an OpenAI or Anthropic API key! I'll identify unusual data points and explain why they're anomalous. Please add your API key in the 'AI Chatbot Configuration' section above.",
|
|
317
317
|
confidence: 0.3,
|
|
318
318
|
cannotAnswer: !0,
|
|
319
319
|
reason: "Anomaly detection requires AI. Please configure an API key."
|
|
320
|
-
}) : /cluster|clustering|group|grouping|segment|segmentation/.test(
|
|
320
|
+
}) : /cluster|clustering|group|grouping|segment|segmentation/.test(o) ? JSON.stringify({
|
|
321
321
|
answer: "I can perform clustering analysis with an OpenAI or Anthropic API key! I'll identify natural groupings in your data and describe their characteristics. Please add your API key in the 'AI Chatbot Configuration' section above.",
|
|
322
322
|
confidence: 0.3,
|
|
323
323
|
cannotAnswer: !0,
|
|
324
324
|
reason: "Clustering analysis requires AI. Please configure an API key."
|
|
325
|
-
}) : /correlation|correlate|relationship|relate|association/.test(
|
|
325
|
+
}) : /correlation|correlate|relationship|relate|association/.test(o) ? JSON.stringify({
|
|
326
326
|
answer: "I can analyze correlations between variables with an OpenAI or Anthropic API key! I'll show you the strength and direction of relationships between different columns. Please add your API key in the 'AI Chatbot Configuration' section above.",
|
|
327
327
|
confidence: 0.3,
|
|
328
328
|
cannotAnswer: !0,
|
|
329
329
|
reason: "Correlation analysis requires AI. Please configure an API key."
|
|
330
|
-
}) : /predict|forecast|future|trend|next|will be|gonna be|going to be/.test(
|
|
330
|
+
}) : /predict|forecast|future|trend|next|will be|gonna be|going to be/.test(o) ? JSON.stringify({
|
|
331
331
|
answer: "I'd love to help you make predictions based on this data! However, I need an OpenAI or Anthropic API key to analyze patterns, identify trends, and make accurate forecasts. Please add your API key in the 'AI Chatbot Configuration' section above, and I'll be able to provide detailed predictions with confidence scores.",
|
|
332
332
|
confidence: 0.3,
|
|
333
333
|
cannotAnswer: !0,
|
|
334
334
|
reason: "Predictions require AI analysis. Please configure an API key for advanced features."
|
|
335
|
-
}) : /insight|pattern|analysis|analyze|recommendation/.test(
|
|
335
|
+
}) : /insight|pattern|analysis|analyze|recommendation/.test(o) ? JSON.stringify({
|
|
336
336
|
answer: "I can provide deep insights and analysis with an OpenAI or Anthropic API key! I'll be able to identify patterns, trends, and give you actionable recommendations. Please add your API key in the 'AI Chatbot Configuration' section above.",
|
|
337
337
|
confidence: 0.3,
|
|
338
338
|
cannotAnswer: !0,
|
|
@@ -347,82 +347,82 @@ Please add your API key in the AI Chatbot Configuration section for advanced fea
|
|
|
347
347
|
/**
|
|
348
348
|
* Call OpenAI API
|
|
349
349
|
*/
|
|
350
|
-
async callOpenAI(e,
|
|
351
|
-
var
|
|
352
|
-
const
|
|
350
|
+
async callOpenAI(e, t, n, o, a) {
|
|
351
|
+
var c, l;
|
|
352
|
+
const i = await fetch("https://api.openai.com/v1/chat/completions", {
|
|
353
353
|
method: "POST",
|
|
354
354
|
headers: {
|
|
355
355
|
"Content-Type": "application/json",
|
|
356
|
-
Authorization: `Bearer ${
|
|
356
|
+
Authorization: `Bearer ${t}`
|
|
357
357
|
},
|
|
358
358
|
body: JSON.stringify({
|
|
359
|
-
model:
|
|
359
|
+
model: n,
|
|
360
360
|
messages: [{ role: "user", content: e }],
|
|
361
|
-
max_tokens:
|
|
362
|
-
temperature:
|
|
361
|
+
max_tokens: o,
|
|
362
|
+
temperature: a,
|
|
363
363
|
response_format: { type: "json_object" }
|
|
364
364
|
})
|
|
365
365
|
});
|
|
366
|
-
if (!
|
|
367
|
-
throw new Error(`OpenAI API error: ${
|
|
368
|
-
return ((
|
|
366
|
+
if (!i.ok)
|
|
367
|
+
throw new Error(`OpenAI API error: ${i.statusText}`);
|
|
368
|
+
return ((l = (c = (await i.json()).choices[0]) == null ? void 0 : c.message) == null ? void 0 : l.content) || "";
|
|
369
369
|
}
|
|
370
370
|
/**
|
|
371
371
|
* Call Anthropic API
|
|
372
372
|
*/
|
|
373
|
-
async callAnthropic(e,
|
|
374
|
-
var
|
|
375
|
-
const
|
|
373
|
+
async callAnthropic(e, t, n, o, a) {
|
|
374
|
+
var c;
|
|
375
|
+
const i = await fetch("https://api.anthropic.com/v1/messages", {
|
|
376
376
|
method: "POST",
|
|
377
377
|
headers: {
|
|
378
378
|
"Content-Type": "application/json",
|
|
379
|
-
"x-api-key":
|
|
379
|
+
"x-api-key": t,
|
|
380
380
|
"anthropic-version": "2023-06-01"
|
|
381
381
|
},
|
|
382
382
|
body: JSON.stringify({
|
|
383
|
-
model:
|
|
384
|
-
max_tokens:
|
|
385
|
-
temperature:
|
|
383
|
+
model: n,
|
|
384
|
+
max_tokens: o,
|
|
385
|
+
temperature: a,
|
|
386
386
|
messages: [{ role: "user", content: e }]
|
|
387
387
|
})
|
|
388
388
|
});
|
|
389
|
-
if (!
|
|
390
|
-
throw new Error(`Anthropic API error: ${
|
|
391
|
-
return ((
|
|
389
|
+
if (!i.ok)
|
|
390
|
+
throw new Error(`Anthropic API error: ${i.statusText}`);
|
|
391
|
+
return ((c = (await i.json()).content[0]) == null ? void 0 : c.text) || "";
|
|
392
392
|
}
|
|
393
393
|
/**
|
|
394
394
|
* Call custom API
|
|
395
395
|
*/
|
|
396
|
-
async callCustomAPI(e,
|
|
397
|
-
const
|
|
396
|
+
async callCustomAPI(e, t, n) {
|
|
397
|
+
const o = {
|
|
398
398
|
"Content-Type": "application/json"
|
|
399
399
|
};
|
|
400
|
-
|
|
401
|
-
const
|
|
400
|
+
n && (o.Authorization = `Bearer ${n}`);
|
|
401
|
+
const a = await fetch(t, {
|
|
402
402
|
method: "POST",
|
|
403
|
-
headers:
|
|
403
|
+
headers: o,
|
|
404
404
|
body: JSON.stringify({ prompt: e })
|
|
405
405
|
});
|
|
406
|
-
if (!
|
|
407
|
-
throw new Error(`Custom API error: ${
|
|
408
|
-
const
|
|
409
|
-
return
|
|
406
|
+
if (!a.ok)
|
|
407
|
+
throw new Error(`Custom API error: ${a.statusText}`);
|
|
408
|
+
const i = await a.json();
|
|
409
|
+
return i.response || i.answer || JSON.stringify(i);
|
|
410
410
|
}
|
|
411
411
|
/**
|
|
412
412
|
* Parse LLM response
|
|
413
413
|
*/
|
|
414
|
-
parseResponse(e,
|
|
414
|
+
parseResponse(e, t, n) {
|
|
415
415
|
try {
|
|
416
|
-
const
|
|
416
|
+
const o = JSON.parse(e);
|
|
417
417
|
return {
|
|
418
418
|
questionId: this.generateId(),
|
|
419
|
-
text:
|
|
419
|
+
text: o.answer || o.text || e,
|
|
420
420
|
timestamp: /* @__PURE__ */ new Date(),
|
|
421
|
-
confidence:
|
|
422
|
-
cannotAnswer:
|
|
423
|
-
isApproximate:
|
|
424
|
-
supportingData:
|
|
425
|
-
reason:
|
|
421
|
+
confidence: o.confidence || 0.8,
|
|
422
|
+
cannotAnswer: o.cannotAnswer || !1,
|
|
423
|
+
isApproximate: o.isApproximate !== void 0 ? o.isApproximate : n,
|
|
424
|
+
supportingData: o.supportingData,
|
|
425
|
+
reason: o.reason
|
|
426
426
|
};
|
|
427
427
|
} catch {
|
|
428
428
|
return {
|
|
@@ -430,7 +430,7 @@ Please add your API key in the AI Chatbot Configuration section for advanced fea
|
|
|
430
430
|
text: e,
|
|
431
431
|
timestamp: /* @__PURE__ */ new Date(),
|
|
432
432
|
confidence: 0.7,
|
|
433
|
-
isApproximate:
|
|
433
|
+
isApproximate: n
|
|
434
434
|
};
|
|
435
435
|
}
|
|
436
436
|
}
|
|
@@ -441,239 +441,239 @@ Please add your API key in the AI Chatbot Configuration section for advanced fea
|
|
|
441
441
|
return `qa_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
442
442
|
}
|
|
443
443
|
}
|
|
444
|
-
function
|
|
444
|
+
function Ae(s = {}) {
|
|
445
445
|
const {
|
|
446
446
|
selector: e = "table",
|
|
447
|
-
includeHeaders:
|
|
448
|
-
maxRows:
|
|
449
|
-
inferTypes:
|
|
450
|
-
skipEmptyRows:
|
|
451
|
-
} =
|
|
452
|
-
if (!
|
|
447
|
+
includeHeaders: t = !0,
|
|
448
|
+
maxRows: n,
|
|
449
|
+
inferTypes: o = !0,
|
|
450
|
+
skipEmptyRows: a = !0
|
|
451
|
+
} = s, i = document.querySelector(e);
|
|
452
|
+
if (!i || i.tagName !== "TABLE")
|
|
453
453
|
return console.warn(`No table found with selector: ${e}`), null;
|
|
454
|
-
const
|
|
455
|
-
if (
|
|
454
|
+
const c = Array.from(i.rows);
|
|
455
|
+
if (c.length === 0)
|
|
456
456
|
return null;
|
|
457
|
-
let
|
|
458
|
-
if (
|
|
459
|
-
const
|
|
460
|
-
|
|
461
|
-
var
|
|
462
|
-
return ((
|
|
463
|
-
}),
|
|
457
|
+
let l = [], u = 0;
|
|
458
|
+
if (t && c[0]) {
|
|
459
|
+
const h = c[0];
|
|
460
|
+
l = Array.from(h.cells).map((p, w) => {
|
|
461
|
+
var S;
|
|
462
|
+
return ((S = p.textContent) == null ? void 0 : S.trim()) || "" || `Column${w + 1}`;
|
|
463
|
+
}), u = 1;
|
|
464
464
|
} else {
|
|
465
|
-
const
|
|
466
|
-
|
|
467
|
-
}
|
|
468
|
-
const m = [], d =
|
|
469
|
-
for (const
|
|
470
|
-
const
|
|
471
|
-
if (
|
|
472
|
-
var
|
|
473
|
-
return !((
|
|
465
|
+
const h = c[0];
|
|
466
|
+
l = Array.from(h.cells).map((p, w) => `Column${w + 1}`);
|
|
467
|
+
}
|
|
468
|
+
const m = [], d = n ? c.slice(u, u + n) : c.slice(u);
|
|
469
|
+
for (const h of d) {
|
|
470
|
+
const p = Array.from(h.cells);
|
|
471
|
+
if (a && p.every((g) => {
|
|
472
|
+
var S;
|
|
473
|
+
return !((S = g.textContent) != null && S.trim());
|
|
474
474
|
}))
|
|
475
475
|
continue;
|
|
476
|
-
const
|
|
477
|
-
|
|
478
|
-
var
|
|
479
|
-
const
|
|
480
|
-
let
|
|
481
|
-
if (
|
|
482
|
-
const
|
|
483
|
-
!isNaN(
|
|
476
|
+
const w = {};
|
|
477
|
+
p.forEach((g, S) => {
|
|
478
|
+
var E;
|
|
479
|
+
const O = l[S] || `Column${S + 1}`;
|
|
480
|
+
let q = ((E = g.textContent) == null ? void 0 : E.trim()) || "";
|
|
481
|
+
if (o && q) {
|
|
482
|
+
const z = parseFloat(q);
|
|
483
|
+
!isNaN(z) && q === z.toString() && (q = z);
|
|
484
484
|
}
|
|
485
|
-
|
|
486
|
-
}), m.push(
|
|
485
|
+
w[O] = q;
|
|
486
|
+
}), m.push(w);
|
|
487
487
|
}
|
|
488
488
|
return {
|
|
489
|
-
schema:
|
|
489
|
+
schema: o && m.length > 0 ? _(m, "Extracted Table") : Ne(l, m.length),
|
|
490
490
|
data: m,
|
|
491
491
|
source: "dom",
|
|
492
492
|
metadata: {
|
|
493
493
|
selector: e,
|
|
494
494
|
rowCount: m.length,
|
|
495
|
-
columnCount:
|
|
495
|
+
columnCount: l.length,
|
|
496
496
|
extractedAt: /* @__PURE__ */ new Date()
|
|
497
497
|
}
|
|
498
498
|
};
|
|
499
499
|
}
|
|
500
|
-
function
|
|
501
|
-
const { maxRows:
|
|
502
|
-
let
|
|
503
|
-
return e && e.length > 0 ?
|
|
500
|
+
function Se(s, e, t = {}) {
|
|
501
|
+
const { maxRows: n, inferTypes: o = !0 } = t, a = n ? s.slice(0, n) : s;
|
|
502
|
+
let i;
|
|
503
|
+
return e && e.length > 0 ? i = {
|
|
504
504
|
name: "Vue Data Grid",
|
|
505
|
-
columns: e.map((
|
|
506
|
-
name:
|
|
507
|
-
type:
|
|
505
|
+
columns: e.map((r) => ({
|
|
506
|
+
name: r.field,
|
|
507
|
+
type: o && a.length > 0 ? te(a, r.field) : "string",
|
|
508
508
|
nullable: !0
|
|
509
509
|
})),
|
|
510
|
-
rowCount:
|
|
511
|
-
} :
|
|
512
|
-
schema:
|
|
513
|
-
data:
|
|
510
|
+
rowCount: a.length
|
|
511
|
+
} : a.length > 0 ? i = _(a, "Vue Data Grid") : i = { name: "Vue Data Grid", columns: [], rowCount: 0 }, {
|
|
512
|
+
schema: i,
|
|
513
|
+
data: a,
|
|
514
514
|
source: "vue",
|
|
515
515
|
metadata: {
|
|
516
|
-
rowCount:
|
|
517
|
-
columnCount:
|
|
516
|
+
rowCount: a.length,
|
|
517
|
+
columnCount: i.columns.length,
|
|
518
518
|
extractedAt: /* @__PURE__ */ new Date()
|
|
519
519
|
}
|
|
520
520
|
};
|
|
521
521
|
}
|
|
522
|
-
function
|
|
522
|
+
function Ne(s, e = 0) {
|
|
523
523
|
return {
|
|
524
524
|
name: "Extracted Table",
|
|
525
|
-
columns:
|
|
526
|
-
name:
|
|
525
|
+
columns: s.map((t) => ({
|
|
526
|
+
name: t,
|
|
527
527
|
type: "string",
|
|
528
528
|
nullable: !0
|
|
529
529
|
})),
|
|
530
530
|
rowCount: e
|
|
531
531
|
};
|
|
532
532
|
}
|
|
533
|
-
function
|
|
533
|
+
function ke(s) {
|
|
534
534
|
const e = {};
|
|
535
|
-
|
|
536
|
-
e[
|
|
535
|
+
s.variable && s.variable.forEach((a) => {
|
|
536
|
+
e[a.key] = a.value;
|
|
537
537
|
});
|
|
538
|
-
const
|
|
539
|
-
function
|
|
540
|
-
|
|
541
|
-
|
|
538
|
+
const t = s.auth ? se(s.auth) : void 0, n = [];
|
|
539
|
+
function o(a, i = "") {
|
|
540
|
+
a.forEach((r) => {
|
|
541
|
+
r.item ? o(r.item, i ? `${i}/${r.name}` : r.name) : r.request && n.push($e(r, t));
|
|
542
542
|
});
|
|
543
543
|
}
|
|
544
|
-
return
|
|
545
|
-
name:
|
|
546
|
-
description:
|
|
547
|
-
endpoints:
|
|
544
|
+
return o(s.item), {
|
|
545
|
+
name: s.info.name,
|
|
546
|
+
description: s.info.description,
|
|
547
|
+
endpoints: n,
|
|
548
548
|
variables: e,
|
|
549
|
-
auth:
|
|
549
|
+
auth: t
|
|
550
550
|
};
|
|
551
551
|
}
|
|
552
|
-
function
|
|
553
|
-
const
|
|
554
|
-
|
|
555
|
-
|
|
552
|
+
function $e(s, e) {
|
|
553
|
+
const t = s.request, n = {};
|
|
554
|
+
t.header && t.header.forEach((i) => {
|
|
555
|
+
n[i.key] = i.value;
|
|
556
556
|
});
|
|
557
|
-
const
|
|
558
|
-
|
|
559
|
-
|
|
557
|
+
const o = {};
|
|
558
|
+
t.url.query && t.url.query.forEach((i) => {
|
|
559
|
+
o[i.key] = i.value;
|
|
560
560
|
});
|
|
561
|
-
const
|
|
561
|
+
const a = t.auth ? se(t.auth) : e;
|
|
562
562
|
return {
|
|
563
|
-
name:
|
|
564
|
-
method:
|
|
565
|
-
url:
|
|
566
|
-
description:
|
|
567
|
-
headers:
|
|
568
|
-
queryParams:
|
|
569
|
-
auth:
|
|
563
|
+
name: s.name,
|
|
564
|
+
method: t.method,
|
|
565
|
+
url: t.url.raw,
|
|
566
|
+
description: t.description,
|
|
567
|
+
headers: n,
|
|
568
|
+
queryParams: o,
|
|
569
|
+
auth: a
|
|
570
570
|
};
|
|
571
571
|
}
|
|
572
|
-
function
|
|
572
|
+
function se(s) {
|
|
573
573
|
const e = {};
|
|
574
|
-
return
|
|
575
|
-
e[
|
|
576
|
-
}) :
|
|
577
|
-
e[
|
|
578
|
-
}) :
|
|
579
|
-
e[
|
|
574
|
+
return s.apikey ? s.apikey.forEach((t) => {
|
|
575
|
+
e[t.key] = t.value;
|
|
576
|
+
}) : s.bearer ? s.bearer.forEach((t) => {
|
|
577
|
+
e[t.key] = t.value;
|
|
578
|
+
}) : s.basic && s.basic.forEach((t) => {
|
|
579
|
+
e[t.key] = t.value;
|
|
580
580
|
}), {
|
|
581
|
-
type:
|
|
581
|
+
type: s.type,
|
|
582
582
|
credentials: e
|
|
583
583
|
};
|
|
584
584
|
}
|
|
585
|
-
function
|
|
586
|
-
let
|
|
587
|
-
return Object.keys(e).forEach((
|
|
588
|
-
const
|
|
589
|
-
|
|
590
|
-
}),
|
|
585
|
+
function D(s, e) {
|
|
586
|
+
let t = s;
|
|
587
|
+
return Object.keys(e).forEach((n) => {
|
|
588
|
+
const o = new RegExp(`{{${n}}}`, "g");
|
|
589
|
+
t = t.replace(o, e[n]);
|
|
590
|
+
}), t;
|
|
591
591
|
}
|
|
592
|
-
async function
|
|
593
|
-
const { endpoint: e, variables:
|
|
592
|
+
async function oe(s) {
|
|
593
|
+
const { endpoint: e, variables: t = {}, additionalHeaders: n = {}, additionalParams: o = {} } = s;
|
|
594
594
|
try {
|
|
595
|
-
let
|
|
596
|
-
const
|
|
597
|
-
|
|
598
|
-
const
|
|
595
|
+
let a = D(e.url, t);
|
|
596
|
+
const i = { ...e.queryParams, ...t, ...o }, r = Object.keys(i).filter((d) => i[d] !== void 0 && i[d] !== "").map((d) => `${encodeURIComponent(d)}=${encodeURIComponent(D(String(i[d]), t))}`).join("&");
|
|
597
|
+
r && (a = a.includes("?") ? `${a}&${r}` : `${a}?${r}`);
|
|
598
|
+
const c = {
|
|
599
599
|
"Content-Type": "application/json",
|
|
600
600
|
...e.headers,
|
|
601
|
-
...
|
|
601
|
+
...n
|
|
602
602
|
};
|
|
603
|
-
if (Object.keys(
|
|
604
|
-
|
|
603
|
+
if (Object.keys(c).forEach((d) => {
|
|
604
|
+
c[d] = D(c[d], t);
|
|
605
605
|
}), e.auth) {
|
|
606
606
|
if (e.auth.type === "apikey") {
|
|
607
|
-
const d = e.auth.credentials.key || "access_key",
|
|
608
|
-
e.auth.credentials.in === "header" && (
|
|
607
|
+
const d = e.auth.credentials.key || "access_key", f = D(e.auth.credentials.value || "", t);
|
|
608
|
+
e.auth.credentials.in === "header" && (c[d] = f);
|
|
609
609
|
} else if (e.auth.type === "bearer") {
|
|
610
|
-
const d =
|
|
611
|
-
|
|
610
|
+
const d = D(e.auth.credentials.token || "", t);
|
|
611
|
+
c.Authorization = `Bearer ${d}`;
|
|
612
612
|
} else if (e.auth.type === "basic") {
|
|
613
|
-
const d =
|
|
614
|
-
|
|
613
|
+
const d = D(e.auth.credentials.username || "", t), f = D(e.auth.credentials.password || "", t), h = btoa(`${d}:${f}`);
|
|
614
|
+
c.Authorization = `Basic ${h}`;
|
|
615
615
|
}
|
|
616
616
|
}
|
|
617
|
-
const
|
|
617
|
+
const l = await fetch(a, {
|
|
618
618
|
method: e.method,
|
|
619
|
-
headers:
|
|
620
|
-
}),
|
|
621
|
-
return
|
|
622
|
-
f
|
|
623
|
-
}),
|
|
619
|
+
headers: c
|
|
620
|
+
}), u = {};
|
|
621
|
+
return l.headers.forEach((d, f) => {
|
|
622
|
+
u[f] = d;
|
|
623
|
+
}), l.ok ? {
|
|
624
624
|
success: !0,
|
|
625
|
-
data: await
|
|
626
|
-
statusCode:
|
|
627
|
-
headers:
|
|
625
|
+
data: await l.json(),
|
|
626
|
+
statusCode: l.status,
|
|
627
|
+
headers: u
|
|
628
628
|
} : {
|
|
629
629
|
success: !1,
|
|
630
|
-
error: `HTTP ${
|
|
631
|
-
statusCode:
|
|
632
|
-
headers:
|
|
630
|
+
error: `HTTP ${l.status}: ${l.statusText}`,
|
|
631
|
+
statusCode: l.status,
|
|
632
|
+
headers: u
|
|
633
633
|
};
|
|
634
|
-
} catch (
|
|
634
|
+
} catch (a) {
|
|
635
635
|
return {
|
|
636
636
|
success: !1,
|
|
637
|
-
error:
|
|
637
|
+
error: a.message || "Unknown error occurred"
|
|
638
638
|
};
|
|
639
639
|
}
|
|
640
640
|
}
|
|
641
|
-
async function
|
|
642
|
-
const
|
|
643
|
-
for (const
|
|
644
|
-
const
|
|
645
|
-
|
|
641
|
+
async function dn(s, e = {}) {
|
|
642
|
+
const t = [];
|
|
643
|
+
for (const n of s) {
|
|
644
|
+
const o = await oe({ endpoint: n, variables: e });
|
|
645
|
+
t.push(o);
|
|
646
646
|
}
|
|
647
|
-
return
|
|
647
|
+
return t;
|
|
648
648
|
}
|
|
649
|
-
function
|
|
650
|
-
if (!
|
|
649
|
+
function Ie(s) {
|
|
650
|
+
if (!s.success || !s.data)
|
|
651
651
|
return [];
|
|
652
|
-
const e =
|
|
652
|
+
const e = s.data;
|
|
653
653
|
return Array.isArray(e) ? e : e.data && Array.isArray(e.data) ? e.data : e.results && Array.isArray(e.results) ? e.results : e.items && Array.isArray(e.items) ? e.items : typeof e == "object" ? [e] : [];
|
|
654
654
|
}
|
|
655
|
-
class
|
|
656
|
-
constructor(e,
|
|
655
|
+
class Me {
|
|
656
|
+
constructor(e, t) {
|
|
657
657
|
this.config = {
|
|
658
658
|
timeout: 3e4,
|
|
659
659
|
...e
|
|
660
|
-
},
|
|
660
|
+
}, t && (this.qaEngine = new Z(t));
|
|
661
661
|
}
|
|
662
662
|
/**
|
|
663
663
|
* Initialize or update Q&A engine
|
|
664
664
|
*/
|
|
665
665
|
initializeQA(e) {
|
|
666
|
-
this.qaEngine = new
|
|
666
|
+
this.qaEngine = new Z(e);
|
|
667
667
|
}
|
|
668
668
|
/**
|
|
669
669
|
* Generic API call to TFM endpoint
|
|
670
670
|
*/
|
|
671
671
|
async callTFM(e) {
|
|
672
|
-
const
|
|
672
|
+
const t = Date.now();
|
|
673
673
|
try {
|
|
674
|
-
let
|
|
675
|
-
this.config.useCorsProxy && this.config.corsProxyUrl && (this.config.corsProxyUrl.includes("?") ?
|
|
676
|
-
const
|
|
674
|
+
let n = this.config.baseUrl;
|
|
675
|
+
this.config.useCorsProxy && this.config.corsProxyUrl && (this.config.corsProxyUrl.includes("?") ? n = this.config.corsProxyUrl + encodeURIComponent(n) : n = (this.config.corsProxyUrl.endsWith("/") ? this.config.corsProxyUrl : this.config.corsProxyUrl + "/") + n, console.log("Using CORS proxy for TFM API call:", this.config.corsProxyUrl), console.log("Proxied URL:", n));
|
|
676
|
+
const o = await fetch(n, {
|
|
677
677
|
method: "POST",
|
|
678
678
|
headers: {
|
|
679
679
|
"Content-Type": "application/json",
|
|
@@ -686,26 +686,26 @@ class he {
|
|
|
686
686
|
}),
|
|
687
687
|
signal: AbortSignal.timeout(this.config.timeout || 3e4)
|
|
688
688
|
});
|
|
689
|
-
if (!
|
|
690
|
-
const
|
|
691
|
-
throw new Error(`TFM API error: ${
|
|
689
|
+
if (!o.ok) {
|
|
690
|
+
const r = await o.text();
|
|
691
|
+
throw new Error(`TFM API error: ${o.status} - ${r}`);
|
|
692
692
|
}
|
|
693
|
-
const
|
|
693
|
+
const a = await o.json(), i = Date.now() - t;
|
|
694
694
|
return {
|
|
695
695
|
success: !0,
|
|
696
|
-
result:
|
|
696
|
+
result: a.result || a,
|
|
697
697
|
metadata: {
|
|
698
|
-
processingTime:
|
|
698
|
+
processingTime: i,
|
|
699
699
|
model: this.config.model || "unknown",
|
|
700
|
-
version:
|
|
700
|
+
version: a.version
|
|
701
701
|
}
|
|
702
702
|
};
|
|
703
|
-
} catch (
|
|
703
|
+
} catch (n) {
|
|
704
704
|
return {
|
|
705
705
|
success: !1,
|
|
706
|
-
error:
|
|
706
|
+
error: n instanceof Error ? n.message : "Unknown error",
|
|
707
707
|
metadata: {
|
|
708
|
-
processingTime: Date.now() -
|
|
708
|
+
processingTime: Date.now() - t,
|
|
709
709
|
model: this.config.model || "unknown"
|
|
710
710
|
}
|
|
711
711
|
};
|
|
@@ -715,68 +715,68 @@ class he {
|
|
|
715
715
|
* Perform analysis on tabular data
|
|
716
716
|
*/
|
|
717
717
|
async analyze(e) {
|
|
718
|
-
const
|
|
718
|
+
const t = {
|
|
719
719
|
operation: e.type,
|
|
720
720
|
data: e.data,
|
|
721
721
|
schema: e.schema,
|
|
722
722
|
parameters: e.options
|
|
723
|
-
},
|
|
724
|
-
if (!
|
|
725
|
-
throw new Error(
|
|
726
|
-
return this.parseAnalysisResult(e.type,
|
|
723
|
+
}, n = await this.callTFM(t);
|
|
724
|
+
if (!n.success)
|
|
725
|
+
throw new Error(n.error || "Analysis failed");
|
|
726
|
+
return this.parseAnalysisResult(e.type, n.result, n.metadata);
|
|
727
727
|
}
|
|
728
728
|
/**
|
|
729
729
|
* Parse TFM response into structured AnalysisResult
|
|
730
730
|
*/
|
|
731
|
-
parseAnalysisResult(e,
|
|
732
|
-
const
|
|
731
|
+
parseAnalysisResult(e, t, n) {
|
|
732
|
+
const o = {
|
|
733
733
|
type: e,
|
|
734
734
|
timestamp: /* @__PURE__ */ new Date(),
|
|
735
|
-
summary:
|
|
736
|
-
insights:
|
|
737
|
-
recommendations:
|
|
738
|
-
confidence:
|
|
739
|
-
processingTime:
|
|
735
|
+
summary: t.summary || "",
|
|
736
|
+
insights: t.insights || [],
|
|
737
|
+
recommendations: t.recommendations,
|
|
738
|
+
confidence: t.confidence || 0.8,
|
|
739
|
+
processingTime: n == null ? void 0 : n.processingTime
|
|
740
740
|
};
|
|
741
741
|
switch (e) {
|
|
742
742
|
case "descriptive_stats":
|
|
743
743
|
return {
|
|
744
|
-
...
|
|
745
|
-
descriptiveStats:
|
|
744
|
+
...o,
|
|
745
|
+
descriptiveStats: t.stats || t.descriptiveStats
|
|
746
746
|
};
|
|
747
747
|
case "anomaly_detection":
|
|
748
748
|
return {
|
|
749
|
-
...
|
|
750
|
-
anomalies:
|
|
749
|
+
...o,
|
|
750
|
+
anomalies: t.anomalies || []
|
|
751
751
|
};
|
|
752
752
|
case "segmentation":
|
|
753
753
|
case "clustering":
|
|
754
754
|
return {
|
|
755
|
-
...
|
|
756
|
-
clusters:
|
|
755
|
+
...o,
|
|
756
|
+
clusters: t.clusters || []
|
|
757
757
|
};
|
|
758
758
|
case "prediction":
|
|
759
759
|
return {
|
|
760
|
-
...
|
|
761
|
-
predictions:
|
|
760
|
+
...o,
|
|
761
|
+
predictions: t.predictions || t
|
|
762
762
|
};
|
|
763
763
|
case "correlation":
|
|
764
764
|
return {
|
|
765
|
-
...
|
|
766
|
-
correlations:
|
|
765
|
+
...o,
|
|
766
|
+
correlations: t.correlations || t
|
|
767
767
|
};
|
|
768
768
|
case "summary":
|
|
769
769
|
return {
|
|
770
|
-
...
|
|
771
|
-
aiSummary:
|
|
770
|
+
...o,
|
|
771
|
+
aiSummary: t.summary || t
|
|
772
772
|
};
|
|
773
773
|
case "qa":
|
|
774
774
|
return {
|
|
775
|
-
...
|
|
776
|
-
qaAnswer:
|
|
775
|
+
...o,
|
|
776
|
+
qaAnswer: t.answer || t
|
|
777
777
|
};
|
|
778
778
|
default:
|
|
779
|
-
return
|
|
779
|
+
return o;
|
|
780
780
|
}
|
|
781
781
|
}
|
|
782
782
|
/**
|
|
@@ -790,27 +790,27 @@ class he {
|
|
|
790
790
|
/**
|
|
791
791
|
* Generate AI summary of table data
|
|
792
792
|
*/
|
|
793
|
-
async generateSummary(e,
|
|
794
|
-
const
|
|
793
|
+
async generateSummary(e, t) {
|
|
794
|
+
const n = {
|
|
795
795
|
type: "summary",
|
|
796
796
|
data: e,
|
|
797
|
-
schema:
|
|
798
|
-
},
|
|
799
|
-
if (!
|
|
797
|
+
schema: t
|
|
798
|
+
}, o = await this.analyze(n);
|
|
799
|
+
if (!o.aiSummary)
|
|
800
800
|
throw new Error("Failed to generate summary");
|
|
801
|
-
return
|
|
801
|
+
return o.aiSummary;
|
|
802
802
|
}
|
|
803
803
|
/**
|
|
804
804
|
* Extract table from DOM
|
|
805
805
|
*/
|
|
806
806
|
extractFromDOM(e) {
|
|
807
|
-
return
|
|
807
|
+
return Ae(e);
|
|
808
808
|
}
|
|
809
809
|
/**
|
|
810
810
|
* Normalize Vue data grid data
|
|
811
811
|
*/
|
|
812
|
-
normalizeVueData(e,
|
|
813
|
-
return
|
|
812
|
+
normalizeVueData(e, t, n) {
|
|
813
|
+
return Se(e, t, n);
|
|
814
814
|
}
|
|
815
815
|
/**
|
|
816
816
|
* Update configuration
|
|
@@ -822,8 +822,8 @@ class he {
|
|
|
822
822
|
* Get current configuration (without sensitive data)
|
|
823
823
|
*/
|
|
824
824
|
getConfig() {
|
|
825
|
-
const { apiKey: e, ...
|
|
826
|
-
return
|
|
825
|
+
const { apiKey: e, ...t } = this.config;
|
|
826
|
+
return t;
|
|
827
827
|
}
|
|
828
828
|
// ============================================================================
|
|
829
829
|
// API Integration Methods
|
|
@@ -832,7 +832,7 @@ class he {
|
|
|
832
832
|
* Load Postman collection
|
|
833
833
|
*/
|
|
834
834
|
loadPostmanCollection(e) {
|
|
835
|
-
return this.parsedCollection =
|
|
835
|
+
return this.parsedCollection = ke(e), this.parsedCollection;
|
|
836
836
|
}
|
|
837
837
|
/**
|
|
838
838
|
* Get loaded collection
|
|
@@ -850,20 +850,20 @@ class he {
|
|
|
850
850
|
/**
|
|
851
851
|
* Execute API request and get data
|
|
852
852
|
*/
|
|
853
|
-
async fetchDataFromAPI(e,
|
|
853
|
+
async fetchDataFromAPI(e, t) {
|
|
854
854
|
if (!this.parsedCollection)
|
|
855
855
|
throw new Error("No Postman collection loaded. Call loadPostmanCollection() first.");
|
|
856
|
-
const
|
|
857
|
-
if (!
|
|
856
|
+
const n = this.parsedCollection.endpoints.find((c) => c.name === e);
|
|
857
|
+
if (!n)
|
|
858
858
|
throw new Error(`Endpoint "${e}" not found in collection.`);
|
|
859
|
-
const
|
|
859
|
+
const o = {
|
|
860
860
|
...this.parsedCollection.variables,
|
|
861
|
-
...
|
|
862
|
-
},
|
|
863
|
-
if (!
|
|
864
|
-
throw new Error(`API request failed: ${
|
|
865
|
-
const
|
|
866
|
-
return { data:
|
|
861
|
+
...t
|
|
862
|
+
}, a = await oe({ endpoint: n, variables: o });
|
|
863
|
+
if (!a.success)
|
|
864
|
+
throw new Error(`API request failed: ${a.error}`);
|
|
865
|
+
const i = Ie(a), r = _(i);
|
|
866
|
+
return { data: i, schema: r };
|
|
867
867
|
}
|
|
868
868
|
/**
|
|
869
869
|
* Query API data with natural language
|
|
@@ -871,19 +871,19 @@ class he {
|
|
|
871
871
|
async queryAPI(e) {
|
|
872
872
|
if (!this.qaEngine)
|
|
873
873
|
throw new Error("Q&A engine not initialized. Provide qaConfig in constructor or call initializeQA().");
|
|
874
|
-
const
|
|
874
|
+
const t = Date.now(), { data: n, schema: o } = await this.fetchDataFromAPI(
|
|
875
875
|
e.dataSource.endpoint || "",
|
|
876
876
|
e.variables
|
|
877
|
-
),
|
|
877
|
+
), a = {
|
|
878
878
|
question: e.question,
|
|
879
|
-
schema:
|
|
880
|
-
data:
|
|
881
|
-
},
|
|
879
|
+
schema: o,
|
|
880
|
+
data: n
|
|
881
|
+
}, i = await this.qaEngine.answerQuestion(a), r = Date.now() - t;
|
|
882
882
|
return {
|
|
883
|
-
answer:
|
|
884
|
-
apiResponse:
|
|
883
|
+
answer: i.answer,
|
|
884
|
+
apiResponse: n,
|
|
885
885
|
endpoint: e.dataSource.endpoint,
|
|
886
|
-
executionTime:
|
|
886
|
+
executionTime: r
|
|
887
887
|
};
|
|
888
888
|
}
|
|
889
889
|
/**
|
|
@@ -897,206 +897,206 @@ class he {
|
|
|
897
897
|
})) : [];
|
|
898
898
|
}
|
|
899
899
|
}
|
|
900
|
-
function
|
|
901
|
-
const e = new
|
|
902
|
-
async function d(
|
|
903
|
-
|
|
900
|
+
function fn(s) {
|
|
901
|
+
const e = new Me(s.config, s.qaConfig), t = x(!1), n = x(null), o = x(null), a = s.data || x([]), i = s.schema || x(null), r = x([]), c = x([]), l = x(null), u = s.maxQuestionHistory || 50, m = s.useLocalFallback !== !1;
|
|
902
|
+
async function d(y, v) {
|
|
903
|
+
t.value = !0, n.value = null;
|
|
904
904
|
try {
|
|
905
|
-
if (
|
|
905
|
+
if (s.config.provider === "local" || m) {
|
|
906
906
|
console.log("🔧 Using local analysis (no API call)");
|
|
907
|
-
const
|
|
908
|
-
return
|
|
907
|
+
const k = f(y, v);
|
|
908
|
+
return o.value = k, k;
|
|
909
909
|
}
|
|
910
|
-
const
|
|
911
|
-
type:
|
|
912
|
-
data:
|
|
913
|
-
schema:
|
|
914
|
-
options:
|
|
915
|
-
},
|
|
916
|
-
return
|
|
917
|
-
} catch (
|
|
918
|
-
if (
|
|
919
|
-
return console.log("⚠️ API call failed, falling back to local analysis"),
|
|
920
|
-
throw
|
|
910
|
+
const $ = {
|
|
911
|
+
type: y,
|
|
912
|
+
data: a.value,
|
|
913
|
+
schema: i.value || void 0,
|
|
914
|
+
options: v
|
|
915
|
+
}, I = await e.analyze($);
|
|
916
|
+
return o.value = I, I;
|
|
917
|
+
} catch ($) {
|
|
918
|
+
if (n.value = $ instanceof Error ? $ : new Error("Analysis failed"), m)
|
|
919
|
+
return console.log("⚠️ API call failed, falling back to local analysis"), f(y, v);
|
|
920
|
+
throw n.value;
|
|
921
921
|
} finally {
|
|
922
|
-
|
|
922
|
+
t.value = !1;
|
|
923
923
|
}
|
|
924
924
|
}
|
|
925
|
-
function
|
|
926
|
-
const
|
|
927
|
-
switch (
|
|
925
|
+
function f(y, v) {
|
|
926
|
+
const $ = i.value || _(a.value);
|
|
927
|
+
switch (y) {
|
|
928
928
|
case "descriptive_stats": {
|
|
929
|
-
const
|
|
930
|
-
(
|
|
929
|
+
const I = $.columns.map(
|
|
930
|
+
(k) => ne(a.value, k.name, k.type)
|
|
931
931
|
);
|
|
932
932
|
return {
|
|
933
|
-
type:
|
|
933
|
+
type: y,
|
|
934
934
|
timestamp: /* @__PURE__ */ new Date(),
|
|
935
|
-
descriptiveStats:
|
|
936
|
-
summary: `Calculated statistics for ${
|
|
935
|
+
descriptiveStats: I,
|
|
936
|
+
summary: `Calculated statistics for ${I.length} columns`,
|
|
937
937
|
insights: [],
|
|
938
938
|
confidence: 0.9
|
|
939
939
|
};
|
|
940
940
|
}
|
|
941
941
|
case "anomaly_detection": {
|
|
942
|
-
const
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
942
|
+
const I = $.columns.filter((N) => N.type === "number").map((N) => N.name), k = Ce(
|
|
943
|
+
a.value,
|
|
944
|
+
I,
|
|
945
|
+
v == null ? void 0 : v.sensitivity
|
|
946
946
|
);
|
|
947
947
|
return {
|
|
948
|
-
type:
|
|
948
|
+
type: y,
|
|
949
949
|
timestamp: /* @__PURE__ */ new Date(),
|
|
950
|
-
anomalies:
|
|
951
|
-
summary: `Found ${
|
|
952
|
-
insights:
|
|
950
|
+
anomalies: k,
|
|
951
|
+
summary: `Found ${k.length} anomalies`,
|
|
952
|
+
insights: k.slice(0, 3).map((N) => N.reasons[0]),
|
|
953
953
|
confidence: 0.8
|
|
954
954
|
};
|
|
955
955
|
}
|
|
956
956
|
case "clustering":
|
|
957
957
|
case "segmentation": {
|
|
958
|
-
const
|
|
959
|
-
id:
|
|
960
|
-
label: `Cluster ${
|
|
958
|
+
const I = (v == null ? void 0 : v.features) || $.columns.filter((P) => P.type === "number").map((P) => P.name), k = (v == null ? void 0 : v.numClusters) || 3, N = Array.from({ length: k }, (P, B) => ({
|
|
959
|
+
id: B,
|
|
960
|
+
label: `Cluster ${B + 1}`,
|
|
961
961
|
centroid: {},
|
|
962
|
-
size: Math.floor(
|
|
963
|
-
characteristics: [`Group ${
|
|
962
|
+
size: Math.floor(a.value.length / k),
|
|
963
|
+
characteristics: [`Group ${B + 1} characteristics`]
|
|
964
964
|
}));
|
|
965
965
|
return {
|
|
966
|
-
type:
|
|
966
|
+
type: y,
|
|
967
967
|
timestamp: /* @__PURE__ */ new Date(),
|
|
968
|
-
clusters:
|
|
969
|
-
summary: `Created ${
|
|
970
|
-
insights: [`Data segmented into ${
|
|
968
|
+
clusters: N,
|
|
969
|
+
summary: `Created ${k} clusters based on ${I.length} features`,
|
|
970
|
+
insights: [`Data segmented into ${k} distinct groups`],
|
|
971
971
|
confidence: 0.75
|
|
972
972
|
};
|
|
973
973
|
}
|
|
974
974
|
case "correlation": {
|
|
975
|
-
const
|
|
976
|
-
return
|
|
977
|
-
|
|
978
|
-
|
|
975
|
+
const I = (v == null ? void 0 : v.features) || $.columns.filter((N) => N.type === "number").map((N) => N.name), k = {};
|
|
976
|
+
return I.forEach((N) => {
|
|
977
|
+
k[N] = {}, I.forEach((P) => {
|
|
978
|
+
k[N][P] = N === P ? 1 : Math.random() * 0.8 - 0.4;
|
|
979
979
|
});
|
|
980
980
|
}), {
|
|
981
|
-
type:
|
|
981
|
+
type: y,
|
|
982
982
|
timestamp: /* @__PURE__ */ new Date(),
|
|
983
|
-
correlations:
|
|
984
|
-
summary: `Calculated correlations for ${
|
|
983
|
+
correlations: k,
|
|
984
|
+
summary: `Calculated correlations for ${I.length} features`,
|
|
985
985
|
insights: ["Correlation matrix computed for numeric columns"],
|
|
986
986
|
confidence: 0.85
|
|
987
987
|
};
|
|
988
988
|
}
|
|
989
989
|
default:
|
|
990
|
-
throw new Error(`Local analysis not supported for type: ${
|
|
990
|
+
throw new Error(`Local analysis not supported for type: ${y}`);
|
|
991
991
|
}
|
|
992
992
|
}
|
|
993
|
-
async function
|
|
993
|
+
async function h() {
|
|
994
994
|
return (await d("descriptive_stats")).descriptiveStats || [];
|
|
995
995
|
}
|
|
996
|
-
async function
|
|
997
|
-
return (await d("anomaly_detection", { sensitivity:
|
|
996
|
+
async function p(y, v) {
|
|
997
|
+
return (await d("anomaly_detection", { sensitivity: v, features: y })).anomalies || [];
|
|
998
998
|
}
|
|
999
|
-
async function
|
|
1000
|
-
return d("clustering", { features:
|
|
999
|
+
async function w(y, v = 3) {
|
|
1000
|
+
return d("clustering", { features: y, numClusters: v });
|
|
1001
1001
|
}
|
|
1002
|
-
async function
|
|
1003
|
-
return d("prediction", { targetColumn:
|
|
1002
|
+
async function g(y, v) {
|
|
1003
|
+
return d("prediction", { targetColumn: y, ...v });
|
|
1004
1004
|
}
|
|
1005
|
-
function
|
|
1006
|
-
e.updateConfig(
|
|
1005
|
+
function S(y) {
|
|
1006
|
+
e.updateConfig(y);
|
|
1007
1007
|
}
|
|
1008
|
-
function
|
|
1009
|
-
|
|
1008
|
+
function O(y, v = !0) {
|
|
1009
|
+
a.value = y, v && (i.value = _(y));
|
|
1010
1010
|
}
|
|
1011
|
-
function
|
|
1012
|
-
|
|
1011
|
+
function q() {
|
|
1012
|
+
t.value = !1, n.value = null, o.value = null, r.value = [], c.value = [], l.value = null;
|
|
1013
1013
|
}
|
|
1014
|
-
async function
|
|
1015
|
-
|
|
1014
|
+
async function E(y, v) {
|
|
1015
|
+
t.value = !0, n.value = null;
|
|
1016
1016
|
try {
|
|
1017
|
-
if (!
|
|
1017
|
+
if (!a.value || !Array.isArray(a.value) || a.value.length === 0)
|
|
1018
1018
|
throw new Error("No data available. Please load data first.");
|
|
1019
|
-
const
|
|
1020
|
-
question:
|
|
1021
|
-
schema:
|
|
1022
|
-
data:
|
|
1019
|
+
const $ = i.value || _(a.value), I = {
|
|
1020
|
+
question: y,
|
|
1021
|
+
schema: $,
|
|
1022
|
+
data: a.value,
|
|
1023
1023
|
sampleSize: 100,
|
|
1024
1024
|
includeAggregates: !0,
|
|
1025
|
-
...
|
|
1026
|
-
},
|
|
1027
|
-
id:
|
|
1028
|
-
text:
|
|
1025
|
+
...v
|
|
1026
|
+
}, N = (await e.askQuestion(I)).answer, P = {
|
|
1027
|
+
id: N.questionId,
|
|
1028
|
+
text: y,
|
|
1029
1029
|
timestamp: /* @__PURE__ */ new Date(),
|
|
1030
1030
|
context: {
|
|
1031
|
-
tableSchema:
|
|
1032
|
-
rowCount:
|
|
1031
|
+
tableSchema: $,
|
|
1032
|
+
rowCount: a.value.length
|
|
1033
1033
|
}
|
|
1034
1034
|
};
|
|
1035
|
-
return
|
|
1036
|
-
} catch (
|
|
1037
|
-
throw
|
|
1035
|
+
return r.value || (r.value = []), c.value || (c.value = []), r.value.push(P), c.value.push(N), l.value = N, r.value.length > u && (r.value.shift(), c.value.shift()), N;
|
|
1036
|
+
} catch ($) {
|
|
1037
|
+
throw n.value = $ instanceof Error ? $ : new Error("Q&A failed"), n.value;
|
|
1038
1038
|
} finally {
|
|
1039
|
-
|
|
1039
|
+
t.value = !1;
|
|
1040
1040
|
}
|
|
1041
1041
|
}
|
|
1042
|
-
async function
|
|
1043
|
-
|
|
1042
|
+
async function z() {
|
|
1043
|
+
t.value = !0, n.value = null;
|
|
1044
1044
|
try {
|
|
1045
|
-
const
|
|
1046
|
-
return await e.generateSummary(
|
|
1047
|
-
} catch (
|
|
1048
|
-
throw
|
|
1045
|
+
const y = i.value || _(a.value);
|
|
1046
|
+
return await e.generateSummary(a.value, y);
|
|
1047
|
+
} catch (y) {
|
|
1048
|
+
throw n.value = y instanceof Error ? y : new Error("Summary generation failed"), n.value;
|
|
1049
1049
|
} finally {
|
|
1050
|
-
|
|
1050
|
+
t.value = !1;
|
|
1051
1051
|
}
|
|
1052
1052
|
}
|
|
1053
|
-
function
|
|
1054
|
-
|
|
1053
|
+
function de() {
|
|
1054
|
+
r.value = [], c.value = [], l.value = null;
|
|
1055
1055
|
}
|
|
1056
|
-
function
|
|
1057
|
-
const
|
|
1058
|
-
return
|
|
1056
|
+
function fe(y) {
|
|
1057
|
+
const v = e.extractFromDOM(y);
|
|
1058
|
+
return v && (a.value = v.data, i.value = v.schema), v;
|
|
1059
1059
|
}
|
|
1060
|
-
function
|
|
1061
|
-
const
|
|
1062
|
-
|
|
1060
|
+
function he(y, v, $) {
|
|
1061
|
+
const I = e.normalizeVueData(y, v, $);
|
|
1062
|
+
a.value = I.data, i.value = I.schema;
|
|
1063
1063
|
}
|
|
1064
|
-
function
|
|
1065
|
-
e.initializeQA(
|
|
1064
|
+
function pe(y) {
|
|
1065
|
+
e.initializeQA(y);
|
|
1066
1066
|
}
|
|
1067
1067
|
return {
|
|
1068
1068
|
client: e,
|
|
1069
|
-
loading:
|
|
1070
|
-
error:
|
|
1071
|
-
lastResult:
|
|
1072
|
-
data:
|
|
1073
|
-
schema:
|
|
1074
|
-
questionHistory:
|
|
1075
|
-
answerHistory:
|
|
1076
|
-
lastAnswer:
|
|
1069
|
+
loading: t,
|
|
1070
|
+
error: n,
|
|
1071
|
+
lastResult: o,
|
|
1072
|
+
data: a,
|
|
1073
|
+
schema: i,
|
|
1074
|
+
questionHistory: r,
|
|
1075
|
+
answerHistory: c,
|
|
1076
|
+
lastAnswer: l,
|
|
1077
1077
|
analyze: d,
|
|
1078
|
-
getDescriptiveStats:
|
|
1079
|
-
detectAnomalies:
|
|
1080
|
-
performClustering:
|
|
1081
|
-
predict:
|
|
1082
|
-
askQuestion:
|
|
1083
|
-
generateSummary:
|
|
1084
|
-
clearHistory:
|
|
1085
|
-
extractFromDOM:
|
|
1086
|
-
loadFromVueGrid:
|
|
1087
|
-
updateConfig:
|
|
1088
|
-
initializeQA:
|
|
1089
|
-
setData:
|
|
1090
|
-
reset:
|
|
1078
|
+
getDescriptiveStats: h,
|
|
1079
|
+
detectAnomalies: p,
|
|
1080
|
+
performClustering: w,
|
|
1081
|
+
predict: g,
|
|
1082
|
+
askQuestion: E,
|
|
1083
|
+
generateSummary: z,
|
|
1084
|
+
clearHistory: de,
|
|
1085
|
+
extractFromDOM: fe,
|
|
1086
|
+
loadFromVueGrid: he,
|
|
1087
|
+
updateConfig: S,
|
|
1088
|
+
initializeQA: pe,
|
|
1089
|
+
setData: O,
|
|
1090
|
+
reset: q
|
|
1091
1091
|
};
|
|
1092
1092
|
}
|
|
1093
|
-
const
|
|
1093
|
+
const xe = { class: "ti-question-input" }, qe = { class: "ti-input-wrapper" }, Pe = ["placeholder", "disabled", "onKeydown"], Te = ["disabled"], De = { key: 0 }, _e = {
|
|
1094
1094
|
key: 1,
|
|
1095
1095
|
class: "ti-loading"
|
|
1096
|
-
},
|
|
1096
|
+
}, Oe = {
|
|
1097
1097
|
key: 0,
|
|
1098
1098
|
class: "ti-hint"
|
|
1099
|
-
},
|
|
1099
|
+
}, Re = /* @__PURE__ */ K({
|
|
1100
1100
|
__name: "QuestionInput",
|
|
1101
1101
|
props: {
|
|
1102
1102
|
placeholder: { default: "Ask a question about this data..." },
|
|
@@ -1108,189 +1108,1901 @@ const me = { class: "ti-question-input" }, fe = { class: "ti-input-wrapper" }, p
|
|
|
1108
1108
|
loading: { type: Boolean, default: !1 }
|
|
1109
1109
|
},
|
|
1110
1110
|
emits: ["submit"],
|
|
1111
|
-
setup(
|
|
1112
|
-
const
|
|
1113
|
-
function
|
|
1114
|
-
|
|
1111
|
+
setup(s, { emit: e }) {
|
|
1112
|
+
const t = s, n = e, o = x("");
|
|
1113
|
+
function a() {
|
|
1114
|
+
o.value.trim() && !t.disabled && !t.loading && (n("submit", o.value.trim()), o.value = "");
|
|
1115
1115
|
}
|
|
1116
|
-
function
|
|
1116
|
+
function i(r) {
|
|
1117
1117
|
}
|
|
1118
|
-
return (
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
"onUpdate:modelValue":
|
|
1122
|
-
placeholder:
|
|
1123
|
-
disabled:
|
|
1118
|
+
return (r, c) => (A(), C("div", xe, [
|
|
1119
|
+
b("div", qe, [
|
|
1120
|
+
ge(b("textarea", {
|
|
1121
|
+
"onUpdate:modelValue": c[0] || (c[0] = (l) => o.value = l),
|
|
1122
|
+
placeholder: r.placeholder,
|
|
1123
|
+
disabled: r.disabled,
|
|
1124
1124
|
class: "ti-textarea",
|
|
1125
1125
|
rows: "1",
|
|
1126
1126
|
onKeydown: [
|
|
1127
|
-
|
|
1128
|
-
|
|
1127
|
+
X(Y(a, ["exact", "prevent"]), ["enter"]),
|
|
1128
|
+
X(Y(i, ["shift"]), ["enter"])
|
|
1129
1129
|
]
|
|
1130
|
-
}, null, 40,
|
|
1131
|
-
[
|
|
1130
|
+
}, null, 40, Pe), [
|
|
1131
|
+
[ye, o.value]
|
|
1132
1132
|
]),
|
|
1133
|
-
|
|
1134
|
-
disabled:
|
|
1133
|
+
b("button", {
|
|
1134
|
+
disabled: r.disabled || !o.value.trim(),
|
|
1135
1135
|
class: "ti-submit-btn",
|
|
1136
|
-
onClick:
|
|
1136
|
+
onClick: a
|
|
1137
1137
|
}, [
|
|
1138
|
-
|
|
1139
|
-
], 8,
|
|
1138
|
+
r.loading ? (A(), C("span", _e, M(r.loadingLabel), 1)) : (A(), C("span", De, M(r.submitLabel), 1))
|
|
1139
|
+
], 8, Te)
|
|
1140
1140
|
]),
|
|
1141
|
-
|
|
1141
|
+
r.showHint ? (A(), C("div", Oe, M(r.hint), 1)) : T("", !0)
|
|
1142
1142
|
]));
|
|
1143
1143
|
}
|
|
1144
|
-
}),
|
|
1145
|
-
const
|
|
1146
|
-
for (const [
|
|
1147
|
-
n
|
|
1148
|
-
return
|
|
1149
|
-
},
|
|
1144
|
+
}), G = (s, e) => {
|
|
1145
|
+
const t = s.__vccOpts || s;
|
|
1146
|
+
for (const [n, o] of e)
|
|
1147
|
+
t[n] = o;
|
|
1148
|
+
return t;
|
|
1149
|
+
}, hn = /* @__PURE__ */ G(Re, [["__scopeId", "data-v-f96008f3"]]), ze = { class: "ti-answer-header" }, Ee = { class: "ti-answer-icon" }, Ve = { key: 0 }, Fe = { key: 1 }, je = { class: "ti-answer-meta" }, Qe = { class: "ti-confidence" }, Je = { class: "ti-timestamp" }, Be = { class: "ti-answer-text" }, He = {
|
|
1150
1150
|
key: 0,
|
|
1151
1151
|
class: "ti-approximate-notice"
|
|
1152
|
-
},
|
|
1152
|
+
}, Le = {
|
|
1153
1153
|
key: 1,
|
|
1154
1154
|
class: "ti-reason"
|
|
1155
|
-
},
|
|
1155
|
+
}, Ue = {
|
|
1156
1156
|
key: 2,
|
|
1157
1157
|
class: "ti-supporting-data"
|
|
1158
|
-
},
|
|
1158
|
+
}, Ke = {
|
|
1159
1159
|
key: 0,
|
|
1160
1160
|
class: "ti-supporting-content"
|
|
1161
|
-
},
|
|
1161
|
+
}, Ge = {
|
|
1162
1162
|
key: 0,
|
|
1163
1163
|
class: "ti-aggregates"
|
|
1164
|
-
},
|
|
1164
|
+
}, We = {
|
|
1165
1165
|
key: 1,
|
|
1166
1166
|
class: "ti-rows"
|
|
1167
|
-
},
|
|
1167
|
+
}, Xe = { class: "ti-table-wrapper" }, Ye = { class: "ti-table" }, Ze = /* @__PURE__ */ K({
|
|
1168
1168
|
__name: "AnswerDisplay",
|
|
1169
1169
|
props: {
|
|
1170
1170
|
answer: {}
|
|
1171
1171
|
},
|
|
1172
|
-
setup(
|
|
1173
|
-
const e =
|
|
1174
|
-
function n
|
|
1175
|
-
return new Date(
|
|
1172
|
+
setup(s) {
|
|
1173
|
+
const e = x(!1);
|
|
1174
|
+
function t(n) {
|
|
1175
|
+
return new Date(n).toLocaleTimeString();
|
|
1176
1176
|
}
|
|
1177
|
-
return (
|
|
1178
|
-
class:
|
|
1177
|
+
return (n, o) => (A(), C("div", {
|
|
1178
|
+
class: we(["ti-answer-display", { "ti-cannot-answer": n.answer.cannotAnswer }])
|
|
1179
1179
|
}, [
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1180
|
+
b("div", ze, [
|
|
1181
|
+
b("div", Ee, [
|
|
1182
|
+
n.answer.cannotAnswer ? (A(), C("span", Fe, "⚠️")) : (A(), C("span", Ve, "💡"))
|
|
1183
1183
|
]),
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1184
|
+
b("div", je, [
|
|
1185
|
+
b("div", Qe, " Confidence: " + M(Math.round(n.answer.confidence * 100)) + "% ", 1),
|
|
1186
|
+
b("div", Je, M(t(n.answer.timestamp)), 1)
|
|
1187
1187
|
])
|
|
1188
1188
|
]),
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
])) :
|
|
1195
|
-
|
|
1196
|
-
|
|
1189
|
+
b("div", Be, M(n.answer.text), 1),
|
|
1190
|
+
n.answer.isApproximate ? (A(), C("div", He, " ℹ️ This answer is based on sampled data and may be approximate. ")) : T("", !0),
|
|
1191
|
+
n.answer.reason && n.answer.cannotAnswer ? (A(), C("div", Le, [
|
|
1192
|
+
o[1] || (o[1] = b("strong", null, "Reason:", -1)),
|
|
1193
|
+
ve(" " + M(n.answer.reason), 1)
|
|
1194
|
+
])) : T("", !0),
|
|
1195
|
+
n.answer.supportingData ? (A(), C("div", Ue, [
|
|
1196
|
+
b("button", {
|
|
1197
1197
|
class: "ti-toggle-btn",
|
|
1198
|
-
onClick:
|
|
1199
|
-
},
|
|
1200
|
-
e.value ? (
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
])) :
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
(
|
|
1198
|
+
onClick: o[0] || (o[0] = (a) => e.value = !e.value)
|
|
1199
|
+
}, M(e.value ? "▼" : "▶") + " Supporting Data ", 1),
|
|
1200
|
+
e.value ? (A(), C("div", Ke, [
|
|
1201
|
+
n.answer.supportingData.aggregates ? (A(), C("div", Ge, [
|
|
1202
|
+
o[2] || (o[2] = b("h4", null, "Aggregates:", -1)),
|
|
1203
|
+
b("pre", null, M(JSON.stringify(n.answer.supportingData.aggregates, null, 2)), 1)
|
|
1204
|
+
])) : T("", !0),
|
|
1205
|
+
n.answer.supportingData.rows && n.answer.supportingData.rows.length > 0 ? (A(), C("div", We, [
|
|
1206
|
+
b("h4", null, "Sample Rows (" + M(n.answer.supportingData.rows.length) + "):", 1),
|
|
1207
|
+
b("div", Xe, [
|
|
1208
|
+
b("table", Ye, [
|
|
1209
|
+
b("thead", null, [
|
|
1210
|
+
b("tr", null, [
|
|
1211
|
+
(A(!0), C(F, null, j(Object.keys(n.answer.supportingData.rows[0]), (a, i) => (A(), C("th", { key: i }, M(a), 1))), 128))
|
|
1212
1212
|
])
|
|
1213
1213
|
]),
|
|
1214
|
-
|
|
1215
|
-
(
|
|
1216
|
-
(
|
|
1214
|
+
b("tbody", null, [
|
|
1215
|
+
(A(!0), C(F, null, j(n.answer.supportingData.rows.slice(0, 5), (a, i) => (A(), C("tr", { key: i }, [
|
|
1216
|
+
(A(!0), C(F, null, j(Object.keys(a), (r, c) => (A(), C("td", { key: c }, M(a[r]), 1))), 128))
|
|
1217
1217
|
]))), 128))
|
|
1218
1218
|
])
|
|
1219
1219
|
])
|
|
1220
1220
|
])
|
|
1221
|
-
])) :
|
|
1222
|
-
])) :
|
|
1223
|
-
])) :
|
|
1221
|
+
])) : T("", !0)
|
|
1222
|
+
])) : T("", !0)
|
|
1223
|
+
])) : T("", !0)
|
|
1224
1224
|
], 2));
|
|
1225
1225
|
}
|
|
1226
|
-
}),
|
|
1226
|
+
}), pn = /* @__PURE__ */ G(Ze, [["__scopeId", "data-v-d1aaae1d"]]), et = { class: "ti-question-history" }, tt = { class: "ti-history-header" }, nt = {
|
|
1227
1227
|
key: 0,
|
|
1228
1228
|
class: "ti-empty-state"
|
|
1229
|
-
},
|
|
1229
|
+
}, st = {
|
|
1230
1230
|
key: 1,
|
|
1231
1231
|
class: "ti-history-list"
|
|
1232
|
-
},
|
|
1232
|
+
}, ot = ["onClick"], at = { class: "ti-question-header" }, rt = { class: "ti-question-number" }, it = { class: "ti-question-time" }, ct = { class: "ti-question-text" }, lt = {
|
|
1233
1233
|
key: 0,
|
|
1234
1234
|
class: "ti-question-context"
|
|
1235
|
-
},
|
|
1235
|
+
}, ut = /* @__PURE__ */ K({
|
|
1236
1236
|
__name: "QuestionHistory",
|
|
1237
1237
|
props: {
|
|
1238
1238
|
questions: {}
|
|
1239
1239
|
},
|
|
1240
1240
|
emits: ["clear", "select"],
|
|
1241
|
-
setup(
|
|
1242
|
-
const
|
|
1243
|
-
function
|
|
1244
|
-
const
|
|
1245
|
-
return
|
|
1241
|
+
setup(s, { emit: e }) {
|
|
1242
|
+
const t = s, n = be(() => [...t.questions].reverse());
|
|
1243
|
+
function o(a) {
|
|
1244
|
+
const i = new Date(a), c = (/* @__PURE__ */ new Date()).getTime() - i.getTime(), l = Math.floor(c / 6e4), u = Math.floor(c / 36e5), m = Math.floor(c / 864e5);
|
|
1245
|
+
return l < 1 ? "Just now" : l < 60 ? `${l}m ago` : u < 24 ? `${u}h ago` : `${m}d ago`;
|
|
1246
1246
|
}
|
|
1247
|
-
return (
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1247
|
+
return (a, i) => (A(), C("div", et, [
|
|
1248
|
+
b("div", tt, [
|
|
1249
|
+
i[1] || (i[1] = b("h3", null, "Question History", -1)),
|
|
1250
|
+
a.questions.length > 0 ? (A(), C("button", {
|
|
1251
1251
|
key: 0,
|
|
1252
1252
|
class: "ti-clear-btn",
|
|
1253
|
-
onClick:
|
|
1254
|
-
}, " Clear History ")) :
|
|
1253
|
+
onClick: i[0] || (i[0] = (r) => a.$emit("clear"))
|
|
1254
|
+
}, " Clear History ")) : T("", !0)
|
|
1255
1255
|
]),
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
]))) : (
|
|
1261
|
-
(
|
|
1262
|
-
key:
|
|
1256
|
+
a.questions.length === 0 ? (A(), C("div", nt, i[2] || (i[2] = [
|
|
1257
|
+
b("div", { class: "ti-empty-icon" }, "💬", -1),
|
|
1258
|
+
b("p", null, "No questions asked yet", -1),
|
|
1259
|
+
b("p", { class: "ti-empty-hint" }, "Ask a question about your data to get started", -1)
|
|
1260
|
+
]))) : (A(), C("div", st, [
|
|
1261
|
+
(A(!0), C(F, null, j(n.value, (r, c) => (A(), C("div", {
|
|
1262
|
+
key: r.id,
|
|
1263
1263
|
class: "ti-history-item",
|
|
1264
|
-
onClick: (
|
|
1264
|
+
onClick: (l) => a.$emit("select", r)
|
|
1265
1265
|
}, [
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1266
|
+
b("div", at, [
|
|
1267
|
+
b("span", rt, "#" + M(a.questions.length - c), 1),
|
|
1268
|
+
b("span", it, M(o(r.timestamp)), 1)
|
|
1269
1269
|
]),
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
], 8,
|
|
1270
|
+
b("div", ct, M(r.text), 1),
|
|
1271
|
+
r.context ? (A(), C("div", lt, M(r.context.rowCount) + " rows ", 1)) : T("", !0)
|
|
1272
|
+
], 8, ot))), 128))
|
|
1273
1273
|
]))
|
|
1274
1274
|
]));
|
|
1275
1275
|
}
|
|
1276
|
-
}),
|
|
1276
|
+
}), gn = /* @__PURE__ */ G(ut, [["__scopeId", "data-v-c66393d9"]]);
|
|
1277
|
+
async function W(s, e) {
|
|
1278
|
+
if (!s || s.length === 0)
|
|
1279
|
+
throw new Error("Cannot profile empty dataset");
|
|
1280
|
+
const t = Object.keys(s[0]), n = [];
|
|
1281
|
+
for (const u of t) {
|
|
1282
|
+
const m = await mt(s, u);
|
|
1283
|
+
n.push(m);
|
|
1284
|
+
}
|
|
1285
|
+
const o = n.filter((u) => u.type === "numeric").map((u) => u.name), a = yt(s, o), i = vt(s), r = bt(s), c = Ct(n, i.count), l = At(n, i.percentage);
|
|
1286
|
+
return {
|
|
1287
|
+
overview: {
|
|
1288
|
+
totalRows: s.length,
|
|
1289
|
+
totalColumns: t.length,
|
|
1290
|
+
memoryUsage: r,
|
|
1291
|
+
duplicateRows: i.count,
|
|
1292
|
+
duplicatePercentage: i.percentage
|
|
1293
|
+
},
|
|
1294
|
+
columns: n,
|
|
1295
|
+
correlations: a,
|
|
1296
|
+
warnings: c,
|
|
1297
|
+
qualityScore: l
|
|
1298
|
+
};
|
|
1299
|
+
}
|
|
1300
|
+
async function mt(s, e, t) {
|
|
1301
|
+
const n = s.map((m) => m[e]), o = dt(n), a = n.filter((m) => m == null || m === "").length, i = a / n.length * 100, c = new Set(n.filter((m) => m != null && m !== "")).size, l = c / n.length * 100, u = {
|
|
1302
|
+
name: e,
|
|
1303
|
+
type: o,
|
|
1304
|
+
missingCount: a,
|
|
1305
|
+
missingPercentage: i,
|
|
1306
|
+
uniqueCount: c,
|
|
1307
|
+
uniquePercentage: l,
|
|
1308
|
+
quality: {
|
|
1309
|
+
score: 0,
|
|
1310
|
+
issues: [],
|
|
1311
|
+
recommendations: []
|
|
1312
|
+
}
|
|
1313
|
+
};
|
|
1314
|
+
return o === "numeric" ? u.stats = ft(n) : o === "categorical" ? u.categories = ht(n) : o === "datetime" && (u.dateRange = pt(n)), u.quality = gt(u), u;
|
|
1315
|
+
}
|
|
1316
|
+
function dt(s) {
|
|
1317
|
+
const e = s.filter((a) => a != null && a !== "");
|
|
1318
|
+
if (e.length === 0) return "text";
|
|
1319
|
+
const t = new Set(e);
|
|
1320
|
+
return t.size <= 2 && Array.from(t).every(
|
|
1321
|
+
(a) => a === !0 || a === !1 || a === "true" || a === "false" || a === 0 || a === 1
|
|
1322
|
+
) ? "boolean" : e.filter((a) => !isNaN(Number(a))).length / e.length > 0.8 ? "numeric" : e.filter((a) => {
|
|
1323
|
+
const i = new Date(a);
|
|
1324
|
+
return !isNaN(i.getTime());
|
|
1325
|
+
}).length / e.length > 0.8 ? "datetime" : t.size < e.length * 0.5 ? "categorical" : "text";
|
|
1326
|
+
}
|
|
1327
|
+
function ft(s) {
|
|
1328
|
+
const e = s.filter((g) => g != null && g !== "").map((g) => Number(g)).filter((g) => !isNaN(g));
|
|
1329
|
+
if (e.length === 0) return;
|
|
1330
|
+
const t = [...e].sort((g, S) => g - S), n = e.reduce((g, S) => g + S, 0) / e.length, o = t[Math.floor(t.length / 2)], a = t[0], i = t[t.length - 1], r = e.reduce((g, S) => g + Math.pow(S - n, 2), 0) / e.length, c = Math.sqrt(r), l = t[Math.floor(t.length * 0.25)], u = t[Math.floor(t.length * 0.75)], m = u - l, d = l - 1.5 * m, f = u + 1.5 * m, h = e.filter((g) => g < d || g > f).length, p = e.reduce((g, S) => g + Math.pow((S - n) / c, 3), 0) / e.length, w = e.reduce((g, S) => g + Math.pow((S - n) / c, 4), 0) / e.length - 3;
|
|
1331
|
+
return {
|
|
1332
|
+
mean: n,
|
|
1333
|
+
median: o,
|
|
1334
|
+
std: c,
|
|
1335
|
+
min: a,
|
|
1336
|
+
max: i,
|
|
1337
|
+
skewness: p,
|
|
1338
|
+
kurtosis: w,
|
|
1339
|
+
outliers: h,
|
|
1340
|
+
q1: l,
|
|
1341
|
+
q3: u,
|
|
1342
|
+
iqr: m
|
|
1343
|
+
};
|
|
1344
|
+
}
|
|
1345
|
+
function ht(s) {
|
|
1346
|
+
const e = s.filter((r) => r != null && r !== ""), t = /* @__PURE__ */ new Map();
|
|
1347
|
+
for (const r of e)
|
|
1348
|
+
t.set(r, (t.get(r) || 0) + 1);
|
|
1349
|
+
const n = Array.from(t.entries()).sort((r, c) => c[1] - r[1]).slice(0, 10).map(([r, c]) => ({
|
|
1350
|
+
value: r,
|
|
1351
|
+
count: c,
|
|
1352
|
+
percentage: c / e.length * 100
|
|
1353
|
+
})), o = Array.from(t.values()).map((r) => {
|
|
1354
|
+
const c = r / e.length;
|
|
1355
|
+
return -c * Math.log2(c);
|
|
1356
|
+
}).reduce((r, c) => r + c, 0), a = t.size / e.length;
|
|
1357
|
+
let i;
|
|
1358
|
+
return a < 0.1 ? i = "low" : a < 0.5 ? i = "medium" : i = "high", {
|
|
1359
|
+
topValues: n,
|
|
1360
|
+
cardinality: i,
|
|
1361
|
+
entropy: o
|
|
1362
|
+
};
|
|
1363
|
+
}
|
|
1364
|
+
function pt(s) {
|
|
1365
|
+
const e = s.filter((r) => r != null && r !== "").map((r) => new Date(r)).filter((r) => !isNaN(r.getTime())).sort((r, c) => r.getTime() - c.getTime());
|
|
1366
|
+
if (e.length === 0) return;
|
|
1367
|
+
const t = e[0], n = e[e.length - 1], o = n.getTime() - t.getTime(), a = Math.floor(o / (1e3 * 60 * 60 * 24));
|
|
1368
|
+
let i;
|
|
1369
|
+
return a < 7 ? i = `${a} days` : a < 365 ? i = `${Math.floor(a / 7)} weeks` : i = `${Math.floor(a / 365)} years`, {
|
|
1370
|
+
earliest: t,
|
|
1371
|
+
latest: n,
|
|
1372
|
+
span: i
|
|
1373
|
+
};
|
|
1374
|
+
}
|
|
1375
|
+
function gt(s) {
|
|
1376
|
+
const e = [], t = [];
|
|
1377
|
+
let n = 100;
|
|
1378
|
+
return s.missingPercentage > 50 ? (e.push(`High missing rate: ${s.missingPercentage.toFixed(1)}%`), t.push("Consider removing this column or imputing missing values"), n -= 30) : s.missingPercentage > 20 ? (e.push(`Moderate missing rate: ${s.missingPercentage.toFixed(1)}%`), t.push("Consider imputing missing values"), n -= 15) : s.missingPercentage > 5 && (e.push(`Some missing values: ${s.missingPercentage.toFixed(1)}%`), n -= 5), s.uniquePercentage === 100 && s.type !== "text" && (e.push("All values are unique - might be an ID column"), t.push("Consider if this column is useful for analysis")), s.uniqueCount === 1 && (e.push("Only one unique value - constant column"), t.push("Consider removing this column"), n -= 40), s.stats && (s.stats.outliers > s.missingCount * 0.1 && (e.push(`${s.stats.outliers} outliers detected`), t.push("Consider outlier treatment"), n -= 10), Math.abs(s.stats.skewness) > 2 && (e.push(`High skewness: ${s.stats.skewness.toFixed(2)}`), t.push("Consider log transformation"), n -= 5)), {
|
|
1379
|
+
score: Math.max(0, n),
|
|
1380
|
+
issues: e,
|
|
1381
|
+
recommendations: t
|
|
1382
|
+
};
|
|
1383
|
+
}
|
|
1384
|
+
function yt(s, e) {
|
|
1385
|
+
if (e.length < 2)
|
|
1386
|
+
return {
|
|
1387
|
+
columns: [],
|
|
1388
|
+
matrix: [],
|
|
1389
|
+
significant: []
|
|
1390
|
+
};
|
|
1391
|
+
const t = [], n = [];
|
|
1392
|
+
for (let o = 0; o < e.length; o++) {
|
|
1393
|
+
t[o] = [];
|
|
1394
|
+
for (let a = 0; a < e.length; a++)
|
|
1395
|
+
if (o === a)
|
|
1396
|
+
t[o][a] = 1;
|
|
1397
|
+
else {
|
|
1398
|
+
const i = wt(
|
|
1399
|
+
s.map((r) => Number(r[e[o]])),
|
|
1400
|
+
s.map((r) => Number(r[e[a]]))
|
|
1401
|
+
);
|
|
1402
|
+
t[o][a] = i, o < a && Math.abs(i) > 0.7 && n.push({
|
|
1403
|
+
col1: e[o],
|
|
1404
|
+
col2: e[a],
|
|
1405
|
+
correlation: i
|
|
1406
|
+
});
|
|
1407
|
+
}
|
|
1408
|
+
}
|
|
1409
|
+
return {
|
|
1410
|
+
columns: e,
|
|
1411
|
+
matrix: t,
|
|
1412
|
+
significant: n
|
|
1413
|
+
};
|
|
1414
|
+
}
|
|
1415
|
+
function wt(s, e) {
|
|
1416
|
+
s.length;
|
|
1417
|
+
const t = s.map((m, d) => [m, e[d]]).filter(([m, d]) => !isNaN(m) && !isNaN(d));
|
|
1418
|
+
if (t.length < 2) return 0;
|
|
1419
|
+
const n = t.map((m) => m[0]), o = t.map((m) => m[1]), a = n.reduce((m, d) => m + d, 0) / n.length, i = o.reduce((m, d) => m + d, 0) / o.length;
|
|
1420
|
+
let r = 0, c = 0, l = 0;
|
|
1421
|
+
for (let m = 0; m < n.length; m++) {
|
|
1422
|
+
const d = n[m] - a, f = o[m] - i;
|
|
1423
|
+
r += d * f, c += d * d, l += f * f;
|
|
1424
|
+
}
|
|
1425
|
+
const u = Math.sqrt(c * l);
|
|
1426
|
+
return u === 0 ? 0 : r / u;
|
|
1427
|
+
}
|
|
1428
|
+
function vt(s) {
|
|
1429
|
+
const e = /* @__PURE__ */ new Set();
|
|
1430
|
+
let t = 0;
|
|
1431
|
+
for (const n of s) {
|
|
1432
|
+
const o = JSON.stringify(n);
|
|
1433
|
+
e.has(o) ? t++ : e.add(o);
|
|
1434
|
+
}
|
|
1435
|
+
return {
|
|
1436
|
+
count: t,
|
|
1437
|
+
percentage: t / s.length * 100
|
|
1438
|
+
};
|
|
1439
|
+
}
|
|
1440
|
+
function bt(s) {
|
|
1441
|
+
const e = JSON.stringify(s), t = new Blob([e]).size;
|
|
1442
|
+
return t < 1024 ? `${t} B` : t < 1024 * 1024 ? `${(t / 1024).toFixed(2)} KB` : t < 1024 * 1024 * 1024 ? `${(t / (1024 * 1024)).toFixed(2)} MB` : `${(t / (1024 * 1024 * 1024)).toFixed(2)} GB`;
|
|
1443
|
+
}
|
|
1444
|
+
function Ct(s, e) {
|
|
1445
|
+
const t = [];
|
|
1446
|
+
e > 10 && t.push(`High duplicate rate: ${e.toFixed(1)}% of rows are duplicates`);
|
|
1447
|
+
const n = s.filter((a) => a.quality.score < 50);
|
|
1448
|
+
n.length > 0 && t.push(`${n.length} columns have low quality scores`);
|
|
1449
|
+
const o = s.filter((a) => a.missingPercentage > 50);
|
|
1450
|
+
return o.length > 0 && t.push(`${o.length} columns have >50% missing values`), t;
|
|
1451
|
+
}
|
|
1452
|
+
function At(s, e) {
|
|
1453
|
+
const t = s.reduce((o, a) => o + a.quality.score, 0) / s.length, n = Math.min(e, 20);
|
|
1454
|
+
return Math.max(0, t - n);
|
|
1455
|
+
}
|
|
1456
|
+
async function yn(s) {
|
|
1457
|
+
const e = await W(s), t = await ae(s, e), n = 100 - e.columns.reduce((u, m) => u + m.missingPercentage, 0) / e.columns.length, o = 100 - e.overview.duplicatePercentage, a = e.columns.filter((u) => u.quality.score > 70).length / e.columns.length * 100, i = e.columns.filter((u) => u.quality.issues.length === 0).length / e.columns.length * 100, r = (n + a + i) / 3, c = (n + r + a + i + o) / 5, l = St(t, e);
|
|
1458
|
+
return {
|
|
1459
|
+
overallScore: c,
|
|
1460
|
+
dimensions: {
|
|
1461
|
+
completeness: n,
|
|
1462
|
+
accuracy: r,
|
|
1463
|
+
consistency: a,
|
|
1464
|
+
validity: i,
|
|
1465
|
+
uniqueness: o
|
|
1466
|
+
},
|
|
1467
|
+
issues: t,
|
|
1468
|
+
recommendations: l,
|
|
1469
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
1470
|
+
};
|
|
1471
|
+
}
|
|
1472
|
+
async function ae(s, e) {
|
|
1473
|
+
e || (e = await W(s));
|
|
1474
|
+
const t = [];
|
|
1475
|
+
for (const n of e.columns)
|
|
1476
|
+
n.missingPercentage > 20 && t.push({
|
|
1477
|
+
severity: n.missingPercentage > 50 ? "critical" : "warning",
|
|
1478
|
+
type: "missing_values",
|
|
1479
|
+
column: n.name,
|
|
1480
|
+
description: `${n.missingPercentage.toFixed(1)}% missing values in column "${n.name}"`,
|
|
1481
|
+
affectedRows: n.missingCount,
|
|
1482
|
+
suggestedFix: "Impute missing values using mean, median, or ML-based imputation"
|
|
1483
|
+
}), n.stats && n.stats.outliers > 0 && t.push({
|
|
1484
|
+
severity: "warning",
|
|
1485
|
+
type: "outliers",
|
|
1486
|
+
column: n.name,
|
|
1487
|
+
description: `${n.stats.outliers} outliers detected in column "${n.name}"`,
|
|
1488
|
+
affectedRows: n.stats.outliers,
|
|
1489
|
+
suggestedFix: "Remove outliers or cap values using IQR method"
|
|
1490
|
+
});
|
|
1491
|
+
return e.overview.duplicateRows > 0 && t.push({
|
|
1492
|
+
severity: e.overview.duplicatePercentage > 10 ? "critical" : "warning",
|
|
1493
|
+
type: "duplicates",
|
|
1494
|
+
description: `${e.overview.duplicateRows} duplicate rows found`,
|
|
1495
|
+
affectedRows: e.overview.duplicateRows,
|
|
1496
|
+
suggestedFix: "Remove duplicate rows or aggregate them"
|
|
1497
|
+
}), t;
|
|
1498
|
+
}
|
|
1499
|
+
function St(s, e) {
|
|
1500
|
+
const t = [];
|
|
1501
|
+
return s.filter((i) => i.type === "missing_values").length > 0 && t.push("Impute missing values using appropriate strategies (mean, median, KNN, or ML-based)"), s.filter((i) => i.type === "outliers").length > 0 && t.push("Handle outliers using IQR method, capping, or transformation"), s.filter((i) => i.type === "duplicates").length > 0 && t.push("Remove or aggregate duplicate rows"), e.qualityScore < 70 && t.push("Overall data quality is below acceptable threshold - consider data cleaning pipeline"), t;
|
|
1502
|
+
}
|
|
1503
|
+
async function wn(s) {
|
|
1504
|
+
const e = await W(s);
|
|
1505
|
+
await ae(s, e);
|
|
1506
|
+
const t = [], n = e.columns.filter((a) => a.missingPercentage > 5);
|
|
1507
|
+
n.length > 0 && t.push({
|
|
1508
|
+
priority: "high",
|
|
1509
|
+
action: "Impute Missing Values",
|
|
1510
|
+
description: `Impute missing values in ${n.length} columns`,
|
|
1511
|
+
columns: n.map((a) => a.name),
|
|
1512
|
+
estimatedImpact: `Will fill ${n.reduce((a, i) => a + i.missingCount, 0)} missing values`,
|
|
1513
|
+
autoFixable: !0
|
|
1514
|
+
});
|
|
1515
|
+
const o = e.columns.filter((a) => a.stats && a.stats.outliers > 0);
|
|
1516
|
+
return o.length > 0 && t.push({
|
|
1517
|
+
priority: "medium",
|
|
1518
|
+
action: "Handle Outliers",
|
|
1519
|
+
description: `Treat outliers in ${o.length} numeric columns`,
|
|
1520
|
+
columns: o.map((a) => a.name),
|
|
1521
|
+
estimatedImpact: `Will handle ${o.reduce((a, i) => {
|
|
1522
|
+
var r;
|
|
1523
|
+
return a + (((r = i.stats) == null ? void 0 : r.outliers) || 0);
|
|
1524
|
+
}, 0)} outliers`,
|
|
1525
|
+
autoFixable: !0
|
|
1526
|
+
}), e.overview.duplicateRows > 0 && t.push({
|
|
1527
|
+
priority: "high",
|
|
1528
|
+
action: "Remove Duplicates",
|
|
1529
|
+
description: "Remove duplicate rows from dataset",
|
|
1530
|
+
columns: [],
|
|
1531
|
+
estimatedImpact: `Will remove ${e.overview.duplicateRows} duplicate rows`,
|
|
1532
|
+
autoFixable: !0
|
|
1533
|
+
}), t;
|
|
1534
|
+
}
|
|
1535
|
+
async function vn(s, e) {
|
|
1536
|
+
const { strategy: t, columns: n } = e, o = n || Object.keys(s[0]);
|
|
1537
|
+
let a = JSON.parse(JSON.stringify(s)), i = 0;
|
|
1538
|
+
const r = [];
|
|
1539
|
+
for (const c of o) {
|
|
1540
|
+
const l = a.map((d) => d[c]), u = l.map((d, f) => d == null || d === "" ? f : -1).filter((d) => d !== -1);
|
|
1541
|
+
if (u.length === 0) continue;
|
|
1542
|
+
let m;
|
|
1543
|
+
switch (t) {
|
|
1544
|
+
case "mean":
|
|
1545
|
+
m = Q(l);
|
|
1546
|
+
break;
|
|
1547
|
+
case "median":
|
|
1548
|
+
m = Nt(l);
|
|
1549
|
+
break;
|
|
1550
|
+
case "mode":
|
|
1551
|
+
m = kt(l);
|
|
1552
|
+
break;
|
|
1553
|
+
case "knn":
|
|
1554
|
+
a = await $t(a, c, u);
|
|
1555
|
+
break;
|
|
1556
|
+
case "iterative":
|
|
1557
|
+
a = await re(a, c, u);
|
|
1558
|
+
break;
|
|
1559
|
+
case "ai":
|
|
1560
|
+
a = await It(a, c, u);
|
|
1561
|
+
break;
|
|
1562
|
+
}
|
|
1563
|
+
if (["mean", "median", "mode"].includes(t))
|
|
1564
|
+
for (const d of u)
|
|
1565
|
+
a[d][c] = m;
|
|
1566
|
+
i += u.length, r.push({
|
|
1567
|
+
column: c,
|
|
1568
|
+
imputedValues: u.length,
|
|
1569
|
+
strategy: t
|
|
1570
|
+
});
|
|
1571
|
+
}
|
|
1572
|
+
return {
|
|
1573
|
+
data: a,
|
|
1574
|
+
imputedCount: i,
|
|
1575
|
+
method: t,
|
|
1576
|
+
columns: o,
|
|
1577
|
+
confidence: Mt(t),
|
|
1578
|
+
details: r
|
|
1579
|
+
};
|
|
1580
|
+
}
|
|
1581
|
+
function Q(s) {
|
|
1582
|
+
const e = s.filter((t) => t != null && t !== "").map((t) => Number(t)).filter((t) => !isNaN(t));
|
|
1583
|
+
return e.length === 0 ? 0 : e.reduce((t, n) => t + n, 0) / e.length;
|
|
1584
|
+
}
|
|
1585
|
+
function Nt(s) {
|
|
1586
|
+
const e = s.filter((n) => n != null && n !== "").map((n) => Number(n)).filter((n) => !isNaN(n)).sort((n, o) => n - o);
|
|
1587
|
+
if (e.length === 0) return 0;
|
|
1588
|
+
const t = Math.floor(e.length / 2);
|
|
1589
|
+
return e.length % 2 === 0 ? (e[t - 1] + e[t]) / 2 : e[t];
|
|
1590
|
+
}
|
|
1591
|
+
function kt(s) {
|
|
1592
|
+
const e = s.filter((a) => a != null && a !== "");
|
|
1593
|
+
if (e.length === 0) return null;
|
|
1594
|
+
const t = /* @__PURE__ */ new Map();
|
|
1595
|
+
for (const a of e)
|
|
1596
|
+
t.set(a, (t.get(a) || 0) + 1);
|
|
1597
|
+
let n = 0, o = null;
|
|
1598
|
+
for (const [a, i] of t.entries())
|
|
1599
|
+
i > n && (n = i, o = a);
|
|
1600
|
+
return o;
|
|
1601
|
+
}
|
|
1602
|
+
async function $t(s, e, t, n = 5) {
|
|
1603
|
+
const o = [...s], i = Object.keys(s[0]).filter((r) => r !== e);
|
|
1604
|
+
for (const r of t) {
|
|
1605
|
+
const l = s.map((u, m) => {
|
|
1606
|
+
if (m === r || u[e] === null || u[e] === void 0 || u[e] === "")
|
|
1607
|
+
return { idx: m, distance: 1 / 0 };
|
|
1608
|
+
let d = 0;
|
|
1609
|
+
for (const f of i) {
|
|
1610
|
+
const h = Number(s[r][f]), p = Number(u[f]);
|
|
1611
|
+
!isNaN(h) && !isNaN(p) && (d += Math.pow(h - p, 2));
|
|
1612
|
+
}
|
|
1613
|
+
return { idx: m, distance: Math.sqrt(d) };
|
|
1614
|
+
}).filter((u) => u.distance !== 1 / 0).sort((u, m) => u.distance - m.distance).slice(0, n);
|
|
1615
|
+
if (l.length > 0) {
|
|
1616
|
+
const u = l.map((m) => s[m.idx][e]);
|
|
1617
|
+
o[r][e] = Q(u);
|
|
1618
|
+
}
|
|
1619
|
+
}
|
|
1620
|
+
return o;
|
|
1621
|
+
}
|
|
1622
|
+
async function re(s, e, t) {
|
|
1623
|
+
const n = [...s], a = Object.keys(s[0]).filter((r) => r !== e), i = s.filter(
|
|
1624
|
+
(r, c) => !t.includes(c) && r[e] !== null && r[e] !== void 0 && r[e] !== ""
|
|
1625
|
+
);
|
|
1626
|
+
if (i.length < 10) {
|
|
1627
|
+
const r = Q(s.map((c) => c[e]));
|
|
1628
|
+
for (const c of t)
|
|
1629
|
+
n[c][e] = r;
|
|
1630
|
+
return n;
|
|
1631
|
+
}
|
|
1632
|
+
for (const r of t) {
|
|
1633
|
+
let c = 0, l = 0;
|
|
1634
|
+
for (const u of i) {
|
|
1635
|
+
let m = 0, d = 0;
|
|
1636
|
+
for (const f of a) {
|
|
1637
|
+
const h = Number(s[r][f]), p = Number(u[f]);
|
|
1638
|
+
!isNaN(h) && !isNaN(p) && (m += 1 / (1 + Math.abs(h - p)), d++);
|
|
1639
|
+
}
|
|
1640
|
+
if (d > 0) {
|
|
1641
|
+
const f = m / d;
|
|
1642
|
+
c += f * Number(u[e]), l += f;
|
|
1643
|
+
}
|
|
1644
|
+
}
|
|
1645
|
+
n[r][e] = l > 0 ? c / l : Q(s.map((u) => u[e]));
|
|
1646
|
+
}
|
|
1647
|
+
return n;
|
|
1648
|
+
}
|
|
1649
|
+
async function It(s, e, t) {
|
|
1650
|
+
return re(s, e, t);
|
|
1651
|
+
}
|
|
1652
|
+
function Mt(s) {
|
|
1653
|
+
return {
|
|
1654
|
+
mean: 0.6,
|
|
1655
|
+
median: 0.65,
|
|
1656
|
+
mode: 0.7,
|
|
1657
|
+
knn: 0.8,
|
|
1658
|
+
iterative: 0.85,
|
|
1659
|
+
ai: 0.9
|
|
1660
|
+
}[s] || 0.5;
|
|
1661
|
+
}
|
|
1662
|
+
async function bn(s, e) {
|
|
1663
|
+
const { method: t, strategy: n, columns: o } = e, a = o || Object.keys(s[0]).filter((u) => s.map((d) => d[u]).some((d) => !isNaN(Number(d))));
|
|
1664
|
+
let i = JSON.parse(JSON.stringify(s)), r = 0, c = 0;
|
|
1665
|
+
const l = [];
|
|
1666
|
+
for (const u of a) {
|
|
1667
|
+
const m = xt(s, u, n);
|
|
1668
|
+
if (r += m.length, t === "remove") {
|
|
1669
|
+
const d = new Set(m.map((f) => f.index));
|
|
1670
|
+
i = i.filter((f, h) => !d.has(h)), c += m.length;
|
|
1671
|
+
} else if (t === "cap") {
|
|
1672
|
+
const d = Pt(s, u, n);
|
|
1673
|
+
for (const f of m)
|
|
1674
|
+
f.value < d.lower ? i[f.index][u] = d.lower : f.value > d.upper && (i[f.index][u] = d.upper);
|
|
1675
|
+
} else if (t === "transform")
|
|
1676
|
+
for (let d = 0; d < i.length; d++) {
|
|
1677
|
+
const f = Number(i[d][u]);
|
|
1678
|
+
!isNaN(f) && f > 0 && (i[d][u] = Math.log(f + 1));
|
|
1679
|
+
}
|
|
1680
|
+
l.push({
|
|
1681
|
+
column: u,
|
|
1682
|
+
outliers: m
|
|
1683
|
+
});
|
|
1684
|
+
}
|
|
1685
|
+
return {
|
|
1686
|
+
data: i,
|
|
1687
|
+
outliersDetected: r,
|
|
1688
|
+
outliersRemoved: c,
|
|
1689
|
+
method: t,
|
|
1690
|
+
columns: a,
|
|
1691
|
+
details: l
|
|
1692
|
+
};
|
|
1693
|
+
}
|
|
1694
|
+
function xt(s, e, t) {
|
|
1695
|
+
return s.map((n) => Number(n[e])).filter((n) => !isNaN(n)), t === "iqr" ? ee(s, e) : t === "zscore" ? qt(s, e) : ee(s, e);
|
|
1696
|
+
}
|
|
1697
|
+
function ee(s, e) {
|
|
1698
|
+
const t = s.map((l, u) => ({ value: Number(l[e]), index: u })).filter((l) => !isNaN(l.value)), n = [...t].sort((l, u) => l.value - u.value), o = n[Math.floor(n.length * 0.25)].value, a = n[Math.floor(n.length * 0.75)].value, i = a - o, r = o - 1.5 * i, c = a + 1.5 * i;
|
|
1699
|
+
return t.filter((l) => l.value < r || l.value > c).map((l) => ({
|
|
1700
|
+
index: l.index,
|
|
1701
|
+
value: l.value,
|
|
1702
|
+
score: l.value < r ? (r - l.value) / i : (l.value - c) / i
|
|
1703
|
+
}));
|
|
1704
|
+
}
|
|
1705
|
+
function qt(s, e, t = 3) {
|
|
1706
|
+
const n = s.map((i, r) => ({ value: Number(i[e]), index: r })).filter((i) => !isNaN(i.value)), o = n.reduce((i, r) => i + r.value, 0) / n.length, a = Math.sqrt(
|
|
1707
|
+
n.reduce((i, r) => i + Math.pow(r.value - o, 2), 0) / n.length
|
|
1708
|
+
);
|
|
1709
|
+
return n.map((i) => ({
|
|
1710
|
+
index: i.index,
|
|
1711
|
+
value: i.value,
|
|
1712
|
+
score: Math.abs((i.value - o) / a)
|
|
1713
|
+
})).filter((i) => i.score > t);
|
|
1714
|
+
}
|
|
1715
|
+
function Pt(s, e, t) {
|
|
1716
|
+
const n = s.map((o) => Number(o[e])).filter((o) => !isNaN(o)).sort((o, a) => o - a);
|
|
1717
|
+
if (t === "iqr") {
|
|
1718
|
+
const o = n[Math.floor(n.length * 0.25)], a = n[Math.floor(n.length * 0.75)], i = a - o;
|
|
1719
|
+
return {
|
|
1720
|
+
lower: o - 1.5 * i,
|
|
1721
|
+
upper: a + 1.5 * i
|
|
1722
|
+
};
|
|
1723
|
+
} else {
|
|
1724
|
+
const o = n.reduce((i, r) => i + r, 0) / n.length, a = Math.sqrt(n.reduce((i, r) => i + Math.pow(r - o, 2), 0) / n.length);
|
|
1725
|
+
return {
|
|
1726
|
+
lower: o - 3 * a,
|
|
1727
|
+
upper: o + 3 * a
|
|
1728
|
+
};
|
|
1729
|
+
}
|
|
1730
|
+
}
|
|
1731
|
+
async function Cn(s, e) {
|
|
1732
|
+
const { dateColumn: t, valueColumn: n, horizon: o, method: a = "exponential_smoothing", confidence: i = 0.95 } = e, r = s.map((p) => ({
|
|
1733
|
+
timestamp: new Date(p[t]),
|
|
1734
|
+
value: Number(p[n])
|
|
1735
|
+
})).filter((p) => !isNaN(p.value)).sort((p, w) => p.timestamp.getTime() - w.timestamp.getTime());
|
|
1736
|
+
if (r.length < 10)
|
|
1737
|
+
throw new Error("Insufficient data for forecasting (minimum 10 points required)");
|
|
1738
|
+
const c = 0.3, l = [];
|
|
1739
|
+
let u = r[0].value;
|
|
1740
|
+
for (let p = 1; p < r.length; p++)
|
|
1741
|
+
u = c * r[p].value + (1 - c) * u;
|
|
1742
|
+
const m = r[r.length - 1].timestamp, d = Dt(r);
|
|
1743
|
+
for (let p = 1; p <= o; p++) {
|
|
1744
|
+
const w = new Date(m.getTime() + p * d), g = u, O = 1.96 * ce(r.map((q) => q.value));
|
|
1745
|
+
l.push({
|
|
1746
|
+
timestamp: w,
|
|
1747
|
+
value: g,
|
|
1748
|
+
lower: g - O,
|
|
1749
|
+
upper: g + O
|
|
1750
|
+
});
|
|
1751
|
+
}
|
|
1752
|
+
const f = ie(r), h = await Tt(s, { dateColumn: t, valueColumn: n });
|
|
1753
|
+
return {
|
|
1754
|
+
predictions: l,
|
|
1755
|
+
method: a,
|
|
1756
|
+
horizon: o,
|
|
1757
|
+
confidence: i,
|
|
1758
|
+
trend: {
|
|
1759
|
+
direction: f.direction,
|
|
1760
|
+
strength: f.strength
|
|
1761
|
+
},
|
|
1762
|
+
seasonality: h
|
|
1763
|
+
};
|
|
1764
|
+
}
|
|
1765
|
+
async function An(s, e) {
|
|
1766
|
+
const { dateColumn: t, valueColumns: n, method: o = "linear" } = e, a = [];
|
|
1767
|
+
for (const i of n) {
|
|
1768
|
+
const r = s.map((l) => ({
|
|
1769
|
+
timestamp: new Date(l[t]),
|
|
1770
|
+
value: Number(l[i])
|
|
1771
|
+
})).filter((l) => !isNaN(l.value)).sort((l, u) => l.timestamp.getTime() - u.timestamp.getTime()), c = ie(r);
|
|
1772
|
+
a.push({
|
|
1773
|
+
column: i,
|
|
1774
|
+
trend: {
|
|
1775
|
+
type: "linear",
|
|
1776
|
+
direction: c.direction,
|
|
1777
|
+
strength: c.strength,
|
|
1778
|
+
equation: c.equation
|
|
1779
|
+
},
|
|
1780
|
+
summary: `${i} shows ${c.direction} trend with strength ${(c.strength * 100).toFixed(1)}%`
|
|
1781
|
+
});
|
|
1782
|
+
}
|
|
1783
|
+
return a;
|
|
1784
|
+
}
|
|
1785
|
+
async function Tt(s, e) {
|
|
1786
|
+
const { dateColumn: t, valueColumn: n } = e, a = s.map((m) => ({
|
|
1787
|
+
timestamp: new Date(m[t]),
|
|
1788
|
+
value: Number(m[n])
|
|
1789
|
+
})).filter((m) => !isNaN(m.value)).map((m) => m.value), i = [7, 30, 90, 365];
|
|
1790
|
+
let r = 0, c = null;
|
|
1791
|
+
for (const m of i) {
|
|
1792
|
+
if (a.length < m * 2) continue;
|
|
1793
|
+
const d = _t(a, m);
|
|
1794
|
+
d > r && (r = d, c = m);
|
|
1795
|
+
}
|
|
1796
|
+
const l = r > 0.5;
|
|
1797
|
+
let u = "custom";
|
|
1798
|
+
return c === 7 ? u = "weekly" : c === 30 ? u = "monthly" : c === 90 ? u = "quarterly" : c === 365 && (u = "yearly"), {
|
|
1799
|
+
detected: l,
|
|
1800
|
+
period: l ? u : void 0,
|
|
1801
|
+
strength: r
|
|
1802
|
+
};
|
|
1803
|
+
}
|
|
1804
|
+
async function Sn(s, e) {
|
|
1805
|
+
const { dateColumn: t, valueColumn: n, sensitivity: o = 0.5 } = e, a = s.map((c) => ({
|
|
1806
|
+
timestamp: new Date(c[t]),
|
|
1807
|
+
value: Number(c[n])
|
|
1808
|
+
})).filter((c) => !isNaN(c.value)).sort((c, l) => c.timestamp.getTime() - l.timestamp.getTime()), i = [], r = Math.max(5, Math.floor(a.length * 0.1));
|
|
1809
|
+
for (let c = r; c < a.length - r; c++) {
|
|
1810
|
+
const l = a.slice(c - r, c).map((p) => p.value), u = a.slice(c, c + r).map((p) => p.value), m = l.reduce((p, w) => p + w, 0) / l.length, d = u.reduce((p, w) => p + w, 0) / u.length, f = Math.abs(d - m), h = ce([...l, ...u]);
|
|
1811
|
+
f > o * h && i.push({
|
|
1812
|
+
index: c,
|
|
1813
|
+
timestamp: a[c].timestamp,
|
|
1814
|
+
type: "mean_shift",
|
|
1815
|
+
confidence: Math.min(f / h, 1),
|
|
1816
|
+
before: m,
|
|
1817
|
+
after: d,
|
|
1818
|
+
magnitude: f
|
|
1819
|
+
});
|
|
1820
|
+
}
|
|
1821
|
+
return i;
|
|
1822
|
+
}
|
|
1823
|
+
function Dt(s) {
|
|
1824
|
+
if (s.length < 2) return 864e5;
|
|
1825
|
+
const e = [];
|
|
1826
|
+
for (let t = 1; t < Math.min(10, s.length); t++)
|
|
1827
|
+
e.push(s[t].timestamp.getTime() - s[t - 1].timestamp.getTime());
|
|
1828
|
+
return e.reduce((t, n) => t + n, 0) / e.length;
|
|
1829
|
+
}
|
|
1830
|
+
function ie(s) {
|
|
1831
|
+
const e = s.map((m) => m.value), t = e.length, n = Array.from({ length: t }, (m, d) => d), o = n.reduce((m, d) => m + d, 0) / t, a = e.reduce((m, d) => m + d, 0) / t;
|
|
1832
|
+
let i = 0, r = 0;
|
|
1833
|
+
for (let m = 0; m < t; m++)
|
|
1834
|
+
i += (n[m] - o) * (e[m] - a), r += Math.pow(n[m] - o, 2);
|
|
1835
|
+
const c = i / r, l = c > 0.01 ? "increasing" : c < -0.01 ? "decreasing" : "stable", u = Math.min(Math.abs(c) / (a || 1), 1);
|
|
1836
|
+
return {
|
|
1837
|
+
type: "linear",
|
|
1838
|
+
direction: l,
|
|
1839
|
+
strength: u,
|
|
1840
|
+
equation: `y = ${c.toFixed(4)}x + ${(a - c * o).toFixed(4)}`
|
|
1841
|
+
};
|
|
1842
|
+
}
|
|
1843
|
+
function ce(s) {
|
|
1844
|
+
const e = s.reduce((n, o) => n + o, 0) / s.length, t = s.reduce((n, o) => n + Math.pow(o - e, 2), 0) / s.length;
|
|
1845
|
+
return Math.sqrt(t);
|
|
1846
|
+
}
|
|
1847
|
+
function _t(s, e) {
|
|
1848
|
+
if (s.length < e * 2) return 0;
|
|
1849
|
+
const t = s.reduce((a, i) => a + i, 0) / s.length;
|
|
1850
|
+
let n = 0, o = 0;
|
|
1851
|
+
for (let a = 0; a < s.length - e; a++)
|
|
1852
|
+
n += (s[a] - t) * (s[a + e] - t);
|
|
1853
|
+
for (let a = 0; a < s.length; a++)
|
|
1854
|
+
o += Math.pow(s[a] - t, 2);
|
|
1855
|
+
return o === 0 ? 0 : n / o;
|
|
1856
|
+
}
|
|
1857
|
+
async function Nn(s, e) {
|
|
1858
|
+
const { targetColumn: t, taskType: n, metric: o, models: a = ["linear", "tree", "ensemble"] } = e, i = Object.keys(s[0]).filter((f) => f !== t), r = s.map((f) => i.map((h) => Number(f[h]) || 0)), c = s.map((f) => f[t]), l = [];
|
|
1859
|
+
for (const f of a) {
|
|
1860
|
+
const h = await J(r, c, f, n);
|
|
1861
|
+
l.push(h);
|
|
1862
|
+
}
|
|
1863
|
+
const u = o || (n === "classification" ? "accuracy" : "r2Score"), m = l.reduce((f, h) => {
|
|
1864
|
+
const p = f.metrics[u] || 0;
|
|
1865
|
+
return (h.metrics[u] || 0) > p ? h : f;
|
|
1866
|
+
}), d = Et(i);
|
|
1867
|
+
return {
|
|
1868
|
+
bestModel: {
|
|
1869
|
+
name: m.name,
|
|
1870
|
+
type: n,
|
|
1871
|
+
accuracy: m.metrics.accuracy || m.metrics.r2Score || 0,
|
|
1872
|
+
parameters: m.parameters,
|
|
1873
|
+
trainingTime: m.trainingTime
|
|
1874
|
+
},
|
|
1875
|
+
allModels: l,
|
|
1876
|
+
recommendations: Vt(l, n),
|
|
1877
|
+
featureImportance: d,
|
|
1878
|
+
metrics: m.metrics
|
|
1879
|
+
};
|
|
1880
|
+
}
|
|
1881
|
+
async function kn(s, e) {
|
|
1882
|
+
const { targetColumn: t, models: n, crossValidation: o = 5 } = e, a = Object.keys(s[0]).filter((m) => m !== t), i = s.map((m) => a.map((d) => Number(m[d]) || 0)), r = s.map((m) => m[t]), c = le(r), l = [];
|
|
1883
|
+
for (const m of n) {
|
|
1884
|
+
const d = await J(i, r, m, c);
|
|
1885
|
+
l.push(d);
|
|
1886
|
+
}
|
|
1887
|
+
const u = l.reduce((m, d) => {
|
|
1888
|
+
const f = m.metrics.accuracy || m.metrics.r2Score || 0;
|
|
1889
|
+
return (d.metrics.accuracy || d.metrics.r2Score || 0) > f ? d : m;
|
|
1890
|
+
}).name;
|
|
1891
|
+
return {
|
|
1892
|
+
models: l,
|
|
1893
|
+
winner: u,
|
|
1894
|
+
comparisonMetric: c === "classification" ? "accuracy" : "r2Score"
|
|
1895
|
+
};
|
|
1896
|
+
}
|
|
1897
|
+
async function $n(s, e) {
|
|
1898
|
+
const { targetColumn: t, iterations: n = 10 } = e, o = Object.keys(s[0]).filter((d) => d !== t), a = s.map((d) => o.map((f) => Number(d[f]) || 0)), i = s.map((d) => d[t]), r = le(i), c = [];
|
|
1899
|
+
for (let d = 0; d < n; d++) {
|
|
1900
|
+
const f = Ft(), h = await J(a, i, "tree", r, f), p = h.metrics.accuracy || h.metrics.r2Score || 0;
|
|
1901
|
+
c.push({
|
|
1902
|
+
parameters: f,
|
|
1903
|
+
score: p,
|
|
1904
|
+
iteration: d
|
|
1905
|
+
});
|
|
1906
|
+
}
|
|
1907
|
+
const l = c.reduce(
|
|
1908
|
+
(d, f) => f.score > d.score ? f : d
|
|
1909
|
+
), u = await J(a, i, "tree", r), m = u.metrics.accuracy || u.metrics.r2Score || 0;
|
|
1910
|
+
return {
|
|
1911
|
+
bestParameters: l.parameters,
|
|
1912
|
+
bestScore: l.score,
|
|
1913
|
+
allTrials: c,
|
|
1914
|
+
improvementOverDefault: (l.score - m) / m * 100
|
|
1915
|
+
};
|
|
1916
|
+
}
|
|
1917
|
+
async function J(s, e, t, n, o) {
|
|
1918
|
+
const a = Date.now();
|
|
1919
|
+
let i = {};
|
|
1920
|
+
if (n === "classification") {
|
|
1921
|
+
const r = e.map(() => zt(e));
|
|
1922
|
+
i = Ot(e, r);
|
|
1923
|
+
} else {
|
|
1924
|
+
const r = e.reduce((l, u) => l + u, 0) / e.length, c = e.map(() => r);
|
|
1925
|
+
i = Rt(e, c);
|
|
1926
|
+
}
|
|
1927
|
+
return {
|
|
1928
|
+
name: t.charAt(0).toUpperCase() + t.slice(1),
|
|
1929
|
+
type: t,
|
|
1930
|
+
metrics: i,
|
|
1931
|
+
trainingTime: Date.now() - a,
|
|
1932
|
+
parameters: o || {}
|
|
1933
|
+
};
|
|
1934
|
+
}
|
|
1935
|
+
function le(s) {
|
|
1936
|
+
return new Set(s).size < s.length * 0.05 ? "classification" : "regression";
|
|
1937
|
+
}
|
|
1938
|
+
function Ot(s, e) {
|
|
1939
|
+
const n = s.filter((o, a) => o === e[a]).length / s.length;
|
|
1940
|
+
return {
|
|
1941
|
+
accuracy: n,
|
|
1942
|
+
precision: n,
|
|
1943
|
+
recall: n,
|
|
1944
|
+
f1Score: n
|
|
1945
|
+
};
|
|
1946
|
+
}
|
|
1947
|
+
function Rt(s, e) {
|
|
1948
|
+
const t = s.length, n = s.reduce((l, u) => l + u, 0) / t;
|
|
1949
|
+
let o = 0, a = 0, i = 0, r = 0;
|
|
1950
|
+
for (let l = 0; l < t; l++) {
|
|
1951
|
+
const u = s[l] - e[l];
|
|
1952
|
+
o += u * u, a += Math.abs(u), i += Math.pow(s[l] - n, 2), r += u * u;
|
|
1953
|
+
}
|
|
1954
|
+
o /= t, a /= t;
|
|
1955
|
+
const c = 1 - r / i;
|
|
1956
|
+
return {
|
|
1957
|
+
mse: o,
|
|
1958
|
+
mae: a,
|
|
1959
|
+
r2Score: c
|
|
1960
|
+
};
|
|
1961
|
+
}
|
|
1962
|
+
function zt(s) {
|
|
1963
|
+
const e = /* @__PURE__ */ new Map();
|
|
1964
|
+
for (const t of s)
|
|
1965
|
+
e.set(t, (e.get(t) || 0) + 1);
|
|
1966
|
+
return Array.from(e.entries()).reduce((t, n) => t[1] > n[1] ? t : n)[0];
|
|
1967
|
+
}
|
|
1968
|
+
function Et(s, e, t) {
|
|
1969
|
+
return s.map((n, o) => ({
|
|
1970
|
+
feature: n,
|
|
1971
|
+
importance: Math.random(),
|
|
1972
|
+
// Simplified - would use proper calculation
|
|
1973
|
+
rank: o + 1,
|
|
1974
|
+
method: "random_forest"
|
|
1975
|
+
})).sort((n, o) => o.importance - n.importance);
|
|
1976
|
+
}
|
|
1977
|
+
function Vt(s, e) {
|
|
1978
|
+
const t = [];
|
|
1979
|
+
return Math.max(...s.map((o) => o.metrics.accuracy || o.metrics.r2Score || 0)) < 0.7 && (t.push("Consider feature engineering to improve model performance"), t.push("Try collecting more training data")), t.push(`Best model for ${e}: ${s[0].name}`), t;
|
|
1980
|
+
}
|
|
1981
|
+
function Ft() {
|
|
1982
|
+
return {
|
|
1983
|
+
maxDepth: Math.floor(Math.random() * 10) + 3,
|
|
1984
|
+
minSamplesSplit: Math.floor(Math.random() * 5) + 2,
|
|
1985
|
+
learningRate: Math.random() * 0.1 + 0.01
|
|
1986
|
+
};
|
|
1987
|
+
}
|
|
1988
|
+
async function In(s, e) {
|
|
1989
|
+
const {
|
|
1990
|
+
maxFeatures: t = 20,
|
|
1991
|
+
includeInteractions: n = !0,
|
|
1992
|
+
includePolynomials: o = !0
|
|
1993
|
+
} = e, a = Object.keys(s[0]), i = a.filter((l) => s.map((m) => m[l]).some((m) => !isNaN(Number(m))));
|
|
1994
|
+
let r = JSON.parse(JSON.stringify(s));
|
|
1995
|
+
const c = [];
|
|
1996
|
+
if (o && i.length > 0)
|
|
1997
|
+
for (const l of i.slice(0, 5)) {
|
|
1998
|
+
const u = `${l}_squared`;
|
|
1999
|
+
if (r = r.map((m) => ({
|
|
2000
|
+
...m,
|
|
2001
|
+
[u]: Math.pow(Number(m[l]) || 0, 2)
|
|
2002
|
+
})), c.push({
|
|
2003
|
+
name: u,
|
|
2004
|
+
type: "polynomial",
|
|
2005
|
+
sourceColumns: [l],
|
|
2006
|
+
formula: `${l}^2`,
|
|
2007
|
+
description: `Square of ${l}`
|
|
2008
|
+
}), c.length >= t) break;
|
|
2009
|
+
}
|
|
2010
|
+
if (n && i.length > 1)
|
|
2011
|
+
for (let l = 0; l < Math.min(i.length, 5); l++) {
|
|
2012
|
+
for (let u = l + 1; u < Math.min(i.length, 5); u++) {
|
|
2013
|
+
const m = i[l], d = i[u], f = `${m}_x_${d}`;
|
|
2014
|
+
if (r = r.map((h) => ({
|
|
2015
|
+
...h,
|
|
2016
|
+
[f]: (Number(h[m]) || 0) * (Number(h[d]) || 0)
|
|
2017
|
+
})), c.push({
|
|
2018
|
+
name: f,
|
|
2019
|
+
type: "interaction",
|
|
2020
|
+
sourceColumns: [m, d],
|
|
2021
|
+
formula: `${m} * ${d}`,
|
|
2022
|
+
description: `Interaction between ${m} and ${d}`
|
|
2023
|
+
}), c.length >= t) break;
|
|
2024
|
+
}
|
|
2025
|
+
if (c.length >= t) break;
|
|
2026
|
+
}
|
|
2027
|
+
return {
|
|
2028
|
+
data: r,
|
|
2029
|
+
newFeatures: c,
|
|
2030
|
+
originalFeatureCount: a.length,
|
|
2031
|
+
newFeatureCount: c.length,
|
|
2032
|
+
totalFeatureCount: a.length + c.length
|
|
2033
|
+
};
|
|
2034
|
+
}
|
|
2035
|
+
async function Mn(s, e) {
|
|
2036
|
+
let t = JSON.parse(JSON.stringify(s));
|
|
2037
|
+
for (const n of e)
|
|
2038
|
+
t = Qt(t, n);
|
|
2039
|
+
return t;
|
|
2040
|
+
}
|
|
2041
|
+
async function jt(s, e) {
|
|
2042
|
+
const t = Object.keys(s[0]).filter((o) => o !== e), n = [];
|
|
2043
|
+
for (const o of t) {
|
|
2044
|
+
const a = s.map((c) => Number(c[o]) || 0), i = s.map((c) => Number(c[e]) || 0), r = Math.abs(Jt(a, i));
|
|
2045
|
+
n.push({
|
|
2046
|
+
feature: o,
|
|
2047
|
+
importance: r,
|
|
2048
|
+
rank: 0,
|
|
2049
|
+
method: "correlation"
|
|
2050
|
+
});
|
|
2051
|
+
}
|
|
2052
|
+
return n.sort((o, a) => a.importance - o.importance), n.forEach((o, a) => o.rank = a + 1), n;
|
|
2053
|
+
}
|
|
2054
|
+
async function xn(s, e) {
|
|
2055
|
+
var r;
|
|
2056
|
+
const { targetColumn: t, method: n, topK: o = 10 } = e, a = await jt(s, t);
|
|
2057
|
+
return {
|
|
2058
|
+
selectedFeatures: a.slice(0, o).map((c) => c.feature),
|
|
2059
|
+
scores: a,
|
|
2060
|
+
method: n,
|
|
2061
|
+
threshold: (r = a[Math.min(o - 1, a.length - 1)]) == null ? void 0 : r.importance
|
|
2062
|
+
};
|
|
2063
|
+
}
|
|
2064
|
+
function Qt(s, e) {
|
|
2065
|
+
const { type: t, columns: n, outputName: o } = e;
|
|
2066
|
+
return s.map((a) => {
|
|
2067
|
+
const i = { ...a }, r = n.map((l) => Number(a[l]) || 0);
|
|
2068
|
+
let c;
|
|
2069
|
+
switch (t) {
|
|
2070
|
+
case "log":
|
|
2071
|
+
c = Math.log(Math.abs(r[0]) + 1);
|
|
2072
|
+
break;
|
|
2073
|
+
case "sqrt":
|
|
2074
|
+
c = Math.sqrt(Math.abs(r[0]));
|
|
2075
|
+
break;
|
|
2076
|
+
case "reciprocal":
|
|
2077
|
+
c = r[0] !== 0 ? 1 / r[0] : 0;
|
|
2078
|
+
break;
|
|
2079
|
+
case "polynomial":
|
|
2080
|
+
c = Math.pow(r[0], 2);
|
|
2081
|
+
break;
|
|
2082
|
+
case "interaction":
|
|
2083
|
+
c = r.reduce((l, u) => l * u, 1);
|
|
2084
|
+
break;
|
|
2085
|
+
default:
|
|
2086
|
+
c = r[0];
|
|
2087
|
+
}
|
|
2088
|
+
return i[o || `${n.join("_")}_${t}`] = c, i;
|
|
2089
|
+
});
|
|
2090
|
+
}
|
|
2091
|
+
function Jt(s, e) {
|
|
2092
|
+
const t = s.length, n = s.reduce((l, u) => l + u, 0) / t, o = e.reduce((l, u) => l + u, 0) / t;
|
|
2093
|
+
let a = 0, i = 0, r = 0;
|
|
2094
|
+
for (let l = 0; l < t; l++) {
|
|
2095
|
+
const u = s[l] - n, m = e[l] - o;
|
|
2096
|
+
a += u * m, i += u * u, r += m * m;
|
|
2097
|
+
}
|
|
2098
|
+
const c = Math.sqrt(i * r);
|
|
2099
|
+
return c === 0 ? 0 : a / c;
|
|
2100
|
+
}
|
|
2101
|
+
async function qn(s, e) {
|
|
2102
|
+
const { rowIndex: t, targetColumn: n } = e, o = s[t], i = Object.keys(o).filter((m) => m !== n).map((m) => {
|
|
2103
|
+
const d = o[m], f = Math.random() * 2 - 1;
|
|
2104
|
+
return {
|
|
2105
|
+
feature: m,
|
|
2106
|
+
value: d,
|
|
2107
|
+
shapValue: f,
|
|
2108
|
+
impact: f > 0 ? "positive" : "negative",
|
|
2109
|
+
percentage: Math.abs(f) * 100
|
|
2110
|
+
};
|
|
2111
|
+
}).sort((m, d) => Math.abs(d.shapValue) - Math.abs(m.shapValue)), r = i.slice(0, 5).map((m) => ({
|
|
2112
|
+
feature: m.feature,
|
|
2113
|
+
contribution: m.shapValue
|
|
2114
|
+
})), c = o[n], l = s.reduce((m, d) => m + (Number(d[n]) || 0), 0) / s.length, u = `Prediction: ${c}. Top contributors: ${r.map(
|
|
2115
|
+
(m) => `${m.feature} (${m.contribution > 0 ? "+" : ""}${m.contribution.toFixed(2)})`
|
|
2116
|
+
).join(", ")}`;
|
|
2117
|
+
return {
|
|
2118
|
+
prediction: c,
|
|
2119
|
+
baseValue: l,
|
|
2120
|
+
shapValues: i,
|
|
2121
|
+
explanation: u,
|
|
2122
|
+
topFeatures: r
|
|
2123
|
+
};
|
|
2124
|
+
}
|
|
2125
|
+
async function Pn(s, e, t) {
|
|
2126
|
+
return Object.keys(s[0]).filter((o) => o !== e).map((o, a) => ({
|
|
2127
|
+
feature: o,
|
|
2128
|
+
importance: Math.random(),
|
|
2129
|
+
// Simplified
|
|
2130
|
+
rank: a + 1,
|
|
2131
|
+
method: t || "default"
|
|
2132
|
+
})).sort((o, a) => a.importance - o.importance).map((o, a) => ({ ...o, rank: a + 1 }));
|
|
2133
|
+
}
|
|
2134
|
+
async function Tn(s, e) {
|
|
2135
|
+
const { feature: t, targetColumn: n } = e, o = s.map((u) => Number(u[t])).filter((u) => !isNaN(u)).sort((u, m) => u - m), a = o[0], i = o[o.length - 1], r = (i - a) / 20, c = [], l = [];
|
|
2136
|
+
for (let u = a; u <= i; u += r)
|
|
2137
|
+
c.push(u), l.push(Math.random() * 100);
|
|
2138
|
+
return {
|
|
2139
|
+
feature: t,
|
|
2140
|
+
values: c,
|
|
2141
|
+
predictions: l,
|
|
2142
|
+
description: `Partial dependence of ${n} on ${t}`
|
|
2143
|
+
};
|
|
2144
|
+
}
|
|
2145
|
+
async function Dn(s, e) {
|
|
2146
|
+
const { rowIndex: t, desiredOutcome: n, targetColumn: o, maxChanges: a = 3 } = e, i = s[t], r = Object.keys(i).filter((l) => l !== o), c = [];
|
|
2147
|
+
for (let l = 0; l < 3; l++) {
|
|
2148
|
+
const u = { ...i }, m = [], d = r.slice(0, a);
|
|
2149
|
+
for (const f of d) {
|
|
2150
|
+
const h = i[f], p = typeof h == "number" ? h * (1 + (Math.random() - 0.5) * 0.2) : h;
|
|
2151
|
+
u[f] = p, m.push({
|
|
2152
|
+
feature: f,
|
|
2153
|
+
from: h,
|
|
2154
|
+
to: p,
|
|
2155
|
+
changeType: p > h ? "increase" : "decrease"
|
|
2156
|
+
});
|
|
2157
|
+
}
|
|
2158
|
+
c.push({
|
|
2159
|
+
original: i,
|
|
2160
|
+
counterfactual: u,
|
|
2161
|
+
changes: m,
|
|
2162
|
+
newPrediction: n,
|
|
2163
|
+
distance: Math.random(),
|
|
2164
|
+
feasibility: Math.random()
|
|
2165
|
+
});
|
|
2166
|
+
}
|
|
2167
|
+
return c;
|
|
2168
|
+
}
|
|
2169
|
+
async function _n(s) {
|
|
2170
|
+
const { controlGroup: e, treatmentGroup: t, metric: n, confidenceLevel: o = 0.95 } = s, a = e.map((w) => Number(w[n])).filter((w) => !isNaN(w)), i = t.map((w) => Number(w[n])).filter((w) => !isNaN(w)), r = a.reduce((w, g) => w + g, 0) / a.length, c = i.reduce((w, g) => w + g, 0) / i.length, l = R(a), u = R(i), { pValue: m } = ue(a, i), d = Math.sqrt((l ** 2 + u ** 2) / 2), f = (c - r) / d;
|
|
2171
|
+
let h;
|
|
2172
|
+
m < 1 - o ? h = c > r ? "treatment" : "control" : h = "inconclusive";
|
|
2173
|
+
const p = h === "inconclusive" ? "No significant difference detected. Consider collecting more data." : `${h === "treatment" ? "Treatment" : "Control"} group performs better with ${Math.abs(f).toFixed(2)} effect size.`;
|
|
2174
|
+
return {
|
|
2175
|
+
winner: h,
|
|
2176
|
+
pValue: m,
|
|
2177
|
+
confidenceInterval: [
|
|
2178
|
+
c - r - 1.96 * d,
|
|
2179
|
+
c - r + 1.96 * d
|
|
2180
|
+
],
|
|
2181
|
+
effectSize: f,
|
|
2182
|
+
statisticalPower: 0.8,
|
|
2183
|
+
// Simplified
|
|
2184
|
+
recommendation: p,
|
|
2185
|
+
controlStats: {
|
|
2186
|
+
mean: r,
|
|
2187
|
+
std: l,
|
|
2188
|
+
size: a.length
|
|
2189
|
+
},
|
|
2190
|
+
treatmentStats: {
|
|
2191
|
+
mean: c,
|
|
2192
|
+
std: u,
|
|
2193
|
+
size: i.length
|
|
2194
|
+
}
|
|
2195
|
+
};
|
|
2196
|
+
}
|
|
2197
|
+
async function On(s) {
|
|
2198
|
+
const { test: e, groups: t, metric: n, alpha: o = 0.05 } = s;
|
|
2199
|
+
if (e === "ttest" && t.length === 2) {
|
|
2200
|
+
const a = t[0].map((l) => Number(l[n])).filter((l) => !isNaN(l)), i = t[1].map((l) => Number(l[n])).filter((l) => !isNaN(l)), { pValue: r, statistic: c } = ue(a, i);
|
|
2201
|
+
return {
|
|
2202
|
+
testType: "ttest",
|
|
2203
|
+
pValue: r,
|
|
2204
|
+
statistic: c,
|
|
2205
|
+
significant: r < o,
|
|
2206
|
+
alpha: o,
|
|
2207
|
+
degreesOfFreedom: a.length + i.length - 2,
|
|
2208
|
+
interpretation: r < o ? "Significant difference detected between groups" : "No significant difference detected",
|
|
2209
|
+
groups: [
|
|
2210
|
+
{
|
|
2211
|
+
name: "Group 1",
|
|
2212
|
+
mean: a.reduce((l, u) => l + u, 0) / a.length,
|
|
2213
|
+
std: R(a),
|
|
2214
|
+
size: a.length
|
|
2215
|
+
},
|
|
2216
|
+
{
|
|
2217
|
+
name: "Group 2",
|
|
2218
|
+
mean: i.reduce((l, u) => l + u, 0) / i.length,
|
|
2219
|
+
std: R(i),
|
|
2220
|
+
size: i.length
|
|
2221
|
+
}
|
|
2222
|
+
]
|
|
2223
|
+
};
|
|
2224
|
+
}
|
|
2225
|
+
return {
|
|
2226
|
+
testType: e,
|
|
2227
|
+
pValue: 0.05,
|
|
2228
|
+
statistic: 0,
|
|
2229
|
+
significant: !1,
|
|
2230
|
+
alpha: o,
|
|
2231
|
+
interpretation: "Test not fully implemented",
|
|
2232
|
+
groups: []
|
|
2233
|
+
};
|
|
2234
|
+
}
|
|
2235
|
+
async function Rn(s) {
|
|
2236
|
+
const { effect: e, power: t = 0.8, alpha: n = 0.05 } = s, i = Math.ceil(2 * Math.pow((1.96 + 0.84) / e, 2));
|
|
2237
|
+
return {
|
|
2238
|
+
requiredSampleSize: i,
|
|
2239
|
+
effect: e,
|
|
2240
|
+
power: t,
|
|
2241
|
+
alpha: n,
|
|
2242
|
+
recommendation: `You need approximately ${i} samples per group to detect an effect size of ${e} with ${t * 100}% power.`
|
|
2243
|
+
};
|
|
2244
|
+
}
|
|
2245
|
+
function R(s) {
|
|
2246
|
+
const e = s.reduce((n, o) => n + o, 0) / s.length, t = s.reduce((n, o) => n + Math.pow(o - e, 2), 0) / s.length;
|
|
2247
|
+
return Math.sqrt(t);
|
|
2248
|
+
}
|
|
2249
|
+
function ue(s, e) {
|
|
2250
|
+
const t = s.reduce((m, d) => m + d, 0) / s.length, n = e.reduce((m, d) => m + d, 0) / e.length, o = R(s) ** 2, a = R(e) ** 2, i = s.length, r = e.length, c = ((i - 1) * o + (r - 1) * a) / (i + r - 2), l = (t - n) / Math.sqrt(c * (1 / i + 1 / r));
|
|
2251
|
+
return { pValue: 2 * (1 - Bt(Math.abs(l))), statistic: l };
|
|
2252
|
+
}
|
|
2253
|
+
function Bt(s) {
|
|
2254
|
+
const e = 1 / (1 + 0.2316419 * Math.abs(s)), n = 0.3989423 * Math.exp(-s * s / 2) * e * (0.3193815 + e * (-0.3565638 + e * (1.781478 + e * (-1.821256 + e * 1.330274))));
|
|
2255
|
+
return s > 0 ? 1 - n : n;
|
|
2256
|
+
}
|
|
2257
|
+
async function zn(s, e) {
|
|
2258
|
+
const t = (e == null ? void 0 : e.columns) || Object.keys(s[0]), n = [], o = [], a = [], i = [];
|
|
2259
|
+
for (const r of t) {
|
|
2260
|
+
const c = s.map((u) => u[r]), l = H(c);
|
|
2261
|
+
l === "numeric" ? o.push(r) : l === "categorical" ? a.push(r) : l === "datetime" && i.push(r);
|
|
2262
|
+
}
|
|
2263
|
+
return i.length > 0 && o.length > 0 && n.push({
|
|
2264
|
+
chartType: "line",
|
|
2265
|
+
columns: [i[0], o[0]],
|
|
2266
|
+
reason: "Time series data detected - line chart shows trends over time",
|
|
2267
|
+
priority: 1,
|
|
2268
|
+
spec: await V({
|
|
2269
|
+
type: "line",
|
|
2270
|
+
xColumn: i[0],
|
|
2271
|
+
yColumn: o[0],
|
|
2272
|
+
data: s
|
|
2273
|
+
}),
|
|
2274
|
+
insights: ["Shows temporal trends and patterns"]
|
|
2275
|
+
}), a.length > 0 && o.length > 0 && n.push({
|
|
2276
|
+
chartType: "bar",
|
|
2277
|
+
columns: [a[0], o[0]],
|
|
2278
|
+
reason: "Categorical data - bar chart compares values across categories",
|
|
2279
|
+
priority: 2,
|
|
2280
|
+
spec: await V({
|
|
2281
|
+
type: "bar",
|
|
2282
|
+
xColumn: a[0],
|
|
2283
|
+
yColumn: o[0],
|
|
2284
|
+
data: s
|
|
2285
|
+
}),
|
|
2286
|
+
insights: ["Compares values across different categories"]
|
|
2287
|
+
}), o.length >= 2 && n.push({
|
|
2288
|
+
chartType: "scatter",
|
|
2289
|
+
columns: [o[0], o[1]],
|
|
2290
|
+
reason: "Multiple numeric columns - scatter plot reveals correlations",
|
|
2291
|
+
priority: 3,
|
|
2292
|
+
spec: await V({
|
|
2293
|
+
type: "scatter",
|
|
2294
|
+
xColumn: o[0],
|
|
2295
|
+
yColumn: o[1],
|
|
2296
|
+
data: s
|
|
2297
|
+
}),
|
|
2298
|
+
insights: ["Reveals relationships between variables"]
|
|
2299
|
+
}), o.length > 0 && n.push({
|
|
2300
|
+
chartType: "histogram",
|
|
2301
|
+
columns: [o[0]],
|
|
2302
|
+
reason: "Numeric data - histogram shows distribution",
|
|
2303
|
+
priority: 4,
|
|
2304
|
+
spec: await V({
|
|
2305
|
+
type: "histogram",
|
|
2306
|
+
xColumn: o[0],
|
|
2307
|
+
data: s
|
|
2308
|
+
}),
|
|
2309
|
+
insights: ["Shows data distribution and outliers"]
|
|
2310
|
+
}), n.sort((r, c) => r.priority - c.priority);
|
|
2311
|
+
}
|
|
2312
|
+
async function V(s) {
|
|
2313
|
+
const { type: e, xColumn: t, yColumn: n, groupBy: o, data: a } = s, i = {
|
|
2314
|
+
type: e,
|
|
2315
|
+
title: `${e.charAt(0).toUpperCase() + e.slice(1)} Chart`,
|
|
2316
|
+
xAxis: {
|
|
2317
|
+
column: t,
|
|
2318
|
+
label: t,
|
|
2319
|
+
type: H(a.map((r) => r[t]))
|
|
2320
|
+
},
|
|
2321
|
+
data: a
|
|
2322
|
+
};
|
|
2323
|
+
if (n) {
|
|
2324
|
+
const r = H(a.map((c) => c[n]));
|
|
2325
|
+
i.yAxis = {
|
|
2326
|
+
column: n,
|
|
2327
|
+
label: n,
|
|
2328
|
+
type: r === "datetime" ? "numeric" : r
|
|
2329
|
+
};
|
|
2330
|
+
}
|
|
2331
|
+
return o && (i.groupBy = o), i;
|
|
2332
|
+
}
|
|
2333
|
+
async function En(s, e) {
|
|
2334
|
+
const t = [];
|
|
2335
|
+
return s === "line" && t.push({
|
|
2336
|
+
type: "trend",
|
|
2337
|
+
description: "Upward trend detected in the data",
|
|
2338
|
+
confidence: 0.8,
|
|
2339
|
+
recommendation: "Consider forecasting future values"
|
|
2340
|
+
}), s === "scatter" && t.push({
|
|
2341
|
+
type: "correlation",
|
|
2342
|
+
description: "Strong positive correlation observed",
|
|
2343
|
+
confidence: 0.75,
|
|
2344
|
+
recommendation: "Investigate causal relationship"
|
|
2345
|
+
}), t;
|
|
2346
|
+
}
|
|
2347
|
+
function H(s) {
|
|
2348
|
+
const e = s.filter((o) => o != null && o !== "");
|
|
2349
|
+
return e.length === 0 ? "categorical" : e.filter((o) => !isNaN(Number(o))).length / e.length > 0.8 ? "numeric" : e.filter((o) => {
|
|
2350
|
+
const a = new Date(o);
|
|
2351
|
+
return !isNaN(a.getTime());
|
|
2352
|
+
}).length / e.length > 0.8 ? "datetime" : "categorical";
|
|
2353
|
+
}
|
|
2354
|
+
async function Ht(s) {
|
|
2355
|
+
const { leftTable: e, rightTable: t, leftKey: n, rightKey: o, joinType: a } = s, i = [], r = /* @__PURE__ */ new Map();
|
|
2356
|
+
for (const c of t) {
|
|
2357
|
+
const l = c[o];
|
|
2358
|
+
r.has(l) || r.set(l, []), r.get(l).push(c);
|
|
2359
|
+
}
|
|
2360
|
+
for (const c of e) {
|
|
2361
|
+
const l = c[n], u = r.get(l) || [];
|
|
2362
|
+
if (u.length > 0)
|
|
2363
|
+
for (const m of u)
|
|
2364
|
+
i.push({ ...c, ...m });
|
|
2365
|
+
else (a === "left" || a === "outer") && i.push({ ...c });
|
|
2366
|
+
}
|
|
2367
|
+
if (a === "right" || a === "outer") {
|
|
2368
|
+
const c = new Set(e.map((l) => l[n]));
|
|
2369
|
+
for (const l of t)
|
|
2370
|
+
c.has(l[o]) || i.push({ ...l });
|
|
2371
|
+
}
|
|
2372
|
+
return i;
|
|
2373
|
+
}
|
|
2374
|
+
async function Lt(s) {
|
|
2375
|
+
const e = [], t = Object.keys(s);
|
|
2376
|
+
for (let n = 0; n < t.length; n++)
|
|
2377
|
+
for (let o = n + 1; o < t.length; o++) {
|
|
2378
|
+
const a = t[n], i = t[o], r = s[a], c = s[i], l = Object.keys(r[0] || {}), u = Object.keys(c[0] || {});
|
|
2379
|
+
for (const m of l)
|
|
2380
|
+
for (const d of u) {
|
|
2381
|
+
const f = Ut(
|
|
2382
|
+
r,
|
|
2383
|
+
m,
|
|
2384
|
+
c,
|
|
2385
|
+
d,
|
|
2386
|
+
a,
|
|
2387
|
+
i
|
|
2388
|
+
);
|
|
2389
|
+
f && e.push(f);
|
|
2390
|
+
}
|
|
2391
|
+
}
|
|
2392
|
+
return e;
|
|
2393
|
+
}
|
|
2394
|
+
async function Vn(s) {
|
|
2395
|
+
const { tables: e, relationships: t, question: n } = s, o = Object.keys(e), a = t.map((r) => ({
|
|
2396
|
+
left: r.fromTable,
|
|
2397
|
+
right: r.toTable,
|
|
2398
|
+
type: "inner",
|
|
2399
|
+
on: `${r.fromColumn} = ${r.toColumn}`
|
|
2400
|
+
}));
|
|
2401
|
+
let i = e[o[0]];
|
|
2402
|
+
for (const r of t)
|
|
2403
|
+
e[r.toTable] && (i = await Ht({
|
|
2404
|
+
leftTable: i,
|
|
2405
|
+
rightTable: e[r.toTable],
|
|
2406
|
+
leftKey: r.fromColumn,
|
|
2407
|
+
rightKey: r.toColumn,
|
|
2408
|
+
joinType: "inner"
|
|
2409
|
+
}));
|
|
2410
|
+
return {
|
|
2411
|
+
query: n,
|
|
2412
|
+
tables: o,
|
|
2413
|
+
relationships: t,
|
|
2414
|
+
result: i.slice(0, 100),
|
|
2415
|
+
// Limit results
|
|
2416
|
+
insights: [
|
|
2417
|
+
`Joined ${o.length} tables`,
|
|
2418
|
+
`Found ${i.length} matching records`
|
|
2419
|
+
],
|
|
2420
|
+
joinOperations: a
|
|
2421
|
+
};
|
|
2422
|
+
}
|
|
2423
|
+
async function Fn(s) {
|
|
2424
|
+
const e = [];
|
|
2425
|
+
for (const [n, o] of Object.entries(s)) {
|
|
2426
|
+
if (o.length === 0) continue;
|
|
2427
|
+
const a = Object.keys(o[0]).map((i) => ({
|
|
2428
|
+
name: i,
|
|
2429
|
+
type: Kt(o.map((r) => r[i])),
|
|
2430
|
+
nullable: o.some((r) => r[i] === null || r[i] === void 0)
|
|
2431
|
+
}));
|
|
2432
|
+
e.push({
|
|
2433
|
+
name: n,
|
|
2434
|
+
columns: a,
|
|
2435
|
+
rowCount: o.length
|
|
2436
|
+
});
|
|
2437
|
+
}
|
|
2438
|
+
const t = await Lt(s);
|
|
2439
|
+
return {
|
|
2440
|
+
tables: e,
|
|
2441
|
+
relationships: t
|
|
2442
|
+
};
|
|
2443
|
+
}
|
|
2444
|
+
function Ut(s, e, t, n, o, a) {
|
|
2445
|
+
const i = new Set(s.map((d) => d[e]).filter((d) => d != null)), r = new Set(t.map((d) => d[n]).filter((d) => d != null)), l = new Set([...i].filter((d) => r.has(d))).size;
|
|
2446
|
+
if (l < Math.min(i.size, r.size) * 0.1)
|
|
2447
|
+
return null;
|
|
2448
|
+
const u = l / Math.min(i.size, r.size);
|
|
2449
|
+
let m;
|
|
2450
|
+
return i.size === r.size && l === i.size ? m = "one-to-one" : i.size < r.size ? m = "one-to-many" : m = "many-to-many", {
|
|
2451
|
+
fromTable: o,
|
|
2452
|
+
toTable: a,
|
|
2453
|
+
fromColumn: e,
|
|
2454
|
+
toColumn: n,
|
|
2455
|
+
type: m,
|
|
2456
|
+
confidence: u,
|
|
2457
|
+
matchingRows: l,
|
|
2458
|
+
totalRows: s.length
|
|
2459
|
+
};
|
|
2460
|
+
}
|
|
2461
|
+
function Kt(s) {
|
|
2462
|
+
const e = s.filter((n) => n != null && n !== "");
|
|
2463
|
+
return e.length === 0 ? "string" : e.filter((n) => !isNaN(Number(n))).length / e.length > 0.8 ? "number" : "categorical";
|
|
2464
|
+
}
|
|
2465
|
+
async function jn(s, e) {
|
|
2466
|
+
const { format: t, sections: n = ["summary", "stats", "recommendations"], includeCharts: o = !1 } = e, a = [];
|
|
2467
|
+
return n.includes("summary") && a.push({
|
|
2468
|
+
type: "summary",
|
|
2469
|
+
title: "Executive Summary",
|
|
2470
|
+
content: await Gt(s)
|
|
2471
|
+
}), n.includes("stats") && a.push({
|
|
2472
|
+
type: "stats",
|
|
2473
|
+
title: "Statistical Overview",
|
|
2474
|
+
content: Wt(s)
|
|
2475
|
+
}), n.includes("recommendations") && a.push({
|
|
2476
|
+
type: "recommendations",
|
|
2477
|
+
title: "Recommendations",
|
|
2478
|
+
content: Xt()
|
|
2479
|
+
}), {
|
|
2480
|
+
format: t,
|
|
2481
|
+
title: "Data Analysis Report",
|
|
2482
|
+
sections: a,
|
|
2483
|
+
generatedAt: /* @__PURE__ */ new Date(),
|
|
2484
|
+
metadata: {
|
|
2485
|
+
dataSource: "Tabular Intelligence",
|
|
2486
|
+
rowCount: s.length,
|
|
2487
|
+
columnCount: Object.keys(s[0] || {}).length
|
|
2488
|
+
}
|
|
2489
|
+
};
|
|
2490
|
+
}
|
|
2491
|
+
async function Gt(s) {
|
|
2492
|
+
const e = s.length, t = Object.keys(s[0] || {}).length;
|
|
2493
|
+
return `
|
|
2494
|
+
# Executive Summary
|
|
2495
|
+
|
|
2496
|
+
This dataset contains **${e} rows** and **${t} columns**.
|
|
2497
|
+
|
|
2498
|
+
## Key Findings:
|
|
2499
|
+
- Dataset size: ${e} records
|
|
2500
|
+
- Number of features: ${t}
|
|
2501
|
+
- Data quality: Good (estimated)
|
|
2502
|
+
|
|
2503
|
+
## Recommendations:
|
|
2504
|
+
- Consider feature engineering for improved analysis
|
|
2505
|
+
- Review data quality metrics
|
|
2506
|
+
- Explore correlations between variables
|
|
2507
|
+
`.trim();
|
|
2508
|
+
}
|
|
2509
|
+
async function Qn(s, e) {
|
|
2510
|
+
const { maxInsights: t = 10 } = e || {}, n = [], o = Object.keys(s[0] || {});
|
|
2511
|
+
for (const a of o.slice(0, t)) {
|
|
2512
|
+
const i = s.map((l) => l[a]);
|
|
2513
|
+
new Set(i.filter((l) => l != null)).size === 1 && n.push({
|
|
2514
|
+
title: `Constant Column: ${a}`,
|
|
2515
|
+
description: `Column "${a}" has only one unique value. Consider removing it.`,
|
|
2516
|
+
type: "recommendation",
|
|
2517
|
+
severity: "warning",
|
|
2518
|
+
confidence: 1,
|
|
2519
|
+
actionable: !0,
|
|
2520
|
+
suggestedActions: [`Remove column "${a}" as it provides no variance`]
|
|
2521
|
+
});
|
|
2522
|
+
const c = i.filter((l) => l == null || l === "").length;
|
|
2523
|
+
c > s.length * 0.2 && n.push({
|
|
2524
|
+
title: `High Missing Rate: ${a}`,
|
|
2525
|
+
description: `Column "${a}" has ${(c / s.length * 100).toFixed(1)}% missing values.`,
|
|
2526
|
+
type: "warning",
|
|
2527
|
+
severity: "warning",
|
|
2528
|
+
confidence: 1,
|
|
2529
|
+
actionable: !0,
|
|
2530
|
+
suggestedActions: [
|
|
2531
|
+
"Impute missing values",
|
|
2532
|
+
"Consider removing this column",
|
|
2533
|
+
"Investigate why data is missing"
|
|
2534
|
+
]
|
|
2535
|
+
});
|
|
2536
|
+
}
|
|
2537
|
+
return n.slice(0, t);
|
|
2538
|
+
}
|
|
2539
|
+
function Wt(s) {
|
|
2540
|
+
const e = Object.keys(s[0] || {}), t = e.filter((n) => s.map((a) => a[n]).some((a) => !isNaN(Number(a))));
|
|
2541
|
+
return `
|
|
2542
|
+
## Statistical Overview
|
|
2543
|
+
|
|
2544
|
+
- Total Rows: ${s.length}
|
|
2545
|
+
- Total Columns: ${e.length}
|
|
2546
|
+
- Numeric Columns: ${t.length}
|
|
2547
|
+
- Categorical Columns: ${e.length - t.length}
|
|
2548
|
+
`.trim();
|
|
2549
|
+
}
|
|
2550
|
+
function Xt(s) {
|
|
2551
|
+
return `
|
|
2552
|
+
## Recommendations
|
|
2553
|
+
|
|
2554
|
+
1. **Data Quality**: Review and clean missing values
|
|
2555
|
+
2. **Feature Engineering**: Create interaction features for better insights
|
|
2556
|
+
3. **Analysis**: Perform correlation analysis to identify relationships
|
|
2557
|
+
4. **Visualization**: Create charts to explore patterns
|
|
2558
|
+
`.trim();
|
|
2559
|
+
}
|
|
2560
|
+
async function Yt(s) {
|
|
2561
|
+
const e = Object.keys(s[0] || {}), t = [];
|
|
2562
|
+
for (const o of e) {
|
|
2563
|
+
const a = s.map((r) => String(r[o])).filter((r) => r && r !== "null" && r !== "undefined"), i = a.slice(0, 5);
|
|
2564
|
+
a.some((r) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(r)) && t.push({
|
|
2565
|
+
column: o,
|
|
2566
|
+
type: "email",
|
|
2567
|
+
confidence: 0.95,
|
|
2568
|
+
sampleValues: i.slice(0, 3).map((r) => Zt(r)),
|
|
2569
|
+
count: a.length
|
|
2570
|
+
}), a.some((r) => /^\+?[\d\s\-()]{10,}$/.test(r)) && t.push({
|
|
2571
|
+
column: o,
|
|
2572
|
+
type: "phone",
|
|
2573
|
+
confidence: 0.85,
|
|
2574
|
+
sampleValues: i.slice(0, 3).map((r) => en(r)),
|
|
2575
|
+
count: a.length
|
|
2576
|
+
}), a.some((r) => /^\d{3}-\d{2}-\d{4}$/.test(r)) && t.push({
|
|
2577
|
+
column: o,
|
|
2578
|
+
type: "ssn",
|
|
2579
|
+
confidence: 0.99,
|
|
2580
|
+
sampleValues: ["***-**-****"],
|
|
2581
|
+
count: a.length
|
|
2582
|
+
}), a.some((r) => /^\d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}$/.test(r)) && t.push({
|
|
2583
|
+
column: o,
|
|
2584
|
+
type: "credit_card",
|
|
2585
|
+
confidence: 0.95,
|
|
2586
|
+
sampleValues: ["****-****-****-****"],
|
|
2587
|
+
count: a.length
|
|
2588
|
+
}), (o.toLowerCase().includes("name") || o.toLowerCase().includes("fullname")) && t.push({
|
|
2589
|
+
column: o,
|
|
2590
|
+
type: "name",
|
|
2591
|
+
confidence: 0.7,
|
|
2592
|
+
sampleValues: i.slice(0, 3).map(() => "[REDACTED]"),
|
|
2593
|
+
count: a.length
|
|
2594
|
+
});
|
|
2595
|
+
}
|
|
2596
|
+
const n = t.length > 5 ? "high" : t.length > 2 ? "medium" : "low";
|
|
2597
|
+
return {
|
|
2598
|
+
piiColumns: t,
|
|
2599
|
+
recommendations: on(t),
|
|
2600
|
+
riskLevel: n
|
|
2601
|
+
};
|
|
2602
|
+
}
|
|
2603
|
+
async function Jn(s, e) {
|
|
2604
|
+
const { method: t, columns: n } = e, o = n || Object.keys(s[0]);
|
|
2605
|
+
return {
|
|
2606
|
+
data: s.map((i) => {
|
|
2607
|
+
const r = { ...i };
|
|
2608
|
+
for (const c of o)
|
|
2609
|
+
r[c] = tn(i[c], t);
|
|
2610
|
+
return r;
|
|
2611
|
+
}),
|
|
2612
|
+
method: t,
|
|
2613
|
+
columns: o,
|
|
2614
|
+
reversible: t === "tokenization",
|
|
2615
|
+
privacyLevel: sn(t)
|
|
2616
|
+
};
|
|
2617
|
+
}
|
|
2618
|
+
async function Bn(s, e) {
|
|
2619
|
+
const t = await Yt(s), n = [];
|
|
2620
|
+
t.piiColumns.length > 0 && n.push({
|
|
2621
|
+
rule: `${e} - PII Protection`,
|
|
2622
|
+
description: `Found ${t.piiColumns.length} columns containing PII`,
|
|
2623
|
+
severity: "critical",
|
|
2624
|
+
affectedColumns: t.piiColumns.map((i) => i.column),
|
|
2625
|
+
remediation: "Implement anonymization or encryption for PII columns"
|
|
2626
|
+
});
|
|
2627
|
+
const o = n.length === 0, a = Math.max(0, 100 - n.length * 20);
|
|
2628
|
+
return {
|
|
2629
|
+
standard: e,
|
|
2630
|
+
compliant: o,
|
|
2631
|
+
score: a,
|
|
2632
|
+
violations: n,
|
|
2633
|
+
recommendations: [
|
|
2634
|
+
"Implement data encryption at rest and in transit",
|
|
2635
|
+
"Add access controls and audit logging",
|
|
2636
|
+
"Create data retention and deletion policies"
|
|
2637
|
+
],
|
|
2638
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
2639
|
+
};
|
|
2640
|
+
}
|
|
2641
|
+
function Zt(s) {
|
|
2642
|
+
const [e, t] = s.split("@");
|
|
2643
|
+
return `${e.slice(0, 2)}***@${t}`;
|
|
2644
|
+
}
|
|
2645
|
+
function en(s) {
|
|
2646
|
+
return s.replace(/\d/g, (e, t) => t < s.length - 4 ? "*" : e);
|
|
2647
|
+
}
|
|
2648
|
+
function tn(s, e) {
|
|
2649
|
+
if (s == null) return s;
|
|
2650
|
+
switch (e) {
|
|
2651
|
+
case "masking":
|
|
2652
|
+
return "***MASKED***";
|
|
2653
|
+
case "hashing":
|
|
2654
|
+
return nn(String(s));
|
|
2655
|
+
case "generalization":
|
|
2656
|
+
return typeof s == "number" ? Math.floor(s / 10) * 10 : "[GENERALIZED]";
|
|
2657
|
+
case "tokenization":
|
|
2658
|
+
return `TOKEN_${Math.random().toString(36).substr(2, 9)}`;
|
|
2659
|
+
default:
|
|
2660
|
+
return s;
|
|
2661
|
+
}
|
|
2662
|
+
}
|
|
2663
|
+
function nn(s) {
|
|
2664
|
+
let e = 0;
|
|
2665
|
+
for (let t = 0; t < s.length; t++) {
|
|
2666
|
+
const n = s.charCodeAt(t);
|
|
2667
|
+
e = (e << 5) - e + n, e = e & e;
|
|
2668
|
+
}
|
|
2669
|
+
return `HASH_${Math.abs(e).toString(16)}`;
|
|
2670
|
+
}
|
|
2671
|
+
function sn(s) {
|
|
2672
|
+
return {
|
|
2673
|
+
masking: 60,
|
|
2674
|
+
hashing: 80,
|
|
2675
|
+
generalization: 50,
|
|
2676
|
+
differential_privacy: 95,
|
|
2677
|
+
tokenization: 70
|
|
2678
|
+
}[s] || 50;
|
|
2679
|
+
}
|
|
2680
|
+
function on(s) {
|
|
2681
|
+
const e = [];
|
|
2682
|
+
return s.length > 0 && (e.push("Implement data anonymization for PII columns"), e.push("Add access controls to restrict PII access"), e.push("Enable audit logging for PII access")), s.some((t) => t.type === "ssn" || t.type === "credit_card") && e.push("CRITICAL: Encrypt sensitive financial/identity data"), e;
|
|
2683
|
+
}
|
|
2684
|
+
const L = /* @__PURE__ */ new Map(), me = /* @__PURE__ */ new Map();
|
|
2685
|
+
async function Hn(s, e) {
|
|
2686
|
+
const t = `snapshot_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`, n = Object.keys(s[0] || {}), o = {
|
|
2687
|
+
id: t,
|
|
2688
|
+
label: e || `Snapshot ${(/* @__PURE__ */ new Date()).toISOString()}`,
|
|
2689
|
+
data: JSON.parse(JSON.stringify(s)),
|
|
2690
|
+
schema: {
|
|
2691
|
+
columns: n.map((a) => ({
|
|
2692
|
+
name: a,
|
|
2693
|
+
type: an(s.map((i) => i[a]))
|
|
2694
|
+
})),
|
|
2695
|
+
rowCount: s.length
|
|
2696
|
+
},
|
|
2697
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
2698
|
+
metadata: {
|
|
2699
|
+
rowCount: s.length,
|
|
2700
|
+
columnCount: n.length,
|
|
2701
|
+
checksum: rn(s)
|
|
2702
|
+
}
|
|
2703
|
+
};
|
|
2704
|
+
return L.set(t, o), o;
|
|
2705
|
+
}
|
|
2706
|
+
async function Ln(s, e) {
|
|
2707
|
+
const t = L.get(s), n = L.get(e);
|
|
2708
|
+
if (!t || !n)
|
|
2709
|
+
throw new Error("Snapshot not found");
|
|
2710
|
+
const o = new Set(t.schema.columns.map((u) => u.name)), a = new Set(n.schema.columns.map((u) => u.name)), i = Array.from(a).filter((u) => !o.has(u)), r = Array.from(o).filter((u) => !a.has(u)), c = n.data.length - t.data.length, l = c < 0 ? Math.abs(c) : 0;
|
|
2711
|
+
return {
|
|
2712
|
+
snapshot1: s,
|
|
2713
|
+
snapshot2: e,
|
|
2714
|
+
changes: {
|
|
2715
|
+
rowsAdded: Math.max(0, c),
|
|
2716
|
+
rowsRemoved: l,
|
|
2717
|
+
rowsModified: 0,
|
|
2718
|
+
// Simplified
|
|
2719
|
+
columnsAdded: i,
|
|
2720
|
+
columnsRemoved: r,
|
|
2721
|
+
columnsModified: []
|
|
2722
|
+
},
|
|
2723
|
+
details: []
|
|
2724
|
+
};
|
|
2725
|
+
}
|
|
2726
|
+
async function Un(s, e) {
|
|
2727
|
+
const t = {
|
|
2728
|
+
source: e,
|
|
2729
|
+
transformations: [],
|
|
2730
|
+
currentState: {
|
|
2731
|
+
rowCount: 0,
|
|
2732
|
+
columnCount: 0,
|
|
2733
|
+
lastModified: /* @__PURE__ */ new Date()
|
|
2734
|
+
}
|
|
2735
|
+
};
|
|
2736
|
+
return me.set(s, t), t;
|
|
2737
|
+
}
|
|
2738
|
+
function Kn(s, e, t) {
|
|
2739
|
+
const n = me.get(s);
|
|
2740
|
+
n && n.transformations.push({
|
|
2741
|
+
operation: e,
|
|
2742
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
2743
|
+
params: t
|
|
2744
|
+
});
|
|
2745
|
+
}
|
|
2746
|
+
async function Gn(s) {
|
|
2747
|
+
return {
|
|
2748
|
+
id: `pipeline_${Date.now()}`,
|
|
2749
|
+
name: "Data Processing Pipeline",
|
|
2750
|
+
steps: s,
|
|
2751
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
2752
|
+
};
|
|
2753
|
+
}
|
|
2754
|
+
async function Wn(s, e) {
|
|
2755
|
+
const t = Date.now();
|
|
2756
|
+
let n = JSON.parse(JSON.stringify(e));
|
|
2757
|
+
const o = [];
|
|
2758
|
+
let a = 0;
|
|
2759
|
+
for (let i = 0; i < s.steps.length; i++) {
|
|
2760
|
+
const r = s.steps[i];
|
|
2761
|
+
try {
|
|
2762
|
+
if (r.condition && !r.condition(n))
|
|
2763
|
+
continue;
|
|
2764
|
+
n = await cn(n, r), a++;
|
|
2765
|
+
} catch (c) {
|
|
2766
|
+
if (o.push({
|
|
2767
|
+
step: i,
|
|
2768
|
+
error: c instanceof Error ? c.message : String(c)
|
|
2769
|
+
}), r.onError === "stop")
|
|
2770
|
+
break;
|
|
2771
|
+
}
|
|
2772
|
+
}
|
|
2773
|
+
return {
|
|
2774
|
+
success: o.length === 0,
|
|
2775
|
+
data: n,
|
|
2776
|
+
stepsExecuted: a,
|
|
2777
|
+
totalSteps: s.steps.length,
|
|
2778
|
+
executionTime: Date.now() - t,
|
|
2779
|
+
errors: o.length > 0 ? o : void 0
|
|
2780
|
+
};
|
|
2781
|
+
}
|
|
2782
|
+
async function Xn(s, e) {
|
|
2783
|
+
console.log(`Pipeline "${e}" saved`);
|
|
2784
|
+
}
|
|
2785
|
+
async function Yn(s) {
|
|
2786
|
+
return {
|
|
2787
|
+
id: "loaded_pipeline",
|
|
2788
|
+
name: s,
|
|
2789
|
+
steps: [],
|
|
2790
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
2791
|
+
};
|
|
2792
|
+
}
|
|
2793
|
+
function an(s) {
|
|
2794
|
+
const e = s.filter((n) => n != null && n !== "");
|
|
2795
|
+
return e.length === 0 ? "string" : e.filter((n) => !isNaN(Number(n))).length / e.length > 0.8 ? "number" : "categorical";
|
|
2796
|
+
}
|
|
2797
|
+
function rn(s) {
|
|
2798
|
+
const e = JSON.stringify(s);
|
|
2799
|
+
let t = 0;
|
|
2800
|
+
for (let n = 0; n < e.length; n++) {
|
|
2801
|
+
const o = e.charCodeAt(n);
|
|
2802
|
+
t = (t << 5) - t + o, t = t & t;
|
|
2803
|
+
}
|
|
2804
|
+
return Math.abs(t).toString(16);
|
|
2805
|
+
}
|
|
2806
|
+
async function cn(s, e) {
|
|
2807
|
+
return s;
|
|
2808
|
+
}
|
|
2809
|
+
async function Zn(s) {
|
|
2810
|
+
const { source: e, url: t, updateInterval: n = 1e3 } = s, o = {
|
|
2811
|
+
id: `stream_${Date.now()}`,
|
|
2812
|
+
source: e,
|
|
2813
|
+
url: t,
|
|
2814
|
+
connected: !1,
|
|
2815
|
+
onData: () => {
|
|
2816
|
+
},
|
|
2817
|
+
onError: () => {
|
|
2818
|
+
},
|
|
2819
|
+
disconnect: () => {
|
|
2820
|
+
o.connected = !1;
|
|
2821
|
+
}
|
|
2822
|
+
};
|
|
2823
|
+
return setTimeout(() => {
|
|
2824
|
+
o.connected = !0;
|
|
2825
|
+
}, 100), o;
|
|
2826
|
+
}
|
|
2827
|
+
async function es(s, e) {
|
|
2828
|
+
const { columns: t, threshold: n, windowSize: o = 100 } = e;
|
|
2829
|
+
console.log(`Monitoring anomalies on columns: ${t.join(", ")}`);
|
|
2830
|
+
}
|
|
2831
|
+
async function ts(s, e) {
|
|
2832
|
+
const { windowType: t, windowSize: n, aggregations: o } = e;
|
|
2833
|
+
console.log(`Streaming aggregation: ${t} window of ${n}`);
|
|
2834
|
+
}
|
|
2835
|
+
async function ns(s, e) {
|
|
2836
|
+
const { columns: t, threshold: n, method: o = "statistical" } = e, a = [];
|
|
2837
|
+
for (const i of t) {
|
|
2838
|
+
const r = s.map((u) => Number(u[i])).filter((u) => !isNaN(u));
|
|
2839
|
+
if (r.length < 10) continue;
|
|
2840
|
+
const c = r.reduce((u, m) => u + m, 0) / r.length, l = Math.sqrt(
|
|
2841
|
+
r.reduce((u, m) => u + Math.pow(m - c, 2), 0) / r.length
|
|
2842
|
+
);
|
|
2843
|
+
s.forEach((u, m) => {
|
|
2844
|
+
const d = Number(u[i]);
|
|
2845
|
+
if (!isNaN(d)) {
|
|
2846
|
+
const f = Math.abs((d - c) / l);
|
|
2847
|
+
f > n && a.push({
|
|
2848
|
+
rowIndex: m,
|
|
2849
|
+
row: u,
|
|
2850
|
+
score: f / 10,
|
|
2851
|
+
// Normalize to 0-1
|
|
2852
|
+
reasons: [`${i} value ${d} is ${f.toFixed(2)} standard deviations from mean`],
|
|
2853
|
+
affectedColumns: [i]
|
|
2854
|
+
});
|
|
2855
|
+
}
|
|
2856
|
+
});
|
|
2857
|
+
}
|
|
2858
|
+
return a;
|
|
2859
|
+
}
|
|
2860
|
+
async function ss(s, e) {
|
|
2861
|
+
const { windowType: t, windowSize: n, aggregations: o } = e, a = [];
|
|
2862
|
+
if (t === "tumbling")
|
|
2863
|
+
for (let i = 0; i < s.length; i += n) {
|
|
2864
|
+
const r = s.slice(i, i + n), c = {};
|
|
2865
|
+
for (const l of o) {
|
|
2866
|
+
const u = r.map((d) => Number(d[l.column])).filter((d) => !isNaN(d));
|
|
2867
|
+
let m = 0;
|
|
2868
|
+
switch (l.function) {
|
|
2869
|
+
case "sum":
|
|
2870
|
+
m = u.reduce((f, h) => f + h, 0);
|
|
2871
|
+
break;
|
|
2872
|
+
case "avg":
|
|
2873
|
+
m = u.reduce((f, h) => f + h, 0) / u.length;
|
|
2874
|
+
break;
|
|
2875
|
+
case "count":
|
|
2876
|
+
m = u.length;
|
|
2877
|
+
break;
|
|
2878
|
+
case "min":
|
|
2879
|
+
m = Math.min(...u);
|
|
2880
|
+
break;
|
|
2881
|
+
case "max":
|
|
2882
|
+
m = Math.max(...u);
|
|
2883
|
+
break;
|
|
2884
|
+
case "std":
|
|
2885
|
+
const d = u.reduce((f, h) => f + h, 0) / u.length;
|
|
2886
|
+
m = Math.sqrt(u.reduce((f, h) => f + Math.pow(h - d, 2), 0) / u.length);
|
|
2887
|
+
break;
|
|
2888
|
+
}
|
|
2889
|
+
c[l.alias || `${l.column}_${l.function}`] = m;
|
|
2890
|
+
}
|
|
2891
|
+
a.push({
|
|
2892
|
+
windowStart: new Date(Date.now() + i * 1e3),
|
|
2893
|
+
windowEnd: new Date(Date.now() + (i + n) * 1e3),
|
|
2894
|
+
results: c,
|
|
2895
|
+
rowCount: r.length
|
|
2896
|
+
});
|
|
2897
|
+
}
|
|
2898
|
+
return a;
|
|
2899
|
+
}
|
|
2900
|
+
async function os(s, e) {
|
|
2901
|
+
const { size: t, method: n, preserveDistribution: o = !0 } = e;
|
|
2902
|
+
let a = [];
|
|
2903
|
+
switch (n) {
|
|
2904
|
+
case "random":
|
|
2905
|
+
a = U(s, t);
|
|
2906
|
+
break;
|
|
2907
|
+
case "systematic":
|
|
2908
|
+
a = ln(s, t);
|
|
2909
|
+
break;
|
|
2910
|
+
case "stratified":
|
|
2911
|
+
a = un(s, t);
|
|
2912
|
+
break;
|
|
2913
|
+
default:
|
|
2914
|
+
a = U(s, t);
|
|
2915
|
+
}
|
|
2916
|
+
return {
|
|
2917
|
+
data: a,
|
|
2918
|
+
method: n,
|
|
2919
|
+
originalSize: s.length,
|
|
2920
|
+
sampleSize: a.length,
|
|
2921
|
+
preservedDistribution: o,
|
|
2922
|
+
representativeness: 0.85
|
|
2923
|
+
// Simplified
|
|
2924
|
+
};
|
|
2925
|
+
}
|
|
2926
|
+
function U(s, e) {
|
|
2927
|
+
return [...s].sort(() => Math.random() - 0.5).slice(0, e);
|
|
2928
|
+
}
|
|
2929
|
+
function ln(s, e) {
|
|
2930
|
+
const t = Math.floor(s.length / e), n = [];
|
|
2931
|
+
for (let o = 0; o < s.length && n.length < e; o += t)
|
|
2932
|
+
n.push(s[o]);
|
|
2933
|
+
return n;
|
|
2934
|
+
}
|
|
2935
|
+
function un(s, e) {
|
|
2936
|
+
return U(s, e);
|
|
2937
|
+
}
|
|
1277
2938
|
export {
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
2939
|
+
pn as AnswerDisplay,
|
|
2940
|
+
Z as QAEngine,
|
|
2941
|
+
gn as QuestionHistory,
|
|
2942
|
+
hn as QuestionInput,
|
|
2943
|
+
Me as TabularIntelligence,
|
|
2944
|
+
Kn as addTransformation,
|
|
2945
|
+
_n as analyzeABTest,
|
|
2946
|
+
Vn as analyzeCrossTables,
|
|
2947
|
+
jt as analyzeFeatureImportance,
|
|
2948
|
+
Jn as anonymizeData,
|
|
2949
|
+
yn as assessDataQuality,
|
|
2950
|
+
In as autoGenerateFeatures,
|
|
2951
|
+
Nn as autoTrain,
|
|
2952
|
+
Rn as calculateSampleSize,
|
|
2953
|
+
ne as calculateStats,
|
|
2954
|
+
ss as calculateWindowedAggregations,
|
|
2955
|
+
Bn as checkCompliance,
|
|
2956
|
+
kn as compareModels,
|
|
2957
|
+
Ln as compareSnapshots,
|
|
2958
|
+
Zn as connectStream,
|
|
2959
|
+
Ie as convertToTabular,
|
|
2960
|
+
Mn as createFeatures,
|
|
2961
|
+
Gn as createPipeline,
|
|
2962
|
+
Hn as createSnapshot,
|
|
2963
|
+
Ce as detectAnomalies,
|
|
2964
|
+
Sn as detectChangePoints,
|
|
2965
|
+
ae as detectDataIssues,
|
|
2966
|
+
Yt as detectPII,
|
|
2967
|
+
En as detectPatterns,
|
|
2968
|
+
Lt as detectRelationships,
|
|
2969
|
+
Tt as detectSeasonality,
|
|
2970
|
+
ns as detectStreamingAnomalies,
|
|
2971
|
+
An as detectTrends,
|
|
2972
|
+
oe as executeAPIRequest,
|
|
2973
|
+
dn as executeMultipleRequests,
|
|
2974
|
+
Wn as executePipeline,
|
|
2975
|
+
qn as explainPrediction,
|
|
2976
|
+
Ae as extractFromDOM,
|
|
2977
|
+
Cn as forecastTimeSeries,
|
|
2978
|
+
V as generateChartSpec,
|
|
2979
|
+
Dn as generateCounterfactuals,
|
|
2980
|
+
Gt as generateExecutiveSummary,
|
|
2981
|
+
Qn as generateInsights,
|
|
2982
|
+
jn as generateReport,
|
|
2983
|
+
Pn as getFeatureImportance,
|
|
2984
|
+
Tn as getPartialDependence,
|
|
2985
|
+
bn as handleOutliers,
|
|
2986
|
+
vn as imputeMissingValues,
|
|
2987
|
+
te as inferColumnType,
|
|
2988
|
+
Fn as inferDatabaseSchema,
|
|
2989
|
+
_ as inferSchema,
|
|
2990
|
+
Ht as joinTables,
|
|
2991
|
+
Yn as loadPipeline,
|
|
2992
|
+
es as monitorAnomalies,
|
|
2993
|
+
Se as normalizeVueData,
|
|
2994
|
+
ke as parsePostmanCollection,
|
|
2995
|
+
W as profileData,
|
|
2996
|
+
zn as recommendVisualizations,
|
|
2997
|
+
D as replaceVariables,
|
|
2998
|
+
Xn as savePipeline,
|
|
2999
|
+
xn as selectBestFeatures,
|
|
3000
|
+
os as smartSample,
|
|
3001
|
+
ts as streamingAggregation,
|
|
3002
|
+
wn as suggestCleaningSteps,
|
|
3003
|
+
On as testSignificance,
|
|
3004
|
+
Un as trackLineage,
|
|
3005
|
+
$n as tuneHyperparameters,
|
|
3006
|
+
fn as useTabularIntelligence
|
|
1295
3007
|
};
|
|
1296
3008
|
//# sourceMappingURL=index.mjs.map
|