@kubohiroya/turbowarp-teachable-machine 3.5.1 → 3.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -3
- package/dist/backend-wasm.js +1 -1
- package/dist/backend-webgpu.js +1 -1
- package/dist/composition.js +657 -6
- package/dist/posenet.js +15 -6
- package/dist/runtime.js +3 -3
- package/dist/tm.js +2723 -2035
- package/dist/types/extension.d.ts +1 -0
- package/dist/types/fixed-input-editors.d.ts +7 -0
- package/dist/types/fixed-input-schema.d.ts +142 -0
- package/docs/fixed-input-editors.ja.md +36 -0
- package/package.json +15 -6
- package/schemas/block-editor-fixed-inputs.schema.json +193 -0
package/dist/composition.js
CHANGED
|
@@ -47,6 +47,644 @@ function requireComputeMode(value) {
|
|
|
47
47
|
if (!mode) throw new TypeError(`TM: Unknown compute mode: ${String(value)}`);
|
|
48
48
|
return mode;
|
|
49
49
|
}
|
|
50
|
+
//#endregion
|
|
51
|
+
//#region node_modules/.pnpm/@kubohiroya+turbowarp-extension-data-editor@0.2.1_react@18.3.1/node_modules/@kubohiroya/turbowarp-extension-data-editor/dist/fixed-input-schema.js
|
|
52
|
+
var numberToken = /^-?(?:0|[1-9][0-9]*)(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?$/u;
|
|
53
|
+
var invalidNumber = Object.freeze({
|
|
54
|
+
kind: "invalid",
|
|
55
|
+
code: "fixed-number-input-invalid"
|
|
56
|
+
});
|
|
57
|
+
/**
|
|
58
|
+
* Parse a NEW numeric draft according to NP-finite-new-input-v1.
|
|
59
|
+
* Never apply this to opening/no-op raw values or use it as an owner validator.
|
|
60
|
+
* Keep the validated token so negative zero, precision and exponent spelling survive.
|
|
61
|
+
*/
|
|
62
|
+
function parseFixedNumberInput(input) {
|
|
63
|
+
if (typeof input === "number") {
|
|
64
|
+
if (!Number.isFinite(input)) return invalidNumber;
|
|
65
|
+
return Object.freeze({
|
|
66
|
+
kind: "valid",
|
|
67
|
+
token: Object.is(input, -0) ? "-0" : String(input),
|
|
68
|
+
value: input
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
if (typeof input !== "string") return invalidNumber;
|
|
72
|
+
const token = input.trim();
|
|
73
|
+
if (!numberToken.test(token)) return invalidNumber;
|
|
74
|
+
const value = Number(token);
|
|
75
|
+
return Number.isFinite(value) ? Object.freeze({
|
|
76
|
+
kind: "valid",
|
|
77
|
+
token,
|
|
78
|
+
value
|
|
79
|
+
}) : invalidNumber;
|
|
80
|
+
}
|
|
81
|
+
var block_editor_fixed_inputs_schema_default = {
|
|
82
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
83
|
+
$id: "https://kubohiroya.github.io/turbowarp-teachable-machine/schemas/block-editor-fixed-inputs.schema.json",
|
|
84
|
+
title: "turbowarp-teachable-machine fixed input registration schema",
|
|
85
|
+
$defs: {
|
|
86
|
+
"setRecognitionMode": {
|
|
87
|
+
"type": "object",
|
|
88
|
+
"properties": { "MODE": {
|
|
89
|
+
"type": "string",
|
|
90
|
+
"enum": [
|
|
91
|
+
"pose",
|
|
92
|
+
"image",
|
|
93
|
+
"audio"
|
|
94
|
+
]
|
|
95
|
+
} }
|
|
96
|
+
},
|
|
97
|
+
"setComputeMode": {
|
|
98
|
+
"type": "object",
|
|
99
|
+
"properties": { "MODE": {
|
|
100
|
+
"type": "string",
|
|
101
|
+
"enum": [
|
|
102
|
+
"auto",
|
|
103
|
+
"webgpu",
|
|
104
|
+
"webgl",
|
|
105
|
+
"wasm",
|
|
106
|
+
"cpu"
|
|
107
|
+
]
|
|
108
|
+
} }
|
|
109
|
+
},
|
|
110
|
+
"setPreviewOpacity": {
|
|
111
|
+
"type": "object",
|
|
112
|
+
"properties": { "OPACITY": {
|
|
113
|
+
"type": "number",
|
|
114
|
+
"$comment": "New finite numeric input uses NP-finite-new-input-v1. Existing raw is preserved on no-op; runtime clamp/floor is not applied to stored raw."
|
|
115
|
+
} }
|
|
116
|
+
},
|
|
117
|
+
"setPreviewPosition": {
|
|
118
|
+
"type": "object",
|
|
119
|
+
"properties": { "POSITION": {
|
|
120
|
+
"type": "string",
|
|
121
|
+
"enum": [
|
|
122
|
+
"top-left",
|
|
123
|
+
"top-right",
|
|
124
|
+
"bottom-left",
|
|
125
|
+
"bottom-right",
|
|
126
|
+
"center",
|
|
127
|
+
"full-stage"
|
|
128
|
+
]
|
|
129
|
+
} }
|
|
130
|
+
},
|
|
131
|
+
"setPreviewMirroring": {
|
|
132
|
+
"type": "object",
|
|
133
|
+
"properties": { "MIRRORING": {
|
|
134
|
+
"type": "string",
|
|
135
|
+
"enum": ["mirrored", "unmirrored"]
|
|
136
|
+
} }
|
|
137
|
+
},
|
|
138
|
+
"setPoseOverlayVisibility": {
|
|
139
|
+
"type": "object",
|
|
140
|
+
"properties": { "VISIBILITY": {
|
|
141
|
+
"type": "string",
|
|
142
|
+
"enum": ["on", "off"]
|
|
143
|
+
} }
|
|
144
|
+
},
|
|
145
|
+
"setPoseJointStyle": {
|
|
146
|
+
"type": "object",
|
|
147
|
+
"properties": {
|
|
148
|
+
"PART": {
|
|
149
|
+
"type": "string",
|
|
150
|
+
"enum": [
|
|
151
|
+
"nose",
|
|
152
|
+
"leftEye",
|
|
153
|
+
"rightEye",
|
|
154
|
+
"leftEar",
|
|
155
|
+
"rightEar",
|
|
156
|
+
"leftShoulder",
|
|
157
|
+
"rightShoulder",
|
|
158
|
+
"leftElbow",
|
|
159
|
+
"rightElbow",
|
|
160
|
+
"leftWrist",
|
|
161
|
+
"rightWrist",
|
|
162
|
+
"leftHip",
|
|
163
|
+
"rightHip",
|
|
164
|
+
"leftKnee",
|
|
165
|
+
"rightKnee",
|
|
166
|
+
"leftAnkle",
|
|
167
|
+
"rightAnkle"
|
|
168
|
+
]
|
|
169
|
+
},
|
|
170
|
+
"OPACITY": {
|
|
171
|
+
"type": "number",
|
|
172
|
+
"$comment": "New finite numeric input uses NP-finite-new-input-v1. Existing raw is preserved on no-op; runtime clamp/floor is not applied to stored raw."
|
|
173
|
+
},
|
|
174
|
+
"RADIUS": {
|
|
175
|
+
"type": "number",
|
|
176
|
+
"$comment": "New finite numeric input uses NP-finite-new-input-v1. Existing raw is preserved on no-op; runtime clamp/floor is not applied to stored raw."
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
"setPoseBoneStyle": {
|
|
181
|
+
"type": "object",
|
|
182
|
+
"properties": {
|
|
183
|
+
"OPACITY": {
|
|
184
|
+
"type": "number",
|
|
185
|
+
"$comment": "New finite numeric input uses NP-finite-new-input-v1. Existing raw is preserved on no-op; runtime clamp/floor is not applied to stored raw."
|
|
186
|
+
},
|
|
187
|
+
"WIDTH": {
|
|
188
|
+
"type": "number",
|
|
189
|
+
"$comment": "New finite numeric input uses NP-finite-new-input-v1. Existing raw is preserved on no-op; runtime clamp/floor is not applied to stored raw."
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
},
|
|
193
|
+
"setPoseOverlayMinimumConfidence": {
|
|
194
|
+
"type": "object",
|
|
195
|
+
"properties": { "CONFIDENCE": {
|
|
196
|
+
"type": "number",
|
|
197
|
+
"$comment": "New finite numeric input uses NP-finite-new-input-v1. Existing raw is preserved on no-op; runtime clamp/floor is not applied to stored raw."
|
|
198
|
+
} }
|
|
199
|
+
},
|
|
200
|
+
"setPoseConfidenceScaling": {
|
|
201
|
+
"type": "object",
|
|
202
|
+
"properties": {
|
|
203
|
+
"PROPERTY": {
|
|
204
|
+
"type": "string",
|
|
205
|
+
"enum": [
|
|
206
|
+
"joint-opacity",
|
|
207
|
+
"joint-radius",
|
|
208
|
+
"bone-opacity",
|
|
209
|
+
"bone-width"
|
|
210
|
+
]
|
|
211
|
+
},
|
|
212
|
+
"STATE": {
|
|
213
|
+
"type": "string",
|
|
214
|
+
"enum": ["on", "off"]
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
},
|
|
218
|
+
"setAccumulatedPoseParameters": {
|
|
219
|
+
"type": "object",
|
|
220
|
+
"properties": {
|
|
221
|
+
"ACCUMULATION": {
|
|
222
|
+
"type": "number",
|
|
223
|
+
"$comment": "New finite numeric input uses NP-finite-new-input-v1. Existing raw is preserved on no-op; runtime clamp/floor is not applied to stored raw."
|
|
224
|
+
},
|
|
225
|
+
"DECAY": {
|
|
226
|
+
"type": "number",
|
|
227
|
+
"$comment": "New finite numeric input uses NP-finite-new-input-v1. Existing raw is preserved on no-op; runtime clamp/floor is not applied to stored raw."
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
},
|
|
231
|
+
"setAccumulatedPoseThreshold": {
|
|
232
|
+
"type": "object",
|
|
233
|
+
"properties": { "THRESHOLD": {
|
|
234
|
+
"type": "number",
|
|
235
|
+
"$comment": "New finite numeric input uses NP-finite-new-input-v1. Existing raw is preserved on no-op; runtime clamp/floor is not applied to stored raw."
|
|
236
|
+
} }
|
|
237
|
+
},
|
|
238
|
+
"isPoseWithThreshold": {
|
|
239
|
+
"type": "object",
|
|
240
|
+
"properties": { "THRESHOLD": {
|
|
241
|
+
"type": "number",
|
|
242
|
+
"$comment": "New finite numeric input uses NP-finite-new-input-v1. Existing raw is preserved on no-op; runtime clamp/floor is not applied to stored raw."
|
|
243
|
+
} }
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
//#endregion
|
|
248
|
+
//#region src/fixed-input-schema.ts
|
|
249
|
+
/** Owner canonical fragments, distinct from older SOURCE/editor schemas. */
|
|
250
|
+
function fixedInputBundle(opcode, argument) {
|
|
251
|
+
const source = {
|
|
252
|
+
repository: "turbowarp-teachable-machine",
|
|
253
|
+
path: "schemas/block-editor-fixed-inputs.schema.json",
|
|
254
|
+
symbol: `#/$defs/${opcode}/properties/${argument}`
|
|
255
|
+
};
|
|
256
|
+
const fragment = block_editor_fixed_inputs_schema_default.$defs[opcode].properties[argument];
|
|
257
|
+
return {
|
|
258
|
+
identity: {
|
|
259
|
+
ownerId: "turbowarp-teachable-machine",
|
|
260
|
+
contractId: "fixed-inputs",
|
|
261
|
+
revision: "1",
|
|
262
|
+
variantId: `${opcode}.${argument}`
|
|
263
|
+
},
|
|
264
|
+
dialect: "2020-12",
|
|
265
|
+
root: {
|
|
266
|
+
retrievalUri: block_editor_fixed_inputs_schema_default.$id,
|
|
267
|
+
document: fragment,
|
|
268
|
+
artifact: {
|
|
269
|
+
role: "canonical-schema",
|
|
270
|
+
source
|
|
271
|
+
}
|
|
272
|
+
},
|
|
273
|
+
resources: [],
|
|
274
|
+
provenance: {
|
|
275
|
+
canonicalSources: [source, {
|
|
276
|
+
repository: "turbowarp-teachable-machine",
|
|
277
|
+
path: "src/extension.ts",
|
|
278
|
+
symbol: opcode
|
|
279
|
+
}],
|
|
280
|
+
generatedFiles: [],
|
|
281
|
+
referenceSchemas: [],
|
|
282
|
+
generationSources: []
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
block_editor_fixed_inputs_schema_default.$defs;
|
|
287
|
+
//#endregion
|
|
288
|
+
//#region src/fixed-input-editors.ts
|
|
289
|
+
var existingNumber = (value) => {
|
|
290
|
+
if (typeof value !== "number" && typeof value !== "string" || typeof value === "string" && value.trim() === "") throw new TypeError("Expected a numeric literal.");
|
|
291
|
+
const number = Number(value);
|
|
292
|
+
if (!Number.isFinite(number)) throw new TypeError("Expected a finite number.");
|
|
293
|
+
return number;
|
|
294
|
+
};
|
|
295
|
+
var newNumber = (value) => {
|
|
296
|
+
const parsed = parseFixedNumberInput(value);
|
|
297
|
+
if (parsed.kind !== "valid") throw new TypeError("Invalid new numeric input.");
|
|
298
|
+
return parsed.token;
|
|
299
|
+
};
|
|
300
|
+
var aliases = {
|
|
301
|
+
"setRecognitionMode.MODE": {
|
|
302
|
+
"pose": "pose",
|
|
303
|
+
"poses": "pose",
|
|
304
|
+
"body": "pose",
|
|
305
|
+
"image": "image",
|
|
306
|
+
"images": "image",
|
|
307
|
+
"object": "image",
|
|
308
|
+
"card": "image",
|
|
309
|
+
"marker": "image",
|
|
310
|
+
"audio": "audio",
|
|
311
|
+
"sound": "audio",
|
|
312
|
+
"voice": "audio",
|
|
313
|
+
"microphone": "audio",
|
|
314
|
+
"mic": "audio",
|
|
315
|
+
"ポーズ": "pose",
|
|
316
|
+
"姿勢": "pose",
|
|
317
|
+
"画像": "image",
|
|
318
|
+
"物体": "image",
|
|
319
|
+
"カード": "image",
|
|
320
|
+
"記号": "image",
|
|
321
|
+
"音声": "audio",
|
|
322
|
+
"音": "audio",
|
|
323
|
+
"声": "audio",
|
|
324
|
+
"マイク": "audio"
|
|
325
|
+
},
|
|
326
|
+
"setPreviewPosition.POSITION": {
|
|
327
|
+
"左上": "top-left",
|
|
328
|
+
"右上": "top-right",
|
|
329
|
+
"左下": "bottom-left",
|
|
330
|
+
"右下": "bottom-right",
|
|
331
|
+
"中央": "center",
|
|
332
|
+
"ステージ全体": "full-stage",
|
|
333
|
+
"top-left": "top-left",
|
|
334
|
+
"top-right": "top-right",
|
|
335
|
+
"bottom-left": "bottom-left",
|
|
336
|
+
"bottom-right": "bottom-right",
|
|
337
|
+
"center": "center",
|
|
338
|
+
"full-stage": "full-stage"
|
|
339
|
+
},
|
|
340
|
+
"setPreviewMirroring.MIRRORING": {
|
|
341
|
+
"mirrored": "mirrored",
|
|
342
|
+
"unmirrored": "unmirrored",
|
|
343
|
+
"mirror": "mirrored",
|
|
344
|
+
"normal": "unmirrored",
|
|
345
|
+
"左右反転": "mirrored",
|
|
346
|
+
"そのまま": "unmirrored"
|
|
347
|
+
},
|
|
348
|
+
"setPoseOverlayVisibility.VISIBILITY": {
|
|
349
|
+
"on": "on",
|
|
350
|
+
"off": "off",
|
|
351
|
+
"show": "on",
|
|
352
|
+
"hide": "off",
|
|
353
|
+
"true": "on",
|
|
354
|
+
"false": "off",
|
|
355
|
+
"表示": "on",
|
|
356
|
+
"非表示": "off"
|
|
357
|
+
},
|
|
358
|
+
"setPoseConfidenceScaling.STATE": {
|
|
359
|
+
"on": "on",
|
|
360
|
+
"off": "off",
|
|
361
|
+
"show": "on",
|
|
362
|
+
"hide": "off",
|
|
363
|
+
"true": "on",
|
|
364
|
+
"false": "off",
|
|
365
|
+
"表示": "on",
|
|
366
|
+
"非表示": "off"
|
|
367
|
+
},
|
|
368
|
+
"setComputeMode.MODE": {
|
|
369
|
+
"auto": "auto",
|
|
370
|
+
"automatic": "auto",
|
|
371
|
+
"default": "auto",
|
|
372
|
+
"fastest": "auto",
|
|
373
|
+
"自動": "auto",
|
|
374
|
+
"おまかせ": "auto",
|
|
375
|
+
"webgpu": "webgpu",
|
|
376
|
+
"gpu": "webgpu",
|
|
377
|
+
"webgl": "webgl",
|
|
378
|
+
"wasm": "wasm",
|
|
379
|
+
"webassembly": "wasm",
|
|
380
|
+
"simd": "wasm",
|
|
381
|
+
"cpu": "cpu",
|
|
382
|
+
"javascript": "cpu"
|
|
383
|
+
}
|
|
384
|
+
};
|
|
385
|
+
function binding(opcode, argument, values) {
|
|
386
|
+
return {
|
|
387
|
+
argument,
|
|
388
|
+
schemaBundle: fixedInputBundle(opcode, argument),
|
|
389
|
+
control: values ? {
|
|
390
|
+
kind: "enum",
|
|
391
|
+
choices: values.map((value) => ({ value }))
|
|
392
|
+
} : { kind: "number" },
|
|
393
|
+
read(value) {
|
|
394
|
+
if (!values) return existingNumber(value);
|
|
395
|
+
if (typeof value !== "string") throw new TypeError("Expected a string.");
|
|
396
|
+
return projectEnum(opcode, argument, value);
|
|
397
|
+
},
|
|
398
|
+
encode(value) {
|
|
399
|
+
if (!values) return newNumber(value);
|
|
400
|
+
if (typeof value !== "string" || !values.includes(value)) throw new TypeError("Invalid selection.");
|
|
401
|
+
return value;
|
|
402
|
+
},
|
|
403
|
+
validateCandidate(value) {
|
|
404
|
+
try {
|
|
405
|
+
if (!values) existingNumber(value);
|
|
406
|
+
else if (typeof value !== "string" || !values.includes(value)) throw new TypeError("Invalid selection.");
|
|
407
|
+
return [];
|
|
408
|
+
} catch {
|
|
409
|
+
return [{ message: "Invalid fixed input." }];
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
function projectEnum(opcode, argument, value) {
|
|
415
|
+
const key = `${opcode}.${argument}`;
|
|
416
|
+
const token = argument === "POSITION" ? value : value.trim().toLowerCase();
|
|
417
|
+
return aliases[key]?.[token] ?? value;
|
|
418
|
+
}
|
|
419
|
+
var fixedInputEditors = [
|
|
420
|
+
{
|
|
421
|
+
apiVersion: 1,
|
|
422
|
+
extensionId: "kubohiroyatm",
|
|
423
|
+
editorId: "fixed-setRecognitionMode",
|
|
424
|
+
opcodes: ["kubohiroyatm_setRecognitionMode"],
|
|
425
|
+
contractId: "turbowarp-teachable-machine/setRecognitionMode",
|
|
426
|
+
contractRevision: "1",
|
|
427
|
+
validationContext: () => ({
|
|
428
|
+
consumerId: "turbowarp-teachable-machine",
|
|
429
|
+
nowMs: 0,
|
|
430
|
+
settings: null
|
|
431
|
+
}),
|
|
432
|
+
bindings: [binding("setRecognitionMode", "MODE", [
|
|
433
|
+
"pose",
|
|
434
|
+
"image",
|
|
435
|
+
"audio"
|
|
436
|
+
])]
|
|
437
|
+
},
|
|
438
|
+
{
|
|
439
|
+
apiVersion: 1,
|
|
440
|
+
extensionId: "kubohiroyatm",
|
|
441
|
+
editorId: "fixed-setComputeMode",
|
|
442
|
+
opcodes: ["kubohiroyatm_setComputeMode"],
|
|
443
|
+
contractId: "turbowarp-teachable-machine/setComputeMode",
|
|
444
|
+
contractRevision: "1",
|
|
445
|
+
validationContext: () => ({
|
|
446
|
+
consumerId: "turbowarp-teachable-machine",
|
|
447
|
+
nowMs: 0,
|
|
448
|
+
settings: null
|
|
449
|
+
}),
|
|
450
|
+
bindings: [binding("setComputeMode", "MODE", [
|
|
451
|
+
"auto",
|
|
452
|
+
"webgpu",
|
|
453
|
+
"webgl",
|
|
454
|
+
"wasm",
|
|
455
|
+
"cpu"
|
|
456
|
+
])]
|
|
457
|
+
},
|
|
458
|
+
{
|
|
459
|
+
apiVersion: 1,
|
|
460
|
+
extensionId: "kubohiroyatm",
|
|
461
|
+
editorId: "fixed-setPreviewOpacity",
|
|
462
|
+
opcodes: ["kubohiroyatm_setPreviewOpacity"],
|
|
463
|
+
contractId: "turbowarp-teachable-machine/setPreviewOpacity",
|
|
464
|
+
contractRevision: "1",
|
|
465
|
+
validationContext: () => ({
|
|
466
|
+
consumerId: "turbowarp-teachable-machine",
|
|
467
|
+
nowMs: 0,
|
|
468
|
+
settings: null
|
|
469
|
+
}),
|
|
470
|
+
bindings: [binding("setPreviewOpacity", "OPACITY")]
|
|
471
|
+
},
|
|
472
|
+
{
|
|
473
|
+
apiVersion: 1,
|
|
474
|
+
extensionId: "kubohiroyatm",
|
|
475
|
+
editorId: "fixed-setPreviewPosition",
|
|
476
|
+
opcodes: ["kubohiroyatm_setPreviewPosition"],
|
|
477
|
+
contractId: "turbowarp-teachable-machine/setPreviewPosition",
|
|
478
|
+
contractRevision: "1",
|
|
479
|
+
validationContext: () => ({
|
|
480
|
+
consumerId: "turbowarp-teachable-machine",
|
|
481
|
+
nowMs: 0,
|
|
482
|
+
settings: null
|
|
483
|
+
}),
|
|
484
|
+
bindings: [binding("setPreviewPosition", "POSITION", [
|
|
485
|
+
"top-left",
|
|
486
|
+
"top-right",
|
|
487
|
+
"bottom-left",
|
|
488
|
+
"bottom-right",
|
|
489
|
+
"center",
|
|
490
|
+
"full-stage"
|
|
491
|
+
])]
|
|
492
|
+
},
|
|
493
|
+
{
|
|
494
|
+
apiVersion: 1,
|
|
495
|
+
extensionId: "kubohiroyatm",
|
|
496
|
+
editorId: "fixed-setPreviewMirroring",
|
|
497
|
+
opcodes: ["kubohiroyatm_setPreviewMirroring"],
|
|
498
|
+
contractId: "turbowarp-teachable-machine/setPreviewMirroring",
|
|
499
|
+
contractRevision: "1",
|
|
500
|
+
validationContext: () => ({
|
|
501
|
+
consumerId: "turbowarp-teachable-machine",
|
|
502
|
+
nowMs: 0,
|
|
503
|
+
settings: null
|
|
504
|
+
}),
|
|
505
|
+
bindings: [binding("setPreviewMirroring", "MIRRORING", ["mirrored", "unmirrored"])]
|
|
506
|
+
},
|
|
507
|
+
{
|
|
508
|
+
apiVersion: 1,
|
|
509
|
+
extensionId: "kubohiroyatm",
|
|
510
|
+
editorId: "fixed-setPoseOverlayVisibility",
|
|
511
|
+
opcodes: ["kubohiroyatm_setPoseOverlayVisibility"],
|
|
512
|
+
contractId: "turbowarp-teachable-machine/setPoseOverlayVisibility",
|
|
513
|
+
contractRevision: "1",
|
|
514
|
+
validationContext: () => ({
|
|
515
|
+
consumerId: "turbowarp-teachable-machine",
|
|
516
|
+
nowMs: 0,
|
|
517
|
+
settings: null
|
|
518
|
+
}),
|
|
519
|
+
bindings: [binding("setPoseOverlayVisibility", "VISIBILITY", ["on", "off"])]
|
|
520
|
+
},
|
|
521
|
+
{
|
|
522
|
+
apiVersion: 1,
|
|
523
|
+
extensionId: "kubohiroyatm",
|
|
524
|
+
editorId: "fixed-setPoseJointStyle",
|
|
525
|
+
opcodes: ["kubohiroyatm_setPoseJointStyle"],
|
|
526
|
+
contractId: "turbowarp-teachable-machine/setPoseJointStyle",
|
|
527
|
+
contractRevision: "1",
|
|
528
|
+
validationContext: () => ({
|
|
529
|
+
consumerId: "turbowarp-teachable-machine",
|
|
530
|
+
nowMs: 0,
|
|
531
|
+
settings: null
|
|
532
|
+
}),
|
|
533
|
+
bindings: [
|
|
534
|
+
binding("setPoseJointStyle", "PART", [
|
|
535
|
+
"nose",
|
|
536
|
+
"leftEye",
|
|
537
|
+
"rightEye",
|
|
538
|
+
"leftEar",
|
|
539
|
+
"rightEar",
|
|
540
|
+
"leftShoulder",
|
|
541
|
+
"rightShoulder",
|
|
542
|
+
"leftElbow",
|
|
543
|
+
"rightElbow",
|
|
544
|
+
"leftWrist",
|
|
545
|
+
"rightWrist",
|
|
546
|
+
"leftHip",
|
|
547
|
+
"rightHip",
|
|
548
|
+
"leftKnee",
|
|
549
|
+
"rightKnee",
|
|
550
|
+
"leftAnkle",
|
|
551
|
+
"rightAnkle"
|
|
552
|
+
]),
|
|
553
|
+
binding("setPoseJointStyle", "OPACITY"),
|
|
554
|
+
binding("setPoseJointStyle", "RADIUS")
|
|
555
|
+
]
|
|
556
|
+
},
|
|
557
|
+
{
|
|
558
|
+
apiVersion: 1,
|
|
559
|
+
extensionId: "kubohiroyatm",
|
|
560
|
+
editorId: "fixed-setPoseBoneStyle",
|
|
561
|
+
opcodes: ["kubohiroyatm_setPoseBoneStyle"],
|
|
562
|
+
contractId: "turbowarp-teachable-machine/setPoseBoneStyle",
|
|
563
|
+
contractRevision: "1",
|
|
564
|
+
validationContext: () => ({
|
|
565
|
+
consumerId: "turbowarp-teachable-machine",
|
|
566
|
+
nowMs: 0,
|
|
567
|
+
settings: null
|
|
568
|
+
}),
|
|
569
|
+
bindings: [binding("setPoseBoneStyle", "OPACITY"), binding("setPoseBoneStyle", "WIDTH")]
|
|
570
|
+
},
|
|
571
|
+
{
|
|
572
|
+
apiVersion: 1,
|
|
573
|
+
extensionId: "kubohiroyatm",
|
|
574
|
+
editorId: "fixed-setPoseOverlayMinimumConfidence",
|
|
575
|
+
opcodes: ["kubohiroyatm_setPoseOverlayMinimumConfidence"],
|
|
576
|
+
contractId: "turbowarp-teachable-machine/setPoseOverlayMinimumConfidence",
|
|
577
|
+
contractRevision: "1",
|
|
578
|
+
validationContext: () => ({
|
|
579
|
+
consumerId: "turbowarp-teachable-machine",
|
|
580
|
+
nowMs: 0,
|
|
581
|
+
settings: null
|
|
582
|
+
}),
|
|
583
|
+
bindings: [binding("setPoseOverlayMinimumConfidence", "CONFIDENCE")]
|
|
584
|
+
},
|
|
585
|
+
{
|
|
586
|
+
apiVersion: 1,
|
|
587
|
+
extensionId: "kubohiroyatm",
|
|
588
|
+
editorId: "fixed-setPoseConfidenceScaling",
|
|
589
|
+
opcodes: ["kubohiroyatm_setPoseConfidenceScaling"],
|
|
590
|
+
contractId: "turbowarp-teachable-machine/setPoseConfidenceScaling",
|
|
591
|
+
contractRevision: "1",
|
|
592
|
+
validationContext: () => ({
|
|
593
|
+
consumerId: "turbowarp-teachable-machine",
|
|
594
|
+
nowMs: 0,
|
|
595
|
+
settings: null
|
|
596
|
+
}),
|
|
597
|
+
bindings: [binding("setPoseConfidenceScaling", "PROPERTY", [
|
|
598
|
+
"joint-opacity",
|
|
599
|
+
"joint-radius",
|
|
600
|
+
"bone-opacity",
|
|
601
|
+
"bone-width"
|
|
602
|
+
]), binding("setPoseConfidenceScaling", "STATE", ["on", "off"])]
|
|
603
|
+
},
|
|
604
|
+
{
|
|
605
|
+
apiVersion: 1,
|
|
606
|
+
extensionId: "kubohiroyatm",
|
|
607
|
+
editorId: "fixed-setAccumulatedPoseParameters",
|
|
608
|
+
opcodes: ["kubohiroyatm_setAccumulatedPoseParameters"],
|
|
609
|
+
contractId: "turbowarp-teachable-machine/setAccumulatedPoseParameters",
|
|
610
|
+
contractRevision: "1",
|
|
611
|
+
validationContext: () => ({
|
|
612
|
+
consumerId: "turbowarp-teachable-machine",
|
|
613
|
+
nowMs: 0,
|
|
614
|
+
settings: null
|
|
615
|
+
}),
|
|
616
|
+
bindings: [binding("setAccumulatedPoseParameters", "ACCUMULATION"), binding("setAccumulatedPoseParameters", "DECAY")]
|
|
617
|
+
},
|
|
618
|
+
{
|
|
619
|
+
apiVersion: 1,
|
|
620
|
+
extensionId: "kubohiroyatm",
|
|
621
|
+
editorId: "fixed-setAccumulatedPoseThreshold",
|
|
622
|
+
opcodes: ["kubohiroyatm_setAccumulatedPoseThreshold"],
|
|
623
|
+
contractId: "turbowarp-teachable-machine/setAccumulatedPoseThreshold",
|
|
624
|
+
contractRevision: "1",
|
|
625
|
+
validationContext: () => ({
|
|
626
|
+
consumerId: "turbowarp-teachable-machine",
|
|
627
|
+
nowMs: 0,
|
|
628
|
+
settings: null
|
|
629
|
+
}),
|
|
630
|
+
bindings: [binding("setAccumulatedPoseThreshold", "THRESHOLD")]
|
|
631
|
+
},
|
|
632
|
+
{
|
|
633
|
+
apiVersion: 1,
|
|
634
|
+
extensionId: "kubohiroyatm",
|
|
635
|
+
editorId: "fixed-isPoseWithThreshold",
|
|
636
|
+
opcodes: ["kubohiroyatm_isPoseWithThreshold"],
|
|
637
|
+
contractId: "turbowarp-teachable-machine/isPoseWithThreshold",
|
|
638
|
+
contractRevision: "1",
|
|
639
|
+
validationContext: () => ({
|
|
640
|
+
consumerId: "turbowarp-teachable-machine",
|
|
641
|
+
nowMs: 0,
|
|
642
|
+
settings: null
|
|
643
|
+
}),
|
|
644
|
+
bindings: [binding("isPoseWithThreshold", "THRESHOLD")]
|
|
645
|
+
}
|
|
646
|
+
];
|
|
647
|
+
/** Register only currently declared opcodes; release obsolete feature-flag scopes. */
|
|
648
|
+
function fixedInputRegistration(scratch) {
|
|
649
|
+
const host = typeof scratch === "object" && scratch !== null ? scratch : {};
|
|
650
|
+
let active;
|
|
651
|
+
let activeOpcodes = "";
|
|
652
|
+
const removers = [];
|
|
653
|
+
let disposed = false;
|
|
654
|
+
const dispose = () => {
|
|
655
|
+
host.vm?.runtime?.off?.("RUNTIME_DISPOSED", shutdown);
|
|
656
|
+
for (const remove of removers.splice(0).reverse()) remove();
|
|
657
|
+
active = void 0;
|
|
658
|
+
activeOpcodes = "";
|
|
659
|
+
};
|
|
660
|
+
const shutdown = () => {
|
|
661
|
+
disposed = true;
|
|
662
|
+
dispose();
|
|
663
|
+
};
|
|
664
|
+
return {
|
|
665
|
+
ensure(opcodes) {
|
|
666
|
+
const api = host.gui?.blockEditors;
|
|
667
|
+
const signature = [...new Set(opcodes)].sort().join("\0");
|
|
668
|
+
if (disposed || api === active && signature === activeOpcodes) return;
|
|
669
|
+
dispose();
|
|
670
|
+
if (api?.apiVersion !== 1 || typeof api.registerFixedInputEditor !== "function") return;
|
|
671
|
+
try {
|
|
672
|
+
for (const definition of fixedInputEditors) if (definition.opcodes.every((opcode) => opcodes.includes(opcode))) {
|
|
673
|
+
const remove = api.registerFixedInputEditor.call(api, definition);
|
|
674
|
+
if (typeof remove !== "function") throw new TypeError("Invalid fixed registration cleanup.");
|
|
675
|
+
removers.push(remove);
|
|
676
|
+
}
|
|
677
|
+
active = api;
|
|
678
|
+
activeOpcodes = signature;
|
|
679
|
+
host.vm?.runtime?.on?.("RUNTIME_DISPOSED", shutdown);
|
|
680
|
+
} catch (error) {
|
|
681
|
+
dispose();
|
|
682
|
+
throw error;
|
|
683
|
+
}
|
|
684
|
+
},
|
|
685
|
+
dispose: shutdown
|
|
686
|
+
};
|
|
687
|
+
}
|
|
50
688
|
var block_definitions_default = {
|
|
51
689
|
extensionName: "Teachable Machine",
|
|
52
690
|
blocks: [
|
|
@@ -549,7 +1187,7 @@ function confidenceMultiplier(value) {
|
|
|
549
1187
|
}
|
|
550
1188
|
var package_default = {
|
|
551
1189
|
name: "@kubohiroya/turbowarp-teachable-machine",
|
|
552
|
-
version: "3.5.
|
|
1190
|
+
version: "3.5.2",
|
|
553
1191
|
description: "A TurboWarp extension for recognition using Teachable Machine pose, image, and audio models.",
|
|
554
1192
|
author: "Hiroya Kubo <hiroya@cuc.ac.jp>",
|
|
555
1193
|
license: "MPL-2.0",
|
|
@@ -581,7 +1219,9 @@ var package_default = {
|
|
|
581
1219
|
"dist/",
|
|
582
1220
|
"README.md",
|
|
583
1221
|
"LICENSE",
|
|
584
|
-
"THIRD_PARTY_NOTICES.md"
|
|
1222
|
+
"THIRD_PARTY_NOTICES.md",
|
|
1223
|
+
"schemas/",
|
|
1224
|
+
"docs/fixed-input-editors.ja.md"
|
|
585
1225
|
],
|
|
586
1226
|
unpkg: "./dist/tm.js",
|
|
587
1227
|
jsdelivr: "./dist/tm.js",
|
|
@@ -617,8 +1257,8 @@ var package_default = {
|
|
|
617
1257
|
"prepack": "npm run build && npm run release:consistency:check"
|
|
618
1258
|
},
|
|
619
1259
|
devDependencies: {
|
|
620
|
-
"@kubohiroya/turbowarp-camera-source": "0.
|
|
621
|
-
"@kubohiroya/vite-plugin-turbowarp-extension": "0.
|
|
1260
|
+
"@kubohiroya/turbowarp-camera-source": "0.17.1",
|
|
1261
|
+
"@kubohiroya/vite-plugin-turbowarp-extension": "0.6.1",
|
|
622
1262
|
"@teachablemachine/image": "0.8.5",
|
|
623
1263
|
"@teachablemachine/pose": "0.8.6",
|
|
624
1264
|
"@tensorflow-models/posenet": "2.2.2",
|
|
@@ -629,7 +1269,8 @@ var package_default = {
|
|
|
629
1269
|
"@types/node": "^22.20.1",
|
|
630
1270
|
"typescript": "^5.9.3",
|
|
631
1271
|
"vite": "^8.2.2",
|
|
632
|
-
"vitest": "^4.0.14"
|
|
1272
|
+
"vitest": "^4.0.14",
|
|
1273
|
+
"@kubohiroya/turbowarp-extension-data-editor": "0.2.1"
|
|
633
1274
|
},
|
|
634
1275
|
keywords: [
|
|
635
1276
|
"turbowarp",
|
|
@@ -640,7 +1281,13 @@ var package_default = {
|
|
|
640
1281
|
"audio",
|
|
641
1282
|
"camera",
|
|
642
1283
|
"teachable-machine"
|
|
643
|
-
]
|
|
1284
|
+
],
|
|
1285
|
+
gitHead: "97ef12018789316d6170a7aab29d7c5b0a4c90f4",
|
|
1286
|
+
"x-turbowarp-source": {
|
|
1287
|
+
"revision": "97ef12018789316d6170a7aab29d7c5b0a4c90f4",
|
|
1288
|
+
"revisionRole": "base-commit",
|
|
1289
|
+
"sourceState": "local-release-overlay"
|
|
1290
|
+
}
|
|
644
1291
|
};
|
|
645
1292
|
//#endregion
|
|
646
1293
|
//#region src/extension.ts
|
|
@@ -1017,7 +1664,10 @@ var TMExtension = class {
|
|
|
1017
1664
|
this.visibilityChangeListener = () => this.handleDocumentVisibilityChange();
|
|
1018
1665
|
if (this.featureFlags.temporalPoseScoring && typeof document !== "undefined") document.addEventListener("visibilitychange", this.visibilityChangeListener);
|
|
1019
1666
|
}
|
|
1667
|
+
fixedEditors = fixedInputRegistration(typeof Scratch === "undefined" ? void 0 : Scratch);
|
|
1020
1668
|
getInfo() {
|
|
1669
|
+
const visibleOpcodes = block_definitions_default.blocks.filter((block) => !block.featureFlag || this.featureFlags[block.featureFlag]).map((block) => `${EXTENSION_ID}_${block.opcode}`);
|
|
1670
|
+
this.fixedEditors.ensure(visibleOpcodes);
|
|
1021
1671
|
return {
|
|
1022
1672
|
id: EXTENSION_ID,
|
|
1023
1673
|
name: Scratch.translate(block_definitions_default.extensionName),
|
|
@@ -2089,6 +2739,7 @@ var TMExtension = class {
|
|
|
2089
2739
|
else if (typeof Scratch !== "undefined") Scratch.vm?.runtime?.emit(ACCUMULATED_POSE_CHANGED_EVENT, payload);
|
|
2090
2740
|
}
|
|
2091
2741
|
dispose() {
|
|
2742
|
+
this.fixedEditors.dispose();
|
|
2092
2743
|
this.stopCamera();
|
|
2093
2744
|
if (this.featureFlags.temporalPoseScoring && typeof document !== "undefined") document.removeEventListener("visibilitychange", this.visibilityChangeListener);
|
|
2094
2745
|
this.onAccumulatedPoseChanged = null;
|