@formant/formant-cli 0.1.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/LICENSE +24 -0
- package/README.md +322 -0
- package/bin/dev.js +5 -0
- package/bin/run.js +5 -0
- package/dist/base-command.d.ts +38 -0
- package/dist/base-command.js +66 -0
- package/dist/base-command.js.map +1 -0
- package/dist/commands/analytics/query.d.ts +12 -0
- package/dist/commands/analytics/query.js +82 -0
- package/dist/commands/analytics/query.js.map +1 -0
- package/dist/commands/analytics/tables.d.ts +9 -0
- package/dist/commands/analytics/tables.js +34 -0
- package/dist/commands/analytics/tables.js.map +1 -0
- package/dist/commands/commands/for-device.d.ts +12 -0
- package/dist/commands/commands/for-device.js +33 -0
- package/dist/commands/commands/for-device.js.map +1 -0
- package/dist/commands/commands/get.d.ts +11 -0
- package/dist/commands/commands/get.js +133 -0
- package/dist/commands/commands/get.js.map +1 -0
- package/dist/commands/commands/history.d.ts +13 -0
- package/dist/commands/commands/history.js +49 -0
- package/dist/commands/commands/history.js.map +1 -0
- package/dist/commands/commands/list.d.ts +9 -0
- package/dist/commands/commands/list.js +31 -0
- package/dist/commands/commands/list.js.map +1 -0
- package/dist/commands/commands/send.d.ts +37 -0
- package/dist/commands/commands/send.js +260 -0
- package/dist/commands/commands/send.js.map +1 -0
- package/dist/commands/devices/config.d.ts +10 -0
- package/dist/commands/devices/config.js +38 -0
- package/dist/commands/devices/config.js.map +1 -0
- package/dist/commands/devices/get.d.ts +10 -0
- package/dist/commands/devices/get.js +35 -0
- package/dist/commands/devices/get.js.map +1 -0
- package/dist/commands/devices/last-seen.d.ts +10 -0
- package/dist/commands/devices/last-seen.js +25 -0
- package/dist/commands/devices/last-seen.js.map +1 -0
- package/dist/commands/devices/list.d.ts +20 -0
- package/dist/commands/devices/list.js +133 -0
- package/dist/commands/devices/list.js.map +1 -0
- package/dist/commands/devices/streams.d.ts +12 -0
- package/dist/commands/devices/streams.js +56 -0
- package/dist/commands/devices/streams.js.map +1 -0
- package/dist/commands/event-triggers/get.d.ts +10 -0
- package/dist/commands/event-triggers/get.js +29 -0
- package/dist/commands/event-triggers/get.js.map +1 -0
- package/dist/commands/event-triggers/list.d.ts +9 -0
- package/dist/commands/event-triggers/list.js +30 -0
- package/dist/commands/event-triggers/list.js.map +1 -0
- package/dist/commands/events/get.d.ts +10 -0
- package/dist/commands/events/get.js +35 -0
- package/dist/commands/events/get.js.map +1 -0
- package/dist/commands/events/list.d.ts +17 -0
- package/dist/commands/events/list.js +81 -0
- package/dist/commands/events/list.js.map +1 -0
- package/dist/commands/fleets/get.d.ts +10 -0
- package/dist/commands/fleets/get.js +28 -0
- package/dist/commands/fleets/get.js.map +1 -0
- package/dist/commands/fleets/list.d.ts +9 -0
- package/dist/commands/fleets/list.js +27 -0
- package/dist/commands/fleets/list.js.map +1 -0
- package/dist/commands/investigations/analytics.d.ts +15 -0
- package/dist/commands/investigations/analytics.js +69 -0
- package/dist/commands/investigations/analytics.js.map +1 -0
- package/dist/commands/investigations/get.d.ts +10 -0
- package/dist/commands/investigations/get.js +38 -0
- package/dist/commands/investigations/get.js.map +1 -0
- package/dist/commands/investigations/list.d.ts +12 -0
- package/dist/commands/investigations/list.js +41 -0
- package/dist/commands/investigations/list.js.map +1 -0
- package/dist/commands/investigations/run.d.ts +15 -0
- package/dist/commands/investigations/run.js +96 -0
- package/dist/commands/investigations/run.js.map +1 -0
- package/dist/commands/investigations/runs-list.d.ts +18 -0
- package/dist/commands/investigations/runs-list.js +57 -0
- package/dist/commands/investigations/runs-list.js.map +1 -0
- package/dist/commands/investigations/runs.d.ts +12 -0
- package/dist/commands/investigations/runs.js +30 -0
- package/dist/commands/investigations/runs.js.map +1 -0
- package/dist/commands/investigations/stats.d.ts +11 -0
- package/dist/commands/investigations/stats.js +40 -0
- package/dist/commands/investigations/stats.js.map +1 -0
- package/dist/commands/investigations/trigger.d.ts +14 -0
- package/dist/commands/investigations/trigger.js +43 -0
- package/dist/commands/investigations/trigger.js.map +1 -0
- package/dist/commands/kv/get.d.ts +10 -0
- package/dist/commands/kv/get.js +28 -0
- package/dist/commands/kv/get.js.map +1 -0
- package/dist/commands/kv/list.d.ts +13 -0
- package/dist/commands/kv/list.js +73 -0
- package/dist/commands/kv/list.js.map +1 -0
- package/dist/commands/kv/set.d.ts +11 -0
- package/dist/commands/kv/set.js +40 -0
- package/dist/commands/kv/set.js.map +1 -0
- package/dist/commands/query/index.d.ts +19 -0
- package/dist/commands/query/index.js +105 -0
- package/dist/commands/query/index.js.map +1 -0
- package/dist/commands/query/latest-values.d.ts +14 -0
- package/dist/commands/query/latest-values.js +102 -0
- package/dist/commands/query/latest-values.js.map +1 -0
- package/dist/commands/schedules/get.d.ts +10 -0
- package/dist/commands/schedules/get.js +29 -0
- package/dist/commands/schedules/get.js.map +1 -0
- package/dist/commands/schedules/list.d.ts +9 -0
- package/dist/commands/schedules/list.js +29 -0
- package/dist/commands/schedules/list.js.map +1 -0
- package/dist/commands/signals/count.d.ts +13 -0
- package/dist/commands/signals/count.js +43 -0
- package/dist/commands/signals/count.js.map +1 -0
- package/dist/commands/signals/get.d.ts +13 -0
- package/dist/commands/signals/get.js +80 -0
- package/dist/commands/signals/get.js.map +1 -0
- package/dist/commands/signals/list.d.ts +9 -0
- package/dist/commands/signals/list.js +30 -0
- package/dist/commands/signals/list.js.map +1 -0
- package/dist/commands/signals/query.d.ts +14 -0
- package/dist/commands/signals/query.js +52 -0
- package/dist/commands/signals/query.js.map +1 -0
- package/dist/commands/users/get.d.ts +10 -0
- package/dist/commands/users/get.js +28 -0
- package/dist/commands/users/get.js.map +1 -0
- package/dist/commands/users/list.d.ts +9 -0
- package/dist/commands/users/list.js +28 -0
- package/dist/commands/users/list.js.map +1 -0
- package/dist/help.d.ts +4 -0
- package/dist/help.js +91 -0
- package/dist/help.js.map +1 -0
- package/dist/hooks/init.d.ts +3 -0
- package/dist/hooks/init.js +7 -0
- package/dist/hooks/init.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/api.d.ts +12 -0
- package/dist/lib/api.js +46 -0
- package/dist/lib/api.js.map +1 -0
- package/dist/lib/auth.d.ts +17 -0
- package/dist/lib/auth.js +41 -0
- package/dist/lib/auth.js.map +1 -0
- package/dist/lib/config.d.ts +7 -0
- package/dist/lib/config.js +21 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/formatters.d.ts +17 -0
- package/dist/lib/formatters.js +53 -0
- package/dist/lib/formatters.js.map +1 -0
- package/oclif.manifest.json +2683 -0
- package/package.json +117 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
PROPRIETARY LICENSE
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024-2026 Formant Inc.
|
|
4
|
+
|
|
5
|
+
All rights reserved.
|
|
6
|
+
|
|
7
|
+
This software and associated documentation files (the "Software") are proprietary
|
|
8
|
+
to Formant Inc. and are provided solely for use by authorized Formant customers.
|
|
9
|
+
|
|
10
|
+
The Software may not be:
|
|
11
|
+
- Copied, modified, merged, published, or distributed without express written
|
|
12
|
+
permission from Formant Inc.
|
|
13
|
+
- Used for any purpose other than in connection with authorized use of Formant
|
|
14
|
+
services
|
|
15
|
+
- Reverse engineered, decompiled, or disassembled
|
|
16
|
+
|
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
20
|
+
FORMANT INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
21
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
22
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
23
|
+
|
|
24
|
+
For licensing inquiries, contact: info@formant.io
|
package/README.md
ADDED
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
# Formant CLI (`fcli`)
|
|
2
|
+
|
|
3
|
+
```
|
|
4
|
+
███████╗ ██████╗██╗ ██╗
|
|
5
|
+
██╔════╝██╔════╝██║ ██║ 🤖 Formant CLI
|
|
6
|
+
█████╗ ██║ ██║ ██║ ⚡ Manage your robot fleet
|
|
7
|
+
██╔══╝ ██║ ██║ ██║ 🚀 from the command line
|
|
8
|
+
██║ ╚██████╗███████╗██║
|
|
9
|
+
╚═╝ ╚═════╝╚══════╝╚═╝
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
The official command-line interface for [Formant](https://formant.io) — manage your robot fleet, query telemetry, trigger investigations, and more, all from your terminal.
|
|
13
|
+
|
|
14
|
+
## Features
|
|
15
|
+
|
|
16
|
+
- 📋 **Device Management** — List, inspect, and configure robots and sensors
|
|
17
|
+
- 📊 **Telemetry Queries** — Retrieve battery, temperature, and sensor data
|
|
18
|
+
- 🔍 **Event Monitoring** — View and filter device events by severity
|
|
19
|
+
- 🤖 **AI Investigations** — Trigger and monitor AI-powered analysis workflows
|
|
20
|
+
- 📡 **Signal Management** — Track and trace investigation signals
|
|
21
|
+
- 💬 **Command Execution** — Send commands to devices
|
|
22
|
+
- 🚨 **Event Triggers** — Configure rules that generate events and signals
|
|
23
|
+
- 👥 **User & Fleet Management** — Manage users, teams, and device groups
|
|
24
|
+
- 📅 **Scheduled Tasks** — Set up recurring jobs and one-time schedules
|
|
25
|
+
- 📈 **Analytics** — Execute SQL queries against analytics data
|
|
26
|
+
- 🗂️ **Key-Value Store** — Manage device metadata
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
### npm
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install -g @formant/formant-cli
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Yarn
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
yarn global add @formant/formant-cli
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### pnpm
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
pnpm add -g @formant/formant-cli
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Authentication
|
|
49
|
+
|
|
50
|
+
Set your Formant credentials as environment variables:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
export FORMANT_USER="your-service-account@example.com"
|
|
54
|
+
export FORMANT_PASSWORD="your-password"
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Or create a `.env` file in your project:
|
|
58
|
+
|
|
59
|
+
```env
|
|
60
|
+
FORMANT_USER=your-service-account@example.com
|
|
61
|
+
FORMANT_PASSWORD=your-password
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Quick Start
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
# View help
|
|
68
|
+
fcli --help
|
|
69
|
+
|
|
70
|
+
# List all devices in dev environment
|
|
71
|
+
fcli devices list --dev
|
|
72
|
+
|
|
73
|
+
# Get device details
|
|
74
|
+
fcli devices get <device-id> --dev
|
|
75
|
+
|
|
76
|
+
# Query battery telemetry
|
|
77
|
+
fcli query --device <device-id> --stream battery_level --start 2026-01-01 --end 2026-01-02 --dev
|
|
78
|
+
|
|
79
|
+
# View recent events
|
|
80
|
+
fcli events list --device <device-id> --severity critical --limit 20 --dev
|
|
81
|
+
|
|
82
|
+
# List investigations
|
|
83
|
+
fcli investigations list --dev
|
|
84
|
+
|
|
85
|
+
# Send a command to a device
|
|
86
|
+
fcli commands send <device-id> <template-id> --param speed=5 --dev
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Commands
|
|
90
|
+
|
|
91
|
+
### Devices
|
|
92
|
+
|
|
93
|
+
Manage robots and sensors in your fleet.
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
fcli devices list [--tag <key>=<value>] [--online] [--dev]
|
|
97
|
+
fcli devices get <device-id> [--dev]
|
|
98
|
+
fcli devices config <device-id> [--dev]
|
|
99
|
+
fcli devices streams <device-id> [--dev]
|
|
100
|
+
fcli devices last-seen <device-id> [--dev]
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Events
|
|
104
|
+
|
|
105
|
+
View important events emitted by devices.
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
fcli events list [--device <id>] [--severity <level>] [--limit <n>] [--dev]
|
|
109
|
+
fcli events get <event-id> [--dev]
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Query
|
|
113
|
+
|
|
114
|
+
Retrieve telemetry and sensor data from devices.
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
fcli query --device <id> --stream <name> --start <date> --end <date> [--dev]
|
|
118
|
+
fcli query latest-values --device <id> --stream <name> [--dev]
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Investigations
|
|
122
|
+
|
|
123
|
+
Run and monitor AI-powered analysis workflows.
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
fcli investigations list [--dev]
|
|
127
|
+
fcli investigations get <investigation-id> [--dev]
|
|
128
|
+
fcli investigations stats [--start <date>] [--end <date>] [--dev]
|
|
129
|
+
fcli investigations runs-list <investigation-id> [--dev]
|
|
130
|
+
fcli investigations run <investigation-id> <run-id> [--trace-signal] [--dev]
|
|
131
|
+
fcli investigations trigger <investigation-id> <device-id> [--dev]
|
|
132
|
+
fcli investigations analytics <investigation-id> [--dev]
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Signals
|
|
136
|
+
|
|
137
|
+
Manage signals (points of interest that trigger analysis).
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
fcli signals list [--start <date>] [--end <date>] [--dev]
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Commands
|
|
144
|
+
|
|
145
|
+
Manage command templates and send commands to devices.
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
fcli commands list [--dev]
|
|
149
|
+
fcli commands get <command-id> [--dev]
|
|
150
|
+
fcli commands for-device <device-id> [--dev]
|
|
151
|
+
fcli commands send <device-id> <template-id> [--param <key>=<value>] [--dev]
|
|
152
|
+
fcli commands history <device-id> [--dev]
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Event Triggers
|
|
156
|
+
|
|
157
|
+
Manage event trigger rules that generate events and signals.
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
fcli event-triggers list [--dev]
|
|
161
|
+
fcli event-triggers get <trigger-id> [--dev]
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Users
|
|
165
|
+
|
|
166
|
+
Manage users in your organization.
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
fcli users list [--dev]
|
|
170
|
+
fcli users get <user-id> [--dev]
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Fleets
|
|
174
|
+
|
|
175
|
+
Manage device groups (fleets).
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
fcli fleets list [--dev]
|
|
179
|
+
fcli fleets get <fleet-id> [--dev]
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Schedules
|
|
183
|
+
|
|
184
|
+
Manage scheduled tasks and recurring jobs.
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
fcli schedules list [--dev]
|
|
188
|
+
fcli schedules get <schedule-id> [--dev]
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Analytics
|
|
192
|
+
|
|
193
|
+
Execute SQL queries against analytics data.
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
fcli analytics query --sql "<query>" [--dev]
|
|
197
|
+
fcli analytics tables [--dev]
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Key-Value Store
|
|
201
|
+
|
|
202
|
+
Manage key-value store for device metadata.
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
fcli kv list <device-id> [--dev]
|
|
206
|
+
fcli kv get <device-id> <key> [--dev]
|
|
207
|
+
fcli kv set <device-id> <key> <value> [--dev]
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## Global Flags
|
|
211
|
+
|
|
212
|
+
- `--dev` — Target the dev environment
|
|
213
|
+
- `--stage` — Target the stage environment
|
|
214
|
+
- `--json` — Format output as JSON
|
|
215
|
+
- `-h, --help` — Show help for a command
|
|
216
|
+
|
|
217
|
+
## Environment Variables
|
|
218
|
+
|
|
219
|
+
| Variable | Description | Required |
|
|
220
|
+
|----------|-------------|----------|
|
|
221
|
+
| `FORMANT_USER` | Service account email | Yes |
|
|
222
|
+
| `FORMANT_PASSWORD` | Service account password | Yes |
|
|
223
|
+
|
|
224
|
+
## Examples
|
|
225
|
+
|
|
226
|
+
### List online devices with specific tag
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
fcli devices list --tag location=warehouse --online --dev
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### Query telemetry data over a time range
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
fcli query --device abc123 --stream battery_level \
|
|
236
|
+
--start 2026-01-01 --end 2026-01-02 --dev --json
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### Trace an investigation back to its signal
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
# Get investigation run
|
|
243
|
+
fcli investigations run <investigation-id> <run-id> --trace-signal --dev
|
|
244
|
+
|
|
245
|
+
# Get the signal details
|
|
246
|
+
fcli signals get <signal-id> --dev
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Monitor critical events
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
fcli events list --severity critical --limit 50 --dev
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### Send a command with parameters
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
fcli commands send device-123 template-456 \
|
|
259
|
+
--param speed=10 \
|
|
260
|
+
--param direction=forward \
|
|
261
|
+
--dev
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
## Output Formats
|
|
265
|
+
|
|
266
|
+
### Table (default)
|
|
267
|
+
|
|
268
|
+
Human-readable tables for terminal viewing:
|
|
269
|
+
|
|
270
|
+
```bash
|
|
271
|
+
fcli devices list --dev
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
### JSON
|
|
275
|
+
|
|
276
|
+
Machine-readable JSON for scripting and automation:
|
|
277
|
+
|
|
278
|
+
```bash
|
|
279
|
+
fcli devices list --dev --json | jq '.items[] | .name'
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
## Development
|
|
283
|
+
|
|
284
|
+
### Build from source
|
|
285
|
+
|
|
286
|
+
```bash
|
|
287
|
+
git clone https://github.com/FormantIO/formant-cli.git
|
|
288
|
+
cd formant-cli
|
|
289
|
+
npm install
|
|
290
|
+
npm run build
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
### Run in development mode
|
|
294
|
+
|
|
295
|
+
```bash
|
|
296
|
+
npm run dev -- devices list --dev
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### Build and pack
|
|
300
|
+
|
|
301
|
+
```bash
|
|
302
|
+
npm run prepack
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
## Requirements
|
|
306
|
+
|
|
307
|
+
- Node.js >= 18.0.0
|
|
308
|
+
- A Formant service account with appropriate permissions
|
|
309
|
+
|
|
310
|
+
## Support
|
|
311
|
+
|
|
312
|
+
- Documentation: [https://formant.io/docs](https://formant.io/docs)
|
|
313
|
+
- Support: [support@formant.io](mailto:support@formant.io)
|
|
314
|
+
- Issues: [https://github.com/FormantIO/formant-cli/issues](https://github.com/FormantIO/formant-cli/issues)
|
|
315
|
+
|
|
316
|
+
## License
|
|
317
|
+
|
|
318
|
+
UNLICENSED — Proprietary software for Formant customers.
|
|
319
|
+
|
|
320
|
+
---
|
|
321
|
+
|
|
322
|
+
Made with ⚡ by [Formant](https://formant.io)
|
package/bin/dev.js
ADDED
package/bin/run.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Command, Interfaces } from '@oclif/core';
|
|
2
|
+
import { type ApiTarget } from './lib/api.js';
|
|
3
|
+
import type { Environment } from './lib/config.js';
|
|
4
|
+
export type InferredFlags<T extends typeof Command> = Interfaces.InferredFlags<typeof BaseCommand['baseFlags'] & T['flags']>;
|
|
5
|
+
export type InferredArgs<T extends typeof Command> = Interfaces.InferredArgs<T['args']>;
|
|
6
|
+
/**
|
|
7
|
+
* Abstract base command for all fcli commands.
|
|
8
|
+
* Provides global --env flag, --json support, and authenticated API helpers.
|
|
9
|
+
*/
|
|
10
|
+
export declare abstract class BaseCommand<T extends typeof Command> extends Command {
|
|
11
|
+
static enableJsonFlag: boolean;
|
|
12
|
+
static baseFlags: {
|
|
13
|
+
dev: Interfaces.BooleanFlag<boolean>;
|
|
14
|
+
stage: Interfaces.BooleanFlag<boolean>;
|
|
15
|
+
};
|
|
16
|
+
protected flags: InferredFlags<T>;
|
|
17
|
+
protected args: InferredArgs<T>;
|
|
18
|
+
/** Resolved environment based on --dev / --stage flags. */
|
|
19
|
+
protected get env(): Environment;
|
|
20
|
+
init(): Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* Make an authenticated GET/POST request to a Formant API.
|
|
23
|
+
* Automatically uses the correct environment from --dev/--stage flags.
|
|
24
|
+
*/
|
|
25
|
+
protected api<R = unknown>(target: ApiTarget, path: string, options?: {
|
|
26
|
+
body?: unknown;
|
|
27
|
+
method?: 'DELETE' | 'GET' | 'PATCH' | 'POST' | 'PUT';
|
|
28
|
+
query?: Record<string, string>;
|
|
29
|
+
}): Promise<R>;
|
|
30
|
+
protected catch(err: Error & {
|
|
31
|
+
exitCode?: number;
|
|
32
|
+
}): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Normalize a date string to ISO 8601 datetime format.
|
|
35
|
+
* Accepts both simple dates (2026-01-01) and full datetime strings.
|
|
36
|
+
*/
|
|
37
|
+
protected normalizeDateTime(dateStr: string): string;
|
|
38
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { Command, Flags } from '@oclif/core';
|
|
2
|
+
import { apiRequest } from './lib/api.js';
|
|
3
|
+
/**
|
|
4
|
+
* Abstract base command for all fcli commands.
|
|
5
|
+
* Provides global --env flag, --json support, and authenticated API helpers.
|
|
6
|
+
*/
|
|
7
|
+
export class BaseCommand extends Command {
|
|
8
|
+
static enableJsonFlag = true;
|
|
9
|
+
static baseFlags = {
|
|
10
|
+
dev: Flags.boolean({
|
|
11
|
+
description: 'Target the dev environment',
|
|
12
|
+
exclusive: ['stage'],
|
|
13
|
+
helpGroup: 'GLOBAL',
|
|
14
|
+
}),
|
|
15
|
+
stage: Flags.boolean({
|
|
16
|
+
description: 'Target the stage environment',
|
|
17
|
+
exclusive: ['dev'],
|
|
18
|
+
helpGroup: 'GLOBAL',
|
|
19
|
+
}),
|
|
20
|
+
};
|
|
21
|
+
flags;
|
|
22
|
+
args;
|
|
23
|
+
/** Resolved environment based on --dev / --stage flags. */
|
|
24
|
+
get env() {
|
|
25
|
+
if (this.flags.dev)
|
|
26
|
+
return 'dev';
|
|
27
|
+
if (this.flags.stage)
|
|
28
|
+
return 'stage';
|
|
29
|
+
return 'prod';
|
|
30
|
+
}
|
|
31
|
+
async init() {
|
|
32
|
+
await super.init();
|
|
33
|
+
const { args, flags } = await this.parse({
|
|
34
|
+
args: this.ctor.args,
|
|
35
|
+
baseFlags: super.ctor.baseFlags,
|
|
36
|
+
enableJsonFlag: this.ctor.enableJsonFlag,
|
|
37
|
+
flags: this.ctor.flags,
|
|
38
|
+
strict: this.ctor.strict,
|
|
39
|
+
});
|
|
40
|
+
this.flags = flags;
|
|
41
|
+
this.args = args;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Make an authenticated GET/POST request to a Formant API.
|
|
45
|
+
* Automatically uses the correct environment from --dev/--stage flags.
|
|
46
|
+
*/
|
|
47
|
+
async api(target, path, options) {
|
|
48
|
+
return apiRequest(this.env, target, path, options);
|
|
49
|
+
}
|
|
50
|
+
async catch(err) {
|
|
51
|
+
throw err;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Normalize a date string to ISO 8601 datetime format.
|
|
55
|
+
* Accepts both simple dates (2026-01-01) and full datetime strings.
|
|
56
|
+
*/
|
|
57
|
+
normalizeDateTime(dateStr) {
|
|
58
|
+
// If it already looks like a full datetime (has 'T' or time), return as-is
|
|
59
|
+
if (dateStr.includes('T') || dateStr.match(/\d{2}:\d{2}/)) {
|
|
60
|
+
return dateStr;
|
|
61
|
+
}
|
|
62
|
+
// Otherwise, append T00:00:00Z to make it a valid datetime
|
|
63
|
+
return `${dateStr}T00:00:00Z`;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=base-command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-command.js","sourceRoot":"","sources":["../src/base-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAE,KAAK,EAAa,MAAM,aAAa,CAAA;AAEtD,OAAO,EAAiB,UAAU,EAAC,MAAM,cAAc,CAAA;AAQvD;;;GAGG;AACH,MAAM,OAAgB,WAAsC,SAAQ,OAAO;IACzE,MAAM,CAAC,cAAc,GAAG,IAAI,CAAA;IAE5B,MAAM,CAAC,SAAS,GAAG;QACjB,GAAG,EAAE,KAAK,CAAC,OAAO,CAAC;YACjB,WAAW,EAAE,4BAA4B;YACzC,SAAS,EAAE,CAAC,OAAO,CAAC;YACpB,SAAS,EAAE,QAAQ;SACpB,CAAC;QACF,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC;YACnB,WAAW,EAAE,8BAA8B;YAC3C,SAAS,EAAE,CAAC,KAAK,CAAC;YAClB,SAAS,EAAE,QAAQ;SACpB,CAAC;KACH,CAAA;IAES,KAAK,CAAmB;IACxB,IAAI,CAAkB;IAEhC,2DAA2D;IAC3D,IAAc,GAAG;QACf,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG;YAAE,OAAO,KAAK,CAAA;QAChC,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK;YAAE,OAAO,OAAO,CAAA;QACpC,OAAO,MAAM,CAAA;IACf,CAAC;IAEM,KAAK,CAAC,IAAI;QACf,MAAM,KAAK,CAAC,IAAI,EAAE,CAAA;QAClB,MAAM,EAAC,IAAI,EAAE,KAAK,EAAC,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC;YACrC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI;YACpB,SAAS,EAAG,KAAK,CAAC,IAA2B,CAAC,SAAS;YACvD,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC,cAAc;YACxC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK;YACtB,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM;SACzB,CAAC,CAAA;QAEF,IAAI,CAAC,KAAK,GAAG,KAAyB,CAAA;QACtC,IAAI,CAAC,IAAI,GAAG,IAAuB,CAAA;IACrC,CAAC;IAED;;;OAGG;IACO,KAAK,CAAC,GAAG,CACjB,MAAiB,EACjB,IAAY,EACZ,OAAgH;QAEhH,OAAO,UAAU,CAAI,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;IACvD,CAAC;IAEkB,KAAK,CAAC,KAAK,CAAC,GAAgC;QAC7D,MAAM,GAAG,CAAA;IACX,CAAC;IAED;;;OAGG;IACO,iBAAiB,CAAC,OAAe;QACzC,2EAA2E;QAC3E,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,CAAC;YAC1D,OAAO,OAAO,CAAA;QAChB,CAAC;QAED,2DAA2D;QAC3D,OAAO,GAAG,OAAO,YAAY,CAAA;IAC/B,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { BaseCommand } from '../../base-command.js';
|
|
2
|
+
export default class AnalyticsQuery extends BaseCommand<typeof AnalyticsQuery> {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static flags: {
|
|
6
|
+
limit: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
|
+
sql: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
|
+
type: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
|
+
};
|
|
10
|
+
static summary: string;
|
|
11
|
+
run(): Promise<Record<string, unknown>>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { Flags } from '@oclif/core';
|
|
2
|
+
import { BaseCommand } from '../../base-command.js';
|
|
3
|
+
import { formatTable } from '../../lib/formatters.js';
|
|
4
|
+
export default class AnalyticsQuery extends BaseCommand {
|
|
5
|
+
static description = `Execute a SQL query against analytics data (Snowflake SQL dialect).
|
|
6
|
+
|
|
7
|
+
Query telemetry data, events, and other analytics tables using Snowflake-compatible SQL.
|
|
8
|
+
Use 'fcli analytics tables' to see available tables and their columns.
|
|
9
|
+
|
|
10
|
+
Note: The analytics engine uses the Snowflake SQL dialect. String comparisons are
|
|
11
|
+
case-sensitive, use ILIKE for case-insensitive matching, and timestamps should be
|
|
12
|
+
quoted strings (e.g. WHERE time > '2026-01-01'). Large unbounded queries may be
|
|
13
|
+
rejected — always filter by time range for large tables.`;
|
|
14
|
+
static examples = [
|
|
15
|
+
'<%= config.bin %> analytics query --sql "SELECT * FROM query_event WHERE time > \'2026-01-01\' LIMIT 10"',
|
|
16
|
+
'<%= config.bin %> analytics query --sql "SELECT device_id, avg(value) as avg_val FROM query_numeric WHERE time > \'2026-02-01\' GROUP BY device_id LIMIT 10"',
|
|
17
|
+
'<%= config.bin %> analytics query --sql "SELECT type, count(*) as cnt FROM query_event WHERE time > \'2026-02-01\' GROUP BY type ORDER BY cnt DESC LIMIT 5"',
|
|
18
|
+
'<%= config.bin %> analytics query --sql "SELECT * FROM query_event LIMIT 10" --json',
|
|
19
|
+
];
|
|
20
|
+
static flags = {
|
|
21
|
+
limit: Flags.integer({
|
|
22
|
+
char: 'l',
|
|
23
|
+
description: 'Maximum number of rows to return',
|
|
24
|
+
}),
|
|
25
|
+
sql: Flags.string({
|
|
26
|
+
char: 's',
|
|
27
|
+
description: 'SQL query to execute',
|
|
28
|
+
required: true,
|
|
29
|
+
}),
|
|
30
|
+
type: Flags.string({
|
|
31
|
+
default: 'advanced',
|
|
32
|
+
description: 'Query type',
|
|
33
|
+
options: ['stream', 'task', 'advanced'],
|
|
34
|
+
}),
|
|
35
|
+
};
|
|
36
|
+
static summary = 'Execute SQL analytics query';
|
|
37
|
+
async run() {
|
|
38
|
+
const body = {
|
|
39
|
+
sqlQuery: this.flags.sql,
|
|
40
|
+
type: this.flags.type,
|
|
41
|
+
};
|
|
42
|
+
if (this.flags.limit) {
|
|
43
|
+
body.limit = this.flags.limit;
|
|
44
|
+
}
|
|
45
|
+
const result = await this.api('query', 'analytics/rows', { body });
|
|
46
|
+
if (result.error) {
|
|
47
|
+
this.error(`Query error: ${result.error}`);
|
|
48
|
+
}
|
|
49
|
+
if (!this.jsonEnabled()) {
|
|
50
|
+
this.log(`\nAnalytics Query Results (${this.env}):\n`);
|
|
51
|
+
this.log(` SQL: ${result.sqlText || this.flags.sql}`);
|
|
52
|
+
this.log(` Rows: ${result.rowCount ?? result.rows?.length ?? 0}\n`);
|
|
53
|
+
const rows = result.rows ?? [];
|
|
54
|
+
if (rows.length > 0) {
|
|
55
|
+
// Build columns from the response metadata
|
|
56
|
+
const columns = (result.columns ?? []).map((col) => ({
|
|
57
|
+
key: col.name,
|
|
58
|
+
label: col.name.toUpperCase(),
|
|
59
|
+
width: Math.max(col.name.length + 2, 20),
|
|
60
|
+
}));
|
|
61
|
+
// Fallback: derive from first row if no column metadata
|
|
62
|
+
if (columns.length === 0) {
|
|
63
|
+
const keys = Object.keys(rows[0]);
|
|
64
|
+
for (const key of keys) {
|
|
65
|
+
columns.push({
|
|
66
|
+
key,
|
|
67
|
+
label: key.toUpperCase(),
|
|
68
|
+
width: Math.max(key.length + 2, 20),
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
this.log(formatTable(rows, columns));
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
this.log(' No results.');
|
|
76
|
+
}
|
|
77
|
+
this.log('');
|
|
78
|
+
}
|
|
79
|
+
return result;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=query.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query.js","sourceRoot":"","sources":["../../../src/commands/analytics/query.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { BaseCommand } from '../../base-command.js';
|
|
2
|
+
export default class AnalyticsTables extends BaseCommand<typeof AnalyticsTables> {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static summary: string;
|
|
6
|
+
run(): Promise<{
|
|
7
|
+
items: unknown[];
|
|
8
|
+
}>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { BaseCommand } from '../../base-command.js';
|
|
2
|
+
import { formatTable } from '../../lib/formatters.js';
|
|
3
|
+
export default class AnalyticsTables extends BaseCommand {
|
|
4
|
+
static description = `List available SQL tables for analytics queries.
|
|
5
|
+
|
|
6
|
+
Shows table names, descriptions, and column definitions that can be used
|
|
7
|
+
with 'fcli analytics query'. The analytics engine uses the Snowflake SQL dialect.`;
|
|
8
|
+
static examples = [
|
|
9
|
+
'<%= config.bin %> analytics tables',
|
|
10
|
+
'<%= config.bin %> analytics tables --json',
|
|
11
|
+
];
|
|
12
|
+
static summary = 'List analytics tables';
|
|
13
|
+
async run() {
|
|
14
|
+
const result = await this.api('query', 'analytics/tables', { method: 'GET' });
|
|
15
|
+
const tables = result.items ?? [];
|
|
16
|
+
if (!this.jsonEnabled()) {
|
|
17
|
+
this.log(`\nAnalytics Tables (${this.env}):\n`);
|
|
18
|
+
for (const table of tables) {
|
|
19
|
+
this.log(` ${table.name}${table.description ? ` — ${table.description}` : ''}`);
|
|
20
|
+
if (table.columns && table.columns.length > 0) {
|
|
21
|
+
const columns = [
|
|
22
|
+
{ key: 'name', label: 'COLUMN', width: 30 },
|
|
23
|
+
{ key: 'dataType', label: 'TYPE', width: 14 },
|
|
24
|
+
{ key: 'description', label: 'DESCRIPTION', width: 40 },
|
|
25
|
+
];
|
|
26
|
+
this.log(formatTable(table.columns, columns));
|
|
27
|
+
}
|
|
28
|
+
this.log('');
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return result;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=tables.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tables.js","sourceRoot":"","sources":["../../../src/commands/analytics/tables.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,uBAAuB,CAAA;AACjD,OAAO,EAAc,WAAW,EAAC,MAAM,yBAAyB,CAAA;AAEhE,MAAM,CAAC,OAAO,OAAO,eAAgB,SAAQ,WAAmC;IAC9E,MAAM,CAAU,WAAW,GAAG;;;kFAGkD,CAAA;IAEhF,MAAM,CAAU,QAAQ,GAAG;QACzB,oCAAoC;QACpC,2CAA2C;KAC5C,CAAA;IAED,MAAM,CAAU,OAAO,GAAG,uBAAuB,CAAA;IAE1C,KAAK,CAAC,GAAG;QACd,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAC3B,OAAO,EACP,kBAAkB,EAClB,EAAC,MAAM,EAAE,KAAK,EAAC,CAChB,CAAA;QAED,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,IAAI,EAAE,CAAA;QAEjC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,IAAI,CAAC,GAAG,CAAC,uBAAuB,IAAI,CAAC,GAAG,MAAM,CAAC,CAAA;YAE/C,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,IAAI,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;gBAEhF,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC9C,MAAM,OAAO,GAAa;wBACxB,EAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,EAAC;wBACzC,EAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAC;wBAC3C,EAAC,GAAG,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,EAAE,EAAC;qBACtD,CAAA;oBAED,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAA;gBAC/C,CAAC;gBAED,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;YACd,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAA;IACf,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { BaseCommand } from '../../base-command.js';
|
|
2
|
+
export default class CommandsForDevice extends BaseCommand<typeof CommandsForDevice> {
|
|
3
|
+
static args: {
|
|
4
|
+
deviceId: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
|
+
};
|
|
6
|
+
static description: string;
|
|
7
|
+
static examples: string[];
|
|
8
|
+
static summary: string;
|
|
9
|
+
run(): Promise<{
|
|
10
|
+
items: unknown[];
|
|
11
|
+
}>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Args } from '@oclif/core';
|
|
2
|
+
import { BaseCommand } from '../../base-command.js';
|
|
3
|
+
import { formatTable } from '../../lib/formatters.js';
|
|
4
|
+
export default class CommandsForDevice extends BaseCommand {
|
|
5
|
+
static args = {
|
|
6
|
+
deviceId: Args.string({ description: 'Device ID (UUID)', required: true }),
|
|
7
|
+
};
|
|
8
|
+
static description = `List command templates available for a specific device.
|
|
9
|
+
|
|
10
|
+
Returns commands that match the device's tags and filters. Only enabled commands
|
|
11
|
+
that apply to this device are shown.`;
|
|
12
|
+
static examples = [
|
|
13
|
+
'<%= config.bin %> commands for-device <device-id>',
|
|
14
|
+
'<%= config.bin %> commands for-device <device-id> --json',
|
|
15
|
+
];
|
|
16
|
+
static summary = 'List commands available for a device';
|
|
17
|
+
async run() {
|
|
18
|
+
const result = await this.api('admin', `devices/${this.args.deviceId}/commands`, { method: 'GET' });
|
|
19
|
+
if (!this.jsonEnabled()) {
|
|
20
|
+
const columns = [
|
|
21
|
+
{ key: 'name', label: 'NAME', width: 30 },
|
|
22
|
+
{ key: 'command', label: 'COMMAND', width: 30 },
|
|
23
|
+
{ key: 'id', label: 'ID', width: 40 },
|
|
24
|
+
{ key: 'description', label: 'DESCRIPTION', width: 30 },
|
|
25
|
+
];
|
|
26
|
+
this.log(`\nAvailable Commands for Device (${this.env}):\n`);
|
|
27
|
+
this.log(formatTable(result.items ?? [], columns));
|
|
28
|
+
this.log('');
|
|
29
|
+
}
|
|
30
|
+
return result;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=for-device.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"for-device.js","sourceRoot":"","sources":["../../../src/commands/commands/for-device.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAC,MAAM,aAAa,CAAA;AAEhC,OAAO,EAAC,WAAW,EAAC,MAAM,uBAAuB,CAAA;AACjD,OAAO,EAAc,WAAW,EAAC,MAAM,yBAAyB,CAAA;AAEhE,MAAM,CAAC,OAAO,OAAO,iBAAkB,SAAQ,WAAqC;IAClF,MAAM,CAAU,IAAI,GAAG;QACrB,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,EAAC,WAAW,EAAE,kBAAkB,EAAE,QAAQ,EAAE,IAAI,EAAC,CAAC;KACzE,CAAA;IAED,MAAM,CAAU,WAAW,GAAG;;;qCAGK,CAAA;IAEnC,MAAM,CAAU,QAAQ,GAAG;QACzB,mDAAmD;QACnD,0DAA0D;KAC3D,CAAA;IAED,MAAM,CAAU,OAAO,GAAG,sCAAsC,CAAA;IAEzD,KAAK,CAAC,GAAG;QACd,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAC3B,OAAO,EACP,WAAW,IAAI,CAAC,IAAI,CAAC,QAAQ,WAAW,EACxC,EAAC,MAAM,EAAE,KAAK,EAAC,CAChB,CAAA;QAED,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,MAAM,OAAO,GAAa;gBACxB,EAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAC;gBACvC,EAAC,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,EAAC;gBAC7C,EAAC,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAC;gBACnC,EAAC,GAAG,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,EAAE,EAAC;aACtD,CAAA;YAED,IAAI,CAAC,GAAG,CAAC,oCAAoC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAA;YAC5D,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC,CAAA;YAClD,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACd,CAAC;QAED,OAAO,MAAM,CAAA;IACf,CAAC"}
|