@uwdata/mosaic-inputs 0.0.1
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 +3 -0
- package/dist/mosaic-inputs.js +1299 -0
- package/dist/mosaic-inputs.min.js +1 -0
- package/package.json +32 -0
- package/src/Menu.js +104 -0
- package/src/Search.js +104 -0
- package/src/Slider.js +70 -0
- package/src/Table.js +210 -0
- package/src/index.js +4 -0
- package/src/util/format.js +47 -0
|
@@ -0,0 +1,1299 @@
|
|
|
1
|
+
// ../core/src/MosaicClient.js
|
|
2
|
+
var MosaicClient = class {
|
|
3
|
+
constructor(filterSelection) {
|
|
4
|
+
this._filterBy = filterSelection;
|
|
5
|
+
}
|
|
6
|
+
get filterBy() {
|
|
7
|
+
return this._filterBy;
|
|
8
|
+
}
|
|
9
|
+
get filterIndexable() {
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
fields() {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
fieldStats() {
|
|
16
|
+
return this;
|
|
17
|
+
}
|
|
18
|
+
query() {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
queryPending() {
|
|
22
|
+
return this;
|
|
23
|
+
}
|
|
24
|
+
queryResult() {
|
|
25
|
+
return this;
|
|
26
|
+
}
|
|
27
|
+
queryError(error) {
|
|
28
|
+
console.error(error);
|
|
29
|
+
return this;
|
|
30
|
+
}
|
|
31
|
+
update() {
|
|
32
|
+
return this;
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// ../sql/src/ref.js
|
|
37
|
+
var Ref = class {
|
|
38
|
+
constructor(table, column2) {
|
|
39
|
+
if (table)
|
|
40
|
+
this.table = String(table);
|
|
41
|
+
if (column2)
|
|
42
|
+
this.column = column2;
|
|
43
|
+
}
|
|
44
|
+
get columns() {
|
|
45
|
+
return this.column ? [this.column] : [];
|
|
46
|
+
}
|
|
47
|
+
toString() {
|
|
48
|
+
const { table, column: column2 } = this;
|
|
49
|
+
if (column2) {
|
|
50
|
+
const col = column2 === "*" ? column2 : `"${column2}"`;
|
|
51
|
+
return (table ? `"${table}".` : "") + col;
|
|
52
|
+
} else {
|
|
53
|
+
return `"${table}"`;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
function isColumnRefFor(ref, name) {
|
|
58
|
+
return ref instanceof Ref && ref.column === name;
|
|
59
|
+
}
|
|
60
|
+
function asColumn(value) {
|
|
61
|
+
return typeof value === "string" ? column(value) : value;
|
|
62
|
+
}
|
|
63
|
+
function asRelation(value) {
|
|
64
|
+
return typeof value === "string" ? relation(value) : value;
|
|
65
|
+
}
|
|
66
|
+
function relation(name) {
|
|
67
|
+
return new Ref(name);
|
|
68
|
+
}
|
|
69
|
+
function column(table, column2) {
|
|
70
|
+
return arguments.length === 1 ? new Ref(null, table) : new Ref(table, column2);
|
|
71
|
+
}
|
|
72
|
+
function desc(expr2) {
|
|
73
|
+
expr2 = asColumn(expr2);
|
|
74
|
+
return {
|
|
75
|
+
expr: expr2,
|
|
76
|
+
desc: true,
|
|
77
|
+
toString: () => `${expr2} DESC NULLS LAST`,
|
|
78
|
+
get columns() {
|
|
79
|
+
return expr2.columns?.() || [];
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
function expr(sql, columns, label) {
|
|
84
|
+
return {
|
|
85
|
+
expr: sql,
|
|
86
|
+
label,
|
|
87
|
+
toString: () => `${sql}`,
|
|
88
|
+
get columns() {
|
|
89
|
+
return columns || [];
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
function transform(func2, label) {
|
|
94
|
+
return (value) => expr(
|
|
95
|
+
func2(value),
|
|
96
|
+
asColumn(value).columns,
|
|
97
|
+
label
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// ../sql/src/to-sql.js
|
|
102
|
+
function toSQL(value) {
|
|
103
|
+
return typeof value === "string" ? `"${value}"` : literalToSQL(value);
|
|
104
|
+
}
|
|
105
|
+
function literalToSQL(value) {
|
|
106
|
+
switch (typeof value) {
|
|
107
|
+
case "boolean":
|
|
108
|
+
return value ? "TRUE" : "FALSE";
|
|
109
|
+
case "string":
|
|
110
|
+
return `'${value}'`;
|
|
111
|
+
default:
|
|
112
|
+
if (value == null) {
|
|
113
|
+
return "NULL";
|
|
114
|
+
} else if (value instanceof Date) {
|
|
115
|
+
return `MAKE_DATE(${value.getUTCFullYear()}, ${value.getUTCMonth() + 1}, ${value.getUTCDate()})`;
|
|
116
|
+
} else if (value instanceof RegExp) {
|
|
117
|
+
return `'${value.source}'`;
|
|
118
|
+
} else {
|
|
119
|
+
return String(value);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// ../sql/src/literal.js
|
|
125
|
+
var Literal = class {
|
|
126
|
+
constructor(value) {
|
|
127
|
+
this.value = value;
|
|
128
|
+
}
|
|
129
|
+
toString() {
|
|
130
|
+
return literalToSQL(this.value);
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
var literal = (value) => new Literal(value);
|
|
134
|
+
|
|
135
|
+
// ../sql/src/compare.js
|
|
136
|
+
function extractColumns(...args) {
|
|
137
|
+
return args.flat().flatMap((arg) => arg?.columns || []);
|
|
138
|
+
}
|
|
139
|
+
var Compare1 = class {
|
|
140
|
+
constructor(op, a) {
|
|
141
|
+
this.op = op;
|
|
142
|
+
this.a = asColumn(a);
|
|
143
|
+
}
|
|
144
|
+
get columns() {
|
|
145
|
+
return extractColumns(this.a);
|
|
146
|
+
}
|
|
147
|
+
visit(callback) {
|
|
148
|
+
callback(this.op, this);
|
|
149
|
+
}
|
|
150
|
+
toString() {
|
|
151
|
+
const { op, a } = this;
|
|
152
|
+
return `(${toSQL(a)} ${op})`;
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
function compare1(op) {
|
|
156
|
+
return (a) => new Compare1(op, a);
|
|
157
|
+
}
|
|
158
|
+
var not = compare1("NOT");
|
|
159
|
+
var isNull = compare1("IS NULL");
|
|
160
|
+
var isNotNull = compare1("IS NOT NULL");
|
|
161
|
+
var Compare2 = class {
|
|
162
|
+
constructor(op, a, b) {
|
|
163
|
+
this.op = op;
|
|
164
|
+
this.a = asColumn(a);
|
|
165
|
+
this.b = asColumn(b);
|
|
166
|
+
}
|
|
167
|
+
get columns() {
|
|
168
|
+
return extractColumns(this.a, this.b);
|
|
169
|
+
}
|
|
170
|
+
visit(callback) {
|
|
171
|
+
callback(this.op, this);
|
|
172
|
+
}
|
|
173
|
+
toString() {
|
|
174
|
+
const { op, a, b } = this;
|
|
175
|
+
return `(${toSQL(a)} ${op} ${toSQL(b)})`;
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
function compare2(op) {
|
|
179
|
+
return (a, b) => new Compare2(op, a, b);
|
|
180
|
+
}
|
|
181
|
+
var eq = compare2("=");
|
|
182
|
+
var neq = compare2("<>");
|
|
183
|
+
var lt = compare2("<");
|
|
184
|
+
var gt = compare2(">");
|
|
185
|
+
var lte = compare2("<=");
|
|
186
|
+
var gte = compare2(">=");
|
|
187
|
+
var isDistinct = compare2("IS DISTINCT FROM");
|
|
188
|
+
var isNotDistinct = compare2("IS NOT DISTINCT FROM");
|
|
189
|
+
var Range = class {
|
|
190
|
+
constructor(op, expr2, value) {
|
|
191
|
+
this.op = op;
|
|
192
|
+
this.expr = asColumn(expr2);
|
|
193
|
+
this.value = value?.map(asColumn);
|
|
194
|
+
}
|
|
195
|
+
get columns() {
|
|
196
|
+
return extractColumns(this.expr, this.value);
|
|
197
|
+
}
|
|
198
|
+
visit(callback) {
|
|
199
|
+
callback(this.op, this);
|
|
200
|
+
}
|
|
201
|
+
toString() {
|
|
202
|
+
const { op, expr: expr2, value } = this;
|
|
203
|
+
if (!value)
|
|
204
|
+
return "";
|
|
205
|
+
const [a, b] = value;
|
|
206
|
+
return `(${toSQL(expr2)} ${op} ${toSQL(a)} AND ${toSQL(b)})`;
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
function range(op) {
|
|
210
|
+
return (a, range2) => new Range(op, a, range2);
|
|
211
|
+
}
|
|
212
|
+
var isBetween = range("BETWEEN");
|
|
213
|
+
var isNotBetween = range("NOT BETWEEN");
|
|
214
|
+
var CompareN = class {
|
|
215
|
+
constructor(op, value) {
|
|
216
|
+
this.op = op;
|
|
217
|
+
this.value = value.map(asColumn);
|
|
218
|
+
}
|
|
219
|
+
get columns() {
|
|
220
|
+
return extractColumns(this.value);
|
|
221
|
+
}
|
|
222
|
+
visit(callback) {
|
|
223
|
+
callback(this.op, this);
|
|
224
|
+
this.value?.forEach((v) => v.visit(callback));
|
|
225
|
+
}
|
|
226
|
+
toString() {
|
|
227
|
+
const { op, value } = this;
|
|
228
|
+
return !value || value.length === 0 ? "" : value.length === 1 ? toSQL(value[0]) : `(${value.map(toSQL).filter((x) => x).join(` ${op} `)})`;
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
function or(...clauses) {
|
|
232
|
+
return new CompareN("OR", clauses.flat());
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// ../sql/src/function-call.js
|
|
236
|
+
var FunctionCall = class {
|
|
237
|
+
constructor(func2, args) {
|
|
238
|
+
this.func = func2;
|
|
239
|
+
this.args = (args || []).map(asColumn);
|
|
240
|
+
}
|
|
241
|
+
get column() {
|
|
242
|
+
return this.columns[0];
|
|
243
|
+
}
|
|
244
|
+
get columns() {
|
|
245
|
+
return this.args.flatMap((a) => a.columns || []);
|
|
246
|
+
}
|
|
247
|
+
toString() {
|
|
248
|
+
const { func: func2, args } = this;
|
|
249
|
+
return `${func2}(${args.map(toSQL).join(", ")})`;
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
function func(op) {
|
|
253
|
+
return (...args) => new FunctionCall(op, args);
|
|
254
|
+
}
|
|
255
|
+
var regexp_matches = func("regexp_matches");
|
|
256
|
+
var contains = func("contains");
|
|
257
|
+
var prefix = func("prefix");
|
|
258
|
+
var suffix = func("suffix");
|
|
259
|
+
var lower = func("lower");
|
|
260
|
+
var upper = func("upper");
|
|
261
|
+
var length = func("length");
|
|
262
|
+
var isNaN2 = func("isnan");
|
|
263
|
+
var isFinite = func("isfinite");
|
|
264
|
+
var isInfinite = func("isinf");
|
|
265
|
+
|
|
266
|
+
// ../sql/src/aggregate.js
|
|
267
|
+
var Aggregate = class {
|
|
268
|
+
constructor(op, args) {
|
|
269
|
+
this.aggregate = op;
|
|
270
|
+
this.args = (args || []).map(asColumn);
|
|
271
|
+
}
|
|
272
|
+
get label() {
|
|
273
|
+
return this.aggregate.toLowerCase() + (this.args.length ? ` ${this.columns.join(", ")}` : "");
|
|
274
|
+
}
|
|
275
|
+
get column() {
|
|
276
|
+
return this.columns[0];
|
|
277
|
+
}
|
|
278
|
+
get columns() {
|
|
279
|
+
return this.args.flatMap((a) => a.columns || []);
|
|
280
|
+
}
|
|
281
|
+
distinct() {
|
|
282
|
+
this.isDistinct = true;
|
|
283
|
+
return this;
|
|
284
|
+
}
|
|
285
|
+
where(expr2) {
|
|
286
|
+
this.filter = expr2;
|
|
287
|
+
return this;
|
|
288
|
+
}
|
|
289
|
+
toString() {
|
|
290
|
+
const { aggregate, args, isDistinct: isDistinct2, filter } = this;
|
|
291
|
+
const arg = args.length === 0 ? "*" : args.map(toSQL).join(", ");
|
|
292
|
+
const distinct = isDistinct2 ? "DISTINCT " : "";
|
|
293
|
+
const where = filter ? ` FILTER (WHERE ${toSQL(filter)})` : "";
|
|
294
|
+
const cast = aggregate === "COUNT" ? "::INTEGER" : "";
|
|
295
|
+
return where && cast ? `(${aggregate}(${distinct}${arg})${where})${cast}` : `${aggregate}(${distinct}${arg})${where}${cast}`;
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
function agg(op) {
|
|
299
|
+
return (...args) => new Aggregate(op, args);
|
|
300
|
+
}
|
|
301
|
+
var count = agg("COUNT");
|
|
302
|
+
var avg = agg("AVG");
|
|
303
|
+
var mean = agg("AVG");
|
|
304
|
+
var mad = agg("MAD");
|
|
305
|
+
var max = agg("MAX");
|
|
306
|
+
var min = agg("MIN");
|
|
307
|
+
var sum = agg("SUM");
|
|
308
|
+
var product = agg("PRODUCT");
|
|
309
|
+
var median = agg("MEDIAN");
|
|
310
|
+
var quantile = agg("QUANTILE");
|
|
311
|
+
var mode = agg("MODE");
|
|
312
|
+
var variance = agg("VARIANCE");
|
|
313
|
+
var stddev = agg("STDDEV");
|
|
314
|
+
var skewness = agg("SKEWNESS");
|
|
315
|
+
var kurtosis = agg("KURTOSIS");
|
|
316
|
+
var entropy = agg("ENTROPY");
|
|
317
|
+
var varPop = agg("VAR_POP");
|
|
318
|
+
var stddevPop = agg("STDDEV_POP");
|
|
319
|
+
var corr = agg("CORR");
|
|
320
|
+
var covarPop = agg("COVAR_POP");
|
|
321
|
+
var regrIntercept = agg("REGR_INTERCEPT");
|
|
322
|
+
var regrSlope = agg("REGR_SLOPE");
|
|
323
|
+
var regrCount = agg("REGR_COUNT");
|
|
324
|
+
var regrR2 = agg("REGR_R2");
|
|
325
|
+
var regrSYY = agg("REGR_SYY");
|
|
326
|
+
var regrSXX = agg("REGR_SXX");
|
|
327
|
+
var regrSXY = agg("REGR_SXY");
|
|
328
|
+
var regrAvgX = agg("REGR_AVGX");
|
|
329
|
+
var regrAvgY = agg("REGR_AVGY");
|
|
330
|
+
var first = agg("FIRST");
|
|
331
|
+
var last = agg("LAST");
|
|
332
|
+
var argmin = agg("ARG_MIN");
|
|
333
|
+
var argmax = agg("ARG_MAX");
|
|
334
|
+
var stringAgg = agg("STRING_AGG");
|
|
335
|
+
var arrayAgg = agg("ARRAY_AGG");
|
|
336
|
+
|
|
337
|
+
// ../sql/src/datetime.js
|
|
338
|
+
var epoch_ms = transform(
|
|
339
|
+
(d) => `(1000 * (epoch(${d}) - second(${d})) + millisecond(${d}))::DOUBLE`
|
|
340
|
+
);
|
|
341
|
+
|
|
342
|
+
// ../sql/src/Query.js
|
|
343
|
+
var Query = class {
|
|
344
|
+
static select(...expr2) {
|
|
345
|
+
return new Query().select(...expr2);
|
|
346
|
+
}
|
|
347
|
+
static from(...expr2) {
|
|
348
|
+
return new Query().from(...expr2);
|
|
349
|
+
}
|
|
350
|
+
static with(...expr2) {
|
|
351
|
+
return new Query().with(...expr2);
|
|
352
|
+
}
|
|
353
|
+
static union(...queries) {
|
|
354
|
+
return new SetOperation("UNION", queries.flat());
|
|
355
|
+
}
|
|
356
|
+
static unionAll(...queries) {
|
|
357
|
+
return new SetOperation("UNION ALL", queries.flat());
|
|
358
|
+
}
|
|
359
|
+
static intersect(...queries) {
|
|
360
|
+
return new SetOperation("INTERSECT", queries.flat());
|
|
361
|
+
}
|
|
362
|
+
static except(...queries) {
|
|
363
|
+
return new SetOperation("EXCEPT", queries.flat());
|
|
364
|
+
}
|
|
365
|
+
constructor() {
|
|
366
|
+
this.query = {
|
|
367
|
+
with: [],
|
|
368
|
+
select: [],
|
|
369
|
+
from: [],
|
|
370
|
+
where: [],
|
|
371
|
+
groupby: [],
|
|
372
|
+
having: [],
|
|
373
|
+
window: [],
|
|
374
|
+
qualify: [],
|
|
375
|
+
orderby: []
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
clone() {
|
|
379
|
+
const q = new Query();
|
|
380
|
+
q.query = { ...this.query };
|
|
381
|
+
return q;
|
|
382
|
+
}
|
|
383
|
+
with(...expr2) {
|
|
384
|
+
const { query } = this;
|
|
385
|
+
if (expr2.length === 0) {
|
|
386
|
+
return query.with;
|
|
387
|
+
} else {
|
|
388
|
+
const list = [];
|
|
389
|
+
const add = (as, q) => {
|
|
390
|
+
const query2 = q.clone();
|
|
391
|
+
query2.cteFor = this;
|
|
392
|
+
list.push({ as, query: query2 });
|
|
393
|
+
};
|
|
394
|
+
expr2.flat().forEach((e) => {
|
|
395
|
+
if (e == null) {
|
|
396
|
+
} else if (e.as && e.query) {
|
|
397
|
+
add(e.as, e.query);
|
|
398
|
+
} else {
|
|
399
|
+
for (const as in e) {
|
|
400
|
+
add(as, e[as]);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
});
|
|
404
|
+
query.with = query.with.concat(list);
|
|
405
|
+
return this;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
select(...expr2) {
|
|
409
|
+
const { query } = this;
|
|
410
|
+
if (expr2.length === 0) {
|
|
411
|
+
return query.select;
|
|
412
|
+
} else {
|
|
413
|
+
const list = [];
|
|
414
|
+
expr2.flat().forEach((e) => {
|
|
415
|
+
if (e == null) {
|
|
416
|
+
} else if (typeof e === "string") {
|
|
417
|
+
list.push({ as: e, expr: asColumn(e) });
|
|
418
|
+
} else if (e instanceof Ref) {
|
|
419
|
+
list.push({ as: e.column, expr: e });
|
|
420
|
+
} else if (Array.isArray(e)) {
|
|
421
|
+
list.push({ as: e[0], expr: e[1] });
|
|
422
|
+
} else {
|
|
423
|
+
for (const as in e) {
|
|
424
|
+
list.push({ as: unquote(as), expr: asColumn(e[as]) });
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
});
|
|
428
|
+
query.select = query.select.concat(list);
|
|
429
|
+
return this;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
$select(...expr2) {
|
|
433
|
+
this.query.select = [];
|
|
434
|
+
return this.select(...expr2);
|
|
435
|
+
}
|
|
436
|
+
distinct(value = true) {
|
|
437
|
+
this.query.distinct = !!value;
|
|
438
|
+
return this;
|
|
439
|
+
}
|
|
440
|
+
from(...expr2) {
|
|
441
|
+
const { query } = this;
|
|
442
|
+
if (expr2.length === 0) {
|
|
443
|
+
return query.from;
|
|
444
|
+
} else {
|
|
445
|
+
const list = [];
|
|
446
|
+
expr2.flat().forEach((e) => {
|
|
447
|
+
if (e == null) {
|
|
448
|
+
} else if (typeof e === "string") {
|
|
449
|
+
list.push({ as: e, from: asRelation(e) });
|
|
450
|
+
} else if (e instanceof Ref) {
|
|
451
|
+
list.push({ as: e.table, from: e });
|
|
452
|
+
} else if (isQuery(e) || Object.hasOwn(e, "toString")) {
|
|
453
|
+
list.push({ from: e });
|
|
454
|
+
} else if (Array.isArray(e)) {
|
|
455
|
+
list.push({ as: unquote(e[0]), from: asRelation(e[1]) });
|
|
456
|
+
} else {
|
|
457
|
+
for (const as in e) {
|
|
458
|
+
list.push({ as: unquote(as), from: asRelation(e[as]) });
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
});
|
|
462
|
+
query.from = query.from.concat(list);
|
|
463
|
+
return this;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
$from(...expr2) {
|
|
467
|
+
this.query.from = [];
|
|
468
|
+
return this.from(...expr2);
|
|
469
|
+
}
|
|
470
|
+
sample(value) {
|
|
471
|
+
const { query } = this;
|
|
472
|
+
if (arguments.length === 0) {
|
|
473
|
+
return query.sample;
|
|
474
|
+
} else {
|
|
475
|
+
let spec = value;
|
|
476
|
+
if (typeof value === "number") {
|
|
477
|
+
spec = value > 0 && value < 1 ? { perc: 100 * value } : { rows: Math.round(value) };
|
|
478
|
+
}
|
|
479
|
+
query.sample = spec;
|
|
480
|
+
return this;
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
where(...expr2) {
|
|
484
|
+
const { query } = this;
|
|
485
|
+
if (expr2.length === 0) {
|
|
486
|
+
return query.where;
|
|
487
|
+
} else {
|
|
488
|
+
query.where = query.where.concat(
|
|
489
|
+
expr2.flat().filter((x) => x)
|
|
490
|
+
);
|
|
491
|
+
return this;
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
$where(...expr2) {
|
|
495
|
+
this.query.where = [];
|
|
496
|
+
return this.where(...expr2);
|
|
497
|
+
}
|
|
498
|
+
groupby(...expr2) {
|
|
499
|
+
const { query } = this;
|
|
500
|
+
if (expr2.length === 0) {
|
|
501
|
+
return query.groupby;
|
|
502
|
+
} else {
|
|
503
|
+
query.groupby = query.groupby.concat(
|
|
504
|
+
expr2.flat().filter((x) => x).map(asColumn)
|
|
505
|
+
);
|
|
506
|
+
return this;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
having(...expr2) {
|
|
510
|
+
const { query } = this;
|
|
511
|
+
if (expr2.length === 0) {
|
|
512
|
+
return query.having;
|
|
513
|
+
} else {
|
|
514
|
+
query.having = query.having.concat(
|
|
515
|
+
expr2.flat().filter((x) => x)
|
|
516
|
+
);
|
|
517
|
+
return this;
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
window(...expr2) {
|
|
521
|
+
const { query } = this;
|
|
522
|
+
if (expr2.length === 0) {
|
|
523
|
+
return query.window;
|
|
524
|
+
} else {
|
|
525
|
+
const list = [];
|
|
526
|
+
expr2.flat().forEach((e) => {
|
|
527
|
+
if (e == null) {
|
|
528
|
+
} else {
|
|
529
|
+
for (const as in e) {
|
|
530
|
+
list.push({ as: unquote(as), expr: e[as] });
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
});
|
|
534
|
+
query.window = query.window.concat(list);
|
|
535
|
+
return this;
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
qualify(...expr2) {
|
|
539
|
+
const { query } = this;
|
|
540
|
+
if (expr2.length === 0) {
|
|
541
|
+
return query.qualify;
|
|
542
|
+
} else {
|
|
543
|
+
query.qualify = query.qualify.concat(
|
|
544
|
+
expr2.flat().filter((x) => x)
|
|
545
|
+
);
|
|
546
|
+
return this;
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
orderby(...expr2) {
|
|
550
|
+
const { query } = this;
|
|
551
|
+
if (expr2.length === 0) {
|
|
552
|
+
return query.orderby;
|
|
553
|
+
} else {
|
|
554
|
+
query.orderby = query.orderby.concat(
|
|
555
|
+
expr2.flat().filter((x) => x).map(asColumn)
|
|
556
|
+
);
|
|
557
|
+
return this;
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
limit(value) {
|
|
561
|
+
const { query } = this;
|
|
562
|
+
if (arguments.length === 0) {
|
|
563
|
+
return query.limit;
|
|
564
|
+
} else {
|
|
565
|
+
query.limit = Number.isFinite(value) ? value : void 0;
|
|
566
|
+
return this;
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
offset(value) {
|
|
570
|
+
const { query } = this;
|
|
571
|
+
if (arguments.length === 0) {
|
|
572
|
+
return query.offset;
|
|
573
|
+
} else {
|
|
574
|
+
query.offset = Number.isFinite(value) ? value : void 0;
|
|
575
|
+
return this;
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
get subqueries() {
|
|
579
|
+
const { query, cteFor } = this;
|
|
580
|
+
const ctes = (cteFor?.query || query).with;
|
|
581
|
+
const cte = ctes?.reduce((o, { as, query: query2 }) => (o[as] = query2, o), {});
|
|
582
|
+
const q = [];
|
|
583
|
+
query.from.forEach(({ from }) => {
|
|
584
|
+
if (isQuery(from)) {
|
|
585
|
+
q.push(from);
|
|
586
|
+
} else if (cte[from.table]) {
|
|
587
|
+
const sub = cte[from.table];
|
|
588
|
+
q.push(sub);
|
|
589
|
+
}
|
|
590
|
+
});
|
|
591
|
+
return q;
|
|
592
|
+
}
|
|
593
|
+
toString() {
|
|
594
|
+
const {
|
|
595
|
+
select,
|
|
596
|
+
distinct,
|
|
597
|
+
from,
|
|
598
|
+
sample,
|
|
599
|
+
where,
|
|
600
|
+
groupby,
|
|
601
|
+
having,
|
|
602
|
+
window,
|
|
603
|
+
qualify,
|
|
604
|
+
orderby,
|
|
605
|
+
limit,
|
|
606
|
+
offset,
|
|
607
|
+
with: cte
|
|
608
|
+
} = this.query;
|
|
609
|
+
const sql = [];
|
|
610
|
+
if (cte.length) {
|
|
611
|
+
const list = cte.map(({ as, query }) => `"${as}" AS (${query})`);
|
|
612
|
+
sql.push(`WITH ${list.join(", ")}`);
|
|
613
|
+
}
|
|
614
|
+
const sels = select.map(
|
|
615
|
+
({ as, expr: expr2 }) => isColumnRefFor(expr2, as) && !expr2.table ? `${expr2}` : `${expr2} AS "${as}"`
|
|
616
|
+
);
|
|
617
|
+
sql.push(`SELECT${distinct ? " DISTINCT" : ""} ${sels.join(", ")}`);
|
|
618
|
+
if (from.length) {
|
|
619
|
+
const rels = from.map(({ as, from: from2 }) => {
|
|
620
|
+
const rel = isQuery(from2) ? `(${from2})` : `${from2}`;
|
|
621
|
+
return !as || as === from2.table ? rel : `${rel} AS "${as}"`;
|
|
622
|
+
});
|
|
623
|
+
sql.push(`FROM ${rels.join(", ")}`);
|
|
624
|
+
}
|
|
625
|
+
if (sample) {
|
|
626
|
+
const { rows, perc, method, seed } = sample;
|
|
627
|
+
const size = rows ? `${rows} ROWS` : `${perc} PERCENT`;
|
|
628
|
+
const how = method ? ` (${method}${seed != null ? `, ${seed}` : ""})` : "";
|
|
629
|
+
sql.push(`USING SAMPLE ${size}${how}`);
|
|
630
|
+
}
|
|
631
|
+
if (where.length) {
|
|
632
|
+
const clauses = where.map(String).filter((x) => x).join(" AND ");
|
|
633
|
+
if (clauses)
|
|
634
|
+
sql.push(`WHERE ${clauses}`);
|
|
635
|
+
}
|
|
636
|
+
if (groupby.length) {
|
|
637
|
+
sql.push(`GROUP BY ${groupby.join(", ")}`);
|
|
638
|
+
}
|
|
639
|
+
if (having.length) {
|
|
640
|
+
const clauses = having.map(String).filter((x) => x).join(" AND ");
|
|
641
|
+
if (clauses)
|
|
642
|
+
sql.push(`HAVING ${clauses}`);
|
|
643
|
+
}
|
|
644
|
+
if (window.length) {
|
|
645
|
+
const windows = window.map(({ as, expr: expr2 }) => `"${as}" AS (${expr2})`);
|
|
646
|
+
sql.push(`WINDOW ${windows.join(", ")}`);
|
|
647
|
+
}
|
|
648
|
+
if (qualify.length) {
|
|
649
|
+
const clauses = qualify.map(String).filter((x) => x).join(" AND ");
|
|
650
|
+
if (clauses)
|
|
651
|
+
sql.push(`QUALIFY ${clauses}`);
|
|
652
|
+
}
|
|
653
|
+
if (orderby.length) {
|
|
654
|
+
sql.push(`ORDER BY ${orderby.join(", ")}`);
|
|
655
|
+
}
|
|
656
|
+
if (Number.isFinite(limit)) {
|
|
657
|
+
sql.push(`LIMIT ${limit}`);
|
|
658
|
+
}
|
|
659
|
+
if (Number.isFinite(offset)) {
|
|
660
|
+
sql.push(`OFFSET ${offset}`);
|
|
661
|
+
}
|
|
662
|
+
return sql.join(" ");
|
|
663
|
+
}
|
|
664
|
+
};
|
|
665
|
+
var SetOperation = class {
|
|
666
|
+
constructor(op, queries) {
|
|
667
|
+
this.op = op;
|
|
668
|
+
this.queries = queries.map((q) => q.clone());
|
|
669
|
+
this.query = { orderby: [] };
|
|
670
|
+
}
|
|
671
|
+
clone() {
|
|
672
|
+
const q = new SetOperation(this.op, this.queries);
|
|
673
|
+
q.query = { ...this.query };
|
|
674
|
+
return q;
|
|
675
|
+
}
|
|
676
|
+
orderby(...expr2) {
|
|
677
|
+
const { query } = this;
|
|
678
|
+
if (expr2.length === 0) {
|
|
679
|
+
return query.orderby;
|
|
680
|
+
} else {
|
|
681
|
+
query.orderby = query.orderby.concat(
|
|
682
|
+
expr2.flat().filter((x) => x).map(asColumn)
|
|
683
|
+
);
|
|
684
|
+
return this;
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
limit(value) {
|
|
688
|
+
const { query } = this;
|
|
689
|
+
if (arguments.length === 0) {
|
|
690
|
+
return query.limit;
|
|
691
|
+
} else {
|
|
692
|
+
query.limit = Number.isFinite(value) ? value : void 0;
|
|
693
|
+
return this;
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
offset(value) {
|
|
697
|
+
const { query } = this;
|
|
698
|
+
if (arguments.length === 0) {
|
|
699
|
+
return query.offset;
|
|
700
|
+
} else {
|
|
701
|
+
query.offset = Number.isFinite(value) ? value : void 0;
|
|
702
|
+
return this;
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
get subqueries() {
|
|
706
|
+
const { queries, cteFor } = this;
|
|
707
|
+
if (cteFor)
|
|
708
|
+
queries.forEach((q) => q.cteFor = cteFor);
|
|
709
|
+
return queries;
|
|
710
|
+
}
|
|
711
|
+
toString() {
|
|
712
|
+
const { op, queries, query: { orderby, limit, offset } } = this;
|
|
713
|
+
const sql = [queries.join(` ${op} `)];
|
|
714
|
+
if (orderby.length) {
|
|
715
|
+
sql.push(`ORDER BY ${orderby.join(", ")}`);
|
|
716
|
+
}
|
|
717
|
+
if (Number.isFinite(limit)) {
|
|
718
|
+
sql.push(`LIMIT ${limit}`);
|
|
719
|
+
}
|
|
720
|
+
if (Number.isFinite(offset)) {
|
|
721
|
+
sql.push(`OFFSET ${offset}`);
|
|
722
|
+
}
|
|
723
|
+
return sql.join(" ");
|
|
724
|
+
}
|
|
725
|
+
};
|
|
726
|
+
function isQuery(value) {
|
|
727
|
+
return value instanceof Query || value instanceof SetOperation;
|
|
728
|
+
}
|
|
729
|
+
function unquote(s) {
|
|
730
|
+
return isDoubleQuoted(s) ? s.slice(1, -1) : s;
|
|
731
|
+
}
|
|
732
|
+
function isDoubleQuoted(s) {
|
|
733
|
+
return s[0] === '"' && s[s.length - 1] === '"';
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
// ../core/src/util/skip-client.js
|
|
737
|
+
function skipClient(client, clause) {
|
|
738
|
+
return clause?.clients?.has(client);
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
// ../core/src/Signal.js
|
|
742
|
+
function isSignal(x) {
|
|
743
|
+
return x instanceof Signal;
|
|
744
|
+
}
|
|
745
|
+
var Signal = class {
|
|
746
|
+
constructor(value) {
|
|
747
|
+
this._value = value;
|
|
748
|
+
this._listeners = /* @__PURE__ */ new Map();
|
|
749
|
+
}
|
|
750
|
+
get value() {
|
|
751
|
+
return this._value;
|
|
752
|
+
}
|
|
753
|
+
update(value, { force } = {}) {
|
|
754
|
+
const changed = this._value !== value;
|
|
755
|
+
if (changed)
|
|
756
|
+
this._value = value;
|
|
757
|
+
if (changed || force)
|
|
758
|
+
this.emit("value", this.value);
|
|
759
|
+
return this;
|
|
760
|
+
}
|
|
761
|
+
addEventListener(type, callback) {
|
|
762
|
+
let list = this._listeners.get(type) || [];
|
|
763
|
+
if (list.indexOf(callback) < 0) {
|
|
764
|
+
list = list.concat(callback);
|
|
765
|
+
}
|
|
766
|
+
this._listeners.set(type, list);
|
|
767
|
+
}
|
|
768
|
+
removeEventListener(type, callback) {
|
|
769
|
+
const list = this._listeners.get(type);
|
|
770
|
+
if (list?.length) {
|
|
771
|
+
this._listeners.set(type, list.filter((x) => x !== callback));
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
emit(type, event) {
|
|
775
|
+
this._listeners.get(type)?.forEach((l) => l(event));
|
|
776
|
+
}
|
|
777
|
+
};
|
|
778
|
+
|
|
779
|
+
// ../core/src/Selection.js
|
|
780
|
+
function isSelection(x) {
|
|
781
|
+
return x instanceof Selection;
|
|
782
|
+
}
|
|
783
|
+
var Selection = class extends Signal {
|
|
784
|
+
static intersect() {
|
|
785
|
+
return new Selection();
|
|
786
|
+
}
|
|
787
|
+
static crossfilter() {
|
|
788
|
+
return new Selection({ cross: true });
|
|
789
|
+
}
|
|
790
|
+
static union() {
|
|
791
|
+
return new Selection({ union: true });
|
|
792
|
+
}
|
|
793
|
+
static single() {
|
|
794
|
+
return new Selection({ single: true });
|
|
795
|
+
}
|
|
796
|
+
constructor({ union, cross, single } = {}) {
|
|
797
|
+
super([]);
|
|
798
|
+
this.active = null;
|
|
799
|
+
this.union = !!union;
|
|
800
|
+
this.cross = !!cross;
|
|
801
|
+
this.single = !!single;
|
|
802
|
+
}
|
|
803
|
+
clone() {
|
|
804
|
+
const s = new Selection();
|
|
805
|
+
s.active = this.active;
|
|
806
|
+
s.union = this.union;
|
|
807
|
+
s.cross = this.cross;
|
|
808
|
+
s._value = this._value;
|
|
809
|
+
return s;
|
|
810
|
+
}
|
|
811
|
+
get value() {
|
|
812
|
+
const { clauses } = this;
|
|
813
|
+
return clauses[clauses.length - 1]?.value;
|
|
814
|
+
}
|
|
815
|
+
get clauses() {
|
|
816
|
+
return super.value;
|
|
817
|
+
}
|
|
818
|
+
activate(clause) {
|
|
819
|
+
this.emit("activate", clause);
|
|
820
|
+
}
|
|
821
|
+
update(clause) {
|
|
822
|
+
const { source, predicate } = clause;
|
|
823
|
+
this.active = clause;
|
|
824
|
+
const clauses = this.single ? [] : this.clauses.filter((c) => source !== c.source);
|
|
825
|
+
if (predicate)
|
|
826
|
+
clauses.push(clause);
|
|
827
|
+
return super.update(clauses);
|
|
828
|
+
}
|
|
829
|
+
predicate(client) {
|
|
830
|
+
const { active, clauses, cross, union } = this;
|
|
831
|
+
if (cross && skipClient(client, active))
|
|
832
|
+
return void 0;
|
|
833
|
+
const list = (cross ? clauses.filter((clause) => !skipClient(client, clause)) : clauses).map((s) => s.predicate);
|
|
834
|
+
return union && list.length > 1 ? or(list) : list;
|
|
835
|
+
}
|
|
836
|
+
};
|
|
837
|
+
|
|
838
|
+
// src/Menu.js
|
|
839
|
+
var isObject = (v) => {
|
|
840
|
+
return v && typeof v === "object" && !Array.isArray(v);
|
|
841
|
+
};
|
|
842
|
+
var Menu = class extends MosaicClient {
|
|
843
|
+
constructor({
|
|
844
|
+
filterBy,
|
|
845
|
+
from,
|
|
846
|
+
column: column2,
|
|
847
|
+
label = column2,
|
|
848
|
+
options,
|
|
849
|
+
value,
|
|
850
|
+
as
|
|
851
|
+
} = {}) {
|
|
852
|
+
super(filterBy);
|
|
853
|
+
this.from = from;
|
|
854
|
+
this.column = column2;
|
|
855
|
+
this.selection = as;
|
|
856
|
+
this.element = document.createElement("div");
|
|
857
|
+
this.element.setAttribute("class", "input");
|
|
858
|
+
this.element.value = this;
|
|
859
|
+
const lab = document.createElement("label");
|
|
860
|
+
lab.innerText = label || column2;
|
|
861
|
+
this.element.appendChild(lab);
|
|
862
|
+
this.select = document.createElement("select");
|
|
863
|
+
if (options) {
|
|
864
|
+
this.data = options.map((value2) => isObject(value2) ? value2 : { value: value2 });
|
|
865
|
+
this.update();
|
|
866
|
+
}
|
|
867
|
+
value = value ?? this.selection?.value ?? this.data?.[0]?.value;
|
|
868
|
+
this.select.value = value;
|
|
869
|
+
if (this.selection?.value === void 0)
|
|
870
|
+
this.publish(value);
|
|
871
|
+
this.element.appendChild(this.select);
|
|
872
|
+
if (this.selection) {
|
|
873
|
+
this.select.addEventListener("input", () => {
|
|
874
|
+
this.publish(this.select.value || null);
|
|
875
|
+
});
|
|
876
|
+
if (!isSelection(this.selection)) {
|
|
877
|
+
this.selection.addEventListener("value", (value2) => {
|
|
878
|
+
if (value2 !== this.select.value) {
|
|
879
|
+
this.select.value = value2;
|
|
880
|
+
}
|
|
881
|
+
});
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
publish(value) {
|
|
886
|
+
const { selection, column: column2 } = this;
|
|
887
|
+
if (isSelection(selection)) {
|
|
888
|
+
selection.update({
|
|
889
|
+
source: this,
|
|
890
|
+
schema: { type: "point" },
|
|
891
|
+
value,
|
|
892
|
+
predicate: value ? eq(column2, literal(value)) : null
|
|
893
|
+
});
|
|
894
|
+
} else if (isSignal(selection)) {
|
|
895
|
+
selection.update(value);
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
fields() {
|
|
899
|
+
const { from, column: column2 } = this;
|
|
900
|
+
return from ? [column(from, column2)] : null;
|
|
901
|
+
}
|
|
902
|
+
query(filter = []) {
|
|
903
|
+
const { from, column: column2 } = this;
|
|
904
|
+
if (!from)
|
|
905
|
+
return null;
|
|
906
|
+
return Query.from(from).select({ value: column2 }).distinct().where(filter).orderby(column2);
|
|
907
|
+
}
|
|
908
|
+
queryResult(data) {
|
|
909
|
+
this.data = [{ value: "", label: "All" }, ...data];
|
|
910
|
+
return this;
|
|
911
|
+
}
|
|
912
|
+
update() {
|
|
913
|
+
const { data, select } = this;
|
|
914
|
+
select.replaceChildren();
|
|
915
|
+
for (const { value, label = value } of data) {
|
|
916
|
+
const opt = document.createElement("option");
|
|
917
|
+
opt.setAttribute("value", value);
|
|
918
|
+
opt.innerText = label;
|
|
919
|
+
this.select.appendChild(opt);
|
|
920
|
+
}
|
|
921
|
+
if (this.selection) {
|
|
922
|
+
this.select.value = this.selection?.value || "";
|
|
923
|
+
}
|
|
924
|
+
return this;
|
|
925
|
+
}
|
|
926
|
+
};
|
|
927
|
+
|
|
928
|
+
// src/Search.js
|
|
929
|
+
var FUNCTIONS = { contains, prefix, suffix, regexp: regexp_matches };
|
|
930
|
+
var _id = 0;
|
|
931
|
+
var Search = class extends MosaicClient {
|
|
932
|
+
constructor({
|
|
933
|
+
filterBy,
|
|
934
|
+
from,
|
|
935
|
+
column: column2,
|
|
936
|
+
label,
|
|
937
|
+
type,
|
|
938
|
+
as
|
|
939
|
+
} = {}) {
|
|
940
|
+
super(filterBy);
|
|
941
|
+
this.id = "search_" + ++_id;
|
|
942
|
+
this.type = type;
|
|
943
|
+
this.from = from;
|
|
944
|
+
this.column = column2;
|
|
945
|
+
this.selection = as;
|
|
946
|
+
this.element = document.createElement("div");
|
|
947
|
+
this.element.setAttribute("class", "input");
|
|
948
|
+
this.element.value = this;
|
|
949
|
+
if (label) {
|
|
950
|
+
const lab = document.createElement("label");
|
|
951
|
+
lab.setAttribute("for", this.id);
|
|
952
|
+
lab.innerText = label;
|
|
953
|
+
this.element.appendChild(lab);
|
|
954
|
+
}
|
|
955
|
+
this.searchbox = document.createElement("input");
|
|
956
|
+
this.searchbox.setAttribute("id", this.id);
|
|
957
|
+
this.searchbox.setAttribute("type", "text");
|
|
958
|
+
this.searchbox.setAttribute("placeholder", "Query");
|
|
959
|
+
this.element.appendChild(this.searchbox);
|
|
960
|
+
if (this.selection) {
|
|
961
|
+
this.searchbox.addEventListener("input", () => {
|
|
962
|
+
this.publish(this.searchbox.value || null);
|
|
963
|
+
});
|
|
964
|
+
if (!isSelection(this.selection)) {
|
|
965
|
+
this.selection.addEventListener("value", (value) => {
|
|
966
|
+
if (value !== this.searchbox.value) {
|
|
967
|
+
this.searchbox.value = value;
|
|
968
|
+
}
|
|
969
|
+
});
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
publish(value) {
|
|
974
|
+
const { selection, column: column2, type } = this;
|
|
975
|
+
if (isSelection(selection)) {
|
|
976
|
+
selection.update({
|
|
977
|
+
source: this,
|
|
978
|
+
schema: { type },
|
|
979
|
+
value,
|
|
980
|
+
predicate: value ? FUNCTIONS[type](column2, literal(value)) : null
|
|
981
|
+
});
|
|
982
|
+
} else if (isSignal(selection)) {
|
|
983
|
+
selection.update(value);
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
fields() {
|
|
987
|
+
const { from, column: column2 } = this;
|
|
988
|
+
return from ? [column(from, column2)] : null;
|
|
989
|
+
}
|
|
990
|
+
query(filter = []) {
|
|
991
|
+
const { from, column: column2 } = this;
|
|
992
|
+
if (!from)
|
|
993
|
+
return null;
|
|
994
|
+
return Query.from(from).select({ list: column2 }).distinct().where(filter);
|
|
995
|
+
}
|
|
996
|
+
queryResult(data) {
|
|
997
|
+
this.data = data;
|
|
998
|
+
return this;
|
|
999
|
+
}
|
|
1000
|
+
update() {
|
|
1001
|
+
const list = document.createElement("datalist");
|
|
1002
|
+
const id = `${this.id}_list`;
|
|
1003
|
+
list.setAttribute("id", id);
|
|
1004
|
+
for (const d of this.data) {
|
|
1005
|
+
const opt = document.createElement("option");
|
|
1006
|
+
opt.setAttribute("value", d.list);
|
|
1007
|
+
list.append(opt);
|
|
1008
|
+
}
|
|
1009
|
+
if (this.datalist)
|
|
1010
|
+
this.datalist.remove();
|
|
1011
|
+
this.element.appendChild(this.datalist = list);
|
|
1012
|
+
this.searchbox.setAttribute("list", id);
|
|
1013
|
+
return this;
|
|
1014
|
+
}
|
|
1015
|
+
};
|
|
1016
|
+
|
|
1017
|
+
// src/Slider.js
|
|
1018
|
+
var _id2 = 0;
|
|
1019
|
+
var Slider = class {
|
|
1020
|
+
constructor({
|
|
1021
|
+
as,
|
|
1022
|
+
min: min2,
|
|
1023
|
+
max: max2,
|
|
1024
|
+
step,
|
|
1025
|
+
column: column2,
|
|
1026
|
+
label = column2,
|
|
1027
|
+
value = as?.value
|
|
1028
|
+
} = {}) {
|
|
1029
|
+
this.id = "slider_" + ++_id2;
|
|
1030
|
+
this.column = column2 || "value";
|
|
1031
|
+
this.selection = as;
|
|
1032
|
+
this.element = document.createElement("div");
|
|
1033
|
+
this.element.setAttribute("class", "input");
|
|
1034
|
+
this.element.value = this;
|
|
1035
|
+
if (label) {
|
|
1036
|
+
const lab = document.createElement("label");
|
|
1037
|
+
lab.setAttribute("for", this.id);
|
|
1038
|
+
lab.innerText = label;
|
|
1039
|
+
this.element.appendChild(lab);
|
|
1040
|
+
}
|
|
1041
|
+
this.slider = document.createElement("input");
|
|
1042
|
+
this.slider.setAttribute("id", this.id);
|
|
1043
|
+
this.slider.setAttribute("type", "range");
|
|
1044
|
+
if (min2 != null)
|
|
1045
|
+
this.slider.setAttribute("min", min2);
|
|
1046
|
+
if (max2 != null)
|
|
1047
|
+
this.slider.setAttribute("max", max2);
|
|
1048
|
+
if (step != null)
|
|
1049
|
+
this.slider.setAttribute("step", step);
|
|
1050
|
+
if (value != null) {
|
|
1051
|
+
this.slider.setAttribute("value", value);
|
|
1052
|
+
if (this.selection?.value === void 0)
|
|
1053
|
+
this.publish(value);
|
|
1054
|
+
}
|
|
1055
|
+
this.element.appendChild(this.slider);
|
|
1056
|
+
if (this.selection) {
|
|
1057
|
+
this.slider.addEventListener("input", () => {
|
|
1058
|
+
this.publish(+this.slider.value);
|
|
1059
|
+
});
|
|
1060
|
+
if (!isSelection(this.selection)) {
|
|
1061
|
+
this.selection.addEventListener("value", (value2) => {
|
|
1062
|
+
if (value2 !== +this.slider.value) {
|
|
1063
|
+
this.slider.value = value2;
|
|
1064
|
+
}
|
|
1065
|
+
});
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
publish(value) {
|
|
1070
|
+
const { selection, column: column2 } = this;
|
|
1071
|
+
if (isSelection(selection)) {
|
|
1072
|
+
selection.update({
|
|
1073
|
+
source: this,
|
|
1074
|
+
schema: { type: "point" },
|
|
1075
|
+
value,
|
|
1076
|
+
predicate: eq(column2, literal(value))
|
|
1077
|
+
});
|
|
1078
|
+
} else if (isSignal(this.selection)) {
|
|
1079
|
+
selection.update(value);
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
};
|
|
1083
|
+
|
|
1084
|
+
// ../../node_modules/isoformat/src/format.js
|
|
1085
|
+
function format(date, fallback) {
|
|
1086
|
+
if (!(date instanceof Date))
|
|
1087
|
+
date = /* @__PURE__ */ new Date(+date);
|
|
1088
|
+
if (isNaN(date))
|
|
1089
|
+
return typeof fallback === "function" ? fallback(date) : fallback;
|
|
1090
|
+
const hours = date.getUTCHours();
|
|
1091
|
+
const minutes = date.getUTCMinutes();
|
|
1092
|
+
const seconds = date.getUTCSeconds();
|
|
1093
|
+
const milliseconds = date.getUTCMilliseconds();
|
|
1094
|
+
return `${formatYear(date.getUTCFullYear(), 4)}-${pad(date.getUTCMonth() + 1, 2)}-${pad(date.getUTCDate(), 2)}${hours || minutes || seconds || milliseconds ? `T${pad(hours, 2)}:${pad(minutes, 2)}${seconds || milliseconds ? `:${pad(seconds, 2)}${milliseconds ? `.${pad(milliseconds, 3)}` : ``}` : ``}Z` : ``}`;
|
|
1095
|
+
}
|
|
1096
|
+
function formatYear(year) {
|
|
1097
|
+
return year < 0 ? `-${pad(-year, 6)}` : year > 9999 ? `+${pad(year, 6)}` : pad(year, 4);
|
|
1098
|
+
}
|
|
1099
|
+
function pad(value, width) {
|
|
1100
|
+
return `${value}`.padStart(width, "0");
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
// src/util/format.js
|
|
1104
|
+
var formatLocaleAuto = localize((locale) => {
|
|
1105
|
+
const formatNumber2 = formatLocaleNumber(locale);
|
|
1106
|
+
return (value) => value == null ? "" : typeof value === "number" ? formatNumber2(value) : value instanceof Date ? formatDate(value) : `${value}`;
|
|
1107
|
+
});
|
|
1108
|
+
var formatLocaleNumber = localize((locale) => {
|
|
1109
|
+
return (value) => value === 0 ? "0" : value.toLocaleString(locale);
|
|
1110
|
+
});
|
|
1111
|
+
var formatAuto = formatLocaleAuto();
|
|
1112
|
+
var formatNumber = formatLocaleNumber();
|
|
1113
|
+
function formatDate(date) {
|
|
1114
|
+
return format(date, "Invalid Date");
|
|
1115
|
+
}
|
|
1116
|
+
function localize(f) {
|
|
1117
|
+
let key = localize, value;
|
|
1118
|
+
return (locale = "en") => locale === key ? value : value = f(key = locale);
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1121
|
+
// src/Table.js
|
|
1122
|
+
var _id3 = -1;
|
|
1123
|
+
var Table = class extends MosaicClient {
|
|
1124
|
+
constructor({
|
|
1125
|
+
filterBy,
|
|
1126
|
+
from,
|
|
1127
|
+
columns = ["*"],
|
|
1128
|
+
format: format2,
|
|
1129
|
+
rowBatch = 100,
|
|
1130
|
+
width,
|
|
1131
|
+
height = 500
|
|
1132
|
+
} = {}) {
|
|
1133
|
+
super(filterBy);
|
|
1134
|
+
this.id = `table-${++_id3}`;
|
|
1135
|
+
this.from = from;
|
|
1136
|
+
this.columns = columns;
|
|
1137
|
+
this.format = format2;
|
|
1138
|
+
this.offset = 0;
|
|
1139
|
+
this.limit = +rowBatch;
|
|
1140
|
+
this.request = new Signal();
|
|
1141
|
+
this.pending = false;
|
|
1142
|
+
this.sortHeader = null;
|
|
1143
|
+
this.sortColumn = null;
|
|
1144
|
+
this.sortDesc = false;
|
|
1145
|
+
this.element = document.createElement("div");
|
|
1146
|
+
this.element.setAttribute("id", this.id);
|
|
1147
|
+
this.element.value = this;
|
|
1148
|
+
if (width) {
|
|
1149
|
+
this.element.style.maxWidth = `${width}px`;
|
|
1150
|
+
}
|
|
1151
|
+
this.element.style.maxHeight = `${height}px`;
|
|
1152
|
+
this.element.style.overflow = "auto";
|
|
1153
|
+
let prevScrollTop = -1;
|
|
1154
|
+
this.element.addEventListener("scroll", (evt) => {
|
|
1155
|
+
const { pending, loaded } = this;
|
|
1156
|
+
const { scrollHeight, scrollTop, clientHeight } = evt.target;
|
|
1157
|
+
const back = scrollTop < prevScrollTop;
|
|
1158
|
+
prevScrollTop = scrollTop;
|
|
1159
|
+
if (back || pending || loaded)
|
|
1160
|
+
return;
|
|
1161
|
+
if (scrollHeight - scrollTop < 2 * clientHeight) {
|
|
1162
|
+
this.pending = true;
|
|
1163
|
+
this.offset += this.limit;
|
|
1164
|
+
const query = this.queryInternal(this.filterBy?.predicate(this));
|
|
1165
|
+
this.request.update(query);
|
|
1166
|
+
}
|
|
1167
|
+
});
|
|
1168
|
+
this.tbl = document.createElement("table");
|
|
1169
|
+
this.element.appendChild(this.tbl);
|
|
1170
|
+
this.head = document.createElement("thead");
|
|
1171
|
+
this.tbl.appendChild(this.head);
|
|
1172
|
+
this.body = document.createElement("tbody");
|
|
1173
|
+
this.tbl.appendChild(this.body);
|
|
1174
|
+
this.style = document.createElement("style");
|
|
1175
|
+
this.element.appendChild(this.style);
|
|
1176
|
+
}
|
|
1177
|
+
fields() {
|
|
1178
|
+
const { from, columns } = this;
|
|
1179
|
+
return columns.map((name) => column(from, name));
|
|
1180
|
+
}
|
|
1181
|
+
fieldStats(stats) {
|
|
1182
|
+
this.stats = stats;
|
|
1183
|
+
const thead = this.head;
|
|
1184
|
+
thead.innerHTML = "";
|
|
1185
|
+
const tr = document.createElement("tr");
|
|
1186
|
+
for (const { column: column2 } of stats) {
|
|
1187
|
+
const th = document.createElement("th");
|
|
1188
|
+
th.addEventListener("click", (evt) => this.sort(evt, column2));
|
|
1189
|
+
th.appendChild(document.createElement("span"));
|
|
1190
|
+
th.appendChild(document.createTextNode(column2));
|
|
1191
|
+
tr.appendChild(th);
|
|
1192
|
+
}
|
|
1193
|
+
thead.appendChild(tr);
|
|
1194
|
+
this.formats = formatof(this.format, stats);
|
|
1195
|
+
this.style.innerText = tableCSS(this.id, alignof({}, stats));
|
|
1196
|
+
return this;
|
|
1197
|
+
}
|
|
1198
|
+
query(filter) {
|
|
1199
|
+
this.offset = 0;
|
|
1200
|
+
return this.queryInternal(filter);
|
|
1201
|
+
}
|
|
1202
|
+
queryInternal(filter = []) {
|
|
1203
|
+
const { from, limit, offset, stats, sortColumn, sortDesc } = this;
|
|
1204
|
+
return Query.from(from).select(stats.map((s) => s.column)).where(filter).orderby(sortColumn ? sortDesc ? desc(sortColumn) : sortColumn : []).limit(limit).offset(offset);
|
|
1205
|
+
}
|
|
1206
|
+
queryResult(data) {
|
|
1207
|
+
if (!this.pending) {
|
|
1208
|
+
this.loaded = false;
|
|
1209
|
+
this.body.replaceChildren();
|
|
1210
|
+
}
|
|
1211
|
+
this.data = data;
|
|
1212
|
+
return this;
|
|
1213
|
+
}
|
|
1214
|
+
update() {
|
|
1215
|
+
const { body, formats, data, stats, limit } = this;
|
|
1216
|
+
const nf = stats.length;
|
|
1217
|
+
let count2 = 0;
|
|
1218
|
+
for (const row of data) {
|
|
1219
|
+
++count2;
|
|
1220
|
+
const tr = document.createElement("tr");
|
|
1221
|
+
for (let i = 0; i < nf; ++i) {
|
|
1222
|
+
const value = row[stats[i].column];
|
|
1223
|
+
const td = document.createElement("td");
|
|
1224
|
+
td.innerText = value == null ? "" : formats[i](value);
|
|
1225
|
+
tr.appendChild(td);
|
|
1226
|
+
}
|
|
1227
|
+
body.appendChild(tr);
|
|
1228
|
+
}
|
|
1229
|
+
if (count2 < limit) {
|
|
1230
|
+
this.loaded = true;
|
|
1231
|
+
}
|
|
1232
|
+
this.pending = false;
|
|
1233
|
+
return this;
|
|
1234
|
+
}
|
|
1235
|
+
sort(event, column2) {
|
|
1236
|
+
if (column2 === this.sortColumn) {
|
|
1237
|
+
this.sortDesc = !this.sortDesc;
|
|
1238
|
+
} else {
|
|
1239
|
+
this.sortColumn = column2;
|
|
1240
|
+
this.sortDesc = false;
|
|
1241
|
+
}
|
|
1242
|
+
const th = event.currentTarget;
|
|
1243
|
+
const currentHeader = this.sortHeader;
|
|
1244
|
+
if (currentHeader === th && event.metaKey) {
|
|
1245
|
+
currentHeader.firstChild.textContent = "";
|
|
1246
|
+
this.sortHeader = null;
|
|
1247
|
+
this.sortColumn = null;
|
|
1248
|
+
} else {
|
|
1249
|
+
if (currentHeader)
|
|
1250
|
+
currentHeader.firstChild.textContent = "";
|
|
1251
|
+
this.sortHeader = th;
|
|
1252
|
+
th.firstChild.textContent = this.sortDesc ? "\u25BE" : "\u25B4";
|
|
1253
|
+
}
|
|
1254
|
+
const query = this.query(this.filterBy?.predicate(this));
|
|
1255
|
+
this.request.update(query);
|
|
1256
|
+
}
|
|
1257
|
+
};
|
|
1258
|
+
function formatof(base = {}, stats, locale) {
|
|
1259
|
+
return stats.map(({ column: column2, type }) => {
|
|
1260
|
+
if (column2 in base) {
|
|
1261
|
+
return base[column2];
|
|
1262
|
+
} else {
|
|
1263
|
+
switch (type) {
|
|
1264
|
+
case "number":
|
|
1265
|
+
return formatLocaleNumber(locale);
|
|
1266
|
+
case "date":
|
|
1267
|
+
return formatDate;
|
|
1268
|
+
default:
|
|
1269
|
+
return formatLocaleAuto(locale);
|
|
1270
|
+
}
|
|
1271
|
+
}
|
|
1272
|
+
});
|
|
1273
|
+
}
|
|
1274
|
+
function alignof(base = {}, stats) {
|
|
1275
|
+
return stats.map(({ column: column2, type }) => {
|
|
1276
|
+
if (column2 in base) {
|
|
1277
|
+
return base[column2];
|
|
1278
|
+
} else if (type === "number") {
|
|
1279
|
+
return "right";
|
|
1280
|
+
} else {
|
|
1281
|
+
return "left";
|
|
1282
|
+
}
|
|
1283
|
+
});
|
|
1284
|
+
}
|
|
1285
|
+
function tableCSS(id, align) {
|
|
1286
|
+
const styles = [];
|
|
1287
|
+
align.forEach((a, i) => {
|
|
1288
|
+
if (a !== "left") {
|
|
1289
|
+
styles.push(`#${id} tr>:nth-child(${i + 1}) {text-align:${a}}`);
|
|
1290
|
+
}
|
|
1291
|
+
});
|
|
1292
|
+
return styles.join(" ");
|
|
1293
|
+
}
|
|
1294
|
+
export {
|
|
1295
|
+
Menu,
|
|
1296
|
+
Search,
|
|
1297
|
+
Slider,
|
|
1298
|
+
Table
|
|
1299
|
+
};
|