scrypted-detection-trainer 0.1.1

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.nodejs.js","mappings":";;;;;;;;;;AAAa;AACb;AACA;AACA;AACA;AACA,eAAe,oCAAoC;AACnD;AACA;AACA,CAAC;AACD;AACA;AACA,CAAC;AACD;AACA;AACA;AACA,8CAA6C,EAAE,aAAa,EAAC;AAC7D,WAAW,GAAG,uBAAuB,GAAG,0BAA0B;AAClE,aAAa,mBAAO,CAAC,gFAAoB;AACzC,gBAAgB,mBAAO,CAAC,gFAAoB;AAC5C,iBAAiB,mBAAO,CAAC,sBAAQ;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,SAAS;AACT;AACA,CAAC;AACD,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,WAAkB,kBAAkB;AAAA,EAMnD;AACT;AACA;AACA,uBAAuB,OAAuB;AAC9C;AACA,kCAAkC,OAAuB;AACzD;AACA;AACA;AACA;AACA,kCAAkC,4EAAQ,SAAS,CAAC;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,iJAAiJ;AACjJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAe;AACf,iC;;;;;;;;;;AC5OA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qC;;;;;;;;;;;ACRa;AACb,8CAA6C,EAAE,aAAa,EAAC;AAC7D,yBAAyB,GAAG,yBAAyB,GAAG,wBAAwB,GAAG,iCAAiC,GAAG,0BAA0B,GAAG,kBAAkB,GAAG,uBAAuB,GAAG,yBAAyB,GAAG,mBAAmB,GAAG,iBAAiB,GAAG,2BAA2B,GAAG,sBAAsB,GAAG,uBAAuB,GAAG,eAAe,GAAG,oBAAoB,GAAG,0BAA0B,GAAG,oCAAoC,GAAG,+BAA+B,GAAG,iCAAiC,GAAG,kBAAkB,GAAG,qBAAqB;AACvjB,qBAAqB;AACrB;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC,gCAAgC,iCAAiC,iCAAiC;AACnG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC,8BAA8B,+BAA+B,+BAA+B;AAC7F,oCAAoC;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC,yBAAyB,0BAA0B,0BAA0B;AAC9E;AACA;AACA;AACA;AACA;AACA;AACA,CAAC,mBAAmB,oBAAoB,oBAAoB;AAC5D;AACA;AACA;AACA;AACA,CAAC,cAAc,eAAe,eAAe;AAC7C;AACA;AACA;AACA;AACA,CAAC,sBAAsB,uBAAuB,uBAAuB;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC,qBAAqB,sBAAsB,sBAAsB;AAClE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC,0BAA0B,2BAA2B,2BAA2B;AACjF;AACA;AACA;AACA;AACA;AACA,CAAC,gBAAgB,iBAAiB,iBAAiB;AACnD;AACA;AACA;AACA;AACA;AACA,CAAC,kBAAkB,mBAAmB,mBAAmB;AACzD;AACA;AACA;AACA;AACA;AACA;AACA,CAAC,wBAAwB,yBAAyB,yBAAyB;AAC3E;AACA;AACA;AACA;AACA,CAAC,sBAAsB,uBAAuB,uBAAuB;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC,iBAAiB,kBAAkB,kBAAkB;AACtD;AACA;AACA;AACA;AACA;AACA;AACA,CAAC,yBAAyB,0BAA0B,0BAA0B;AAC9E;AACA;AACA;AACA;AACA;AACA;AACA,CAAC,gCAAgC,iCAAiC,iCAAiC;AACnG;AACA;AACA;AACA;AACA;AACA;AACA,CAAC,uBAAuB,wBAAwB,wBAAwB;AACxE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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","sources":["../node_modules/@scrypted/sdk/dist/src/index.js","../node_modules/@scrypted/sdk/dist/src|sync","../node_modules/@scrypted/sdk/dist/types/gen/index.js","../src/main.ts","../external node-commonjs \"module\"","../webpack/bootstrap","../webpack/runtime/hasOwnProperty shorthand","../webpack/before-startup","../webpack/startup","../webpack/after-startup"],"sourcesContent":["\"use strict\";\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __exportStar = (this && this.__exportStar) || function(m, exports) {\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.sdk = exports.MixinDeviceBase = exports.ScryptedDeviceBase = void 0;\n__exportStar(require(\"../types/gen/index\"), exports);\nconst index_1 = require(\"../types/gen/index\");\nconst module_1 = require(\"module\");\n/**\n * @category Core Reference\n */\nclass ScryptedDeviceBase extends index_1.DeviceBase {\n constructor(nativeId) {\n super();\n this.nativeId = nativeId;\n }\n get storage() {\n if (!this._storage) {\n this._storage = exports.sdk.deviceManager.getDeviceStorage(this.nativeId);\n }\n return this._storage;\n }\n get log() {\n if (!this._log) {\n this._log = exports.sdk.deviceManager.getDeviceLogger(this.nativeId);\n }\n return this._log;\n }\n get console() {\n if (!this._console) {\n this._console = exports.sdk.deviceManager.getDeviceConsole(this.nativeId);\n }\n return this._console;\n }\n async createMediaObject(data, mimeType) {\n return exports.sdk.mediaManager.createMediaObject(data, mimeType, {\n sourceId: this.id,\n });\n }\n getMediaObjectConsole(mediaObject) {\n if (typeof mediaObject.sourceId !== 'string')\n return this.console;\n return exports.sdk.deviceManager.getMixinConsole(mediaObject.sourceId, this.nativeId);\n }\n _lazyLoadDeviceState() {\n if (!this._deviceState) {\n if (this.nativeId) {\n this._deviceState = exports.sdk.deviceManager.getDeviceState(this.nativeId);\n }\n else {\n this._deviceState = exports.sdk.deviceManager.getDeviceState();\n }\n }\n }\n /**\n * Fire an event for this device.\n */\n onDeviceEvent(eventInterface, eventData) {\n return exports.sdk.deviceManager.onDeviceEvent(this.nativeId, eventInterface, eventData);\n }\n}\nexports.ScryptedDeviceBase = ScryptedDeviceBase;\n/**\n * @category Mixin Reference\n */\nclass MixinDeviceBase extends index_1.DeviceBase {\n constructor(options) {\n super();\n this._listeners = new Set();\n this.mixinDevice = options.mixinDevice;\n this.mixinDeviceInterfaces = options.mixinDeviceInterfaces;\n this.mixinStorageSuffix = options.mixinStorageSuffix;\n this._deviceState = options.mixinDeviceState;\n this.nativeId = exports.sdk.systemManager.getDeviceById(this.id).nativeId;\n this.mixinProviderNativeId = options.mixinProviderNativeId;\n // RpcProxy will trap all properties, and the following check/hack will determine\n // if the device state came from another node worker thread.\n // This should ultimately be discouraged and warned at some point in the future.\n if (this._deviceState.__rpcproxy_traps_all_properties && typeof this._deviceState.id === 'string') {\n this._deviceState = exports.sdk.deviceManager.createDeviceState(this._deviceState.id, this._deviceState.setState);\n }\n }\n get storage() {\n if (!this._storage) {\n const mixinStorageSuffix = this.mixinStorageSuffix;\n const mixinStorageKey = this.id + (mixinStorageSuffix ? ':' + mixinStorageSuffix : '');\n this._storage = exports.sdk.deviceManager.getMixinStorage(mixinStorageKey, this.mixinProviderNativeId);\n }\n return this._storage;\n }\n get console() {\n if (!this._console) {\n if (exports.sdk.deviceManager.getMixinConsole)\n this._console = exports.sdk.deviceManager.getMixinConsole(this.id, this.mixinProviderNativeId);\n else\n this._console = exports.sdk.deviceManager.getDeviceConsole(this.mixinProviderNativeId);\n }\n return this._console;\n }\n async createMediaObject(data, mimeType) {\n return exports.sdk.mediaManager.createMediaObject(data, mimeType, {\n sourceId: this.id,\n });\n }\n getMediaObjectConsole(mediaObject) {\n if (typeof mediaObject.sourceId !== 'string')\n return this.console;\n return exports.sdk.deviceManager.getMixinConsole(mediaObject.sourceId, this.mixinProviderNativeId);\n }\n /**\n * Fire an event for this device.\n */\n onDeviceEvent(eventInterface, eventData) {\n return exports.sdk.deviceManager.onMixinEvent(this.id, this, eventInterface, eventData);\n }\n _lazyLoadDeviceState() {\n }\n manageListener(listener) {\n this._listeners.add(listener);\n }\n release() {\n for (const l of this._listeners) {\n l.removeListener();\n }\n }\n}\nexports.MixinDeviceBase = MixinDeviceBase;\n(function () {\n function _createGetState(state) {\n return function () {\n this._lazyLoadDeviceState();\n // @ts-ignore: accessing private property\n return this._deviceState?.[state];\n };\n }\n function _createSetState(state) {\n return function (value) {\n this._lazyLoadDeviceState();\n // @ts-ignore: accessing private property\n if (!this._deviceState) {\n console.warn('device state is unavailable. the device must be discovered with deviceManager.onDeviceDiscovered or deviceManager.onDevicesChanged before the state can be set.');\n }\n else {\n // @ts-ignore: accessing private property\n this._deviceState[state] = value;\n }\n };\n }\n for (const field of Object.values(index_1.ScryptedInterfaceProperty)) {\n if (field === index_1.ScryptedInterfaceProperty.nativeId)\n continue;\n Object.defineProperty(ScryptedDeviceBase.prototype, field, {\n set: _createSetState(field),\n get: _createGetState(field),\n });\n Object.defineProperty(MixinDeviceBase.prototype, field, {\n set: _createSetState(field),\n get: _createGetState(field),\n });\n }\n})();\nexports.sdk = {};\ntry {\n let loaded = false;\n try {\n // todo: remove usage of process.env.SCRYPTED_SDK_MODULE, only existed in prerelease builds.\n // import.meta is not a reliable way to detect es module support in webpack since webpack\n // evaluates that to true at runtime.\n const esModule = process.env.SCRYPTED_SDK_ES_MODULE || process.env.SCRYPTED_SDK_MODULE;\n const cjsModule = process.env.SCRYPTED_SDK_CJS_MODULE || process.env.SCRYPTED_SDK_MODULE;\n // @ts-expect-error\n if (esModule && typeof import.meta !== 'undefined') {\n // @ts-expect-error\n const require = (0, module_1.createRequire)(import.meta.url);\n const sdkModule = require(esModule);\n Object.assign(exports.sdk, sdkModule.getScryptedStatic());\n loaded = true;\n }\n else if (cjsModule) {\n // @ts-expect-error\n if (typeof __non_webpack_require__ !== 'undefined') {\n // @ts-expect-error\n const sdkModule = __non_webpack_require__(process.env.SCRYPTED_SDK_MODULE);\n Object.assign(exports.sdk, sdkModule.getScryptedStatic());\n loaded = true;\n }\n else {\n const sdkModule = require(cjsModule);\n Object.assign(exports.sdk, sdkModule.getScryptedStatic());\n loaded = true;\n }\n }\n }\n catch (e) {\n console.warn(\"failed to load sdk module\", e);\n throw e;\n }\n if (!loaded) {\n let runtimeAPI;\n try {\n runtimeAPI = pluginRuntimeAPI;\n }\n catch (e) {\n }\n Object.assign(exports.sdk, {\n log: deviceManager.getDeviceLogger(undefined),\n deviceManager,\n endpointManager,\n mediaManager,\n systemManager,\n pluginHostAPI,\n ...runtimeAPI,\n });\n }\n try {\n exports.sdk.systemManager.setScryptedInterfaceDescriptors?.(index_1.TYPES_VERSION, index_1.ScryptedInterfaceDescriptors)?.catch(() => { });\n }\n catch (e) {\n }\n}\ncatch (e) {\n console.error('sdk initialization error, import @scrypted/types or use @scrypted/client instead', e);\n}\nexports.default = exports.sdk;\n//# sourceMappingURL=index.js.map","function webpackEmptyContext(req) {\n\tvar e = new Error(\"Cannot find module '\" + req + \"'\");\n\te.code = 'MODULE_NOT_FOUND';\n\tthrow e;\n}\nwebpackEmptyContext.keys = () => ([]);\nwebpackEmptyContext.resolve = webpackEmptyContext;\nwebpackEmptyContext.id = \"./node_modules/@scrypted/sdk/dist/src sync recursive\";\nmodule.exports = webpackEmptyContext;","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.ScryptedMimeTypes = exports.ScryptedInterface = exports.MediaPlayerState = exports.SecuritySystemObstruction = exports.SecuritySystemMode = exports.AirQuality = exports.AirPurifierMode = exports.AirPurifierStatus = exports.ChargeState = exports.LockState = exports.PanTiltZoomMovement = exports.ThermostatMode = exports.TemperatureUnit = exports.FanMode = exports.HumidityMode = exports.ScryptedDeviceType = exports.ScryptedInterfaceDescriptors = exports.ScryptedInterfaceMethod = exports.ScryptedInterfaceProperty = exports.DeviceBase = exports.TYPES_VERSION = void 0;\nexports.TYPES_VERSION = \"0.3.116\";\nclass DeviceBase {\n}\nexports.DeviceBase = DeviceBase;\nvar ScryptedInterfaceProperty;\n(function (ScryptedInterfaceProperty) {\n ScryptedInterfaceProperty[\"id\"] = \"id\";\n ScryptedInterfaceProperty[\"info\"] = \"info\";\n ScryptedInterfaceProperty[\"interfaces\"] = \"interfaces\";\n ScryptedInterfaceProperty[\"mixins\"] = \"mixins\";\n ScryptedInterfaceProperty[\"name\"] = \"name\";\n ScryptedInterfaceProperty[\"nativeId\"] = \"nativeId\";\n ScryptedInterfaceProperty[\"pluginId\"] = \"pluginId\";\n ScryptedInterfaceProperty[\"providedInterfaces\"] = \"providedInterfaces\";\n ScryptedInterfaceProperty[\"providedName\"] = \"providedName\";\n ScryptedInterfaceProperty[\"providedRoom\"] = \"providedRoom\";\n ScryptedInterfaceProperty[\"providedType\"] = \"providedType\";\n ScryptedInterfaceProperty[\"providerId\"] = \"providerId\";\n ScryptedInterfaceProperty[\"room\"] = \"room\";\n ScryptedInterfaceProperty[\"type\"] = \"type\";\n ScryptedInterfaceProperty[\"scryptedRuntimeArguments\"] = \"scryptedRuntimeArguments\";\n ScryptedInterfaceProperty[\"on\"] = \"on\";\n ScryptedInterfaceProperty[\"brightness\"] = \"brightness\";\n ScryptedInterfaceProperty[\"colorTemperature\"] = \"colorTemperature\";\n ScryptedInterfaceProperty[\"rgb\"] = \"rgb\";\n ScryptedInterfaceProperty[\"hsv\"] = \"hsv\";\n ScryptedInterfaceProperty[\"buttons\"] = \"buttons\";\n ScryptedInterfaceProperty[\"sensors\"] = \"sensors\";\n ScryptedInterfaceProperty[\"running\"] = \"running\";\n ScryptedInterfaceProperty[\"paused\"] = \"paused\";\n ScryptedInterfaceProperty[\"docked\"] = \"docked\";\n ScryptedInterfaceProperty[\"temperatureSetting\"] = \"temperatureSetting\";\n ScryptedInterfaceProperty[\"temperature\"] = \"temperature\";\n ScryptedInterfaceProperty[\"temperatureUnit\"] = \"temperatureUnit\";\n ScryptedInterfaceProperty[\"humidity\"] = \"humidity\";\n ScryptedInterfaceProperty[\"audioVolumes\"] = \"audioVolumes\";\n ScryptedInterfaceProperty[\"recordingActive\"] = \"recordingActive\";\n ScryptedInterfaceProperty[\"ptzCapabilities\"] = \"ptzCapabilities\";\n ScryptedInterfaceProperty[\"lockState\"] = \"lockState\";\n ScryptedInterfaceProperty[\"entryOpen\"] = \"entryOpen\";\n ScryptedInterfaceProperty[\"batteryLevel\"] = \"batteryLevel\";\n ScryptedInterfaceProperty[\"chargeState\"] = \"chargeState\";\n ScryptedInterfaceProperty[\"online\"] = \"online\";\n ScryptedInterfaceProperty[\"fromMimeType\"] = \"fromMimeType\";\n ScryptedInterfaceProperty[\"toMimeType\"] = \"toMimeType\";\n ScryptedInterfaceProperty[\"converters\"] = \"converters\";\n ScryptedInterfaceProperty[\"binaryState\"] = \"binaryState\";\n ScryptedInterfaceProperty[\"tampered\"] = \"tampered\";\n ScryptedInterfaceProperty[\"sleeping\"] = \"sleeping\";\n ScryptedInterfaceProperty[\"powerDetected\"] = \"powerDetected\";\n ScryptedInterfaceProperty[\"audioDetected\"] = \"audioDetected\";\n ScryptedInterfaceProperty[\"motionDetected\"] = \"motionDetected\";\n ScryptedInterfaceProperty[\"ambientLight\"] = \"ambientLight\";\n ScryptedInterfaceProperty[\"occupied\"] = \"occupied\";\n ScryptedInterfaceProperty[\"flooded\"] = \"flooded\";\n ScryptedInterfaceProperty[\"ultraviolet\"] = \"ultraviolet\";\n ScryptedInterfaceProperty[\"luminance\"] = \"luminance\";\n ScryptedInterfaceProperty[\"position\"] = \"position\";\n ScryptedInterfaceProperty[\"securitySystemState\"] = \"securitySystemState\";\n ScryptedInterfaceProperty[\"pm10Density\"] = \"pm10Density\";\n ScryptedInterfaceProperty[\"pm25Density\"] = \"pm25Density\";\n ScryptedInterfaceProperty[\"vocDensity\"] = \"vocDensity\";\n ScryptedInterfaceProperty[\"noxDensity\"] = \"noxDensity\";\n ScryptedInterfaceProperty[\"co2ppm\"] = \"co2ppm\";\n ScryptedInterfaceProperty[\"airQuality\"] = \"airQuality\";\n ScryptedInterfaceProperty[\"airPurifierState\"] = \"airPurifierState\";\n ScryptedInterfaceProperty[\"filterChangeIndication\"] = \"filterChangeIndication\";\n ScryptedInterfaceProperty[\"filterLifeLevel\"] = \"filterLifeLevel\";\n ScryptedInterfaceProperty[\"humiditySetting\"] = \"humiditySetting\";\n ScryptedInterfaceProperty[\"fan\"] = \"fan\";\n ScryptedInterfaceProperty[\"applicationInfo\"] = \"applicationInfo\";\n ScryptedInterfaceProperty[\"systemDevice\"] = \"systemDevice\";\n})(ScryptedInterfaceProperty || (exports.ScryptedInterfaceProperty = ScryptedInterfaceProperty = {}));\nvar ScryptedInterfaceMethod;\n(function (ScryptedInterfaceMethod) {\n ScryptedInterfaceMethod[\"listen\"] = \"listen\";\n ScryptedInterfaceMethod[\"probe\"] = \"probe\";\n ScryptedInterfaceMethod[\"setMixins\"] = \"setMixins\";\n ScryptedInterfaceMethod[\"setName\"] = \"setName\";\n ScryptedInterfaceMethod[\"setRoom\"] = \"setRoom\";\n ScryptedInterfaceMethod[\"setType\"] = \"setType\";\n ScryptedInterfaceMethod[\"getPluginJson\"] = \"getPluginJson\";\n ScryptedInterfaceMethod[\"turnOff\"] = \"turnOff\";\n ScryptedInterfaceMethod[\"turnOn\"] = \"turnOn\";\n ScryptedInterfaceMethod[\"setBrightness\"] = \"setBrightness\";\n ScryptedInterfaceMethod[\"getTemperatureMaxK\"] = \"getTemperatureMaxK\";\n ScryptedInterfaceMethod[\"getTemperatureMinK\"] = \"getTemperatureMinK\";\n ScryptedInterfaceMethod[\"setColorTemperature\"] = \"setColorTemperature\";\n ScryptedInterfaceMethod[\"setRgb\"] = \"setRgb\";\n ScryptedInterfaceMethod[\"setHsv\"] = \"setHsv\";\n ScryptedInterfaceMethod[\"pressButton\"] = \"pressButton\";\n ScryptedInterfaceMethod[\"sendNotification\"] = \"sendNotification\";\n ScryptedInterfaceMethod[\"start\"] = \"start\";\n ScryptedInterfaceMethod[\"stop\"] = \"stop\";\n ScryptedInterfaceMethod[\"pause\"] = \"pause\";\n ScryptedInterfaceMethod[\"resume\"] = \"resume\";\n ScryptedInterfaceMethod[\"dock\"] = \"dock\";\n ScryptedInterfaceMethod[\"setTemperature\"] = \"setTemperature\";\n ScryptedInterfaceMethod[\"setTemperatureUnit\"] = \"setTemperatureUnit\";\n ScryptedInterfaceMethod[\"getPictureOptions\"] = \"getPictureOptions\";\n ScryptedInterfaceMethod[\"takePicture\"] = \"takePicture\";\n ScryptedInterfaceMethod[\"getAudioStream\"] = \"getAudioStream\";\n ScryptedInterfaceMethod[\"setAudioVolumes\"] = \"setAudioVolumes\";\n ScryptedInterfaceMethod[\"startDisplay\"] = \"startDisplay\";\n ScryptedInterfaceMethod[\"stopDisplay\"] = \"stopDisplay\";\n ScryptedInterfaceMethod[\"getVideoStream\"] = \"getVideoStream\";\n ScryptedInterfaceMethod[\"getVideoStreamOptions\"] = \"getVideoStreamOptions\";\n ScryptedInterfaceMethod[\"getPrivacyMasks\"] = \"getPrivacyMasks\";\n ScryptedInterfaceMethod[\"setPrivacyMasks\"] = \"setPrivacyMasks\";\n ScryptedInterfaceMethod[\"getVideoTextOverlays\"] = \"getVideoTextOverlays\";\n ScryptedInterfaceMethod[\"setVideoTextOverlay\"] = \"setVideoTextOverlay\";\n ScryptedInterfaceMethod[\"getRecordingStream\"] = \"getRecordingStream\";\n ScryptedInterfaceMethod[\"getRecordingStreamCurrentTime\"] = \"getRecordingStreamCurrentTime\";\n ScryptedInterfaceMethod[\"getRecordingStreamOptions\"] = \"getRecordingStreamOptions\";\n ScryptedInterfaceMethod[\"getRecordingStreamThumbnail\"] = \"getRecordingStreamThumbnail\";\n ScryptedInterfaceMethod[\"deleteRecordingStream\"] = \"deleteRecordingStream\";\n ScryptedInterfaceMethod[\"setRecordingActive\"] = \"setRecordingActive\";\n ScryptedInterfaceMethod[\"ptzCommand\"] = \"ptzCommand\";\n ScryptedInterfaceMethod[\"getRecordedEvents\"] = \"getRecordedEvents\";\n ScryptedInterfaceMethod[\"getVideoClip\"] = \"getVideoClip\";\n ScryptedInterfaceMethod[\"getVideoClips\"] = \"getVideoClips\";\n ScryptedInterfaceMethod[\"getVideoClipThumbnail\"] = \"getVideoClipThumbnail\";\n ScryptedInterfaceMethod[\"removeVideoClips\"] = \"removeVideoClips\";\n ScryptedInterfaceMethod[\"setVideoStreamOptions\"] = \"setVideoStreamOptions\";\n ScryptedInterfaceMethod[\"startIntercom\"] = \"startIntercom\";\n ScryptedInterfaceMethod[\"stopIntercom\"] = \"stopIntercom\";\n ScryptedInterfaceMethod[\"lock\"] = \"lock\";\n ScryptedInterfaceMethod[\"unlock\"] = \"unlock\";\n ScryptedInterfaceMethod[\"addPassword\"] = \"addPassword\";\n ScryptedInterfaceMethod[\"getPasswords\"] = \"getPasswords\";\n ScryptedInterfaceMethod[\"removePassword\"] = \"removePassword\";\n ScryptedInterfaceMethod[\"activate\"] = \"activate\";\n ScryptedInterfaceMethod[\"deactivate\"] = \"deactivate\";\n ScryptedInterfaceMethod[\"isReversible\"] = \"isReversible\";\n ScryptedInterfaceMethod[\"closeEntry\"] = \"closeEntry\";\n ScryptedInterfaceMethod[\"openEntry\"] = \"openEntry\";\n ScryptedInterfaceMethod[\"getDevice\"] = \"getDevice\";\n ScryptedInterfaceMethod[\"releaseDevice\"] = \"releaseDevice\";\n ScryptedInterfaceMethod[\"adoptDevice\"] = \"adoptDevice\";\n ScryptedInterfaceMethod[\"discoverDevices\"] = \"discoverDevices\";\n ScryptedInterfaceMethod[\"createDevice\"] = \"createDevice\";\n ScryptedInterfaceMethod[\"getCreateDeviceSettings\"] = \"getCreateDeviceSettings\";\n ScryptedInterfaceMethod[\"reboot\"] = \"reboot\";\n ScryptedInterfaceMethod[\"getRefreshFrequency\"] = \"getRefreshFrequency\";\n ScryptedInterfaceMethod[\"refresh\"] = \"refresh\";\n ScryptedInterfaceMethod[\"getMediaStatus\"] = \"getMediaStatus\";\n ScryptedInterfaceMethod[\"load\"] = \"load\";\n ScryptedInterfaceMethod[\"seek\"] = \"seek\";\n ScryptedInterfaceMethod[\"skipNext\"] = \"skipNext\";\n ScryptedInterfaceMethod[\"skipPrevious\"] = \"skipPrevious\";\n ScryptedInterfaceMethod[\"convert\"] = \"convert\";\n ScryptedInterfaceMethod[\"convertMedia\"] = \"convertMedia\";\n ScryptedInterfaceMethod[\"getSettings\"] = \"getSettings\";\n ScryptedInterfaceMethod[\"putSetting\"] = \"putSetting\";\n ScryptedInterfaceMethod[\"armSecuritySystem\"] = \"armSecuritySystem\";\n ScryptedInterfaceMethod[\"disarmSecuritySystem\"] = \"disarmSecuritySystem\";\n ScryptedInterfaceMethod[\"setAirPurifierState\"] = \"setAirPurifierState\";\n ScryptedInterfaceMethod[\"getReadmeMarkdown\"] = \"getReadmeMarkdown\";\n ScryptedInterfaceMethod[\"getOauthUrl\"] = \"getOauthUrl\";\n ScryptedInterfaceMethod[\"onOauthCallback\"] = \"onOauthCallback\";\n ScryptedInterfaceMethod[\"canMixin\"] = \"canMixin\";\n ScryptedInterfaceMethod[\"getMixin\"] = \"getMixin\";\n ScryptedInterfaceMethod[\"releaseMixin\"] = \"releaseMixin\";\n ScryptedInterfaceMethod[\"onRequest\"] = \"onRequest\";\n ScryptedInterfaceMethod[\"onConnection\"] = \"onConnection\";\n ScryptedInterfaceMethod[\"onPush\"] = \"onPush\";\n ScryptedInterfaceMethod[\"run\"] = \"run\";\n ScryptedInterfaceMethod[\"eval\"] = \"eval\";\n ScryptedInterfaceMethod[\"loadScripts\"] = \"loadScripts\";\n ScryptedInterfaceMethod[\"saveScript\"] = \"saveScript\";\n ScryptedInterfaceMethod[\"forkInterface\"] = \"forkInterface\";\n ScryptedInterfaceMethod[\"trackObjects\"] = \"trackObjects\";\n ScryptedInterfaceMethod[\"getDetectionInput\"] = \"getDetectionInput\";\n ScryptedInterfaceMethod[\"getObjectTypes\"] = \"getObjectTypes\";\n ScryptedInterfaceMethod[\"detectObjects\"] = \"detectObjects\";\n ScryptedInterfaceMethod[\"generateObjectDetections\"] = \"generateObjectDetections\";\n ScryptedInterfaceMethod[\"getDetectionModel\"] = \"getDetectionModel\";\n ScryptedInterfaceMethod[\"setHumidity\"] = \"setHumidity\";\n ScryptedInterfaceMethod[\"setFan\"] = \"setFan\";\n ScryptedInterfaceMethod[\"startRTCSignalingSession\"] = \"startRTCSignalingSession\";\n ScryptedInterfaceMethod[\"createRTCSignalingSession\"] = \"createRTCSignalingSession\";\n ScryptedInterfaceMethod[\"getScryptedUserAccessControl\"] = \"getScryptedUserAccessControl\";\n ScryptedInterfaceMethod[\"generateVideoFrames\"] = \"generateVideoFrames\";\n ScryptedInterfaceMethod[\"connectStream\"] = \"connectStream\";\n ScryptedInterfaceMethod[\"getTTYSettings\"] = \"getTTYSettings\";\n})(ScryptedInterfaceMethod || (exports.ScryptedInterfaceMethod = ScryptedInterfaceMethod = {}));\nexports.ScryptedInterfaceDescriptors = {\n \"ScryptedDevice\": {\n \"name\": \"ScryptedDevice\",\n \"methods\": [\n \"listen\",\n \"probe\",\n \"setMixins\",\n \"setName\",\n \"setRoom\",\n \"setType\"\n ],\n \"properties\": [\n \"id\",\n \"info\",\n \"interfaces\",\n \"mixins\",\n \"name\",\n \"nativeId\",\n \"pluginId\",\n \"providedInterfaces\",\n \"providedName\",\n \"providedRoom\",\n \"providedType\",\n \"providerId\",\n \"room\",\n \"type\"\n ]\n },\n \"ScryptedPlugin\": {\n \"name\": \"ScryptedPlugin\",\n \"methods\": [\n \"getPluginJson\"\n ],\n \"properties\": []\n },\n \"ScryptedPluginRuntime\": {\n \"name\": \"ScryptedPluginRuntime\",\n \"methods\": [],\n \"properties\": [\n \"scryptedRuntimeArguments\"\n ]\n },\n \"OnOff\": {\n \"name\": \"OnOff\",\n \"methods\": [\n \"turnOff\",\n \"turnOn\"\n ],\n \"properties\": [\n \"on\"\n ]\n },\n \"Brightness\": {\n \"name\": \"Brightness\",\n \"methods\": [\n \"setBrightness\"\n ],\n \"properties\": [\n \"brightness\"\n ]\n },\n \"ColorSettingTemperature\": {\n \"name\": \"ColorSettingTemperature\",\n \"methods\": [\n \"getTemperatureMaxK\",\n \"getTemperatureMinK\",\n \"setColorTemperature\"\n ],\n \"properties\": [\n \"colorTemperature\"\n ]\n },\n \"ColorSettingRgb\": {\n \"name\": \"ColorSettingRgb\",\n \"methods\": [\n \"setRgb\"\n ],\n \"properties\": [\n \"rgb\"\n ]\n },\n \"ColorSettingHsv\": {\n \"name\": \"ColorSettingHsv\",\n \"methods\": [\n \"setHsv\"\n ],\n \"properties\": [\n \"hsv\"\n ]\n },\n \"Buttons\": {\n \"name\": \"Buttons\",\n \"methods\": [],\n \"properties\": [\n \"buttons\"\n ]\n },\n \"PressButtons\": {\n \"name\": \"PressButtons\",\n \"methods\": [\n \"pressButton\"\n ],\n \"properties\": []\n },\n \"Sensors\": {\n \"name\": \"Sensors\",\n \"methods\": [],\n \"properties\": [\n \"sensors\"\n ]\n },\n \"Notifier\": {\n \"name\": \"Notifier\",\n \"methods\": [\n \"sendNotification\"\n ],\n \"properties\": []\n },\n \"StartStop\": {\n \"name\": \"StartStop\",\n \"methods\": [\n \"start\",\n \"stop\"\n ],\n \"properties\": [\n \"running\"\n ]\n },\n \"Pause\": {\n \"name\": \"Pause\",\n \"methods\": [\n \"pause\",\n \"resume\"\n ],\n \"properties\": [\n \"paused\"\n ]\n },\n \"Dock\": {\n \"name\": \"Dock\",\n \"methods\": [\n \"dock\"\n ],\n \"properties\": [\n \"docked\"\n ]\n },\n \"TemperatureSetting\": {\n \"name\": \"TemperatureSetting\",\n \"methods\": [\n \"setTemperature\"\n ],\n \"properties\": [\n \"temperatureSetting\"\n ]\n },\n \"Thermometer\": {\n \"name\": \"Thermometer\",\n \"methods\": [\n \"setTemperatureUnit\"\n ],\n \"properties\": [\n \"temperature\",\n \"temperatureUnit\"\n ]\n },\n \"HumiditySensor\": {\n \"name\": \"HumiditySensor\",\n \"methods\": [],\n \"properties\": [\n \"humidity\"\n ]\n },\n \"Camera\": {\n \"name\": \"Camera\",\n \"methods\": [\n \"getPictureOptions\",\n \"takePicture\"\n ],\n \"properties\": []\n },\n \"Microphone\": {\n \"name\": \"Microphone\",\n \"methods\": [\n \"getAudioStream\"\n ],\n \"properties\": []\n },\n \"AudioVolumeControl\": {\n \"name\": \"AudioVolumeControl\",\n \"methods\": [\n \"setAudioVolumes\"\n ],\n \"properties\": [\n \"audioVolumes\"\n ]\n },\n \"Display\": {\n \"name\": \"Display\",\n \"methods\": [\n \"startDisplay\",\n \"stopDisplay\"\n ],\n \"properties\": []\n },\n \"VideoCamera\": {\n \"name\": \"VideoCamera\",\n \"methods\": [\n \"getVideoStream\",\n \"getVideoStreamOptions\"\n ],\n \"properties\": []\n },\n \"VideoCameraMask\": {\n \"name\": \"VideoCameraMask\",\n \"methods\": [\n \"getPrivacyMasks\",\n \"setPrivacyMasks\"\n ],\n \"properties\": []\n },\n \"VideoTextOverlays\": {\n \"name\": \"VideoTextOverlays\",\n \"methods\": [\n \"getVideoTextOverlays\",\n \"setVideoTextOverlay\"\n ],\n \"properties\": []\n },\n \"VideoRecorder\": {\n \"name\": \"VideoRecorder\",\n \"methods\": [\n \"getRecordingStream\",\n \"getRecordingStreamCurrentTime\",\n \"getRecordingStreamOptions\",\n \"getRecordingStreamThumbnail\"\n ],\n \"properties\": [\n \"recordingActive\"\n ]\n },\n \"VideoRecorderManagement\": {\n \"name\": \"VideoRecorderManagement\",\n \"methods\": [\n \"deleteRecordingStream\",\n \"setRecordingActive\"\n ],\n \"properties\": []\n },\n \"PanTiltZoom\": {\n \"name\": \"PanTiltZoom\",\n \"methods\": [\n \"ptzCommand\"\n ],\n \"properties\": [\n \"ptzCapabilities\"\n ]\n },\n \"EventRecorder\": {\n \"name\": \"EventRecorder\",\n \"methods\": [\n \"getRecordedEvents\"\n ],\n \"properties\": []\n },\n \"VideoClips\": {\n \"name\": \"VideoClips\",\n \"methods\": [\n \"getVideoClip\",\n \"getVideoClips\",\n \"getVideoClipThumbnail\",\n \"removeVideoClips\"\n ],\n \"properties\": []\n },\n \"VideoCameraConfiguration\": {\n \"name\": \"VideoCameraConfiguration\",\n \"methods\": [\n \"setVideoStreamOptions\"\n ],\n \"properties\": []\n },\n \"Intercom\": {\n \"name\": \"Intercom\",\n \"methods\": [\n \"startIntercom\",\n \"stopIntercom\"\n ],\n \"properties\": []\n },\n \"Lock\": {\n \"name\": \"Lock\",\n \"methods\": [\n \"lock\",\n \"unlock\"\n ],\n \"properties\": [\n \"lockState\"\n ]\n },\n \"PasswordStore\": {\n \"name\": \"PasswordStore\",\n \"methods\": [\n \"addPassword\",\n \"getPasswords\",\n \"removePassword\"\n ],\n \"properties\": []\n },\n \"Scene\": {\n \"name\": \"Scene\",\n \"methods\": [\n \"activate\",\n \"deactivate\",\n \"isReversible\"\n ],\n \"properties\": []\n },\n \"Entry\": {\n \"name\": \"Entry\",\n \"methods\": [\n \"closeEntry\",\n \"openEntry\"\n ],\n \"properties\": []\n },\n \"EntrySensor\": {\n \"name\": \"EntrySensor\",\n \"methods\": [],\n \"properties\": [\n \"entryOpen\"\n ]\n },\n \"DeviceProvider\": {\n \"name\": \"DeviceProvider\",\n \"methods\": [\n \"getDevice\",\n \"releaseDevice\"\n ],\n \"properties\": []\n },\n \"DeviceDiscovery\": {\n \"name\": \"DeviceDiscovery\",\n \"methods\": [\n \"adoptDevice\",\n \"discoverDevices\"\n ],\n \"properties\": []\n },\n \"DeviceCreator\": {\n \"name\": \"DeviceCreator\",\n \"methods\": [\n \"createDevice\",\n \"getCreateDeviceSettings\"\n ],\n \"properties\": []\n },\n \"Battery\": {\n \"name\": \"Battery\",\n \"methods\": [],\n \"properties\": [\n \"batteryLevel\"\n ]\n },\n \"Charger\": {\n \"name\": \"Charger\",\n \"methods\": [],\n \"properties\": [\n \"chargeState\"\n ]\n },\n \"Reboot\": {\n \"name\": \"Reboot\",\n \"methods\": [\n \"reboot\"\n ],\n \"properties\": []\n },\n \"Refresh\": {\n \"name\": \"Refresh\",\n \"methods\": [\n \"getRefreshFrequency\",\n \"refresh\"\n ],\n \"properties\": []\n },\n \"MediaPlayer\": {\n \"name\": \"MediaPlayer\",\n \"methods\": [\n \"getMediaStatus\",\n \"load\",\n \"seek\",\n \"skipNext\",\n \"skipPrevious\"\n ],\n \"properties\": []\n },\n \"Online\": {\n \"name\": \"Online\",\n \"methods\": [],\n \"properties\": [\n \"online\"\n ]\n },\n \"BufferConverter\": {\n \"name\": \"BufferConverter\",\n \"methods\": [\n \"convert\"\n ],\n \"properties\": [\n \"fromMimeType\",\n \"toMimeType\"\n ]\n },\n \"MediaConverter\": {\n \"name\": \"MediaConverter\",\n \"methods\": [\n \"convertMedia\"\n ],\n \"properties\": [\n \"converters\"\n ]\n },\n \"Settings\": {\n \"name\": \"Settings\",\n \"methods\": [\n \"getSettings\",\n \"putSetting\"\n ],\n \"properties\": []\n },\n \"BinarySensor\": {\n \"name\": \"BinarySensor\",\n \"methods\": [],\n \"properties\": [\n \"binaryState\"\n ]\n },\n \"TamperSensor\": {\n \"name\": \"TamperSensor\",\n \"methods\": [],\n \"properties\": [\n \"tampered\"\n ]\n },\n \"Sleep\": {\n \"name\": \"Sleep\",\n \"methods\": [],\n \"properties\": [\n \"sleeping\"\n ]\n },\n \"PowerSensor\": {\n \"name\": \"PowerSensor\",\n \"methods\": [],\n \"properties\": [\n \"powerDetected\"\n ]\n },\n \"AudioSensor\": {\n \"name\": \"AudioSensor\",\n \"methods\": [],\n \"properties\": [\n \"audioDetected\"\n ]\n },\n \"MotionSensor\": {\n \"name\": \"MotionSensor\",\n \"methods\": [],\n \"properties\": [\n \"motionDetected\"\n ]\n },\n \"AmbientLightSensor\": {\n \"name\": \"AmbientLightSensor\",\n \"methods\": [],\n \"properties\": [\n \"ambientLight\"\n ]\n },\n \"OccupancySensor\": {\n \"name\": \"OccupancySensor\",\n \"methods\": [],\n \"properties\": [\n \"occupied\"\n ]\n },\n \"FloodSensor\": {\n \"name\": \"FloodSensor\",\n \"methods\": [],\n \"properties\": [\n \"flooded\"\n ]\n },\n \"UltravioletSensor\": {\n \"name\": \"UltravioletSensor\",\n \"methods\": [],\n \"properties\": [\n \"ultraviolet\"\n ]\n },\n \"LuminanceSensor\": {\n \"name\": \"LuminanceSensor\",\n \"methods\": [],\n \"properties\": [\n \"luminance\"\n ]\n },\n \"PositionSensor\": {\n \"name\": \"PositionSensor\",\n \"methods\": [],\n \"properties\": [\n \"position\"\n ]\n },\n \"SecuritySystem\": {\n \"name\": \"SecuritySystem\",\n \"methods\": [\n \"armSecuritySystem\",\n \"disarmSecuritySystem\"\n ],\n \"properties\": [\n \"securitySystemState\"\n ]\n },\n \"PM10Sensor\": {\n \"name\": \"PM10Sensor\",\n \"methods\": [],\n \"properties\": [\n \"pm10Density\"\n ]\n },\n \"PM25Sensor\": {\n \"name\": \"PM25Sensor\",\n \"methods\": [],\n \"properties\": [\n \"pm25Density\"\n ]\n },\n \"VOCSensor\": {\n \"name\": \"VOCSensor\",\n \"methods\": [],\n \"properties\": [\n \"vocDensity\"\n ]\n },\n \"NOXSensor\": {\n \"name\": \"NOXSensor\",\n \"methods\": [],\n \"properties\": [\n \"noxDensity\"\n ]\n },\n \"CO2Sensor\": {\n \"name\": \"CO2Sensor\",\n \"methods\": [],\n \"properties\": [\n \"co2ppm\"\n ]\n },\n \"AirQualitySensor\": {\n \"name\": \"AirQualitySensor\",\n \"methods\": [],\n \"properties\": [\n \"airQuality\"\n ]\n },\n \"AirPurifier\": {\n \"name\": \"AirPurifier\",\n \"methods\": [\n \"setAirPurifierState\"\n ],\n \"properties\": [\n \"airPurifierState\"\n ]\n },\n \"FilterMaintenance\": {\n \"name\": \"FilterMaintenance\",\n \"methods\": [],\n \"properties\": [\n \"filterChangeIndication\",\n \"filterLifeLevel\"\n ]\n },\n \"Readme\": {\n \"name\": \"Readme\",\n \"methods\": [\n \"getReadmeMarkdown\"\n ],\n \"properties\": []\n },\n \"OauthClient\": {\n \"name\": \"OauthClient\",\n \"methods\": [\n \"getOauthUrl\",\n \"onOauthCallback\"\n ],\n \"properties\": []\n },\n \"MixinProvider\": {\n \"name\": \"MixinProvider\",\n \"methods\": [\n \"canMixin\",\n \"getMixin\",\n \"releaseMixin\"\n ],\n \"properties\": []\n },\n \"HttpRequestHandler\": {\n \"name\": \"HttpRequestHandler\",\n \"methods\": [\n \"onRequest\"\n ],\n \"properties\": []\n },\n \"EngineIOHandler\": {\n \"name\": \"EngineIOHandler\",\n \"methods\": [\n \"onConnection\"\n ],\n \"properties\": []\n },\n \"PushHandler\": {\n \"name\": \"PushHandler\",\n \"methods\": [\n \"onPush\"\n ],\n \"properties\": []\n },\n \"Program\": {\n \"name\": \"Program\",\n \"methods\": [\n \"run\"\n ],\n \"properties\": []\n },\n \"Scriptable\": {\n \"name\": \"Scriptable\",\n \"methods\": [\n \"eval\",\n \"loadScripts\",\n \"saveScript\"\n ],\n \"properties\": []\n },\n \"ClusterForkInterface\": {\n \"name\": \"ClusterForkInterface\",\n \"methods\": [\n \"forkInterface\"\n ],\n \"properties\": []\n },\n \"ObjectTracker\": {\n \"name\": \"ObjectTracker\",\n \"methods\": [\n \"trackObjects\"\n ],\n \"properties\": []\n },\n \"ObjectDetector\": {\n \"name\": \"ObjectDetector\",\n \"methods\": [\n \"getDetectionInput\",\n \"getObjectTypes\"\n ],\n \"properties\": []\n },\n \"ObjectDetection\": {\n \"name\": \"ObjectDetection\",\n \"methods\": [\n \"detectObjects\",\n \"generateObjectDetections\",\n \"getDetectionModel\"\n ],\n \"properties\": []\n },\n \"ObjectDetectionPreview\": {\n \"name\": \"ObjectDetectionPreview\",\n \"methods\": [],\n \"properties\": []\n },\n \"ObjectDetectionGenerator\": {\n \"name\": \"ObjectDetectionGenerator\",\n \"methods\": [],\n \"properties\": []\n },\n \"HumiditySetting\": {\n \"name\": \"HumiditySetting\",\n \"methods\": [\n \"setHumidity\"\n ],\n \"properties\": [\n \"humiditySetting\"\n ]\n },\n \"Fan\": {\n \"name\": \"Fan\",\n \"methods\": [\n \"setFan\"\n ],\n \"properties\": [\n \"fan\"\n ]\n },\n \"RTCSignalingChannel\": {\n \"name\": \"RTCSignalingChannel\",\n \"methods\": [\n \"startRTCSignalingSession\"\n ],\n \"properties\": []\n },\n \"RTCSignalingClient\": {\n \"name\": \"RTCSignalingClient\",\n \"methods\": [\n \"createRTCSignalingSession\"\n ],\n \"properties\": []\n },\n \"LauncherApplication\": {\n \"name\": \"LauncherApplication\",\n \"methods\": [],\n \"properties\": [\n \"applicationInfo\"\n ]\n },\n \"ScryptedUser\": {\n \"name\": \"ScryptedUser\",\n \"methods\": [\n \"getScryptedUserAccessControl\"\n ],\n \"properties\": []\n },\n \"VideoFrameGenerator\": {\n \"name\": \"VideoFrameGenerator\",\n \"methods\": [\n \"generateVideoFrames\"\n ],\n \"properties\": []\n },\n \"StreamService\": {\n \"name\": \"StreamService\",\n \"methods\": [\n \"connectStream\"\n ],\n \"properties\": []\n },\n \"TTY\": {\n \"name\": \"TTY\",\n \"methods\": [],\n \"properties\": []\n },\n \"TTYSettings\": {\n \"name\": \"TTYSettings\",\n \"methods\": [\n \"getTTYSettings\"\n ],\n \"properties\": []\n },\n \"ScryptedSystemDevice\": {\n \"name\": \"ScryptedSystemDevice\",\n \"methods\": [],\n \"properties\": [\n \"systemDevice\"\n ]\n },\n \"ScryptedDeviceCreator\": {\n \"name\": \"ScryptedDeviceCreator\",\n \"methods\": [],\n \"properties\": []\n },\n \"ScryptedSettings\": {\n \"name\": \"ScryptedSettings\",\n \"methods\": [],\n \"properties\": []\n }\n};\n/**\n * @category Core Reference\n */\nvar ScryptedDeviceType;\n(function (ScryptedDeviceType) {\n /**\n * @deprecated\n */\n ScryptedDeviceType[\"Builtin\"] = \"Builtin\";\n /**\n * Internal devices will not show up in device lists unless explicitly searched.\n */\n ScryptedDeviceType[\"Internal\"] = \"Internal\";\n ScryptedDeviceType[\"Camera\"] = \"Camera\";\n ScryptedDeviceType[\"Fan\"] = \"Fan\";\n ScryptedDeviceType[\"Light\"] = \"Light\";\n ScryptedDeviceType[\"Switch\"] = \"Switch\";\n ScryptedDeviceType[\"Outlet\"] = \"Outlet\";\n ScryptedDeviceType[\"Sensor\"] = \"Sensor\";\n ScryptedDeviceType[\"Scene\"] = \"Scene\";\n ScryptedDeviceType[\"Program\"] = \"Program\";\n ScryptedDeviceType[\"Automation\"] = \"Automation\";\n ScryptedDeviceType[\"Vacuum\"] = \"Vacuum\";\n ScryptedDeviceType[\"Notifier\"] = \"Notifier\";\n ScryptedDeviceType[\"Thermostat\"] = \"Thermostat\";\n ScryptedDeviceType[\"Lock\"] = \"Lock\";\n ScryptedDeviceType[\"PasswordControl\"] = \"PasswordControl\";\n /**\n * Displays have audio and video output.\n */\n ScryptedDeviceType[\"Display\"] = \"Display\";\n /**\n * Smart Displays have two way audio and video.\n */\n ScryptedDeviceType[\"SmartDisplay\"] = \"SmartDisplay\";\n ScryptedDeviceType[\"Speaker\"] = \"Speaker\";\n /**\n * Smart Speakers have two way audio.\n */\n ScryptedDeviceType[\"SmartSpeaker\"] = \"SmartSpeaker\";\n ScryptedDeviceType[\"Event\"] = \"Event\";\n ScryptedDeviceType[\"Entry\"] = \"Entry\";\n ScryptedDeviceType[\"Garage\"] = \"Garage\";\n ScryptedDeviceType[\"DeviceProvider\"] = \"DeviceProvider\";\n ScryptedDeviceType[\"DataSource\"] = \"DataSource\";\n ScryptedDeviceType[\"API\"] = \"API\";\n ScryptedDeviceType[\"Doorbell\"] = \"Doorbell\";\n ScryptedDeviceType[\"Irrigation\"] = \"Irrigation\";\n ScryptedDeviceType[\"Valve\"] = \"Valve\";\n ScryptedDeviceType[\"Person\"] = \"Person\";\n ScryptedDeviceType[\"SecuritySystem\"] = \"SecuritySystem\";\n ScryptedDeviceType[\"WindowCovering\"] = \"WindowCovering\";\n ScryptedDeviceType[\"Siren\"] = \"Siren\";\n ScryptedDeviceType[\"AirPurifier\"] = \"AirPurifier\";\n ScryptedDeviceType[\"Internet\"] = \"Internet\";\n ScryptedDeviceType[\"Network\"] = \"Network\";\n ScryptedDeviceType[\"Bridge\"] = \"Bridge\";\n ScryptedDeviceType[\"Unknown\"] = \"Unknown\";\n})(ScryptedDeviceType || (exports.ScryptedDeviceType = ScryptedDeviceType = {}));\nvar HumidityMode;\n(function (HumidityMode) {\n HumidityMode[\"Humidify\"] = \"Humidify\";\n HumidityMode[\"Dehumidify\"] = \"Dehumidify\";\n HumidityMode[\"Auto\"] = \"Auto\";\n HumidityMode[\"Off\"] = \"Off\";\n})(HumidityMode || (exports.HumidityMode = HumidityMode = {}));\nvar FanMode;\n(function (FanMode) {\n FanMode[\"Auto\"] = \"Auto\";\n FanMode[\"Manual\"] = \"Manual\";\n})(FanMode || (exports.FanMode = FanMode = {}));\nvar TemperatureUnit;\n(function (TemperatureUnit) {\n TemperatureUnit[\"C\"] = \"C\";\n TemperatureUnit[\"F\"] = \"F\";\n})(TemperatureUnit || (exports.TemperatureUnit = TemperatureUnit = {}));\nvar ThermostatMode;\n(function (ThermostatMode) {\n ThermostatMode[\"Off\"] = \"Off\";\n ThermostatMode[\"Cool\"] = \"Cool\";\n ThermostatMode[\"Heat\"] = \"Heat\";\n ThermostatMode[\"HeatCool\"] = \"HeatCool\";\n ThermostatMode[\"Auto\"] = \"Auto\";\n ThermostatMode[\"FanOnly\"] = \"FanOnly\";\n ThermostatMode[\"Purifier\"] = \"Purifier\";\n ThermostatMode[\"Eco\"] = \"Eco\";\n ThermostatMode[\"Dry\"] = \"Dry\";\n ThermostatMode[\"On\"] = \"On\";\n})(ThermostatMode || (exports.ThermostatMode = ThermostatMode = {}));\nvar PanTiltZoomMovement;\n(function (PanTiltZoomMovement) {\n PanTiltZoomMovement[\"Absolute\"] = \"Absolute\";\n PanTiltZoomMovement[\"Relative\"] = \"Relative\";\n PanTiltZoomMovement[\"Continuous\"] = \"Continuous\";\n PanTiltZoomMovement[\"Preset\"] = \"Preset\";\n PanTiltZoomMovement[\"Home\"] = \"Home\";\n})(PanTiltZoomMovement || (exports.PanTiltZoomMovement = PanTiltZoomMovement = {}));\nvar LockState;\n(function (LockState) {\n LockState[\"Locked\"] = \"Locked\";\n LockState[\"Unlocked\"] = \"Unlocked\";\n LockState[\"Jammed\"] = \"Jammed\";\n})(LockState || (exports.LockState = LockState = {}));\nvar ChargeState;\n(function (ChargeState) {\n ChargeState[\"Trickle\"] = \"trickle\";\n ChargeState[\"Charging\"] = \"charging\";\n ChargeState[\"NotCharging\"] = \"not-charging\";\n})(ChargeState || (exports.ChargeState = ChargeState = {}));\nvar AirPurifierStatus;\n(function (AirPurifierStatus) {\n AirPurifierStatus[\"Inactive\"] = \"Inactive\";\n AirPurifierStatus[\"Idle\"] = \"Idle\";\n AirPurifierStatus[\"Active\"] = \"Active\";\n AirPurifierStatus[\"ActiveNightMode\"] = \"ActiveNightMode\";\n})(AirPurifierStatus || (exports.AirPurifierStatus = AirPurifierStatus = {}));\nvar AirPurifierMode;\n(function (AirPurifierMode) {\n AirPurifierMode[\"Manual\"] = \"Manual\";\n AirPurifierMode[\"Automatic\"] = \"Automatic\";\n})(AirPurifierMode || (exports.AirPurifierMode = AirPurifierMode = {}));\nvar AirQuality;\n(function (AirQuality) {\n AirQuality[\"Unknown\"] = \"Unknown\";\n AirQuality[\"Excellent\"] = \"Excellent\";\n AirQuality[\"Good\"] = \"Good\";\n AirQuality[\"Fair\"] = \"Fair\";\n AirQuality[\"Inferior\"] = \"Inferior\";\n AirQuality[\"Poor\"] = \"Poor\";\n})(AirQuality || (exports.AirQuality = AirQuality = {}));\nvar SecuritySystemMode;\n(function (SecuritySystemMode) {\n SecuritySystemMode[\"Disarmed\"] = \"Disarmed\";\n SecuritySystemMode[\"HomeArmed\"] = \"HomeArmed\";\n SecuritySystemMode[\"AwayArmed\"] = \"AwayArmed\";\n SecuritySystemMode[\"NightArmed\"] = \"NightArmed\";\n})(SecuritySystemMode || (exports.SecuritySystemMode = SecuritySystemMode = {}));\nvar SecuritySystemObstruction;\n(function (SecuritySystemObstruction) {\n SecuritySystemObstruction[\"Sensor\"] = \"Sensor\";\n SecuritySystemObstruction[\"Occupied\"] = \"Occupied\";\n SecuritySystemObstruction[\"Time\"] = \"Time\";\n SecuritySystemObstruction[\"Error\"] = \"Error\";\n})(SecuritySystemObstruction || (exports.SecuritySystemObstruction = SecuritySystemObstruction = {}));\nvar MediaPlayerState;\n(function (MediaPlayerState) {\n MediaPlayerState[\"Idle\"] = \"Idle\";\n MediaPlayerState[\"Playing\"] = \"Playing\";\n MediaPlayerState[\"Paused\"] = \"Paused\";\n MediaPlayerState[\"Buffering\"] = \"Buffering\";\n})(MediaPlayerState || (exports.MediaPlayerState = MediaPlayerState = {}));\nvar ScryptedInterface;\n(function (ScryptedInterface) {\n ScryptedInterface[\"ScryptedDevice\"] = \"ScryptedDevice\";\n ScryptedInterface[\"ScryptedPlugin\"] = \"ScryptedPlugin\";\n ScryptedInterface[\"ScryptedPluginRuntime\"] = \"ScryptedPluginRuntime\";\n ScryptedInterface[\"OnOff\"] = \"OnOff\";\n ScryptedInterface[\"Brightness\"] = \"Brightness\";\n ScryptedInterface[\"ColorSettingTemperature\"] = \"ColorSettingTemperature\";\n ScryptedInterface[\"ColorSettingRgb\"] = \"ColorSettingRgb\";\n ScryptedInterface[\"ColorSettingHsv\"] = \"ColorSettingHsv\";\n ScryptedInterface[\"Buttons\"] = \"Buttons\";\n ScryptedInterface[\"PressButtons\"] = \"PressButtons\";\n ScryptedInterface[\"Sensors\"] = \"Sensors\";\n ScryptedInterface[\"Notifier\"] = \"Notifier\";\n ScryptedInterface[\"StartStop\"] = \"StartStop\";\n ScryptedInterface[\"Pause\"] = \"Pause\";\n ScryptedInterface[\"Dock\"] = \"Dock\";\n ScryptedInterface[\"TemperatureSetting\"] = \"TemperatureSetting\";\n ScryptedInterface[\"Thermometer\"] = \"Thermometer\";\n ScryptedInterface[\"HumiditySensor\"] = \"HumiditySensor\";\n ScryptedInterface[\"Camera\"] = \"Camera\";\n ScryptedInterface[\"Microphone\"] = \"Microphone\";\n ScryptedInterface[\"AudioVolumeControl\"] = \"AudioVolumeControl\";\n ScryptedInterface[\"Display\"] = \"Display\";\n ScryptedInterface[\"VideoCamera\"] = \"VideoCamera\";\n ScryptedInterface[\"VideoCameraMask\"] = \"VideoCameraMask\";\n ScryptedInterface[\"VideoTextOverlays\"] = \"VideoTextOverlays\";\n ScryptedInterface[\"VideoRecorder\"] = \"VideoRecorder\";\n ScryptedInterface[\"VideoRecorderManagement\"] = \"VideoRecorderManagement\";\n ScryptedInterface[\"PanTiltZoom\"] = \"PanTiltZoom\";\n ScryptedInterface[\"EventRecorder\"] = \"EventRecorder\";\n ScryptedInterface[\"VideoClips\"] = \"VideoClips\";\n ScryptedInterface[\"VideoCameraConfiguration\"] = \"VideoCameraConfiguration\";\n ScryptedInterface[\"Intercom\"] = \"Intercom\";\n ScryptedInterface[\"Lock\"] = \"Lock\";\n ScryptedInterface[\"PasswordStore\"] = \"PasswordStore\";\n ScryptedInterface[\"Scene\"] = \"Scene\";\n ScryptedInterface[\"Entry\"] = \"Entry\";\n ScryptedInterface[\"EntrySensor\"] = \"EntrySensor\";\n ScryptedInterface[\"DeviceProvider\"] = \"DeviceProvider\";\n ScryptedInterface[\"DeviceDiscovery\"] = \"DeviceDiscovery\";\n ScryptedInterface[\"DeviceCreator\"] = \"DeviceCreator\";\n ScryptedInterface[\"Battery\"] = \"Battery\";\n ScryptedInterface[\"Charger\"] = \"Charger\";\n ScryptedInterface[\"Reboot\"] = \"Reboot\";\n ScryptedInterface[\"Refresh\"] = \"Refresh\";\n ScryptedInterface[\"MediaPlayer\"] = \"MediaPlayer\";\n ScryptedInterface[\"Online\"] = \"Online\";\n ScryptedInterface[\"BufferConverter\"] = \"BufferConverter\";\n ScryptedInterface[\"MediaConverter\"] = \"MediaConverter\";\n ScryptedInterface[\"Settings\"] = \"Settings\";\n ScryptedInterface[\"BinarySensor\"] = \"BinarySensor\";\n ScryptedInterface[\"TamperSensor\"] = \"TamperSensor\";\n ScryptedInterface[\"Sleep\"] = \"Sleep\";\n ScryptedInterface[\"PowerSensor\"] = \"PowerSensor\";\n ScryptedInterface[\"AudioSensor\"] = \"AudioSensor\";\n ScryptedInterface[\"MotionSensor\"] = \"MotionSensor\";\n ScryptedInterface[\"AmbientLightSensor\"] = \"AmbientLightSensor\";\n ScryptedInterface[\"OccupancySensor\"] = \"OccupancySensor\";\n ScryptedInterface[\"FloodSensor\"] = \"FloodSensor\";\n ScryptedInterface[\"UltravioletSensor\"] = \"UltravioletSensor\";\n ScryptedInterface[\"LuminanceSensor\"] = \"LuminanceSensor\";\n ScryptedInterface[\"PositionSensor\"] = \"PositionSensor\";\n ScryptedInterface[\"SecuritySystem\"] = \"SecuritySystem\";\n ScryptedInterface[\"PM10Sensor\"] = \"PM10Sensor\";\n ScryptedInterface[\"PM25Sensor\"] = \"PM25Sensor\";\n ScryptedInterface[\"VOCSensor\"] = \"VOCSensor\";\n ScryptedInterface[\"NOXSensor\"] = \"NOXSensor\";\n ScryptedInterface[\"CO2Sensor\"] = \"CO2Sensor\";\n ScryptedInterface[\"AirQualitySensor\"] = \"AirQualitySensor\";\n ScryptedInterface[\"AirPurifier\"] = \"AirPurifier\";\n ScryptedInterface[\"FilterMaintenance\"] = \"FilterMaintenance\";\n ScryptedInterface[\"Readme\"] = \"Readme\";\n ScryptedInterface[\"OauthClient\"] = \"OauthClient\";\n ScryptedInterface[\"MixinProvider\"] = \"MixinProvider\";\n ScryptedInterface[\"HttpRequestHandler\"] = \"HttpRequestHandler\";\n ScryptedInterface[\"EngineIOHandler\"] = \"EngineIOHandler\";\n ScryptedInterface[\"PushHandler\"] = \"PushHandler\";\n ScryptedInterface[\"Program\"] = \"Program\";\n ScryptedInterface[\"Scriptable\"] = \"Scriptable\";\n ScryptedInterface[\"ClusterForkInterface\"] = \"ClusterForkInterface\";\n ScryptedInterface[\"ObjectTracker\"] = \"ObjectTracker\";\n ScryptedInterface[\"ObjectDetector\"] = \"ObjectDetector\";\n ScryptedInterface[\"ObjectDetection\"] = \"ObjectDetection\";\n ScryptedInterface[\"ObjectDetectionPreview\"] = \"ObjectDetectionPreview\";\n ScryptedInterface[\"ObjectDetectionGenerator\"] = \"ObjectDetectionGenerator\";\n ScryptedInterface[\"HumiditySetting\"] = \"HumiditySetting\";\n ScryptedInterface[\"Fan\"] = \"Fan\";\n ScryptedInterface[\"RTCSignalingChannel\"] = \"RTCSignalingChannel\";\n ScryptedInterface[\"RTCSignalingClient\"] = \"RTCSignalingClient\";\n ScryptedInterface[\"LauncherApplication\"] = \"LauncherApplication\";\n ScryptedInterface[\"ScryptedUser\"] = \"ScryptedUser\";\n ScryptedInterface[\"VideoFrameGenerator\"] = \"VideoFrameGenerator\";\n ScryptedInterface[\"StreamService\"] = \"StreamService\";\n ScryptedInterface[\"TTY\"] = \"TTY\";\n ScryptedInterface[\"TTYSettings\"] = \"TTYSettings\";\n ScryptedInterface[\"ScryptedSystemDevice\"] = \"ScryptedSystemDevice\";\n ScryptedInterface[\"ScryptedDeviceCreator\"] = \"ScryptedDeviceCreator\";\n ScryptedInterface[\"ScryptedSettings\"] = \"ScryptedSettings\";\n})(ScryptedInterface || (exports.ScryptedInterface = ScryptedInterface = {}));\nvar ScryptedMimeTypes;\n(function (ScryptedMimeTypes) {\n ScryptedMimeTypes[\"Url\"] = \"text/x-uri\";\n ScryptedMimeTypes[\"InsecureLocalUrl\"] = \"text/x-insecure-local-uri\";\n ScryptedMimeTypes[\"LocalUrl\"] = \"text/x-local-uri\";\n ScryptedMimeTypes[\"ServerId\"] = \"text/x-server-id\";\n ScryptedMimeTypes[\"PushEndpoint\"] = \"text/x-push-endpoint\";\n ScryptedMimeTypes[\"SchemePrefix\"] = \"x-scrypted/x-scrypted-scheme-\";\n ScryptedMimeTypes[\"MediaStreamUrl\"] = \"text/x-media-url\";\n ScryptedMimeTypes[\"MediaObject\"] = \"x-scrypted/x-scrypted-media-object\";\n ScryptedMimeTypes[\"RequestMediaObject\"] = \"x-scrypted/x-scrypted-request-media-object\";\n ScryptedMimeTypes[\"RequestMediaStream\"] = \"x-scrypted/x-scrypted-request-stream\";\n ScryptedMimeTypes[\"MediaStreamFeedback\"] = \"x-scrypted/x-media-stream-feedback\";\n ScryptedMimeTypes[\"FFmpegInput\"] = \"x-scrypted/x-ffmpeg-input\";\n ScryptedMimeTypes[\"FFmpegTranscodeStream\"] = \"x-scrypted/x-ffmpeg-transcode-stream\";\n ScryptedMimeTypes[\"RTCSignalingChannel\"] = \"x-scrypted/x-scrypted-rtc-signaling-channel\";\n ScryptedMimeTypes[\"RTCSignalingSession\"] = \"x-scrypted/x-scrypted-rtc-signaling-session\";\n ScryptedMimeTypes[\"RTCConnectionManagement\"] = \"x-scrypted/x-scrypted-rtc-connection-management\";\n ScryptedMimeTypes[\"Image\"] = \"x-scrypted/x-scrypted-image\";\n})(ScryptedMimeTypes || (exports.ScryptedMimeTypes = ScryptedMimeTypes = {}));\n//# sourceMappingURL=index.js.map","import sdk, {\n ScryptedDeviceBase,\n Settings,\n Setting,\n HttpRequestHandler,\n HttpRequest,\n HttpResponse,\n ScryptedInterface,\n ScryptedDeviceType,\n ObjectsDetected,\n ObjectDetector,\n} from '@scrypted/sdk';\n\nconst { systemManager, deviceManager, mediaManager } = sdk;\n\n// ─── Constants ────────────────────────────────────────────────────────────────\n\nconst LABELS = ['person', 'animal', 'face', 'vehicle', 'plate', 'package', 'discard'] as const;\ntype Label = typeof LABELS[number];\n\nconst CAPTURE_CLASSES = new Set(['person', 'cat', 'dog', 'animal', 'bird', 'face', 'vehicle', 'car', 'truck', 'bus', 'motorcycle', 'bicycle', 'plate', 'package']);\n\nconst RATE_OPTIONS = ['disabled', '1 per minute', '1 per 10 seconds', 'every detection'] as const;\ntype RateOption = typeof RATE_OPTIONS[number];\n\nconst RATE_MS: Record<RateOption, number> = {\n 'disabled': Infinity,\n '1 per minute': 60_000,\n '1 per 10 seconds': 10_000,\n 'every detection': 0,\n};\n\nconst MAX_CAPTURES = 2000;\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\ninterface CaptureRecord {\n id: string;\n cameraId: string;\n cameraName: string;\n timestamp: number;\n detectedClass: string;\n score: number;\n boundingBox: number[]; // [x, y, w, h] in pixels\n inputDimensions: number[]; // [width, height]\n detectionId?: string;\n label?: Label; // set after review\n reviewed: boolean;\n}\n\n// ─── Plugin ───────────────────────────────────────────────────────────────────\n\nclass DetectionTrainer extends ScryptedDeviceBase implements Settings, HttpRequestHandler {\n // Map<cameraId, lastCaptureTimestamp>\n private lastCapture = new Map<string, number>();\n // Map<captureId, CaptureRecord>\n private captures = new Map<string, CaptureRecord>();\n // Map<captureId, jpegBuffer>\n private images = new Map<string, Buffer>();\n // Active event listeners\n private listeners: (() => void)[] = [];\n\n constructor(nativeId?: string) {\n super(nativeId);\n this.loadState();\n this.registerListeners();\n }\n\n // ── Persistence ──────────────────────────────────────────────────────────\n\n private loadState() {\n try {\n const raw = this.storage.getItem('captures');\n if (raw) {\n const arr: CaptureRecord[] = JSON.parse(raw);\n for (const r of arr) this.captures.set(r.id, r);\n this.console.log(`Loaded ${this.captures.size} captures from storage.`);\n }\n } catch (e) {\n this.console.warn('Could not load captures from storage:', e);\n }\n // images are stored as individual items\n for (const [id] of this.captures) {\n const raw = this.storage.getItem(`img:${id}`);\n if (raw) this.images.set(id, Buffer.from(raw, 'base64'));\n }\n }\n\n private saveCaptures() {\n this.storage.setItem('captures', JSON.stringify([...this.captures.values()]));\n }\n\n private saveImage(id: string, buf: Buffer) {\n this.storage.setItem(`img:${id}`, buf.toString('base64'));\n }\n\n private deleteCapture(id: string) {\n const old = this.storage.getItem(`img:${id}`);\n if (old) this.storage.removeItem(`img:${id}`);\n this.captures.delete(id);\n this.images.delete(id);\n this.saveCaptures();\n }\n\n // ── Settings ─────────────────────────────────────────────────────────────\n\n async getSettings(): Promise<Setting[]> {\n const cameras = Object.keys(systemManager.getSystemState())\n .map(id => systemManager.getDeviceById(id))\n .filter(d => d &&\n (d.type === ScryptedDeviceType.Camera || d.type === ScryptedDeviceType.Doorbell) &&\n d.interfaces?.includes(ScryptedInterface.ObjectDetector)\n );\n\n const settings: Setting[] = [\n {\n key: 'info',\n title: 'Detection Trainer',\n description: `${this.captures.size} captures stored (${[...this.captures.values()].filter(c => !c.reviewed).length} pending review, ${[...this.captures.values()].filter(c => c.reviewed && c.label !== 'discard').length} labeled). Open the web UI to review and export.`,\n readonly: true,\n value: '',\n },\n {\n key: 'open_ui',\n title: 'Open Review UI',\n description: 'Open the detection review and labeling interface.',\n type: 'button',\n },\n ];\n\n for (const cam of cameras) {\n const key = `rate:${cam.id}`;\n settings.push({\n key,\n title: cam.name,\n group: 'Capture Rate per Camera',\n description: 'How often to capture detections from this camera.',\n value: this.storage.getItem(key) || '1 per minute',\n choices: [...RATE_OPTIONS],\n });\n }\n\n return settings;\n }\n\n async putSetting(key: string, value: string) {\n if (key === 'open_ui') return;\n this.storage.setItem(key, value);\n if (key.startsWith('rate:')) {\n // Re-register listeners when rates change\n this.registerListeners();\n }\n }\n\n // ── Listeners ─────────────────────────────────────────────────────────────\n\n private registerListeners() {\n // Remove old listeners\n for (const remove of this.listeners) remove();\n this.listeners = [];\n\n const cameras = Object.keys(systemManager.getSystemState())\n .map(id => systemManager.getDeviceById(id))\n .filter(d => d &&\n (d.type === ScryptedDeviceType.Camera || d.type === ScryptedDeviceType.Doorbell) &&\n d.interfaces?.includes(ScryptedInterface.ObjectDetector)\n );\n\n for (const cam of cameras) {\n const rateKey = `rate:${cam.id}`;\n const rateLabel = (this.storage.getItem(rateKey) || '1 per minute') as RateOption;\n if (rateLabel === 'disabled') continue;\n\n const listener = cam.listen(ScryptedInterface.ObjectDetector, async (source, details, data) => {\n await this.onDetection(cam.id, cam.name, data as ObjectsDetected, RATE_MS[rateLabel]);\n });\n this.listeners.push(() => listener.removeListener());\n }\n\n this.console.log(`Listening to ${this.listeners.length} camera(s).`);\n }\n\n // ── Detection Handler ─────────────────────────────────────────────────────\n\n private async onDetection(cameraId: string, cameraName: string, data: ObjectsDetected, rateLimitMs: number) {\n if (!data?.detections?.length || !data.inputDimensions) return;\n\n // Rate limit per camera\n const now = Date.now();\n const last = this.lastCapture.get(cameraId) || 0;\n if (now - last < rateLimitMs) return;\n\n // Filter to target classes\n const targets = data.detections.filter(d =>\n d.className && CAPTURE_CLASSES.has(d.className.toLowerCase()) && d.boundingBox\n );\n if (!targets.length) return;\n\n // Pick the highest-confidence target detection\n const best = targets.sort((a, b) => (b.score || 0) - (a.score || 0))[0];\n\n // Enforce max storage\n if (this.captures.size >= MAX_CAPTURES) {\n // Evict oldest unreviewed capture\n const oldest = [...this.captures.values()]\n .filter(c => !c.reviewed)\n .sort((a, b) => a.timestamp - b.timestamp)[0];\n if (oldest) this.deleteCapture(oldest.id);\n else return; // All reviewed, don't evict labeled data\n }\n\n this.lastCapture.set(cameraId, now);\n\n // Try to get the detection image\n let jpeg: Buffer | undefined;\n try {\n if (data.detectionId) {\n const cam = systemManager.getDeviceById(cameraId) as unknown as ObjectDetector;\n const mo = await cam.getDetectionInput(data.detectionId);\n jpeg = await mediaManager.convertMediaObjectToBuffer(mo, 'image/jpeg');\n }\n } catch (e) {\n this.console.warn(`Could not get detection image for ${cameraName}:`, e);\n }\n\n if (!jpeg) return; // Skip if no image\n\n const id = `${now}-${Math.random().toString(36).slice(2, 8)}`;\n const record: CaptureRecord = {\n id,\n cameraId,\n cameraName,\n timestamp: now,\n detectedClass: best.className!,\n score: best.score || 0,\n boundingBox: best.boundingBox as number[],\n inputDimensions: data.inputDimensions as number[],\n detectionId: data.detectionId,\n reviewed: false,\n };\n\n this.captures.set(id, record);\n this.images.set(id, jpeg);\n this.saveImage(id, jpeg);\n this.saveCaptures();\n\n this.console.log(`Captured ${best.className} (${Math.round((best.score || 0) * 100)}%) from ${cameraName} [${this.captures.size} total]`);\n }\n\n // ── HTTP Handler ──────────────────────────────────────────────────────────\n\n async onRequest(request: HttpRequest, response: HttpResponse) {\n const url = new URL(request.url, 'http://localhost');\n const path = url.pathname.replace(request.rootPath, '');\n\n // Serve image\n if (path.startsWith('/img/')) {\n const id = path.slice(5);\n const img = this.images.get(id);\n if (!img) return response.send('Not found', { code: 404 });\n return response.send(img, { headers: { 'Content-Type': 'image/jpeg', 'Cache-Control': 'max-age=3600' } });\n }\n\n // API: label a capture\n if (path === '/api/label' && request.body) {\n const rawBody = request.body as any;\n const body = JSON.parse(typeof rawBody === 'string' ? rawBody : Buffer.isBuffer(rawBody) ? rawBody.toString() : String(rawBody));\n const record = this.captures.get(body.id);\n if (!record) return response.send('Not found', { code: 404 });\n record.label = body.label as Label;\n record.reviewed = true;\n if (body.label === 'discard') {\n this.deleteCapture(body.id);\n } else {\n this.captures.set(body.id, record);\n this.saveCaptures();\n }\n return response.send(JSON.stringify({ ok: true }), { headers: { 'Content-Type': 'application/json' } });\n }\n\n // API: get pending captures\n if (path === '/api/pending') {\n const pending = [...this.captures.values()]\n .filter(c => !c.reviewed)\n .sort((a, b) => b.timestamp - a.timestamp)\n .slice(0, 50);\n return response.send(JSON.stringify(pending), { headers: { 'Content-Type': 'application/json' } });\n }\n\n // API: stats\n if (path === '/api/stats') {\n const all = [...this.captures.values()];\n const stats = {\n total: all.length,\n pending: all.filter(c => !c.reviewed).length,\n labeled: all.filter(c => c.reviewed && c.label !== 'discard').length,\n byLabel: {} as Record<string, number>,\n byCamera: {} as Record<string, number>,\n byDetectedClass: {} as Record<string, number>,\n };\n for (const r of all) {\n if (r.label) stats.byLabel[r.label] = (stats.byLabel[r.label] || 0) + 1;\n stats.byCamera[r.cameraName] = (stats.byCamera[r.cameraName] || 0) + 1;\n stats.byDetectedClass[r.detectedClass] = (stats.byDetectedClass[r.detectedClass] || 0) + 1;\n }\n return response.send(JSON.stringify(stats), { headers: { 'Content-Type': 'application/json' } });\n }\n\n // API: export YOLO dataset\n if (path === '/api/export') {\n const labeled = [...this.captures.values()].filter(c => c.reviewed && c.label && c.label !== 'discard');\n if (!labeled.length) return response.send(JSON.stringify({ error: 'No labeled data yet' }), { headers: { 'Content-Type': 'application/json' }, code: 400 });\n\n const classMap: Record<Label, number> = {\n person: 0, animal: 1, face: 2, vehicle: 3, plate: 4, package: 5, discard: -1,\n };\n\n // Build a simple tarball-like structure as JSON for download\n const dataset: { filename: string; content: string; encoding: string }[] = [];\n\n for (const record of labeled) {\n const img = this.images.get(record.id);\n if (!img) continue;\n\n const fname = `${record.id}`;\n dataset.push({ filename: `images/${fname}.jpg`, content: img.toString('base64'), encoding: 'base64' });\n\n const [x, y, w, h] = record.boundingBox;\n const [imgW, imgH] = record.inputDimensions;\n const cx = (x + w / 2) / imgW;\n const cy = (y + h / 2) / imgH;\n const nw = w / imgW;\n const nh = h / imgH;\n const classId = classMap[record.label!];\n const labelLine = `${classId} ${cx.toFixed(6)} ${cy.toFixed(6)} ${nw.toFixed(6)} ${nh.toFixed(6)}\\n`;\n dataset.push({ filename: `labels/${fname}.txt`, content: labelLine, encoding: 'utf8' });\n }\n\n const yaml = [\n 'path: dataset',\n 'train: images',\n 'val: images',\n '',\n 'nc: 6',\n \"names: ['person', 'animal', 'face', 'vehicle', 'plate', 'package']\",\n '',\n '# Generated by Scrypted Detection Trainer',\n `# ${labeled.length} labeled samples`,\n ].join('\\n');\n dataset.push({ filename: 'data.yaml', content: yaml, encoding: 'utf8' });\n\n return response.send(JSON.stringify({ files: dataset, count: labeled.length }), {\n headers: { 'Content-Type': 'application/json' },\n });\n }\n\n // Serve Web UI\n if (path === '/' || path === '' || path === '/index.html') {\n return response.send(this.renderUI(), { headers: { 'Content-Type': 'text/html' } });\n }\n\n response.send('Not found', { code: 404 });\n }\n\n // ── Web UI ────────────────────────────────────────────────────────────────\n\n private renderUI(): string {\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<title>Detection Trainer</title>\n<style>\n * { box-sizing: border-box; margin: 0; padding: 0; }\n body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background: #0f0f0f; color: #e8e8e8; min-height: 100vh; }\n header { background: #1a1a1a; border-bottom: 1px solid #333; padding: 16px 24px; display: flex; align-items: center; justify-content: space-between; }\n header h1 { font-size: 18px; font-weight: 600; color: #fff; }\n .stats { display: flex; gap: 20px; font-size: 13px; color: #aaa; }\n .stat span { color: #fff; font-weight: 600; }\n .container { max-width: 1000px; margin: 0 auto; padding: 24px; }\n .card { background: #1a1a1a; border: 1px solid #2a2a2a; border-radius: 12px; overflow: hidden; margin-bottom: 24px; }\n .card-header { padding: 16px 20px; border-bottom: 1px solid #2a2a2a; display: flex; align-items: center; justify-content: space-between; }\n .card-header h2 { font-size: 15px; font-weight: 600; }\n .badge { background: #333; color: #aaa; font-size: 12px; padding: 2px 8px; border-radius: 20px; }\n .badge.orange { background: #3d2a00; color: #f90; }\n .badge.green { background: #0d2d0d; color: #4c4; }\n\n /* Detection card */\n .detection { display: grid; grid-template-columns: 200px 1fr; gap: 0; border-bottom: 1px solid #222; }\n .detection:last-child { border-bottom: none; }\n .detection-img { position: relative; background: #111; display: flex; align-items: center; justify-content: center; min-height: 150px; }\n .detection-img img { width: 100%; height: 150px; object-fit: cover; display: block; }\n .detection-class { position: absolute; top: 6px; left: 6px; background: rgba(0,0,0,0.7); color: #fff; font-size: 11px; padding: 2px 6px; border-radius: 4px; }\n .detection-info { padding: 14px 16px; display: flex; flex-direction: column; gap: 10px; }\n .detection-meta { font-size: 12px; color: #888; display: flex; flex-wrap: wrap; gap: 10px; }\n .detection-meta strong { color: #ccc; }\n .label-buttons { display: flex; flex-wrap: wrap; gap: 8px; }\n .label-btn { padding: 7px 14px; border-radius: 8px; border: 1px solid #444; background: #222; color: #ccc; cursor: pointer; font-size: 13px; transition: all .15s; }\n .label-btn:hover { border-color: #666; background: #2a2a2a; color: #fff; }\n .label-btn.person { border-color: #2a6; color: #4d9; }\n .label-btn.person:hover { background: #0d2a1a; }\n .label-btn.animal { border-color: #a63; color: #d85; }\n .label-btn.animal:hover { background: #2a1a0d; }\n .label-btn.face { border-color: #49c; color: #6be; }\n .label-btn.face:hover { background: #0d1a2a; }\n .label-btn.vehicle { border-color: #76b; color: #99d; }\n .label-btn.vehicle:hover { background: #1a1a2a; }\n .label-btn.discard { border-color: #622; color: #a44; }\n .label-btn.discard:hover { background: #2a0d0d; }\n .detection.labeled { opacity: 0.4; pointer-events: none; }\n .labeled-tag { font-size: 11px; color: #4d9; background: #0d2a1a; border: 1px solid #2a6; padding: 2px 8px; border-radius: 4px; }\n\n /* Empty state */\n .empty { padding: 48px; text-align: center; color: #555; }\n .empty .icon { font-size: 48px; margin-bottom: 12px; }\n\n /* Export section */\n .export-btn { padding: 10px 20px; background: #1a4d8a; border: none; border-radius: 8px; color: #fff; cursor: pointer; font-size: 14px; font-weight: 500; }\n .export-btn:hover { background: #1e5ca0; }\n .export-btn:disabled { background: #333; color: #666; cursor: not-allowed; }\n .export-info { font-size: 13px; color: #888; padding: 12px 20px; }\n\n /* Progress bar */\n .progress { height: 4px; background: #222; border-radius: 2px; overflow: hidden; margin-top: 8px; }\n .progress-bar { height: 100%; background: #1a6; border-radius: 2px; transition: width .3s; }\n\n .toast { position: fixed; bottom: 24px; right: 24px; background: #1a3; color: #fff; padding: 10px 18px; border-radius: 8px; font-size: 13px; opacity: 0; transition: opacity .3s; pointer-events: none; }\n .toast.show { opacity: 1; }\n\n .tab-bar { display: flex; gap: 2px; padding: 12px 20px 0; border-bottom: 1px solid #2a2a2a; }\n .tab { padding: 8px 14px; font-size: 13px; color: #888; cursor: pointer; border-bottom: 2px solid transparent; margin-bottom: -1px; }\n .tab.active { color: #fff; border-bottom-color: #4a9; }\n .tab-content { padding: 20px; }\n .tab-panel { display: none; }\n .tab-panel.active { display: block; }\n\n .breakdown-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 10px; }\n .breakdown-item { background: #222; border-radius: 8px; padding: 12px; }\n .breakdown-item .label { font-size: 12px; color: #888; margin-bottom: 4px; }\n .breakdown-item .value { font-size: 20px; font-weight: 600; color: #fff; }\n</style>\n</head>\n<body>\n<header>\n <h1>🎯 Detection Trainer</h1>\n <div class=\"stats\">\n <div>Pending <span id=\"stat-pending\">—</span></div>\n <div>Labeled <span id=\"stat-labeled\">—</span></div>\n <div>Total <span id=\"stat-total\">—</span></div>\n </div>\n</header>\n<div class=\"container\">\n\n <div class=\"card\">\n <div class=\"tab-bar\">\n <div class=\"tab active\" onclick=\"showTab('review')\">Review</div>\n <div class=\"tab\" onclick=\"showTab('stats')\">Stats</div>\n <div class=\"tab\" onclick=\"showTab('export')\">Export Dataset</div>\n </div>\n\n <!-- Review tab -->\n <div class=\"tab-panel active\" id=\"tab-review\">\n <div id=\"detections-list\"></div>\n </div>\n\n <!-- Stats tab -->\n <div class=\"tab-panel\" id=\"tab-stats\">\n <div class=\"tab-content\">\n <p style=\"font-size:13px;color:#888;margin-bottom:16px;\">Breakdown of captured and labeled detections.</p>\n <h3 style=\"font-size:13px;color:#aaa;margin-bottom:10px;\">By Detected Class (what the model said)</h3>\n <div class=\"breakdown-grid\" id=\"stats-detected\"></div>\n <h3 style=\"font-size:13px;color:#aaa;margin:20px 0 10px;\">By Corrected Label (what you said)</h3>\n <div class=\"breakdown-grid\" id=\"stats-label\"></div>\n <h3 style=\"font-size:13px;color:#aaa;margin:20px 0 10px;\">By Camera</h3>\n <div class=\"breakdown-grid\" id=\"stats-camera\"></div>\n </div>\n </div>\n\n <!-- Export tab -->\n <div class=\"tab-panel\" id=\"tab-export\">\n <div class=\"tab-content\">\n <p style=\"font-size:13px;color:#888;margin-bottom:16px;\">\n Exports a YOLO-format dataset (images + labels + data.yaml) as a downloadable bundle.\n Only labeled detections are included. Review more detections first to build a larger dataset.\n </p>\n <div id=\"export-stats\" class=\"export-info\">Loading…</div>\n <div style=\"display:flex;gap:12px;align-items:center;margin-top:12px;\">\n <button class=\"export-btn\" id=\"export-btn\" onclick=\"exportDataset()\">Download Dataset</button>\n <span id=\"export-status\" style=\"font-size:13px;color:#888;\"></span>\n </div>\n </div>\n </div>\n </div>\n</div>\n\n<div class=\"toast\" id=\"toast\"></div>\n\n<script>\nconst BASE = location.pathname.replace(/\\\\/$/, '');\nlet pending = [];\nlet labeledCount = 0;\n\nfunction showTab(name) {\n document.querySelectorAll('.tab').forEach((t, i) => {\n const names = ['review', 'stats', 'export'];\n t.classList.toggle('active', names[i] === name);\n });\n document.querySelectorAll('.tab-panel').forEach(p => p.classList.remove('active'));\n document.getElementById('tab-' + name).classList.add('active');\n if (name === 'stats') loadStats();\n if (name === 'export') loadExportInfo();\n}\n\nfunction toast(msg, color='#1a3') {\n const el = document.getElementById('toast');\n el.textContent = msg;\n el.style.background = color;\n el.classList.add('show');\n setTimeout(() => el.classList.remove('show'), 2500);\n}\n\nasync function loadPending() {\n const res = await fetch(BASE + '/api/pending');\n pending = await res.json();\n\n const statsRes = await fetch(BASE + '/api/stats');\n const stats = await statsRes.json();\n document.getElementById('stat-pending').textContent = stats.pending;\n document.getElementById('stat-labeled').textContent = stats.labeled;\n document.getElementById('stat-total').textContent = stats.total;\n\n const list = document.getElementById('detections-list');\n if (!pending.length) {\n list.innerHTML = '<div class=\"empty\"><div class=\"icon\">✅</div><div>No pending detections to review.<br><span style=\"font-size:12px;color:#444\">Captures will appear here as cameras detect objects.</span></div></div>';\n return;\n }\n\n list.innerHTML = pending.map(r => {\n const date = new Date(r.timestamp).toLocaleString();\n const score = Math.round(r.score * 100);\n return \\`\n <div class=\"detection\" id=\"det-\\${r.id}\">\n <div class=\"detection-img\">\n <img src=\"\\${BASE}/img/\\${r.id}\" alt=\"\\${r.detectedClass}\" loading=\"lazy\" onerror=\"this.parentElement.innerHTML='<div style=\\\\\"padding:20px;color:#555;font-size:12px;text-align:center\\\\\">Image unavailable</div>'\">\n <div class=\"detection-class\">\\${r.detectedClass} \\${score}%</div>\n </div>\n <div class=\"detection-info\">\n <div class=\"detection-meta\">\n <div><strong>\\${r.cameraName}</strong></div>\n <div>\\${date}</div>\n <div>Box: \\${r.boundingBox.map(v => Math.round(v)).join(', ')}</div>\n </div>\n <div style=\"font-size:12px;color:#888;\">What is this actually?</div>\n <div class=\"label-buttons\">\n <button class=\"label-btn person\" onclick=\"label('\\${r.id}', 'person')\">👤 Person</button>\n <button class=\"label-btn animal\" onclick=\"label('\\${r.id}', 'animal')\">🐾 Animal</button>\n <button class=\"label-btn face\" onclick=\"label('\\${r.id}', 'face')\">😀 Face</button>\n <button class=\"label-btn vehicle\" onclick=\"label('\\${r.id}', 'vehicle')\">🚗 Vehicle</button>\n <button class=\"label-btn\" onclick=\"label('\\${r.id}', 'plate')\">🔢 Plate</button>\n <button class=\"label-btn\" onclick=\"label('\\${r.id}', 'package')\">📦 Package</button>\n <button class=\"label-btn discard\" onclick=\"label('\\${r.id}', 'discard')\">🗑 Discard</button>\n </div>\n </div>\n </div>\\`;\n }).join('');\n}\n\nasync function label(id, labelVal) {\n const el = document.getElementById('det-' + id);\n if (el) {\n el.classList.add('labeled');\n const btns = el.querySelectorAll('.label-btn');\n btns.forEach(b => b.disabled = true);\n }\n await fetch(BASE + '/api/label', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ id, label: labelVal }),\n });\n toast(labelVal === 'discard' ? 'Discarded' : 'Labeled: ' + labelVal, labelVal === 'discard' ? '#633' : '#1a6');\n setTimeout(() => {\n if (el) el.remove();\n loadPending();\n }, 600);\n}\n\nasync function loadStats() {\n const res = await fetch(BASE + '/api/stats');\n const stats = await res.json();\n\n const renderBreakdown = (obj, container) => {\n const el = document.getElementById(container);\n const entries = Object.entries(obj).sort((a, b) => b[1] - a[1]);\n el.innerHTML = entries.length\n ? entries.map(([k, v]) => \\`<div class=\"breakdown-item\"><div class=\"label\">\\${k}</div><div class=\"value\">\\${v}</div></div>\\`).join('')\n : '<div style=\"color:#555;font-size:13px;\">None yet</div>';\n };\n\n renderBreakdown(stats.byDetectedClass, 'stats-detected');\n renderBreakdown(stats.byLabel, 'stats-label');\n renderBreakdown(stats.byCamera, 'stats-camera');\n}\n\nasync function loadExportInfo() {\n const res = await fetch(BASE + '/api/stats');\n const stats = await res.json();\n document.getElementById('export-stats').textContent =\n \\`\\${stats.labeled} labeled samples ready for export across \\${Object.keys(stats.byCamera).length} camera(s).\\`;\n}\n\nasync function exportDataset() {\n const btn = document.getElementById('export-btn');\n const status = document.getElementById('export-status');\n btn.disabled = true;\n status.textContent = 'Preparing…';\n\n try {\n const res = await fetch(BASE + '/api/export');\n if (!res.ok) { status.textContent = 'Nothing to export yet.'; btn.disabled = false; return; }\n const data = await res.json();\n if (data.error) { status.textContent = data.error; btn.disabled = false; return; }\n\n // Build a zip-like structure using a self-extracting HTML page\n // Actually just download as a JSON bundle that train.py can consume\n const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'scrypted_dataset_' + new Date().toISOString().slice(0,10) + '.json';\n a.click();\n URL.revokeObjectURL(url);\n status.textContent = \\`Downloaded \\${data.count} samples.\\`;\n toast('Dataset downloaded!');\n } catch (e) {\n status.textContent = 'Export failed: ' + e.message;\n }\n btn.disabled = false;\n}\n\n// Initial load\nloadPending();\n// Auto-refresh pending every 30s\nsetInterval(loadPending, 30_000);\n</script>\n</body>\n</html>`;\n }\n}\n\nexport default DetectionTrainer;\n","module.exports = require(\"module\");","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\tif (!(moduleId in __webpack_modules__)) {\n\t\tdelete __webpack_module_cache__[moduleId];\n\t\tvar e = new Error(\"Cannot find module '\" + moduleId + \"'\");\n\t\te.code = 'MODULE_NOT_FOUND';\n\t\tthrow e;\n\t}\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","","// startup\n// Load entry module and return exports\n// This entry module is referenced by other modules so it can't be inlined\nvar __webpack_exports__ = __webpack_require__(\"./src/main.ts\");\n",""],"names":[],"sourceRoot":""}
package/out/plugin.zip ADDED
Binary file
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "scrypted-detection-trainer",
3
+ "version": "0.1.1",
4
+ "description": "Collect and label detections to fine-tune the Scrypted NVR object detection model.",
5
+ "keywords": [
6
+ "scrypted-plugin"
7
+ ],
8
+ "main": "dist/main.js",
9
+ "scripts": {
10
+ "scrypted-setup-project": "scrypted-setup-project",
11
+ "prescrypted-setup-project": "scrypted-package-json",
12
+ "build": "scrypted-webpack",
13
+ "prepublishOnly": "NODE_ENV=production scrypted-webpack",
14
+ "scrypted-deploy": "scrypted-deploy"
15
+ },
16
+ "scrypted": {
17
+ "name": "Detection Trainer",
18
+ "type": "Other",
19
+ "interfaces": [
20
+ "Settings",
21
+ "HttpRequestHandler"
22
+ ]
23
+ },
24
+ "dependencies": {
25
+ "@scrypted/sdk": "^0.3.69"
26
+ },
27
+ "devDependencies": {
28
+ "@types/node": "^20.0.0"
29
+ }
30
+ }