@camstack/addon-pipeline 1.2.632 → 1.2.634
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/CHANGELOG.md +12 -0
- package/dist/audio-analyzer/index.js +3 -3
- package/dist/audio-analyzer/index.mjs +3 -3
- package/dist/{custom-model-catalog-B2w26VBG.mjs → custom-model-catalog-BjkdcgOE.mjs} +2 -2
- package/dist/{custom-model-catalog-DN4xBVQE.js → custom-model-catalog-CgSsz_wK.js} +2 -2
- package/dist/detection-pipeline/index.js +4 -4
- package/dist/detection-pipeline/index.mjs +4 -4
- package/dist/{dist-CLo3QHtG.js → dist-C5sQVajZ.js} +685 -13
- package/dist/{dist-DWkdwtle.mjs → dist-DlB7gVjz.mjs} +685 -13
- package/dist/{model-catalogs-DIviCtiQ.js → model-catalogs-D6iqJdhC.js} +1 -1
- package/dist/{model-catalogs-rs7okKyp.mjs → model-catalogs-XdVK-cpH.mjs} +1 -1
- package/dist/motion-wasm/index.js +1 -1
- package/dist/motion-wasm/index.mjs +1 -1
- package/dist/{node-CAJ1Dal-.mjs → node-DI6cJT3H.mjs} +1 -1
- package/dist/{node-CPqDCFas.js → node-DqynP4Sn.js} +1 -1
- package/dist/pipeline-runner/index.js +3 -3
- package/dist/pipeline-runner/index.mjs +3 -3
- package/dist/{process-memory-BrKzYxim.js → process-memory-BWsvhswo.js} +1 -1
- package/dist/{process-memory-DJWthb6k.mjs → process-memory-CdsO2dxD.mjs} +1 -1
- package/dist/recorder/index.js +8 -2
- package/dist/recorder/index.mjs +8 -2
- package/dist/{segment-demux-js-Bt5bxfyh.js → segment-demux-js-CEqPvaCD.js} +1 -1
- package/dist/{segment-demux-js-CZdgio0n.mjs → segment-demux-js-jzhozTBr.mjs} +1 -1
- package/dist/stream-broker/_stub.js +2 -2
- package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-CjjdxZUq.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-BfutHWHx.mjs} +2 -2
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-DfXSkf61.mjs +26 -0
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-CGcEN1m1.mjs +26 -0
- package/dist/stream-broker/demux-worker-child.js +1 -1
- package/dist/stream-broker/demux-worker-child.mjs +1 -1
- package/dist/stream-broker/{hostInit-MWvZi8Nq.mjs → hostInit-oZNKK5YV.mjs} +2 -2
- package/dist/stream-broker/index.js +115 -19
- package/dist/stream-broker/index.mjs +115 -19
- package/dist/stream-broker/remoteEntry.js +1 -1
- package/package.json +1 -1
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-DZmxw-we.mjs +0 -26
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-CFflpMdb.mjs +0 -26
|
@@ -5580,7 +5580,7 @@ var ZodIssueCode = {
|
|
|
5580
5580
|
var ZodFirstPartyTypeKind;
|
|
5581
5581
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5582
5582
|
//#endregion
|
|
5583
|
-
//#region ../types/dist/sleep-
|
|
5583
|
+
//#region ../types/dist/sleep-DJws6ho7.mjs
|
|
5584
5584
|
/**
|
|
5585
5585
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5586
5586
|
* window to float samples (D455).
|
|
@@ -9124,6 +9124,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
9124
9124
|
"image-settings",
|
|
9125
9125
|
"integrations",
|
|
9126
9126
|
"intercom",
|
|
9127
|
+
"ir-transmitter",
|
|
9127
9128
|
"keychain",
|
|
9128
9129
|
"keychain-admin",
|
|
9129
9130
|
"lawn-mower-control",
|
|
@@ -9182,6 +9183,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
9182
9183
|
"recording-onboard",
|
|
9183
9184
|
"recording-signal",
|
|
9184
9185
|
"records",
|
|
9186
|
+
"remote",
|
|
9185
9187
|
"running-state",
|
|
9186
9188
|
"scene-monitor",
|
|
9187
9189
|
"script-runner",
|
|
@@ -9205,6 +9207,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
9205
9207
|
"system",
|
|
9206
9208
|
"tamper",
|
|
9207
9209
|
"temperature-sensor",
|
|
9210
|
+
"template",
|
|
9208
9211
|
"terminal-session",
|
|
9209
9212
|
"toast",
|
|
9210
9213
|
"training",
|
|
@@ -10145,6 +10148,11 @@ Object.freeze({
|
|
|
10145
10148
|
"standby"
|
|
10146
10149
|
]
|
|
10147
10150
|
},
|
|
10151
|
+
{
|
|
10152
|
+
"path": "stateSource",
|
|
10153
|
+
"valueType": "enum",
|
|
10154
|
+
"enumValues": ["reported", "assumed"]
|
|
10155
|
+
},
|
|
10148
10156
|
{
|
|
10149
10157
|
"path": "volumeLevel",
|
|
10150
10158
|
"valueType": "number"
|
|
@@ -10371,6 +10379,11 @@ Object.freeze({
|
|
|
10371
10379
|
"path": "batteryPower",
|
|
10372
10380
|
"valueType": "number"
|
|
10373
10381
|
},
|
|
10382
|
+
{
|
|
10383
|
+
"path": "powerSource",
|
|
10384
|
+
"valueType": "enum",
|
|
10385
|
+
"enumValues": ["mains", "battery"]
|
|
10386
|
+
},
|
|
10374
10387
|
{
|
|
10375
10388
|
"path": "desiccantLeftDays",
|
|
10376
10389
|
"valueType": "number"
|
|
@@ -10415,6 +10428,18 @@ Object.freeze({
|
|
|
10415
10428
|
{
|
|
10416
10429
|
"path": "volume",
|
|
10417
10430
|
"valueType": "number"
|
|
10431
|
+
},
|
|
10432
|
+
{
|
|
10433
|
+
"path": "lastFeedGrams",
|
|
10434
|
+
"valueType": "number"
|
|
10435
|
+
},
|
|
10436
|
+
{
|
|
10437
|
+
"path": "lastFeedHopper1",
|
|
10438
|
+
"valueType": "number"
|
|
10439
|
+
},
|
|
10440
|
+
{
|
|
10441
|
+
"path": "lastFeedHopper2",
|
|
10442
|
+
"valueType": "number"
|
|
10418
10443
|
}
|
|
10419
10444
|
],
|
|
10420
10445
|
"power-meter": [
|
|
@@ -11106,7 +11131,7 @@ function sleep(ms) {
|
|
|
11106
11131
|
return new Promise((resolve) => setTimeout(resolve, Math.max(0, ms)));
|
|
11107
11132
|
}
|
|
11108
11133
|
//#endregion
|
|
11109
|
-
//#region ../types/dist/err-msg-
|
|
11134
|
+
//#region ../types/dist/err-msg-BCdlR2Li.mjs
|
|
11110
11135
|
var DeviceType = /* @__PURE__ */ function(DeviceType) {
|
|
11111
11136
|
DeviceType["Camera"] = "camera";
|
|
11112
11137
|
DeviceType["Hub"] = "hub";
|
|
@@ -11452,6 +11477,9 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
11452
11477
|
/** Fallback when the notifier service name doesn't match a known
|
|
11453
11478
|
* pattern. */
|
|
11454
11479
|
DeviceRole["GenericNotifier"] = "generic-notifier";
|
|
11480
|
+
/** Emits a pulse train (infrared or RF) on request — the `ir-transmitter`
|
|
11481
|
+
* cap. A `DeviceType.Generic` device. */
|
|
11482
|
+
DeviceRole["IrTransmitter"] = "ir-transmitter";
|
|
11455
11483
|
return DeviceRole;
|
|
11456
11484
|
}({});
|
|
11457
11485
|
/**
|
|
@@ -11465,7 +11493,7 @@ function errMsg(err) {
|
|
|
11465
11493
|
return String(err);
|
|
11466
11494
|
}
|
|
11467
11495
|
//#endregion
|
|
11468
|
-
//#region ../types/dist/composition-
|
|
11496
|
+
//#region ../types/dist/composition-bIBW5_13.mjs
|
|
11469
11497
|
var AUDIO_ENCODER_BY_CODEC = {
|
|
11470
11498
|
opus: "libopus",
|
|
11471
11499
|
aac: "aac",
|
|
@@ -11923,6 +11951,15 @@ function audioPlanFromEncodeProfile(audio) {
|
|
|
11923
11951
|
* plane. Width / height / fps / bitrate in the profile are a downstream BUDGET,
|
|
11924
11952
|
* not a forced rescale.
|
|
11925
11953
|
*/
|
|
11954
|
+
/**
|
|
11955
|
+
* Probe bound for an input that is one of OUR OWN RTSP restreams. Not zero: a
|
|
11956
|
+
* zero-length probe makes ffmpeg trust the SDP completely, and a restream that
|
|
11957
|
+
* announces a track it never sends would leave the mapping wrong unnoticed.
|
|
11958
|
+
*/
|
|
11959
|
+
var RESTREAM_INPUT_PROBE = {
|
|
11960
|
+
analyzeDurationUs: 2e5,
|
|
11961
|
+
probeSizeBytes: 64 * 1024
|
|
11962
|
+
};
|
|
11926
11963
|
function invocationFromEncodeProfile(input) {
|
|
11927
11964
|
const v = input.profile.video;
|
|
11928
11965
|
const shouldCopy = v.codec === "copy" || input.forceReencode !== true && v.codec === input.sourceCodec;
|
|
@@ -11960,6 +11997,8 @@ function invocationFromEncodeProfile(input) {
|
|
|
11960
11997
|
url: input.sourceUrl,
|
|
11961
11998
|
rtspTransport: "tcp",
|
|
11962
11999
|
fflags: ["+discardcorrupt"],
|
|
12000
|
+
analyzeDurationUs: RESTREAM_INPUT_PROBE.analyzeDurationUs,
|
|
12001
|
+
probeSizeBytes: RESTREAM_INPUT_PROBE.probeSizeBytes,
|
|
11963
12002
|
...input.profile.inputArgs?.length ? { extraArgs: input.profile.inputArgs } : {}
|
|
11964
12003
|
},
|
|
11965
12004
|
video,
|
|
@@ -19408,9 +19447,21 @@ var AlertSeveritySchema = _enum([
|
|
|
19408
19447
|
"error",
|
|
19409
19448
|
"critical"
|
|
19410
19449
|
]);
|
|
19450
|
+
/**
|
|
19451
|
+
* An action that RUNS something instead of going somewhere: the admin UI calls
|
|
19452
|
+
* the addon's custom action (`addons.custom`) with exactly these fields. The
|
|
19453
|
+
* producer owns the meaning; the UI knows nothing about the addon or the kind.
|
|
19454
|
+
*/
|
|
19455
|
+
var AlertActionInvokeSchema = object({
|
|
19456
|
+
addonId: string().min(1),
|
|
19457
|
+
action: string().min(1),
|
|
19458
|
+
input: record(string(), unknown()).optional()
|
|
19459
|
+
});
|
|
19460
|
+
/** An action has `href` (a link) OR `invoke` (a button that runs a custom action). */
|
|
19411
19461
|
var AlertActionSchema = object({
|
|
19412
19462
|
label: string(),
|
|
19413
19463
|
href: string().optional(),
|
|
19464
|
+
invoke: AlertActionInvokeSchema.optional(),
|
|
19414
19465
|
/**
|
|
19415
19466
|
* How `href` is followed. Absent / `app`: an admin-ui route (client-side).
|
|
19416
19467
|
* `server`: a route the HUB serves (an addon HTTP route such as an OAuth
|
|
@@ -22363,12 +22414,13 @@ var CHANGED = {
|
|
|
22363
22414
|
expr: "now"
|
|
22364
22415
|
};
|
|
22365
22416
|
function numeric(input) {
|
|
22417
|
+
const { alsoFrom, ...base } = input;
|
|
22366
22418
|
return {
|
|
22367
|
-
...
|
|
22419
|
+
...base,
|
|
22368
22420
|
family: "numeric",
|
|
22369
22421
|
deviceType: DeviceType.Sensor,
|
|
22370
22422
|
memberDeviceType: DeviceType.Sensor,
|
|
22371
|
-
memberDeviceTypes: [DeviceType.Sensor],
|
|
22423
|
+
memberDeviceTypes: [DeviceType.Sensor, ...alsoFrom?.deviceTypes ?? []],
|
|
22372
22424
|
activeWhen: void 0,
|
|
22373
22425
|
commandCaps: [],
|
|
22374
22426
|
baseUnit: baseUnitOf(input.quantity),
|
|
@@ -22376,9 +22428,10 @@ function numeric(input) {
|
|
|
22376
22428
|
accept: [{
|
|
22377
22429
|
cap: input.outputCap,
|
|
22378
22430
|
fieldPath: input.outputField
|
|
22379
|
-
}]
|
|
22431
|
+
}, ...alsoFrom === void 0 ? [] : [alsoFrom.accept]]
|
|
22380
22432
|
};
|
|
22381
22433
|
}
|
|
22434
|
+
var CLIMATE_DEVICES = [DeviceType.Thermostat, DeviceType.Climate];
|
|
22382
22435
|
function binary(input) {
|
|
22383
22436
|
return {
|
|
22384
22437
|
...input,
|
|
@@ -22404,7 +22457,14 @@ var GROUP_TEMPLATES = [
|
|
|
22404
22457
|
quantity: "temperature",
|
|
22405
22458
|
defaultAggregate: "mean",
|
|
22406
22459
|
empty: "null",
|
|
22407
|
-
companions: [NOW$2]
|
|
22460
|
+
companions: [NOW$2],
|
|
22461
|
+
alsoFrom: {
|
|
22462
|
+
deviceTypes: CLIMATE_DEVICES,
|
|
22463
|
+
accept: {
|
|
22464
|
+
cap: "climate-control",
|
|
22465
|
+
fieldPath: "currentTemp"
|
|
22466
|
+
}
|
|
22467
|
+
}
|
|
22408
22468
|
}),
|
|
22409
22469
|
numeric({
|
|
22410
22470
|
id: "humidity",
|
|
@@ -22415,7 +22475,14 @@ var GROUP_TEMPLATES = [
|
|
|
22415
22475
|
quantity: "humidity",
|
|
22416
22476
|
defaultAggregate: "mean",
|
|
22417
22477
|
empty: "null",
|
|
22418
|
-
companions: [NOW$2]
|
|
22478
|
+
companions: [NOW$2],
|
|
22479
|
+
alsoFrom: {
|
|
22480
|
+
deviceTypes: CLIMATE_DEVICES,
|
|
22481
|
+
accept: {
|
|
22482
|
+
cap: "climate-control",
|
|
22483
|
+
fieldPath: "currentHumidity"
|
|
22484
|
+
}
|
|
22485
|
+
}
|
|
22419
22486
|
}),
|
|
22420
22487
|
numeric({
|
|
22421
22488
|
id: "pressure",
|
|
@@ -46700,6 +46767,17 @@ var LlmProfileSchema = object({
|
|
|
46700
46767
|
* field in its editor only when its descriptor lists it in `profileFields`. */
|
|
46701
46768
|
topK: number().int().positive().optional(),
|
|
46702
46769
|
maxTokens: number().int().positive().optional(),
|
|
46770
|
+
/** How hard the model "thinks" before it answers. Omitted = the model's own
|
|
46771
|
+
* default. `off` matters for structured output: a thinking model can spend
|
|
46772
|
+
* the whole completion on reasoning and return an empty `content`. Carried
|
|
46773
|
+
* only by the wires that have it — a kind offers the field in its editor
|
|
46774
|
+
* only when its descriptor lists it in `profileFields`. */
|
|
46775
|
+
reasoningEffort: _enum([
|
|
46776
|
+
"off",
|
|
46777
|
+
"low",
|
|
46778
|
+
"medium",
|
|
46779
|
+
"high"
|
|
46780
|
+
]).optional(),
|
|
46703
46781
|
/** Prompt context window. Advisory for cloud kinds (they enforce their own). */
|
|
46704
46782
|
contextLength: number().int().positive().optional(),
|
|
46705
46783
|
/** Default system prompt. A caller's `system` REPLACES it (never appends —
|
|
@@ -46738,6 +46816,7 @@ var LlmProfileFieldSchema = _enum([
|
|
|
46738
46816
|
"topP",
|
|
46739
46817
|
"topK",
|
|
46740
46818
|
"maxTokens",
|
|
46819
|
+
"reasoningEffort",
|
|
46741
46820
|
"contextLength",
|
|
46742
46821
|
"systemPrompt",
|
|
46743
46822
|
"timeoutMs",
|
|
@@ -48040,6 +48119,43 @@ var NotificationActionSchema = object({
|
|
|
48040
48119
|
*/
|
|
48041
48120
|
mode: _enum(["navigate", "background"]).optional()
|
|
48042
48121
|
});
|
|
48122
|
+
/** A delivery parameter value: what a notifier declared it takes. */
|
|
48123
|
+
var DeliveryParamValueSchema = union$1([
|
|
48124
|
+
string(),
|
|
48125
|
+
number(),
|
|
48126
|
+
boolean()
|
|
48127
|
+
]);
|
|
48128
|
+
/**
|
|
48129
|
+
* One extra delivery parameter a notifier KIND declares (D938). A rule that
|
|
48130
|
+
* addresses a target of that kind may set it; a kind that declares nothing is
|
|
48131
|
+
* never handed one. The admin UI derives its control from this descriptor —
|
|
48132
|
+
* no editor knows a service by name.
|
|
48133
|
+
*
|
|
48134
|
+
* Optional fields are `.optional()`, never `.default()` (a Zod default does not
|
|
48135
|
+
* run on the addon cap path).
|
|
48136
|
+
*/
|
|
48137
|
+
var DeliveryParamSchema = object({
|
|
48138
|
+
key: string().min(1),
|
|
48139
|
+
label: string(),
|
|
48140
|
+
/** i18n key of the label, resolved by the declaring addon's namespace. */
|
|
48141
|
+
labelKey: string().optional(),
|
|
48142
|
+
type: _enum([
|
|
48143
|
+
"enum",
|
|
48144
|
+
"number",
|
|
48145
|
+
"boolean",
|
|
48146
|
+
"string"
|
|
48147
|
+
]),
|
|
48148
|
+
/** `enum` only: the closed set of accepted values. */
|
|
48149
|
+
options: array(object({
|
|
48150
|
+
value: string(),
|
|
48151
|
+
label: string()
|
|
48152
|
+
})).optional(),
|
|
48153
|
+
/** `number` only. */
|
|
48154
|
+
min: number().optional(),
|
|
48155
|
+
max: number().optional(),
|
|
48156
|
+
/** What the notifier does when the rule sets nothing; shown as the placeholder. */
|
|
48157
|
+
default: DeliveryParamValueSchema.optional()
|
|
48158
|
+
});
|
|
48043
48159
|
/**
|
|
48044
48160
|
* The canonical notification. `body` is the only hard field (Apprise model).
|
|
48045
48161
|
* `priority` is a 5-level ORDINAL (1=lowest … 3=normal(default) … 5=urgent),
|
|
@@ -48062,7 +48178,13 @@ var NotificationSchema = object({
|
|
|
48062
48178
|
tag: string().optional(),
|
|
48063
48179
|
deviceId: number().optional(),
|
|
48064
48180
|
eventId: string().optional(),
|
|
48065
|
-
metadata: record(string(), unknown()).optional()
|
|
48181
|
+
metadata: record(string(), unknown()).optional(),
|
|
48182
|
+
/**
|
|
48183
|
+
* Values for the parameters the target's kind DECLARES in
|
|
48184
|
+
* {@link TargetKindSchema} `deliveryParams`. Already validated against the
|
|
48185
|
+
* declaration by the sender; a notifier reads only the keys it declared.
|
|
48186
|
+
*/
|
|
48187
|
+
delivery: record(string(), DeliveryParamValueSchema).optional()
|
|
48066
48188
|
});
|
|
48067
48189
|
/** One declared native severity/priority level for a kind. */
|
|
48068
48190
|
var TargetKindLevelSchema = object({
|
|
@@ -48168,6 +48290,11 @@ var TargetKindSchema = object({
|
|
|
48168
48290
|
*/
|
|
48169
48291
|
destinationKeys: array(string()).optional(),
|
|
48170
48292
|
supportsDiscovery: boolean(),
|
|
48293
|
+
/**
|
|
48294
|
+
* Extra delivery parameters a rule may set for a target of this kind (D938).
|
|
48295
|
+
* Absent = none; the rule editor then offers nothing.
|
|
48296
|
+
*/
|
|
48297
|
+
deliveryParams: array(DeliveryParamSchema).optional(),
|
|
48171
48298
|
caps: TargetKindCapsSchema
|
|
48172
48299
|
});
|
|
48173
48300
|
/**
|
|
@@ -61182,7 +61309,9 @@ var ManifestShapeSchema = object({
|
|
|
61182
61309
|
icon: string().optional()
|
|
61183
61310
|
}).optional(),
|
|
61184
61311
|
protected: boolean().optional(),
|
|
61185
|
-
removable: boolean().optional()
|
|
61312
|
+
removable: boolean().optional(),
|
|
61313
|
+
/** Declared Integrations-page block (mirror of `AddonDeclaration.integrationSection`). */
|
|
61314
|
+
integrationSection: _enum(["system", "providers"]).optional()
|
|
61186
61315
|
});
|
|
61187
61316
|
var AddonProcessSchema = object({
|
|
61188
61317
|
pid: number().optional(),
|
|
@@ -62044,11 +62173,373 @@ DeviceType.Light, method(object({
|
|
|
62044
62173
|
level: number().min(0).max(100),
|
|
62045
62174
|
lastChangedAt: number()
|
|
62046
62175
|
});
|
|
62176
|
+
/**
|
|
62177
|
+
* The role vocabulary of a remote (D963): what a button MEANS, independent of
|
|
62178
|
+
* how it is wired. A layout template places buttons by role; a device binds a
|
|
62179
|
+
* role to an action; an exporter asks for a role by name. Roles are shared so
|
|
62180
|
+
* one layout fits every appliance and one voice command fits every binding.
|
|
62181
|
+
*
|
|
62182
|
+
* A role outside this list is `custom:<key>` — the operator's own button (a
|
|
62183
|
+
* SmartIR source, a channel preset). The key is a lowercase slug.
|
|
62184
|
+
*/
|
|
62185
|
+
var REMOTE_KNOWN_ROLES = [
|
|
62186
|
+
"power",
|
|
62187
|
+
"power_on",
|
|
62188
|
+
"power_off",
|
|
62189
|
+
"volume_up",
|
|
62190
|
+
"volume_down",
|
|
62191
|
+
"mute",
|
|
62192
|
+
"channel_up",
|
|
62193
|
+
"channel_down",
|
|
62194
|
+
"up",
|
|
62195
|
+
"down",
|
|
62196
|
+
"left",
|
|
62197
|
+
"right",
|
|
62198
|
+
"ok",
|
|
62199
|
+
"back",
|
|
62200
|
+
"home",
|
|
62201
|
+
"menu",
|
|
62202
|
+
"info",
|
|
62203
|
+
"guide",
|
|
62204
|
+
"exit",
|
|
62205
|
+
"input",
|
|
62206
|
+
"play",
|
|
62207
|
+
"pause",
|
|
62208
|
+
"play_pause",
|
|
62209
|
+
"stop",
|
|
62210
|
+
"next",
|
|
62211
|
+
"previous",
|
|
62212
|
+
"fast_forward",
|
|
62213
|
+
"rewind",
|
|
62214
|
+
"digit_0",
|
|
62215
|
+
"digit_1",
|
|
62216
|
+
"digit_2",
|
|
62217
|
+
"digit_3",
|
|
62218
|
+
"digit_4",
|
|
62219
|
+
"digit_5",
|
|
62220
|
+
"digit_6",
|
|
62221
|
+
"digit_7",
|
|
62222
|
+
"digit_8",
|
|
62223
|
+
"digit_9"
|
|
62224
|
+
];
|
|
62225
|
+
var CUSTOM_KEY_RE = /^[a-z0-9][a-z0-9_]{0,47}$/;
|
|
62226
|
+
var KNOWN_ROLES = new Set(REMOTE_KNOWN_ROLES);
|
|
62227
|
+
function isRemoteKnownRole(value) {
|
|
62228
|
+
return KNOWN_ROLES.has(value);
|
|
62229
|
+
}
|
|
62230
|
+
function isRemoteCustomKey(key) {
|
|
62231
|
+
return CUSTOM_KEY_RE.test(key);
|
|
62232
|
+
}
|
|
62233
|
+
/** The key of a `custom:<key>` role, or null for any other string. */
|
|
62234
|
+
function customKeyOfRole(role) {
|
|
62235
|
+
if (!role.startsWith("custom:")) return null;
|
|
62236
|
+
const key = role.slice(7);
|
|
62237
|
+
return isRemoteCustomKey(key) ? key : null;
|
|
62238
|
+
}
|
|
62239
|
+
function isRemoteRole(value) {
|
|
62240
|
+
return isRemoteKnownRole(value) || customKeyOfRole(value) !== null;
|
|
62241
|
+
}
|
|
62242
|
+
var RemoteRoleSchema = string().refine(isRemoteRole, { message: "a role is one of the known roles or custom:<key> (lowercase letters, digits, _)" });
|
|
62243
|
+
var RemoteBindingSchema = object({ action: AutomationCapStepSchema.extend({ deviceId: number().int().nonnegative() }) });
|
|
62244
|
+
var RemoteCustomButtonSchema = object({
|
|
62245
|
+
/** The slug after `custom:` in the role. */
|
|
62246
|
+
key: string().refine(isRemoteCustomKey, { message: "a lowercase slug" }),
|
|
62247
|
+
/** What the operator calls it, and what a voice command may name. */
|
|
62248
|
+
name: string().min(1).max(60)
|
|
62249
|
+
});
|
|
62250
|
+
var RemotePowerModeSchema = _enum(["toggle", "discrete"]);
|
|
62251
|
+
var RemoteConfigSchema = object({
|
|
62252
|
+
layoutTemplateId: string().min(1).nullable(),
|
|
62253
|
+
/**
|
|
62254
|
+
* The transmitter device new bindings and an import send through. A binding
|
|
62255
|
+
* names its own device, so one command may override it.
|
|
62256
|
+
*/
|
|
62257
|
+
defaultTransmitterId: number().int().nonnegative().nullable().default(null),
|
|
62258
|
+
/** Keyed by role. A role with no entry falls back to the native cap. */
|
|
62259
|
+
bindings: record(string(), RemoteBindingSchema),
|
|
62260
|
+
customButtons: array(RemoteCustomButtonSchema).max(100),
|
|
62261
|
+
power: object({ mode: RemotePowerModeSchema })
|
|
62262
|
+
}).superRefine((config, ctx) => {
|
|
62263
|
+
const roles = Object.keys(config.bindings);
|
|
62264
|
+
if (roles.length > 200) ctx.addIssue({
|
|
62265
|
+
code: "custom",
|
|
62266
|
+
message: "too many bindings",
|
|
62267
|
+
path: ["bindings"]
|
|
62268
|
+
});
|
|
62269
|
+
for (const role of roles) if (!isRemoteRole(role)) ctx.addIssue({
|
|
62270
|
+
code: "custom",
|
|
62271
|
+
message: `"${role}" is not a role`,
|
|
62272
|
+
path: ["bindings", role]
|
|
62273
|
+
});
|
|
62274
|
+
const keys = /* @__PURE__ */ new Set();
|
|
62275
|
+
config.customButtons.forEach((button, index) => {
|
|
62276
|
+
if (keys.has(button.key)) ctx.addIssue({
|
|
62277
|
+
code: "custom",
|
|
62278
|
+
message: `custom button "${button.key}" is listed twice`,
|
|
62279
|
+
path: [
|
|
62280
|
+
"customButtons",
|
|
62281
|
+
index,
|
|
62282
|
+
"key"
|
|
62283
|
+
]
|
|
62284
|
+
});
|
|
62285
|
+
keys.add(button.key);
|
|
62286
|
+
});
|
|
62287
|
+
for (const role of roles) {
|
|
62288
|
+
const key = customKeyOfRole(role);
|
|
62289
|
+
if (key !== null && !keys.has(key)) ctx.addIssue({
|
|
62290
|
+
code: "custom",
|
|
62291
|
+
message: `${role} is bound but has no entry in customButtons`,
|
|
62292
|
+
path: ["bindings", role]
|
|
62293
|
+
});
|
|
62294
|
+
}
|
|
62295
|
+
});
|
|
62296
|
+
object({
|
|
62297
|
+
power: object({
|
|
62298
|
+
state: _enum(["on", "off"]),
|
|
62299
|
+
at: number()
|
|
62300
|
+
}).nullable(),
|
|
62301
|
+
muted: object({
|
|
62302
|
+
value: boolean(),
|
|
62303
|
+
at: number()
|
|
62304
|
+
}).nullable()
|
|
62305
|
+
});
|
|
62306
|
+
var RemoteLayoutButtonSchema = object({
|
|
62307
|
+
id: string().min(1).max(40),
|
|
62308
|
+
/** 0-based grid position. */
|
|
62309
|
+
row: number().int().min(0).max(24),
|
|
62310
|
+
col: number().int().min(0).max(24),
|
|
62311
|
+
rowSpan: number().int().min(1).max(24),
|
|
62312
|
+
colSpan: number().int().min(1).max(24),
|
|
62313
|
+
icon: string().min(1).max(60).optional(),
|
|
62314
|
+
label: string().min(1).max(40).optional(),
|
|
62315
|
+
role: RemoteRoleSchema
|
|
62316
|
+
});
|
|
62317
|
+
object({
|
|
62318
|
+
columns: number().int().min(1).max(24),
|
|
62319
|
+
rows: number().int().min(1).max(24),
|
|
62320
|
+
buttons: array(RemoteLayoutButtonSchema).max(200)
|
|
62321
|
+
}).superRefine((grid, ctx) => {
|
|
62322
|
+
const ids = /* @__PURE__ */ new Set();
|
|
62323
|
+
const taken = /* @__PURE__ */ new Map();
|
|
62324
|
+
grid.buttons.forEach((button, index) => {
|
|
62325
|
+
if (ids.has(button.id)) ctx.addIssue({
|
|
62326
|
+
code: "custom",
|
|
62327
|
+
message: `button id "${button.id}" is used twice`,
|
|
62328
|
+
path: [
|
|
62329
|
+
"buttons",
|
|
62330
|
+
index,
|
|
62331
|
+
"id"
|
|
62332
|
+
]
|
|
62333
|
+
});
|
|
62334
|
+
ids.add(button.id);
|
|
62335
|
+
if (button.row + button.rowSpan > grid.rows || button.col + button.colSpan > grid.columns) {
|
|
62336
|
+
ctx.addIssue({
|
|
62337
|
+
code: "custom",
|
|
62338
|
+
message: `button "${button.id}" leaves the grid`,
|
|
62339
|
+
path: ["buttons", index]
|
|
62340
|
+
});
|
|
62341
|
+
return;
|
|
62342
|
+
}
|
|
62343
|
+
for (let r = button.row; r < button.row + button.rowSpan; r += 1) for (let c = button.col; c < button.col + button.colSpan; c += 1) {
|
|
62344
|
+
const cell = `${r}:${c}`;
|
|
62345
|
+
const other = taken.get(cell);
|
|
62346
|
+
if (other !== void 0) {
|
|
62347
|
+
ctx.addIssue({
|
|
62348
|
+
code: "custom",
|
|
62349
|
+
message: `buttons "${other}" and "${button.id}" overlap`,
|
|
62350
|
+
path: ["buttons", index]
|
|
62351
|
+
});
|
|
62352
|
+
return;
|
|
62353
|
+
}
|
|
62354
|
+
taken.set(cell, button.id);
|
|
62355
|
+
}
|
|
62356
|
+
});
|
|
62357
|
+
});
|
|
62358
|
+
var RemoteBoundCommandSchema = object({
|
|
62359
|
+
role: RemoteRoleSchema,
|
|
62360
|
+
/** The operator's name for a custom button; absent for a known role. */
|
|
62361
|
+
label: string().optional(),
|
|
62362
|
+
custom: boolean()
|
|
62363
|
+
});
|
|
62364
|
+
var RemoteCommandListSchema = object({
|
|
62365
|
+
layoutTemplateId: string().nullable(),
|
|
62366
|
+
power: object({ mode: RemotePowerModeSchema }),
|
|
62367
|
+
/** Only the roles that are BOUND — the ones a press can reach. */
|
|
62368
|
+
commands: array(RemoteBoundCommandSchema)
|
|
62369
|
+
});
|
|
62370
|
+
var RemoteRefusalReasonSchema = _enum([
|
|
62371
|
+
"no-remote",
|
|
62372
|
+
"unbound-role",
|
|
62373
|
+
"action-failed"
|
|
62374
|
+
]);
|
|
62375
|
+
var RemoteSendResultSchema = discriminatedUnion("status", [
|
|
62376
|
+
object({
|
|
62377
|
+
status: literal("sent"),
|
|
62378
|
+
/** How many times the action ran. */
|
|
62379
|
+
sends: number().int().min(1)
|
|
62380
|
+
}),
|
|
62381
|
+
object({
|
|
62382
|
+
status: literal("skipped"),
|
|
62383
|
+
reason: literal("already-in-state")
|
|
62384
|
+
}),
|
|
62385
|
+
object({
|
|
62386
|
+
status: literal("refused"),
|
|
62387
|
+
reason: RemoteRefusalReasonSchema,
|
|
62388
|
+
detail: string().optional()
|
|
62389
|
+
})
|
|
62390
|
+
]);
|
|
62391
|
+
var RemoteMediaCommandSchema = _enum([
|
|
62392
|
+
"play",
|
|
62393
|
+
"pause",
|
|
62394
|
+
"stop",
|
|
62395
|
+
"next",
|
|
62396
|
+
"previous",
|
|
62397
|
+
"setMute",
|
|
62398
|
+
"selectSource"
|
|
62399
|
+
]);
|
|
62400
|
+
/** A send result, or `not-routed`: the role is not bound, so the native cap answers. */
|
|
62401
|
+
var RemoteMediaCommandResultSchema = discriminatedUnion("status", [...RemoteSendResultSchema.options, object({ status: literal("not-routed") })]);
|
|
62402
|
+
var RemoteSetConfigResultSchema = discriminatedUnion("status", [object({ status: literal("saved") }), object({
|
|
62403
|
+
status: literal("refused"),
|
|
62404
|
+
reason: _enum(["unknown-template", "not-a-media-player"]),
|
|
62405
|
+
detail: string()
|
|
62406
|
+
})]);
|
|
62407
|
+
var deviceInput = object({ deviceId: number().int().nonnegative() });
|
|
62408
|
+
DeviceType.MediaPlayer;
|
|
62409
|
+
method(deviceInput, RemoteConfigSchema, { auth: "admin" }), method(deviceInput.extend({ config: RemoteConfigSchema }), RemoteSetConfigResultSchema, {
|
|
62410
|
+
kind: "mutation",
|
|
62411
|
+
auth: "admin"
|
|
62412
|
+
}), method(deviceInput, RemoteCommandListSchema, { auth: "protected" }), method(deviceInput.extend({
|
|
62413
|
+
role: RemoteRoleSchema,
|
|
62414
|
+
/** Sends in a row (volume steps). */
|
|
62415
|
+
repeat: number().int().min(1).max(50).default(1)
|
|
62416
|
+
}), RemoteSendResultSchema, {
|
|
62417
|
+
kind: "mutation",
|
|
62418
|
+
auth: "protected"
|
|
62419
|
+
}), method(deviceInput.extend({
|
|
62420
|
+
command: RemoteMediaCommandSchema,
|
|
62421
|
+
muted: boolean().optional(),
|
|
62422
|
+
source: string().optional(),
|
|
62423
|
+
repeat: number().int().min(1).max(50).default(1)
|
|
62424
|
+
}), RemoteMediaCommandResultSchema, {
|
|
62425
|
+
kind: "mutation",
|
|
62426
|
+
auth: "protected"
|
|
62427
|
+
});
|
|
62428
|
+
var TemplateKindSchema = _enum(["remote"]);
|
|
62429
|
+
/**
|
|
62430
|
+
* template — the generic store of reusable, named operator data (D963). A
|
|
62431
|
+
* record is `{ id, kind, name, payload }`; the kinds (today only `remote`, the
|
|
62432
|
+
* button grid of a remote) and the schema each payload must satisfy are
|
|
62433
|
+
* declared by the system in `template-kinds.ts`. Nothing here is specific to a
|
|
62434
|
+
* kind: the engine validates a payload against its kind's schema and, on a
|
|
62435
|
+
* delete, asks the kind's owner whether anything still points at the record.
|
|
62436
|
+
*
|
|
62437
|
+
* Every refusal is a typed result — a UI says "unknown kind" or names the
|
|
62438
|
+
* devices that still use a template, without parsing text.
|
|
62439
|
+
*/
|
|
62440
|
+
var TemplateRecordSchema = object({
|
|
62441
|
+
id: string().min(1),
|
|
62442
|
+
kind: TemplateKindSchema,
|
|
62443
|
+
name: string().min(1).max(120),
|
|
62444
|
+
/** Shaped by the kind; `checkTemplatePayload(kind, payload)` reads it. */
|
|
62445
|
+
payload: unknown(),
|
|
62446
|
+
createdAt: number(),
|
|
62447
|
+
updatedAt: number()
|
|
62448
|
+
});
|
|
62449
|
+
var TemplateWriteResultSchema = discriminatedUnion("status", [object({
|
|
62450
|
+
status: literal("saved"),
|
|
62451
|
+
template: TemplateRecordSchema
|
|
62452
|
+
}), object({
|
|
62453
|
+
status: literal("refused"),
|
|
62454
|
+
reason: _enum(["invalid-payload", "not-found"]),
|
|
62455
|
+
detail: string()
|
|
62456
|
+
})]);
|
|
62457
|
+
/** A device still pointing at a template. */
|
|
62458
|
+
var TemplateUserSchema = object({
|
|
62459
|
+
deviceId: number().int().nonnegative(),
|
|
62460
|
+
name: string()
|
|
62461
|
+
});
|
|
62462
|
+
var TemplateDeleteResultSchema = discriminatedUnion("status", [
|
|
62463
|
+
object({ status: literal("deleted") }),
|
|
62464
|
+
object({ status: literal("not-found") }),
|
|
62465
|
+
object({
|
|
62466
|
+
status: literal("in-use"),
|
|
62467
|
+
devices: array(TemplateUserSchema).min(1)
|
|
62468
|
+
})
|
|
62469
|
+
]);
|
|
62470
|
+
method(object({ kind: TemplateKindSchema.optional() }), array(TemplateRecordSchema), { auth: "protected" }), method(object({ id: string().min(1) }), TemplateRecordSchema.nullable(), { auth: "protected" }), method(object({
|
|
62471
|
+
kind: TemplateKindSchema,
|
|
62472
|
+
name: string().min(1).max(120),
|
|
62473
|
+
payload: unknown()
|
|
62474
|
+
}), TemplateWriteResultSchema, {
|
|
62475
|
+
kind: "mutation",
|
|
62476
|
+
auth: "admin"
|
|
62477
|
+
}), method(object({
|
|
62478
|
+
id: string().min(1),
|
|
62479
|
+
name: string().min(1).max(120).optional(),
|
|
62480
|
+
payload: unknown().optional()
|
|
62481
|
+
}), TemplateWriteResultSchema, {
|
|
62482
|
+
kind: "mutation",
|
|
62483
|
+
auth: "admin"
|
|
62484
|
+
}), method(object({ id: string().min(1) }), TemplateDeleteResultSchema, {
|
|
62485
|
+
kind: "mutation",
|
|
62486
|
+
auth: "admin"
|
|
62487
|
+
});
|
|
62047
62488
|
DeviceType.Button, method(object({ deviceId: number().int().nonnegative() }), _void(), {
|
|
62048
62489
|
kind: "mutation",
|
|
62049
62490
|
auth: "protected"
|
|
62050
62491
|
});
|
|
62051
62492
|
/**
|
|
62493
|
+
* A pulse train in signed microseconds: mark (+) first, then space (-), strictly
|
|
62494
|
+
* alternating, no zeros, 2..1024 entries.
|
|
62495
|
+
*/
|
|
62496
|
+
var IrTimingsSchema = array(number().int()).min(2).max(1024).superRefine((timings, ctx) => {
|
|
62497
|
+
timings.forEach((value, index) => {
|
|
62498
|
+
const expectMark = index % 2 === 0;
|
|
62499
|
+
if (value === 0 || value > 0 !== expectMark) ctx.addIssue({
|
|
62500
|
+
code: "custom",
|
|
62501
|
+
message: `timing ${index} must be a non-zero ${expectMark ? "mark (positive)" : "space (negative)"}`,
|
|
62502
|
+
path: [index]
|
|
62503
|
+
});
|
|
62504
|
+
});
|
|
62505
|
+
});
|
|
62506
|
+
/** Per-command transmit options. Every key is optional; a transmitter applies what it can. */
|
|
62507
|
+
var TransmitSettingsSchema = object({
|
|
62508
|
+
carrierHz: number().int().positive().optional(),
|
|
62509
|
+
dutyCyclePercent: number().int().min(1).max(100).optional(),
|
|
62510
|
+
repeat: number().int().min(0).max(20).optional(),
|
|
62511
|
+
repeatDelayMs: number().int().min(0).optional()
|
|
62512
|
+
});
|
|
62513
|
+
/** The setting keys a transmitter may declare as settable (`getInfo.settable`). */
|
|
62514
|
+
var TransmitSettingKeySchema = _enum([
|
|
62515
|
+
"carrierHz",
|
|
62516
|
+
"dutyCyclePercent",
|
|
62517
|
+
"repeat",
|
|
62518
|
+
"repeatDelayMs"
|
|
62519
|
+
]);
|
|
62520
|
+
var IrMediumSchema = _enum(["ir", "rf"]);
|
|
62521
|
+
var IrSendResultSchema = object({
|
|
62522
|
+
ok: literal(true),
|
|
62523
|
+
/** Settings the transmitter could not apply; the train was still sent. */
|
|
62524
|
+
ignoredSettings: array(string())
|
|
62525
|
+
});
|
|
62526
|
+
var IrTransmitterInfoSchema = object({
|
|
62527
|
+
media: array(IrMediumSchema),
|
|
62528
|
+
settable: array(TransmitSettingKeySchema),
|
|
62529
|
+
maxTimings: number().int().positive()
|
|
62530
|
+
});
|
|
62531
|
+
DeviceType.Generic, method(object({
|
|
62532
|
+
deviceId: number().int().nonnegative(),
|
|
62533
|
+
timings: IrTimingsSchema,
|
|
62534
|
+
settings: TransmitSettingsSchema.optional()
|
|
62535
|
+
}), IrSendResultSchema, {
|
|
62536
|
+
kind: "mutation",
|
|
62537
|
+
auth: "protected"
|
|
62538
|
+
}), method(object({ deviceId: number().int().nonnegative() }), IrTransmitterInfoSchema, {
|
|
62539
|
+
kind: "query",
|
|
62540
|
+
auth: "protected"
|
|
62541
|
+
});
|
|
62542
|
+
/**
|
|
62052
62543
|
* `calendar-source` — collection cap exposing per-provider calendars and
|
|
62053
62544
|
* their events. Every addon that contributes calendars (Home Assistant,
|
|
62054
62545
|
* a future Google Calendar addon, …) registers a provider here. The hub
|
|
@@ -64743,9 +65234,35 @@ var MediaInfoSchema = object({
|
|
|
64743
65234
|
/** Optional cover-art / thumbnail URL. */
|
|
64744
65235
|
imageUrl: string().optional()
|
|
64745
65236
|
});
|
|
65237
|
+
/**
|
|
65238
|
+
* Where `state`, `volumeLevel`, `isMuted` and `source` come from. `reported`:
|
|
65239
|
+
* the device said so. `assumed`: the driver has no feedback (infrared) and
|
|
65240
|
+
* tracks what it last SENT; it moves only after a send was accepted, and a
|
|
65241
|
+
* human at the real remote makes it wrong. A UI shows an assumed value as a
|
|
65242
|
+
* guess, never as a reading.
|
|
65243
|
+
*/
|
|
65244
|
+
var MediaPlayerStateSourceSchema = _enum(["reported", "assumed"]);
|
|
65245
|
+
/** The fields of a media-player status a driver can only guess. */
|
|
65246
|
+
var MediaPlayerAssumedFieldSchema = _enum([
|
|
65247
|
+
"state",
|
|
65248
|
+
"volumeLevel",
|
|
65249
|
+
"isMuted",
|
|
65250
|
+
"source"
|
|
65251
|
+
]);
|
|
64746
65252
|
object({
|
|
64747
65253
|
/** Playback lifecycle state. */
|
|
64748
65254
|
state: MediaPlayerStateSchema,
|
|
65255
|
+
/**
|
|
65256
|
+
* Whether the state fields are readings or the driver's own bookkeeping.
|
|
65257
|
+
* A slice written before this field existed parses as `reported`.
|
|
65258
|
+
*/
|
|
65259
|
+
stateSource: MediaPlayerStateSourceSchema.default("reported"),
|
|
65260
|
+
/**
|
|
65261
|
+
* Which fields are the driver's own guess. `stateSource` is `assumed` when
|
|
65262
|
+
* this is not empty; a field not listed here is a reading even then (power
|
|
65263
|
+
* from a running-state source, mute guessed from the last send).
|
|
65264
|
+
*/
|
|
65265
|
+
assumedFields: array(MediaPlayerAssumedFieldSchema).default([]),
|
|
64749
65266
|
/** Volume as 0..100 inclusive. Null when the device has no volume
|
|
64750
65267
|
* surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
|
|
64751
65268
|
volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
@@ -66151,9 +66668,14 @@ object({
|
|
|
66151
66668
|
* (`device_class: problem`, on = low). True when the tank reports empty,
|
|
66152
66669
|
* or, on a dual-hopper model, when EITHER hopper is empty. */
|
|
66153
66670
|
lowFood: boolean(),
|
|
66154
|
-
/** Battery charge 0..100 (%).
|
|
66155
|
-
*
|
|
66671
|
+
/** Battery charge 0..100 (%). On a feeder running on `mains` this is the
|
|
66672
|
+
* BACKUP battery's charge, not the power source. Null when the device has
|
|
66673
|
+
* no battery reading. */
|
|
66156
66674
|
batteryPower: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
66675
|
+
/** What the feeder is powered from right now: `mains` (plugged in, the
|
|
66676
|
+
* battery is only a backup) or `battery`. Null when the device does not
|
|
66677
|
+
* report it. */
|
|
66678
|
+
powerSource: _enum(["mains", "battery"]).nullable(),
|
|
66157
66679
|
/**
|
|
66158
66680
|
* Desiccant life remaining, stored in seconds (duration base, D944).
|
|
66159
66681
|
* Providers convert from the days the feeder reports. Null when the
|
|
@@ -66181,6 +66703,14 @@ object({
|
|
|
66181
66703
|
feedSound: boolean(),
|
|
66182
66704
|
/** Speaker / prompt volume level (device-scaled integer). */
|
|
66183
66705
|
volume: number().meta(readingMeta("none")),
|
|
66706
|
+
/** Portion (grams) of the last manual feed sent from a single-hopper
|
|
66707
|
+
* stepper — the default the next manual feed starts from. Persisted per
|
|
66708
|
+
* device by the provider; null until a manual feed has been sent. */
|
|
66709
|
+
lastFeedGrams: gramsPortion.nullable(),
|
|
66710
|
+
/** Hopper-1 portion of the last manual feed (dual-hopper); null until sent. */
|
|
66711
|
+
lastFeedHopper1: gramsPortion.nullable(),
|
|
66712
|
+
/** Hopper-2 portion of the last manual feed (dual-hopper); null until sent. */
|
|
66713
|
+
lastFeedHopper2: gramsPortion.nullable(),
|
|
66184
66714
|
/** Ms epoch when the slice was last refreshed from the cloud. */
|
|
66185
66715
|
lastFetchedAt: number()
|
|
66186
66716
|
});
|
|
@@ -71346,6 +71876,14 @@ method(object({}), array(TrainingBaseModelSchema).readonly(), { auth: "admin" })
|
|
|
71346
71876
|
kind: "mutation",
|
|
71347
71877
|
auth: "admin"
|
|
71348
71878
|
});
|
|
71879
|
+
discriminatedUnion("kind", [object({
|
|
71880
|
+
kind: literal("raw"),
|
|
71881
|
+
timings: array(number().int()),
|
|
71882
|
+
settings: TransmitSettingsSchema.optional()
|
|
71883
|
+
}), object({
|
|
71884
|
+
kind: literal("pronto"),
|
|
71885
|
+
code: string()
|
|
71886
|
+
})]);
|
|
71349
71887
|
/**
|
|
71350
71888
|
* Which of OUR object detections a clip window holds — the ONE overlap rule
|
|
71351
71889
|
* and the ONE label ranking, for every clip source (D923).
|
|
@@ -71388,7 +71926,7 @@ function dominantClipLabels(events) {
|
|
|
71388
71926
|
}
|
|
71389
71927
|
DeviceFeature.FanSpeed, DeviceFeature.FanPreset, DeviceFeature.FanDirection, DeviceFeature.FanOscillating, DeviceFeature.CoverPositionable, DeviceFeature.CoverTilt, DeviceFeature.ValvePositionable, DeviceFeature.MediaPlayerVolume, DeviceFeature.ClimateFanMode;
|
|
71390
71928
|
SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
|
|
71391
|
-
DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, DeviceType.EventEmitter, DeviceType.Camera, DeviceType.Hub, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.Dishwasher, DeviceType.Washer, DeviceType.Dryer, DeviceType.Camera, DeviceType.Camera, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
|
|
71929
|
+
DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, DeviceType.EventEmitter, DeviceType.Camera, DeviceType.Hub, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.Dishwasher, DeviceType.Washer, DeviceType.Dryer, DeviceType.Camera, DeviceType.Camera, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
|
|
71392
71930
|
String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
|
|
71393
71931
|
DeviceRole.BinarySensor, DeviceRole.MotionSensor;
|
|
71394
71932
|
new Set(CAP_NAMES);
|
|
@@ -75011,6 +75549,20 @@ Object.freeze({
|
|
|
75011
75549
|
access: "create",
|
|
75012
75550
|
role: "viewer"
|
|
75013
75551
|
},
|
|
75552
|
+
"irTransmitter.getInfo": {
|
|
75553
|
+
capName: "ir-transmitter",
|
|
75554
|
+
capScope: "device",
|
|
75555
|
+
addonId: null,
|
|
75556
|
+
access: "view",
|
|
75557
|
+
role: "viewer"
|
|
75558
|
+
},
|
|
75559
|
+
"irTransmitter.send": {
|
|
75560
|
+
capName: "ir-transmitter",
|
|
75561
|
+
capScope: "device",
|
|
75562
|
+
addonId: null,
|
|
75563
|
+
access: "create",
|
|
75564
|
+
role: "viewer"
|
|
75565
|
+
},
|
|
75014
75566
|
"keychain.delete": {
|
|
75015
75567
|
capName: "keychain",
|
|
75016
75568
|
capScope: "system",
|
|
@@ -79134,6 +79686,41 @@ Object.freeze({
|
|
|
79134
79686
|
access: "create",
|
|
79135
79687
|
role: "admin"
|
|
79136
79688
|
},
|
|
79689
|
+
"remote.getConfig": {
|
|
79690
|
+
capName: "remote",
|
|
79691
|
+
capScope: "system",
|
|
79692
|
+
addonId: null,
|
|
79693
|
+
access: "view",
|
|
79694
|
+
role: "admin"
|
|
79695
|
+
},
|
|
79696
|
+
"remote.listCommands": {
|
|
79697
|
+
capName: "remote",
|
|
79698
|
+
capScope: "system",
|
|
79699
|
+
addonId: null,
|
|
79700
|
+
access: "view",
|
|
79701
|
+
role: "admin"
|
|
79702
|
+
},
|
|
79703
|
+
"remote.sendCommand": {
|
|
79704
|
+
capName: "remote",
|
|
79705
|
+
capScope: "system",
|
|
79706
|
+
addonId: null,
|
|
79707
|
+
access: "create",
|
|
79708
|
+
role: "admin"
|
|
79709
|
+
},
|
|
79710
|
+
"remote.sendMediaCommand": {
|
|
79711
|
+
capName: "remote",
|
|
79712
|
+
capScope: "system",
|
|
79713
|
+
addonId: null,
|
|
79714
|
+
access: "create",
|
|
79715
|
+
role: "admin"
|
|
79716
|
+
},
|
|
79717
|
+
"remote.setConfig": {
|
|
79718
|
+
capName: "remote",
|
|
79719
|
+
capScope: "system",
|
|
79720
|
+
addonId: null,
|
|
79721
|
+
access: "create",
|
|
79722
|
+
role: "admin"
|
|
79723
|
+
},
|
|
79137
79724
|
"runningState.getStatus": {
|
|
79138
79725
|
capName: "running-state",
|
|
79139
79726
|
capScope: "device",
|
|
@@ -80324,6 +80911,41 @@ Object.freeze({
|
|
|
80324
80911
|
access: "view",
|
|
80325
80912
|
role: "viewer"
|
|
80326
80913
|
},
|
|
80914
|
+
"template.create": {
|
|
80915
|
+
capName: "template",
|
|
80916
|
+
capScope: "system",
|
|
80917
|
+
addonId: null,
|
|
80918
|
+
access: "create",
|
|
80919
|
+
role: "admin"
|
|
80920
|
+
},
|
|
80921
|
+
"template.delete": {
|
|
80922
|
+
capName: "template",
|
|
80923
|
+
capScope: "system",
|
|
80924
|
+
addonId: null,
|
|
80925
|
+
access: "delete",
|
|
80926
|
+
role: "admin"
|
|
80927
|
+
},
|
|
80928
|
+
"template.get": {
|
|
80929
|
+
capName: "template",
|
|
80930
|
+
capScope: "system",
|
|
80931
|
+
addonId: null,
|
|
80932
|
+
access: "view",
|
|
80933
|
+
role: "admin"
|
|
80934
|
+
},
|
|
80935
|
+
"template.list": {
|
|
80936
|
+
capName: "template",
|
|
80937
|
+
capScope: "system",
|
|
80938
|
+
addonId: null,
|
|
80939
|
+
access: "view",
|
|
80940
|
+
role: "admin"
|
|
80941
|
+
},
|
|
80942
|
+
"template.update": {
|
|
80943
|
+
capName: "template",
|
|
80944
|
+
capScope: "system",
|
|
80945
|
+
addonId: null,
|
|
80946
|
+
access: "create",
|
|
80947
|
+
role: "admin"
|
|
80948
|
+
},
|
|
80327
80949
|
"terminalSession.adoptLegacyMonitor": {
|
|
80328
80950
|
capName: "terminal-session",
|
|
80329
80951
|
capScope: "system",
|
|
@@ -82634,6 +83256,11 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
82634
83256
|
icon: "circle-dot"
|
|
82635
83257
|
}]
|
|
82636
83258
|
},
|
|
83259
|
+
"ir-transmitter": {
|
|
83260
|
+
scope: "device",
|
|
83261
|
+
noun: t("IR / RF transmitter", "Trasmettitore IR / RF"),
|
|
83262
|
+
notOperatorFacing: { send: "a raw pulse train is not something an operator composes in an automation; the remote that owns the command table sends it" }
|
|
83263
|
+
},
|
|
82637
83264
|
control: {
|
|
82638
83265
|
scope: "device",
|
|
82639
83266
|
noun: t("Control", "Controllo"),
|
|
@@ -85150,6 +85777,7 @@ var SYSTEM_CAP_VOCABULARY = {
|
|
|
85150
85777
|
"recording-archive": system(STORAGE),
|
|
85151
85778
|
"recording-export": system("recording exports — requested from the timeline, not an automation step"),
|
|
85152
85779
|
records: system(INTERNAL),
|
|
85780
|
+
remote: system("the per-device remote setup — authored in the Customize remote editor, sent through the remote UI"),
|
|
85153
85781
|
"server-management": system(CLUSTER),
|
|
85154
85782
|
"settings-store": system(INTERNAL),
|
|
85155
85783
|
"smtp-provider": system(INTERNAL),
|
|
@@ -85162,6 +85790,7 @@ var SYSTEM_CAP_VOCABULARY = {
|
|
|
85162
85790
|
"storage-provider": system(STORAGE),
|
|
85163
85791
|
"stream-broker": system(PIPELINE),
|
|
85164
85792
|
system: system(CLUSTER),
|
|
85793
|
+
template: system("operator-authored templates — edited in their own editor, never actuated"),
|
|
85165
85794
|
"terminal-session": system(CLUSTER),
|
|
85166
85795
|
toast: system(UI_PLUMBING),
|
|
85167
85796
|
training: system(ML),
|
|
@@ -86353,6 +86982,16 @@ Object.freeze({
|
|
|
86353
86982
|
form: "single",
|
|
86354
86983
|
optional: false
|
|
86355
86984
|
}],
|
|
86985
|
+
"irTransmitter.getInfo": [{
|
|
86986
|
+
name: "deviceId",
|
|
86987
|
+
form: "single",
|
|
86988
|
+
optional: false
|
|
86989
|
+
}],
|
|
86990
|
+
"irTransmitter.send": [{
|
|
86991
|
+
name: "deviceId",
|
|
86992
|
+
form: "single",
|
|
86993
|
+
optional: false
|
|
86994
|
+
}],
|
|
86356
86995
|
"keychain.deleteDeviceScope": [{
|
|
86357
86996
|
name: "deviceId",
|
|
86358
86997
|
form: "single",
|
|
@@ -87578,6 +88217,31 @@ Object.freeze({
|
|
|
87578
88217
|
form: "single",
|
|
87579
88218
|
optional: true
|
|
87580
88219
|
}],
|
|
88220
|
+
"remote.getConfig": [{
|
|
88221
|
+
name: "deviceId",
|
|
88222
|
+
form: "single",
|
|
88223
|
+
optional: false
|
|
88224
|
+
}],
|
|
88225
|
+
"remote.listCommands": [{
|
|
88226
|
+
name: "deviceId",
|
|
88227
|
+
form: "single",
|
|
88228
|
+
optional: false
|
|
88229
|
+
}],
|
|
88230
|
+
"remote.sendCommand": [{
|
|
88231
|
+
name: "deviceId",
|
|
88232
|
+
form: "single",
|
|
88233
|
+
optional: false
|
|
88234
|
+
}],
|
|
88235
|
+
"remote.sendMediaCommand": [{
|
|
88236
|
+
name: "deviceId",
|
|
88237
|
+
form: "single",
|
|
88238
|
+
optional: false
|
|
88239
|
+
}],
|
|
88240
|
+
"remote.setConfig": [{
|
|
88241
|
+
name: "deviceId",
|
|
88242
|
+
form: "single",
|
|
88243
|
+
optional: false
|
|
88244
|
+
}],
|
|
87581
88245
|
"runningState.getStatus": [{
|
|
87582
88246
|
name: "deviceId",
|
|
87583
88247
|
form: "single",
|
|
@@ -91119,5 +91783,13 @@ function armRemovalReconcile(opts) {
|
|
|
91119
91783
|
timer.unref?.();
|
|
91120
91784
|
return () => clearInterval(timer);
|
|
91121
91785
|
}
|
|
91786
|
+
object({
|
|
91787
|
+
manufacturer: string().optional(),
|
|
91788
|
+
supportedModels: array(string()).optional(),
|
|
91789
|
+
supportedController: string().optional(),
|
|
91790
|
+
commandsEncoding: string(),
|
|
91791
|
+
delay: number().nonnegative().optional(),
|
|
91792
|
+
commands: record(string(), unknown())
|
|
91793
|
+
});
|
|
91122
91794
|
//#endregion
|
|
91123
91795
|
export { applyModelBoundSettings as $, defineCustomActions as $n, parseProcStatus as $t, NativeLeaseAdmissionSchema as A, stripRetiredBandPreBufferSec as An, evictionPolicyForMode as At, RECORDING_SOURCE_CAMSTACK as B, isSoftwareDecode as Bn, isFirstLevelMacroClass as Bt, EVENT_PAD_MS as C, runtimeDevices as Cn, record as Cr, dominantClipLabels as Ct, G711_SCALE_CORRECTION_DB as D, storageEvictableCapability as Dn, enumerateInferenceDevices as Dt, FailureCounters as E, stepModelRunsOnFormat as En, EventCategory as Er, egressTransportFromRequest as Et, PIPELINE_RAMP as F, DEFAULT_FIRST_SIGHTING_FRESHNESS_MS as Fn, fuseRecoveredDetections as Ft, RecordingSignalStatusSchema as G, BaseAddon as Gn, mapAudioLabelToMacro as Gt, RECOVERY_MOTION_MAX_AGE_MS as H, DeviceType as Hn, linkedStepOf as Ht, PoolMemoryWatchdog as I, Fmp4BoxSplitter as In, gbToBytes as It, VISIT_MERGE_GAP_MS as J, HF_REPO as Jn, memoizePinnedFfmpeg as Jt, RingBuffer as K, CAM_PROFILE_ORDER as Kn, mayReadLocation as Kt, RATE_CONTROL_RELAXED as L, buildFfmpegArgs as Ln, gifDeriveSpeed as Lt, NodeBenchRunnerInputSchema as M, videoclipsCapability as Mn, exportSubjectOf as Mt, OBJECT_DETECTION_STEP_ID as N, webrtcSessionCapability as Nn, failureContributionCapability as Nt, LABEL_SUPPLY_MACRO as O, storageOccupancyCapability as On, evaluateZoneRules as Ot, OpsLogEntrySchema as P, AUDIO_PRESETS as Pn, ffmpegRate as Pt, applyCropClassFloors as Q, customAction as Qn, overlayClusterStepSettings as Qt, RATE_CONTROL_TIGHT as R, evaluateSensorEdge as Rn, gifFromMp4Args as Rt, EVENT_OWNER_TYPES as S, rootSuppliesOf as Sn, preprocess as Sr, deviceRemovalHookCapability as St, ExportRecordSchema as T, startMoverUnderClearance as Tn, union$1 as Tr, egressTranscodeSharingKey as Tt, ROOT_SUPPLIABLE_STEP_IDS as U, errMsg as Un, loadContributionCapability as Ut, RECORDING_SOURCE_CAMSTACK_ADDON as V, DeviceFeature as Vn, linkedLabelStepId as Vt, RecordingConfigSchema as W, BOOT_RECOVERY_BACKOFF_MS as Wn, logChannelsCapability as Wt, addonWidgetsSourceCapability as X, audioChunkBytesPerSample as Xn, modeMayWrite as Xt, YAMNET_TO_MACRO as Y, MODEL_FORMATS as Yn, migrateLegacyDeviceSignalConfig as Yt, allowedSuppliedEffect as Z, createEvent as Zn, motionDetectionCapability as Zt, DEFAULT_DETAIL_CROP_CONVENTION as _, resolveLocationMode as _n, discriminatedUnion as _r, deriveBatteryPresence as _t, BackgroundRunRegistry as a, planMotionCrops as an, isSecretMarker as ar, buildBenchStepTree as at, DEVICE_BACKEND_TO_FORMAT as b, resolveRecordingProfiles as bn, number as br, deriveRootFaceRefineRect as bt, CLIP_STILL_REASON_CODE_HEADER as c, readRecoveryRecipeForSteps as cn, maskUrlCredentials as cr, clipExportFailure as ct, CLUSTER_MODEL_SCOPED_STEPS as d, recordingExportCapability as dn, selectAssignedProfileSlots as dr, containingParentIndex as dt, pickClusterStepSettings as en, defineRecordKinds as er, armRemovalReconcile as et, COCO_80_LABELS as f, recordingSignalCapability as fn, sleep as fr, countRecoverySkips as ft, DEFAULT_CLUSTER_STEP_SETTINGS as g, resolveEgressDecodeHwAccel as gn, boolean as gr, defaultDeviceFor as gt, DEFAULT_AUDIO_ANALYZER_CONFIG as h, resolveCreateExportSubject as hn, array as hr, declareLogChannel as ht, AUDIO_MACRO_LABELS as i, pipelineRunnerCapability as in, isEvent as ir, batteryCapability as it, NativeLeaseSettingsSchema as j, supportedRuntimes as jn, evictionPolicyOfLocation as jt, LABEL_SUPPLY_VOCABULARIES as k, streamBrokerCapability as kn, eventOverlapsClipWindow as kt, CLIP_STILL_REASON_HEADER as l, recordingArchiveCapability as ln, nodePin as lr, clipExportFailureOf as lt, CROP_SUPPLY_SOURCES as m, resolveClusterStepModelId as mn, _enum as mr, createLogChannelsProvider as mt, APPLE_SA_TO_MACRO as n, pickNativeLeaseOverride as nn, hfModelUrl as nr, audioAnalyzerCapability as nt, BatteryStatusSchema as o, planRecoveryCrops as on, makeProfileBrokerId as or, cameraOwnsMotionViaSensor as ot, COCO_TO_MACRO as p, remapCropDetections as pn, userError as pr, createHwAccelCache as pt, VIDEOCLIPS_MAX_OFFER_BYTES as q, CamProfileSchema as qn, mayWriteToLocation as qt, AUDIO_BACKEND_CHOICES as r, pipelineExecutorCapability as rn, hydrateSchema as rr, audioKindId as rt, CLIP_BROKER_PACED_RATES as s, rankStreams as sn, makeSourceBrokerId as sr, cameraStreamsCapability as st, APPEARANCE_BLOCKS as t, pickDetailCropConvention as tn, expandAudioChunkToF32le as tr, audioAnalysisCapability as tt, CLIP_STREAM_TRANSPORT_HEADER as u, recordingCapability as un, parseProfileBrokerId as ur, collectModelBoundKeys as ut, DEFAULT_EVENTS_BAND_BUFFER_SEC as v, resolveModelBoundSetting as vn, lazy as vr, deriveDetailCropRect as vt, EncodeProfileSchema as w, selectRecoveryStep as wn, string as wr, edgetpuDelegateDevice as wt, DEVICE_RAMP as x, resolveRootSupply as xn, object as xr, detectionPipelineCapability as xt, DEFAULT_NATIVE_LEASE_SETTINGS as y, resolvePoolMemoryPolicy as yn, literal as yr, deriveRecordingMode as yt, RECORDING_EXPORT_MAX_READ_BYTES as z, invocationFromEncodeProfile as zn, inferModelProvider as zt };
|