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.
- package/dist/main.nodejs.js +2 -0
- package/dist/main.nodejs.js.map +1 -0
- package/dist/plugin.zip +0 -0
- package/out/main.nodejs.js +2200 -0
- package/out/main.nodejs.js.map +1 -0
- package/out/plugin.zip +0 -0
- package/package.json +30 -0
- package/src/main.ts +651 -0
- package/tsconfig.json +13 -0
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
(()=>{var e={562(e,t,n){"use strict";var r=this&&this.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,i)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||r(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),t.sdk=t.MixinDeviceBase=t.ScryptedDeviceBase=void 0,i(n(192),t);const o=n(192);n(339);class a extends o.DeviceBase{constructor(e){super(),this.nativeId=e}get storage(){return this._storage||(this._storage=t.sdk.deviceManager.getDeviceStorage(this.nativeId)),this._storage}get log(){return this._log||(this._log=t.sdk.deviceManager.getDeviceLogger(this.nativeId)),this._log}get console(){return this._console||(this._console=t.sdk.deviceManager.getDeviceConsole(this.nativeId)),this._console}async createMediaObject(e,n){return t.sdk.mediaManager.createMediaObject(e,n,{sourceId:this.id})}getMediaObjectConsole(e){return"string"!=typeof e.sourceId?this.console:t.sdk.deviceManager.getMixinConsole(e.sourceId,this.nativeId)}_lazyLoadDeviceState(){this._deviceState||(this.nativeId?this._deviceState=t.sdk.deviceManager.getDeviceState(this.nativeId):this._deviceState=t.sdk.deviceManager.getDeviceState())}onDeviceEvent(e,n){return t.sdk.deviceManager.onDeviceEvent(this.nativeId,e,n)}}t.ScryptedDeviceBase=a;class s extends o.DeviceBase{constructor(e){super(),this._listeners=new Set,this.mixinDevice=e.mixinDevice,this.mixinDeviceInterfaces=e.mixinDeviceInterfaces,this.mixinStorageSuffix=e.mixinStorageSuffix,this._deviceState=e.mixinDeviceState,this.nativeId=t.sdk.systemManager.getDeviceById(this.id).nativeId,this.mixinProviderNativeId=e.mixinProviderNativeId,this._deviceState.__rpcproxy_traps_all_properties&&"string"==typeof this._deviceState.id&&(this._deviceState=t.sdk.deviceManager.createDeviceState(this._deviceState.id,this._deviceState.setState))}get storage(){if(!this._storage){const e=this.mixinStorageSuffix,n=this.id+(e?":"+e:"");this._storage=t.sdk.deviceManager.getMixinStorage(n,this.mixinProviderNativeId)}return this._storage}get console(){return this._console||(t.sdk.deviceManager.getMixinConsole?this._console=t.sdk.deviceManager.getMixinConsole(this.id,this.mixinProviderNativeId):this._console=t.sdk.deviceManager.getDeviceConsole(this.mixinProviderNativeId)),this._console}async createMediaObject(e,n){return t.sdk.mediaManager.createMediaObject(e,n,{sourceId:this.id})}getMediaObjectConsole(e){return"string"!=typeof e.sourceId?this.console:t.sdk.deviceManager.getMixinConsole(e.sourceId,this.mixinProviderNativeId)}onDeviceEvent(e,n){return t.sdk.deviceManager.onMixinEvent(this.id,this,e,n)}_lazyLoadDeviceState(){}manageListener(e){this._listeners.add(e)}release(){for(const e of this._listeners)e.removeListener()}}t.MixinDeviceBase=s,function(){function e(e){return function(){return this._lazyLoadDeviceState(),this._deviceState?.[e]}}function t(e){return function(t){this._lazyLoadDeviceState(),this._deviceState?this._deviceState[e]=t:console.warn("device state is unavailable. the device must be discovered with deviceManager.onDeviceDiscovered or deviceManager.onDevicesChanged before the state can be set.")}}for(const n of Object.values(o.ScryptedInterfaceProperty))n!==o.ScryptedInterfaceProperty.nativeId&&(Object.defineProperty(a.prototype,n,{set:t(n),get:e(n)}),Object.defineProperty(s.prototype,n,{set:t(n),get:e(n)}))}(),t.sdk={};try{let e=!1;try{process.env.SCRYPTED_SDK_ES_MODULE||process.env.SCRYPTED_SDK_MODULE;const r=process.env.SCRYPTED_SDK_CJS_MODULE||process.env.SCRYPTED_SDK_MODULE;if(r)if("undefined"!=typeof require){const n=require(process.env.SCRYPTED_SDK_MODULE);Object.assign(t.sdk,n.getScryptedStatic()),e=!0}else{const i=n(891)(r);Object.assign(t.sdk,i.getScryptedStatic()),e=!0}}catch(e){throw console.warn("failed to load sdk module",e),e}if(!e){let e;try{e=pluginRuntimeAPI}catch(e){}Object.assign(t.sdk,{log:deviceManager.getDeviceLogger(void 0),deviceManager,endpointManager,mediaManager,systemManager,pluginHostAPI,...e})}try{t.sdk.systemManager.setScryptedInterfaceDescriptors?.(o.TYPES_VERSION,o.ScryptedInterfaceDescriptors)?.catch(()=>{})}catch(e){}}catch(e){console.error("sdk initialization error, import @scrypted/types or use @scrypted/client instead",e)}t.default=t.sdk},891(e){function t(e){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}t.keys=()=>[],t.resolve=t,t.id=891,e.exports=t},192(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.ScryptedMimeTypes=t.ScryptedInterface=t.MediaPlayerState=t.SecuritySystemObstruction=t.SecuritySystemMode=t.AirQuality=t.AirPurifierMode=t.AirPurifierStatus=t.ChargeState=t.LockState=t.PanTiltZoomMovement=t.ThermostatMode=t.TemperatureUnit=t.FanMode=t.HumidityMode=t.ScryptedDeviceType=t.ScryptedInterfaceDescriptors=t.ScryptedInterfaceMethod=t.ScryptedInterfaceProperty=t.DeviceBase=t.TYPES_VERSION=void 0,t.TYPES_VERSION="0.3.116";var n,r,i,o,a,s,d,c,l,p,m,u,g,v,h,y,S,b;t.DeviceBase=class{},function(e){e.id="id",e.info="info",e.interfaces="interfaces",e.mixins="mixins",e.name="name",e.nativeId="nativeId",e.pluginId="pluginId",e.providedInterfaces="providedInterfaces",e.providedName="providedName",e.providedRoom="providedRoom",e.providedType="providedType",e.providerId="providerId",e.room="room",e.type="type",e.scryptedRuntimeArguments="scryptedRuntimeArguments",e.on="on",e.brightness="brightness",e.colorTemperature="colorTemperature",e.rgb="rgb",e.hsv="hsv",e.buttons="buttons",e.sensors="sensors",e.running="running",e.paused="paused",e.docked="docked",e.temperatureSetting="temperatureSetting",e.temperature="temperature",e.temperatureUnit="temperatureUnit",e.humidity="humidity",e.audioVolumes="audioVolumes",e.recordingActive="recordingActive",e.ptzCapabilities="ptzCapabilities",e.lockState="lockState",e.entryOpen="entryOpen",e.batteryLevel="batteryLevel",e.chargeState="chargeState",e.online="online",e.fromMimeType="fromMimeType",e.toMimeType="toMimeType",e.converters="converters",e.binaryState="binaryState",e.tampered="tampered",e.sleeping="sleeping",e.powerDetected="powerDetected",e.audioDetected="audioDetected",e.motionDetected="motionDetected",e.ambientLight="ambientLight",e.occupied="occupied",e.flooded="flooded",e.ultraviolet="ultraviolet",e.luminance="luminance",e.position="position",e.securitySystemState="securitySystemState",e.pm10Density="pm10Density",e.pm25Density="pm25Density",e.vocDensity="vocDensity",e.noxDensity="noxDensity",e.co2ppm="co2ppm",e.airQuality="airQuality",e.airPurifierState="airPurifierState",e.filterChangeIndication="filterChangeIndication",e.filterLifeLevel="filterLifeLevel",e.humiditySetting="humiditySetting",e.fan="fan",e.applicationInfo="applicationInfo",e.systemDevice="systemDevice"}(n||(t.ScryptedInterfaceProperty=n={})),function(e){e.listen="listen",e.probe="probe",e.setMixins="setMixins",e.setName="setName",e.setRoom="setRoom",e.setType="setType",e.getPluginJson="getPluginJson",e.turnOff="turnOff",e.turnOn="turnOn",e.setBrightness="setBrightness",e.getTemperatureMaxK="getTemperatureMaxK",e.getTemperatureMinK="getTemperatureMinK",e.setColorTemperature="setColorTemperature",e.setRgb="setRgb",e.setHsv="setHsv",e.pressButton="pressButton",e.sendNotification="sendNotification",e.start="start",e.stop="stop",e.pause="pause",e.resume="resume",e.dock="dock",e.setTemperature="setTemperature",e.setTemperatureUnit="setTemperatureUnit",e.getPictureOptions="getPictureOptions",e.takePicture="takePicture",e.getAudioStream="getAudioStream",e.setAudioVolumes="setAudioVolumes",e.startDisplay="startDisplay",e.stopDisplay="stopDisplay",e.getVideoStream="getVideoStream",e.getVideoStreamOptions="getVideoStreamOptions",e.getPrivacyMasks="getPrivacyMasks",e.setPrivacyMasks="setPrivacyMasks",e.getVideoTextOverlays="getVideoTextOverlays",e.setVideoTextOverlay="setVideoTextOverlay",e.getRecordingStream="getRecordingStream",e.getRecordingStreamCurrentTime="getRecordingStreamCurrentTime",e.getRecordingStreamOptions="getRecordingStreamOptions",e.getRecordingStreamThumbnail="getRecordingStreamThumbnail",e.deleteRecordingStream="deleteRecordingStream",e.setRecordingActive="setRecordingActive",e.ptzCommand="ptzCommand",e.getRecordedEvents="getRecordedEvents",e.getVideoClip="getVideoClip",e.getVideoClips="getVideoClips",e.getVideoClipThumbnail="getVideoClipThumbnail",e.removeVideoClips="removeVideoClips",e.setVideoStreamOptions="setVideoStreamOptions",e.startIntercom="startIntercom",e.stopIntercom="stopIntercom",e.lock="lock",e.unlock="unlock",e.addPassword="addPassword",e.getPasswords="getPasswords",e.removePassword="removePassword",e.activate="activate",e.deactivate="deactivate",e.isReversible="isReversible",e.closeEntry="closeEntry",e.openEntry="openEntry",e.getDevice="getDevice",e.releaseDevice="releaseDevice",e.adoptDevice="adoptDevice",e.discoverDevices="discoverDevices",e.createDevice="createDevice",e.getCreateDeviceSettings="getCreateDeviceSettings",e.reboot="reboot",e.getRefreshFrequency="getRefreshFrequency",e.refresh="refresh",e.getMediaStatus="getMediaStatus",e.load="load",e.seek="seek",e.skipNext="skipNext",e.skipPrevious="skipPrevious",e.convert="convert",e.convertMedia="convertMedia",e.getSettings="getSettings",e.putSetting="putSetting",e.armSecuritySystem="armSecuritySystem",e.disarmSecuritySystem="disarmSecuritySystem",e.setAirPurifierState="setAirPurifierState",e.getReadmeMarkdown="getReadmeMarkdown",e.getOauthUrl="getOauthUrl",e.onOauthCallback="onOauthCallback",e.canMixin="canMixin",e.getMixin="getMixin",e.releaseMixin="releaseMixin",e.onRequest="onRequest",e.onConnection="onConnection",e.onPush="onPush",e.run="run",e.eval="eval",e.loadScripts="loadScripts",e.saveScript="saveScript",e.forkInterface="forkInterface",e.trackObjects="trackObjects",e.getDetectionInput="getDetectionInput",e.getObjectTypes="getObjectTypes",e.detectObjects="detectObjects",e.generateObjectDetections="generateObjectDetections",e.getDetectionModel="getDetectionModel",e.setHumidity="setHumidity",e.setFan="setFan",e.startRTCSignalingSession="startRTCSignalingSession",e.createRTCSignalingSession="createRTCSignalingSession",e.getScryptedUserAccessControl="getScryptedUserAccessControl",e.generateVideoFrames="generateVideoFrames",e.connectStream="connectStream",e.getTTYSettings="getTTYSettings"}(r||(t.ScryptedInterfaceMethod=r={})),t.ScryptedInterfaceDescriptors={ScryptedDevice:{name:"ScryptedDevice",methods:["listen","probe","setMixins","setName","setRoom","setType"],properties:["id","info","interfaces","mixins","name","nativeId","pluginId","providedInterfaces","providedName","providedRoom","providedType","providerId","room","type"]},ScryptedPlugin:{name:"ScryptedPlugin",methods:["getPluginJson"],properties:[]},ScryptedPluginRuntime:{name:"ScryptedPluginRuntime",methods:[],properties:["scryptedRuntimeArguments"]},OnOff:{name:"OnOff",methods:["turnOff","turnOn"],properties:["on"]},Brightness:{name:"Brightness",methods:["setBrightness"],properties:["brightness"]},ColorSettingTemperature:{name:"ColorSettingTemperature",methods:["getTemperatureMaxK","getTemperatureMinK","setColorTemperature"],properties:["colorTemperature"]},ColorSettingRgb:{name:"ColorSettingRgb",methods:["setRgb"],properties:["rgb"]},ColorSettingHsv:{name:"ColorSettingHsv",methods:["setHsv"],properties:["hsv"]},Buttons:{name:"Buttons",methods:[],properties:["buttons"]},PressButtons:{name:"PressButtons",methods:["pressButton"],properties:[]},Sensors:{name:"Sensors",methods:[],properties:["sensors"]},Notifier:{name:"Notifier",methods:["sendNotification"],properties:[]},StartStop:{name:"StartStop",methods:["start","stop"],properties:["running"]},Pause:{name:"Pause",methods:["pause","resume"],properties:["paused"]},Dock:{name:"Dock",methods:["dock"],properties:["docked"]},TemperatureSetting:{name:"TemperatureSetting",methods:["setTemperature"],properties:["temperatureSetting"]},Thermometer:{name:"Thermometer",methods:["setTemperatureUnit"],properties:["temperature","temperatureUnit"]},HumiditySensor:{name:"HumiditySensor",methods:[],properties:["humidity"]},Camera:{name:"Camera",methods:["getPictureOptions","takePicture"],properties:[]},Microphone:{name:"Microphone",methods:["getAudioStream"],properties:[]},AudioVolumeControl:{name:"AudioVolumeControl",methods:["setAudioVolumes"],properties:["audioVolumes"]},Display:{name:"Display",methods:["startDisplay","stopDisplay"],properties:[]},VideoCamera:{name:"VideoCamera",methods:["getVideoStream","getVideoStreamOptions"],properties:[]},VideoCameraMask:{name:"VideoCameraMask",methods:["getPrivacyMasks","setPrivacyMasks"],properties:[]},VideoTextOverlays:{name:"VideoTextOverlays",methods:["getVideoTextOverlays","setVideoTextOverlay"],properties:[]},VideoRecorder:{name:"VideoRecorder",methods:["getRecordingStream","getRecordingStreamCurrentTime","getRecordingStreamOptions","getRecordingStreamThumbnail"],properties:["recordingActive"]},VideoRecorderManagement:{name:"VideoRecorderManagement",methods:["deleteRecordingStream","setRecordingActive"],properties:[]},PanTiltZoom:{name:"PanTiltZoom",methods:["ptzCommand"],properties:["ptzCapabilities"]},EventRecorder:{name:"EventRecorder",methods:["getRecordedEvents"],properties:[]},VideoClips:{name:"VideoClips",methods:["getVideoClip","getVideoClips","getVideoClipThumbnail","removeVideoClips"],properties:[]},VideoCameraConfiguration:{name:"VideoCameraConfiguration",methods:["setVideoStreamOptions"],properties:[]},Intercom:{name:"Intercom",methods:["startIntercom","stopIntercom"],properties:[]},Lock:{name:"Lock",methods:["lock","unlock"],properties:["lockState"]},PasswordStore:{name:"PasswordStore",methods:["addPassword","getPasswords","removePassword"],properties:[]},Scene:{name:"Scene",methods:["activate","deactivate","isReversible"],properties:[]},Entry:{name:"Entry",methods:["closeEntry","openEntry"],properties:[]},EntrySensor:{name:"EntrySensor",methods:[],properties:["entryOpen"]},DeviceProvider:{name:"DeviceProvider",methods:["getDevice","releaseDevice"],properties:[]},DeviceDiscovery:{name:"DeviceDiscovery",methods:["adoptDevice","discoverDevices"],properties:[]},DeviceCreator:{name:"DeviceCreator",methods:["createDevice","getCreateDeviceSettings"],properties:[]},Battery:{name:"Battery",methods:[],properties:["batteryLevel"]},Charger:{name:"Charger",methods:[],properties:["chargeState"]},Reboot:{name:"Reboot",methods:["reboot"],properties:[]},Refresh:{name:"Refresh",methods:["getRefreshFrequency","refresh"],properties:[]},MediaPlayer:{name:"MediaPlayer",methods:["getMediaStatus","load","seek","skipNext","skipPrevious"],properties:[]},Online:{name:"Online",methods:[],properties:["online"]},BufferConverter:{name:"BufferConverter",methods:["convert"],properties:["fromMimeType","toMimeType"]},MediaConverter:{name:"MediaConverter",methods:["convertMedia"],properties:["converters"]},Settings:{name:"Settings",methods:["getSettings","putSetting"],properties:[]},BinarySensor:{name:"BinarySensor",methods:[],properties:["binaryState"]},TamperSensor:{name:"TamperSensor",methods:[],properties:["tampered"]},Sleep:{name:"Sleep",methods:[],properties:["sleeping"]},PowerSensor:{name:"PowerSensor",methods:[],properties:["powerDetected"]},AudioSensor:{name:"AudioSensor",methods:[],properties:["audioDetected"]},MotionSensor:{name:"MotionSensor",methods:[],properties:["motionDetected"]},AmbientLightSensor:{name:"AmbientLightSensor",methods:[],properties:["ambientLight"]},OccupancySensor:{name:"OccupancySensor",methods:[],properties:["occupied"]},FloodSensor:{name:"FloodSensor",methods:[],properties:["flooded"]},UltravioletSensor:{name:"UltravioletSensor",methods:[],properties:["ultraviolet"]},LuminanceSensor:{name:"LuminanceSensor",methods:[],properties:["luminance"]},PositionSensor:{name:"PositionSensor",methods:[],properties:["position"]},SecuritySystem:{name:"SecuritySystem",methods:["armSecuritySystem","disarmSecuritySystem"],properties:["securitySystemState"]},PM10Sensor:{name:"PM10Sensor",methods:[],properties:["pm10Density"]},PM25Sensor:{name:"PM25Sensor",methods:[],properties:["pm25Density"]},VOCSensor:{name:"VOCSensor",methods:[],properties:["vocDensity"]},NOXSensor:{name:"NOXSensor",methods:[],properties:["noxDensity"]},CO2Sensor:{name:"CO2Sensor",methods:[],properties:["co2ppm"]},AirQualitySensor:{name:"AirQualitySensor",methods:[],properties:["airQuality"]},AirPurifier:{name:"AirPurifier",methods:["setAirPurifierState"],properties:["airPurifierState"]},FilterMaintenance:{name:"FilterMaintenance",methods:[],properties:["filterChangeIndication","filterLifeLevel"]},Readme:{name:"Readme",methods:["getReadmeMarkdown"],properties:[]},OauthClient:{name:"OauthClient",methods:["getOauthUrl","onOauthCallback"],properties:[]},MixinProvider:{name:"MixinProvider",methods:["canMixin","getMixin","releaseMixin"],properties:[]},HttpRequestHandler:{name:"HttpRequestHandler",methods:["onRequest"],properties:[]},EngineIOHandler:{name:"EngineIOHandler",methods:["onConnection"],properties:[]},PushHandler:{name:"PushHandler",methods:["onPush"],properties:[]},Program:{name:"Program",methods:["run"],properties:[]},Scriptable:{name:"Scriptable",methods:["eval","loadScripts","saveScript"],properties:[]},ClusterForkInterface:{name:"ClusterForkInterface",methods:["forkInterface"],properties:[]},ObjectTracker:{name:"ObjectTracker",methods:["trackObjects"],properties:[]},ObjectDetector:{name:"ObjectDetector",methods:["getDetectionInput","getObjectTypes"],properties:[]},ObjectDetection:{name:"ObjectDetection",methods:["detectObjects","generateObjectDetections","getDetectionModel"],properties:[]},ObjectDetectionPreview:{name:"ObjectDetectionPreview",methods:[],properties:[]},ObjectDetectionGenerator:{name:"ObjectDetectionGenerator",methods:[],properties:[]},HumiditySetting:{name:"HumiditySetting",methods:["setHumidity"],properties:["humiditySetting"]},Fan:{name:"Fan",methods:["setFan"],properties:["fan"]},RTCSignalingChannel:{name:"RTCSignalingChannel",methods:["startRTCSignalingSession"],properties:[]},RTCSignalingClient:{name:"RTCSignalingClient",methods:["createRTCSignalingSession"],properties:[]},LauncherApplication:{name:"LauncherApplication",methods:[],properties:["applicationInfo"]},ScryptedUser:{name:"ScryptedUser",methods:["getScryptedUserAccessControl"],properties:[]},VideoFrameGenerator:{name:"VideoFrameGenerator",methods:["generateVideoFrames"],properties:[]},StreamService:{name:"StreamService",methods:["connectStream"],properties:[]},TTY:{name:"TTY",methods:[],properties:[]},TTYSettings:{name:"TTYSettings",methods:["getTTYSettings"],properties:[]},ScryptedSystemDevice:{name:"ScryptedSystemDevice",methods:[],properties:["systemDevice"]},ScryptedDeviceCreator:{name:"ScryptedDeviceCreator",methods:[],properties:[]},ScryptedSettings:{name:"ScryptedSettings",methods:[],properties:[]}},function(e){e.Builtin="Builtin",e.Internal="Internal",e.Camera="Camera",e.Fan="Fan",e.Light="Light",e.Switch="Switch",e.Outlet="Outlet",e.Sensor="Sensor",e.Scene="Scene",e.Program="Program",e.Automation="Automation",e.Vacuum="Vacuum",e.Notifier="Notifier",e.Thermostat="Thermostat",e.Lock="Lock",e.PasswordControl="PasswordControl",e.Display="Display",e.SmartDisplay="SmartDisplay",e.Speaker="Speaker",e.SmartSpeaker="SmartSpeaker",e.Event="Event",e.Entry="Entry",e.Garage="Garage",e.DeviceProvider="DeviceProvider",e.DataSource="DataSource",e.API="API",e.Doorbell="Doorbell",e.Irrigation="Irrigation",e.Valve="Valve",e.Person="Person",e.SecuritySystem="SecuritySystem",e.WindowCovering="WindowCovering",e.Siren="Siren",e.AirPurifier="AirPurifier",e.Internet="Internet",e.Network="Network",e.Bridge="Bridge",e.Unknown="Unknown"}(i||(t.ScryptedDeviceType=i={})),function(e){e.Humidify="Humidify",e.Dehumidify="Dehumidify",e.Auto="Auto",e.Off="Off"}(o||(t.HumidityMode=o={})),function(e){e.Auto="Auto",e.Manual="Manual"}(a||(t.FanMode=a={})),function(e){e.C="C",e.F="F"}(s||(t.TemperatureUnit=s={})),function(e){e.Off="Off",e.Cool="Cool",e.Heat="Heat",e.HeatCool="HeatCool",e.Auto="Auto",e.FanOnly="FanOnly",e.Purifier="Purifier",e.Eco="Eco",e.Dry="Dry",e.On="On"}(d||(t.ThermostatMode=d={})),function(e){e.Absolute="Absolute",e.Relative="Relative",e.Continuous="Continuous",e.Preset="Preset",e.Home="Home"}(c||(t.PanTiltZoomMovement=c={})),function(e){e.Locked="Locked",e.Unlocked="Unlocked",e.Jammed="Jammed"}(l||(t.LockState=l={})),function(e){e.Trickle="trickle",e.Charging="charging",e.NotCharging="not-charging"}(p||(t.ChargeState=p={})),function(e){e.Inactive="Inactive",e.Idle="Idle",e.Active="Active",e.ActiveNightMode="ActiveNightMode"}(m||(t.AirPurifierStatus=m={})),function(e){e.Manual="Manual",e.Automatic="Automatic"}(u||(t.AirPurifierMode=u={})),function(e){e.Unknown="Unknown",e.Excellent="Excellent",e.Good="Good",e.Fair="Fair",e.Inferior="Inferior",e.Poor="Poor"}(g||(t.AirQuality=g={})),function(e){e.Disarmed="Disarmed",e.HomeArmed="HomeArmed",e.AwayArmed="AwayArmed",e.NightArmed="NightArmed"}(v||(t.SecuritySystemMode=v={})),function(e){e.Sensor="Sensor",e.Occupied="Occupied",e.Time="Time",e.Error="Error"}(h||(t.SecuritySystemObstruction=h={})),function(e){e.Idle="Idle",e.Playing="Playing",e.Paused="Paused",e.Buffering="Buffering"}(y||(t.MediaPlayerState=y={})),function(e){e.ScryptedDevice="ScryptedDevice",e.ScryptedPlugin="ScryptedPlugin",e.ScryptedPluginRuntime="ScryptedPluginRuntime",e.OnOff="OnOff",e.Brightness="Brightness",e.ColorSettingTemperature="ColorSettingTemperature",e.ColorSettingRgb="ColorSettingRgb",e.ColorSettingHsv="ColorSettingHsv",e.Buttons="Buttons",e.PressButtons="PressButtons",e.Sensors="Sensors",e.Notifier="Notifier",e.StartStop="StartStop",e.Pause="Pause",e.Dock="Dock",e.TemperatureSetting="TemperatureSetting",e.Thermometer="Thermometer",e.HumiditySensor="HumiditySensor",e.Camera="Camera",e.Microphone="Microphone",e.AudioVolumeControl="AudioVolumeControl",e.Display="Display",e.VideoCamera="VideoCamera",e.VideoCameraMask="VideoCameraMask",e.VideoTextOverlays="VideoTextOverlays",e.VideoRecorder="VideoRecorder",e.VideoRecorderManagement="VideoRecorderManagement",e.PanTiltZoom="PanTiltZoom",e.EventRecorder="EventRecorder",e.VideoClips="VideoClips",e.VideoCameraConfiguration="VideoCameraConfiguration",e.Intercom="Intercom",e.Lock="Lock",e.PasswordStore="PasswordStore",e.Scene="Scene",e.Entry="Entry",e.EntrySensor="EntrySensor",e.DeviceProvider="DeviceProvider",e.DeviceDiscovery="DeviceDiscovery",e.DeviceCreator="DeviceCreator",e.Battery="Battery",e.Charger="Charger",e.Reboot="Reboot",e.Refresh="Refresh",e.MediaPlayer="MediaPlayer",e.Online="Online",e.BufferConverter="BufferConverter",e.MediaConverter="MediaConverter",e.Settings="Settings",e.BinarySensor="BinarySensor",e.TamperSensor="TamperSensor",e.Sleep="Sleep",e.PowerSensor="PowerSensor",e.AudioSensor="AudioSensor",e.MotionSensor="MotionSensor",e.AmbientLightSensor="AmbientLightSensor",e.OccupancySensor="OccupancySensor",e.FloodSensor="FloodSensor",e.UltravioletSensor="UltravioletSensor",e.LuminanceSensor="LuminanceSensor",e.PositionSensor="PositionSensor",e.SecuritySystem="SecuritySystem",e.PM10Sensor="PM10Sensor",e.PM25Sensor="PM25Sensor",e.VOCSensor="VOCSensor",e.NOXSensor="NOXSensor",e.CO2Sensor="CO2Sensor",e.AirQualitySensor="AirQualitySensor",e.AirPurifier="AirPurifier",e.FilterMaintenance="FilterMaintenance",e.Readme="Readme",e.OauthClient="OauthClient",e.MixinProvider="MixinProvider",e.HttpRequestHandler="HttpRequestHandler",e.EngineIOHandler="EngineIOHandler",e.PushHandler="PushHandler",e.Program="Program",e.Scriptable="Scriptable",e.ClusterForkInterface="ClusterForkInterface",e.ObjectTracker="ObjectTracker",e.ObjectDetector="ObjectDetector",e.ObjectDetection="ObjectDetection",e.ObjectDetectionPreview="ObjectDetectionPreview",e.ObjectDetectionGenerator="ObjectDetectionGenerator",e.HumiditySetting="HumiditySetting",e.Fan="Fan",e.RTCSignalingChannel="RTCSignalingChannel",e.RTCSignalingClient="RTCSignalingClient",e.LauncherApplication="LauncherApplication",e.ScryptedUser="ScryptedUser",e.VideoFrameGenerator="VideoFrameGenerator",e.StreamService="StreamService",e.TTY="TTY",e.TTYSettings="TTYSettings",e.ScryptedSystemDevice="ScryptedSystemDevice",e.ScryptedDeviceCreator="ScryptedDeviceCreator",e.ScryptedSettings="ScryptedSettings"}(S||(t.ScryptedInterface=S={})),function(e){e.Url="text/x-uri",e.InsecureLocalUrl="text/x-insecure-local-uri",e.LocalUrl="text/x-local-uri",e.ServerId="text/x-server-id",e.PushEndpoint="text/x-push-endpoint",e.SchemePrefix="x-scrypted/x-scrypted-scheme-",e.MediaStreamUrl="text/x-media-url",e.MediaObject="x-scrypted/x-scrypted-media-object",e.RequestMediaObject="x-scrypted/x-scrypted-request-media-object",e.RequestMediaStream="x-scrypted/x-scrypted-request-stream",e.MediaStreamFeedback="x-scrypted/x-media-stream-feedback",e.FFmpegInput="x-scrypted/x-ffmpeg-input",e.FFmpegTranscodeStream="x-scrypted/x-ffmpeg-transcode-stream",e.RTCSignalingChannel="x-scrypted/x-scrypted-rtc-signaling-channel",e.RTCSignalingSession="x-scrypted/x-scrypted-rtc-signaling-session",e.RTCConnectionManagement="x-scrypted/x-scrypted-rtc-connection-management",e.Image="x-scrypted/x-scrypted-image"}(b||(t.ScryptedMimeTypes=b={}))},927(e,t,n){"use strict";var r,i=this&&this.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,i)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),o=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),a=this&&this.__importStar||(r=function(e){return r=Object.getOwnPropertyNames||function(e){var t=[];for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[t.length]=n);return t},r(e)},function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n=r(e),a=0;a<n.length;a++)"default"!==n[a]&&i(t,e,n[a]);return o(t,e),t});Object.defineProperty(t,"__esModule",{value:!0});const s=a(n(562)),{systemManager:d,deviceManager:c,mediaManager:l}=s.default,p=new Set(["person","cat","dog","animal","bird","face","vehicle","car","truck","bus","motorcycle","bicycle","plate","package"]),m=["disabled","1 per minute","1 per 10 seconds","every detection"],u={disabled:1/0,"1 per minute":6e4,"1 per 10 seconds":1e4,"every detection":0};class g extends s.ScryptedDeviceBase{constructor(e){super(e),this.lastCapture=new Map,this.captures=new Map,this.images=new Map,this.listeners=[],this.loadState(),this.registerListeners()}loadState(){try{const e=this.storage.getItem("captures");if(e){const t=JSON.parse(e);for(const e of t)this.captures.set(e.id,e);this.console.log(`Loaded ${this.captures.size} captures from storage.`)}}catch(e){this.console.warn("Could not load captures from storage:",e)}for(const[e]of this.captures){const t=this.storage.getItem(`img:${e}`);t&&this.images.set(e,Buffer.from(t,"base64"))}}saveCaptures(){this.storage.setItem("captures",JSON.stringify([...this.captures.values()]))}saveImage(e,t){this.storage.setItem(`img:${e}`,t.toString("base64"))}deleteCapture(e){this.storage.getItem(`img:${e}`)&&this.storage.removeItem(`img:${e}`),this.captures.delete(e),this.images.delete(e),this.saveCaptures()}async getSettings(){const e=Object.keys(d.getSystemState()).map(e=>d.getDeviceById(e)).filter(e=>e&&(e.type===s.ScryptedDeviceType.Camera||e.type===s.ScryptedDeviceType.Doorbell)&&e.interfaces?.includes(s.ScryptedInterface.ObjectDetector)),t=[{key:"info",title:"Detection Trainer",description:`${this.captures.size} captures stored (${[...this.captures.values()].filter(e=>!e.reviewed).length} pending review, ${[...this.captures.values()].filter(e=>e.reviewed&&"discard"!==e.label).length} labeled). Open the web UI to review and export.`,readonly:!0,value:""},{key:"open_ui",title:"Open Review UI",description:"Open the detection review and labeling interface.",type:"button"}];for(const n of e){const e=`rate:${n.id}`;t.push({key:e,title:n.name,group:"Capture Rate per Camera",description:"How often to capture detections from this camera.",value:this.storage.getItem(e)||"1 per minute",choices:[...m]})}return t}async putSetting(e,t){"open_ui"!==e&&(this.storage.setItem(e,t),e.startsWith("rate:")&&this.registerListeners())}registerListeners(){for(const e of this.listeners)e();this.listeners=[];const e=Object.keys(d.getSystemState()).map(e=>d.getDeviceById(e)).filter(e=>e&&(e.type===s.ScryptedDeviceType.Camera||e.type===s.ScryptedDeviceType.Doorbell)&&e.interfaces?.includes(s.ScryptedInterface.ObjectDetector));for(const t of e){const e=`rate:${t.id}`,n=this.storage.getItem(e)||"1 per minute";if("disabled"===n)continue;const r=t.listen(s.ScryptedInterface.ObjectDetector,async(e,r,i)=>{await this.onDetection(t.id,t.name,i,u[n])});this.listeners.push(()=>r.removeListener())}this.console.log(`Listening to ${this.listeners.length} camera(s).`)}async onDetection(e,t,n,r){if(!n?.detections?.length||!n.inputDimensions)return;const i=Date.now();if(i-(this.lastCapture.get(e)||0)<r)return;const o=n.detections.filter(e=>e.className&&p.has(e.className.toLowerCase())&&e.boundingBox);if(!o.length)return;const a=o.sort((e,t)=>(t.score||0)-(e.score||0))[0];if(this.captures.size>=2e3){const e=[...this.captures.values()].filter(e=>!e.reviewed).sort((e,t)=>e.timestamp-t.timestamp)[0];if(!e)return;this.deleteCapture(e.id)}let s;this.lastCapture.set(e,i);try{if(n.detectionId){const t=d.getDeviceById(e),r=await t.getDetectionInput(n.detectionId);s=await l.convertMediaObjectToBuffer(r,"image/jpeg")}}catch(e){this.console.warn(`Could not get detection image for ${t}:`,e)}if(!s)return;const c=`${i}-${Math.random().toString(36).slice(2,8)}`,m={id:c,cameraId:e,cameraName:t,timestamp:i,detectedClass:a.className,score:a.score||0,boundingBox:a.boundingBox,inputDimensions:n.inputDimensions,detectionId:n.detectionId,reviewed:!1};this.captures.set(c,m),this.images.set(c,s),this.saveImage(c,s),this.saveCaptures(),this.console.log(`Captured ${a.className} (${Math.round(100*(a.score||0))}%) from ${t} [${this.captures.size} total]`)}async onRequest(e,t){const n=new URL(e.url,"http://localhost").pathname.replace(e.rootPath,"");if(n.startsWith("/img/")){const e=n.slice(5),r=this.images.get(e);return r?t.send(r,{headers:{"Content-Type":"image/jpeg","Cache-Control":"max-age=3600"}}):t.send("Not found",{code:404})}if("/api/label"===n&&e.body){const n=e.body,r=JSON.parse("string"==typeof n?n:Buffer.isBuffer(n)?n.toString():String(n)),i=this.captures.get(r.id);return i?(i.label=r.label,i.reviewed=!0,"discard"===r.label?this.deleteCapture(r.id):(this.captures.set(r.id,i),this.saveCaptures()),t.send(JSON.stringify({ok:!0}),{headers:{"Content-Type":"application/json"}})):t.send("Not found",{code:404})}if("/api/pending"===n){const e=[...this.captures.values()].filter(e=>!e.reviewed).sort((e,t)=>t.timestamp-e.timestamp).slice(0,50);return t.send(JSON.stringify(e),{headers:{"Content-Type":"application/json"}})}if("/api/stats"===n){const e=[...this.captures.values()],n={total:e.length,pending:e.filter(e=>!e.reviewed).length,labeled:e.filter(e=>e.reviewed&&"discard"!==e.label).length,byLabel:{},byCamera:{},byDetectedClass:{}};for(const t of e)t.label&&(n.byLabel[t.label]=(n.byLabel[t.label]||0)+1),n.byCamera[t.cameraName]=(n.byCamera[t.cameraName]||0)+1,n.byDetectedClass[t.detectedClass]=(n.byDetectedClass[t.detectedClass]||0)+1;return t.send(JSON.stringify(n),{headers:{"Content-Type":"application/json"}})}if("/api/export"===n){const e=[...this.captures.values()].filter(e=>e.reviewed&&e.label&&"discard"!==e.label);if(!e.length)return t.send(JSON.stringify({error:"No labeled data yet"}),{headers:{"Content-Type":"application/json"},code:400});const n={person:0,animal:1,face:2,vehicle:3,plate:4,package:5,discard:-1},r=[];for(const t of e){const e=this.images.get(t.id);if(!e)continue;const i=`${t.id}`;r.push({filename:`images/${i}.jpg`,content:e.toString("base64"),encoding:"base64"});const[o,a,s,d]=t.boundingBox,[c,l]=t.inputDimensions,p=(o+s/2)/c,m=(a+d/2)/l,u=s/c,g=d/l,v=`${n[t.label]} ${p.toFixed(6)} ${m.toFixed(6)} ${u.toFixed(6)} ${g.toFixed(6)}\n`;r.push({filename:`labels/${i}.txt`,content:v,encoding:"utf8"})}const i=["path: dataset","train: images","val: images","","nc: 6","names: ['person', 'animal', 'face', 'vehicle', 'plate', 'package']","","# Generated by Scrypted Detection Trainer",`# ${e.length} labeled samples`].join("\n");return r.push({filename:"data.yaml",content:i,encoding:"utf8"}),t.send(JSON.stringify({files:r,count:e.length}),{headers:{"Content-Type":"application/json"}})}if("/"===n||""===n||"/index.html"===n)return t.send(this.renderUI(),{headers:{"Content-Type":"text/html"}});t.send("Not found",{code:404})}renderUI(){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 \x3c!-- Review tab --\x3e\n <div class="tab-panel active" id="tab-review">\n <div id="detections-list"></div>\n </div>\n\n \x3c!-- Stats tab --\x3e\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 \x3c!-- Export tab --\x3e\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>'}}t.default=g},339(e){"use strict";e.exports=require("module")}},t={};function n(r){var i=t[r];if(void 0!==i)return i.exports;var o=t[r]={exports:{}};return e[r].call(o.exports,o,o.exports,n),o.exports}n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t);var r=n(927),i=exports="undefined"==typeof exports?{}:exports;for(var o in r)i[o]=r[o];r.__esModule&&Object.defineProperty(i,"__esModule",{value:!0})})();
|
|
2
|
+
//# sourceMappingURL=main.nodejs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.nodejs.js","mappings":"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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/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 = 891;\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\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__(927);\n"],"names":["__createBinding","this","Object","create","o","m","k","k2","undefined","desc","getOwnPropertyDescriptor","__esModule","writable","configurable","enumerable","get","defineProperty","__exportStar","exports","p","prototype","hasOwnProperty","call","value","sdk","MixinDeviceBase","ScryptedDeviceBase","index_1","DeviceBase","constructor","nativeId","super","storage","_storage","deviceManager","getDeviceStorage","log","_log","getDeviceLogger","console","_console","getDeviceConsole","createMediaObject","data","mimeType","mediaManager","sourceId","id","getMediaObjectConsole","mediaObject","getMixinConsole","_lazyLoadDeviceState","_deviceState","getDeviceState","onDeviceEvent","eventInterface","eventData","options","_listeners","Set","mixinDevice","mixinDeviceInterfaces","mixinStorageSuffix","mixinDeviceState","systemManager","getDeviceById","mixinProviderNativeId","__rpcproxy_traps_all_properties","createDeviceState","setState","mixinStorageKey","getMixinStorage","onMixinEvent","manageListener","listener","add","release","l","removeListener","_createGetState","state","_createSetState","warn","field","values","ScryptedInterfaceProperty","set","loaded","process","env","SCRYPTED_SDK_ES_MODULE","SCRYPTED_SDK_MODULE","cjsModule","SCRYPTED_SDK_CJS_MODULE","sdkModule","assign","getScryptedStatic","e","runtimeAPI","pluginRuntimeAPI","endpointManager","pluginHostAPI","setScryptedInterfaceDescriptors","TYPES_VERSION","ScryptedInterfaceDescriptors","catch","error","webpackEmptyContext","req","Error","code","keys","resolve","module","ScryptedMimeTypes","ScryptedInterface","MediaPlayerState","SecuritySystemObstruction","SecuritySystemMode","AirQuality","AirPurifierMode","AirPurifierStatus","ChargeState","LockState","PanTiltZoomMovement","ThermostatMode","TemperatureUnit","FanMode","HumidityMode","ScryptedDeviceType","ScryptedInterfaceMethod","CAPTURE_CLASSES","RATE_OPTIONS","RATE_MS","Infinity","DetectionTrainer","lastCapture","Map","captures","images","listeners","loadState","registerListeners","raw","getItem","arr","JSON","parse","r","size","Buffer","from","saveCaptures","setItem","stringify","saveImage","buf","toString","deleteCapture","removeItem","delete","getSettings","cameras","getSystemState","map","filter","d","type","Camera","Doorbell","interfaces","includes","ObjectDetector","settings","key","title","description","c","reviewed","length","label","readonly","cam","push","name","group","choices","putSetting","startsWith","remove","rateKey","rateLabel","listen","async","source","details","onDetection","cameraId","cameraName","rateLimitMs","detections","inputDimensions","now","Date","targets","className","has","toLowerCase","boundingBox","best","sort","a","b","score","oldest","timestamp","jpeg","detectionId","mo","getDetectionInput","convertMediaObjectToBuffer","Math","random","slice","record","detectedClass","round","onRequest","request","response","path","URL","url","pathname","replace","rootPath","img","send","headers","body","rawBody","isBuffer","String","ok","pending","all","stats","total","labeled","byLabel","byCamera","byDetectedClass","classMap","person","animal","face","vehicle","plate","package","discard","dataset","fname","filename","content","encoding","x","y","w","h","imgW","imgH","cx","cy","nw","nh","labelLine","toFixed","yaml","join","files","count","renderUI","require","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","__webpack_modules__","obj","prop","__webpack_exports__"],"sourceRoot":""}
|
package/dist/plugin.zip
ADDED
|
Binary file
|