@loaders.gl/scan 5.0.0-alpha.10
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/LICENSE +52 -0
- package/README.md +219 -0
- package/dist/delta.cjs +25568 -0
- package/dist/delta.cjs.map +6 -0
- package/dist/delta.d.ts +11 -0
- package/dist/delta.d.ts.map +1 -0
- package/dist/delta.js +12 -0
- package/dist/delta.js.map +1 -0
- package/dist/dist.min.js +18535 -0
- package/dist/federated-table-scan-source.d.ts +116 -0
- package/dist/federated-table-scan-source.d.ts.map +1 -0
- package/dist/federated-table-scan-source.js +691 -0
- package/dist/federated-table-scan-source.js.map +1 -0
- package/dist/hudi.cjs +25405 -0
- package/dist/hudi.cjs.map +6 -0
- package/dist/hudi.d.ts +58 -0
- package/dist/hudi.d.ts.map +1 -0
- package/dist/hudi.js +147 -0
- package/dist/hudi.js.map +1 -0
- package/dist/iceberg.cjs +27662 -0
- package/dist/iceberg.cjs.map +6 -0
- package/dist/iceberg.d.ts +12 -0
- package/dist/iceberg.d.ts.map +1 -0
- package/dist/iceberg.js +12 -0
- package/dist/iceberg.js.map +1 -0
- package/dist/index.cjs +3540 -0
- package/dist/index.cjs.map +6 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/scan-engine.d.ts +44 -0
- package/dist/scan-engine.d.ts.map +1 -0
- package/dist/scan-engine.js +51 -0
- package/dist/scan-engine.js.map +1 -0
- package/dist/scan-query.d.ts +24 -0
- package/dist/scan-query.d.ts.map +1 -0
- package/dist/scan-query.js +5 -0
- package/dist/scan-query.js.map +1 -0
- package/dist/vector-table-scan-source.d.ts +92 -0
- package/dist/vector-table-scan-source.d.ts.map +1 -0
- package/dist/vector-table-scan-source.js +220 -0
- package/dist/vector-table-scan-source.js.map +1 -0
- package/package.json +66 -0
- package/src/delta.ts +18 -0
- package/src/federated-table-scan-source.ts +991 -0
- package/src/hudi.ts +235 -0
- package/src/iceberg.ts +36 -0
- package/src/index.ts +97 -0
- package/src/scan-engine.ts +100 -0
- package/src/scan-query.ts +27 -0
- package/src/vector-table-scan-source.ts +300 -0
package/dist/hudi.d.ts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { CoreAPI, ScanFragment, ScanFragmentProvider, ScanQueryMetadata, ScanQueryMetadataOptions, TableScanSource } from '@loaders.gl/loader-utils';
|
|
2
|
+
import { DataSource } from '@loaders.gl/loader-utils';
|
|
3
|
+
import type { ParquetDatasetBatch, ParquetDatasetExplain, ParquetDatasetReadOptions, ParquetPredicate, ParquetDatasetSourceOptions } from '@loaders.gl/parquet/parquet-source-types';
|
|
4
|
+
/** A physical Parquet base file recorded by a Hudi snapshot descriptor. */
|
|
5
|
+
export type HudiBaseFile = Readonly<{
|
|
6
|
+
/** Path or URL of the Parquet base file. */
|
|
7
|
+
path: string;
|
|
8
|
+
/** Compressed file size in bytes, when recorded by the descriptor. */
|
|
9
|
+
size?: number;
|
|
10
|
+
/** Number of records in the base file, when recorded by the descriptor. */
|
|
11
|
+
numRecords?: number;
|
|
12
|
+
/** Partition column values associated with the base file. */
|
|
13
|
+
partitionValues?: Readonly<Record<string, unknown>>;
|
|
14
|
+
}>;
|
|
15
|
+
/** Minimal, portable descriptor used by the Hudi proof of concept. */
|
|
16
|
+
export type HudiSnapshotDescriptor = Readonly<{
|
|
17
|
+
tableType?: 'COPY_ON_WRITE' | 'MERGE_ON_READ';
|
|
18
|
+
basePath?: string;
|
|
19
|
+
completedInstant?: string;
|
|
20
|
+
files: readonly HudiBaseFile[];
|
|
21
|
+
}>;
|
|
22
|
+
/** Options for reading a Hudi snapshot descriptor and its Parquet base files. */
|
|
23
|
+
export type HudiSourceOptions = ParquetDatasetSourceOptions & {
|
|
24
|
+
hudi?: {
|
|
25
|
+
baseUrl?: string;
|
|
26
|
+
headers?: HeadersInit;
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
/** Query options accepted by a Hudi snapshot scan. */
|
|
30
|
+
export type HudiScanOptions = ParquetDatasetReadOptions;
|
|
31
|
+
/**
|
|
32
|
+
* Minimal read-only Hudi Copy-on-Write source.
|
|
33
|
+
*
|
|
34
|
+
* The POC consumes a small JSON snapshot descriptor containing the selected base files. It does
|
|
35
|
+
* not claim to decode Hudi log files, merge-on-read records, or incremental timeline queries.
|
|
36
|
+
*/
|
|
37
|
+
export declare class HudiTableSource extends DataSource<string | Blob, HudiSourceOptions> implements TableScanSource<ParquetDatasetBatch, ParquetPredicate>, ScanFragmentProvider<ParquetPredicate> {
|
|
38
|
+
private descriptorPromise;
|
|
39
|
+
/** Creates a source from a Hudi snapshot descriptor URL or Blob. */
|
|
40
|
+
constructor(data: string | Blob, options?: HudiSourceOptions, coreApi?: CoreAPI);
|
|
41
|
+
/** Loads and validates the POC snapshot descriptor. */
|
|
42
|
+
getDescriptor(signal?: AbortSignal): Promise<HudiSnapshotDescriptor>;
|
|
43
|
+
/** Discovers the Copy-on-Write Parquet base files in the selected snapshot. */
|
|
44
|
+
getScanFragments(options?: HudiScanOptions): Promise<readonly ScanFragment[]>;
|
|
45
|
+
/** Discovers schema and snapshot statistics without decoding every row. */
|
|
46
|
+
getQueryMetadata(options?: ScanQueryMetadataOptions): Promise<ScanQueryMetadata>;
|
|
47
|
+
/** Explains the Hudi snapshot and delegated Parquet physical plan. */
|
|
48
|
+
getScanPlan(options?: HudiScanOptions): Promise<ParquetDatasetExplain>;
|
|
49
|
+
/** Reads the selected Hudi snapshot through the shared Parquet executor. */
|
|
50
|
+
read(options?: HudiScanOptions): AsyncIterable<ParquetDatasetBatch>;
|
|
51
|
+
/** Alias for `read()` used by scan-aware consumers. */
|
|
52
|
+
scan(options?: HudiScanOptions): AsyncIterable<ParquetDatasetBatch>;
|
|
53
|
+
private loadDescriptor;
|
|
54
|
+
private createDataset;
|
|
55
|
+
private createDatasetFromOptions;
|
|
56
|
+
private resolveDataFile;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=hudi.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hudi.d.ts","sourceRoot":"","sources":["../src/hudi.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,OAAO,EACP,YAAY,EACZ,oBAAoB,EACpB,iBAAiB,EACjB,wBAAwB,EACxB,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAA0B,UAAU,EAAC,MAAM,0BAA0B,CAAC;AAG7E,OAAO,KAAK,EACV,mBAAmB,EACnB,qBAAqB,EACrB,yBAAyB,EACzB,gBAAgB,EAChB,2BAA2B,EAC5B,MAAM,0CAA0C,CAAC;AAElD,2EAA2E;AAC3E,MAAM,MAAM,YAAY,GAAG,QAAQ,CAAC;IAClC,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6DAA6D;IAC7D,eAAe,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACrD,CAAC,CAAC;AAEH,sEAAsE;AACtE,MAAM,MAAM,sBAAsB,GAAG,QAAQ,CAAC;IAC5C,SAAS,CAAC,EAAE,eAAe,GAAG,eAAe,CAAC;IAC9C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;CAChC,CAAC,CAAC;AAEH,iFAAiF;AACjF,MAAM,MAAM,iBAAiB,GAAG,2BAA2B,GAAG;IAC5D,IAAI,CAAC,EAAE;QACL,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,WAAW,CAAC;KACvB,CAAC;CACH,CAAC;AAEF,sDAAsD;AACtD,MAAM,MAAM,eAAe,GAAG,yBAAyB,CAAC;AAExD;;;;;GAKG;AACH,qBAAa,eACX,SAAQ,UAAU,CAAC,MAAM,GAAG,IAAI,EAAE,iBAAiB,CACnD,YACE,eAAe,CAAC,mBAAmB,EAAE,gBAAgB,CAAC,EACtD,oBAAoB,CAAC,gBAAgB,CAAC;IAExC,OAAO,CAAC,iBAAiB,CAAgD;IAEzE,oEAAoE;gBACxD,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,OAAO,GAAE,iBAAsB,EAAE,OAAO,CAAC,EAAE,OAAO;IAInF,uDAAuD;IACjD,aAAa,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAU1E,+EAA+E;IACzE,gBAAgB,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,SAAS,YAAY,EAAE,CAAC;IAmBvF,2EAA2E;IACrE,gBAAgB,CAAC,OAAO,GAAE,wBAA6B,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAsB1F,sEAAsE;IAChE,WAAW,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAIhF,4EAA4E;IAC5E,IAAI,CAAC,OAAO,GAAE,eAAoB,GAAG,aAAa,CAAC,mBAAmB,CAAC;IAIvE,uDAAuD;IACvD,IAAI,CAAC,OAAO,GAAE,eAAoB,GAAG,aAAa,CAAC,mBAAmB,CAAC;YAIzD,cAAc;IA4D5B,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,wBAAwB;IAehC,OAAO,CAAC,eAAe;CAKxB"}
|
package/dist/hudi.js
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
// loaders.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
import { createScanQueryMetadata, DataSource } from '@loaders.gl/loader-utils';
|
|
5
|
+
import { ParquetDatasetSource } from '@loaders.gl/parquet/parquet-dataset-source';
|
|
6
|
+
import { PARQUET_TABLE_QUERY_CAPABILITIES } from '@loaders.gl/parquet/parquet-source-capabilities';
|
|
7
|
+
/**
|
|
8
|
+
* Minimal read-only Hudi Copy-on-Write source.
|
|
9
|
+
*
|
|
10
|
+
* The POC consumes a small JSON snapshot descriptor containing the selected base files. It does
|
|
11
|
+
* not claim to decode Hudi log files, merge-on-read records, or incremental timeline queries.
|
|
12
|
+
*/
|
|
13
|
+
export class HudiTableSource extends DataSource {
|
|
14
|
+
descriptorPromise = null;
|
|
15
|
+
/** Creates a source from a Hudi snapshot descriptor URL or Blob. */
|
|
16
|
+
constructor(data, options = {}, coreApi) {
|
|
17
|
+
super(data, options, undefined, coreApi);
|
|
18
|
+
}
|
|
19
|
+
/** Loads and validates the POC snapshot descriptor. */
|
|
20
|
+
async getDescriptor(signal) {
|
|
21
|
+
if (!this.descriptorPromise) {
|
|
22
|
+
this.descriptorPromise = this.loadDescriptor(signal).catch(error => {
|
|
23
|
+
this.descriptorPromise = null;
|
|
24
|
+
throw error;
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
return this.descriptorPromise;
|
|
28
|
+
}
|
|
29
|
+
/** Discovers the Copy-on-Write Parquet base files in the selected snapshot. */
|
|
30
|
+
async getScanFragments(options = {}) {
|
|
31
|
+
const descriptor = await this.getDescriptor(options.signal);
|
|
32
|
+
if (descriptor.tableType === 'MERGE_ON_READ') {
|
|
33
|
+
throw new Error('Hudi Merge-on-Read snapshots are not supported by this POC');
|
|
34
|
+
}
|
|
35
|
+
return Object.freeze(descriptor.files.map(file => Object.freeze({
|
|
36
|
+
id: file.path,
|
|
37
|
+
uri: this.resolveDataFile(file.path, descriptor.basePath),
|
|
38
|
+
partitionValues: file.partitionValues,
|
|
39
|
+
byteLength: file.size,
|
|
40
|
+
rowCount: file.numRecords,
|
|
41
|
+
metadata: { completedInstant: descriptor.completedInstant }
|
|
42
|
+
})));
|
|
43
|
+
}
|
|
44
|
+
/** Discovers schema and snapshot statistics without decoding every row. */
|
|
45
|
+
async getQueryMetadata(options = {}) {
|
|
46
|
+
const fragments = await this.getScanFragments(options);
|
|
47
|
+
if (!fragments.length)
|
|
48
|
+
throw new Error('Hudi snapshot contains no Parquet base files');
|
|
49
|
+
const dataset = this.createDataset(fragments);
|
|
50
|
+
const schema = await dataset.getSchema({ signal: options.signal });
|
|
51
|
+
return createScanQueryMetadata({
|
|
52
|
+
sourceType: 'hudi',
|
|
53
|
+
queryType: 'table',
|
|
54
|
+
execution: { status: 'supported', method: 'read' },
|
|
55
|
+
name: this.data instanceof Blob ? undefined : this.data,
|
|
56
|
+
schema,
|
|
57
|
+
capabilities: { table: PARQUET_TABLE_QUERY_CAPABILITIES },
|
|
58
|
+
statistics: {
|
|
59
|
+
rowCount: fragments.reduce((total, fragment) => total + Number(fragment.rowCount || 0), 0),
|
|
60
|
+
byteLength: fragments.reduce((total, fragment) => total + Number(fragment.byteLength || 0), 0)
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
/** Explains the Hudi snapshot and delegated Parquet physical plan. */
|
|
65
|
+
async getScanPlan(options = {}) {
|
|
66
|
+
return this.createDataset(await this.getScanFragments(options)).getScanPlan(options);
|
|
67
|
+
}
|
|
68
|
+
/** Reads the selected Hudi snapshot through the shared Parquet executor. */
|
|
69
|
+
read(options = {}) {
|
|
70
|
+
return this.createDatasetFromOptions(options).read(options);
|
|
71
|
+
}
|
|
72
|
+
/** Alias for `read()` used by scan-aware consumers. */
|
|
73
|
+
scan(options = {}) {
|
|
74
|
+
return this.read(options);
|
|
75
|
+
}
|
|
76
|
+
async loadDescriptor(signal) {
|
|
77
|
+
const text = typeof this.data === 'string'
|
|
78
|
+
? await (await this.fetch(this.url, { headers: this.options.hudi?.headers, signal })).text()
|
|
79
|
+
: await this.data.text();
|
|
80
|
+
let descriptor;
|
|
81
|
+
try {
|
|
82
|
+
descriptor = JSON.parse(text);
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
throw new Error('Hudi snapshot descriptor must be valid JSON');
|
|
86
|
+
}
|
|
87
|
+
const files = descriptor && typeof descriptor === 'object'
|
|
88
|
+
? descriptor.files
|
|
89
|
+
: undefined;
|
|
90
|
+
if (!Array.isArray(files)) {
|
|
91
|
+
throw new Error('Hudi snapshot descriptor must contain a files array');
|
|
92
|
+
}
|
|
93
|
+
for (const [index, file] of files.entries()) {
|
|
94
|
+
if (!file || typeof file !== 'object' || Array.isArray(file)) {
|
|
95
|
+
throw new Error(`Hudi snapshot file at index ${index} must be an object`);
|
|
96
|
+
}
|
|
97
|
+
const value = file;
|
|
98
|
+
if (typeof value.path !== 'string' || !value.path) {
|
|
99
|
+
throw new Error(`Hudi snapshot file at index ${index} must contain a non-empty string path`);
|
|
100
|
+
}
|
|
101
|
+
if (value.size !== undefined &&
|
|
102
|
+
(typeof value.size !== 'number' || !Number.isFinite(value.size))) {
|
|
103
|
+
throw new Error(`Hudi snapshot file at index ${index} size must be a finite number`);
|
|
104
|
+
}
|
|
105
|
+
if (value.numRecords !== undefined &&
|
|
106
|
+
(typeof value.numRecords !== 'number' || !Number.isFinite(value.numRecords))) {
|
|
107
|
+
throw new Error(`Hudi snapshot file at index ${index} numRecords must be a finite number`);
|
|
108
|
+
}
|
|
109
|
+
if (value.partitionValues !== undefined &&
|
|
110
|
+
(!value.partitionValues ||
|
|
111
|
+
typeof value.partitionValues !== 'object' ||
|
|
112
|
+
Array.isArray(value.partitionValues))) {
|
|
113
|
+
throw new Error(`Hudi snapshot file at index ${index} partitionValues must be an object`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
const value = descriptor;
|
|
117
|
+
if (value.tableType &&
|
|
118
|
+
value.tableType !== 'COPY_ON_WRITE' &&
|
|
119
|
+
value.tableType !== 'MERGE_ON_READ') {
|
|
120
|
+
throw new Error(`Unsupported Hudi table type: ${String(value.tableType)}`);
|
|
121
|
+
}
|
|
122
|
+
return value;
|
|
123
|
+
}
|
|
124
|
+
createDataset(fragments) {
|
|
125
|
+
return new ParquetDatasetSource(fragments.map(fragment => ({
|
|
126
|
+
data: fragment.uri,
|
|
127
|
+
id: fragment.id,
|
|
128
|
+
partitions: fragment.partitionValues,
|
|
129
|
+
metadata: fragment.metadata
|
|
130
|
+
})), this.options);
|
|
131
|
+
}
|
|
132
|
+
createDatasetFromOptions(options) {
|
|
133
|
+
return new ParquetDatasetSource(() => this.getScanFragments(options).then(fragments => fragments.map(fragment => ({
|
|
134
|
+
data: fragment.uri,
|
|
135
|
+
id: fragment.id,
|
|
136
|
+
partitions: fragment.partitionValues,
|
|
137
|
+
metadata: fragment.metadata
|
|
138
|
+
}))), this.options);
|
|
139
|
+
}
|
|
140
|
+
resolveDataFile(path, basePath) {
|
|
141
|
+
const baseUrl = this.options.hudi?.baseUrl || basePath;
|
|
142
|
+
if (baseUrl)
|
|
143
|
+
return new URL(path, baseUrl).toString();
|
|
144
|
+
return path;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=hudi.js.map
|
package/dist/hudi.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hudi.js","sourceRoot":"","sources":["../src/hudi.ts"],"names":[],"mappings":"AAAA,aAAa;AACb,+BAA+B;AAC/B,oCAAoC;AAUpC,OAAO,EAAC,uBAAuB,EAAE,UAAU,EAAC,MAAM,0BAA0B,CAAC;AAC7E,OAAO,EAAC,oBAAoB,EAAC,MAAM,4CAA4C,CAAC;AAChF,OAAO,EAAC,gCAAgC,EAAC,MAAM,iDAAiD,CAAC;AAwCjG;;;;;GAKG;AACH,MAAM,OAAO,eACX,SAAQ,UAA4C;IAK5C,iBAAiB,GAA2C,IAAI,CAAC;IAEzE,oEAAoE;IACpE,YAAY,IAAmB,EAAE,UAA6B,EAAE,EAAE,OAAiB;QACjF,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IAC3C,CAAC;IAED,uDAAuD;IACvD,KAAK,CAAC,aAAa,CAAC,MAAoB;QACtC,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC5B,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;gBACjE,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;gBAC9B,MAAM,KAAK,CAAC;YACd,CAAC,CAAC,CAAC;QACL,CAAC;QACD,OAAO,IAAI,CAAC,iBAAiB,CAAC;IAChC,CAAC;IAED,+EAA+E;IAC/E,KAAK,CAAC,gBAAgB,CAAC,UAA2B,EAAE;QAClD,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC5D,IAAI,UAAU,CAAC,SAAS,KAAK,eAAe,EAAE,CAAC;YAC7C,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;QAChF,CAAC;QACD,OAAO,MAAM,CAAC,MAAM,CAClB,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAC1B,MAAM,CAAC,MAAM,CAAC;YACZ,EAAE,EAAE,IAAI,CAAC,IAAI;YACb,GAAG,EAAE,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,QAAQ,CAAC;YACzD,eAAe,EAAE,IAAI,CAAC,eAAe;YACrC,UAAU,EAAE,IAAI,CAAC,IAAI;YACrB,QAAQ,EAAE,IAAI,CAAC,UAAU;YACzB,QAAQ,EAAE,EAAC,gBAAgB,EAAE,UAAU,CAAC,gBAAgB,EAAC;SAC1D,CAAC,CACH,CACF,CAAC;IACJ,CAAC;IAED,2EAA2E;IAC3E,KAAK,CAAC,gBAAgB,CAAC,UAAoC,EAAE;QAC3D,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QACvD,IAAI,CAAC,SAAS,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;QACvF,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;QAC9C,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,EAAC,MAAM,EAAE,OAAO,CAAC,MAAM,EAAC,CAAC,CAAC;QACjE,OAAO,uBAAuB,CAAC;YAC7B,UAAU,EAAE,MAAM;YAClB,SAAS,EAAE,OAAO;YAClB,SAAS,EAAE,EAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAC;YAChD,IAAI,EAAE,IAAI,CAAC,IAAI,YAAY,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI;YACvD,MAAM;YACN,YAAY,EAAE,EAAC,KAAK,EAAE,gCAAgC,EAAC;YACvD,UAAU,EAAE;gBACV,QAAQ,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,CAAC,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;gBAC1F,UAAU,EAAE,SAAS,CAAC,MAAM,CAC1B,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,CAAC,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,UAAU,IAAI,CAAC,CAAC,EAC7D,CAAC,CACF;aACF;SACF,CAAC,CAAC;IACL,CAAC;IAED,sEAAsE;IACtE,KAAK,CAAC,WAAW,CAAC,UAA2B,EAAE;QAC7C,OAAO,IAAI,CAAC,aAAa,CAAC,MAAM,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IACvF,CAAC;IAED,4EAA4E;IAC5E,IAAI,CAAC,UAA2B,EAAE;QAChC,OAAO,IAAI,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC9D,CAAC;IAED,uDAAuD;IACvD,IAAI,CAAC,UAA2B,EAAE;QAChC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC5B,CAAC;IAEO,KAAK,CAAC,cAAc,CAAC,MAAoB;QAC/C,MAAM,IAAI,GACR,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ;YAC3B,CAAC,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,EAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAC,CAAC,CAAC,CAAC,IAAI,EAAE;YAC1F,CAAC,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAI,UAAmB,CAAC;QACxB,IAAI,CAAC;YACH,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAChC,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;QACjE,CAAC;QACD,MAAM,KAAK,GACT,UAAU,IAAI,OAAO,UAAU,KAAK,QAAQ;YAC1C,CAAC,CAAE,UAAgC,CAAC,KAAK;YACzC,CAAC,CAAC,SAAS,CAAC;QAChB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;QACzE,CAAC;QACD,KAAK,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;YAC5C,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC7D,MAAM,IAAI,KAAK,CAAC,+BAA+B,KAAK,oBAAoB,CAAC,CAAC;YAC5E,CAAC;YACD,MAAM,KAAK,GAAG,IAA+B,CAAC;YAC9C,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;gBAClD,MAAM,IAAI,KAAK,CACb,+BAA+B,KAAK,uCAAuC,CAC5E,CAAC;YACJ,CAAC;YACD,IACE,KAAK,CAAC,IAAI,KAAK,SAAS;gBACxB,CAAC,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAChE,CAAC;gBACD,MAAM,IAAI,KAAK,CAAC,+BAA+B,KAAK,+BAA+B,CAAC,CAAC;YACvF,CAAC;YACD,IACE,KAAK,CAAC,UAAU,KAAK,SAAS;gBAC9B,CAAC,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,EAC5E,CAAC;gBACD,MAAM,IAAI,KAAK,CAAC,+BAA+B,KAAK,qCAAqC,CAAC,CAAC;YAC7F,CAAC;YACD,IACE,KAAK,CAAC,eAAe,KAAK,SAAS;gBACnC,CAAC,CAAC,KAAK,CAAC,eAAe;oBACrB,OAAO,KAAK,CAAC,eAAe,KAAK,QAAQ;oBACzC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,EACvC,CAAC;gBACD,MAAM,IAAI,KAAK,CAAC,+BAA+B,KAAK,oCAAoC,CAAC,CAAC;YAC5F,CAAC;QACH,CAAC;QACD,MAAM,KAAK,GAAG,UAAoC,CAAC;QACnD,IACE,KAAK,CAAC,SAAS;YACf,KAAK,CAAC,SAAS,KAAK,eAAe;YACnC,KAAK,CAAC,SAAS,KAAK,eAAe,EACnC,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,gCAAgC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QAC7E,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAEO,aAAa,CAAC,SAAkC;QACtD,OAAO,IAAI,oBAAoB,CAC7B,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;YACzB,IAAI,EAAE,QAAQ,CAAC,GAAI;YACnB,EAAE,EAAE,QAAQ,CAAC,EAAE;YACf,UAAU,EAAE,QAAQ,CAAC,eAAwB;YAC7C,QAAQ,EAAE,QAAQ,CAAC,QAAQ;SAC5B,CAAC,CAAC,EACH,IAAI,CAAC,OAAO,CACb,CAAC;IACJ,CAAC;IAEO,wBAAwB,CAAC,OAAwB;QACvD,OAAO,IAAI,oBAAoB,CAC7B,GAAG,EAAE,CACH,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAC9C,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;YACzB,IAAI,EAAE,QAAQ,CAAC,GAAI;YACnB,EAAE,EAAE,QAAQ,CAAC,EAAE;YACf,UAAU,EAAE,QAAQ,CAAC,eAAwB;YAC7C,QAAQ,EAAE,QAAQ,CAAC,QAAQ;SAC5B,CAAC,CAAC,CACJ,EACH,IAAI,CAAC,OAAO,CACb,CAAC;IACJ,CAAC;IAEO,eAAe,CAAC,IAAY,EAAE,QAAiB;QACrD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,IAAI,QAAQ,CAAC;QACvD,IAAI,OAAO;YAAE,OAAO,IAAI,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC;QACtD,OAAO,IAAI,CAAC;IACd,CAAC;CACF"}
|