@gasm-compiler/cli 0.1.0 → 0.2.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 +81 -124
- package/dist/cli.js +89 -16
- package/package.json +3 -2
- package/dist/cli.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,172 +1,129 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @gasm-compiler/cli
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**Command-line compiler for WebAssembly → WGSL**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Compile WebAssembly (`.wasm`) or AssemblyScript (`.as`/`.ts`) files to WGSL compute shaders from the command line. Built on top of [`@gasm-compiler/core`](https://www.npmjs.com/package/@gasm-compiler/core).
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Version 0.2 defaults to strict Gasm v0.2 compilation. Use
|
|
8
|
+
`--spec-version 0.1` only for archived v0.1 inputs.
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
2. **Compile to WebAssembly** using the AssemblyScript compiler
|
|
11
|
-
3. **Transform to WGSL** using the Gasm Compiler Gasm compiler
|
|
12
|
-
4. **Execute on GPU** using WebGPU
|
|
13
|
-
|
|
14
|
-
## Quick Start
|
|
15
|
-
|
|
16
|
-
### Prerequisites
|
|
17
|
-
|
|
18
|
-
- [Deno](https://deno.com) installed
|
|
19
|
-
- AssemblyScript installed (or use `npm` within the examples folder)
|
|
10
|
+
---
|
|
20
11
|
|
|
21
|
-
|
|
12
|
+
## Installation
|
|
22
13
|
|
|
23
14
|
```bash
|
|
24
|
-
|
|
25
|
-
deno run --allow-all src/cli.ts compile examples/demo.as --output output.wgsl
|
|
26
|
-
|
|
27
|
-
# View help
|
|
28
|
-
deno run --allow-all src/cli.ts --help
|
|
29
|
-
|
|
30
|
-
# Show detailed compiler output
|
|
31
|
-
deno run --allow-all src/cli.ts compile examples/demo.as --verbose
|
|
15
|
+
npm install -g @gasm-compiler/cli
|
|
32
16
|
```
|
|
33
17
|
|
|
34
|
-
|
|
18
|
+
Or use without installing:
|
|
35
19
|
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
├── src/
|
|
39
|
-
│ ├── cli.ts # Main CLI entry point
|
|
40
|
-
│ ├── compiler.ts # Compilation orchestration
|
|
41
|
-
│ └── utils.ts # Utility functions
|
|
42
|
-
├── examples/
|
|
43
|
-
│ ├── package.json # AssemblyScript dependencies
|
|
44
|
-
│ ├── demo.as # Sample AssemblyScript program
|
|
45
|
-
│ └── asconfig.json # AssemblyScript compiler config
|
|
46
|
-
├── deno.json # Deno configuration
|
|
47
|
-
├── package.json # NPM package metadata
|
|
48
|
-
└── README.md # This file
|
|
20
|
+
```bash
|
|
21
|
+
npx @gasm-compiler/cli compile shader.wasm -o shader.wgsl
|
|
49
22
|
```
|
|
50
23
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
### Simple Arithmetic
|
|
54
|
-
|
|
55
|
-
The `examples/demo.ts` file contains a basic example showing:
|
|
56
|
-
- Function definitions
|
|
57
|
-
- Integer arithmetic
|
|
58
|
-
- Memory operations
|
|
59
|
-
- Control flow
|
|
60
|
-
|
|
61
|
-
### WASM vs WGSL Execution Comparison
|
|
24
|
+
---
|
|
62
25
|
|
|
63
|
-
|
|
26
|
+
## Quick Start
|
|
64
27
|
|
|
65
28
|
```bash
|
|
66
|
-
#
|
|
67
|
-
|
|
29
|
+
# Compile a .wasm file to WGSL
|
|
30
|
+
gasm-compiler compile shader.wasm --output shader.wgsl
|
|
68
31
|
|
|
69
|
-
#
|
|
70
|
-
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
This validates that:
|
|
74
|
-
- ✅ WASM functions produce expected results
|
|
75
|
-
- ✅ WGSL code compiles successfully
|
|
76
|
-
- ✅ Compilation preserves semantics
|
|
32
|
+
# Compile AssemblyScript to WGSL (compiles to Wasm first, then to WGSL)
|
|
33
|
+
gasm-compiler compile kernel.as --output kernel.wgsl
|
|
77
34
|
|
|
78
|
-
|
|
35
|
+
# Print WGSL to stdout
|
|
36
|
+
gasm-compiler compile shader.wasm
|
|
79
37
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
```bash
|
|
83
|
-
# Compile and view the WGSL output
|
|
84
|
-
deno run --allow-all src/cli.ts compile examples/demo.as
|
|
38
|
+
# Show verbose compilation steps
|
|
39
|
+
gasm-compiler compile shader.wasm --verbose
|
|
85
40
|
|
|
86
|
-
#
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
# Verbose output with compilation steps
|
|
90
|
-
deno run --allow-all src/cli.ts compile examples/demo.as --verbose
|
|
41
|
+
# View help
|
|
42
|
+
gasm-compiler --help
|
|
91
43
|
```
|
|
92
44
|
|
|
93
|
-
|
|
45
|
+
---
|
|
94
46
|
|
|
95
|
-
|
|
96
|
-
2. **Gasm Validation**: The compiler validates that the Wasm conforms to the Gasm specification
|
|
97
|
-
3. **IR Generation**: An intermediate representation is built for analysis and transformation
|
|
98
|
-
4. **WGSL Code Generation**: The IR is transformed into WGSL shader code ready for WebGPU
|
|
47
|
+
## Commands
|
|
99
48
|
|
|
100
|
-
|
|
49
|
+
### `compile <input>`
|
|
101
50
|
|
|
102
|
-
|
|
103
|
-
- `--output <file>` - Write output to file (default: stdout)
|
|
104
|
-
- `--verbose` - Show detailed compilation steps
|
|
105
|
-
- `--keep-wasm` - Keep intermediate WASM files
|
|
106
|
-
- `--optimize` - Apply optimization passes
|
|
51
|
+
Compiles a WebAssembly binary or AssemblyScript source to WGSL.
|
|
107
52
|
|
|
108
|
-
|
|
53
|
+
| Option | Description |
|
|
54
|
+
|--------|-------------|
|
|
55
|
+
| `--output <file>`, `-o` | Write WGSL output to a file (default: stdout) |
|
|
56
|
+
| `--verbose` | Show detailed compilation steps |
|
|
57
|
+
| `--keep-wasm` | Keep intermediate `.wasm` file when compiling from AssemblyScript |
|
|
58
|
+
| `--optimize` | Apply optimization passes |
|
|
109
59
|
|
|
110
|
-
|
|
60
|
+
**Examples:**
|
|
111
61
|
|
|
112
62
|
```bash
|
|
113
|
-
#
|
|
114
|
-
|
|
115
|
-
```
|
|
63
|
+
# Compile pre-built Wasm
|
|
64
|
+
gasm-compiler compile my_shader.wasm -o my_shader.wgsl
|
|
116
65
|
|
|
117
|
-
|
|
66
|
+
# Compile AssemblyScript with verbose output
|
|
67
|
+
gasm-compiler compile gpu_kernel.as --verbose -o output.wgsl
|
|
118
68
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
```bash
|
|
122
|
-
cd ../core
|
|
123
|
-
deno test --allow-all
|
|
69
|
+
# Pipe output into another tool
|
|
70
|
+
gasm-compiler compile shader.wasm | tee shader.wgsl
|
|
124
71
|
```
|
|
125
72
|
|
|
126
|
-
|
|
73
|
+
---
|
|
127
74
|
|
|
128
|
-
|
|
75
|
+
## How It Works
|
|
129
76
|
|
|
130
77
|
```
|
|
131
|
-
AssemblyScript (.as)
|
|
78
|
+
AssemblyScript (.as/.ts) WebAssembly (.wasm)
|
|
79
|
+
↓ │
|
|
80
|
+
ASC Compiler │
|
|
81
|
+
↓ │
|
|
82
|
+
WebAssembly Binary ←────────────────┘
|
|
132
83
|
↓
|
|
133
|
-
|
|
84
|
+
Gasm Compiler (parse, validate, transform)
|
|
134
85
|
↓
|
|
135
|
-
|
|
136
|
-
↓
|
|
137
|
-
Core Compiler (Gasm)
|
|
138
|
-
├─ Parser
|
|
139
|
-
├─ Validator
|
|
140
|
-
├─ IR Generator
|
|
141
|
-
└─ Code Generator
|
|
142
|
-
↓
|
|
143
|
-
WGSL Code (.wgsl)
|
|
86
|
+
WGSL Compute Shader (.wgsl)
|
|
144
87
|
```
|
|
145
88
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
89
|
+
1. If the input is AssemblyScript, it is first compiled to WebAssembly using the AssemblyScript compiler
|
|
90
|
+
2. The WebAssembly binary is validated against the Gasm specification (GPU-safe subset)
|
|
91
|
+
3. The compiler transforms the Wasm into WGSL, restructuring control flow and lowering memory operations
|
|
92
|
+
4. The output is a valid WGSL compute shader ready for use with WebGPU
|
|
149
93
|
|
|
150
|
-
|
|
151
|
-
deno test --allow-all tests/cli_test.ts
|
|
94
|
+
---
|
|
152
95
|
|
|
153
|
-
|
|
154
|
-
deno test --allow-all --unstable-webgpu tests/execution_test.ts
|
|
96
|
+
## Writing Gasm-Compatible WebAssembly
|
|
155
97
|
|
|
156
|
-
|
|
98
|
+
Your WebAssembly module must conform to the Gasm subset:
|
|
157
99
|
|
|
158
|
-
-
|
|
159
|
-
-
|
|
160
|
-
-
|
|
161
|
-
-
|
|
162
|
-
- [ ] Integration with gpu.js or wgpu for execution
|
|
100
|
+
- Export a single linear memory as `"memory"`
|
|
101
|
+
- Only import globals from the `"gasm"` module (GPU built-ins like `global_invocation_id_x`)
|
|
102
|
+
- No function or memory imports
|
|
103
|
+
- Export your entry point function
|
|
163
104
|
|
|
164
|
-
|
|
105
|
+
**Example (WAT):**
|
|
106
|
+
```wasm
|
|
107
|
+
(module
|
|
108
|
+
(import "gasm" "global_invocation_id_x" (global $gid_x i32))
|
|
109
|
+
(memory (export "memory") 1)
|
|
110
|
+
(func (export "main")
|
|
111
|
+
;; Your GPU kernel logic here
|
|
112
|
+
;; Use $gid_x for per-thread indexing
|
|
113
|
+
))
|
|
114
|
+
```
|
|
165
115
|
|
|
166
|
-
- [
|
|
167
|
-
- [Gasm Specification](../../spec/gasm-v0.1.md)
|
|
168
|
-
- [AssemblyScript Handbook](https://www.assemblyscript.org/)
|
|
116
|
+
For the full list of available Gasm built-in globals and supported instructions, see the [`@gasm-compiler/core` documentation](https://www.npmjs.com/package/@gasm-compiler/core).
|
|
169
117
|
|
|
170
118
|
---
|
|
171
119
|
|
|
172
|
-
|
|
120
|
+
## Related Packages
|
|
121
|
+
|
|
122
|
+
- [`@gasm-compiler/core`](https://www.npmjs.com/package/@gasm-compiler/core) — Core compiler library (programmatic API)
|
|
123
|
+
- [`@gasm-compiler/math-reference`](https://www.npmjs.com/package/@gasm-compiler/math-reference) — CPU-side reference implementations of Gasm math functions
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## License
|
|
128
|
+
|
|
129
|
+
See [LICENSE](./LICENSE) for details.
|
package/dist/cli.js
CHANGED
|
@@ -9,10 +9,12 @@ import { parseArgs } from "jsr:@std/cli/parse-args";
|
|
|
9
9
|
import { resolve } from "jsr:@std/path";
|
|
10
10
|
import { ensureFile } from "jsr:@std/fs";
|
|
11
11
|
import {
|
|
12
|
+
compileToArtifact,
|
|
12
13
|
compileWithDiagnostics,
|
|
13
14
|
disassembleToWAT,
|
|
15
|
+
isParseError,
|
|
14
16
|
parseWasmModule,
|
|
15
|
-
|
|
17
|
+
validateGasmMetadataSchema
|
|
16
18
|
} from "@gasm-compiler/core";
|
|
17
19
|
function printDiagnostics(diagnostics, verbose) {
|
|
18
20
|
for (const w of diagnostics.warnings) {
|
|
@@ -24,13 +26,17 @@ function printDiagnostics(diagnostics, verbose) {
|
|
|
24
26
|
for (const d of diagnostics.demotions) {
|
|
25
27
|
counts.set(d.kind, (counts.get(d.kind) ?? 0) + 1);
|
|
26
28
|
}
|
|
27
|
-
const parts = [...counts.entries()].map(
|
|
29
|
+
const parts = [...counts.entries()].map(
|
|
30
|
+
([kind, count]) => `${kind} (${count})`
|
|
31
|
+
);
|
|
28
32
|
console.error(`demotions: ${parts.join(", ")}`);
|
|
29
33
|
}
|
|
30
34
|
}
|
|
31
35
|
async function compileAssemblyScriptToWGSL(inputFile, options = {}) {
|
|
32
36
|
const {
|
|
33
37
|
output: outputFile,
|
|
38
|
+
metadata: metadataFile,
|
|
39
|
+
specVersion: requestedSpecVersion,
|
|
34
40
|
watOutput: watOutputFile,
|
|
35
41
|
verbose = false,
|
|
36
42
|
keepWasm = false,
|
|
@@ -41,6 +47,17 @@ async function compileAssemblyScriptToWGSL(inputFile, options = {}) {
|
|
|
41
47
|
sourceMapping
|
|
42
48
|
} = options;
|
|
43
49
|
try {
|
|
50
|
+
if (requestedSpecVersion !== void 0 && requestedSpecVersion !== "0.1" && requestedSpecVersion !== "0.2") {
|
|
51
|
+
throw new Error(
|
|
52
|
+
`Unsupported spec version "${requestedSpecVersion}"; expected 0.1 or 0.2`
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
const specVersion = requestedSpecVersion ?? "0.2";
|
|
56
|
+
if (metadataFile && specVersion !== "0.2") {
|
|
57
|
+
throw new Error(
|
|
58
|
+
"--metadata requires --spec-version 0.2"
|
|
59
|
+
);
|
|
60
|
+
}
|
|
44
61
|
if (verbose) console.log(`[1/4] Validating input file: ${inputFile}`);
|
|
45
62
|
const resolvedInput = resolve(inputFile);
|
|
46
63
|
const stats = await Deno.stat(resolvedInput);
|
|
@@ -49,7 +66,9 @@ async function compileAssemblyScriptToWGSL(inputFile, options = {}) {
|
|
|
49
66
|
}
|
|
50
67
|
const isWasm = resolvedInput.endsWith(".wasm");
|
|
51
68
|
if (!isWasm && !resolvedInput.endsWith(".as") && !resolvedInput.endsWith(".ts")) {
|
|
52
|
-
console.warn(
|
|
69
|
+
console.warn(
|
|
70
|
+
"Warning: Input file does not have .as, .ts, or .wasm extension"
|
|
71
|
+
);
|
|
53
72
|
}
|
|
54
73
|
let wasmPath = resolvedInput.replace(/\.(as|ts)$/, ".wasm");
|
|
55
74
|
if (!isWasm) {
|
|
@@ -104,28 +123,63 @@ ${errorMsg}`);
|
|
|
104
123
|
const demotionPolicy = {};
|
|
105
124
|
if (denyF64Demotion) demotionPolicy.f64 = "deny";
|
|
106
125
|
if (allowI64Demotion) demotionPolicy.i64 = "allow-lossy";
|
|
107
|
-
const validLevels = [
|
|
126
|
+
const validLevels = [
|
|
127
|
+
"none",
|
|
128
|
+
"minimal",
|
|
129
|
+
"normal",
|
|
130
|
+
"detailed",
|
|
131
|
+
"verbose"
|
|
132
|
+
];
|
|
108
133
|
let sourceMappingLevel;
|
|
109
134
|
if (sourceMapping) {
|
|
110
135
|
if (validLevels.includes(sourceMapping)) {
|
|
111
136
|
sourceMappingLevel = sourceMapping;
|
|
112
137
|
} else {
|
|
113
|
-
console.warn(
|
|
138
|
+
console.warn(
|
|
139
|
+
`Warning: Unknown source-mapping level "${sourceMapping}", using "normal"`
|
|
140
|
+
);
|
|
114
141
|
sourceMappingLevel = "normal";
|
|
115
142
|
}
|
|
116
143
|
}
|
|
117
|
-
const
|
|
144
|
+
const compileOptions = {
|
|
118
145
|
optimize,
|
|
119
146
|
demotionPolicy,
|
|
120
147
|
warningsAsErrors,
|
|
121
|
-
sourceMapping: sourceMappingLevel
|
|
122
|
-
|
|
148
|
+
sourceMapping: sourceMappingLevel,
|
|
149
|
+
specVersion
|
|
150
|
+
};
|
|
151
|
+
const result = metadataFile ? compileToArtifact(wasmBytes, compileOptions) : compileWithDiagnostics(wasmBytes, compileOptions);
|
|
123
152
|
printDiagnostics(result.diagnostics, verbose);
|
|
124
153
|
if (!result.ok) {
|
|
125
154
|
const first = result.diagnostics.errors[0];
|
|
126
|
-
throw new Error(
|
|
155
|
+
throw new Error(
|
|
156
|
+
first ? `${first.code}: ${first.message}` : "Compilation failed"
|
|
157
|
+
);
|
|
127
158
|
}
|
|
128
159
|
const wgslCode = result.wgsl;
|
|
160
|
+
if (metadataFile) {
|
|
161
|
+
if (!("metadata" in result)) {
|
|
162
|
+
throw new Error("Compiler did not produce metadata");
|
|
163
|
+
}
|
|
164
|
+
const schema = validateGasmMetadataSchema(result.metadata);
|
|
165
|
+
if (!schema.valid) {
|
|
166
|
+
throw new Error(
|
|
167
|
+
`Generated metadata failed schema validation: ${schema.errors.join(", ")}`
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
const resolvedMetadata = resolve(metadataFile);
|
|
171
|
+
await ensureFile(resolvedMetadata);
|
|
172
|
+
await Deno.writeTextFile(
|
|
173
|
+
resolvedMetadata,
|
|
174
|
+
`${JSON.stringify(result.metadata, null, 2)}
|
|
175
|
+
`
|
|
176
|
+
);
|
|
177
|
+
if (verbose) {
|
|
178
|
+
console.log(`\u2713 Metadata written to: ${resolvedMetadata}`);
|
|
179
|
+
} else {
|
|
180
|
+
console.log(`\u2713 Metadata written to: ${metadataFile}`);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
129
183
|
if (watOutputFile) {
|
|
130
184
|
if (verbose) console.log("[4a/4] Generating WAT disassembly...");
|
|
131
185
|
const parseResult = parseWasmModule(wasmBytes);
|
|
@@ -140,7 +194,9 @@ ${errorMsg}`);
|
|
|
140
194
|
console.log(`\u2713 WAT written to: ${watOutputFile}`);
|
|
141
195
|
}
|
|
142
196
|
} else {
|
|
143
|
-
console.warn(
|
|
197
|
+
console.warn(
|
|
198
|
+
`Warning: Failed to parse WASM for WAT disassembly: ${parseResult.message}`
|
|
199
|
+
);
|
|
144
200
|
}
|
|
145
201
|
}
|
|
146
202
|
if (outputFile) {
|
|
@@ -174,7 +230,10 @@ async function getAssemblyScriptPath() {
|
|
|
174
230
|
const possiblePaths = [
|
|
175
231
|
// Relative to CLI package
|
|
176
232
|
resolve(scriptDir, "../../node_modules/.bin/asc"),
|
|
177
|
-
resolve(
|
|
233
|
+
resolve(
|
|
234
|
+
scriptDir,
|
|
235
|
+
"../../node_modules/.pnpm/assemblyscript@0.28.9/node_modules/assemblyscript/node_modules/.bin/asc"
|
|
236
|
+
),
|
|
178
237
|
resolve(scriptDir, "../node_modules/.bin/asc"),
|
|
179
238
|
resolve(scriptDir, "../examples/node_modules/.bin/asc"),
|
|
180
239
|
// Relative to workspace root
|
|
@@ -196,10 +255,16 @@ async function getAssemblyScriptPath() {
|
|
|
196
255
|
}
|
|
197
256
|
|
|
198
257
|
// src/cli.ts
|
|
199
|
-
var VERSION = "0.
|
|
258
|
+
var VERSION = "0.2.0";
|
|
200
259
|
async function main() {
|
|
201
260
|
const args = parseArgs(Deno.args, {
|
|
202
|
-
string: [
|
|
261
|
+
string: [
|
|
262
|
+
"output",
|
|
263
|
+
"metadata",
|
|
264
|
+
"spec-version",
|
|
265
|
+
"wat-output",
|
|
266
|
+
"source-mapping"
|
|
267
|
+
],
|
|
203
268
|
boolean: [
|
|
204
269
|
"help",
|
|
205
270
|
"version",
|
|
@@ -229,12 +294,16 @@ async function main() {
|
|
|
229
294
|
if (command === "compile") {
|
|
230
295
|
if (args._.length < 2) {
|
|
231
296
|
console.error("Error: compile requires an input file");
|
|
232
|
-
console.error(
|
|
297
|
+
console.error(
|
|
298
|
+
"Usage: cli compile <input.as|wasm> [--output <output.wgsl>]"
|
|
299
|
+
);
|
|
233
300
|
Deno.exit(1);
|
|
234
301
|
}
|
|
235
302
|
const inputFile = args._[1];
|
|
236
303
|
const options = {
|
|
237
304
|
output: args.output,
|
|
305
|
+
metadata: args.metadata,
|
|
306
|
+
specVersion: args["spec-version"],
|
|
238
307
|
watOutput: args["wat-output"],
|
|
239
308
|
verbose: args.verbose,
|
|
240
309
|
keepWasm: args["keep-wasm"],
|
|
@@ -251,7 +320,10 @@ async function main() {
|
|
|
251
320
|
Deno.exit(1);
|
|
252
321
|
}
|
|
253
322
|
} catch (error) {
|
|
254
|
-
console.error(
|
|
323
|
+
console.error(
|
|
324
|
+
"Error:",
|
|
325
|
+
error instanceof Error ? error.message : String(error)
|
|
326
|
+
);
|
|
255
327
|
if (args.verbose && error instanceof Error && error.stack) {
|
|
256
328
|
console.error("\nStack trace:");
|
|
257
329
|
console.error(error.stack);
|
|
@@ -274,6 +346,8 @@ COMMANDS:
|
|
|
274
346
|
|
|
275
347
|
OPTIONS:
|
|
276
348
|
--output <file> Write WGSL output to file (default: stdout)
|
|
349
|
+
--metadata <file> Write validated Gasm v0.2 metadata sidecar JSON
|
|
350
|
+
--spec-version <version> Compile as Gasm 0.1 or 0.2 (default: 0.2)
|
|
277
351
|
--wat-output <file> Also write WAT (WebAssembly Text) disassembly to file
|
|
278
352
|
--verbose Show detailed compilation steps
|
|
279
353
|
--keep-wasm Keep intermediate WASM files
|
|
@@ -306,4 +380,3 @@ main().catch((error) => {
|
|
|
306
380
|
console.error("Fatal error:", error);
|
|
307
381
|
Deno.exit(1);
|
|
308
382
|
});
|
|
309
|
-
//# sourceMappingURL=cli.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gasm-compiler/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "CLI for compiling WebAssembly/AssemblyScript to WGSL using Gasm Compiler",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/cli.js",
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
},
|
|
18
18
|
"files": [
|
|
19
19
|
"dist",
|
|
20
|
+
"!dist/**/*.map",
|
|
20
21
|
"LICENSE",
|
|
21
22
|
"README.md"
|
|
22
23
|
],
|
|
@@ -34,7 +35,7 @@
|
|
|
34
35
|
"cli"
|
|
35
36
|
],
|
|
36
37
|
"dependencies": {
|
|
37
|
-
"@gasm-compiler/core": "0.
|
|
38
|
+
"@gasm-compiler/core": "0.4.0"
|
|
38
39
|
},
|
|
39
40
|
"devDependencies": {
|
|
40
41
|
"assemblyscript": "v0.28.9",
|
package/dist/cli.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/compiler.ts"],"sourcesContent":["/**\n * Gasm Compiler CLI - Main Entry Point\n *\n * Provides a command-line interface for compiling AssemblyScript to WGSL\n * using the Gasm compiler.\n */\n\nimport { parseArgs } from \"jsr:@std/cli/parse-args\";\nimport { compileAssemblyScriptToWGSL } from \"./compiler.ts\";\n\nconst VERSION = \"0.1.0\";\n\ninterface CLIOptions {\n help?: boolean;\n version?: boolean;\n output?: string;\n \"wat-output\"?: string;\n verbose?: boolean;\n \"keep-wasm\"?: boolean;\n optimize?: boolean;\n \"deny-f64-demotion\"?: boolean;\n \"allow-i64-demotion\"?: boolean;\n \"warnings-as-errors\"?: boolean;\n \"source-mapping\"?: string;\n _: string[];\n}\n\nasync function main() {\n const args = parseArgs(Deno.args, {\n string: [\"output\", \"wat-output\", \"source-mapping\"],\n boolean: [\n \"help\",\n \"version\",\n \"verbose\",\n \"keep-wasm\",\n \"optimize\",\n \"deny-f64-demotion\",\n \"allow-i64-demotion\",\n \"warnings-as-errors\",\n ],\n default: {\n verbose: false,\n \"keep-wasm\": false,\n optimize: false,\n },\n }) as CLIOptions;\n\n // Handle --version\n if (args.version) {\n console.log(`Gasm Compiler CLI v${VERSION}`);\n Deno.exit(0);\n }\n\n // Handle --help or no command\n if (args.help || args._.length === 0) {\n printHelp();\n Deno.exit(args.help ? 0 : 1);\n }\n\n const command = args._[0];\n\n try {\n if (command === \"compile\") {\n if (args._.length < 2) {\n console.error(\"Error: compile requires an input file\");\n console.error(\"Usage: cli compile <input.as|wasm> [--output <output.wgsl>]\");\n Deno.exit(1);\n }\n\n const inputFile = args._[1] as string;\n const options = {\n output: args.output as string | undefined,\n watOutput: args[\"wat-output\"] as string | undefined,\n verbose: args.verbose as boolean,\n keepWasm: args[\"keep-wasm\"] as boolean,\n optimize: args.optimize as boolean,\n denyF64Demotion: args[\"deny-f64-demotion\"] as boolean,\n allowI64Demotion: args[\"allow-i64-demotion\"] as boolean,\n warningsAsErrors: args[\"warnings-as-errors\"] as boolean,\n sourceMapping: args[\"source-mapping\"] as string | undefined,\n };\n\n await compileAssemblyScriptToWGSL(inputFile, options);\n } else {\n console.error(`Unknown command: ${command}`);\n printHelp();\n Deno.exit(1);\n }\n } catch (error) {\n console.error(\"Error:\", error instanceof Error ? error.message : String(error));\n if (args.verbose && error instanceof Error && error.stack) {\n console.error(\"\\nStack trace:\");\n console.error(error.stack);\n }\n Deno.exit(1);\n }\n}\n\nfunction printHelp() {\n console.log(`\nGasm Compiler CLI v${VERSION}\nCompile WebAssembly or AssemblyScript to WGSL using the Gasm compiler\n\nUSAGE:\n gasm-compiler <COMMAND> [OPTIONS] [ARGS]\n\nCOMMANDS:\n compile <input.wasm|.as> Compile WebAssembly or AssemblyScript to WGSL\n help Show this help message\n version Show version information\n\nOPTIONS:\n --output <file> Write WGSL output to file (default: stdout)\n --wat-output <file> Also write WAT (WebAssembly Text) disassembly to file\n --verbose Show detailed compilation steps\n --keep-wasm Keep intermediate WASM files\n --optimize Apply optimization passes\n --deny-f64-demotion Fail if f64 would be demoted to f32\n --allow-i64-demotion Allow lossy i64→i32 demotion (mod 2^32)\n --warnings-as-errors Treat compiler warnings as errors\n --source-mapping <level> Add source mapping comments (none, minimal, normal, detailed, verbose)\n --help Show this help message\n --version Show version information\n\nEXAMPLES:\n # Compile WASM to stdout\n deno run --allow-all src/cli.ts compile input.wasm\n\n # Compile WASM to file\n deno run --allow-all src/cli.ts compile input.wasm --output output.wgsl\n\n # Compile with verbose output\n deno run --allow-all src/cli.ts compile input.wasm --verbose --output output.wgsl\n\n # Compile with optimization\n deno run --allow-all src/cli.ts compile input.wasm --optimize --output output.wgsl\n\nDOCUMENTATION:\n https://github.com/MartinEricsson/gasm-compiler\n `);\n}\n\n// Run main\nmain().catch((error) => {\n console.error(\"Fatal error:\", error);\n Deno.exit(1);\n});\n","/**\n * Gasm Compiler CLI - Compilation Orchestration\n *\n * Handles the compilation pipeline:\n * AssemblyScript → WASM → Gasm Validation → IR → WGSL\n * \n * Note: This Deno-based CLI wrapper will be deprecated in favor of\n * the Node.js compiler exported from @gasm-compiler/core/compiler\n */\n\nimport { resolve } from \"jsr:@std/path\";\nimport { ensureFile } from \"jsr:@std/fs\";\nimport { \n compileWithDiagnostics, \n disassembleToWAT,\n parseWasmModule,\n isParseError,\n type CompileDiagnostics \n} from \"@gasm-compiler/core\";\n\nexport interface CompileOptions {\n output?: string;\n watOutput?: string;\n verbose?: boolean;\n keepWasm?: boolean;\n optimize?: boolean;\n denyF64Demotion?: boolean;\n allowI64Demotion?: boolean;\n warningsAsErrors?: boolean;\n sourceMapping?: string;\n}\n\nfunction printDiagnostics(diagnostics: CompileDiagnostics, verbose: boolean): void {\n for (const w of diagnostics.warnings) {\n const where = w.functionName ? ` (${w.functionName})` : \"\";\n console.error(`warning${where}: ${w.message}`);\n }\n\n if (verbose && diagnostics.demotions.length > 0) {\n const counts = new Map<string, number>();\n for (const d of diagnostics.demotions) {\n counts.set(d.kind, (counts.get(d.kind) ?? 0) + 1);\n }\n const parts = [...counts.entries()].map(([kind, count]) => `${kind} (${count})`);\n console.error(`demotions: ${parts.join(\", \")}`);\n }\n}\n\n/**\n * Compiles an AssemblyScript file to WGSL using the Gasm compiler.\n *\n * Pipeline:\n * 1. Validate input file exists\n * 2. Compile AssemblyScript to WASM using asc\n * 3. Read WASM binary\n * 4. Compile WASM to WGSL using Gasm\n * 5. Write output to file or stdout\n *\n * @param inputFile - Path to .as file\n * @param options - Compilation options\n */\nexport async function compileAssemblyScriptToWGSL(\n inputFile: string,\n options: CompileOptions = {},\n) {\n const {\n output: outputFile,\n watOutput: watOutputFile,\n verbose = false,\n keepWasm = false,\n optimize = false,\n denyF64Demotion = false,\n allowI64Demotion = false,\n warningsAsErrors = false,\n sourceMapping,\n } = options;\n\n try {\n // 1. Validate input file\n if (verbose) console.log(`[1/4] Validating input file: ${inputFile}`);\n\n const resolvedInput = resolve(inputFile);\n const stats = await Deno.stat(resolvedInput);\n\n if (!stats.isFile) {\n throw new Error(`Not a file: ${inputFile}`);\n }\n\n const isWasm = resolvedInput.endsWith(\".wasm\");\n\n if (!isWasm && !resolvedInput.endsWith(\".as\") && !resolvedInput.endsWith(\".ts\")) {\n console.warn(\"Warning: Input file does not have .as, .ts, or .wasm extension\");\n }\n\n let wasmPath = resolvedInput.replace(/\\.(as|ts)$/, \".wasm\");\n\n // 2. Compile AssemblyScript to WASM (if input is not already WASM)\n if (!isWasm) {\n if (verbose) console.log(\"[2/4] Compiling AssemblyScript to WASM...\");\n\n const asmPath = await getAssemblyScriptPath();\n\n // If input ends with .as, create a temporary .ts file for asc\n // (asc appends .ts to .as files, causing lookup failures)\n let inputForAsc = resolvedInput;\n let cleanupTsFile = false;\n\n if (resolvedInput.endsWith(\".as\")) {\n inputForAsc = resolvedInput.replace(/\\.as$/, \".ts\");\n cleanupTsFile = true;\n\n try {\n // Create a symlink from .as to .ts\n await Deno.symlink(resolvedInput, inputForAsc);\n } catch (e) {\n if (!(e instanceof Deno.errors.AlreadyExists)) {\n // If symlink fails for other reasons, copy the file instead\n const content = await Deno.readTextFile(resolvedInput);\n await Deno.writeTextFile(inputForAsc, content);\n }\n }\n }\n\n const compileCommand = new Deno.Command(asmPath, {\n args: [inputForAsc, \"-o\", wasmPath],\n stdout: \"piped\",\n stderr: \"piped\",\n });\n\n const compileProcess = compileCommand.spawn();\n const { success, stdout, stderr } = await compileProcess.output();\n\n // Clean up temporary .ts file if we created it\n if (cleanupTsFile) {\n try {\n await Deno.remove(inputForAsc);\n } catch {\n // Ignore cleanup errors\n }\n }\n\n if (!success) {\n const errorMsg = new TextDecoder().decode(stderr);\n throw new Error(`AssemblyScript compilation failed:\\n${errorMsg}`);\n }\n\n if (verbose) {\n const output = new TextDecoder().decode(stdout);\n if (output) console.log(output);\n }\n } else {\n if (verbose) console.log(\"[2/4] Input is WASM, skipping compilation...\");\n wasmPath = resolvedInput;\n }\n\n // 3. Read WASM binary and compile to WGSL\n if (verbose) console.log(\"[3/4] Reading WASM binary...\");\n\n const wasmBytes = await Deno.readFile(wasmPath);\n\n if (verbose) {\n console.log(` WASM size: ${wasmBytes.length} bytes`);\n console.log(\"[4/4] Compiling WASM to WGSL using Gasm...\");\n }\n\n const demotionPolicy: {\n f64?: \"allow\" | \"deny\";\n i64?: \"deny\" | \"allow-lossy\";\n } = {};\n if (denyF64Demotion) demotionPolicy.f64 = \"deny\";\n if (allowI64Demotion) demotionPolicy.i64 = \"allow-lossy\";\n\n // Parse source mapping level\n type SourceMappingLevel = \"none\" | \"minimal\" | \"normal\" | \"detailed\" | \"verbose\";\n const validLevels: SourceMappingLevel[] = [\"none\", \"minimal\", \"normal\", \"detailed\", \"verbose\"];\n let sourceMappingLevel: SourceMappingLevel | undefined;\n if (sourceMapping) {\n if (validLevels.includes(sourceMapping as SourceMappingLevel)) {\n sourceMappingLevel = sourceMapping as SourceMappingLevel;\n } else {\n console.warn(`Warning: Unknown source-mapping level \"${sourceMapping}\", using \"normal\"`);\n sourceMappingLevel = \"normal\";\n }\n }\n\n const result = compileWithDiagnostics(wasmBytes, {\n optimize,\n demotionPolicy,\n warningsAsErrors,\n sourceMapping: sourceMappingLevel,\n });\n\n printDiagnostics(result.diagnostics, verbose);\n\n if (!result.ok) {\n const first = result.diagnostics.errors[0];\n throw new Error(first?.message ?? \"Compilation failed\");\n }\n\n const wgslCode = result.wgsl;\n\n // 4. Generate WAT disassembly if requested\n if (watOutputFile) {\n if (verbose) console.log(\"[4a/4] Generating WAT disassembly...\");\n \n // Parse the WASM to get the module structure\n const parseResult = parseWasmModule(wasmBytes);\n \n // Check if parsing succeeded\n if (!isParseError(parseResult)) {\n const watCode = disassembleToWAT(parseResult);\n const resolvedWatOutput = resolve(watOutputFile);\n await ensureFile(resolvedWatOutput);\n await Deno.writeTextFile(resolvedWatOutput, watCode);\n \n if (verbose) {\n console.log(`✓ WAT disassembly written to: ${resolvedWatOutput}`);\n } else {\n console.log(`✓ WAT written to: ${watOutputFile}`);\n }\n } else {\n console.warn(`Warning: Failed to parse WASM for WAT disassembly: ${parseResult.message}`);\n }\n }\n\n // 5. Write WGSL output\n if (outputFile) {\n const resolvedOutput = resolve(outputFile);\n await ensureFile(resolvedOutput);\n await Deno.writeTextFile(resolvedOutput, wgslCode);\n\n if (verbose) {\n console.log(`✓ Successfully compiled to: ${resolvedOutput}`);\n } else {\n console.log(`✓ Compiled to: ${outputFile}`);\n }\n } else {\n console.log(wgslCode);\n }\n\n // Clean up intermediate WASM if not keeping (and we generated it)\n if (!keepWasm && !isWasm) {\n try {\n await Deno.remove(wasmPath);\n if (verbose) console.log(\" Cleaned up intermediate WASM file\");\n } catch {\n // Ignore cleanup errors\n }\n }\n } catch (error) {\n if (error instanceof Error) {\n throw error;\n }\n throw new Error(`Unknown error: ${String(error)}`);\n }\n}\n\n/**\n * Locates the AssemblyScript compiler executable\n * Tries multiple common paths\n */\nasync function getAssemblyScriptPath(): Promise<string> {\n // Get the directory of the current script for relative path resolution\n const scriptDir = new URL(\".\", import.meta.url).pathname;\n\n const possiblePaths = [\n // Relative to CLI package\n resolve(scriptDir, \"../../node_modules/.bin/asc\"),\n resolve(scriptDir, \"../../node_modules/.pnpm/assemblyscript@0.28.9/node_modules/assemblyscript/node_modules/.bin/asc\"),\n resolve(scriptDir, \"../node_modules/.bin/asc\"),\n resolve(scriptDir, \"../examples/node_modules/.bin/asc\"),\n \n // Relative to workspace root\n resolve(scriptDir, \"../../node_modules/.bin/asc\"),\n resolve(scriptDir, \"../../../node_modules/.bin/asc\"),\n \n // AssemblyScript toy example\n resolve(scriptDir, \"../../assemblyscript-toy/node_modules/.bin/asc\"),\n ];\n\n for (const path of possiblePaths) {\n try {\n const stat = await Deno.stat(path);\n if (stat.isFile) {\n return path;\n }\n } catch {\n // Path doesn't exist, try next\n }\n }\n\n // If not found, assume 'asc' is in PATH\n return \"asc\";\n}\n"],"mappings":";;;;;AAOA,SAAS,iBAAiB;;;ACG1B,SAAS,eAAe;AACxB,SAAS,kBAAkB;AAC3B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AAcP,SAAS,iBAAiB,aAAiC,SAAwB;AACjF,aAAW,KAAK,YAAY,UAAU;AACpC,UAAM,QAAQ,EAAE,eAAe,KAAK,EAAE,YAAY,MAAM;AACxD,YAAQ,MAAM,UAAU,KAAK,KAAK,EAAE,OAAO,EAAE;AAAA,EAC/C;AAEA,MAAI,WAAW,YAAY,UAAU,SAAS,GAAG;AAC/C,UAAM,SAAS,oBAAI,IAAoB;AACvC,eAAW,KAAK,YAAY,WAAW;AACrC,aAAO,IAAI,EAAE,OAAO,OAAO,IAAI,EAAE,IAAI,KAAK,KAAK,CAAC;AAAA,IAClD;AACA,UAAM,QAAQ,CAAC,GAAG,OAAO,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,GAAG,IAAI,KAAK,KAAK,GAAG;AAC/E,YAAQ,MAAM,cAAc,MAAM,KAAK,IAAI,CAAC,EAAE;AAAA,EAChD;AACF;AAeA,eAAsB,4BACpB,WACA,UAA0B,CAAC,GAC3B;AACA,QAAM;AAAA,IACJ,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,UAAU;AAAA,IACV,WAAW;AAAA,IACX,WAAW;AAAA,IACX,kBAAkB;AAAA,IAClB,mBAAmB;AAAA,IACnB,mBAAmB;AAAA,IACnB;AAAA,EACF,IAAI;AAEJ,MAAI;AAEF,QAAI,QAAS,SAAQ,IAAI,gCAAgC,SAAS,EAAE;AAEpE,UAAM,gBAAgB,QAAQ,SAAS;AACvC,UAAM,QAAQ,MAAM,KAAK,KAAK,aAAa;AAE3C,QAAI,CAAC,MAAM,QAAQ;AACjB,YAAM,IAAI,MAAM,eAAe,SAAS,EAAE;AAAA,IAC5C;AAEA,UAAM,SAAS,cAAc,SAAS,OAAO;AAE7C,QAAI,CAAC,UAAU,CAAC,cAAc,SAAS,KAAK,KAAK,CAAC,cAAc,SAAS,KAAK,GAAG;AAC/E,cAAQ,KAAK,gEAAgE;AAAA,IAC/E;AAEA,QAAI,WAAW,cAAc,QAAQ,cAAc,OAAO;AAG1D,QAAI,CAAC,QAAQ;AACX,UAAI,QAAS,SAAQ,IAAI,2CAA2C;AAEpE,YAAM,UAAU,MAAM,sBAAsB;AAI5C,UAAI,cAAc;AAClB,UAAI,gBAAgB;AAEpB,UAAI,cAAc,SAAS,KAAK,GAAG;AACjC,sBAAc,cAAc,QAAQ,SAAS,KAAK;AAClD,wBAAgB;AAEhB,YAAI;AAEF,gBAAM,KAAK,QAAQ,eAAe,WAAW;AAAA,QAC/C,SAAS,GAAG;AACV,cAAI,EAAE,aAAa,KAAK,OAAO,gBAAgB;AAE7C,kBAAM,UAAU,MAAM,KAAK,aAAa,aAAa;AACrD,kBAAM,KAAK,cAAc,aAAa,OAAO;AAAA,UAC/C;AAAA,QACF;AAAA,MACF;AAEA,YAAM,iBAAiB,IAAI,KAAK,QAAQ,SAAS;AAAA,QAC/C,MAAM,CAAC,aAAa,MAAM,QAAQ;AAAA,QAClC,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV,CAAC;AAED,YAAM,iBAAiB,eAAe,MAAM;AAC5C,YAAM,EAAE,SAAS,QAAQ,OAAO,IAAI,MAAM,eAAe,OAAO;AAGhE,UAAI,eAAe;AACjB,YAAI;AACF,gBAAM,KAAK,OAAO,WAAW;AAAA,QAC/B,QAAQ;AAAA,QAER;AAAA,MACF;AAEA,UAAI,CAAC,SAAS;AACZ,cAAM,WAAW,IAAI,YAAY,EAAE,OAAO,MAAM;AAChD,cAAM,IAAI,MAAM;AAAA,EAAuC,QAAQ,EAAE;AAAA,MACnE;AAEA,UAAI,SAAS;AACX,cAAM,SAAS,IAAI,YAAY,EAAE,OAAO,MAAM;AAC9C,YAAI,OAAQ,SAAQ,IAAI,MAAM;AAAA,MAChC;AAAA,IACF,OAAO;AACL,UAAI,QAAS,SAAQ,IAAI,8CAA8C;AACvE,iBAAW;AAAA,IACb;AAGA,QAAI,QAAS,SAAQ,IAAI,8BAA8B;AAEvD,UAAM,YAAY,MAAM,KAAK,SAAS,QAAQ;AAE9C,QAAI,SAAS;AACX,cAAQ,IAAI,kBAAkB,UAAU,MAAM,QAAQ;AACtD,cAAQ,IAAI,4CAA4C;AAAA,IAC1D;AAEA,UAAM,iBAGF,CAAC;AACL,QAAI,gBAAiB,gBAAe,MAAM;AAC1C,QAAI,iBAAkB,gBAAe,MAAM;AAI3C,UAAM,cAAoC,CAAC,QAAQ,WAAW,UAAU,YAAY,SAAS;AAC7F,QAAI;AACJ,QAAI,eAAe;AACjB,UAAI,YAAY,SAAS,aAAmC,GAAG;AAC7D,6BAAqB;AAAA,MACvB,OAAO;AACL,gBAAQ,KAAK,0CAA0C,aAAa,mBAAmB;AACvF,6BAAqB;AAAA,MACvB;AAAA,IACF;AAEA,UAAM,SAAS,uBAAuB,WAAW;AAAA,MAC/C;AAAA,MACA;AAAA,MACA;AAAA,MACA,eAAe;AAAA,IACjB,CAAC;AAED,qBAAiB,OAAO,aAAa,OAAO;AAE5C,QAAI,CAAC,OAAO,IAAI;AACd,YAAM,QAAQ,OAAO,YAAY,OAAO,CAAC;AACzC,YAAM,IAAI,MAAM,OAAO,WAAW,oBAAoB;AAAA,IACxD;AAEA,UAAM,WAAW,OAAO;AAGxB,QAAI,eAAe;AACjB,UAAI,QAAS,SAAQ,IAAI,sCAAsC;AAG/D,YAAM,cAAc,gBAAgB,SAAS;AAG7C,UAAI,CAAC,aAAa,WAAW,GAAG;AAC9B,cAAM,UAAU,iBAAiB,WAAW;AAC5C,cAAM,oBAAoB,QAAQ,aAAa;AAC/C,cAAM,WAAW,iBAAiB;AAClC,cAAM,KAAK,cAAc,mBAAmB,OAAO;AAEnD,YAAI,SAAS;AACX,kBAAQ,IAAI,sCAAiC,iBAAiB,EAAE;AAAA,QAClE,OAAO;AACL,kBAAQ,IAAI,0BAAqB,aAAa,EAAE;AAAA,QAClD;AAAA,MACF,OAAO;AACL,gBAAQ,KAAK,sDAAsD,YAAY,OAAO,EAAE;AAAA,MAC1F;AAAA,IACF;AAGA,QAAI,YAAY;AACd,YAAM,iBAAiB,QAAQ,UAAU;AACzC,YAAM,WAAW,cAAc;AAC/B,YAAM,KAAK,cAAc,gBAAgB,QAAQ;AAEjD,UAAI,SAAS;AACX,gBAAQ,IAAI,oCAA+B,cAAc,EAAE;AAAA,MAC7D,OAAO;AACL,gBAAQ,IAAI,uBAAkB,UAAU,EAAE;AAAA,MAC5C;AAAA,IACF,OAAO;AACL,cAAQ,IAAI,QAAQ;AAAA,IACtB;AAGA,QAAI,CAAC,YAAY,CAAC,QAAQ;AACxB,UAAI;AACF,cAAM,KAAK,OAAO,QAAQ;AAC1B,YAAI,QAAS,SAAQ,IAAI,uCAAuC;AAAA,MAClE,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,QAAI,iBAAiB,OAAO;AAC1B,YAAM;AAAA,IACR;AACA,UAAM,IAAI,MAAM,kBAAkB,OAAO,KAAK,CAAC,EAAE;AAAA,EACnD;AACF;AAMA,eAAe,wBAAyC;AAEtD,QAAM,YAAY,IAAI,IAAI,KAAK,YAAY,GAAG,EAAE;AAEhD,QAAM,gBAAgB;AAAA;AAAA,IAEpB,QAAQ,WAAW,6BAA6B;AAAA,IAChD,QAAQ,WAAW,kGAAkG;AAAA,IACrH,QAAQ,WAAW,0BAA0B;AAAA,IAC7C,QAAQ,WAAW,mCAAmC;AAAA;AAAA,IAGtD,QAAQ,WAAW,6BAA6B;AAAA,IAChD,QAAQ,WAAW,gCAAgC;AAAA;AAAA,IAGnD,QAAQ,WAAW,gDAAgD;AAAA,EACrE;AAEA,aAAW,QAAQ,eAAe;AAChC,QAAI;AACF,YAAM,OAAO,MAAM,KAAK,KAAK,IAAI;AACjC,UAAI,KAAK,QAAQ;AACf,eAAO;AAAA,MACT;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AAGA,SAAO;AACT;;;AD3RA,IAAM,UAAU;AAiBhB,eAAe,OAAO;AACpB,QAAM,OAAO,UAAU,KAAK,MAAM;AAAA,IAChC,QAAQ,CAAC,UAAU,cAAc,gBAAgB;AAAA,IACjD,SAAS;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP,SAAS;AAAA,MACT,aAAa;AAAA,MACb,UAAU;AAAA,IACZ;AAAA,EACF,CAAC;AAGD,MAAI,KAAK,SAAS;AAChB,YAAQ,IAAI,sBAAsB,OAAO,EAAE;AAC3C,SAAK,KAAK,CAAC;AAAA,EACb;AAGA,MAAI,KAAK,QAAQ,KAAK,EAAE,WAAW,GAAG;AACpC,cAAU;AACV,SAAK,KAAK,KAAK,OAAO,IAAI,CAAC;AAAA,EAC7B;AAEA,QAAM,UAAU,KAAK,EAAE,CAAC;AAExB,MAAI;AACF,QAAI,YAAY,WAAW;AACzB,UAAI,KAAK,EAAE,SAAS,GAAG;AACrB,gBAAQ,MAAM,uCAAuC;AACrD,gBAAQ,MAAM,6DAA6D;AAC3E,aAAK,KAAK,CAAC;AAAA,MACb;AAEA,YAAM,YAAY,KAAK,EAAE,CAAC;AAC1B,YAAM,UAAU;AAAA,QACd,QAAQ,KAAK;AAAA,QACb,WAAW,KAAK,YAAY;AAAA,QAC5B,SAAS,KAAK;AAAA,QACd,UAAU,KAAK,WAAW;AAAA,QAC1B,UAAU,KAAK;AAAA,QACf,iBAAiB,KAAK,mBAAmB;AAAA,QACzC,kBAAkB,KAAK,oBAAoB;AAAA,QAC3C,kBAAkB,KAAK,oBAAoB;AAAA,QAC3C,eAAe,KAAK,gBAAgB;AAAA,MACtC;AAEA,YAAM,4BAA4B,WAAW,OAAO;AAAA,IACtD,OAAO;AACL,cAAQ,MAAM,oBAAoB,OAAO,EAAE;AAC3C,gBAAU;AACV,WAAK,KAAK,CAAC;AAAA,IACb;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAC9E,QAAI,KAAK,WAAW,iBAAiB,SAAS,MAAM,OAAO;AACzD,cAAQ,MAAM,gBAAgB;AAC9B,cAAQ,MAAM,MAAM,KAAK;AAAA,IAC3B;AACA,SAAK,KAAK,CAAC;AAAA,EACb;AACF;AAEA,SAAS,YAAY;AACnB,UAAQ,IAAI;AAAA,qBACO,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAuCzB;AACH;AAGA,KAAK,EAAE,MAAM,CAAC,UAAU;AACtB,UAAQ,MAAM,gBAAgB,KAAK;AACnC,OAAK,KAAK,CAAC;AACb,CAAC;","names":[]}
|