toposync-ext-streaming 0.1.2__tar.gz → 0.1.3__tar.gz
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.
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/PKG-INFO +1 -1
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/pyproject.toml +1 -1
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/src/toposync_ext_streaming/api/routes.py +4 -1
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/src/toposync_ext_streaming/extension.json +1 -1
- toposync_ext_streaming-0.1.3/src/toposync_ext_streaming/static/703.js +2 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/src/toposync_ext_streaming/wizard/pipeline_builder.py +95 -3
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/ui/src/settings/StreamingSettingsPanel.tsx +4 -4
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/ui/src/settings/WizardCreatePipelineFromTransmission.tsx +8 -8
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/ui/src/translations.ts +14 -14
- toposync_ext_streaming-0.1.2/src/toposync_ext_streaming/static/703.js +0 -2
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/.gitignore +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/LICENSE +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/LICENSE.ffmpeg +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/LICENSE.mediamtx +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/README.md +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/src/toposync_ext_streaming/__init__.py +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/src/toposync_ext_streaming/api/__init__.py +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/src/toposync_ext_streaming/api/models.py +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/src/toposync_ext_streaming/bin/ffmpeg/LICENSE +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/src/toposync_ext_streaming/bin/mediamtx/LICENSE +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/src/toposync_ext_streaming/pipelines/__init__.py +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/src/toposync_ext_streaming/pipelines/operators.py +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/src/toposync_ext_streaming/plugin.py +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/src/toposync_ext_streaming/static/326.js +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/src/toposync_ext_streaming/static/326.js.LICENSE.txt +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/src/toposync_ext_streaming/static/4.js +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/src/toposync_ext_streaming/static/4.js.LICENSE.txt +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/src/toposync_ext_streaming/static/623.js +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/src/toposync_ext_streaming/static/623.js.LICENSE.txt +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/src/toposync_ext_streaming/static/703.js.LICENSE.txt +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/src/toposync_ext_streaming/static/main.js +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/src/toposync_ext_streaming/static/main.js.LICENSE.txt +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/src/toposync_ext_streaming/static/remoteEntry.js +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/src/toposync_ext_streaming/streaming/__init__.py +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/src/toposync_ext_streaming/streaming/arbitration.py +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/src/toposync_ext_streaming/streaming/camera_ingest.py +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/src/toposync_ext_streaming/streaming/distributed_sync.py +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/src/toposync_ext_streaming/streaming/engine_manager.py +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/src/toposync_ext_streaming/streaming/ffmpeg_binary.py +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/src/toposync_ext_streaming/streaming/mediamtx_api_client.py +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/src/toposync_ext_streaming/streaming/mediamtx_binary.py +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/src/toposync_ext_streaming/streaming/mediamtx_config.py +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/src/toposync_ext_streaming/streaming/mediamtx_processes.py +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/src/toposync_ext_streaming/streaming/placeholder.py +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/src/toposync_ext_streaming/streaming/platform.py +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/src/toposync_ext_streaming/streaming/publisher_manager.py +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/src/toposync_ext_streaming/streaming/resize.py +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/src/toposync_ext_streaming/streaming/runtime_state.py +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/src/toposync_ext_streaming/streaming/writer_bridge.py +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/src/toposync_ext_streaming/wizard/__init__.py +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/ui/package.json +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/ui/src/activate.tsx +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/ui/src/api/streamingApi.ts +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/ui/src/constants.ts +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/ui/src/entry.ts +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/ui/src/settings/SubModal.tsx +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/ui/src/types.ts +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/ui/tsconfig.json +0 -0
- {toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/ui/webpack.config.js +0 -0
|
@@ -20,7 +20,7 @@ from toposync.runtime.config_store import (
|
|
|
20
20
|
ProcessingServer,
|
|
21
21
|
)
|
|
22
22
|
from toposync.runtime.pipelines.compiler import GraphCompileError, PipelineGraphCompiler
|
|
23
|
-
from toposync.runtime.pipelines.templates import safe_pipeline_name
|
|
23
|
+
from toposync.runtime.pipelines.templates import camera_names_by_id, safe_pipeline_name
|
|
24
24
|
from toposync.runtime.services import ServiceRegistry
|
|
25
25
|
|
|
26
26
|
from ..streaming.engine_manager import MediaMtxEngineManager
|
|
@@ -1277,7 +1277,10 @@ def create_streaming_router() -> APIRouter:
|
|
|
1277
1277
|
else:
|
|
1278
1278
|
suggested = suggested_streaming_wizard_pipeline_name(
|
|
1279
1279
|
transmission_id=transmission.id,
|
|
1280
|
+
transmission_name=transmission.name,
|
|
1281
|
+
transmission_path=transmission.path,
|
|
1280
1282
|
camera_id=resolved_camera_id,
|
|
1283
|
+
camera_name=camera_names_by_id(app_settings.extensions).get(resolved_camera_id),
|
|
1281
1284
|
preset_id=body.preset_id,
|
|
1282
1285
|
)
|
|
1283
1286
|
pipeline_name = _unique_pipeline_name(suggested, existing_names=existing_names)
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! For license information please see 703.js.LICENSE.txt */
|
|
2
|
+
"use strict";(self.webpackChunk_toposync_extension_streaming_ui=self.webpackChunk_toposync_extension_streaming_ui||[]).push([[703],{87(e,s,t){t.d(s,{D:()=>a});const a="com.toposync.streaming"},94(e,s,t){var a=t(496),i=Symbol.for("react.element"),n=(Symbol.for("react.fragment"),Object.prototype.hasOwnProperty),r=a.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,o={key:!0,ref:!0,__self:!0,__source:!0};function l(e,s,t){var a,l={},m=null,c=null;for(a in void 0!==t&&(m=""+t),void 0!==s.key&&(m=""+s.key),void 0!==s.ref&&(c=s.ref),s)n.call(s,a)&&!o.hasOwnProperty(a)&&(l[a]=s[a]);if(e&&e.defaultProps)for(a in s=e.defaultProps)void 0===l[a]&&(l[a]=s[a]);return{$$typeof:i,type:e,key:m,ref:c,props:l,_owner:r.current}}s.jsx=l,s.jsxs=l},155(e,s,t){t.d(s,{Y:()=>p});var a=t(870),i=t(496),n=t(901),r=t(697);const o=[{id:"simple_stream",titleKey:"ext.streaming.wizard.presets.simple_stream.title",descriptionKey:"ext.streaming.wizard.presets.simple_stream.desc",fallbackTitle:"Simple stream",fallbackDescription:"camera.source + optional fps reducer + stream.publish_video"},{id:"motion_gate_stream",titleKey:"ext.streaming.wizard.presets.motion_gate_stream.title",descriptionKey:"ext.streaming.wizard.presets.motion_gate_stream.desc",fallbackTitle:"Motion gate stream",fallbackDescription:"camera.source + motion gate + fps reducer + stream.publish_video"},{id:"detection_stream",titleKey:"ext.streaming.wizard.presets.detection_stream.title",descriptionKey:"ext.streaming.wizard.presets.detection_stream.desc",fallbackTitle:"Detection stream",fallbackDescription:"camera.source + object detection + stream.publish_video"},{id:"tracking_stream",titleKey:"ext.streaming.wizard.presets.tracking_stream.title",descriptionKey:"ext.streaming.wizard.presets.tracking_stream.desc",fallbackTitle:"Tracking stream",fallbackDescription:"camera.source + object tracking + stream.publish_video"},{id:"segmentation_stream",titleKey:"ext.streaming.wizard.presets.segmentation_stream.title",descriptionKey:"ext.streaming.wizard.presets.segmentation_stream.desc",fallbackTitle:"Segmentation stream",fallbackDescription:"camera.source + object segmentation + stream.publish_video"}];function l(e){const s=String(e||"").trim();if(!s)return;const t=Number(s);return Number.isFinite(t)?t:void 0}function m(e){const s=String(e||"").trim();if(!s)return;const t=Number.parseInt(s,10);return Number.isFinite(t)?t:void 0}function c(e){return String(e||"").trim().toLowerCase()||"local"}function d(e){return String(e||"").normalize("NFD").replace(/[\u0300-\u036f]/g,"").toLowerCase().trim()}function g(e){const s=String(e||"").trim();return s.length<=12?s:`${s.slice(0,8)}...`}function u(e,s){const t=String(s||"").trim();return t&&e.some(e=>String(e.id||"").trim()===t)?t:""}function p({open:e,i18n:s,transmission:t,engineRunning:p,processingServers:x,onClose:h,onCreated:_}){const{t:v}=s.useI18n(),b=(0,i.useId)(),f=(0,i.useRef)(null),[y,j]=(0,i.useState)("form"),[N,w]=(0,i.useState)("simple_stream"),[S,C]=(0,i.useState)(""),[k,z]=(0,i.useState)(!1),[T,M]=(0,i.useState)(""),[A,P]=(0,i.useState)([]),[L,B]=(0,i.useState)(!1),[R,E]=(0,i.useState)(null),[F,D]=(0,i.useState)(""),[U,W]=(0,i.useState)(!0),[I,O]=(0,i.useState)("local"),[H,$]=(0,i.useState)("auto"),[q,G]=(0,i.useState)(!1),[X,K]=(0,i.useState)(""),[V,J]=(0,i.useState)("0.01"),[Q,Y]=(0,i.useState)("6"),[Z,ee]=(0,i.useState)("contain"),[se,te]=(0,i.useState)("0"),[ae,ie]=(0,i.useState)("auto"),[ne,re]=(0,i.useState)("0.55"),[oe,le]=(0,i.useState)(!0),[me,ce]=(0,i.useState)(""),[de,ge]=(0,i.useState)(""),[ue,pe]=(0,i.useState)(!1),[xe,he]=(0,i.useState)(null),[_e,ve]=(0,i.useState)(null),be=String(t?.camera_controls?.camera_id||"").trim();(0,i.useEffect)(()=>{e&&(j("form"),w("simple_stream"),C(""),z(!1),M(""),P([]),B(!1),E(null),D(""),W(!0),O(c(t?.host_server_id)),$("auto"),G(!1),K(""),J("0.01"),Y("6"),ee("contain"),te("0"),ie("auto"),re("0.55"),le(!0),ce(""),ge(""),pe(!1),he(null),ve(null))},[e,t?.host_server_id,t?.id]),(0,i.useEffect)(()=>{if(!e)return;const s=new AbortController;return B(!0),E(null),P([]),(async()=>{try{const e=await(0,n.bO)(s.signal);if(s.signal.aborted)return;const a=Array.isArray(e.cameras)?e.cameras:[];P(a),C(e=>{if(0===a.length)return"";const s=String(e||"").trim();return u(a,s)||function(e,s,t){const a=u(e,s);if(a)return a;const i=[t?.name,t?.path].map(e=>d(String(e||""))).filter(Boolean);if(i.length>0){const s=e.find(e=>{const s=d(String(e.name||"")),t=d(String(e.id||""));return s&&i.includes(s)||t&&i.includes(t)});if(s)return String(s.id||"").trim()}return 1===e.length?String(e[0]?.id||"").trim():""}(a,be,t)})}catch(e){if(e instanceof DOMException&&"AbortError"===e.name)return;E(e instanceof Error?e.message:String(e))}finally{s.signal.aborted||B(!1)}})(),()=>s.abort()},[e,t?.id,t?.name,t?.path,be]),(0,i.useEffect)(()=>{if(k)return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e)};function e(e){const s=f.current;s&&e.target instanceof Node&&(s.contains(e.target)||z(!1))}},[k]);const fe=(0,i.useMemo)(()=>t?t.name?.trim()||t.path?.trim()||t.id:"",[t]),ye=(0,i.useMemo)(()=>o.find(e=>e.id===N)??o[0],[N]),je=(0,i.useMemo)(()=>A.find(e=>String(e.id||"").trim()===S.trim())??null,[S,A]),Ne=(0,i.useMemo)(()=>{const e=new Map;for(const s of A){const t=String(s.name||"").trim();if(!t)continue;const a=d(t);e.set(a,(e.get(a)??0)+1)}return e},[A]),we=(0,i.useMemo)(()=>{const e=d(T);return e?A.filter(s=>d(`${s.name||""} ${s.id||""}`).includes(e)):A},[T,A]),Se=(0,i.useMemo)(()=>function(e){const s=e.find(e=>"local"===c(e.id))??null,t=e.filter(e=>"local"!==c(e.id)).sort((e,s)=>String(e.id||"").localeCompare(String(s.id||"")));return s?[s,...t]:[{id:"local",name:"Local",kind:"inprocess",url:""},...t]}(Array.isArray(x)?x:[]),[x]),Ce=(0,i.useMemo)(()=>{const e=new Set(["local"]);for(const s of Se)e.add(c(s.id));return e},[Se]),ke=c(t?.host_server_id),ze=c(I),Te=ke!==ze;function Me(e){const s=e.split(",").map(e=>e.trim().toLowerCase()).filter(Boolean);if(0!==s.length)return Array.from(new Set(s))}function Ae(e){return String(e?.name||"").trim()||v("ext.streaming.wizard.camera_unnamed",{},"Unnamed camera")}function Pe(e,s){const t=String(e?.id||s||"").trim();if(!t)return"";const a=String(e?.name||"").trim();return a?(Ne.get(d(a))??0)>1?`ID ${g(t)}`:"":`ID ${g(t)}`}return(0,a.jsxs)(r.y,{open:e,title:v("ext.streaming.wizard.title",{},"Criar fluxo para transmissão"),closeAriaLabel:v("core.actions.close",{},"Close"),onClose:()=>{ue||h()},children:["form"===y?(0,a.jsxs)("div",{className:"streamingWizard",children:[(0,a.jsx)("div",{className:"card",children:(0,a.jsxs)("div",{className:"cardBody",children:[(0,a.jsx)("div",{className:"modalSectionTitle",style:{marginBottom:6},children:fe}),(0,a.jsx)("div",{className:"cardMeta",children:t?.id||""}),p?null:(0,a.jsx)("div",{className:"cardMeta",style:{marginTop:8},children:v("ext.streaming.wizard.engine_warning",{},"A engine de streaming está parada. Você pode criar o fluxo agora e iniciar a engine depois.")})]})}),L?(0,a.jsx)("div",{className:"settingsStatusMuted streamingWizardFeedback",children:v("ext.streaming.wizard.loading_cameras",{},"Carregando câmeras…")}):null,R?(0,a.jsx)("div",{className:"errorText streamingWizardFeedback",children:R}):null,xe?(0,a.jsx)("div",{className:"errorText streamingWizardFeedback",children:xe}):null,(0,a.jsx)("div",{className:"card",children:(0,a.jsxs)("div",{className:"cardBody",children:[(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:v("ext.streaming.wizard.camera",{},"Câmera")}),(0,a.jsxs)("div",{className:"streamingCameraPicker",ref:f,children:[(0,a.jsxs)("button",{type:"button",className:"input streamingCameraPickerButton","aria-haspopup":"listbox","aria-expanded":k,"aria-controls":b,onClick:()=>{M(""),z(e=>!e)},onKeyDown:e=>{"ArrowDown"===e.key&&(e.preventDefault(),M(""),z(!0)),"Escape"===e.key&&z(!1)},disabled:L||0===A.length,children:[(0,a.jsxs)("span",{className:"streamingCameraPickerButtonText",children:[(0,a.jsx)("span",{className:"streamingCameraPickerName",children:je?Ae(je):L?v("ext.streaming.wizard.loading_cameras",{},"Loading cameras..."):v("ext.streaming.wizard.camera_placeholder",{},"Select a camera")}),je||S.trim()?(0,a.jsx)("span",{className:"streamingCameraPickerMeta",children:Pe(je,S)}):null]}),(0,a.jsx)("i",{className:"fa-solid "+(k?"fa-chevron-up":"fa-chevron-down"),"aria-hidden":"true"})]}),k?(0,a.jsxs)("div",{className:"streamingCameraPickerPopover",children:[(0,a.jsx)("input",{className:"input streamingCameraPickerSearch",value:T,onChange:e=>M(e.target.value),onKeyDown:e=>{"Escape"===e.key&&(e.preventDefault(),z(!1))},placeholder:v("ext.streaming.wizard.camera_search",{},"Search by name or ID"),autoFocus:!0}),(0,a.jsx)("div",{className:"streamingCameraPickerList",id:b,role:"listbox","aria-label":v("ext.streaming.wizard.camera",{},"Camera"),children:we.length>0?we.map(e=>{const s=String(e.id||"").trim(),t=s===S.trim(),i=Pe(e);return(0,a.jsxs)("button",{type:"button",className:"streamingCameraPickerOption"+(t?" isSelected":""),role:"option","aria-selected":t,onClick:()=>{C(s),z(!1),M("")},children:[(0,a.jsxs)("span",{className:"streamingCameraPickerOptionMain",children:[(0,a.jsx)("span",{className:"streamingCameraPickerOptionName",children:Ae(e)}),i?(0,a.jsx)("span",{className:"streamingCameraPickerOptionMeta",children:i}):null]}),t?(0,a.jsx)("i",{className:"fa-solid fa-check","aria-hidden":"true"}):null]},s)}):(0,a.jsx)("div",{className:"streamingCameraPickerEmpty",children:v("ext.streaming.wizard.camera_no_results",{},"No cameras match your search.")})})]}):null]}),0!==A.length||L?null:(0,a.jsx)("div",{className:"cardMeta",children:v("ext.streaming.wizard.camera_empty",{},"No cameras found. Add a camera in Settings > Cameras.")})]}),(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:v("ext.streaming.wizard.preset",{},"Preset")}),(0,a.jsx)("select",{className:"input",value:N,onChange:e=>w(e.target.value),children:o.map(e=>(0,a.jsx)("option",{value:e.id,children:v(e.titleKey,{},e.fallbackTitle)},e.id))}),(0,a.jsx)("div",{className:"label",children:v(ye.descriptionKey,{},ye.fallbackDescription)})]}),(0,a.jsxs)("div",{className:"rowWrap",style:{gap:10},children:[(0,a.jsxs)("div",{className:"field",style:{flex:1,minWidth:220},children:[(0,a.jsx)("label",{className:"label",children:v("ext.streaming.wizard.pipeline_name",{},"Nome do fluxo (opcional)")}),(0,a.jsx)("input",{className:"input",value:F,onChange:e=>D(e.target.value)})]}),(0,a.jsxs)("div",{className:"field",style:{width:180},children:[(0,a.jsx)("label",{className:"label",children:v("ext.streaming.wizard.processing_server",{},"Processing server")}),(0,a.jsxs)("select",{className:"input",value:ze,onChange:e=>O(c(e.target.value)),children:[Se.map(e=>{const s=c(e.id),t=String(e.name||"").trim(),i="local"===s?v("ext.streaming.processing_servers.local_label",{},"local (this machine)"):t?`${s} (${t})`:s;return(0,a.jsx)("option",{value:s,children:i},s)}),Ce.has(ze)?null:(0,a.jsx)("option",{value:ze,children:ze})]})]})]}),Te?(0,a.jsx)("div",{className:"errorText",children:v("ext.streaming.wizard.host_mismatch_inline",{transmissionHost:ke,pipelineHost:ze},`Transmission is hosted on ${ke} and pipeline is on ${ze}. They must match.`)}):null,(0,a.jsxs)("div",{className:"rowWrap",style:{gap:10},children:[(0,a.jsxs)("div",{className:"field",style:{width:170},children:[(0,a.jsx)("label",{className:"label",children:v("ext.streaming.wizard.fps",{},"FPS limit")}),(0,a.jsx)("input",{className:"input",value:X,onChange:e=>K(e.target.value),placeholder:"5"})]}),(0,a.jsxs)("div",{className:"field",style:{width:170},children:[(0,a.jsx)("label",{className:"label",children:v("ext.streaming.wizard.writer_priority",{},"Writer priority")}),(0,a.jsx)("input",{className:"input",value:se,onChange:e=>te(e.target.value)})]}),(0,a.jsxs)("div",{className:"field",style:{width:180},children:[(0,a.jsx)("label",{className:"label",children:v("ext.streaming.wizard.source_backend",{},"Backend da câmera")}),(0,a.jsxs)("select",{className:"input",value:H,onChange:e=>$(e.target.value),children:[(0,a.jsx)("option",{value:"auto",children:v("ext.streaming.wizard.source_backend.option.auto",{},"Auto")}),(0,a.jsx)("option",{value:"opencv",children:v("ext.streaming.wizard.source_backend.option.opencv",{},"OpenCV")}),(0,a.jsx)("option",{value:"ffmpeg",children:v("ext.streaming.wizard.source_backend.option.ffmpeg",{},"FFmpeg")})]})]}),(0,a.jsxs)("div",{className:"field",style:{width:180},children:[(0,a.jsx)("label",{className:"label",children:v("ext.streaming.wizard.bypass_mode",{},"Bypass mode")}),(0,a.jsxs)("select",{className:"input",value:ae,onChange:e=>ie(e.target.value),children:[(0,a.jsx)("option",{value:"auto",children:v("ext.streaming.wizard.bypass_mode.option.auto",{},"Auto")}),(0,a.jsx)("option",{value:"force_on",children:v("ext.streaming.wizard.bypass_mode.option.force_on",{},"Force on")}),(0,a.jsx)("option",{value:"force_off",children:v("ext.streaming.wizard.bypass_mode.option.force_off",{},"Force off")})]})]})]}),(0,a.jsxs)("div",{className:"rowWrap",style:{gap:10},children:[(0,a.jsxs)("div",{className:"field",style:{width:180},children:[(0,a.jsx)("label",{className:"label",children:v("ext.streaming.wizard.resize_mode",{},"Resize mode")}),(0,a.jsxs)("select",{className:"input",value:Z,onChange:e=>ee(e.target.value),children:[(0,a.jsx)("option",{value:"contain",children:v("ext.streaming.wizard.resize_mode.option.contain",{},"Contain")}),(0,a.jsx)("option",{value:"none",children:v("ext.streaming.wizard.resize_mode.option.none",{},"No resize")})]})]}),(0,a.jsxs)("div",{className:"field",style:{width:180},children:[(0,a.jsx)("label",{className:"label",children:v("ext.streaming.wizard.motion_sensitivity",{},"Motion sensitivity")}),(0,a.jsx)("input",{className:"input",value:V,onChange:e=>J(e.target.value)})]}),(0,a.jsxs)("div",{className:"field",style:{width:180},children:[(0,a.jsx)("label",{className:"label",children:v("ext.streaming.wizard.motion_hold",{},"Motion hold (s)")}),(0,a.jsx)("input",{className:"input",value:Q,onChange:e=>Y(e.target.value)})]}),(0,a.jsxs)("div",{className:"field",style:{width:180},children:[(0,a.jsx)("label",{className:"label",children:v("ext.streaming.wizard.yolo_conf",{},"Vision confidence")}),(0,a.jsx)("input",{className:"input",value:ne,onChange:e=>re(e.target.value)})]})]}),(0,a.jsxs)("div",{className:"field",children:[(0,a.jsxs)("label",{className:"rowWrap",style:{gap:10},children:[(0,a.jsx)("input",{type:"checkbox",checked:oe,onChange:e=>le(e.target.checked)}),(0,a.jsx)("span",{className:"cardMeta",children:v("ext.streaming.wizard.yolo_filter_enabled",{},"Filter frames after vision (recommended)")})]}),(0,a.jsx)("div",{className:"cardMeta",style:{marginLeft:28},children:v("ext.streaming.wizard.yolo_filter_enabled.hint",{},"When disabled, the pipeline still runs vision inference but keeps all frames.")})]}),(0,a.jsxs)("div",{className:"rowWrap",style:{gap:10},children:[(0,a.jsxs)("div",{className:"field",style:{flex:1,minWidth:260},children:[(0,a.jsx)("label",{className:"label",children:v("ext.streaming.wizard.detection_categories",{},"Detection categories (csv)")}),(0,a.jsx)("input",{className:"input",value:me,onChange:e=>ce(e.target.value),placeholder:"person,car"})]}),(0,a.jsxs)("div",{className:"field",style:{flex:1,minWidth:260},children:[(0,a.jsx)("label",{className:"label",children:v("ext.streaming.wizard.tracking_categories",{},"Tracking categories (csv)")}),(0,a.jsx)("input",{className:"input",value:de,onChange:e=>ge(e.target.value),placeholder:"person,car"})]})]}),(0,a.jsx)("div",{className:"field",children:(0,a.jsxs)("label",{className:"rowWrap",style:{gap:10},children:[(0,a.jsx)("input",{type:"checkbox",checked:U,onChange:e=>W(e.target.checked)}),(0,a.jsx)("span",{className:"cardMeta",children:v("ext.streaming.wizard.enabled",{},"Fluxo habilitado após criação")})]})}),(0,a.jsx)("div",{className:"field",children:(0,a.jsxs)("label",{className:"rowWrap",style:{gap:10},children:[(0,a.jsx)("input",{type:"checkbox",checked:q,onChange:e=>G(e.target.checked)}),(0,a.jsx)("span",{className:"cardMeta",children:v("ext.streaming.wizard.use_fps_reducer",{},"Inserir step core.fps_reducer")})]})})]})}),(0,a.jsxs)("div",{className:"rowWrap",style:{marginTop:14,justifyContent:"flex-end",gap:10},children:[(0,a.jsx)("button",{className:"chipButton",type:"button",onClick:h,disabled:ue,children:v("core.actions.cancel",{},"Cancelar")}),(0,a.jsx)("button",{className:"primaryButton",type:"button",onClick:()=>{!async function(){if(t)if(S.trim())if(Ce.has(ze))if(Te)he(v("ext.streaming.wizard.errors.host_mismatch",{transmissionHost:ke,pipelineHost:ze},`Transmission is hosted on '${ke}'. Select the same processing server for the pipeline.`));else{pe(!0),he(null),z(!1);try{const e=await(0,n.A$)({transmission_id:t.id,camera_id:S.trim(),preset_id:N,optional_parameters:{pipeline_name:F.trim()||void 0,enabled:U,processing_server_id:ze,source_backend:H,use_fps_reducer:q,fps_limit:l(X),motion_sensitivity:l(V),motion_hold_seconds:l(Q),resize_mode:Z,writer_priority:m(se),bypass_mode:ae,yolo_confidence_threshold:l(ne),yolo_filter_enabled:oe,detection_categories:Me(me),tracking_categories:Me(de)}});ve(e),j("done"),_(e)}catch(e){he(e instanceof Error?e.message:String(e))}finally{pe(!1)}}else he(v("ext.streaming.wizard.errors.invalid_processing_server",{serverId:ze},`Invalid processing server: ${ze}`));else he(v("ext.streaming.wizard.errors.select_camera",{},"Select a camera."))}()},disabled:ue||!S.trim()||Te||!Ce.has(ze),children:ue?v("ext.streaming.wizard.creating",{},"Criando…"):v("ext.streaming.wizard.create",{},"Criar fluxo")})]})]}):null,"done"===y&&_e?(0,a.jsxs)("div",{className:"streamingWizard",children:[(0,a.jsx)("div",{className:"card",children:(0,a.jsxs)("div",{className:"cardBody",children:[(0,a.jsx)("div",{className:"modalSectionTitle",style:{marginBottom:6},children:v("ext.streaming.wizard.done_title",{},"Fluxo criado")}),(0,a.jsxs)("div",{className:"cardMeta",children:[v("ext.streaming.wizard.pipeline_created_name",{},"Fluxo"),": ",_e.pipeline_name]}),Array.isArray(_e.warnings)&&_e.warnings.length>0?(0,a.jsx)("div",{className:"cardMeta",style:{marginTop:8},children:_e.warnings.join(" ")}):null]})}),(0,a.jsxs)("div",{className:"rowWrap",style:{marginTop:14,justifyContent:"flex-end",gap:10},children:[(0,a.jsx)("button",{className:"chipButton",type:"button",onClick:h,children:v("core.actions.close",{},"Fechar")}),(0,a.jsx)("button",{className:"primaryButton",type:"button",onClick:()=>{!function(){if("undefined"==typeof window)return;const e="/settings/pipelines";window.location.pathname!==e&&(window.history.pushState(null,"",e),window.dispatchEvent(new PopStateEvent("popstate")))}(),h()},children:v("ext.streaming.wizard.open_pipelines",{},"Abrir Fluxos")})]})]}):null]})}},323(e,s,t){t.d(s,{w:()=>v});var a=t(870),i=t(496),n=t(901),r=t(87),o=t(697),l=t(155);function m(e,s){const t=Number.parseInt(String(e||"").trim(),10);return Number.isFinite(t)?t:s}function c(e){const s=String(e||"").trim();if(!s)return null;const t=Number.parseInt(s,10);return Number.isFinite(t)?t:null}function d(e){const s=String(e||"").trim().toLowerCase();return s?Array.from(s).map(e=>/[a-z0-9_-]/.test(e)?e:"-").join("").replace(/-+/g,"-").replace(/^[-_]+|[-_]+$/g,""):""}function g(e){return"function"==typeof structuredClone?structuredClone(e):JSON.parse(JSON.stringify(e))}function u(e){try{const s=globalThis.crypto;if(s?.randomUUID)return`${e}_${s.randomUUID()}`}catch{}return`${e}_${Date.now()}_${Math.floor(1e6*Math.random())}`}function p(e){const s=String(e||"").replace(/\r/g,"").split(/[\n,]/g),t=[],a=new Set;for(const e of s){const s=String(e||"").trim();if(!s)continue;const i=s.toLowerCase();(i.startsWith("stun:")||i.startsWith("turn:")||i.startsWith("turns:"))&&(a.has(i)||(a.add(i),t.push(s)))}return t}function x(e){if(!Number.isFinite(e)||!e||e<1)return"-";const s=Math.max(0,Math.floor(e)),t=Math.floor(s/3600),a=Math.floor(s%3600/60),i=s%60;return t>0?`${t}h ${a}m`:a>0?`${a}m ${i}s`:`${i}s`}function h(e){return{id:u("output"),protocol:e,enabled:!0,resolution:{width:1280,height:720},fps_limit:12,bitrate_kbps:null,latency_profile:"normal",authentication:{enabled:!1,username:"",password:""}}}function _(e){return String(e||"").trim().toLowerCase()||"local"}function v(){return{id:r.D,icon:"tower-broadcast",name:{key:"ext.streaming.settings.name",fallback:"Transmissões"},description:{key:"ext.streaming.settings.desc"},render:({i18n:e,settings:s})=>(0,a.jsx)(b,{i18n:e,settings:s})}}function b({i18n:e,settings:s}){const{t}=e.useI18n(),[r,u]=(0,i.useState)(!0),[v,b]=(0,i.useState)(null),[f,y]=(0,i.useState)(null),[j,N]=(0,i.useState)(!0),[w,S]=(0,i.useState)(!1),[C,k]=(0,i.useState)(null),[z,T]=(0,i.useState)(null),[M,A]=(0,i.useState)(null),[P,L]=(0,i.useState)(!0),[B,R]=(0,i.useState)(null),[E,F]=(0,i.useState)(null),[D,U]=(0,i.useState)(null),[W,I]=(0,i.useState)(!1),[O,H]=(0,i.useState)(!1),[$,q]=(0,i.useState)(!0),[G,X]=(0,i.useState)(null),[K,V]=(0,i.useState)([]),[J,Q]=(0,i.useState)(""),[Y,Z]=(0,i.useState)(null),[ee,se]=(0,i.useState)(null),[te,ae]=(0,i.useState)(!1),[ie,ne]=(0,i.useState)(null),[re,oe]=(0,i.useState)(!1),[le,me]=(0,i.useState)(!1),[ce,de]=(0,i.useState)(null),[ge,ue]=(0,i.useState)({}),[pe,xe]=(0,i.useState)(null),[he,_e]=(0,i.useState)(null),[ve,be]=(0,i.useState)(!0),[fe,ye]=(0,i.useState)(null),[je,Ne]=(0,i.useState)([{id:"local",name:"Local",kind:"inprocess",url:""}]),[we,Se]=(0,i.useState)(!1),[Ce,ke]=(0,i.useState)(!1),[ze,Te]=(0,i.useState)(null),[Me,Ae]=(0,i.useState)(""),[Pe,Le]=(0,i.useState)(""),[Be,Re]=(0,i.useState)("local"),[Ee,Fe]=(0,i.useState)("hls"),[De,Ue]=(0,i.useState)("1280"),[We,Ie]=(0,i.useState)("720"),[Oe,He]=(0,i.useState)("12"),[$e,qe]=(0,i.useState)(!1),[Ge,Xe]=(0,i.useState)(""),[Ke,Ve]=(0,i.useState)(!1),[Je,Qe]=(0,i.useState)(null),[Ye,Ze]=(0,i.useState)([]),[es,ss]=(0,i.useState)(!1),[ts,as]=(0,i.useState)(!1),[is,ns]=(0,i.useState)(null),[rs,os]=(0,i.useState)(null),ls=(0,i.useMemo)(()=>{const e=s.transmissions;return Array.isArray(e)?e.length:0},[s.transmissions]),ms=K.length>0?K.length:ls,cs=(0,i.useCallback)(async e=>{u(!0),y(null);try{const s=await(0,n.m9)(e);b(s)}catch(e){if(e instanceof DOMException&&"AbortError"===e.name)return;b(null),y(e instanceof Error?e.message:String(e))}finally{e?.aborted||u(!1)}},[]),ds=(0,i.useCallback)(async e=>{N(!0),A(null);try{const s=await(0,n.JB)(e);T(s)}catch(e){if(e instanceof DOMException&&"AbortError"===e.name)return;T(null),A(e instanceof Error?e.message:String(e))}finally{e?.aborted||N(!1)}},[]),gs=(0,i.useCallback)(async e=>{L(!0),R(null);try{const s=await(0,n.WO)(e);if(e?.aborted)return;F(s),U(g(s.engine??{})),I(!1)}catch(e){if(e instanceof DOMException&&"AbortError"===e.name)return;F(null),R(e instanceof Error?e.message:String(e))}finally{e?.aborted||L(!1)}},[]),us=(0,i.useCallback)(async e=>{q(!0),X(null);try{const s=await(0,n.I$)(e);V(s)}catch(e){if(e instanceof DOMException&&"AbortError"===e.name)return;V([]),X(e instanceof Error?e.message:String(e))}finally{e?.aborted||q(!1)}},[]),ps=(0,i.useCallback)(async e=>{be(!0),ye(null);try{const s=await(0,n.cr)(e);if(e?.aborted)return;Ne(function(e){const s=e.find(e=>"local"===_(e.id))??null,t=e.filter(e=>"local"!==_(e.id)).sort((e,s)=>String(e.id||"").localeCompare(String(s.id||"")));return s?[s,...t]:[{id:"local",name:"Local",kind:"inprocess",url:""},...t]}(Array.isArray(s)?s:[]))}catch(e){if(e instanceof DOMException&&"AbortError"===e.name)return;Ne([{id:"local",name:"Local",kind:"inprocess",url:""}]),ye(e instanceof Error?e.message:String(e))}finally{e?.aborted||be(!1)}},[]),xs=(0,i.useCallback)(async e=>{Ve(!0),Qe(null);try{const s=await(0,n.bO)(e);if(e?.aborted)return;const t=Array.isArray(s.cameras)?s.cameras:[];Ze(t)}catch(e){if(e instanceof DOMException&&"AbortError"===e.name)return;Ze([]),Qe(e instanceof Error?e.message:String(e))}finally{e?.aborted||Ve(!1)}},[]);(0,i.useEffect)(()=>{const e=new AbortController;return cs(e.signal),ds(e.signal),gs(e.signal),us(e.signal),ps(e.signal),xs(e.signal),()=>e.abort()},[xs,ds,cs,ps,gs,us]),(0,i.useEffect)(()=>{const e=window.setInterval(()=>{"hidden"!==document.visibilityState&&ds()},5e3);return()=>window.clearInterval(e)},[ds]),(0,i.useEffect)(()=>{Y&&K.some(e=>e.id===Y)||Z(K[0]?.id??null)},[Y,K]);const hs=(0,i.useMemo)(()=>Y?K.find(e=>e.id===Y)??null:null,[Y,K]);(0,i.useEffect)(()=>{if(!hs)return ne(null),oe(!1),void de(null);re||(ne(g(hs)),de(null))},[hs,re]);const _s=(0,i.useMemo)(()=>{const e=J.trim().toLowerCase();return e?K.filter(s=>{const t=String(s.name||"").trim().toLowerCase(),a=String(s.path||"").trim().toLowerCase(),i=String(s.id||"").trim().toLowerCase();return t.includes(e)||a.includes(e)||i.includes(e)}):K},[J,K]),vs=(0,i.useMemo)(()=>{const e=new Set(["local"]);for(const s of je)e.add(_(s.id));return e},[je]);async function bs(e){if("reclaim"!==e||confirm(t("ext.streaming.engine.reclaim_confirm",{},"This will try to stop and cleanup stale MediaMTX processes for this data directory. Continue?"))){S(!0),k(e),A(null);try{const s=await(0,n.hF)(e);T(s),gs()}catch(e){A(e instanceof Error?e.message:String(e)),ds()}finally{S(!1),k(null)}}}async function fs(e){xe(e),X(null);try{const s=await(0,n.pU)(e);ue(t=>({...t,[e]:s}))}catch(e){X(e instanceof Error?e.message:String(e))}finally{xe(null)}}function ys(e){ne(s=>s?{...s,...e}:s),oe(!0),de(null)}function js(e,s){ne(t=>{if(!t)return t;const a=Array.isArray(t.outputs)?t.outputs:[];return{...t,outputs:a.map(t=>t.id===e?{...t,...s}:t)}}),oe(!0),de(null)}function Ns(e){ne(s=>{if(!s)return s;const t=Array.isArray(s.outputs)?s.outputs:[];return{...s,outputs:[...t,h(e)]}}),oe(!0),de(null)}async function ws(){if(ie){me(!0),de(null);try{const e=_(ie.host_server_id);if(!vs.has(e))return void de(t("ext.streaming.errors.invalid_host_server",{serverId:e},`Invalid host server: ${e}`));const s={...ie,id:ie.id||Y||"",host_server_id:e},a=await(0,n.Cs)(s.id,s);V(e=>e.map(e=>e.id===a.id?a:e)),ne(g(a)),oe(!1),fs(a.id)}catch(e){de(e instanceof Error?e.message:String(e))}finally{me(!1)}}}(0,i.useEffect)(()=>{if(!we)return;if(qe(!1),Xe(""),Ye.length>0)return;const e=new AbortController;return xs(e.signal),()=>e.abort()},[we,xs]),(0,i.useEffect)(()=>{we&&(Ge.trim()||0!==Ye.length&&Xe(String(Ye[0]?.id||"").trim()))},[Ye,we,Ge]);const Ss=Y?ge[Y]??null:null,Cs=Boolean(z?.running),ks=Array.isArray(z?.orphan_pids)?z.orphan_pids:[],zs=Cs?"restart":"start",Ts="start"===C?t("ext.streaming.engine.starting",{},"Iniciando…"):"restart"===C?t("ext.streaming.engine.restarting",{},"Reiniciando…"):Cs?t("ext.streaming.engine.restart",{},"Reiniciar"):t("ext.streaming.engine.start",{},"Iniciar"),Ms="stop"===C?t("ext.streaming.engine.stopping",{},"Parando…"):t("ext.streaming.engine.stop",{},"Parar"),As="reclaim"===C?t("ext.streaming.engine.reclaiming",{},"Recuperando…"):t("ext.streaming.engine.reclaim",{},"Recuperar"),Ps="download"===C?t("ext.streaming.engine.downloading",{},"Baixando…"):t("ext.streaming.engine.download",{},"Baixar engine"),Ls="refresh"===C?t("ext.streaming.engine.refreshing",{},"Atualizando…"):t("ext.streaming.engine.refresh",{},"Atualizar");return(0,a.jsxs)("div",{className:"streamingSettingsPanel",children:[(0,a.jsx)("div",{className:"card",children:(0,a.jsxs)("div",{className:"cardBody",children:[(0,a.jsx)("div",{className:"modalSectionTitle",style:{marginBottom:6},children:t("ext.streaming.settings.title",{},"Transmissões")}),(0,a.jsx)("div",{className:"cardMeta",children:t("ext.streaming.settings.subtitle",{},"Crie transmissões, configure saídas (HLS/RTSP/WebRTC) e gere URLs a partir do MediaMTX.")}),(0,a.jsxs)("div",{className:"streamingQuickSteps",children:[(0,a.jsx)("div",{className:"streamingQuickStepsTitle",children:t("ext.streaming.settings.quickstart",{},"Fluxo Recomendado")}),(0,a.jsxs)("ol",{className:"streamingQuickStepsList",children:[(0,a.jsx)("li",{children:t("ext.streaming.settings.quickstart_step_1",{},"Crie uma transmissão com ao menos uma saída.")}),(0,a.jsx)("li",{children:t("ext.streaming.settings.quickstart_step_2",{},"Ajuste resolução/FPS/autenticação por saída.")}),(0,a.jsx)("li",{children:t("ext.streaming.settings.quickstart_step_3",{},"Salve, carregue URLs e use o wizard para gerar o fluxo.")})]})]})]})}),(0,a.jsx)("div",{className:"sectionDivider"}),(0,a.jsx)("div",{className:"card",children:(0,a.jsxs)("div",{className:"cardBody",children:[(0,a.jsxs)("div",{className:"cardMeta",children:[t("ext.streaming.settings.transmissions",{},"Transmissões configuradas"),": ",ms]}),r?(0,a.jsx)("div",{className:"settingsStatusMuted",children:t("ext.streaming.settings.health.loading")}):null,r||f||"ok"!==v?.status?null:(0,a.jsx)("div",{className:"streamingStatusOk",children:t("ext.streaming.settings.health.ok")}),r||!f&&"ok"===v?.status?null:(0,a.jsxs)("div",{className:"errorText",children:[t("ext.streaming.settings.health.failed")," ",f?`(${f})`:""]}),(0,a.jsx)("div",{className:"rowWrap",children:(0,a.jsx)("button",{className:"chipButton",type:"button",onClick:()=>{cs()},children:t("ext.streaming.settings.health.refresh")})})]})}),(0,a.jsx)("div",{className:"sectionDivider"}),(0,a.jsx)("div",{className:"card",children:(0,a.jsxs)("div",{className:"cardBody",children:[(0,a.jsx)("div",{className:"modalSectionTitle",style:{marginBottom:6},children:t("ext.streaming.engine.title",{},"Engine (MediaMTX)")}),j?(0,a.jsx)("div",{className:"settingsStatusMuted",children:t("ext.streaming.engine.loading")}):null,!j&&z?.running?(0,a.jsx)("div",{className:"streamingStatusOk",children:t("ext.streaming.engine.running")}):null,j||z?.running?null:(0,a.jsx)("div",{className:"settingsStatusMuted",children:t("ext.streaming.engine.stopped")}),z?(0,a.jsxs)("div",{className:"streamingFormGrid streamingFormGridEnginePorts",style:{marginTop:10},children:[(0,a.jsxs)("div",{className:"cardMeta",children:[t("ext.streaming.engine.meta_version",{},"Versão"),": ",z.mediamtx_version||"-"]}),(0,a.jsxs)("div",{className:"cardMeta",children:[t("ext.streaming.engine.meta_pid",{},"PID"),": ",z.pid??"-"]}),(0,a.jsxs)("div",{className:"cardMeta",children:[t("ext.streaming.engine.meta_uptime",{},"Uptime"),": ",x(z.uptime_seconds)]}),(0,a.jsxs)("div",{className:"cardMeta",children:[t("ext.streaming.engine.meta_api",{},"API"),": ",z.ports?.api??"-"]})]}):null,z?.bind_host&&z?.ports?(0,a.jsxs)("div",{className:"cardMeta",style:{marginTop:6},children:[z.bind_host," - RTSP ",z.ports.rtsp??"-"," - HLS ",z.ports.hls??"-"," - WebRTC"," ",z.ports.webrtc??"-"]}):null,z?.urls?.rtsp_url?(0,a.jsxs)("div",{className:"cardMeta",style:{marginTop:6},children:[t("ext.streaming.engine.test_rtsp",{},"RTSP (test)"),": ",z.urls.rtsp_url]}):null,z?.urls?.hls_url?(0,a.jsxs)("div",{className:"cardMeta",children:[t("ext.streaming.engine.test_hls",{},"HLS (test)"),": ",z.urls.hls_url]}):null,z?.urls?.webrtc_url?(0,a.jsxs)("div",{className:"cardMeta",children:[t("ext.streaming.engine.test_webrtc",{},"WebRTC/WHEP (test)"),": ",z.urls.webrtc_url]}):null,Array.isArray(z?.warnings)&&z.warnings.length>0?(0,a.jsx)("div",{style:{marginTop:6},children:z.warnings.map((e,s)=>(0,a.jsx)("div",{className:"cardMeta",style:s>0?{marginTop:4}:void 0,children:e},`${e}-${s}`))}):null,ks.length>0?(0,a.jsx)("div",{className:"cardMeta",style:{marginTop:6},children:t("ext.streaming.engine.orphan_processes",{count:ks.length,pids:ks.join(", ")},`Found ${ks.length} external MediaMTX process(es) for this data directory: ${ks.join(", ")}.`)}):null,z?.last_error?(0,a.jsx)("div",{className:"errorText",style:{marginTop:6},children:z.last_error}):null,M?(0,a.jsx)("div",{className:"errorText",style:{marginTop:6},children:M}):null,(0,a.jsxs)("div",{className:"rowWrap",style:{gap:8},children:[(0,a.jsx)("button",{className:"primaryButton",type:"button",disabled:w,onClick:()=>{bs(zs)},children:Ts}),(0,a.jsxs)("button",{className:"chipButton",type:"button",disabled:w,onClick:()=>{!async function(){S(!0),k("download"),A(null);try{const e=await(0,n.jP)();T(e),gs()}catch(e){A(e instanceof Error?e.message:String(e)),ds()}finally{S(!1),k(null)}}()},children:[(0,a.jsx)("i",{className:"fa-solid fa-download","aria-hidden":"true"})," ",Ps]}),(0,a.jsx)("button",{className:"chipButton",type:"button",disabled:w||!Cs,onClick:()=>{bs("stop")},children:Ms}),(0,a.jsxs)("button",{className:"chipButton",type:"button",disabled:w,onClick:()=>{bs("reclaim")},children:[(0,a.jsx)("i",{className:"fa-solid fa-broom","aria-hidden":"true"})," ",As]}),(0,a.jsxs)("button",{className:"chipButton",type:"button",disabled:w||"refresh"===C,onClick:()=>{!async function(){k("refresh");try{await ds()}finally{k(null)}}()},children:[(0,a.jsx)("i",{className:"fa-solid fa-rotate-right","aria-hidden":"true"})," ",Ls]})]}),z?(0,a.jsxs)("div",{style:{marginTop:10},children:[(0,a.jsxs)("div",{className:"cardMeta",children:[t("ext.streaming.engine.meta_restarts",{},"Reinícios"),": ",z.restart_count??0]}),z.binary_path?(0,a.jsxs)("div",{className:"cardMeta",style:{marginTop:4},children:[t("ext.streaming.engine.meta_binary",{},"Binário"),": ",z.binary_path]}):null,z.config_path?(0,a.jsxs)("div",{className:"cardMeta",style:{marginTop:4},children:[t("ext.streaming.engine.meta_config",{},"Config"),": ",z.config_path]}):null,z.log_path?(0,a.jsxs)("div",{className:"cardMeta",style:{marginTop:4},children:[t("ext.streaming.engine.meta_log",{},"Log"),": ",z.log_path]}):null]}):null,(0,a.jsx)("div",{className:"sectionDivider"}),(0,a.jsx)("div",{className:"modalSectionTitle",style:{marginBottom:6},children:t("ext.streaming.engine.settings_title",{},"Configuração")}),P?(0,a.jsx)("div",{className:"settingsStatusMuted",children:t("ext.streaming.engine.settings_loading",{},"Carregando…")}):null,B?(0,a.jsx)("div",{className:"errorText",children:B}):null,!P&&D?(0,a.jsxs)("div",{children:[(0,a.jsx)("div",{className:"rowWrap",style:{gap:10},children:(0,a.jsxs)("label",{className:"rowWrap",style:{gap:8},children:[(0,a.jsx)("input",{type:"checkbox",checked:Boolean(D.expose_to_lan),onChange:e=>{U(s=>({...s??{},expose_to_lan:e.target.checked})),I(!0)}}),(0,a.jsx)("span",{className:"cardMeta",children:t("ext.streaming.engine.expose_to_lan",{},"Expor na LAN (0.0.0.0)")})]})}),(0,a.jsxs)("div",{className:"streamingFormGrid streamingFormGridEnginePorts",style:{marginTop:10},children:[(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.engine.port_rtsp",{},"RTSP port")}),(0,a.jsx)("input",{className:"input",value:String(D.preferred_ports?.rtsp??""),onChange:e=>{const s=c(e.target.value);U(e=>({...e??{},preferred_ports:{...e?.preferred_ports??{},rtsp:s??void 0}})),I(!0)}})]}),(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.engine.port_hls",{},"HLS port")}),(0,a.jsx)("input",{className:"input",value:String(D.preferred_ports?.hls??""),onChange:e=>{const s=c(e.target.value);U(e=>({...e??{},preferred_ports:{...e?.preferred_ports??{},hls:s??void 0}})),I(!0)}})]}),(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.engine.port_webrtc",{},"WebRTC port")}),(0,a.jsx)("input",{className:"input",value:String(D.preferred_ports?.webrtc??""),onChange:e=>{const s=c(e.target.value);U(e=>({...e??{},preferred_ports:{...e?.preferred_ports??{},webrtc:s??void 0}})),I(!0)}})]}),(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.engine.port_api",{},"API port")}),(0,a.jsx)("input",{className:"input",value:String(D.preferred_ports?.api??""),onChange:e=>{const s=c(e.target.value);U(e=>({...e??{},preferred_ports:{...e?.preferred_ports??{},api:s??void 0}})),I(!0)}})]})]}),(0,a.jsxs)("div",{className:"field",style:{marginTop:10},children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.engine.ice_servers_label",{},"STUN/TURN servers (optional, one per line)")}),(0,a.jsx)("textarea",{className:"input",style:{minHeight:84,padding:"8px 10px"},value:(Bs=D.webrtc_ice_servers,Array.isArray(Bs)&&0!==Bs.length?Bs.map(e=>String(e||"").trim()).filter(Boolean).join("\n"):""),placeholder:"stun:stun.l.google.com:19302\nturn:username:password@turn.example.com:3478?transport=udp",onChange:e=>{U(s=>({...s??{},webrtc_ice_servers:p(e.target.value)})),I(!0)}}),(0,a.jsx)("div",{className:"cardMeta",style:{marginTop:6},children:t("ext.streaming.engine.ice_servers_hint",{},"Use only when you need to traverse NAT. On a simple LAN, leave it empty.")})]}),(0,a.jsxs)("div",{className:"rowWrap",style:{gap:8,justifyContent:"flex-end",marginTop:10},children:[(0,a.jsx)("button",{className:"chipButton",type:"button",disabled:!W||O,onClick:()=>{E?.engine&&(U(g(E.engine)),I(!1))},children:t("ext.streaming.engine.settings_discard",{},"Descartar")}),(0,a.jsx)("button",{className:"primaryButton",type:"button",disabled:!W||O,onClick:()=>{!async function(){if(D){H(!0),R(null);try{const e=await(0,n.eR)({engine:{expose_to_lan:Boolean(D.expose_to_lan),preferred_ports:{rtsp:D.preferred_ports?.rtsp,hls:D.preferred_ports?.hls,api:D.preferred_ports?.api,webrtc:D.preferred_ports?.webrtc},webrtc_ice_servers:Array.isArray(D.webrtc_ice_servers)?D.webrtc_ice_servers:[]}});F(e),U(g(e.engine??{})),I(!1),ds()}catch(e){R(e instanceof Error?e.message:String(e))}finally{H(!1)}}}()},children:O?t("ext.streaming.engine.settings_applying",{},"Aplicando…"):t("ext.streaming.engine.settings_apply",{},"Aplicar")})]})]}):null]})}),(0,a.jsx)("div",{className:"sectionDivider"}),(0,a.jsxs)("div",{className:"settingsSplit",children:[(0,a.jsxs)("div",{className:"settingsSplitSidebar",children:[(0,a.jsxs)("div",{className:"settingsSplitToolbar",children:[(0,a.jsx)("input",{className:"input",placeholder:t("ext.streaming.transmissions.search",{},"Buscar transmissões…"),value:J,onChange:e=>Q(e.target.value)}),(0,a.jsx)("button",{className:"iconButton iconButtonPrimary",type:"button","aria-label":t("ext.streaming.transmissions.add",{},"Adicionar transmissão"),onClick:()=>{Te(null),Re("local"),Se(!0)},children:(0,a.jsx)("i",{className:"fa-solid fa-plus","aria-hidden":"true"})})]}),$?(0,a.jsx)("div",{className:"settingsStatusMuted",style:{marginTop:10},children:t("ext.streaming.transmissions.loading",{},"Carregando…")}):null,G?(0,a.jsx)("div",{className:"errorText",style:{marginTop:10},children:G}):null,ve?(0,a.jsx)("div",{className:"settingsStatusMuted",style:{marginTop:10},children:t("ext.streaming.processing_servers.loading",{},"Loading processing servers…")}):null,fe?(0,a.jsx)("div",{className:"errorText",style:{marginTop:10},children:fe}):null,0!==_s.length||$?(0,a.jsx)("div",{className:"settingsList",children:_s.map(e=>{const s=e.id===Y,i=String(e.name||"").trim()||String(e.path||"").trim()||e.id,n=_(e.host_server_id),r=Array.isArray(e.outputs)?e.outputs.length:0,o=t("ext.streaming.transmissions.meta_line",{host:n,path:e.path||"-",outputs:r},`host: ${n} • path: ${e.path||"-"} • outputs: ${r}`);return(0,a.jsx)("button",{type:"button",className:["choiceItem",s?"isSelected":""].filter(Boolean).join(" "),onClick:()=>function(e){if(e!==Y)return re?(se(e),void ae(!0)):void Z(e)}(e.id),children:(0,a.jsxs)("div",{className:"settingsListItemRow",children:[(0,a.jsxs)("div",{className:"settingsListItemMain",children:[(0,a.jsx)("div",{className:"settingsListItemTitle",title:i,children:i}),(0,a.jsx)("div",{className:"settingsListItemMeta",title:o,children:o})]}),e.enabled?null:(0,a.jsx)("span",{className:"pillBadge",title:t("ext.streaming.transmissions.badge_disabled_title",{},"Disabled"),children:t("ext.streaming.transmissions.badge_disabled",{},"off")})]})},e.id)})}):(0,a.jsx)("div",{className:"card",style:{marginTop:10},children:(0,a.jsxs)("div",{className:"cardBody",children:[(0,a.jsx)("div",{children:t("ext.streaming.transmissions.empty",{},"Nenhuma transmissão criada.")}),(0,a.jsxs)("ol",{className:"streamingQuickStepsList streamingQuickStepsListCompact",children:[(0,a.jsx)("li",{children:t("ext.streaming.settings.quickstart_step_1",{},"Crie uma transmissão com ao menos uma saída.")}),(0,a.jsx)("li",{children:t("ext.streaming.settings.quickstart_step_2",{},"Ajuste resolução/FPS/autenticação por saída.")}),(0,a.jsx)("li",{children:t("ext.streaming.settings.quickstart_step_3",{},"Salve, carregue URLs e use o wizard para gerar o fluxo.")})]}),(0,a.jsxs)("button",{className:"primaryButton",type:"button",onClick:()=>{Re("local"),Se(!0)},children:[(0,a.jsx)("i",{className:"fa-solid fa-plus","aria-hidden":"true"})," ",t("ext.streaming.transmissions.add",{},"Adicionar transmissão")]})]})})]}),(0,a.jsx)("div",{className:"settingsSplitMain",children:hs&&ie?(0,a.jsxs)("div",{className:"settingsDetail",children:[(0,a.jsxs)("div",{className:"settingsDetailHeader",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("div",{className:"modalSectionTitle",style:{marginBottom:4},children:ie.name?.trim()||ie.path?.trim()||ie.id}),(0,a.jsxs)("div",{className:"cardMeta",children:["ID: ",ie.id]})]}),(0,a.jsxs)("div",{className:"rowWrap",style:{gap:10,justifyContent:"flex-end"},children:[re?(0,a.jsx)("span",{className:"pillBadge",title:t("ext.streaming.transmissions.badge_unsaved_title",{},"Unsaved changes"),children:t("ext.streaming.transmissions.badge_unsaved",{},"pending")}):null,(0,a.jsx)("button",{className:"chipButton",type:"button",disabled:!re||le,onClick:function(){hs&&(ne(g(hs)),oe(!1),de(null),xe(null))},children:t("ext.streaming.transmissions.discard",{},"Descartar")}),(0,a.jsx)("button",{className:"primaryButton",type:"button",disabled:!re||le,onClick:()=>{ws()},children:le?t("ext.streaming.transmissions.saving",{},"Salvando…"):t("ext.streaming.transmissions.save",{},"Salvar")}),(0,a.jsx)("button",{className:"chipButton",type:"button",disabled:le,onClick:()=>ss(!0),children:t("ext.streaming.transmissions.delete",{},"Excluir")})]})]}),ce?(0,a.jsx)("div",{className:"errorText",style:{marginTop:10},children:ce}):null,(0,a.jsx)("div",{className:"sectionDivider"}),(0,a.jsx)("div",{className:"card",children:(0,a.jsxs)("div",{className:"cardBody",children:[(0,a.jsx)("div",{className:"modalSectionTitle",style:{marginBottom:6},children:t("ext.streaming.transmissions.basic",{},"Básico")}),(0,a.jsxs)("div",{className:"streamingFormGrid streamingFormGridTransmissionPrimary",children:[(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.transmissions.name",{},"Nome")}),(0,a.jsx)("input",{className:"input",value:ie.name??"",onChange:e=>ys({name:e.target.value})})]}),(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.transmissions.path",{},"Path/slug")}),(0,a.jsx)("input",{className:"input",value:ie.path??"",onChange:e=>ys({path:e.target.value})}),(0,a.jsx)("div",{className:"cardMeta",style:{marginTop:6},children:t("ext.streaming.transmissions.path_hint",{},"Use apenas a-z, 0-9, - e _. O servidor normaliza automaticamente.")})]})]}),(0,a.jsx)("div",{className:"rowWrap",style:{gap:14,marginTop:10},children:(0,a.jsxs)("label",{className:"rowWrap",style:{gap:8},children:[(0,a.jsx)("input",{type:"checkbox",checked:Boolean(ie.enabled),onChange:e=>ys({enabled:e.target.checked})}),(0,a.jsx)("span",{className:"cardMeta",children:t("ext.streaming.transmissions.enabled",{},"Ativa")})]})}),(0,a.jsxs)("div",{className:"streamingFormGrid streamingFormGridTransmissionSecondary",style:{marginTop:10},children:[(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.transmissions.host_server",{},"Host server")}),(0,a.jsxs)("select",{className:"input",value:_(ie.host_server_id),onChange:e=>ys({host_server_id:_(e.target.value)}),children:[je.map(e=>{const s=_(e.id),i=String(e.name||"").trim(),n="local"===s?t("ext.streaming.processing_servers.local_label",{},"local (this machine)"):i?`${s} (${i})`:s;return(0,a.jsx)("option",{value:s,children:n},s)}),vs.has(_(ie.host_server_id))?null:(0,a.jsx)("option",{value:_(ie.host_server_id),children:_(ie.host_server_id)})]}),(0,a.jsx)("div",{className:"cardMeta",style:{marginTop:6},children:t("ext.streaming.transmissions.host_server_hint",{},"A transmissão será hospedada neste processing server.")})]}),(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.transmissions.placeholder",{},"Placeholder")}),(0,a.jsxs)("select",{className:"input",value:ie.placeholder??"gray",onChange:e=>ys({placeholder:e.target.value}),children:[(0,a.jsx)("option",{value:"gray",children:t("ext.streaming.transmissions.placeholder.gray",{},"Gray")}),(0,a.jsx)("option",{value:"black",children:t("ext.streaming.transmissions.placeholder.black",{},"Black")})]})]}),(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.transmissions.arbitration",{},"Arbitragem")}),(0,a.jsxs)("select",{className:"input",value:ie.arbitration??"priority_latest",onChange:e=>ys({arbitration:e.target.value}),children:[(0,a.jsx)("option",{value:"priority_latest",children:t("ext.streaming.transmissions.arbitration.priority_latest",{},"Priority, then latest")}),(0,a.jsx)("option",{value:"latest",children:t("ext.streaming.transmissions.arbitration.latest",{},"Latest writer wins")})]})]})]}),(0,a.jsxs)("div",{style:{marginTop:14},children:[(0,a.jsx)("div",{className:"modalSectionTitle",style:{marginBottom:6},children:t("ext.streaming.transmissions.camera_controls.title",{},"Controles de câmera")}),(0,a.jsxs)("div",{className:"rowWrap",style:{gap:10,alignItems:"center"},children:[(0,a.jsxs)("label",{className:"rowWrap",style:{gap:8},children:[(0,a.jsx)("input",{type:"checkbox",checked:Boolean(ie.camera_controls?.enabled),disabled:!Boolean(ie.camera_controls?.enabled)&&(Ke||0===Ye.length),onChange:e=>{if(!e.target.checked)return void ys({camera_controls:null});const s=String(ie.camera_controls?.camera_id||"").trim(),t=String(Ye[0]?.id||"").trim();ys({camera_controls:{enabled:!0,camera_id:s||t}})}}),(0,a.jsx)("span",{className:"cardMeta",children:t("ext.streaming.transmissions.camera_controls.enable",{},"Habilitar controles de câmera")})]}),Ke?(0,a.jsx)("div",{className:"settingsStatusMuted",children:t("ext.streaming.transmissions.camera_controls.loading",{},"Carregando câmeras…")}):null]}),(0,a.jsx)("div",{className:"cardMeta",style:{marginTop:6},children:t("ext.streaming.transmissions.camera_controls.hint",{},"Quando habilitado, esta transmissão poderá controlar uma câmera (presets/PTZ) via API.")}),Je?(0,a.jsx)("div",{className:"errorText",style:{marginTop:8},children:Je}):null,Boolean(ie.camera_controls?.enabled)?(0,a.jsxs)("div",{className:"field",style:{marginTop:10},children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.transmissions.camera_controls.camera",{},"Câmera")}),(0,a.jsxs)("select",{className:"input",value:String(ie.camera_controls?.camera_id||"").trim(),onChange:e=>{ys({camera_controls:{enabled:!0,camera_id:String(e.target.value||"").trim()}})},disabled:0===Ye.length,children:[Ye.map(e=>{const s=String(e.id||"").trim(),t=String(e.name||"").trim()||s;return(0,a.jsx)("option",{value:s,children:t},s)}),(()=>{const e=String(ie.camera_controls?.camera_id||"").trim(),s=Ye.some(s=>String(s.id||"").trim()===e);return!e||s?null:(0,a.jsx)("option",{value:e,children:e})})()]}),0!==Ye.length||Ke?null:(0,a.jsx)("div",{className:"cardMeta",style:{marginTop:6},children:t("ext.streaming.transmissions.camera_controls.empty",{},"Nenhuma câmera encontrada. Cadastre uma câmera em Configurações > Câmeras.")})]}):null]}),vs.has(_(ie.host_server_id))?null:(0,a.jsx)("div",{className:"errorText",style:{marginTop:10},children:t("ext.streaming.transmissions.host_server_missing",{},"This host server no longer exists. Select another one before saving.")})]})}),(0,a.jsx)("div",{className:"sectionDivider"}),(0,a.jsx)("div",{className:"card",children:(0,a.jsxs)("div",{className:"cardBody",children:[(0,a.jsxs)("div",{className:"settingsDetailHeader",style:{marginBottom:10},children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("div",{className:"modalSectionTitle",style:{marginBottom:4},children:t("ext.streaming.transmissions.outputs",{},"Saídas")}),(0,a.jsx)("div",{className:"cardMeta",children:t("ext.streaming.transmissions.outputs_hint",{},"Cada saída pode ter resolução/FPS/bitrate diferentes.")})]}),(0,a.jsxs)("div",{className:"rowWrap",style:{gap:8,justifyContent:"flex-end"},children:[(0,a.jsx)("button",{className:"chipButton",type:"button",onClick:()=>Ns("hls"),children:t("ext.streaming.outputs.add_hls",{},"+ HLS")}),(0,a.jsx)("button",{className:"chipButton",type:"button",onClick:()=>Ns("rtsp"),children:t("ext.streaming.outputs.add_rtsp",{},"+ RTSP")}),(0,a.jsx)("button",{className:"chipButton",type:"button",onClick:()=>Ns("webrtc"),children:t("ext.streaming.outputs.add_webrtc",{},"+ WebRTC")})]})]}),Array.isArray(ie.outputs)&&0===ie.outputs.length?(0,a.jsx)("div",{className:"cardMeta",children:t("ext.streaming.transmissions.outputs_empty",{},"Nenhuma saída adicionada.")}):null,Array.isArray(ie.outputs)?ie.outputs.map(e=>{const s=e.authentication??{enabled:!1,username:"",password:""},i=e.resolution??{width:1280,height:720};return(0,a.jsx)("div",{className:"card",style:{marginTop:10},children:(0,a.jsxs)("div",{className:"cardBody",children:[(0,a.jsxs)("div",{className:"settingsDetailHeader",children:[(0,a.jsxs)("div",{children:[(0,a.jsxs)("div",{className:"settingsListItemTitle",children:[e.protocol.toUpperCase()," ",(0,a.jsxs)("span",{className:"cardMeta",style:{fontWeight:500},children:["(",i.width??"-","x",i.height??"-",")"]})]}),(0,a.jsxs)("div",{className:"settingsListItemMeta",children:[t("ext.streaming.outputs.output_id",{},"Output ID"),": ",e.id]})]}),(0,a.jsxs)("div",{className:"rowWrap",style:{gap:10,justifyContent:"flex-end"},children:[(0,a.jsxs)("label",{className:"rowWrap",style:{gap:8},children:[(0,a.jsx)("input",{type:"checkbox",checked:Boolean(e.enabled),onChange:s=>js(e.id,{enabled:s.target.checked})}),(0,a.jsx)("span",{className:"cardMeta",children:t("ext.streaming.outputs.enabled",{},"Ativa")})]}),(0,a.jsx)("button",{className:"chipButton",type:"button",onClick:()=>{return s=e.id,ne(e=>{if(!e)return e;const t=Array.isArray(e.outputs)?e.outputs:[];return{...e,outputs:t.filter(e=>e.id!==s)}}),oe(!0),void de(null);var s},children:t("ext.streaming.outputs.remove",{},"Remover")})]})]}),(0,a.jsxs)("div",{className:"streamingFormGrid streamingFormGridOutputMain",style:{marginTop:10},children:[(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.outputs.protocol",{},"Protocolo")}),(0,a.jsxs)("select",{className:"input",value:e.protocol,onChange:s=>js(e.id,{protocol:s.target.value}),children:[(0,a.jsx)("option",{value:"hls",children:"HLS"}),(0,a.jsx)("option",{value:"rtsp",children:"RTSP"}),(0,a.jsx)("option",{value:"webrtc",children:"WebRTC"})]})]}),(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.outputs.width",{},"Largura")}),(0,a.jsx)("input",{className:"input",value:String(i.width??""),onChange:s=>{const t=c(s.target.value);if(null===t)return void js(e.id,{resolution:null});const a="number"==typeof i.height&&i.height>0?i.height:720;js(e.id,{resolution:{width:Math.max(1,t),height:Math.max(1,a)}})}})]}),(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.outputs.height",{},"Altura")}),(0,a.jsx)("input",{className:"input",value:String(i.height??""),onChange:s=>{const t=c(s.target.value);if(null===t)return void js(e.id,{resolution:null});const a="number"==typeof i.width&&i.width>0?i.width:1280;js(e.id,{resolution:{width:Math.max(1,a),height:Math.max(1,t)}})}})]}),(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.outputs.fps",{},"FPS")}),(0,a.jsx)("input",{className:"input",value:null===e.fps_limit||void 0===e.fps_limit?"":String(e.fps_limit),onChange:s=>js(e.id,{fps_limit:c(s.target.value)})})]}),(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.outputs.bitrate",{},"Bitrate (kbps)")}),(0,a.jsx)("input",{className:"input",value:null===e.bitrate_kbps||void 0===e.bitrate_kbps?"":String(e.bitrate_kbps),onChange:s=>js(e.id,{bitrate_kbps:c(s.target.value)})})]}),(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.outputs.latency",{},"Latência")}),(0,a.jsxs)("select",{className:"input",value:e.latency_profile??"normal",onChange:s=>js(e.id,{latency_profile:s.target.value}),children:[(0,a.jsx)("option",{value:"normal",children:t("ext.streaming.outputs.latency_option.normal",{},"Normal")}),(0,a.jsx)("option",{value:"low",children:t("ext.streaming.outputs.latency_option.low",{},"Low")}),(0,a.jsx)("option",{value:"ultra_low",children:t("ext.streaming.outputs.latency_option.ultra_low",{},"Ultra low")})]})]})]}),(0,a.jsx)("div",{className:"sectionDivider"}),(0,a.jsx)("div",{className:"modalSectionTitle",style:{marginBottom:6},children:t("ext.streaming.outputs.auth",{},"Autenticação (opcional)")}),(0,a.jsx)("div",{className:"rowWrap",style:{gap:14},children:(0,a.jsxs)("label",{className:"rowWrap",style:{gap:8},children:[(0,a.jsx)("input",{type:"checkbox",checked:Boolean(s.enabled),onChange:t=>{const a=t.target.checked;js(e.id,{authentication:{...s,enabled:a}})}}),(0,a.jsx)("span",{className:"cardMeta",children:t("ext.streaming.outputs.auth_enabled",{},"Habilitar user/senha")})]})}),s.enabled?(0,a.jsxs)("div",{className:"streamingFormGrid streamingFormGridOutputAuth",style:{marginTop:10},children:[(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.outputs.username",{},"Usuário")}),(0,a.jsx)("input",{className:"input",value:String(s.username??""),onChange:t=>js(e.id,{authentication:{...s,username:t.target.value}})})]}),(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.outputs.password",{},"Senha")}),(0,a.jsx)("input",{className:"input",type:"password",value:String(s.password??""),onChange:t=>js(e.id,{authentication:{...s,password:t.target.value}})})]}),(0,a.jsx)("div",{className:"cardMeta streamingOutputAuthNote",children:t("ext.streaming.outputs.auth_note",{},"As credenciais são aplicadas no MediaMTX para leitura/playback deste output.")})]}):null]})},e.id)}):null]})}),(0,a.jsx)("div",{className:"sectionDivider"}),(0,a.jsx)("div",{className:"card",children:(0,a.jsxs)("div",{className:"cardBody",children:[(0,a.jsxs)("div",{className:"settingsDetailHeader",style:{marginBottom:10},children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("div",{className:"modalSectionTitle",style:{marginBottom:4},children:t("ext.streaming.transmissions.urls",{},"URLs")}),(0,a.jsx)("div",{className:"cardMeta",children:t("ext.streaming.transmissions.urls_hint",{},"As URLs são geradas pelo engine (MediaMTX).")})]}),(0,a.jsxs)("div",{className:"rowWrap",style:{gap:8,justifyContent:"flex-end"},children:[(0,a.jsx)("button",{className:"chipButton",type:"button",disabled:pe===ie.id,onClick:()=>{fs(ie.id)},children:pe===ie.id?t("ext.streaming.transmissions.loading_urls",{},"Carregando URLs…"):t("ext.streaming.transmissions.load_urls",{},"Carregar URLs")}),(0,a.jsx)("button",{className:"primaryButton",type:"button",onClick:()=>os(ie),children:t("ext.streaming.wizard.open",{},"Criar fluxo com esta transmissão")})]})]}),z?.running?null:(0,a.jsx)("div",{className:"cardMeta",style:{marginBottom:10},children:t("ext.streaming.transmissions.engine_off_warning",{},"A engine está parada: as URLs existirão, mas não haverá playback até iniciar.")}),re?(0,a.jsx)("div",{className:"cardMeta",style:{marginBottom:10},children:t("ext.streaming.transmissions.urls_save_warning",{},"Salve alterações para garantir que paths/outputs estejam atualizados antes de compartilhar URLs.")}):null,Ss&&Ss.transmission_id===ie.id?(0,a.jsxs)("div",{children:[Ss.outputs.map(e=>(0,a.jsx)("div",{className:"card",style:{marginTop:10},children:(0,a.jsxs)("div",{className:"cardBody",children:[(0,a.jsx)("div",{className:"settingsListItemTitle",style:{marginBottom:6},children:e.protocol.toUpperCase()}),(0,a.jsxs)("div",{className:"cardMeta",children:[t("ext.streaming.transmissions.engine_path",{},"Engine path"),": ",e.resolved_engine_path]}),e.requires_auth?(0,a.jsx)("div",{className:"cardMeta",style:{marginTop:6},children:e.auth_username?t("ext.streaming.transmissions.auth_required_user",{username:e.auth_username},`Requires authentication (username: ${e.auth_username}).`):t("ext.streaming.transmissions.auth_required",{},"Requires authentication.")}):(0,a.jsx)("div",{className:"cardMeta",style:{marginTop:6},children:t("ext.streaming.transmissions.auth_not_required",{},"No authentication.")}),(0,a.jsxs)("div",{className:"rowWrap",style:{gap:8,marginTop:10},children:[(0,a.jsx)("input",{className:"input",style:{flex:1},value:e.url,readOnly:!0}),(0,a.jsx)("button",{className:"iconButton",type:"button","aria-label":t("ext.streaming.transmissions.copy_url",{},"Copy URL"),onClick:()=>{(async function(e){const s=String(e??"");try{return void await navigator.clipboard.writeText(s)}catch{}const t=document.createElement("textarea");t.value=s,t.style.position="fixed",t.style.top="-9999px",t.style.left="-9999px",t.setAttribute("readonly","true"),document.body.appendChild(t),t.select();try{document.execCommand("copy")}finally{document.body.removeChild(t)}})(e.url).then(()=>{_e(e.url),window.setTimeout(()=>_e(null),1200)})},children:(0,a.jsx)("i",{className:"fa-solid fa-copy","aria-hidden":"true"})})]}),he===e.url?(0,a.jsx)("div",{className:"streamingStatusOk",style:{marginTop:8},children:t("ext.streaming.transmissions.copied",{},"Copiado!")}):null]})},`${Ss.transmission_id}-${e.output_id}`)),Array.isArray(Ss.warnings)&&Ss.warnings.length>0?(0,a.jsx)("div",{className:"cardMeta",style:{marginTop:10},children:Ss.warnings.join(" ")}):null]}):(0,a.jsx)("div",{className:"cardMeta",children:t("ext.streaming.transmissions.urls_empty",{},"Carregue as URLs para visualizar aqui.")})]})})]}):(0,a.jsx)("div",{className:"card",children:(0,a.jsxs)("div",{className:"cardBody",children:[(0,a.jsx)("div",{children:t("ext.streaming.transmissions.select",{},"Selecione uma transmissão para editar.")}),(0,a.jsx)("div",{className:"cardMeta",children:t("ext.streaming.transmissions.select_hint",{},"Dica: comece criando uma transmissão e depois abra o wizard para gerar o fluxo.")}),(0,a.jsxs)("button",{className:"primaryButton",type:"button",onClick:()=>{Re("local"),Se(!0)},children:[(0,a.jsx)("i",{className:"fa-solid fa-plus","aria-hidden":"true"})," ",t("ext.streaming.transmissions.add",{},"Adicionar transmissão")]})]})})})]}),(0,a.jsxs)(o.y,{open:we,title:t("ext.streaming.transmissions.create",{},"Criar transmissão"),closeAriaLabel:t("core.actions.close",{},"Close"),onClose:()=>{Ce||Se(!1)},children:[ze?(0,a.jsx)("div",{className:"errorText",style:{marginBottom:10},children:ze}):null,(0,a.jsxs)("div",{className:"streamingFormGrid streamingFormGridCreatePrimary",children:[(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.transmissions.name",{},"Nome")}),(0,a.jsx)("input",{className:"input",value:Me,onChange:e=>Ae(e.target.value)})]}),(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.transmissions.path",{},"Path/slug")}),(0,a.jsx)("input",{className:"input",value:Pe,onChange:e=>Le(e.target.value),placeholder:d(Me)||"stream"})]}),(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.transmissions.host_server",{},"Host server")}),(0,a.jsx)("select",{className:"input",value:_(Be),onChange:e=>Re(_(e.target.value)),children:je.map(e=>{const s=_(e.id),i=String(e.name||"").trim(),n="local"===s?t("ext.streaming.processing_servers.local_label",{},"local (this machine)"):i?`${s} (${i})`:s;return(0,a.jsx)("option",{value:s,children:n},s)})})]})]}),(0,a.jsxs)("div",{className:"streamingFormGrid streamingFormGridCreateOutput",style:{marginTop:10},children:[(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.transmissions.protocol",{},"Saída")}),(0,a.jsxs)("select",{className:"input",value:Ee,onChange:e=>Fe(e.target.value),children:[(0,a.jsx)("option",{value:"hls",children:"HLS"}),(0,a.jsx)("option",{value:"rtsp",children:"RTSP"}),(0,a.jsx)("option",{value:"webrtc",children:"WebRTC"})]})]}),(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.transmissions.width",{},"Largura")}),(0,a.jsx)("input",{className:"input",value:De,onChange:e=>Ue(e.target.value)})]}),(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.transmissions.height",{},"Altura")}),(0,a.jsx)("input",{className:"input",value:We,onChange:e=>Ie(e.target.value)})]}),(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.transmissions.fps",{},"FPS")}),(0,a.jsx)("input",{className:"input",value:Oe,onChange:e=>He(e.target.value)})]})]}),(0,a.jsx)("div",{className:"sectionDivider",style:{marginTop:14}}),(0,a.jsx)("div",{className:"modalSectionTitle",style:{marginBottom:6},children:t("ext.streaming.transmissions.camera_controls.title",{},"Controles de câmera")}),(0,a.jsx)("div",{className:"rowWrap",style:{gap:10},children:(0,a.jsxs)("label",{className:"rowWrap",style:{gap:8},children:[(0,a.jsx)("input",{type:"checkbox",checked:$e,onChange:e=>qe(e.target.checked)}),(0,a.jsx)("span",{className:"cardMeta",children:t("ext.streaming.transmissions.camera_controls.enable",{},"Habilitar controles de câmera")})]})}),(0,a.jsx)("div",{className:"cardMeta",style:{marginTop:6},children:t("ext.streaming.transmissions.camera_controls.hint",{},"Quando habilitado, esta transmissão poderá controlar uma câmera (presets/PTZ) via API.")}),$e?(0,a.jsxs)("div",{style:{marginTop:10},children:[Ke?(0,a.jsx)("div",{className:"settingsStatusMuted",children:t("ext.streaming.transmissions.camera_controls.loading",{},"Carregando câmeras…")}):null,Je?(0,a.jsx)("div",{className:"errorText",children:Je}):null,(0,a.jsx)("div",{className:"streamingFormGrid streamingFormGridCreatePrimary",style:{marginTop:10},children:(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.transmissions.camera_controls.camera",{},"Câmera")}),(0,a.jsx)("select",{className:"input",value:Ge,onChange:e=>Xe(String(e.target.value||"").trim()),disabled:0===Ye.length,children:Ye.map(e=>{const s=String(e.id||"").trim(),t=String(e.name||"").trim()||s;return(0,a.jsx)("option",{value:s,children:t},s)})}),0!==Ye.length||Ke?null:(0,a.jsx)("div",{className:"cardMeta",style:{marginTop:6},children:t("ext.streaming.transmissions.camera_controls.empty",{},"Nenhuma câmera encontrada. Cadastre uma câmera em Configurações > Câmeras.")})]})})]}):null,(0,a.jsx)("div",{className:"rowWrap",style:{marginTop:12,justifyContent:"flex-end"},children:(0,a.jsx)("button",{className:"primaryButton",type:"button",disabled:Ce,onClick:()=>{!async function(){ke(!0),Te(null);try{const e=_(Be);if(!vs.has(e))return void Te(t("ext.streaming.errors.invalid_host_server",{serverId:e},`Invalid host server: ${e}`));const s=Me.trim()||t("ext.streaming.transmissions.default_name",{},"Transmission"),a=d(Pe.trim()||s)||"stream";let i;if($e){const e=Ge.trim();if(!e)return void Te(t("ext.streaming.transmissions.camera_controls.select_camera_error",{},"Selecione uma câmera."));i={enabled:!0,camera_id:e}}const r=await(0,n.Fu)({name:s,path:a,enabled:!0,host_server_id:e,camera_controls:i??void 0,outputs:[{protocol:Ee,enabled:!0,resolution:{width:m(De,1280),height:m(We,720)},fps_limit:m(Oe,12)}]});V(e=>[r,...e.filter(e=>e.id!==r.id)]),Z(r.id),ne(g(r)),oe(!1),de(null),Se(!1),Ae(""),Le(""),Re("local"),qe(!1),Xe("")}catch(e){Te(e instanceof Error?e.message:String(e))}finally{ke(!1)}}()},children:Ce?t("ext.streaming.transmissions.creating",{},"Criando…"):t("ext.streaming.transmissions.create_button",{},"Criar transmissão")})})]}),(0,a.jsxs)(o.y,{open:te,title:t("ext.streaming.transmissions.discard_title",{},"Descartar alterações?"),closeAriaLabel:t("core.actions.close",{},"Close"),onClose:()=>{ae(!1),se(null)},children:[(0,a.jsx)("div",{className:"cardMeta",style:{marginBottom:10},children:t("ext.streaming.transmissions.discard_body",{},"Você tem alterações não salvas. Para trocar de transmissão, descarte ou salve primeiro.")}),(0,a.jsxs)("div",{className:"rowWrap",style:{justifyContent:"flex-end",gap:10},children:[(0,a.jsx)("button",{className:"chipButton",type:"button",onClick:()=>{ae(!1),se(null)},children:t("ext.streaming.common.cancel",{},"Cancelar")}),(0,a.jsx)("button",{className:"chipButton",type:"button",onClick:()=>{ee&&(oe(!1),de(null),ae(!1),Z(ee),se(null))},children:t("ext.streaming.transmissions.discard",{},"Descartar")}),(0,a.jsx)("button",{className:"primaryButton",type:"button",onClick:()=>{ae(!1),ws().then(()=>{ee&&(Z(ee),se(null))})},children:t("ext.streaming.transmissions.save",{},"Salvar")})]})]}),(0,a.jsxs)(o.y,{open:es,title:t("ext.streaming.transmissions.delete_title",{},"Excluir transmissão"),closeAriaLabel:t("core.actions.close",{},"Close"),onClose:()=>{ts||(ss(!1),ns(null))},children:[is?(0,a.jsx)("div",{className:"errorText",style:{marginBottom:10},children:is}):null,(0,a.jsx)("div",{className:"cardMeta",style:{marginBottom:10},children:t("ext.streaming.transmissions.delete_body",{},"Esta ação é irreversível.")}),(0,a.jsxs)("div",{className:"rowWrap",style:{justifyContent:"flex-end",gap:10},children:[(0,a.jsx)("button",{className:"chipButton",type:"button",disabled:ts,onClick:()=>ss(!1),children:t("ext.streaming.common.cancel",{},"Cancelar")}),(0,a.jsx)("button",{className:"primaryButton",type:"button",disabled:ts,onClick:()=>{!async function(){if(hs){as(!0),ns(null);try{await(0,n.yL)(hs.id),V(e=>e.filter(e=>e.id!==hs.id)),ue(e=>{const s={...e};return delete s[hs.id],s}),Z(null),ne(null),oe(!1),ss(!1)}catch(e){ns(e instanceof Error?e.message:String(e))}finally{as(!1)}}}()},children:ts?t("ext.streaming.transmissions.deleting",{},"Excluindo…"):t("ext.streaming.transmissions.delete",{},"Excluir")})]})]}),(0,a.jsx)(l.Y,{open:null!==rs,i18n:e,transmission:rs,engineRunning:Boolean(z?.running),processingServers:je,onClose:()=>os(null),onCreated:()=>{us()}})]});var Bs}},416(e,s,t){t.d(s,{J:()=>a});const a={en:{"ext.streaming.common.cancel":"Cancel","ext.streaming.settings.name":"Streams","ext.streaming.settings.desc":"Configure streams and generate playback URLs.","ext.streaming.settings.title":"Streams","ext.streaming.settings.subtitle":"Create streams, configure outputs (HLS/RTSP/WebRTC) and generate URLs via MediaMTX.","ext.streaming.settings.building":"Under construction.","ext.streaming.settings.quickstart":"Recommended flow","ext.streaming.settings.quickstart_step_1":"Create a stream with at least one output.","ext.streaming.settings.quickstart_step_2":"Adjust resolution/FPS/authentication per output.","ext.streaming.settings.quickstart_step_3":"Save, load URLs, then use the wizard to generate a pipeline.","ext.streaming.settings.health.loading":"Checking backend health…","ext.streaming.settings.health.ok":"Backend health: OK","ext.streaming.settings.health.failed":"Backend health: unavailable","ext.streaming.settings.health.refresh":"Refresh status","ext.streaming.settings.transmissions":"Configured streams","ext.streaming.engine.title":"Engine (MediaMTX)","ext.streaming.engine.loading":"Checking engine status…","ext.streaming.engine.running":"Engine status: running","ext.streaming.engine.stopped":"Engine status: stopped","ext.streaming.engine.start":"Start","ext.streaming.engine.starting":"Starting…","ext.streaming.engine.download":"Download engine","ext.streaming.engine.downloading":"Downloading…","ext.streaming.engine.stop":"Stop","ext.streaming.engine.stopping":"Stopping…","ext.streaming.engine.restart":"Restart","ext.streaming.engine.restarting":"Restarting…","ext.streaming.engine.reclaim":"Reclaim","ext.streaming.engine.reclaiming":"Reclaiming…","ext.streaming.engine.reclaim_confirm":"This will try to stop and cleanup stale MediaMTX processes for this data directory. Continue?","ext.streaming.engine.refresh":"Refresh","ext.streaming.engine.refreshing":"Refreshing…","ext.streaming.engine.test_rtsp":"RTSP (test)","ext.streaming.engine.test_hls":"HLS (test)","ext.streaming.engine.test_webrtc":"WebRTC/WHEP (test)","ext.streaming.engine.settings_title":"Engine settings","ext.streaming.engine.settings_loading":"Loading…","ext.streaming.engine.settings_discard":"Discard","ext.streaming.engine.settings_apply":"Apply","ext.streaming.engine.settings_applying":"Applying…","ext.streaming.engine.expose_to_lan":"Expose on LAN (0.0.0.0)","ext.streaming.engine.port_rtsp":"RTSP port","ext.streaming.engine.port_hls":"HLS port","ext.streaming.engine.port_webrtc":"WebRTC port","ext.streaming.engine.port_api":"API port","ext.streaming.engine.ice_servers_label":"STUN/TURN servers (optional, one per line)","ext.streaming.engine.ice_servers_hint":"Only needed to traverse NAT. On a simple LAN, leave it empty.","ext.streaming.engine.meta_version":"Version","ext.streaming.engine.meta_pid":"PID","ext.streaming.engine.meta_uptime":"Uptime","ext.streaming.engine.meta_api":"API","ext.streaming.engine.meta_restarts":"Restarts","ext.streaming.engine.meta_binary":"Binary","ext.streaming.engine.meta_config":"Config","ext.streaming.engine.meta_log":"Log","ext.streaming.engine.orphan_processes":"Found {{count}} external MediaMTX process(es) for this data directory: {{pids}}.","ext.streaming.processing_servers.loading":"Loading processing servers…","ext.streaming.processing_servers.local_label":"local (this machine)","ext.streaming.errors.invalid_host_server":"Invalid host server: {{serverId}}","ext.streaming.transmissions.search":"Search streams…","ext.streaming.transmissions.loading":"Loading…","ext.streaming.transmissions.empty":"No streams created yet.","ext.streaming.transmissions.add":"Add stream","ext.streaming.transmissions.create":"Create stream","ext.streaming.transmissions.create_button":"Create stream","ext.streaming.transmissions.creating":"Creating…","ext.streaming.transmissions.select":"Select a stream to edit.","ext.streaming.transmissions.select_hint":"Tip: create a stream, then use the wizard to generate a pipeline.","ext.streaming.transmissions.meta_line":"Host: {{host}} • Path: {{path}} • Outputs: {{outputs}}","ext.streaming.transmissions.badge_disabled":"off","ext.streaming.transmissions.badge_disabled_title":"Disabled","ext.streaming.transmissions.badge_unsaved":"pending","ext.streaming.transmissions.badge_unsaved_title":"Unsaved changes","ext.streaming.transmissions.discard":"Discard","ext.streaming.transmissions.save":"Save","ext.streaming.transmissions.saving":"Saving…","ext.streaming.transmissions.delete":"Delete","ext.streaming.transmissions.discard_title":"Discard changes?","ext.streaming.transmissions.discard_body":"You have unsaved changes. Discard or save before switching streams.","ext.streaming.transmissions.delete_title":"Delete stream","ext.streaming.transmissions.delete_body":"This action cannot be undone.","ext.streaming.transmissions.deleting":"Deleting…","ext.streaming.transmissions.basic":"Basics","ext.streaming.transmissions.name":"Name","ext.streaming.transmissions.default_name":"Stream","ext.streaming.transmissions.path":"Path/slug","ext.streaming.transmissions.path_hint":"Use only a-z, 0-9, - and _. The server normalizes automatically.","ext.streaming.transmissions.enabled":"Enabled","ext.streaming.transmissions.host_server":"Host server","ext.streaming.transmissions.host_server_hint":"This stream will be hosted on this processing server.","ext.streaming.transmissions.host_server_missing":"This host server no longer exists. Select another one before saving.","ext.streaming.transmissions.placeholder":"Placeholder","ext.streaming.transmissions.placeholder.gray":"Gray background","ext.streaming.transmissions.placeholder.black":"Black background","ext.streaming.transmissions.arbitration":"Arbitration","ext.streaming.transmissions.arbitration.priority_latest":"Priority, then latest","ext.streaming.transmissions.arbitration.latest":"Latest writer wins","ext.streaming.transmissions.outputs":"Outputs","ext.streaming.transmissions.outputs_hint":"Each output can have different resolution/FPS/bitrate.","ext.streaming.transmissions.outputs_empty":"No outputs added yet.","ext.streaming.transmissions.protocol":"Protocol","ext.streaming.transmissions.width":"Width","ext.streaming.transmissions.height":"Height","ext.streaming.transmissions.fps":"FPS","ext.streaming.transmissions.camera_controls.title":"Camera controls","ext.streaming.transmissions.camera_controls.enable":"Enable camera controls","ext.streaming.transmissions.camera_controls.hint":"When enabled, this stream can control a camera (presets/PTZ) via API.","ext.streaming.transmissions.camera_controls.loading":"Loading cameras…","ext.streaming.transmissions.camera_controls.camera":"Camera","ext.streaming.transmissions.camera_controls.empty":"No cameras found. Add a camera in Settings > Cameras.","ext.streaming.transmissions.camera_controls.select_camera_error":"Select a camera.","ext.streaming.transmissions.urls":"URLs","ext.streaming.transmissions.urls_hint":"URLs are generated by the engine (MediaMTX).","ext.streaming.transmissions.load_urls":"Load URLs","ext.streaming.transmissions.loading_urls":"Loading URLs…","ext.streaming.transmissions.urls_empty":"Load URLs to view them here.","ext.streaming.transmissions.urls_save_warning":"Save changes to ensure paths/outputs are up to date before sharing URLs.","ext.streaming.transmissions.engine_off_warning":"The engine is stopped: URLs exist, but playback will not work until you start it.","ext.streaming.transmissions.engine_path":"Engine path","ext.streaming.transmissions.auth_required":"Requires authentication.","ext.streaming.transmissions.auth_required_user":"Requires authentication (username: {{username}}).","ext.streaming.transmissions.auth_not_required":"No authentication.","ext.streaming.transmissions.copy_url":"Copy URL","ext.streaming.transmissions.copied":"Copied!","ext.streaming.outputs.add_hls":"+ HLS","ext.streaming.outputs.add_rtsp":"+ RTSP","ext.streaming.outputs.add_webrtc":"+ WebRTC","ext.streaming.outputs.remove":"Remove","ext.streaming.outputs.output_id":"Output ID","ext.streaming.outputs.enabled":"Enabled","ext.streaming.outputs.protocol":"Protocol","ext.streaming.outputs.width":"Width","ext.streaming.outputs.height":"Height","ext.streaming.outputs.fps":"FPS","ext.streaming.outputs.bitrate":"Bitrate (kbps)","ext.streaming.outputs.latency":"Latency","ext.streaming.outputs.latency_option.normal":"Normal","ext.streaming.outputs.latency_option.low":"Low","ext.streaming.outputs.latency_option.ultra_low":"Ultra low","ext.streaming.outputs.auth":"Authentication (optional)","ext.streaming.outputs.auth_enabled":"Enable username/password","ext.streaming.outputs.username":"Username","ext.streaming.outputs.password":"Password","ext.streaming.outputs.auth_note":"Credentials are applied in MediaMTX for playback of this output.","ext.streaming.wizard.open":"Create pipeline for this stream","ext.streaming.wizard.title":"Create pipeline","ext.streaming.wizard.engine_warning":"The streaming engine is stopped. You can create the pipeline now and start the engine later.","ext.streaming.wizard.loading_cameras":"Loading cameras…","ext.streaming.wizard.camera":"Camera","ext.streaming.wizard.camera_placeholder":"Select a camera","ext.streaming.wizard.camera_search":"Search by name or ID","ext.streaming.wizard.camera_no_results":"No cameras match your search.","ext.streaming.wizard.camera_empty":"No cameras found. Add a camera in Settings > Cameras.","ext.streaming.wizard.camera_unnamed":"Unnamed camera","ext.streaming.wizard.preset":"Preset","ext.streaming.wizard.presets.simple_stream.title":"Simple stream","ext.streaming.wizard.presets.simple_stream.desc":"camera.source + optional fps reducer + stream.publish_video","ext.streaming.wizard.presets.motion_gate_stream.title":"Motion gate stream","ext.streaming.wizard.presets.motion_gate_stream.desc":"camera.source + motion gate + fps reducer + stream.publish_video","ext.streaming.wizard.presets.detection_stream.title":"Detection stream","ext.streaming.wizard.presets.detection_stream.desc":"camera.source + object detection + stream.publish_video","ext.streaming.wizard.presets.tracking_stream.title":"Tracking stream","ext.streaming.wizard.presets.tracking_stream.desc":"camera.source + object tracking + stream.publish_video","ext.streaming.wizard.presets.segmentation_stream.title":"Segmentation stream","ext.streaming.wizard.presets.segmentation_stream.desc":"camera.source + object segmentation + stream.publish_video","ext.streaming.wizard.pipeline_name":"Pipeline name (optional)","ext.streaming.wizard.processing_server":"Processing server","ext.streaming.wizard.host_mismatch_inline":"Stream host: {{transmissionHost}}. Pipeline host: {{pipelineHost}}. They must match.","ext.streaming.wizard.fps":"FPS limit","ext.streaming.wizard.writer_priority":"Writer priority","ext.streaming.wizard.source_backend":"Camera backend","ext.streaming.wizard.source_backend.option.auto":"Auto","ext.streaming.wizard.source_backend.option.opencv":"OpenCV","ext.streaming.wizard.source_backend.option.ffmpeg":"FFmpeg","ext.streaming.wizard.bypass_mode":"Bypass mode","ext.streaming.wizard.bypass_mode.option.auto":"Auto","ext.streaming.wizard.bypass_mode.option.force_on":"Force on","ext.streaming.wizard.bypass_mode.option.force_off":"Force off","ext.streaming.wizard.resize_mode":"Resize mode","ext.streaming.wizard.resize_mode.option.contain":"Contain","ext.streaming.wizard.resize_mode.option.none":"No resize","ext.streaming.wizard.motion_sensitivity":"Motion sensitivity","ext.streaming.wizard.motion_hold":"Motion hold (s)","ext.streaming.wizard.yolo_conf":"Vision confidence","ext.streaming.wizard.yolo_filter_enabled":"Filter frames after vision (recommended)","ext.streaming.wizard.yolo_filter_enabled.hint":"When disabled, the pipeline still runs vision inference but keeps all frames.","ext.streaming.wizard.detection_categories":"Detection categories (csv)","ext.streaming.wizard.tracking_categories":"Tracking categories (csv)","ext.streaming.wizard.enabled":"Enable pipeline after creation","ext.streaming.wizard.use_fps_reducer":"Add core.fps_reducer step","ext.streaming.wizard.create":"Create pipeline","ext.streaming.wizard.creating":"Creating…","ext.streaming.wizard.done_title":"Pipeline created","ext.streaming.wizard.pipeline_created_name":"Pipeline","ext.streaming.wizard.open_pipelines":"Open Pipelines","ext.streaming.wizard.errors.select_camera":"Select a camera.","ext.streaming.wizard.errors.invalid_processing_server":"Invalid processing server: {{serverId}}","ext.streaming.wizard.errors.host_mismatch":"Stream host is {{transmissionHost}}. Select the same processing server for the pipeline.","ext.streaming.runtime.loading":"Refreshing demand and publisher status…","ext.streaming.runtime.demand_on":"demand:on","ext.streaming.runtime.demand_off":"demand:off","ext.streaming.runtime.publisher_running":"running","ext.streaming.runtime.publisher_stopped":"stopped","ext.streaming.runtime.output_status":"Viewers/publisher"},"pt-BR":{"ext.streaming.common.cancel":"Cancelar","ext.streaming.settings.name":"Transmissões","ext.streaming.settings.desc":"Configure transmissões e gere URLs de reprodução.","ext.streaming.settings.title":"Transmissões","ext.streaming.settings.subtitle":"Crie transmissões, configure saídas (HLS/RTSP/WebRTC) e gere URLs via MediaMTX.","ext.streaming.settings.building":"Em construção.","ext.streaming.settings.quickstart":"Fluxo recomendado","ext.streaming.settings.quickstart_step_1":"Crie uma transmissão com pelo menos uma saída.","ext.streaming.settings.quickstart_step_2":"Ajuste resolução/FPS/autenticação por saída.","ext.streaming.settings.quickstart_step_3":"Salve, carregue URLs e use o wizard para gerar um fluxo.","ext.streaming.settings.health.loading":"Verificando saúde do backend…","ext.streaming.settings.health.ok":"Saúde do backend: OK","ext.streaming.settings.health.failed":"Saúde do backend: indisponível","ext.streaming.settings.health.refresh":"Atualizar status","ext.streaming.settings.transmissions":"Transmissões configuradas","ext.streaming.engine.title":"Engine (MediaMTX)","ext.streaming.engine.loading":"Verificando status da engine…","ext.streaming.engine.running":"Status da engine: rodando","ext.streaming.engine.stopped":"Status da engine: parada","ext.streaming.engine.start":"Iniciar","ext.streaming.engine.starting":"Iniciando…","ext.streaming.engine.download":"Baixar engine","ext.streaming.engine.downloading":"Baixando…","ext.streaming.engine.stop":"Parar","ext.streaming.engine.stopping":"Parando…","ext.streaming.engine.restart":"Reiniciar","ext.streaming.engine.restarting":"Reiniciando…","ext.streaming.engine.reclaim":"Recuperar","ext.streaming.engine.reclaiming":"Recuperando…","ext.streaming.engine.reclaim_confirm":"Isso vai tentar parar e limpar processos MediaMTX antigos deste diretório de dados. Continuar?","ext.streaming.engine.refresh":"Atualizar","ext.streaming.engine.refreshing":"Atualizando…","ext.streaming.engine.test_rtsp":"RTSP (teste)","ext.streaming.engine.test_hls":"HLS (teste)","ext.streaming.engine.test_webrtc":"WebRTC/WHEP (teste)","ext.streaming.engine.settings_title":"Configuração da engine","ext.streaming.engine.settings_loading":"Carregando…","ext.streaming.engine.settings_discard":"Descartar","ext.streaming.engine.settings_apply":"Aplicar","ext.streaming.engine.settings_applying":"Aplicando…","ext.streaming.engine.expose_to_lan":"Expor na LAN (0.0.0.0)","ext.streaming.engine.port_rtsp":"Porta RTSP","ext.streaming.engine.port_hls":"Porta HLS","ext.streaming.engine.port_webrtc":"Porta WebRTC","ext.streaming.engine.port_api":"Porta API","ext.streaming.engine.ice_servers_label":"Servidores STUN/TURN (opcional, um por linha)","ext.streaming.engine.ice_servers_hint":"Use apenas se precisar atravessar NAT. Em uma LAN simples, deixe vazio.","ext.streaming.engine.meta_version":"Versão","ext.streaming.engine.meta_pid":"PID","ext.streaming.engine.meta_uptime":"Uptime","ext.streaming.engine.meta_api":"API","ext.streaming.engine.meta_restarts":"Reinícios","ext.streaming.engine.meta_binary":"Binário","ext.streaming.engine.meta_config":"Config","ext.streaming.engine.meta_log":"Log","ext.streaming.engine.orphan_processes":"Foram encontrados {{count}} processos externos do MediaMTX para este diretório de dados: {{pids}}.","ext.streaming.processing_servers.loading":"Carregando servidores de processamento…","ext.streaming.processing_servers.local_label":"local (esta máquina)","ext.streaming.errors.invalid_host_server":"Servidor host inválido: {{serverId}}","ext.streaming.transmissions.search":"Buscar transmissões…","ext.streaming.transmissions.loading":"Carregando…","ext.streaming.transmissions.empty":"Nenhuma transmissão criada ainda.","ext.streaming.transmissions.add":"Adicionar transmissão","ext.streaming.transmissions.create":"Criar transmissão","ext.streaming.transmissions.create_button":"Criar transmissão","ext.streaming.transmissions.creating":"Criando…","ext.streaming.transmissions.select":"Selecione uma transmissão para editar.","ext.streaming.transmissions.select_hint":"Dica: crie uma transmissão e depois use o wizard para gerar um fluxo.","ext.streaming.transmissions.meta_line":"Host: {{host}} • Path: {{path}} • Saídas: {{outputs}}","ext.streaming.transmissions.badge_disabled":"off","ext.streaming.transmissions.badge_disabled_title":"Desativada","ext.streaming.transmissions.badge_unsaved":"pendente","ext.streaming.transmissions.badge_unsaved_title":"Alterações não salvas","ext.streaming.transmissions.discard":"Descartar","ext.streaming.transmissions.save":"Salvar","ext.streaming.transmissions.saving":"Salvando…","ext.streaming.transmissions.delete":"Excluir","ext.streaming.transmissions.discard_title":"Descartar alterações?","ext.streaming.transmissions.discard_body":"Você tem alterações não salvas. Descarte ou salve antes de trocar de transmissão.","ext.streaming.transmissions.delete_title":"Excluir transmissão","ext.streaming.transmissions.delete_body":"Esta ação não pode ser desfeita.","ext.streaming.transmissions.deleting":"Excluindo…","ext.streaming.transmissions.basic":"Básico","ext.streaming.transmissions.name":"Nome","ext.streaming.transmissions.default_name":"Transmissão","ext.streaming.transmissions.path":"Path/slug","ext.streaming.transmissions.path_hint":"Use apenas a-z, 0-9, - e _. O servidor normaliza automaticamente.","ext.streaming.transmissions.enabled":"Ativa","ext.streaming.transmissions.host_server":"Host da transmissão","ext.streaming.transmissions.host_server_hint":"A transmissão será hospedada neste servidor de processamento.","ext.streaming.transmissions.host_server_missing":"Este host server não existe mais. Selecione outro antes de salvar.","ext.streaming.transmissions.placeholder":"Placeholder","ext.streaming.transmissions.placeholder.gray":"Fundo cinza","ext.streaming.transmissions.placeholder.black":"Fundo preto","ext.streaming.transmissions.arbitration":"Arbitragem","ext.streaming.transmissions.arbitration.priority_latest":"Prioridade, depois mais recente","ext.streaming.transmissions.arbitration.latest":"Mais recente vence","ext.streaming.transmissions.outputs":"Saídas","ext.streaming.transmissions.outputs_hint":"Cada saída pode ter resolução/FPS/bitrate diferentes.","ext.streaming.transmissions.outputs_empty":"Nenhuma saída adicionada ainda.","ext.streaming.transmissions.protocol":"Protocolo","ext.streaming.transmissions.width":"Largura","ext.streaming.transmissions.height":"Altura","ext.streaming.transmissions.fps":"FPS","ext.streaming.transmissions.camera_controls.title":"Controles de câmera","ext.streaming.transmissions.camera_controls.enable":"Habilitar controles de câmera","ext.streaming.transmissions.camera_controls.hint":"Quando habilitado, esta transmissão poderá controlar uma câmera (presets/PTZ) via API.","ext.streaming.transmissions.camera_controls.loading":"Carregando câmeras…","ext.streaming.transmissions.camera_controls.camera":"Câmera","ext.streaming.transmissions.camera_controls.empty":"Nenhuma câmera encontrada. Cadastre uma câmera em Configurações > Câmeras.","ext.streaming.transmissions.camera_controls.select_camera_error":"Selecione uma câmera.","ext.streaming.transmissions.urls":"URLs","ext.streaming.transmissions.urls_hint":"As URLs são geradas pela engine (MediaMTX).","ext.streaming.transmissions.load_urls":"Carregar URLs","ext.streaming.transmissions.loading_urls":"Carregando URLs…","ext.streaming.transmissions.urls_empty":"Carregue as URLs para visualizar aqui.","ext.streaming.transmissions.urls_save_warning":"Salve alterações para garantir que paths/saídas estejam atualizados antes de compartilhar URLs.","ext.streaming.transmissions.engine_off_warning":"A engine está parada: as URLs existem, mas o playback não funcionará até iniciar.","ext.streaming.transmissions.engine_path":"Path da engine","ext.streaming.transmissions.auth_required":"Requer autenticação.","ext.streaming.transmissions.auth_required_user":"Requer autenticação (usuário: {{username}}).","ext.streaming.transmissions.auth_not_required":"Sem autenticação.","ext.streaming.transmissions.copy_url":"Copiar URL","ext.streaming.transmissions.copied":"Copiado!","ext.streaming.outputs.add_hls":"+ HLS","ext.streaming.outputs.add_rtsp":"+ RTSP","ext.streaming.outputs.add_webrtc":"+ WebRTC","ext.streaming.outputs.remove":"Remover","ext.streaming.outputs.output_id":"ID da saída","ext.streaming.outputs.enabled":"Ativa","ext.streaming.outputs.protocol":"Protocolo","ext.streaming.outputs.width":"Largura","ext.streaming.outputs.height":"Altura","ext.streaming.outputs.fps":"FPS","ext.streaming.outputs.bitrate":"Bitrate (kbps)","ext.streaming.outputs.latency":"Latência","ext.streaming.outputs.latency_option.normal":"Normal","ext.streaming.outputs.latency_option.low":"Baixa","ext.streaming.outputs.latency_option.ultra_low":"Ultra baixa","ext.streaming.outputs.auth":"Autenticação (opcional)","ext.streaming.outputs.auth_enabled":"Habilitar usuário/senha","ext.streaming.outputs.username":"Usuário","ext.streaming.outputs.password":"Senha","ext.streaming.outputs.auth_note":"As credenciais são aplicadas no MediaMTX para leitura/playback desta saída.","ext.streaming.wizard.open":"Criar fluxo com esta transmissão","ext.streaming.wizard.title":"Criar fluxo","ext.streaming.wizard.engine_warning":"A engine de streaming está parada. Você pode criar o fluxo agora e iniciar a engine depois.","ext.streaming.wizard.loading_cameras":"Carregando câmeras…","ext.streaming.wizard.camera":"Câmera","ext.streaming.wizard.camera_placeholder":"Selecione uma câmera","ext.streaming.wizard.camera_search":"Buscar por nome ou ID","ext.streaming.wizard.camera_no_results":"Nenhuma câmera corresponde à busca.","ext.streaming.wizard.camera_empty":"Nenhuma câmera encontrada. Cadastre uma câmera em Configurações > Câmeras.","ext.streaming.wizard.camera_unnamed":"Câmera sem nome","ext.streaming.wizard.preset":"Preset","ext.streaming.wizard.presets.simple_stream.title":"Stream simples","ext.streaming.wizard.presets.simple_stream.desc":"camera.source + redutor de FPS (opcional) + stream.publish_video","ext.streaming.wizard.presets.motion_gate_stream.title":"Stream com gate de movimento","ext.streaming.wizard.presets.motion_gate_stream.desc":"camera.source + gate de movimento + redutor de FPS + stream.publish_video","ext.streaming.wizard.presets.detection_stream.title":"Stream com detecção","ext.streaming.wizard.presets.detection_stream.desc":"camera.source + detecção de objetos + stream.publish_video","ext.streaming.wizard.presets.tracking_stream.title":"Stream com tracking","ext.streaming.wizard.presets.tracking_stream.desc":"camera.source + tracking de objetos + stream.publish_video","ext.streaming.wizard.presets.segmentation_stream.title":"Stream com segmentação","ext.streaming.wizard.presets.segmentation_stream.desc":"camera.source + segmentação de objetos + stream.publish_video","ext.streaming.wizard.pipeline_name":"Nome do fluxo (opcional)","ext.streaming.wizard.processing_server":"Servidor de processamento","ext.streaming.wizard.host_mismatch_inline":"Host da transmissão: {{transmissionHost}}. Host do fluxo: {{pipelineHost}}. Eles precisam ser iguais.","ext.streaming.wizard.fps":"Limite de FPS","ext.streaming.wizard.writer_priority":"Prioridade do writer","ext.streaming.wizard.source_backend":"Backend da câmera","ext.streaming.wizard.source_backend.option.auto":"Auto","ext.streaming.wizard.source_backend.option.opencv":"OpenCV","ext.streaming.wizard.source_backend.option.ffmpeg":"FFmpeg","ext.streaming.wizard.bypass_mode":"Modo bypass","ext.streaming.wizard.bypass_mode.option.auto":"Auto","ext.streaming.wizard.bypass_mode.option.force_on":"Forçar ligado","ext.streaming.wizard.bypass_mode.option.force_off":"Forçar desligado","ext.streaming.wizard.resize_mode":"Modo de redimensionamento","ext.streaming.wizard.resize_mode.option.contain":"Contain","ext.streaming.wizard.resize_mode.option.none":"Sem resize","ext.streaming.wizard.motion_sensitivity":"Sensibilidade de movimento","ext.streaming.wizard.motion_hold":"Hold de movimento (s)","ext.streaming.wizard.yolo_conf":"Confiança da visão","ext.streaming.wizard.yolo_filter_enabled":"Filtrar frames após visão (recomendado)","ext.streaming.wizard.yolo_filter_enabled.hint":"Quando desligado, o fluxo ainda executa a inferência de visão, mas mantém todos os frames.","ext.streaming.wizard.detection_categories":"Categorias de detecção (csv)","ext.streaming.wizard.tracking_categories":"Categorias de tracking (csv)","ext.streaming.wizard.enabled":"Habilitar fluxo após criação","ext.streaming.wizard.use_fps_reducer":"Inserir step core.fps_reducer","ext.streaming.wizard.create":"Criar fluxo","ext.streaming.wizard.creating":"Criando…","ext.streaming.wizard.done_title":"Fluxo criado","ext.streaming.wizard.pipeline_created_name":"Fluxo","ext.streaming.wizard.open_pipelines":"Abrir Fluxos","ext.streaming.wizard.errors.select_camera":"Selecione uma câmera.","ext.streaming.wizard.errors.invalid_processing_server":"Servidor de processamento inválido: {{serverId}}","ext.streaming.wizard.errors.host_mismatch":"O host da transmissão é {{transmissionHost}}. Selecione o mesmo servidor de processamento para o fluxo.","ext.streaming.runtime.loading":"Atualizando demanda e status do publisher…","ext.streaming.runtime.demand_on":"demanda:on","ext.streaming.runtime.demand_off":"demanda:off","ext.streaming.runtime.publisher_running":"rodando","ext.streaming.runtime.publisher_stopped":"parado","ext.streaming.runtime.output_status":"Viewers/publisher"}}},697(e,s,t){t.d(s,{y:()=>n});var a=t(870),i=(t(496),t(428));function n({title:e,open:s,onClose:t,closeAriaLabel:n,children:r,panelStyle:o}){if(!s)return null;const l=String(n||"").trim()||"Close";return(0,i.createPortal)((0,a.jsx)("div",{className:"modalBackdrop",style:{zIndex:"calc(var(--z-modal) + 1)"},onMouseDown:e=>{e.target===e.currentTarget&&t()},role:"presentation",children:(0,a.jsxs)("div",{className:"modalPanel",style:{width:"min(920px, calc(100vw - 28px))",...o??{}},role:"dialog","aria-modal":"true","aria-label":e,children:[(0,a.jsxs)("div",{className:"modalHeader",children:[(0,a.jsx)("div",{className:"modalTitle",children:e}),(0,a.jsx)("button",{className:"iconButton",type:"button",onClick:t,"aria-label":l,children:(0,a.jsx)("i",{className:"fa-solid fa-xmark","aria-hidden":"true"})})]}),(0,a.jsx)("div",{className:"modalBody",children:r})]})}),document.body)}},703(e,s,t){t.r(s),t.d(s,{activate:()=>n});var a=t(323),i=t(416);function n(e){e.i18n.registerTranslations(i.J),e.registerSettingsPanel((0,a.w)())}},870(e,s,t){e.exports=t(94)},901(e,s,t){async function a(e){const s=`HTTP ${e.status}`;try{const a=await e.json();if(t=a,!Boolean(t)||"object"!=typeof t)return s;const i=a.detail;return"string"==typeof i&&i.trim()?i.trim():s}catch{try{return(await e.text()).trim()||s}catch{return s}}var t}async function i(e,s){const t=await fetch(e,s);if(!t.ok)throw new Error(await a(t));return await t.json()}async function n(e){return i("/api/streams/health",{signal:e})}async function r(e){return i("/api/streams/engine/status",{signal:e})}async function o(e){return i(`/api/streams/engine/${e}`,{method:"POST"})}async function l(){return i("/api/streams/engine/download",{method:"POST"})}async function m(e){return i("/api/streams/settings",{signal:e})}async function c(e){return i("/api/streams/settings",{method:"PATCH",headers:{"content-type":"application/json"},body:JSON.stringify(e??{})})}async function d(e){return i("/api/streams/transmissions",{signal:e})}async function g(e){return i("/api/streams/transmissions",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}async function u(e,s){return i(`/api/streams/transmissions/${encodeURIComponent(e)}`,{method:"PUT",headers:{"content-type":"application/json"},body:JSON.stringify(s)})}async function p(e){const s=await fetch(`/api/streams/transmissions/${encodeURIComponent(e)}`,{method:"DELETE"});if(!s.ok)throw new Error(await a(s))}async function x(e){return i(`/api/streams/transmissions/${encodeURIComponent(e)}/urls`)}async function h(e){return i("/api/cameras/index",{signal:e})}async function _(e){const s=await i("/api/processing-servers",{signal:e});return Array.isArray(s.servers)?s.servers:[]}async function v(e){return i("/api/streams/wizard/create-pipeline",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}t.d(s,{A$:()=>v,Cs:()=>u,Fu:()=>g,I$:()=>d,JB:()=>r,WO:()=>m,bO:()=>h,cr:()=>_,eR:()=>c,hF:()=>o,jP:()=>l,m9:()=>n,pU:()=>x,yL:()=>p})}}]);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import unicodedata
|
|
3
4
|
from typing import Any, Literal
|
|
4
5
|
|
|
5
6
|
from toposync.runtime.pipelines.templates import safe_pipeline_name
|
|
@@ -20,14 +21,42 @@ STREAMING_WIZARD_PRESETS: tuple[WizardPresetId, ...] = (
|
|
|
20
21
|
"segmentation_stream",
|
|
21
22
|
)
|
|
22
23
|
|
|
24
|
+
DEFAULT_STREAMING_DETECTION_MODEL_ID = "rfdetr_det_medium"
|
|
25
|
+
|
|
26
|
+
_GENERIC_NAME_COMPONENTS = {"stream", "transmission", "transmissao", "fluxo"}
|
|
27
|
+
_PRESET_NAME_COMPONENTS: dict[str, str] = {
|
|
28
|
+
"simple_stream": "stream",
|
|
29
|
+
"motion_gate_stream": "motion",
|
|
30
|
+
"detection_stream": "detection",
|
|
31
|
+
"tracking_stream": "tracking",
|
|
32
|
+
"segmentation_stream": "segmentation",
|
|
33
|
+
}
|
|
34
|
+
|
|
23
35
|
|
|
24
36
|
def suggested_streaming_wizard_pipeline_name(
|
|
25
37
|
*,
|
|
26
38
|
transmission_id: str,
|
|
27
39
|
camera_id: str,
|
|
28
40
|
preset_id: WizardPresetId,
|
|
41
|
+
transmission_name: str | None = None,
|
|
42
|
+
transmission_path: str | None = None,
|
|
43
|
+
camera_name: str | None = None,
|
|
29
44
|
) -> str:
|
|
30
|
-
|
|
45
|
+
transmission_component = _pick_name_component(
|
|
46
|
+
transmission_path,
|
|
47
|
+
transmission_name,
|
|
48
|
+
transmission_id,
|
|
49
|
+
fallback="stream",
|
|
50
|
+
skip_generic=True,
|
|
51
|
+
)
|
|
52
|
+
camera_component = _pick_name_component(camera_id, camera_name)
|
|
53
|
+
preset_component = _PRESET_NAME_COMPONENTS.get(str(preset_id), "stream")
|
|
54
|
+
|
|
55
|
+
components = [transmission_component, camera_component, preset_component]
|
|
56
|
+
if camera_component and _is_generic_component(transmission_component):
|
|
57
|
+
components = [camera_component, preset_component]
|
|
58
|
+
|
|
59
|
+
base = "__".join(_dedupe_name_components(components))
|
|
31
60
|
return safe_pipeline_name(base)
|
|
32
61
|
|
|
33
62
|
|
|
@@ -114,7 +143,7 @@ def build_streaming_wizard_graph(
|
|
|
114
143
|
"id": "detect",
|
|
115
144
|
"operator": "vision.detect",
|
|
116
145
|
"config": {
|
|
117
|
-
"model_id":
|
|
146
|
+
"model_id": DEFAULT_STREAMING_DETECTION_MODEL_ID,
|
|
118
147
|
"categories": detection_categories,
|
|
119
148
|
"confidence_threshold": float(yolo_confidence),
|
|
120
149
|
"emit_mode": yolo_emit_mode,
|
|
@@ -130,7 +159,7 @@ def build_streaming_wizard_graph(
|
|
|
130
159
|
"id": "detect",
|
|
131
160
|
"operator": "vision.detect",
|
|
132
161
|
"config": {
|
|
133
|
-
"model_id":
|
|
162
|
+
"model_id": DEFAULT_STREAMING_DETECTION_MODEL_ID,
|
|
134
163
|
"categories": tracking_categories,
|
|
135
164
|
"confidence_threshold": float(yolo_confidence),
|
|
136
165
|
"emit_mode": "annotate",
|
|
@@ -203,6 +232,69 @@ def _append_edge(
|
|
|
203
232
|
)
|
|
204
233
|
|
|
205
234
|
|
|
235
|
+
def _pick_name_component(
|
|
236
|
+
*values: str | None,
|
|
237
|
+
fallback: str = "",
|
|
238
|
+
skip_generic: bool = False,
|
|
239
|
+
) -> str:
|
|
240
|
+
candidates = [_safe_name_component(value) for value in values]
|
|
241
|
+
candidates = [item for item in candidates if item]
|
|
242
|
+
for candidate in candidates:
|
|
243
|
+
if skip_generic and _is_generic_component(candidate):
|
|
244
|
+
continue
|
|
245
|
+
if _is_uuid_component(candidate):
|
|
246
|
+
continue
|
|
247
|
+
return candidate
|
|
248
|
+
for candidate in candidates:
|
|
249
|
+
if skip_generic and (_is_generic_component(candidate) or _is_uuid_component(candidate)):
|
|
250
|
+
continue
|
|
251
|
+
return candidate
|
|
252
|
+
return _safe_name_component(fallback)
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
def _dedupe_name_components(values: list[str]) -> list[str]:
|
|
256
|
+
components: list[str] = []
|
|
257
|
+
seen: set[str] = set()
|
|
258
|
+
for value in values:
|
|
259
|
+
component = _safe_name_component(value)
|
|
260
|
+
key = _component_key(component)
|
|
261
|
+
if not component or not key or key in seen:
|
|
262
|
+
continue
|
|
263
|
+
seen.add(key)
|
|
264
|
+
components.append(component)
|
|
265
|
+
return components
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
def _safe_name_component(value: str | None) -> str:
|
|
269
|
+
raw = str(value or "").strip()
|
|
270
|
+
if not raw:
|
|
271
|
+
return ""
|
|
272
|
+
ascii_raw = unicodedata.normalize("NFKD", raw).encode("ascii", "ignore").decode("ascii")
|
|
273
|
+
return safe_pipeline_name(ascii_raw or raw)
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
def _component_key(value: str | None) -> str:
|
|
277
|
+
return _safe_name_component(value).strip("_").lower()
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
def _is_generic_component(value: str | None) -> bool:
|
|
281
|
+
return _component_key(value) in _GENERIC_NAME_COMPONENTS
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
def _is_uuid_component(value: str | None) -> bool:
|
|
285
|
+
key = _component_key(value).replace("_", "-")
|
|
286
|
+
if len(key) != 36:
|
|
287
|
+
return False
|
|
288
|
+
for index, char in enumerate(key):
|
|
289
|
+
if index in {8, 13, 18, 23}:
|
|
290
|
+
if char != "-":
|
|
291
|
+
return False
|
|
292
|
+
continue
|
|
293
|
+
if char not in "0123456789abcdef":
|
|
294
|
+
return False
|
|
295
|
+
return True
|
|
296
|
+
|
|
297
|
+
|
|
206
298
|
def _pick_choice(value: Any, *, allowed: set[str], default: str) -> str:
|
|
207
299
|
normalized = str(value or "").strip().lower()
|
|
208
300
|
if normalized in allowed:
|
|
@@ -747,7 +747,7 @@ function StreamingSettingsPanelContent({
|
|
|
747
747
|
<ol className="streamingQuickStepsList">
|
|
748
748
|
<li>{t("ext.streaming.settings.quickstart_step_1", {}, "Crie uma transmissão com ao menos uma saída.")}</li>
|
|
749
749
|
<li>{t("ext.streaming.settings.quickstart_step_2", {}, "Ajuste resolução/FPS/autenticação por saída.")}</li>
|
|
750
|
-
<li>{t("ext.streaming.settings.quickstart_step_3", {}, "Salve, carregue URLs e use o wizard para gerar o
|
|
750
|
+
<li>{t("ext.streaming.settings.quickstart_step_3", {}, "Salve, carregue URLs e use o wizard para gerar o fluxo.")}</li>
|
|
751
751
|
</ol>
|
|
752
752
|
</div>
|
|
753
753
|
</div>
|
|
@@ -1114,7 +1114,7 @@ function StreamingSettingsPanelContent({
|
|
|
1114
1114
|
<ol className="streamingQuickStepsList streamingQuickStepsListCompact">
|
|
1115
1115
|
<li>{t("ext.streaming.settings.quickstart_step_1", {}, "Crie uma transmissão com ao menos uma saída.")}</li>
|
|
1116
1116
|
<li>{t("ext.streaming.settings.quickstart_step_2", {}, "Ajuste resolução/FPS/autenticação por saída.")}</li>
|
|
1117
|
-
<li>{t("ext.streaming.settings.quickstart_step_3", {}, "Salve, carregue URLs e use o wizard para gerar o
|
|
1117
|
+
<li>{t("ext.streaming.settings.quickstart_step_3", {}, "Salve, carregue URLs e use o wizard para gerar o fluxo.")}</li>
|
|
1118
1118
|
</ol>
|
|
1119
1119
|
<button
|
|
1120
1120
|
className="primaryButton"
|
|
@@ -1180,7 +1180,7 @@ function StreamingSettingsPanelContent({
|
|
|
1180
1180
|
{t("ext.streaming.transmissions.select", {}, "Selecione uma transmissão para editar.")}
|
|
1181
1181
|
</div>
|
|
1182
1182
|
<div className="cardMeta">
|
|
1183
|
-
{t("ext.streaming.transmissions.select_hint", {}, "Dica: comece criando uma transmissão e depois abra o wizard para gerar o
|
|
1183
|
+
{t("ext.streaming.transmissions.select_hint", {}, "Dica: comece criando uma transmissão e depois abra o wizard para gerar o fluxo.")}
|
|
1184
1184
|
</div>
|
|
1185
1185
|
<button
|
|
1186
1186
|
className="primaryButton"
|
|
@@ -1695,7 +1695,7 @@ function StreamingSettingsPanelContent({
|
|
|
1695
1695
|
: t("ext.streaming.transmissions.load_urls", {}, "Carregar URLs")}
|
|
1696
1696
|
</button>
|
|
1697
1697
|
<button className="primaryButton" type="button" onClick={() => setWizardTransmission(transmissionDraft)}>
|
|
1698
|
-
{t("ext.streaming.wizard.open", {}, "Criar
|
|
1698
|
+
{t("ext.streaming.wizard.open", {}, "Criar fluxo com esta transmissão")}
|
|
1699
1699
|
</button>
|
|
1700
1700
|
</div>
|
|
1701
1701
|
</div>
|
|
@@ -395,7 +395,7 @@ export function WizardCreatePipelineFromTransmission({
|
|
|
395
395
|
return (
|
|
396
396
|
<SubModal
|
|
397
397
|
open={open}
|
|
398
|
-
title={t("ext.streaming.wizard.title", {}, "Criar
|
|
398
|
+
title={t("ext.streaming.wizard.title", {}, "Criar fluxo para transmissão")}
|
|
399
399
|
closeAriaLabel={t("core.actions.close", {}, "Close")}
|
|
400
400
|
onClose={() => {
|
|
401
401
|
if (createBusy) return;
|
|
@@ -415,7 +415,7 @@ export function WizardCreatePipelineFromTransmission({
|
|
|
415
415
|
{t(
|
|
416
416
|
"ext.streaming.wizard.engine_warning",
|
|
417
417
|
{},
|
|
418
|
-
"A engine de streaming está parada. Você pode criar o
|
|
418
|
+
"A engine de streaming está parada. Você pode criar o fluxo agora e iniciar a engine depois.",
|
|
419
419
|
)}
|
|
420
420
|
</div>
|
|
421
421
|
) : null}
|
|
@@ -540,7 +540,7 @@ export function WizardCreatePipelineFromTransmission({
|
|
|
540
540
|
|
|
541
541
|
<div className="rowWrap" style={{ gap: 10 }}>
|
|
542
542
|
<div className="field" style={{ flex: 1, minWidth: 220 }}>
|
|
543
|
-
<label className="label">{t("ext.streaming.wizard.pipeline_name", {}, "Nome do
|
|
543
|
+
<label className="label">{t("ext.streaming.wizard.pipeline_name", {}, "Nome do fluxo (opcional)")}</label>
|
|
544
544
|
<input className="input" value={pipelineName} onChange={(event) => setPipelineName(event.target.value)} />
|
|
545
545
|
</div>
|
|
546
546
|
<div className="field" style={{ width: 180 }}>
|
|
@@ -674,7 +674,7 @@ export function WizardCreatePipelineFromTransmission({
|
|
|
674
674
|
<div className="field">
|
|
675
675
|
<label className="rowWrap" style={{ gap: 10 }}>
|
|
676
676
|
<input type="checkbox" checked={enabled} onChange={(event) => setEnabled(event.target.checked)} />
|
|
677
|
-
<span className="cardMeta">{t("ext.streaming.wizard.enabled", {}, "
|
|
677
|
+
<span className="cardMeta">{t("ext.streaming.wizard.enabled", {}, "Fluxo habilitado após criação")}</span>
|
|
678
678
|
</label>
|
|
679
679
|
</div>
|
|
680
680
|
|
|
@@ -702,7 +702,7 @@ export function WizardCreatePipelineFromTransmission({
|
|
|
702
702
|
|| !knownProcessingServerIds.has(selectedProcessingServerId)
|
|
703
703
|
}
|
|
704
704
|
>
|
|
705
|
-
{createBusy ? t("ext.streaming.wizard.creating", {}, "Criando…") : t("ext.streaming.wizard.create", {}, "Criar
|
|
705
|
+
{createBusy ? t("ext.streaming.wizard.creating", {}, "Criando…") : t("ext.streaming.wizard.create", {}, "Criar fluxo")}
|
|
706
706
|
</button>
|
|
707
707
|
</div>
|
|
708
708
|
</div>
|
|
@@ -713,10 +713,10 @@ export function WizardCreatePipelineFromTransmission({
|
|
|
713
713
|
<div className="card">
|
|
714
714
|
<div className="cardBody">
|
|
715
715
|
<div className="modalSectionTitle" style={{ marginBottom: 6 }}>
|
|
716
|
-
{t("ext.streaming.wizard.done_title", {}, "
|
|
716
|
+
{t("ext.streaming.wizard.done_title", {}, "Fluxo criado")}
|
|
717
717
|
</div>
|
|
718
718
|
<div className="cardMeta">
|
|
719
|
-
{t("ext.streaming.wizard.pipeline_created_name", {}, "
|
|
719
|
+
{t("ext.streaming.wizard.pipeline_created_name", {}, "Fluxo")}: {created.pipeline_name}
|
|
720
720
|
</div>
|
|
721
721
|
{Array.isArray(created.warnings) && created.warnings.length > 0 ? (
|
|
722
722
|
<div className="cardMeta" style={{ marginTop: 8 }}>
|
|
@@ -738,7 +738,7 @@ export function WizardCreatePipelineFromTransmission({
|
|
|
738
738
|
onClose();
|
|
739
739
|
}}
|
|
740
740
|
>
|
|
741
|
-
{t("ext.streaming.wizard.open_pipelines", {}, "Abrir
|
|
741
|
+
{t("ext.streaming.wizard.open_pipelines", {}, "Abrir Fluxos")}
|
|
742
742
|
</button>
|
|
743
743
|
</div>
|
|
744
744
|
</div>
|
|
@@ -232,7 +232,7 @@ export const streamingTranslations = {
|
|
|
232
232
|
"ext.streaming.settings.quickstart": "Fluxo recomendado",
|
|
233
233
|
"ext.streaming.settings.quickstart_step_1": "Crie uma transmissão com pelo menos uma saída.",
|
|
234
234
|
"ext.streaming.settings.quickstart_step_2": "Ajuste resolução/FPS/autenticação por saída.",
|
|
235
|
-
"ext.streaming.settings.quickstart_step_3": "Salve, carregue URLs e use o wizard para gerar um
|
|
235
|
+
"ext.streaming.settings.quickstart_step_3": "Salve, carregue URLs e use o wizard para gerar um fluxo.",
|
|
236
236
|
"ext.streaming.settings.health.loading": "Verificando saúde do backend…",
|
|
237
237
|
"ext.streaming.settings.health.ok": "Saúde do backend: OK",
|
|
238
238
|
"ext.streaming.settings.health.failed": "Saúde do backend: indisponível",
|
|
@@ -294,7 +294,7 @@ export const streamingTranslations = {
|
|
|
294
294
|
"ext.streaming.transmissions.create_button": "Criar transmissão",
|
|
295
295
|
"ext.streaming.transmissions.creating": "Criando…",
|
|
296
296
|
"ext.streaming.transmissions.select": "Selecione uma transmissão para editar.",
|
|
297
|
-
"ext.streaming.transmissions.select_hint": "Dica: crie uma transmissão e depois use o wizard para gerar um
|
|
297
|
+
"ext.streaming.transmissions.select_hint": "Dica: crie uma transmissão e depois use o wizard para gerar um fluxo.",
|
|
298
298
|
"ext.streaming.transmissions.meta_line": "Host: {{host}} • Path: {{path}} • Saídas: {{outputs}}",
|
|
299
299
|
"ext.streaming.transmissions.badge_disabled": "off",
|
|
300
300
|
"ext.streaming.transmissions.badge_disabled_title": "Desativada",
|
|
@@ -380,9 +380,9 @@ export const streamingTranslations = {
|
|
|
380
380
|
"ext.streaming.outputs.password": "Senha",
|
|
381
381
|
"ext.streaming.outputs.auth_note": "As credenciais são aplicadas no MediaMTX para leitura/playback desta saída.",
|
|
382
382
|
|
|
383
|
-
"ext.streaming.wizard.open": "Criar
|
|
384
|
-
"ext.streaming.wizard.title": "Criar
|
|
385
|
-
"ext.streaming.wizard.engine_warning": "A engine de streaming está parada. Você pode criar o
|
|
383
|
+
"ext.streaming.wizard.open": "Criar fluxo com esta transmissão",
|
|
384
|
+
"ext.streaming.wizard.title": "Criar fluxo",
|
|
385
|
+
"ext.streaming.wizard.engine_warning": "A engine de streaming está parada. Você pode criar o fluxo agora e iniciar a engine depois.",
|
|
386
386
|
"ext.streaming.wizard.loading_cameras": "Carregando câmeras…",
|
|
387
387
|
"ext.streaming.wizard.camera": "Câmera",
|
|
388
388
|
"ext.streaming.wizard.camera_placeholder": "Selecione uma câmera",
|
|
@@ -401,9 +401,9 @@ export const streamingTranslations = {
|
|
|
401
401
|
"ext.streaming.wizard.presets.tracking_stream.desc": "camera.source + tracking de objetos + stream.publish_video",
|
|
402
402
|
"ext.streaming.wizard.presets.segmentation_stream.title": "Stream com segmentação",
|
|
403
403
|
"ext.streaming.wizard.presets.segmentation_stream.desc": "camera.source + segmentação de objetos + stream.publish_video",
|
|
404
|
-
"ext.streaming.wizard.pipeline_name": "Nome do
|
|
404
|
+
"ext.streaming.wizard.pipeline_name": "Nome do fluxo (opcional)",
|
|
405
405
|
"ext.streaming.wizard.processing_server": "Servidor de processamento",
|
|
406
|
-
"ext.streaming.wizard.host_mismatch_inline": "Host da transmissão: {{transmissionHost}}. Host do
|
|
406
|
+
"ext.streaming.wizard.host_mismatch_inline": "Host da transmissão: {{transmissionHost}}. Host do fluxo: {{pipelineHost}}. Eles precisam ser iguais.",
|
|
407
407
|
"ext.streaming.wizard.fps": "Limite de FPS",
|
|
408
408
|
"ext.streaming.wizard.writer_priority": "Prioridade do writer",
|
|
409
409
|
"ext.streaming.wizard.source_backend": "Backend da câmera",
|
|
@@ -421,20 +421,20 @@ export const streamingTranslations = {
|
|
|
421
421
|
"ext.streaming.wizard.motion_hold": "Hold de movimento (s)",
|
|
422
422
|
"ext.streaming.wizard.yolo_conf": "Confiança da visão",
|
|
423
423
|
"ext.streaming.wizard.yolo_filter_enabled": "Filtrar frames após visão (recomendado)",
|
|
424
|
-
"ext.streaming.wizard.yolo_filter_enabled.hint": "Quando desligado, o
|
|
424
|
+
"ext.streaming.wizard.yolo_filter_enabled.hint": "Quando desligado, o fluxo ainda executa a inferência de visão, mas mantém todos os frames.",
|
|
425
425
|
"ext.streaming.wizard.detection_categories": "Categorias de detecção (csv)",
|
|
426
426
|
"ext.streaming.wizard.tracking_categories": "Categorias de tracking (csv)",
|
|
427
|
-
"ext.streaming.wizard.enabled": "Habilitar
|
|
427
|
+
"ext.streaming.wizard.enabled": "Habilitar fluxo após criação",
|
|
428
428
|
"ext.streaming.wizard.use_fps_reducer": "Inserir step core.fps_reducer",
|
|
429
|
-
"ext.streaming.wizard.create": "Criar
|
|
429
|
+
"ext.streaming.wizard.create": "Criar fluxo",
|
|
430
430
|
"ext.streaming.wizard.creating": "Criando…",
|
|
431
|
-
"ext.streaming.wizard.done_title": "
|
|
432
|
-
"ext.streaming.wizard.pipeline_created_name": "
|
|
433
|
-
"ext.streaming.wizard.open_pipelines": "Abrir
|
|
431
|
+
"ext.streaming.wizard.done_title": "Fluxo criado",
|
|
432
|
+
"ext.streaming.wizard.pipeline_created_name": "Fluxo",
|
|
433
|
+
"ext.streaming.wizard.open_pipelines": "Abrir Fluxos",
|
|
434
434
|
|
|
435
435
|
"ext.streaming.wizard.errors.select_camera": "Selecione uma câmera.",
|
|
436
436
|
"ext.streaming.wizard.errors.invalid_processing_server": "Servidor de processamento inválido: {{serverId}}",
|
|
437
|
-
"ext.streaming.wizard.errors.host_mismatch": "O host da transmissão é {{transmissionHost}}. Selecione o mesmo servidor de processamento para o
|
|
437
|
+
"ext.streaming.wizard.errors.host_mismatch": "O host da transmissão é {{transmissionHost}}. Selecione o mesmo servidor de processamento para o fluxo.",
|
|
438
438
|
|
|
439
439
|
"ext.streaming.runtime.loading": "Atualizando demanda e status do publisher…",
|
|
440
440
|
"ext.streaming.runtime.demand_on": "demanda:on",
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
/*! For license information please see 703.js.LICENSE.txt */
|
|
2
|
-
"use strict";(self.webpackChunk_toposync_extension_streaming_ui=self.webpackChunk_toposync_extension_streaming_ui||[]).push([[703],{87(e,s,t){t.d(s,{D:()=>a});const a="com.toposync.streaming"},94(e,s,t){var a=t(496),i=Symbol.for("react.element"),n=(Symbol.for("react.fragment"),Object.prototype.hasOwnProperty),r=a.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,o={key:!0,ref:!0,__self:!0,__source:!0};function l(e,s,t){var a,l={},m=null,c=null;for(a in void 0!==t&&(m=""+t),void 0!==s.key&&(m=""+s.key),void 0!==s.ref&&(c=s.ref),s)n.call(s,a)&&!o.hasOwnProperty(a)&&(l[a]=s[a]);if(e&&e.defaultProps)for(a in s=e.defaultProps)void 0===l[a]&&(l[a]=s[a]);return{$$typeof:i,type:e,key:m,ref:c,props:l,_owner:r.current}}s.jsx=l,s.jsxs=l},155(e,s,t){t.d(s,{Y:()=>p});var a=t(870),i=t(496),n=t(901),r=t(697);const o=[{id:"simple_stream",titleKey:"ext.streaming.wizard.presets.simple_stream.title",descriptionKey:"ext.streaming.wizard.presets.simple_stream.desc",fallbackTitle:"Simple stream",fallbackDescription:"camera.source + optional fps reducer + stream.publish_video"},{id:"motion_gate_stream",titleKey:"ext.streaming.wizard.presets.motion_gate_stream.title",descriptionKey:"ext.streaming.wizard.presets.motion_gate_stream.desc",fallbackTitle:"Motion gate stream",fallbackDescription:"camera.source + motion gate + fps reducer + stream.publish_video"},{id:"detection_stream",titleKey:"ext.streaming.wizard.presets.detection_stream.title",descriptionKey:"ext.streaming.wizard.presets.detection_stream.desc",fallbackTitle:"Detection stream",fallbackDescription:"camera.source + object detection + stream.publish_video"},{id:"tracking_stream",titleKey:"ext.streaming.wizard.presets.tracking_stream.title",descriptionKey:"ext.streaming.wizard.presets.tracking_stream.desc",fallbackTitle:"Tracking stream",fallbackDescription:"camera.source + object tracking + stream.publish_video"},{id:"segmentation_stream",titleKey:"ext.streaming.wizard.presets.segmentation_stream.title",descriptionKey:"ext.streaming.wizard.presets.segmentation_stream.desc",fallbackTitle:"Segmentation stream",fallbackDescription:"camera.source + object segmentation + stream.publish_video"}];function l(e){const s=String(e||"").trim();if(!s)return;const t=Number(s);return Number.isFinite(t)?t:void 0}function m(e){const s=String(e||"").trim();if(!s)return;const t=Number.parseInt(s,10);return Number.isFinite(t)?t:void 0}function c(e){return String(e||"").trim().toLowerCase()||"local"}function d(e){return String(e||"").normalize("NFD").replace(/[\u0300-\u036f]/g,"").toLowerCase().trim()}function g(e){const s=String(e||"").trim();return s.length<=12?s:`${s.slice(0,8)}...`}function u(e,s){const t=String(s||"").trim();return t&&e.some(e=>String(e.id||"").trim()===t)?t:""}function p({open:e,i18n:s,transmission:t,engineRunning:p,processingServers:x,onClose:h,onCreated:_}){const{t:v}=s.useI18n(),b=(0,i.useId)(),f=(0,i.useRef)(null),[y,j]=(0,i.useState)("form"),[N,w]=(0,i.useState)("simple_stream"),[S,C]=(0,i.useState)(""),[k,z]=(0,i.useState)(!1),[T,M]=(0,i.useState)(""),[A,P]=(0,i.useState)([]),[L,B]=(0,i.useState)(!1),[R,E]=(0,i.useState)(null),[D,F]=(0,i.useState)(""),[U,W]=(0,i.useState)(!0),[I,O]=(0,i.useState)("local"),[H,$]=(0,i.useState)("auto"),[q,G]=(0,i.useState)(!1),[X,K]=(0,i.useState)(""),[V,J]=(0,i.useState)("0.01"),[Q,Y]=(0,i.useState)("6"),[Z,ee]=(0,i.useState)("contain"),[se,te]=(0,i.useState)("0"),[ae,ie]=(0,i.useState)("auto"),[ne,re]=(0,i.useState)("0.55"),[oe,le]=(0,i.useState)(!0),[me,ce]=(0,i.useState)(""),[de,ge]=(0,i.useState)(""),[ue,pe]=(0,i.useState)(!1),[xe,he]=(0,i.useState)(null),[_e,ve]=(0,i.useState)(null),be=String(t?.camera_controls?.camera_id||"").trim();(0,i.useEffect)(()=>{e&&(j("form"),w("simple_stream"),C(""),z(!1),M(""),P([]),B(!1),E(null),F(""),W(!0),O(c(t?.host_server_id)),$("auto"),G(!1),K(""),J("0.01"),Y("6"),ee("contain"),te("0"),ie("auto"),re("0.55"),le(!0),ce(""),ge(""),pe(!1),he(null),ve(null))},[e,t?.host_server_id,t?.id]),(0,i.useEffect)(()=>{if(!e)return;const s=new AbortController;return B(!0),E(null),P([]),(async()=>{try{const e=await(0,n.bO)(s.signal);if(s.signal.aborted)return;const a=Array.isArray(e.cameras)?e.cameras:[];P(a),C(e=>{if(0===a.length)return"";const s=String(e||"").trim();return u(a,s)||function(e,s,t){const a=u(e,s);if(a)return a;const i=[t?.name,t?.path].map(e=>d(String(e||""))).filter(Boolean);if(i.length>0){const s=e.find(e=>{const s=d(String(e.name||"")),t=d(String(e.id||""));return s&&i.includes(s)||t&&i.includes(t)});if(s)return String(s.id||"").trim()}return 1===e.length?String(e[0]?.id||"").trim():""}(a,be,t)})}catch(e){if(e instanceof DOMException&&"AbortError"===e.name)return;E(e instanceof Error?e.message:String(e))}finally{s.signal.aborted||B(!1)}})(),()=>s.abort()},[e,t?.id,t?.name,t?.path,be]),(0,i.useEffect)(()=>{if(k)return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e)};function e(e){const s=f.current;s&&e.target instanceof Node&&(s.contains(e.target)||z(!1))}},[k]);const fe=(0,i.useMemo)(()=>t?t.name?.trim()||t.path?.trim()||t.id:"",[t]),ye=(0,i.useMemo)(()=>o.find(e=>e.id===N)??o[0],[N]),je=(0,i.useMemo)(()=>A.find(e=>String(e.id||"").trim()===S.trim())??null,[S,A]),Ne=(0,i.useMemo)(()=>{const e=new Map;for(const s of A){const t=String(s.name||"").trim();if(!t)continue;const a=d(t);e.set(a,(e.get(a)??0)+1)}return e},[A]),we=(0,i.useMemo)(()=>{const e=d(T);return e?A.filter(s=>d(`${s.name||""} ${s.id||""}`).includes(e)):A},[T,A]),Se=(0,i.useMemo)(()=>function(e){const s=e.find(e=>"local"===c(e.id))??null,t=e.filter(e=>"local"!==c(e.id)).sort((e,s)=>String(e.id||"").localeCompare(String(s.id||"")));return s?[s,...t]:[{id:"local",name:"Local",kind:"inprocess",url:""},...t]}(Array.isArray(x)?x:[]),[x]),Ce=(0,i.useMemo)(()=>{const e=new Set(["local"]);for(const s of Se)e.add(c(s.id));return e},[Se]),ke=c(t?.host_server_id),ze=c(I),Te=ke!==ze;function Me(e){const s=e.split(",").map(e=>e.trim().toLowerCase()).filter(Boolean);if(0!==s.length)return Array.from(new Set(s))}function Ae(e){return String(e?.name||"").trim()||v("ext.streaming.wizard.camera_unnamed",{},"Unnamed camera")}function Pe(e,s){const t=String(e?.id||s||"").trim();if(!t)return"";const a=String(e?.name||"").trim();return a?(Ne.get(d(a))??0)>1?`ID ${g(t)}`:"":`ID ${g(t)}`}return(0,a.jsxs)(r.y,{open:e,title:v("ext.streaming.wizard.title",{},"Criar pipeline para transmissão"),closeAriaLabel:v("core.actions.close",{},"Close"),onClose:()=>{ue||h()},children:["form"===y?(0,a.jsxs)("div",{className:"streamingWizard",children:[(0,a.jsx)("div",{className:"card",children:(0,a.jsxs)("div",{className:"cardBody",children:[(0,a.jsx)("div",{className:"modalSectionTitle",style:{marginBottom:6},children:fe}),(0,a.jsx)("div",{className:"cardMeta",children:t?.id||""}),p?null:(0,a.jsx)("div",{className:"cardMeta",style:{marginTop:8},children:v("ext.streaming.wizard.engine_warning",{},"A engine de streaming está parada. Você pode criar o pipeline agora e iniciar a engine depois.")})]})}),L?(0,a.jsx)("div",{className:"settingsStatusMuted streamingWizardFeedback",children:v("ext.streaming.wizard.loading_cameras",{},"Carregando câmeras…")}):null,R?(0,a.jsx)("div",{className:"errorText streamingWizardFeedback",children:R}):null,xe?(0,a.jsx)("div",{className:"errorText streamingWizardFeedback",children:xe}):null,(0,a.jsx)("div",{className:"card",children:(0,a.jsxs)("div",{className:"cardBody",children:[(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:v("ext.streaming.wizard.camera",{},"Câmera")}),(0,a.jsxs)("div",{className:"streamingCameraPicker",ref:f,children:[(0,a.jsxs)("button",{type:"button",className:"input streamingCameraPickerButton","aria-haspopup":"listbox","aria-expanded":k,"aria-controls":b,onClick:()=>{M(""),z(e=>!e)},onKeyDown:e=>{"ArrowDown"===e.key&&(e.preventDefault(),M(""),z(!0)),"Escape"===e.key&&z(!1)},disabled:L||0===A.length,children:[(0,a.jsxs)("span",{className:"streamingCameraPickerButtonText",children:[(0,a.jsx)("span",{className:"streamingCameraPickerName",children:je?Ae(je):L?v("ext.streaming.wizard.loading_cameras",{},"Loading cameras..."):v("ext.streaming.wizard.camera_placeholder",{},"Select a camera")}),je||S.trim()?(0,a.jsx)("span",{className:"streamingCameraPickerMeta",children:Pe(je,S)}):null]}),(0,a.jsx)("i",{className:"fa-solid "+(k?"fa-chevron-up":"fa-chevron-down"),"aria-hidden":"true"})]}),k?(0,a.jsxs)("div",{className:"streamingCameraPickerPopover",children:[(0,a.jsx)("input",{className:"input streamingCameraPickerSearch",value:T,onChange:e=>M(e.target.value),onKeyDown:e=>{"Escape"===e.key&&(e.preventDefault(),z(!1))},placeholder:v("ext.streaming.wizard.camera_search",{},"Search by name or ID"),autoFocus:!0}),(0,a.jsx)("div",{className:"streamingCameraPickerList",id:b,role:"listbox","aria-label":v("ext.streaming.wizard.camera",{},"Camera"),children:we.length>0?we.map(e=>{const s=String(e.id||"").trim(),t=s===S.trim(),i=Pe(e);return(0,a.jsxs)("button",{type:"button",className:"streamingCameraPickerOption"+(t?" isSelected":""),role:"option","aria-selected":t,onClick:()=>{C(s),z(!1),M("")},children:[(0,a.jsxs)("span",{className:"streamingCameraPickerOptionMain",children:[(0,a.jsx)("span",{className:"streamingCameraPickerOptionName",children:Ae(e)}),i?(0,a.jsx)("span",{className:"streamingCameraPickerOptionMeta",children:i}):null]}),t?(0,a.jsx)("i",{className:"fa-solid fa-check","aria-hidden":"true"}):null]},s)}):(0,a.jsx)("div",{className:"streamingCameraPickerEmpty",children:v("ext.streaming.wizard.camera_no_results",{},"No cameras match your search.")})})]}):null]}),0!==A.length||L?null:(0,a.jsx)("div",{className:"cardMeta",children:v("ext.streaming.wizard.camera_empty",{},"No cameras found. Add a camera in Settings > Cameras.")})]}),(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:v("ext.streaming.wizard.preset",{},"Preset")}),(0,a.jsx)("select",{className:"input",value:N,onChange:e=>w(e.target.value),children:o.map(e=>(0,a.jsx)("option",{value:e.id,children:v(e.titleKey,{},e.fallbackTitle)},e.id))}),(0,a.jsx)("div",{className:"label",children:v(ye.descriptionKey,{},ye.fallbackDescription)})]}),(0,a.jsxs)("div",{className:"rowWrap",style:{gap:10},children:[(0,a.jsxs)("div",{className:"field",style:{flex:1,minWidth:220},children:[(0,a.jsx)("label",{className:"label",children:v("ext.streaming.wizard.pipeline_name",{},"Nome do pipeline (opcional)")}),(0,a.jsx)("input",{className:"input",value:D,onChange:e=>F(e.target.value)})]}),(0,a.jsxs)("div",{className:"field",style:{width:180},children:[(0,a.jsx)("label",{className:"label",children:v("ext.streaming.wizard.processing_server",{},"Processing server")}),(0,a.jsxs)("select",{className:"input",value:ze,onChange:e=>O(c(e.target.value)),children:[Se.map(e=>{const s=c(e.id),t=String(e.name||"").trim(),i="local"===s?v("ext.streaming.processing_servers.local_label",{},"local (this machine)"):t?`${s} (${t})`:s;return(0,a.jsx)("option",{value:s,children:i},s)}),Ce.has(ze)?null:(0,a.jsx)("option",{value:ze,children:ze})]})]})]}),Te?(0,a.jsx)("div",{className:"errorText",children:v("ext.streaming.wizard.host_mismatch_inline",{transmissionHost:ke,pipelineHost:ze},`Transmission is hosted on ${ke} and pipeline is on ${ze}. They must match.`)}):null,(0,a.jsxs)("div",{className:"rowWrap",style:{gap:10},children:[(0,a.jsxs)("div",{className:"field",style:{width:170},children:[(0,a.jsx)("label",{className:"label",children:v("ext.streaming.wizard.fps",{},"FPS limit")}),(0,a.jsx)("input",{className:"input",value:X,onChange:e=>K(e.target.value),placeholder:"5"})]}),(0,a.jsxs)("div",{className:"field",style:{width:170},children:[(0,a.jsx)("label",{className:"label",children:v("ext.streaming.wizard.writer_priority",{},"Writer priority")}),(0,a.jsx)("input",{className:"input",value:se,onChange:e=>te(e.target.value)})]}),(0,a.jsxs)("div",{className:"field",style:{width:180},children:[(0,a.jsx)("label",{className:"label",children:v("ext.streaming.wizard.source_backend",{},"Backend da câmera")}),(0,a.jsxs)("select",{className:"input",value:H,onChange:e=>$(e.target.value),children:[(0,a.jsx)("option",{value:"auto",children:v("ext.streaming.wizard.source_backend.option.auto",{},"Auto")}),(0,a.jsx)("option",{value:"opencv",children:v("ext.streaming.wizard.source_backend.option.opencv",{},"OpenCV")}),(0,a.jsx)("option",{value:"ffmpeg",children:v("ext.streaming.wizard.source_backend.option.ffmpeg",{},"FFmpeg")})]})]}),(0,a.jsxs)("div",{className:"field",style:{width:180},children:[(0,a.jsx)("label",{className:"label",children:v("ext.streaming.wizard.bypass_mode",{},"Bypass mode")}),(0,a.jsxs)("select",{className:"input",value:ae,onChange:e=>ie(e.target.value),children:[(0,a.jsx)("option",{value:"auto",children:v("ext.streaming.wizard.bypass_mode.option.auto",{},"Auto")}),(0,a.jsx)("option",{value:"force_on",children:v("ext.streaming.wizard.bypass_mode.option.force_on",{},"Force on")}),(0,a.jsx)("option",{value:"force_off",children:v("ext.streaming.wizard.bypass_mode.option.force_off",{},"Force off")})]})]})]}),(0,a.jsxs)("div",{className:"rowWrap",style:{gap:10},children:[(0,a.jsxs)("div",{className:"field",style:{width:180},children:[(0,a.jsx)("label",{className:"label",children:v("ext.streaming.wizard.resize_mode",{},"Resize mode")}),(0,a.jsxs)("select",{className:"input",value:Z,onChange:e=>ee(e.target.value),children:[(0,a.jsx)("option",{value:"contain",children:v("ext.streaming.wizard.resize_mode.option.contain",{},"Contain")}),(0,a.jsx)("option",{value:"none",children:v("ext.streaming.wizard.resize_mode.option.none",{},"No resize")})]})]}),(0,a.jsxs)("div",{className:"field",style:{width:180},children:[(0,a.jsx)("label",{className:"label",children:v("ext.streaming.wizard.motion_sensitivity",{},"Motion sensitivity")}),(0,a.jsx)("input",{className:"input",value:V,onChange:e=>J(e.target.value)})]}),(0,a.jsxs)("div",{className:"field",style:{width:180},children:[(0,a.jsx)("label",{className:"label",children:v("ext.streaming.wizard.motion_hold",{},"Motion hold (s)")}),(0,a.jsx)("input",{className:"input",value:Q,onChange:e=>Y(e.target.value)})]}),(0,a.jsxs)("div",{className:"field",style:{width:180},children:[(0,a.jsx)("label",{className:"label",children:v("ext.streaming.wizard.yolo_conf",{},"Vision confidence")}),(0,a.jsx)("input",{className:"input",value:ne,onChange:e=>re(e.target.value)})]})]}),(0,a.jsxs)("div",{className:"field",children:[(0,a.jsxs)("label",{className:"rowWrap",style:{gap:10},children:[(0,a.jsx)("input",{type:"checkbox",checked:oe,onChange:e=>le(e.target.checked)}),(0,a.jsx)("span",{className:"cardMeta",children:v("ext.streaming.wizard.yolo_filter_enabled",{},"Filter frames after vision (recommended)")})]}),(0,a.jsx)("div",{className:"cardMeta",style:{marginLeft:28},children:v("ext.streaming.wizard.yolo_filter_enabled.hint",{},"When disabled, the pipeline still runs vision inference but keeps all frames.")})]}),(0,a.jsxs)("div",{className:"rowWrap",style:{gap:10},children:[(0,a.jsxs)("div",{className:"field",style:{flex:1,minWidth:260},children:[(0,a.jsx)("label",{className:"label",children:v("ext.streaming.wizard.detection_categories",{},"Detection categories (csv)")}),(0,a.jsx)("input",{className:"input",value:me,onChange:e=>ce(e.target.value),placeholder:"person,car"})]}),(0,a.jsxs)("div",{className:"field",style:{flex:1,minWidth:260},children:[(0,a.jsx)("label",{className:"label",children:v("ext.streaming.wizard.tracking_categories",{},"Tracking categories (csv)")}),(0,a.jsx)("input",{className:"input",value:de,onChange:e=>ge(e.target.value),placeholder:"person,car"})]})]}),(0,a.jsx)("div",{className:"field",children:(0,a.jsxs)("label",{className:"rowWrap",style:{gap:10},children:[(0,a.jsx)("input",{type:"checkbox",checked:U,onChange:e=>W(e.target.checked)}),(0,a.jsx)("span",{className:"cardMeta",children:v("ext.streaming.wizard.enabled",{},"Pipeline habilitado após criação")})]})}),(0,a.jsx)("div",{className:"field",children:(0,a.jsxs)("label",{className:"rowWrap",style:{gap:10},children:[(0,a.jsx)("input",{type:"checkbox",checked:q,onChange:e=>G(e.target.checked)}),(0,a.jsx)("span",{className:"cardMeta",children:v("ext.streaming.wizard.use_fps_reducer",{},"Inserir step core.fps_reducer")})]})})]})}),(0,a.jsxs)("div",{className:"rowWrap",style:{marginTop:14,justifyContent:"flex-end",gap:10},children:[(0,a.jsx)("button",{className:"chipButton",type:"button",onClick:h,disabled:ue,children:v("core.actions.cancel",{},"Cancelar")}),(0,a.jsx)("button",{className:"primaryButton",type:"button",onClick:()=>{!async function(){if(t)if(S.trim())if(Ce.has(ze))if(Te)he(v("ext.streaming.wizard.errors.host_mismatch",{transmissionHost:ke,pipelineHost:ze},`Transmission is hosted on '${ke}'. Select the same processing server for the pipeline.`));else{pe(!0),he(null),z(!1);try{const e=await(0,n.A$)({transmission_id:t.id,camera_id:S.trim(),preset_id:N,optional_parameters:{pipeline_name:D.trim()||void 0,enabled:U,processing_server_id:ze,source_backend:H,use_fps_reducer:q,fps_limit:l(X),motion_sensitivity:l(V),motion_hold_seconds:l(Q),resize_mode:Z,writer_priority:m(se),bypass_mode:ae,yolo_confidence_threshold:l(ne),yolo_filter_enabled:oe,detection_categories:Me(me),tracking_categories:Me(de)}});ve(e),j("done"),_(e)}catch(e){he(e instanceof Error?e.message:String(e))}finally{pe(!1)}}else he(v("ext.streaming.wizard.errors.invalid_processing_server",{serverId:ze},`Invalid processing server: ${ze}`));else he(v("ext.streaming.wizard.errors.select_camera",{},"Select a camera."))}()},disabled:ue||!S.trim()||Te||!Ce.has(ze),children:ue?v("ext.streaming.wizard.creating",{},"Criando…"):v("ext.streaming.wizard.create",{},"Criar pipeline")})]})]}):null,"done"===y&&_e?(0,a.jsxs)("div",{className:"streamingWizard",children:[(0,a.jsx)("div",{className:"card",children:(0,a.jsxs)("div",{className:"cardBody",children:[(0,a.jsx)("div",{className:"modalSectionTitle",style:{marginBottom:6},children:v("ext.streaming.wizard.done_title",{},"Pipeline criado")}),(0,a.jsxs)("div",{className:"cardMeta",children:[v("ext.streaming.wizard.pipeline_created_name",{},"Pipeline"),": ",_e.pipeline_name]}),Array.isArray(_e.warnings)&&_e.warnings.length>0?(0,a.jsx)("div",{className:"cardMeta",style:{marginTop:8},children:_e.warnings.join(" ")}):null]})}),(0,a.jsxs)("div",{className:"rowWrap",style:{marginTop:14,justifyContent:"flex-end",gap:10},children:[(0,a.jsx)("button",{className:"chipButton",type:"button",onClick:h,children:v("core.actions.close",{},"Fechar")}),(0,a.jsx)("button",{className:"primaryButton",type:"button",onClick:()=>{!function(){if("undefined"==typeof window)return;const e="/settings/pipelines";window.location.pathname!==e&&(window.history.pushState(null,"",e),window.dispatchEvent(new PopStateEvent("popstate")))}(),h()},children:v("ext.streaming.wizard.open_pipelines",{},"Abrir Pipelines")})]})]}):null]})}},323(e,s,t){t.d(s,{w:()=>v});var a=t(870),i=t(496),n=t(901),r=t(87),o=t(697),l=t(155);function m(e,s){const t=Number.parseInt(String(e||"").trim(),10);return Number.isFinite(t)?t:s}function c(e){const s=String(e||"").trim();if(!s)return null;const t=Number.parseInt(s,10);return Number.isFinite(t)?t:null}function d(e){const s=String(e||"").trim().toLowerCase();return s?Array.from(s).map(e=>/[a-z0-9_-]/.test(e)?e:"-").join("").replace(/-+/g,"-").replace(/^[-_]+|[-_]+$/g,""):""}function g(e){return"function"==typeof structuredClone?structuredClone(e):JSON.parse(JSON.stringify(e))}function u(e){try{const s=globalThis.crypto;if(s?.randomUUID)return`${e}_${s.randomUUID()}`}catch{}return`${e}_${Date.now()}_${Math.floor(1e6*Math.random())}`}function p(e){const s=String(e||"").replace(/\r/g,"").split(/[\n,]/g),t=[],a=new Set;for(const e of s){const s=String(e||"").trim();if(!s)continue;const i=s.toLowerCase();(i.startsWith("stun:")||i.startsWith("turn:")||i.startsWith("turns:"))&&(a.has(i)||(a.add(i),t.push(s)))}return t}function x(e){if(!Number.isFinite(e)||!e||e<1)return"-";const s=Math.max(0,Math.floor(e)),t=Math.floor(s/3600),a=Math.floor(s%3600/60),i=s%60;return t>0?`${t}h ${a}m`:a>0?`${a}m ${i}s`:`${i}s`}function h(e){return{id:u("output"),protocol:e,enabled:!0,resolution:{width:1280,height:720},fps_limit:12,bitrate_kbps:null,latency_profile:"normal",authentication:{enabled:!1,username:"",password:""}}}function _(e){return String(e||"").trim().toLowerCase()||"local"}function v(){return{id:r.D,icon:"tower-broadcast",name:{key:"ext.streaming.settings.name",fallback:"Transmissões"},description:{key:"ext.streaming.settings.desc"},render:({i18n:e,settings:s})=>(0,a.jsx)(b,{i18n:e,settings:s})}}function b({i18n:e,settings:s}){const{t}=e.useI18n(),[r,u]=(0,i.useState)(!0),[v,b]=(0,i.useState)(null),[f,y]=(0,i.useState)(null),[j,N]=(0,i.useState)(!0),[w,S]=(0,i.useState)(!1),[C,k]=(0,i.useState)(null),[z,T]=(0,i.useState)(null),[M,A]=(0,i.useState)(null),[P,L]=(0,i.useState)(!0),[B,R]=(0,i.useState)(null),[E,D]=(0,i.useState)(null),[F,U]=(0,i.useState)(null),[W,I]=(0,i.useState)(!1),[O,H]=(0,i.useState)(!1),[$,q]=(0,i.useState)(!0),[G,X]=(0,i.useState)(null),[K,V]=(0,i.useState)([]),[J,Q]=(0,i.useState)(""),[Y,Z]=(0,i.useState)(null),[ee,se]=(0,i.useState)(null),[te,ae]=(0,i.useState)(!1),[ie,ne]=(0,i.useState)(null),[re,oe]=(0,i.useState)(!1),[le,me]=(0,i.useState)(!1),[ce,de]=(0,i.useState)(null),[ge,ue]=(0,i.useState)({}),[pe,xe]=(0,i.useState)(null),[he,_e]=(0,i.useState)(null),[ve,be]=(0,i.useState)(!0),[fe,ye]=(0,i.useState)(null),[je,Ne]=(0,i.useState)([{id:"local",name:"Local",kind:"inprocess",url:""}]),[we,Se]=(0,i.useState)(!1),[Ce,ke]=(0,i.useState)(!1),[ze,Te]=(0,i.useState)(null),[Me,Ae]=(0,i.useState)(""),[Pe,Le]=(0,i.useState)(""),[Be,Re]=(0,i.useState)("local"),[Ee,De]=(0,i.useState)("hls"),[Fe,Ue]=(0,i.useState)("1280"),[We,Ie]=(0,i.useState)("720"),[Oe,He]=(0,i.useState)("12"),[$e,qe]=(0,i.useState)(!1),[Ge,Xe]=(0,i.useState)(""),[Ke,Ve]=(0,i.useState)(!1),[Je,Qe]=(0,i.useState)(null),[Ye,Ze]=(0,i.useState)([]),[es,ss]=(0,i.useState)(!1),[ts,as]=(0,i.useState)(!1),[is,ns]=(0,i.useState)(null),[rs,os]=(0,i.useState)(null),ls=(0,i.useMemo)(()=>{const e=s.transmissions;return Array.isArray(e)?e.length:0},[s.transmissions]),ms=K.length>0?K.length:ls,cs=(0,i.useCallback)(async e=>{u(!0),y(null);try{const s=await(0,n.m9)(e);b(s)}catch(e){if(e instanceof DOMException&&"AbortError"===e.name)return;b(null),y(e instanceof Error?e.message:String(e))}finally{e?.aborted||u(!1)}},[]),ds=(0,i.useCallback)(async e=>{N(!0),A(null);try{const s=await(0,n.JB)(e);T(s)}catch(e){if(e instanceof DOMException&&"AbortError"===e.name)return;T(null),A(e instanceof Error?e.message:String(e))}finally{e?.aborted||N(!1)}},[]),gs=(0,i.useCallback)(async e=>{L(!0),R(null);try{const s=await(0,n.WO)(e);if(e?.aborted)return;D(s),U(g(s.engine??{})),I(!1)}catch(e){if(e instanceof DOMException&&"AbortError"===e.name)return;D(null),R(e instanceof Error?e.message:String(e))}finally{e?.aborted||L(!1)}},[]),us=(0,i.useCallback)(async e=>{q(!0),X(null);try{const s=await(0,n.I$)(e);V(s)}catch(e){if(e instanceof DOMException&&"AbortError"===e.name)return;V([]),X(e instanceof Error?e.message:String(e))}finally{e?.aborted||q(!1)}},[]),ps=(0,i.useCallback)(async e=>{be(!0),ye(null);try{const s=await(0,n.cr)(e);if(e?.aborted)return;Ne(function(e){const s=e.find(e=>"local"===_(e.id))??null,t=e.filter(e=>"local"!==_(e.id)).sort((e,s)=>String(e.id||"").localeCompare(String(s.id||"")));return s?[s,...t]:[{id:"local",name:"Local",kind:"inprocess",url:""},...t]}(Array.isArray(s)?s:[]))}catch(e){if(e instanceof DOMException&&"AbortError"===e.name)return;Ne([{id:"local",name:"Local",kind:"inprocess",url:""}]),ye(e instanceof Error?e.message:String(e))}finally{e?.aborted||be(!1)}},[]),xs=(0,i.useCallback)(async e=>{Ve(!0),Qe(null);try{const s=await(0,n.bO)(e);if(e?.aborted)return;const t=Array.isArray(s.cameras)?s.cameras:[];Ze(t)}catch(e){if(e instanceof DOMException&&"AbortError"===e.name)return;Ze([]),Qe(e instanceof Error?e.message:String(e))}finally{e?.aborted||Ve(!1)}},[]);(0,i.useEffect)(()=>{const e=new AbortController;return cs(e.signal),ds(e.signal),gs(e.signal),us(e.signal),ps(e.signal),xs(e.signal),()=>e.abort()},[xs,ds,cs,ps,gs,us]),(0,i.useEffect)(()=>{const e=window.setInterval(()=>{"hidden"!==document.visibilityState&&ds()},5e3);return()=>window.clearInterval(e)},[ds]),(0,i.useEffect)(()=>{Y&&K.some(e=>e.id===Y)||Z(K[0]?.id??null)},[Y,K]);const hs=(0,i.useMemo)(()=>Y?K.find(e=>e.id===Y)??null:null,[Y,K]);(0,i.useEffect)(()=>{if(!hs)return ne(null),oe(!1),void de(null);re||(ne(g(hs)),de(null))},[hs,re]);const _s=(0,i.useMemo)(()=>{const e=J.trim().toLowerCase();return e?K.filter(s=>{const t=String(s.name||"").trim().toLowerCase(),a=String(s.path||"").trim().toLowerCase(),i=String(s.id||"").trim().toLowerCase();return t.includes(e)||a.includes(e)||i.includes(e)}):K},[J,K]),vs=(0,i.useMemo)(()=>{const e=new Set(["local"]);for(const s of je)e.add(_(s.id));return e},[je]);async function bs(e){if("reclaim"!==e||confirm(t("ext.streaming.engine.reclaim_confirm",{},"This will try to stop and cleanup stale MediaMTX processes for this data directory. Continue?"))){S(!0),k(e),A(null);try{const s=await(0,n.hF)(e);T(s),gs()}catch(e){A(e instanceof Error?e.message:String(e)),ds()}finally{S(!1),k(null)}}}async function fs(e){xe(e),X(null);try{const s=await(0,n.pU)(e);ue(t=>({...t,[e]:s}))}catch(e){X(e instanceof Error?e.message:String(e))}finally{xe(null)}}function ys(e){ne(s=>s?{...s,...e}:s),oe(!0),de(null)}function js(e,s){ne(t=>{if(!t)return t;const a=Array.isArray(t.outputs)?t.outputs:[];return{...t,outputs:a.map(t=>t.id===e?{...t,...s}:t)}}),oe(!0),de(null)}function Ns(e){ne(s=>{if(!s)return s;const t=Array.isArray(s.outputs)?s.outputs:[];return{...s,outputs:[...t,h(e)]}}),oe(!0),de(null)}async function ws(){if(ie){me(!0),de(null);try{const e=_(ie.host_server_id);if(!vs.has(e))return void de(t("ext.streaming.errors.invalid_host_server",{serverId:e},`Invalid host server: ${e}`));const s={...ie,id:ie.id||Y||"",host_server_id:e},a=await(0,n.Cs)(s.id,s);V(e=>e.map(e=>e.id===a.id?a:e)),ne(g(a)),oe(!1),fs(a.id)}catch(e){de(e instanceof Error?e.message:String(e))}finally{me(!1)}}}(0,i.useEffect)(()=>{if(!we)return;if(qe(!1),Xe(""),Ye.length>0)return;const e=new AbortController;return xs(e.signal),()=>e.abort()},[we,xs]),(0,i.useEffect)(()=>{we&&(Ge.trim()||0!==Ye.length&&Xe(String(Ye[0]?.id||"").trim()))},[Ye,we,Ge]);const Ss=Y?ge[Y]??null:null,Cs=Boolean(z?.running),ks=Array.isArray(z?.orphan_pids)?z.orphan_pids:[],zs=Cs?"restart":"start",Ts="start"===C?t("ext.streaming.engine.starting",{},"Iniciando…"):"restart"===C?t("ext.streaming.engine.restarting",{},"Reiniciando…"):Cs?t("ext.streaming.engine.restart",{},"Reiniciar"):t("ext.streaming.engine.start",{},"Iniciar"),Ms="stop"===C?t("ext.streaming.engine.stopping",{},"Parando…"):t("ext.streaming.engine.stop",{},"Parar"),As="reclaim"===C?t("ext.streaming.engine.reclaiming",{},"Recuperando…"):t("ext.streaming.engine.reclaim",{},"Recuperar"),Ps="download"===C?t("ext.streaming.engine.downloading",{},"Baixando…"):t("ext.streaming.engine.download",{},"Baixar engine"),Ls="refresh"===C?t("ext.streaming.engine.refreshing",{},"Atualizando…"):t("ext.streaming.engine.refresh",{},"Atualizar");return(0,a.jsxs)("div",{className:"streamingSettingsPanel",children:[(0,a.jsx)("div",{className:"card",children:(0,a.jsxs)("div",{className:"cardBody",children:[(0,a.jsx)("div",{className:"modalSectionTitle",style:{marginBottom:6},children:t("ext.streaming.settings.title",{},"Transmissões")}),(0,a.jsx)("div",{className:"cardMeta",children:t("ext.streaming.settings.subtitle",{},"Crie transmissões, configure saídas (HLS/RTSP/WebRTC) e gere URLs a partir do MediaMTX.")}),(0,a.jsxs)("div",{className:"streamingQuickSteps",children:[(0,a.jsx)("div",{className:"streamingQuickStepsTitle",children:t("ext.streaming.settings.quickstart",{},"Fluxo Recomendado")}),(0,a.jsxs)("ol",{className:"streamingQuickStepsList",children:[(0,a.jsx)("li",{children:t("ext.streaming.settings.quickstart_step_1",{},"Crie uma transmissão com ao menos uma saída.")}),(0,a.jsx)("li",{children:t("ext.streaming.settings.quickstart_step_2",{},"Ajuste resolução/FPS/autenticação por saída.")}),(0,a.jsx)("li",{children:t("ext.streaming.settings.quickstart_step_3",{},"Salve, carregue URLs e use o wizard para gerar o pipeline.")})]})]})]})}),(0,a.jsx)("div",{className:"sectionDivider"}),(0,a.jsx)("div",{className:"card",children:(0,a.jsxs)("div",{className:"cardBody",children:[(0,a.jsxs)("div",{className:"cardMeta",children:[t("ext.streaming.settings.transmissions",{},"Transmissões configuradas"),": ",ms]}),r?(0,a.jsx)("div",{className:"settingsStatusMuted",children:t("ext.streaming.settings.health.loading")}):null,r||f||"ok"!==v?.status?null:(0,a.jsx)("div",{className:"streamingStatusOk",children:t("ext.streaming.settings.health.ok")}),r||!f&&"ok"===v?.status?null:(0,a.jsxs)("div",{className:"errorText",children:[t("ext.streaming.settings.health.failed")," ",f?`(${f})`:""]}),(0,a.jsx)("div",{className:"rowWrap",children:(0,a.jsx)("button",{className:"chipButton",type:"button",onClick:()=>{cs()},children:t("ext.streaming.settings.health.refresh")})})]})}),(0,a.jsx)("div",{className:"sectionDivider"}),(0,a.jsx)("div",{className:"card",children:(0,a.jsxs)("div",{className:"cardBody",children:[(0,a.jsx)("div",{className:"modalSectionTitle",style:{marginBottom:6},children:t("ext.streaming.engine.title",{},"Engine (MediaMTX)")}),j?(0,a.jsx)("div",{className:"settingsStatusMuted",children:t("ext.streaming.engine.loading")}):null,!j&&z?.running?(0,a.jsx)("div",{className:"streamingStatusOk",children:t("ext.streaming.engine.running")}):null,j||z?.running?null:(0,a.jsx)("div",{className:"settingsStatusMuted",children:t("ext.streaming.engine.stopped")}),z?(0,a.jsxs)("div",{className:"streamingFormGrid streamingFormGridEnginePorts",style:{marginTop:10},children:[(0,a.jsxs)("div",{className:"cardMeta",children:[t("ext.streaming.engine.meta_version",{},"Versão"),": ",z.mediamtx_version||"-"]}),(0,a.jsxs)("div",{className:"cardMeta",children:[t("ext.streaming.engine.meta_pid",{},"PID"),": ",z.pid??"-"]}),(0,a.jsxs)("div",{className:"cardMeta",children:[t("ext.streaming.engine.meta_uptime",{},"Uptime"),": ",x(z.uptime_seconds)]}),(0,a.jsxs)("div",{className:"cardMeta",children:[t("ext.streaming.engine.meta_api",{},"API"),": ",z.ports?.api??"-"]})]}):null,z?.bind_host&&z?.ports?(0,a.jsxs)("div",{className:"cardMeta",style:{marginTop:6},children:[z.bind_host," - RTSP ",z.ports.rtsp??"-"," - HLS ",z.ports.hls??"-"," - WebRTC"," ",z.ports.webrtc??"-"]}):null,z?.urls?.rtsp_url?(0,a.jsxs)("div",{className:"cardMeta",style:{marginTop:6},children:[t("ext.streaming.engine.test_rtsp",{},"RTSP (test)"),": ",z.urls.rtsp_url]}):null,z?.urls?.hls_url?(0,a.jsxs)("div",{className:"cardMeta",children:[t("ext.streaming.engine.test_hls",{},"HLS (test)"),": ",z.urls.hls_url]}):null,z?.urls?.webrtc_url?(0,a.jsxs)("div",{className:"cardMeta",children:[t("ext.streaming.engine.test_webrtc",{},"WebRTC/WHEP (test)"),": ",z.urls.webrtc_url]}):null,Array.isArray(z?.warnings)&&z.warnings.length>0?(0,a.jsx)("div",{style:{marginTop:6},children:z.warnings.map((e,s)=>(0,a.jsx)("div",{className:"cardMeta",style:s>0?{marginTop:4}:void 0,children:e},`${e}-${s}`))}):null,ks.length>0?(0,a.jsx)("div",{className:"cardMeta",style:{marginTop:6},children:t("ext.streaming.engine.orphan_processes",{count:ks.length,pids:ks.join(", ")},`Found ${ks.length} external MediaMTX process(es) for this data directory: ${ks.join(", ")}.`)}):null,z?.last_error?(0,a.jsx)("div",{className:"errorText",style:{marginTop:6},children:z.last_error}):null,M?(0,a.jsx)("div",{className:"errorText",style:{marginTop:6},children:M}):null,(0,a.jsxs)("div",{className:"rowWrap",style:{gap:8},children:[(0,a.jsx)("button",{className:"primaryButton",type:"button",disabled:w,onClick:()=>{bs(zs)},children:Ts}),(0,a.jsxs)("button",{className:"chipButton",type:"button",disabled:w,onClick:()=>{!async function(){S(!0),k("download"),A(null);try{const e=await(0,n.jP)();T(e),gs()}catch(e){A(e instanceof Error?e.message:String(e)),ds()}finally{S(!1),k(null)}}()},children:[(0,a.jsx)("i",{className:"fa-solid fa-download","aria-hidden":"true"})," ",Ps]}),(0,a.jsx)("button",{className:"chipButton",type:"button",disabled:w||!Cs,onClick:()=>{bs("stop")},children:Ms}),(0,a.jsxs)("button",{className:"chipButton",type:"button",disabled:w,onClick:()=>{bs("reclaim")},children:[(0,a.jsx)("i",{className:"fa-solid fa-broom","aria-hidden":"true"})," ",As]}),(0,a.jsxs)("button",{className:"chipButton",type:"button",disabled:w||"refresh"===C,onClick:()=>{!async function(){k("refresh");try{await ds()}finally{k(null)}}()},children:[(0,a.jsx)("i",{className:"fa-solid fa-rotate-right","aria-hidden":"true"})," ",Ls]})]}),z?(0,a.jsxs)("div",{style:{marginTop:10},children:[(0,a.jsxs)("div",{className:"cardMeta",children:[t("ext.streaming.engine.meta_restarts",{},"Reinícios"),": ",z.restart_count??0]}),z.binary_path?(0,a.jsxs)("div",{className:"cardMeta",style:{marginTop:4},children:[t("ext.streaming.engine.meta_binary",{},"Binário"),": ",z.binary_path]}):null,z.config_path?(0,a.jsxs)("div",{className:"cardMeta",style:{marginTop:4},children:[t("ext.streaming.engine.meta_config",{},"Config"),": ",z.config_path]}):null,z.log_path?(0,a.jsxs)("div",{className:"cardMeta",style:{marginTop:4},children:[t("ext.streaming.engine.meta_log",{},"Log"),": ",z.log_path]}):null]}):null,(0,a.jsx)("div",{className:"sectionDivider"}),(0,a.jsx)("div",{className:"modalSectionTitle",style:{marginBottom:6},children:t("ext.streaming.engine.settings_title",{},"Configuração")}),P?(0,a.jsx)("div",{className:"settingsStatusMuted",children:t("ext.streaming.engine.settings_loading",{},"Carregando…")}):null,B?(0,a.jsx)("div",{className:"errorText",children:B}):null,!P&&F?(0,a.jsxs)("div",{children:[(0,a.jsx)("div",{className:"rowWrap",style:{gap:10},children:(0,a.jsxs)("label",{className:"rowWrap",style:{gap:8},children:[(0,a.jsx)("input",{type:"checkbox",checked:Boolean(F.expose_to_lan),onChange:e=>{U(s=>({...s??{},expose_to_lan:e.target.checked})),I(!0)}}),(0,a.jsx)("span",{className:"cardMeta",children:t("ext.streaming.engine.expose_to_lan",{},"Expor na LAN (0.0.0.0)")})]})}),(0,a.jsxs)("div",{className:"streamingFormGrid streamingFormGridEnginePorts",style:{marginTop:10},children:[(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.engine.port_rtsp",{},"RTSP port")}),(0,a.jsx)("input",{className:"input",value:String(F.preferred_ports?.rtsp??""),onChange:e=>{const s=c(e.target.value);U(e=>({...e??{},preferred_ports:{...e?.preferred_ports??{},rtsp:s??void 0}})),I(!0)}})]}),(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.engine.port_hls",{},"HLS port")}),(0,a.jsx)("input",{className:"input",value:String(F.preferred_ports?.hls??""),onChange:e=>{const s=c(e.target.value);U(e=>({...e??{},preferred_ports:{...e?.preferred_ports??{},hls:s??void 0}})),I(!0)}})]}),(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.engine.port_webrtc",{},"WebRTC port")}),(0,a.jsx)("input",{className:"input",value:String(F.preferred_ports?.webrtc??""),onChange:e=>{const s=c(e.target.value);U(e=>({...e??{},preferred_ports:{...e?.preferred_ports??{},webrtc:s??void 0}})),I(!0)}})]}),(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.engine.port_api",{},"API port")}),(0,a.jsx)("input",{className:"input",value:String(F.preferred_ports?.api??""),onChange:e=>{const s=c(e.target.value);U(e=>({...e??{},preferred_ports:{...e?.preferred_ports??{},api:s??void 0}})),I(!0)}})]})]}),(0,a.jsxs)("div",{className:"field",style:{marginTop:10},children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.engine.ice_servers_label",{},"STUN/TURN servers (optional, one per line)")}),(0,a.jsx)("textarea",{className:"input",style:{minHeight:84,padding:"8px 10px"},value:(Bs=F.webrtc_ice_servers,Array.isArray(Bs)&&0!==Bs.length?Bs.map(e=>String(e||"").trim()).filter(Boolean).join("\n"):""),placeholder:"stun:stun.l.google.com:19302\nturn:username:password@turn.example.com:3478?transport=udp",onChange:e=>{U(s=>({...s??{},webrtc_ice_servers:p(e.target.value)})),I(!0)}}),(0,a.jsx)("div",{className:"cardMeta",style:{marginTop:6},children:t("ext.streaming.engine.ice_servers_hint",{},"Use only when you need to traverse NAT. On a simple LAN, leave it empty.")})]}),(0,a.jsxs)("div",{className:"rowWrap",style:{gap:8,justifyContent:"flex-end",marginTop:10},children:[(0,a.jsx)("button",{className:"chipButton",type:"button",disabled:!W||O,onClick:()=>{E?.engine&&(U(g(E.engine)),I(!1))},children:t("ext.streaming.engine.settings_discard",{},"Descartar")}),(0,a.jsx)("button",{className:"primaryButton",type:"button",disabled:!W||O,onClick:()=>{!async function(){if(F){H(!0),R(null);try{const e=await(0,n.eR)({engine:{expose_to_lan:Boolean(F.expose_to_lan),preferred_ports:{rtsp:F.preferred_ports?.rtsp,hls:F.preferred_ports?.hls,api:F.preferred_ports?.api,webrtc:F.preferred_ports?.webrtc},webrtc_ice_servers:Array.isArray(F.webrtc_ice_servers)?F.webrtc_ice_servers:[]}});D(e),U(g(e.engine??{})),I(!1),ds()}catch(e){R(e instanceof Error?e.message:String(e))}finally{H(!1)}}}()},children:O?t("ext.streaming.engine.settings_applying",{},"Aplicando…"):t("ext.streaming.engine.settings_apply",{},"Aplicar")})]})]}):null]})}),(0,a.jsx)("div",{className:"sectionDivider"}),(0,a.jsxs)("div",{className:"settingsSplit",children:[(0,a.jsxs)("div",{className:"settingsSplitSidebar",children:[(0,a.jsxs)("div",{className:"settingsSplitToolbar",children:[(0,a.jsx)("input",{className:"input",placeholder:t("ext.streaming.transmissions.search",{},"Buscar transmissões…"),value:J,onChange:e=>Q(e.target.value)}),(0,a.jsx)("button",{className:"iconButton iconButtonPrimary",type:"button","aria-label":t("ext.streaming.transmissions.add",{},"Adicionar transmissão"),onClick:()=>{Te(null),Re("local"),Se(!0)},children:(0,a.jsx)("i",{className:"fa-solid fa-plus","aria-hidden":"true"})})]}),$?(0,a.jsx)("div",{className:"settingsStatusMuted",style:{marginTop:10},children:t("ext.streaming.transmissions.loading",{},"Carregando…")}):null,G?(0,a.jsx)("div",{className:"errorText",style:{marginTop:10},children:G}):null,ve?(0,a.jsx)("div",{className:"settingsStatusMuted",style:{marginTop:10},children:t("ext.streaming.processing_servers.loading",{},"Loading processing servers…")}):null,fe?(0,a.jsx)("div",{className:"errorText",style:{marginTop:10},children:fe}):null,0!==_s.length||$?(0,a.jsx)("div",{className:"settingsList",children:_s.map(e=>{const s=e.id===Y,i=String(e.name||"").trim()||String(e.path||"").trim()||e.id,n=_(e.host_server_id),r=Array.isArray(e.outputs)?e.outputs.length:0,o=t("ext.streaming.transmissions.meta_line",{host:n,path:e.path||"-",outputs:r},`host: ${n} • path: ${e.path||"-"} • outputs: ${r}`);return(0,a.jsx)("button",{type:"button",className:["choiceItem",s?"isSelected":""].filter(Boolean).join(" "),onClick:()=>function(e){if(e!==Y)return re?(se(e),void ae(!0)):void Z(e)}(e.id),children:(0,a.jsxs)("div",{className:"settingsListItemRow",children:[(0,a.jsxs)("div",{className:"settingsListItemMain",children:[(0,a.jsx)("div",{className:"settingsListItemTitle",title:i,children:i}),(0,a.jsx)("div",{className:"settingsListItemMeta",title:o,children:o})]}),e.enabled?null:(0,a.jsx)("span",{className:"pillBadge",title:t("ext.streaming.transmissions.badge_disabled_title",{},"Disabled"),children:t("ext.streaming.transmissions.badge_disabled",{},"off")})]})},e.id)})}):(0,a.jsx)("div",{className:"card",style:{marginTop:10},children:(0,a.jsxs)("div",{className:"cardBody",children:[(0,a.jsx)("div",{children:t("ext.streaming.transmissions.empty",{},"Nenhuma transmissão criada.")}),(0,a.jsxs)("ol",{className:"streamingQuickStepsList streamingQuickStepsListCompact",children:[(0,a.jsx)("li",{children:t("ext.streaming.settings.quickstart_step_1",{},"Crie uma transmissão com ao menos uma saída.")}),(0,a.jsx)("li",{children:t("ext.streaming.settings.quickstart_step_2",{},"Ajuste resolução/FPS/autenticação por saída.")}),(0,a.jsx)("li",{children:t("ext.streaming.settings.quickstart_step_3",{},"Salve, carregue URLs e use o wizard para gerar o pipeline.")})]}),(0,a.jsxs)("button",{className:"primaryButton",type:"button",onClick:()=>{Re("local"),Se(!0)},children:[(0,a.jsx)("i",{className:"fa-solid fa-plus","aria-hidden":"true"})," ",t("ext.streaming.transmissions.add",{},"Adicionar transmissão")]})]})})]}),(0,a.jsx)("div",{className:"settingsSplitMain",children:hs&&ie?(0,a.jsxs)("div",{className:"settingsDetail",children:[(0,a.jsxs)("div",{className:"settingsDetailHeader",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("div",{className:"modalSectionTitle",style:{marginBottom:4},children:ie.name?.trim()||ie.path?.trim()||ie.id}),(0,a.jsxs)("div",{className:"cardMeta",children:["ID: ",ie.id]})]}),(0,a.jsxs)("div",{className:"rowWrap",style:{gap:10,justifyContent:"flex-end"},children:[re?(0,a.jsx)("span",{className:"pillBadge",title:t("ext.streaming.transmissions.badge_unsaved_title",{},"Unsaved changes"),children:t("ext.streaming.transmissions.badge_unsaved",{},"pending")}):null,(0,a.jsx)("button",{className:"chipButton",type:"button",disabled:!re||le,onClick:function(){hs&&(ne(g(hs)),oe(!1),de(null),xe(null))},children:t("ext.streaming.transmissions.discard",{},"Descartar")}),(0,a.jsx)("button",{className:"primaryButton",type:"button",disabled:!re||le,onClick:()=>{ws()},children:le?t("ext.streaming.transmissions.saving",{},"Salvando…"):t("ext.streaming.transmissions.save",{},"Salvar")}),(0,a.jsx)("button",{className:"chipButton",type:"button",disabled:le,onClick:()=>ss(!0),children:t("ext.streaming.transmissions.delete",{},"Excluir")})]})]}),ce?(0,a.jsx)("div",{className:"errorText",style:{marginTop:10},children:ce}):null,(0,a.jsx)("div",{className:"sectionDivider"}),(0,a.jsx)("div",{className:"card",children:(0,a.jsxs)("div",{className:"cardBody",children:[(0,a.jsx)("div",{className:"modalSectionTitle",style:{marginBottom:6},children:t("ext.streaming.transmissions.basic",{},"Básico")}),(0,a.jsxs)("div",{className:"streamingFormGrid streamingFormGridTransmissionPrimary",children:[(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.transmissions.name",{},"Nome")}),(0,a.jsx)("input",{className:"input",value:ie.name??"",onChange:e=>ys({name:e.target.value})})]}),(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.transmissions.path",{},"Path/slug")}),(0,a.jsx)("input",{className:"input",value:ie.path??"",onChange:e=>ys({path:e.target.value})}),(0,a.jsx)("div",{className:"cardMeta",style:{marginTop:6},children:t("ext.streaming.transmissions.path_hint",{},"Use apenas a-z, 0-9, - e _. O servidor normaliza automaticamente.")})]})]}),(0,a.jsx)("div",{className:"rowWrap",style:{gap:14,marginTop:10},children:(0,a.jsxs)("label",{className:"rowWrap",style:{gap:8},children:[(0,a.jsx)("input",{type:"checkbox",checked:Boolean(ie.enabled),onChange:e=>ys({enabled:e.target.checked})}),(0,a.jsx)("span",{className:"cardMeta",children:t("ext.streaming.transmissions.enabled",{},"Ativa")})]})}),(0,a.jsxs)("div",{className:"streamingFormGrid streamingFormGridTransmissionSecondary",style:{marginTop:10},children:[(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.transmissions.host_server",{},"Host server")}),(0,a.jsxs)("select",{className:"input",value:_(ie.host_server_id),onChange:e=>ys({host_server_id:_(e.target.value)}),children:[je.map(e=>{const s=_(e.id),i=String(e.name||"").trim(),n="local"===s?t("ext.streaming.processing_servers.local_label",{},"local (this machine)"):i?`${s} (${i})`:s;return(0,a.jsx)("option",{value:s,children:n},s)}),vs.has(_(ie.host_server_id))?null:(0,a.jsx)("option",{value:_(ie.host_server_id),children:_(ie.host_server_id)})]}),(0,a.jsx)("div",{className:"cardMeta",style:{marginTop:6},children:t("ext.streaming.transmissions.host_server_hint",{},"A transmissão será hospedada neste processing server.")})]}),(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.transmissions.placeholder",{},"Placeholder")}),(0,a.jsxs)("select",{className:"input",value:ie.placeholder??"gray",onChange:e=>ys({placeholder:e.target.value}),children:[(0,a.jsx)("option",{value:"gray",children:t("ext.streaming.transmissions.placeholder.gray",{},"Gray")}),(0,a.jsx)("option",{value:"black",children:t("ext.streaming.transmissions.placeholder.black",{},"Black")})]})]}),(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.transmissions.arbitration",{},"Arbitragem")}),(0,a.jsxs)("select",{className:"input",value:ie.arbitration??"priority_latest",onChange:e=>ys({arbitration:e.target.value}),children:[(0,a.jsx)("option",{value:"priority_latest",children:t("ext.streaming.transmissions.arbitration.priority_latest",{},"Priority, then latest")}),(0,a.jsx)("option",{value:"latest",children:t("ext.streaming.transmissions.arbitration.latest",{},"Latest writer wins")})]})]})]}),(0,a.jsxs)("div",{style:{marginTop:14},children:[(0,a.jsx)("div",{className:"modalSectionTitle",style:{marginBottom:6},children:t("ext.streaming.transmissions.camera_controls.title",{},"Controles de câmera")}),(0,a.jsxs)("div",{className:"rowWrap",style:{gap:10,alignItems:"center"},children:[(0,a.jsxs)("label",{className:"rowWrap",style:{gap:8},children:[(0,a.jsx)("input",{type:"checkbox",checked:Boolean(ie.camera_controls?.enabled),disabled:!Boolean(ie.camera_controls?.enabled)&&(Ke||0===Ye.length),onChange:e=>{if(!e.target.checked)return void ys({camera_controls:null});const s=String(ie.camera_controls?.camera_id||"").trim(),t=String(Ye[0]?.id||"").trim();ys({camera_controls:{enabled:!0,camera_id:s||t}})}}),(0,a.jsx)("span",{className:"cardMeta",children:t("ext.streaming.transmissions.camera_controls.enable",{},"Habilitar controles de câmera")})]}),Ke?(0,a.jsx)("div",{className:"settingsStatusMuted",children:t("ext.streaming.transmissions.camera_controls.loading",{},"Carregando câmeras…")}):null]}),(0,a.jsx)("div",{className:"cardMeta",style:{marginTop:6},children:t("ext.streaming.transmissions.camera_controls.hint",{},"Quando habilitado, esta transmissão poderá controlar uma câmera (presets/PTZ) via API.")}),Je?(0,a.jsx)("div",{className:"errorText",style:{marginTop:8},children:Je}):null,Boolean(ie.camera_controls?.enabled)?(0,a.jsxs)("div",{className:"field",style:{marginTop:10},children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.transmissions.camera_controls.camera",{},"Câmera")}),(0,a.jsxs)("select",{className:"input",value:String(ie.camera_controls?.camera_id||"").trim(),onChange:e=>{ys({camera_controls:{enabled:!0,camera_id:String(e.target.value||"").trim()}})},disabled:0===Ye.length,children:[Ye.map(e=>{const s=String(e.id||"").trim(),t=String(e.name||"").trim()||s;return(0,a.jsx)("option",{value:s,children:t},s)}),(()=>{const e=String(ie.camera_controls?.camera_id||"").trim(),s=Ye.some(s=>String(s.id||"").trim()===e);return!e||s?null:(0,a.jsx)("option",{value:e,children:e})})()]}),0!==Ye.length||Ke?null:(0,a.jsx)("div",{className:"cardMeta",style:{marginTop:6},children:t("ext.streaming.transmissions.camera_controls.empty",{},"Nenhuma câmera encontrada. Cadastre uma câmera em Configurações > Câmeras.")})]}):null]}),vs.has(_(ie.host_server_id))?null:(0,a.jsx)("div",{className:"errorText",style:{marginTop:10},children:t("ext.streaming.transmissions.host_server_missing",{},"This host server no longer exists. Select another one before saving.")})]})}),(0,a.jsx)("div",{className:"sectionDivider"}),(0,a.jsx)("div",{className:"card",children:(0,a.jsxs)("div",{className:"cardBody",children:[(0,a.jsxs)("div",{className:"settingsDetailHeader",style:{marginBottom:10},children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("div",{className:"modalSectionTitle",style:{marginBottom:4},children:t("ext.streaming.transmissions.outputs",{},"Saídas")}),(0,a.jsx)("div",{className:"cardMeta",children:t("ext.streaming.transmissions.outputs_hint",{},"Cada saída pode ter resolução/FPS/bitrate diferentes.")})]}),(0,a.jsxs)("div",{className:"rowWrap",style:{gap:8,justifyContent:"flex-end"},children:[(0,a.jsx)("button",{className:"chipButton",type:"button",onClick:()=>Ns("hls"),children:t("ext.streaming.outputs.add_hls",{},"+ HLS")}),(0,a.jsx)("button",{className:"chipButton",type:"button",onClick:()=>Ns("rtsp"),children:t("ext.streaming.outputs.add_rtsp",{},"+ RTSP")}),(0,a.jsx)("button",{className:"chipButton",type:"button",onClick:()=>Ns("webrtc"),children:t("ext.streaming.outputs.add_webrtc",{},"+ WebRTC")})]})]}),Array.isArray(ie.outputs)&&0===ie.outputs.length?(0,a.jsx)("div",{className:"cardMeta",children:t("ext.streaming.transmissions.outputs_empty",{},"Nenhuma saída adicionada.")}):null,Array.isArray(ie.outputs)?ie.outputs.map(e=>{const s=e.authentication??{enabled:!1,username:"",password:""},i=e.resolution??{width:1280,height:720};return(0,a.jsx)("div",{className:"card",style:{marginTop:10},children:(0,a.jsxs)("div",{className:"cardBody",children:[(0,a.jsxs)("div",{className:"settingsDetailHeader",children:[(0,a.jsxs)("div",{children:[(0,a.jsxs)("div",{className:"settingsListItemTitle",children:[e.protocol.toUpperCase()," ",(0,a.jsxs)("span",{className:"cardMeta",style:{fontWeight:500},children:["(",i.width??"-","x",i.height??"-",")"]})]}),(0,a.jsxs)("div",{className:"settingsListItemMeta",children:[t("ext.streaming.outputs.output_id",{},"Output ID"),": ",e.id]})]}),(0,a.jsxs)("div",{className:"rowWrap",style:{gap:10,justifyContent:"flex-end"},children:[(0,a.jsxs)("label",{className:"rowWrap",style:{gap:8},children:[(0,a.jsx)("input",{type:"checkbox",checked:Boolean(e.enabled),onChange:s=>js(e.id,{enabled:s.target.checked})}),(0,a.jsx)("span",{className:"cardMeta",children:t("ext.streaming.outputs.enabled",{},"Ativa")})]}),(0,a.jsx)("button",{className:"chipButton",type:"button",onClick:()=>{return s=e.id,ne(e=>{if(!e)return e;const t=Array.isArray(e.outputs)?e.outputs:[];return{...e,outputs:t.filter(e=>e.id!==s)}}),oe(!0),void de(null);var s},children:t("ext.streaming.outputs.remove",{},"Remover")})]})]}),(0,a.jsxs)("div",{className:"streamingFormGrid streamingFormGridOutputMain",style:{marginTop:10},children:[(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.outputs.protocol",{},"Protocolo")}),(0,a.jsxs)("select",{className:"input",value:e.protocol,onChange:s=>js(e.id,{protocol:s.target.value}),children:[(0,a.jsx)("option",{value:"hls",children:"HLS"}),(0,a.jsx)("option",{value:"rtsp",children:"RTSP"}),(0,a.jsx)("option",{value:"webrtc",children:"WebRTC"})]})]}),(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.outputs.width",{},"Largura")}),(0,a.jsx)("input",{className:"input",value:String(i.width??""),onChange:s=>{const t=c(s.target.value);if(null===t)return void js(e.id,{resolution:null});const a="number"==typeof i.height&&i.height>0?i.height:720;js(e.id,{resolution:{width:Math.max(1,t),height:Math.max(1,a)}})}})]}),(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.outputs.height",{},"Altura")}),(0,a.jsx)("input",{className:"input",value:String(i.height??""),onChange:s=>{const t=c(s.target.value);if(null===t)return void js(e.id,{resolution:null});const a="number"==typeof i.width&&i.width>0?i.width:1280;js(e.id,{resolution:{width:Math.max(1,a),height:Math.max(1,t)}})}})]}),(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.outputs.fps",{},"FPS")}),(0,a.jsx)("input",{className:"input",value:null===e.fps_limit||void 0===e.fps_limit?"":String(e.fps_limit),onChange:s=>js(e.id,{fps_limit:c(s.target.value)})})]}),(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.outputs.bitrate",{},"Bitrate (kbps)")}),(0,a.jsx)("input",{className:"input",value:null===e.bitrate_kbps||void 0===e.bitrate_kbps?"":String(e.bitrate_kbps),onChange:s=>js(e.id,{bitrate_kbps:c(s.target.value)})})]}),(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.outputs.latency",{},"Latência")}),(0,a.jsxs)("select",{className:"input",value:e.latency_profile??"normal",onChange:s=>js(e.id,{latency_profile:s.target.value}),children:[(0,a.jsx)("option",{value:"normal",children:t("ext.streaming.outputs.latency_option.normal",{},"Normal")}),(0,a.jsx)("option",{value:"low",children:t("ext.streaming.outputs.latency_option.low",{},"Low")}),(0,a.jsx)("option",{value:"ultra_low",children:t("ext.streaming.outputs.latency_option.ultra_low",{},"Ultra low")})]})]})]}),(0,a.jsx)("div",{className:"sectionDivider"}),(0,a.jsx)("div",{className:"modalSectionTitle",style:{marginBottom:6},children:t("ext.streaming.outputs.auth",{},"Autenticação (opcional)")}),(0,a.jsx)("div",{className:"rowWrap",style:{gap:14},children:(0,a.jsxs)("label",{className:"rowWrap",style:{gap:8},children:[(0,a.jsx)("input",{type:"checkbox",checked:Boolean(s.enabled),onChange:t=>{const a=t.target.checked;js(e.id,{authentication:{...s,enabled:a}})}}),(0,a.jsx)("span",{className:"cardMeta",children:t("ext.streaming.outputs.auth_enabled",{},"Habilitar user/senha")})]})}),s.enabled?(0,a.jsxs)("div",{className:"streamingFormGrid streamingFormGridOutputAuth",style:{marginTop:10},children:[(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.outputs.username",{},"Usuário")}),(0,a.jsx)("input",{className:"input",value:String(s.username??""),onChange:t=>js(e.id,{authentication:{...s,username:t.target.value}})})]}),(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.outputs.password",{},"Senha")}),(0,a.jsx)("input",{className:"input",type:"password",value:String(s.password??""),onChange:t=>js(e.id,{authentication:{...s,password:t.target.value}})})]}),(0,a.jsx)("div",{className:"cardMeta streamingOutputAuthNote",children:t("ext.streaming.outputs.auth_note",{},"As credenciais são aplicadas no MediaMTX para leitura/playback deste output.")})]}):null]})},e.id)}):null]})}),(0,a.jsx)("div",{className:"sectionDivider"}),(0,a.jsx)("div",{className:"card",children:(0,a.jsxs)("div",{className:"cardBody",children:[(0,a.jsxs)("div",{className:"settingsDetailHeader",style:{marginBottom:10},children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("div",{className:"modalSectionTitle",style:{marginBottom:4},children:t("ext.streaming.transmissions.urls",{},"URLs")}),(0,a.jsx)("div",{className:"cardMeta",children:t("ext.streaming.transmissions.urls_hint",{},"As URLs são geradas pelo engine (MediaMTX).")})]}),(0,a.jsxs)("div",{className:"rowWrap",style:{gap:8,justifyContent:"flex-end"},children:[(0,a.jsx)("button",{className:"chipButton",type:"button",disabled:pe===ie.id,onClick:()=>{fs(ie.id)},children:pe===ie.id?t("ext.streaming.transmissions.loading_urls",{},"Carregando URLs…"):t("ext.streaming.transmissions.load_urls",{},"Carregar URLs")}),(0,a.jsx)("button",{className:"primaryButton",type:"button",onClick:()=>os(ie),children:t("ext.streaming.wizard.open",{},"Criar pipeline com esta transmissão")})]})]}),z?.running?null:(0,a.jsx)("div",{className:"cardMeta",style:{marginBottom:10},children:t("ext.streaming.transmissions.engine_off_warning",{},"A engine está parada: as URLs existirão, mas não haverá playback até iniciar.")}),re?(0,a.jsx)("div",{className:"cardMeta",style:{marginBottom:10},children:t("ext.streaming.transmissions.urls_save_warning",{},"Salve alterações para garantir que paths/outputs estejam atualizados antes de compartilhar URLs.")}):null,Ss&&Ss.transmission_id===ie.id?(0,a.jsxs)("div",{children:[Ss.outputs.map(e=>(0,a.jsx)("div",{className:"card",style:{marginTop:10},children:(0,a.jsxs)("div",{className:"cardBody",children:[(0,a.jsx)("div",{className:"settingsListItemTitle",style:{marginBottom:6},children:e.protocol.toUpperCase()}),(0,a.jsxs)("div",{className:"cardMeta",children:[t("ext.streaming.transmissions.engine_path",{},"Engine path"),": ",e.resolved_engine_path]}),e.requires_auth?(0,a.jsx)("div",{className:"cardMeta",style:{marginTop:6},children:e.auth_username?t("ext.streaming.transmissions.auth_required_user",{username:e.auth_username},`Requires authentication (username: ${e.auth_username}).`):t("ext.streaming.transmissions.auth_required",{},"Requires authentication.")}):(0,a.jsx)("div",{className:"cardMeta",style:{marginTop:6},children:t("ext.streaming.transmissions.auth_not_required",{},"No authentication.")}),(0,a.jsxs)("div",{className:"rowWrap",style:{gap:8,marginTop:10},children:[(0,a.jsx)("input",{className:"input",style:{flex:1},value:e.url,readOnly:!0}),(0,a.jsx)("button",{className:"iconButton",type:"button","aria-label":t("ext.streaming.transmissions.copy_url",{},"Copy URL"),onClick:()=>{(async function(e){const s=String(e??"");try{return void await navigator.clipboard.writeText(s)}catch{}const t=document.createElement("textarea");t.value=s,t.style.position="fixed",t.style.top="-9999px",t.style.left="-9999px",t.setAttribute("readonly","true"),document.body.appendChild(t),t.select();try{document.execCommand("copy")}finally{document.body.removeChild(t)}})(e.url).then(()=>{_e(e.url),window.setTimeout(()=>_e(null),1200)})},children:(0,a.jsx)("i",{className:"fa-solid fa-copy","aria-hidden":"true"})})]}),he===e.url?(0,a.jsx)("div",{className:"streamingStatusOk",style:{marginTop:8},children:t("ext.streaming.transmissions.copied",{},"Copiado!")}):null]})},`${Ss.transmission_id}-${e.output_id}`)),Array.isArray(Ss.warnings)&&Ss.warnings.length>0?(0,a.jsx)("div",{className:"cardMeta",style:{marginTop:10},children:Ss.warnings.join(" ")}):null]}):(0,a.jsx)("div",{className:"cardMeta",children:t("ext.streaming.transmissions.urls_empty",{},"Carregue as URLs para visualizar aqui.")})]})})]}):(0,a.jsx)("div",{className:"card",children:(0,a.jsxs)("div",{className:"cardBody",children:[(0,a.jsx)("div",{children:t("ext.streaming.transmissions.select",{},"Selecione uma transmissão para editar.")}),(0,a.jsx)("div",{className:"cardMeta",children:t("ext.streaming.transmissions.select_hint",{},"Dica: comece criando uma transmissão e depois abra o wizard para gerar o pipeline.")}),(0,a.jsxs)("button",{className:"primaryButton",type:"button",onClick:()=>{Re("local"),Se(!0)},children:[(0,a.jsx)("i",{className:"fa-solid fa-plus","aria-hidden":"true"})," ",t("ext.streaming.transmissions.add",{},"Adicionar transmissão")]})]})})})]}),(0,a.jsxs)(o.y,{open:we,title:t("ext.streaming.transmissions.create",{},"Criar transmissão"),closeAriaLabel:t("core.actions.close",{},"Close"),onClose:()=>{Ce||Se(!1)},children:[ze?(0,a.jsx)("div",{className:"errorText",style:{marginBottom:10},children:ze}):null,(0,a.jsxs)("div",{className:"streamingFormGrid streamingFormGridCreatePrimary",children:[(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.transmissions.name",{},"Nome")}),(0,a.jsx)("input",{className:"input",value:Me,onChange:e=>Ae(e.target.value)})]}),(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.transmissions.path",{},"Path/slug")}),(0,a.jsx)("input",{className:"input",value:Pe,onChange:e=>Le(e.target.value),placeholder:d(Me)||"stream"})]}),(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.transmissions.host_server",{},"Host server")}),(0,a.jsx)("select",{className:"input",value:_(Be),onChange:e=>Re(_(e.target.value)),children:je.map(e=>{const s=_(e.id),i=String(e.name||"").trim(),n="local"===s?t("ext.streaming.processing_servers.local_label",{},"local (this machine)"):i?`${s} (${i})`:s;return(0,a.jsx)("option",{value:s,children:n},s)})})]})]}),(0,a.jsxs)("div",{className:"streamingFormGrid streamingFormGridCreateOutput",style:{marginTop:10},children:[(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.transmissions.protocol",{},"Saída")}),(0,a.jsxs)("select",{className:"input",value:Ee,onChange:e=>De(e.target.value),children:[(0,a.jsx)("option",{value:"hls",children:"HLS"}),(0,a.jsx)("option",{value:"rtsp",children:"RTSP"}),(0,a.jsx)("option",{value:"webrtc",children:"WebRTC"})]})]}),(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.transmissions.width",{},"Largura")}),(0,a.jsx)("input",{className:"input",value:Fe,onChange:e=>Ue(e.target.value)})]}),(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.transmissions.height",{},"Altura")}),(0,a.jsx)("input",{className:"input",value:We,onChange:e=>Ie(e.target.value)})]}),(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.transmissions.fps",{},"FPS")}),(0,a.jsx)("input",{className:"input",value:Oe,onChange:e=>He(e.target.value)})]})]}),(0,a.jsx)("div",{className:"sectionDivider",style:{marginTop:14}}),(0,a.jsx)("div",{className:"modalSectionTitle",style:{marginBottom:6},children:t("ext.streaming.transmissions.camera_controls.title",{},"Controles de câmera")}),(0,a.jsx)("div",{className:"rowWrap",style:{gap:10},children:(0,a.jsxs)("label",{className:"rowWrap",style:{gap:8},children:[(0,a.jsx)("input",{type:"checkbox",checked:$e,onChange:e=>qe(e.target.checked)}),(0,a.jsx)("span",{className:"cardMeta",children:t("ext.streaming.transmissions.camera_controls.enable",{},"Habilitar controles de câmera")})]})}),(0,a.jsx)("div",{className:"cardMeta",style:{marginTop:6},children:t("ext.streaming.transmissions.camera_controls.hint",{},"Quando habilitado, esta transmissão poderá controlar uma câmera (presets/PTZ) via API.")}),$e?(0,a.jsxs)("div",{style:{marginTop:10},children:[Ke?(0,a.jsx)("div",{className:"settingsStatusMuted",children:t("ext.streaming.transmissions.camera_controls.loading",{},"Carregando câmeras…")}):null,Je?(0,a.jsx)("div",{className:"errorText",children:Je}):null,(0,a.jsx)("div",{className:"streamingFormGrid streamingFormGridCreatePrimary",style:{marginTop:10},children:(0,a.jsxs)("div",{className:"field",children:[(0,a.jsx)("label",{className:"label",children:t("ext.streaming.transmissions.camera_controls.camera",{},"Câmera")}),(0,a.jsx)("select",{className:"input",value:Ge,onChange:e=>Xe(String(e.target.value||"").trim()),disabled:0===Ye.length,children:Ye.map(e=>{const s=String(e.id||"").trim(),t=String(e.name||"").trim()||s;return(0,a.jsx)("option",{value:s,children:t},s)})}),0!==Ye.length||Ke?null:(0,a.jsx)("div",{className:"cardMeta",style:{marginTop:6},children:t("ext.streaming.transmissions.camera_controls.empty",{},"Nenhuma câmera encontrada. Cadastre uma câmera em Configurações > Câmeras.")})]})})]}):null,(0,a.jsx)("div",{className:"rowWrap",style:{marginTop:12,justifyContent:"flex-end"},children:(0,a.jsx)("button",{className:"primaryButton",type:"button",disabled:Ce,onClick:()=>{!async function(){ke(!0),Te(null);try{const e=_(Be);if(!vs.has(e))return void Te(t("ext.streaming.errors.invalid_host_server",{serverId:e},`Invalid host server: ${e}`));const s=Me.trim()||t("ext.streaming.transmissions.default_name",{},"Transmission"),a=d(Pe.trim()||s)||"stream";let i;if($e){const e=Ge.trim();if(!e)return void Te(t("ext.streaming.transmissions.camera_controls.select_camera_error",{},"Selecione uma câmera."));i={enabled:!0,camera_id:e}}const r=await(0,n.Fu)({name:s,path:a,enabled:!0,host_server_id:e,camera_controls:i??void 0,outputs:[{protocol:Ee,enabled:!0,resolution:{width:m(Fe,1280),height:m(We,720)},fps_limit:m(Oe,12)}]});V(e=>[r,...e.filter(e=>e.id!==r.id)]),Z(r.id),ne(g(r)),oe(!1),de(null),Se(!1),Ae(""),Le(""),Re("local"),qe(!1),Xe("")}catch(e){Te(e instanceof Error?e.message:String(e))}finally{ke(!1)}}()},children:Ce?t("ext.streaming.transmissions.creating",{},"Criando…"):t("ext.streaming.transmissions.create_button",{},"Criar transmissão")})})]}),(0,a.jsxs)(o.y,{open:te,title:t("ext.streaming.transmissions.discard_title",{},"Descartar alterações?"),closeAriaLabel:t("core.actions.close",{},"Close"),onClose:()=>{ae(!1),se(null)},children:[(0,a.jsx)("div",{className:"cardMeta",style:{marginBottom:10},children:t("ext.streaming.transmissions.discard_body",{},"Você tem alterações não salvas. Para trocar de transmissão, descarte ou salve primeiro.")}),(0,a.jsxs)("div",{className:"rowWrap",style:{justifyContent:"flex-end",gap:10},children:[(0,a.jsx)("button",{className:"chipButton",type:"button",onClick:()=>{ae(!1),se(null)},children:t("ext.streaming.common.cancel",{},"Cancelar")}),(0,a.jsx)("button",{className:"chipButton",type:"button",onClick:()=>{ee&&(oe(!1),de(null),ae(!1),Z(ee),se(null))},children:t("ext.streaming.transmissions.discard",{},"Descartar")}),(0,a.jsx)("button",{className:"primaryButton",type:"button",onClick:()=>{ae(!1),ws().then(()=>{ee&&(Z(ee),se(null))})},children:t("ext.streaming.transmissions.save",{},"Salvar")})]})]}),(0,a.jsxs)(o.y,{open:es,title:t("ext.streaming.transmissions.delete_title",{},"Excluir transmissão"),closeAriaLabel:t("core.actions.close",{},"Close"),onClose:()=>{ts||(ss(!1),ns(null))},children:[is?(0,a.jsx)("div",{className:"errorText",style:{marginBottom:10},children:is}):null,(0,a.jsx)("div",{className:"cardMeta",style:{marginBottom:10},children:t("ext.streaming.transmissions.delete_body",{},"Esta ação é irreversível.")}),(0,a.jsxs)("div",{className:"rowWrap",style:{justifyContent:"flex-end",gap:10},children:[(0,a.jsx)("button",{className:"chipButton",type:"button",disabled:ts,onClick:()=>ss(!1),children:t("ext.streaming.common.cancel",{},"Cancelar")}),(0,a.jsx)("button",{className:"primaryButton",type:"button",disabled:ts,onClick:()=>{!async function(){if(hs){as(!0),ns(null);try{await(0,n.yL)(hs.id),V(e=>e.filter(e=>e.id!==hs.id)),ue(e=>{const s={...e};return delete s[hs.id],s}),Z(null),ne(null),oe(!1),ss(!1)}catch(e){ns(e instanceof Error?e.message:String(e))}finally{as(!1)}}}()},children:ts?t("ext.streaming.transmissions.deleting",{},"Excluindo…"):t("ext.streaming.transmissions.delete",{},"Excluir")})]})]}),(0,a.jsx)(l.Y,{open:null!==rs,i18n:e,transmission:rs,engineRunning:Boolean(z?.running),processingServers:je,onClose:()=>os(null),onCreated:()=>{us()}})]});var Bs}},416(e,s,t){t.d(s,{J:()=>a});const a={en:{"ext.streaming.common.cancel":"Cancel","ext.streaming.settings.name":"Streams","ext.streaming.settings.desc":"Configure streams and generate playback URLs.","ext.streaming.settings.title":"Streams","ext.streaming.settings.subtitle":"Create streams, configure outputs (HLS/RTSP/WebRTC) and generate URLs via MediaMTX.","ext.streaming.settings.building":"Under construction.","ext.streaming.settings.quickstart":"Recommended flow","ext.streaming.settings.quickstart_step_1":"Create a stream with at least one output.","ext.streaming.settings.quickstart_step_2":"Adjust resolution/FPS/authentication per output.","ext.streaming.settings.quickstart_step_3":"Save, load URLs, then use the wizard to generate a pipeline.","ext.streaming.settings.health.loading":"Checking backend health…","ext.streaming.settings.health.ok":"Backend health: OK","ext.streaming.settings.health.failed":"Backend health: unavailable","ext.streaming.settings.health.refresh":"Refresh status","ext.streaming.settings.transmissions":"Configured streams","ext.streaming.engine.title":"Engine (MediaMTX)","ext.streaming.engine.loading":"Checking engine status…","ext.streaming.engine.running":"Engine status: running","ext.streaming.engine.stopped":"Engine status: stopped","ext.streaming.engine.start":"Start","ext.streaming.engine.starting":"Starting…","ext.streaming.engine.download":"Download engine","ext.streaming.engine.downloading":"Downloading…","ext.streaming.engine.stop":"Stop","ext.streaming.engine.stopping":"Stopping…","ext.streaming.engine.restart":"Restart","ext.streaming.engine.restarting":"Restarting…","ext.streaming.engine.reclaim":"Reclaim","ext.streaming.engine.reclaiming":"Reclaiming…","ext.streaming.engine.reclaim_confirm":"This will try to stop and cleanup stale MediaMTX processes for this data directory. Continue?","ext.streaming.engine.refresh":"Refresh","ext.streaming.engine.refreshing":"Refreshing…","ext.streaming.engine.test_rtsp":"RTSP (test)","ext.streaming.engine.test_hls":"HLS (test)","ext.streaming.engine.test_webrtc":"WebRTC/WHEP (test)","ext.streaming.engine.settings_title":"Engine settings","ext.streaming.engine.settings_loading":"Loading…","ext.streaming.engine.settings_discard":"Discard","ext.streaming.engine.settings_apply":"Apply","ext.streaming.engine.settings_applying":"Applying…","ext.streaming.engine.expose_to_lan":"Expose on LAN (0.0.0.0)","ext.streaming.engine.port_rtsp":"RTSP port","ext.streaming.engine.port_hls":"HLS port","ext.streaming.engine.port_webrtc":"WebRTC port","ext.streaming.engine.port_api":"API port","ext.streaming.engine.ice_servers_label":"STUN/TURN servers (optional, one per line)","ext.streaming.engine.ice_servers_hint":"Only needed to traverse NAT. On a simple LAN, leave it empty.","ext.streaming.engine.meta_version":"Version","ext.streaming.engine.meta_pid":"PID","ext.streaming.engine.meta_uptime":"Uptime","ext.streaming.engine.meta_api":"API","ext.streaming.engine.meta_restarts":"Restarts","ext.streaming.engine.meta_binary":"Binary","ext.streaming.engine.meta_config":"Config","ext.streaming.engine.meta_log":"Log","ext.streaming.engine.orphan_processes":"Found {{count}} external MediaMTX process(es) for this data directory: {{pids}}.","ext.streaming.processing_servers.loading":"Loading processing servers…","ext.streaming.processing_servers.local_label":"local (this machine)","ext.streaming.errors.invalid_host_server":"Invalid host server: {{serverId}}","ext.streaming.transmissions.search":"Search streams…","ext.streaming.transmissions.loading":"Loading…","ext.streaming.transmissions.empty":"No streams created yet.","ext.streaming.transmissions.add":"Add stream","ext.streaming.transmissions.create":"Create stream","ext.streaming.transmissions.create_button":"Create stream","ext.streaming.transmissions.creating":"Creating…","ext.streaming.transmissions.select":"Select a stream to edit.","ext.streaming.transmissions.select_hint":"Tip: create a stream, then use the wizard to generate a pipeline.","ext.streaming.transmissions.meta_line":"Host: {{host}} • Path: {{path}} • Outputs: {{outputs}}","ext.streaming.transmissions.badge_disabled":"off","ext.streaming.transmissions.badge_disabled_title":"Disabled","ext.streaming.transmissions.badge_unsaved":"pending","ext.streaming.transmissions.badge_unsaved_title":"Unsaved changes","ext.streaming.transmissions.discard":"Discard","ext.streaming.transmissions.save":"Save","ext.streaming.transmissions.saving":"Saving…","ext.streaming.transmissions.delete":"Delete","ext.streaming.transmissions.discard_title":"Discard changes?","ext.streaming.transmissions.discard_body":"You have unsaved changes. Discard or save before switching streams.","ext.streaming.transmissions.delete_title":"Delete stream","ext.streaming.transmissions.delete_body":"This action cannot be undone.","ext.streaming.transmissions.deleting":"Deleting…","ext.streaming.transmissions.basic":"Basics","ext.streaming.transmissions.name":"Name","ext.streaming.transmissions.default_name":"Stream","ext.streaming.transmissions.path":"Path/slug","ext.streaming.transmissions.path_hint":"Use only a-z, 0-9, - and _. The server normalizes automatically.","ext.streaming.transmissions.enabled":"Enabled","ext.streaming.transmissions.host_server":"Host server","ext.streaming.transmissions.host_server_hint":"This stream will be hosted on this processing server.","ext.streaming.transmissions.host_server_missing":"This host server no longer exists. Select another one before saving.","ext.streaming.transmissions.placeholder":"Placeholder","ext.streaming.transmissions.placeholder.gray":"Gray background","ext.streaming.transmissions.placeholder.black":"Black background","ext.streaming.transmissions.arbitration":"Arbitration","ext.streaming.transmissions.arbitration.priority_latest":"Priority, then latest","ext.streaming.transmissions.arbitration.latest":"Latest writer wins","ext.streaming.transmissions.outputs":"Outputs","ext.streaming.transmissions.outputs_hint":"Each output can have different resolution/FPS/bitrate.","ext.streaming.transmissions.outputs_empty":"No outputs added yet.","ext.streaming.transmissions.protocol":"Protocol","ext.streaming.transmissions.width":"Width","ext.streaming.transmissions.height":"Height","ext.streaming.transmissions.fps":"FPS","ext.streaming.transmissions.camera_controls.title":"Camera controls","ext.streaming.transmissions.camera_controls.enable":"Enable camera controls","ext.streaming.transmissions.camera_controls.hint":"When enabled, this stream can control a camera (presets/PTZ) via API.","ext.streaming.transmissions.camera_controls.loading":"Loading cameras…","ext.streaming.transmissions.camera_controls.camera":"Camera","ext.streaming.transmissions.camera_controls.empty":"No cameras found. Add a camera in Settings > Cameras.","ext.streaming.transmissions.camera_controls.select_camera_error":"Select a camera.","ext.streaming.transmissions.urls":"URLs","ext.streaming.transmissions.urls_hint":"URLs are generated by the engine (MediaMTX).","ext.streaming.transmissions.load_urls":"Load URLs","ext.streaming.transmissions.loading_urls":"Loading URLs…","ext.streaming.transmissions.urls_empty":"Load URLs to view them here.","ext.streaming.transmissions.urls_save_warning":"Save changes to ensure paths/outputs are up to date before sharing URLs.","ext.streaming.transmissions.engine_off_warning":"The engine is stopped: URLs exist, but playback will not work until you start it.","ext.streaming.transmissions.engine_path":"Engine path","ext.streaming.transmissions.auth_required":"Requires authentication.","ext.streaming.transmissions.auth_required_user":"Requires authentication (username: {{username}}).","ext.streaming.transmissions.auth_not_required":"No authentication.","ext.streaming.transmissions.copy_url":"Copy URL","ext.streaming.transmissions.copied":"Copied!","ext.streaming.outputs.add_hls":"+ HLS","ext.streaming.outputs.add_rtsp":"+ RTSP","ext.streaming.outputs.add_webrtc":"+ WebRTC","ext.streaming.outputs.remove":"Remove","ext.streaming.outputs.output_id":"Output ID","ext.streaming.outputs.enabled":"Enabled","ext.streaming.outputs.protocol":"Protocol","ext.streaming.outputs.width":"Width","ext.streaming.outputs.height":"Height","ext.streaming.outputs.fps":"FPS","ext.streaming.outputs.bitrate":"Bitrate (kbps)","ext.streaming.outputs.latency":"Latency","ext.streaming.outputs.latency_option.normal":"Normal","ext.streaming.outputs.latency_option.low":"Low","ext.streaming.outputs.latency_option.ultra_low":"Ultra low","ext.streaming.outputs.auth":"Authentication (optional)","ext.streaming.outputs.auth_enabled":"Enable username/password","ext.streaming.outputs.username":"Username","ext.streaming.outputs.password":"Password","ext.streaming.outputs.auth_note":"Credentials are applied in MediaMTX for playback of this output.","ext.streaming.wizard.open":"Create pipeline for this stream","ext.streaming.wizard.title":"Create pipeline","ext.streaming.wizard.engine_warning":"The streaming engine is stopped. You can create the pipeline now and start the engine later.","ext.streaming.wizard.loading_cameras":"Loading cameras…","ext.streaming.wizard.camera":"Camera","ext.streaming.wizard.camera_placeholder":"Select a camera","ext.streaming.wizard.camera_search":"Search by name or ID","ext.streaming.wizard.camera_no_results":"No cameras match your search.","ext.streaming.wizard.camera_empty":"No cameras found. Add a camera in Settings > Cameras.","ext.streaming.wizard.camera_unnamed":"Unnamed camera","ext.streaming.wizard.preset":"Preset","ext.streaming.wizard.presets.simple_stream.title":"Simple stream","ext.streaming.wizard.presets.simple_stream.desc":"camera.source + optional fps reducer + stream.publish_video","ext.streaming.wizard.presets.motion_gate_stream.title":"Motion gate stream","ext.streaming.wizard.presets.motion_gate_stream.desc":"camera.source + motion gate + fps reducer + stream.publish_video","ext.streaming.wizard.presets.detection_stream.title":"Detection stream","ext.streaming.wizard.presets.detection_stream.desc":"camera.source + object detection + stream.publish_video","ext.streaming.wizard.presets.tracking_stream.title":"Tracking stream","ext.streaming.wizard.presets.tracking_stream.desc":"camera.source + object tracking + stream.publish_video","ext.streaming.wizard.presets.segmentation_stream.title":"Segmentation stream","ext.streaming.wizard.presets.segmentation_stream.desc":"camera.source + object segmentation + stream.publish_video","ext.streaming.wizard.pipeline_name":"Pipeline name (optional)","ext.streaming.wizard.processing_server":"Processing server","ext.streaming.wizard.host_mismatch_inline":"Stream host: {{transmissionHost}}. Pipeline host: {{pipelineHost}}. They must match.","ext.streaming.wizard.fps":"FPS limit","ext.streaming.wizard.writer_priority":"Writer priority","ext.streaming.wizard.source_backend":"Camera backend","ext.streaming.wizard.source_backend.option.auto":"Auto","ext.streaming.wizard.source_backend.option.opencv":"OpenCV","ext.streaming.wizard.source_backend.option.ffmpeg":"FFmpeg","ext.streaming.wizard.bypass_mode":"Bypass mode","ext.streaming.wizard.bypass_mode.option.auto":"Auto","ext.streaming.wizard.bypass_mode.option.force_on":"Force on","ext.streaming.wizard.bypass_mode.option.force_off":"Force off","ext.streaming.wizard.resize_mode":"Resize mode","ext.streaming.wizard.resize_mode.option.contain":"Contain","ext.streaming.wizard.resize_mode.option.none":"No resize","ext.streaming.wizard.motion_sensitivity":"Motion sensitivity","ext.streaming.wizard.motion_hold":"Motion hold (s)","ext.streaming.wizard.yolo_conf":"Vision confidence","ext.streaming.wizard.yolo_filter_enabled":"Filter frames after vision (recommended)","ext.streaming.wizard.yolo_filter_enabled.hint":"When disabled, the pipeline still runs vision inference but keeps all frames.","ext.streaming.wizard.detection_categories":"Detection categories (csv)","ext.streaming.wizard.tracking_categories":"Tracking categories (csv)","ext.streaming.wizard.enabled":"Enable pipeline after creation","ext.streaming.wizard.use_fps_reducer":"Add core.fps_reducer step","ext.streaming.wizard.create":"Create pipeline","ext.streaming.wizard.creating":"Creating…","ext.streaming.wizard.done_title":"Pipeline created","ext.streaming.wizard.pipeline_created_name":"Pipeline","ext.streaming.wizard.open_pipelines":"Open Pipelines","ext.streaming.wizard.errors.select_camera":"Select a camera.","ext.streaming.wizard.errors.invalid_processing_server":"Invalid processing server: {{serverId}}","ext.streaming.wizard.errors.host_mismatch":"Stream host is {{transmissionHost}}. Select the same processing server for the pipeline.","ext.streaming.runtime.loading":"Refreshing demand and publisher status…","ext.streaming.runtime.demand_on":"demand:on","ext.streaming.runtime.demand_off":"demand:off","ext.streaming.runtime.publisher_running":"running","ext.streaming.runtime.publisher_stopped":"stopped","ext.streaming.runtime.output_status":"Viewers/publisher"},"pt-BR":{"ext.streaming.common.cancel":"Cancelar","ext.streaming.settings.name":"Transmissões","ext.streaming.settings.desc":"Configure transmissões e gere URLs de reprodução.","ext.streaming.settings.title":"Transmissões","ext.streaming.settings.subtitle":"Crie transmissões, configure saídas (HLS/RTSP/WebRTC) e gere URLs via MediaMTX.","ext.streaming.settings.building":"Em construção.","ext.streaming.settings.quickstart":"Fluxo recomendado","ext.streaming.settings.quickstart_step_1":"Crie uma transmissão com pelo menos uma saída.","ext.streaming.settings.quickstart_step_2":"Ajuste resolução/FPS/autenticação por saída.","ext.streaming.settings.quickstart_step_3":"Salve, carregue URLs e use o wizard para gerar um pipeline.","ext.streaming.settings.health.loading":"Verificando saúde do backend…","ext.streaming.settings.health.ok":"Saúde do backend: OK","ext.streaming.settings.health.failed":"Saúde do backend: indisponível","ext.streaming.settings.health.refresh":"Atualizar status","ext.streaming.settings.transmissions":"Transmissões configuradas","ext.streaming.engine.title":"Engine (MediaMTX)","ext.streaming.engine.loading":"Verificando status da engine…","ext.streaming.engine.running":"Status da engine: rodando","ext.streaming.engine.stopped":"Status da engine: parada","ext.streaming.engine.start":"Iniciar","ext.streaming.engine.starting":"Iniciando…","ext.streaming.engine.download":"Baixar engine","ext.streaming.engine.downloading":"Baixando…","ext.streaming.engine.stop":"Parar","ext.streaming.engine.stopping":"Parando…","ext.streaming.engine.restart":"Reiniciar","ext.streaming.engine.restarting":"Reiniciando…","ext.streaming.engine.reclaim":"Recuperar","ext.streaming.engine.reclaiming":"Recuperando…","ext.streaming.engine.reclaim_confirm":"Isso vai tentar parar e limpar processos MediaMTX antigos deste diretório de dados. Continuar?","ext.streaming.engine.refresh":"Atualizar","ext.streaming.engine.refreshing":"Atualizando…","ext.streaming.engine.test_rtsp":"RTSP (teste)","ext.streaming.engine.test_hls":"HLS (teste)","ext.streaming.engine.test_webrtc":"WebRTC/WHEP (teste)","ext.streaming.engine.settings_title":"Configuração da engine","ext.streaming.engine.settings_loading":"Carregando…","ext.streaming.engine.settings_discard":"Descartar","ext.streaming.engine.settings_apply":"Aplicar","ext.streaming.engine.settings_applying":"Aplicando…","ext.streaming.engine.expose_to_lan":"Expor na LAN (0.0.0.0)","ext.streaming.engine.port_rtsp":"Porta RTSP","ext.streaming.engine.port_hls":"Porta HLS","ext.streaming.engine.port_webrtc":"Porta WebRTC","ext.streaming.engine.port_api":"Porta API","ext.streaming.engine.ice_servers_label":"Servidores STUN/TURN (opcional, um por linha)","ext.streaming.engine.ice_servers_hint":"Use apenas se precisar atravessar NAT. Em uma LAN simples, deixe vazio.","ext.streaming.engine.meta_version":"Versão","ext.streaming.engine.meta_pid":"PID","ext.streaming.engine.meta_uptime":"Uptime","ext.streaming.engine.meta_api":"API","ext.streaming.engine.meta_restarts":"Reinícios","ext.streaming.engine.meta_binary":"Binário","ext.streaming.engine.meta_config":"Config","ext.streaming.engine.meta_log":"Log","ext.streaming.engine.orphan_processes":"Foram encontrados {{count}} processos externos do MediaMTX para este diretório de dados: {{pids}}.","ext.streaming.processing_servers.loading":"Carregando servidores de processamento…","ext.streaming.processing_servers.local_label":"local (esta máquina)","ext.streaming.errors.invalid_host_server":"Servidor host inválido: {{serverId}}","ext.streaming.transmissions.search":"Buscar transmissões…","ext.streaming.transmissions.loading":"Carregando…","ext.streaming.transmissions.empty":"Nenhuma transmissão criada ainda.","ext.streaming.transmissions.add":"Adicionar transmissão","ext.streaming.transmissions.create":"Criar transmissão","ext.streaming.transmissions.create_button":"Criar transmissão","ext.streaming.transmissions.creating":"Criando…","ext.streaming.transmissions.select":"Selecione uma transmissão para editar.","ext.streaming.transmissions.select_hint":"Dica: crie uma transmissão e depois use o wizard para gerar um pipeline.","ext.streaming.transmissions.meta_line":"Host: {{host}} • Path: {{path}} • Saídas: {{outputs}}","ext.streaming.transmissions.badge_disabled":"off","ext.streaming.transmissions.badge_disabled_title":"Desativada","ext.streaming.transmissions.badge_unsaved":"pendente","ext.streaming.transmissions.badge_unsaved_title":"Alterações não salvas","ext.streaming.transmissions.discard":"Descartar","ext.streaming.transmissions.save":"Salvar","ext.streaming.transmissions.saving":"Salvando…","ext.streaming.transmissions.delete":"Excluir","ext.streaming.transmissions.discard_title":"Descartar alterações?","ext.streaming.transmissions.discard_body":"Você tem alterações não salvas. Descarte ou salve antes de trocar de transmissão.","ext.streaming.transmissions.delete_title":"Excluir transmissão","ext.streaming.transmissions.delete_body":"Esta ação não pode ser desfeita.","ext.streaming.transmissions.deleting":"Excluindo…","ext.streaming.transmissions.basic":"Básico","ext.streaming.transmissions.name":"Nome","ext.streaming.transmissions.default_name":"Transmissão","ext.streaming.transmissions.path":"Path/slug","ext.streaming.transmissions.path_hint":"Use apenas a-z, 0-9, - e _. O servidor normaliza automaticamente.","ext.streaming.transmissions.enabled":"Ativa","ext.streaming.transmissions.host_server":"Host da transmissão","ext.streaming.transmissions.host_server_hint":"A transmissão será hospedada neste servidor de processamento.","ext.streaming.transmissions.host_server_missing":"Este host server não existe mais. Selecione outro antes de salvar.","ext.streaming.transmissions.placeholder":"Placeholder","ext.streaming.transmissions.placeholder.gray":"Fundo cinza","ext.streaming.transmissions.placeholder.black":"Fundo preto","ext.streaming.transmissions.arbitration":"Arbitragem","ext.streaming.transmissions.arbitration.priority_latest":"Prioridade, depois mais recente","ext.streaming.transmissions.arbitration.latest":"Mais recente vence","ext.streaming.transmissions.outputs":"Saídas","ext.streaming.transmissions.outputs_hint":"Cada saída pode ter resolução/FPS/bitrate diferentes.","ext.streaming.transmissions.outputs_empty":"Nenhuma saída adicionada ainda.","ext.streaming.transmissions.protocol":"Protocolo","ext.streaming.transmissions.width":"Largura","ext.streaming.transmissions.height":"Altura","ext.streaming.transmissions.fps":"FPS","ext.streaming.transmissions.camera_controls.title":"Controles de câmera","ext.streaming.transmissions.camera_controls.enable":"Habilitar controles de câmera","ext.streaming.transmissions.camera_controls.hint":"Quando habilitado, esta transmissão poderá controlar uma câmera (presets/PTZ) via API.","ext.streaming.transmissions.camera_controls.loading":"Carregando câmeras…","ext.streaming.transmissions.camera_controls.camera":"Câmera","ext.streaming.transmissions.camera_controls.empty":"Nenhuma câmera encontrada. Cadastre uma câmera em Configurações > Câmeras.","ext.streaming.transmissions.camera_controls.select_camera_error":"Selecione uma câmera.","ext.streaming.transmissions.urls":"URLs","ext.streaming.transmissions.urls_hint":"As URLs são geradas pela engine (MediaMTX).","ext.streaming.transmissions.load_urls":"Carregar URLs","ext.streaming.transmissions.loading_urls":"Carregando URLs…","ext.streaming.transmissions.urls_empty":"Carregue as URLs para visualizar aqui.","ext.streaming.transmissions.urls_save_warning":"Salve alterações para garantir que paths/saídas estejam atualizados antes de compartilhar URLs.","ext.streaming.transmissions.engine_off_warning":"A engine está parada: as URLs existem, mas o playback não funcionará até iniciar.","ext.streaming.transmissions.engine_path":"Path da engine","ext.streaming.transmissions.auth_required":"Requer autenticação.","ext.streaming.transmissions.auth_required_user":"Requer autenticação (usuário: {{username}}).","ext.streaming.transmissions.auth_not_required":"Sem autenticação.","ext.streaming.transmissions.copy_url":"Copiar URL","ext.streaming.transmissions.copied":"Copiado!","ext.streaming.outputs.add_hls":"+ HLS","ext.streaming.outputs.add_rtsp":"+ RTSP","ext.streaming.outputs.add_webrtc":"+ WebRTC","ext.streaming.outputs.remove":"Remover","ext.streaming.outputs.output_id":"ID da saída","ext.streaming.outputs.enabled":"Ativa","ext.streaming.outputs.protocol":"Protocolo","ext.streaming.outputs.width":"Largura","ext.streaming.outputs.height":"Altura","ext.streaming.outputs.fps":"FPS","ext.streaming.outputs.bitrate":"Bitrate (kbps)","ext.streaming.outputs.latency":"Latência","ext.streaming.outputs.latency_option.normal":"Normal","ext.streaming.outputs.latency_option.low":"Baixa","ext.streaming.outputs.latency_option.ultra_low":"Ultra baixa","ext.streaming.outputs.auth":"Autenticação (opcional)","ext.streaming.outputs.auth_enabled":"Habilitar usuário/senha","ext.streaming.outputs.username":"Usuário","ext.streaming.outputs.password":"Senha","ext.streaming.outputs.auth_note":"As credenciais são aplicadas no MediaMTX para leitura/playback desta saída.","ext.streaming.wizard.open":"Criar pipeline com esta transmissão","ext.streaming.wizard.title":"Criar pipeline","ext.streaming.wizard.engine_warning":"A engine de streaming está parada. Você pode criar o pipeline agora e iniciar a engine depois.","ext.streaming.wizard.loading_cameras":"Carregando câmeras…","ext.streaming.wizard.camera":"Câmera","ext.streaming.wizard.camera_placeholder":"Selecione uma câmera","ext.streaming.wizard.camera_search":"Buscar por nome ou ID","ext.streaming.wizard.camera_no_results":"Nenhuma câmera corresponde à busca.","ext.streaming.wizard.camera_empty":"Nenhuma câmera encontrada. Cadastre uma câmera em Configurações > Câmeras.","ext.streaming.wizard.camera_unnamed":"Câmera sem nome","ext.streaming.wizard.preset":"Preset","ext.streaming.wizard.presets.simple_stream.title":"Stream simples","ext.streaming.wizard.presets.simple_stream.desc":"camera.source + redutor de FPS (opcional) + stream.publish_video","ext.streaming.wizard.presets.motion_gate_stream.title":"Stream com gate de movimento","ext.streaming.wizard.presets.motion_gate_stream.desc":"camera.source + gate de movimento + redutor de FPS + stream.publish_video","ext.streaming.wizard.presets.detection_stream.title":"Stream com detecção","ext.streaming.wizard.presets.detection_stream.desc":"camera.source + detecção de objetos + stream.publish_video","ext.streaming.wizard.presets.tracking_stream.title":"Stream com tracking","ext.streaming.wizard.presets.tracking_stream.desc":"camera.source + tracking de objetos + stream.publish_video","ext.streaming.wizard.presets.segmentation_stream.title":"Stream com segmentação","ext.streaming.wizard.presets.segmentation_stream.desc":"camera.source + segmentação de objetos + stream.publish_video","ext.streaming.wizard.pipeline_name":"Nome do pipeline (opcional)","ext.streaming.wizard.processing_server":"Servidor de processamento","ext.streaming.wizard.host_mismatch_inline":"Host da transmissão: {{transmissionHost}}. Host do pipeline: {{pipelineHost}}. Eles precisam ser iguais.","ext.streaming.wizard.fps":"Limite de FPS","ext.streaming.wizard.writer_priority":"Prioridade do writer","ext.streaming.wizard.source_backend":"Backend da câmera","ext.streaming.wizard.source_backend.option.auto":"Auto","ext.streaming.wizard.source_backend.option.opencv":"OpenCV","ext.streaming.wizard.source_backend.option.ffmpeg":"FFmpeg","ext.streaming.wizard.bypass_mode":"Modo bypass","ext.streaming.wizard.bypass_mode.option.auto":"Auto","ext.streaming.wizard.bypass_mode.option.force_on":"Forçar ligado","ext.streaming.wizard.bypass_mode.option.force_off":"Forçar desligado","ext.streaming.wizard.resize_mode":"Modo de redimensionamento","ext.streaming.wizard.resize_mode.option.contain":"Contain","ext.streaming.wizard.resize_mode.option.none":"Sem resize","ext.streaming.wizard.motion_sensitivity":"Sensibilidade de movimento","ext.streaming.wizard.motion_hold":"Hold de movimento (s)","ext.streaming.wizard.yolo_conf":"Confiança da visão","ext.streaming.wizard.yolo_filter_enabled":"Filtrar frames após visão (recomendado)","ext.streaming.wizard.yolo_filter_enabled.hint":"Quando desligado, o pipeline ainda executa a inferência de visão, mas mantém todos os frames.","ext.streaming.wizard.detection_categories":"Categorias de detecção (csv)","ext.streaming.wizard.tracking_categories":"Categorias de tracking (csv)","ext.streaming.wizard.enabled":"Habilitar pipeline após criação","ext.streaming.wizard.use_fps_reducer":"Inserir step core.fps_reducer","ext.streaming.wizard.create":"Criar pipeline","ext.streaming.wizard.creating":"Criando…","ext.streaming.wizard.done_title":"Pipeline criado","ext.streaming.wizard.pipeline_created_name":"Pipeline","ext.streaming.wizard.open_pipelines":"Abrir Pipelines","ext.streaming.wizard.errors.select_camera":"Selecione uma câmera.","ext.streaming.wizard.errors.invalid_processing_server":"Servidor de processamento inválido: {{serverId}}","ext.streaming.wizard.errors.host_mismatch":"O host da transmissão é {{transmissionHost}}. Selecione o mesmo servidor de processamento para o pipeline.","ext.streaming.runtime.loading":"Atualizando demanda e status do publisher…","ext.streaming.runtime.demand_on":"demanda:on","ext.streaming.runtime.demand_off":"demanda:off","ext.streaming.runtime.publisher_running":"rodando","ext.streaming.runtime.publisher_stopped":"parado","ext.streaming.runtime.output_status":"Viewers/publisher"}}},697(e,s,t){t.d(s,{y:()=>n});var a=t(870),i=(t(496),t(428));function n({title:e,open:s,onClose:t,closeAriaLabel:n,children:r,panelStyle:o}){if(!s)return null;const l=String(n||"").trim()||"Close";return(0,i.createPortal)((0,a.jsx)("div",{className:"modalBackdrop",style:{zIndex:"calc(var(--z-modal) + 1)"},onMouseDown:e=>{e.target===e.currentTarget&&t()},role:"presentation",children:(0,a.jsxs)("div",{className:"modalPanel",style:{width:"min(920px, calc(100vw - 28px))",...o??{}},role:"dialog","aria-modal":"true","aria-label":e,children:[(0,a.jsxs)("div",{className:"modalHeader",children:[(0,a.jsx)("div",{className:"modalTitle",children:e}),(0,a.jsx)("button",{className:"iconButton",type:"button",onClick:t,"aria-label":l,children:(0,a.jsx)("i",{className:"fa-solid fa-xmark","aria-hidden":"true"})})]}),(0,a.jsx)("div",{className:"modalBody",children:r})]})}),document.body)}},703(e,s,t){t.r(s),t.d(s,{activate:()=>n});var a=t(323),i=t(416);function n(e){e.i18n.registerTranslations(i.J),e.registerSettingsPanel((0,a.w)())}},870(e,s,t){e.exports=t(94)},901(e,s,t){async function a(e){const s=`HTTP ${e.status}`;try{const a=await e.json();if(t=a,!Boolean(t)||"object"!=typeof t)return s;const i=a.detail;return"string"==typeof i&&i.trim()?i.trim():s}catch{try{return(await e.text()).trim()||s}catch{return s}}var t}async function i(e,s){const t=await fetch(e,s);if(!t.ok)throw new Error(await a(t));return await t.json()}async function n(e){return i("/api/streams/health",{signal:e})}async function r(e){return i("/api/streams/engine/status",{signal:e})}async function o(e){return i(`/api/streams/engine/${e}`,{method:"POST"})}async function l(){return i("/api/streams/engine/download",{method:"POST"})}async function m(e){return i("/api/streams/settings",{signal:e})}async function c(e){return i("/api/streams/settings",{method:"PATCH",headers:{"content-type":"application/json"},body:JSON.stringify(e??{})})}async function d(e){return i("/api/streams/transmissions",{signal:e})}async function g(e){return i("/api/streams/transmissions",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}async function u(e,s){return i(`/api/streams/transmissions/${encodeURIComponent(e)}`,{method:"PUT",headers:{"content-type":"application/json"},body:JSON.stringify(s)})}async function p(e){const s=await fetch(`/api/streams/transmissions/${encodeURIComponent(e)}`,{method:"DELETE"});if(!s.ok)throw new Error(await a(s))}async function x(e){return i(`/api/streams/transmissions/${encodeURIComponent(e)}/urls`)}async function h(e){return i("/api/cameras/index",{signal:e})}async function _(e){const s=await i("/api/processing-servers",{signal:e});return Array.isArray(s.servers)?s.servers:[]}async function v(e){return i("/api/streams/wizard/create-pipeline",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}t.d(s,{A$:()=>v,Cs:()=>u,Fu:()=>g,I$:()=>d,JB:()=>r,WO:()=>m,bO:()=>h,cr:()=>_,eR:()=>c,hF:()=>o,jP:()=>l,m9:()=>n,pU:()=>x,yL:()=>p})}}]);
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/src/toposync_ext_streaming/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/src/toposync_ext_streaming/plugin.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{toposync_ext_streaming-0.1.2 → toposync_ext_streaming-0.1.3}/src/toposync_ext_streaming/static/4.js
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|