{"context":{"domain":"cict-ds"},"layers":{"ApplicationLayer":{"reference":"ApplicationLayer","availableInstances":[{"reference":"ComponentsDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"component":"data2-core@DataSet","reference":"SystemsDataSet","params":{"filter":{"domain":"data2"},"pagination":{"size":1},"datasource":{"component":"data2-core-types@ProcessReference","params":{"reference":"SystemsDataSource"}}}},{"reference":"ExternalComponentInstancesDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"reference":"SystemsDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[{"_id":"5e3b796d6228227ca637d0f4","name":"data2","domain":"data2","organization":"62292184611f480b3191c37c","visibility":"public","updatedAt":"2022-03-09T02:01:26.213Z"}]}},{"reference":"OrganizationsDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"reference":"DataComponentInstancesDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"component":"data2-core@DataSet","reference":"OneFileComponentInstancesDataSet","params":{"pagination":{"size":1},"master":{"dataset":{"component":"data2-core-types@ProcessReference","params":{"reference":"SystemsDataSet"}},"localField":"system","masterField":"_id"},"datasource":{"component":"data2-core-types@ProcessReference","params":{"reference":"FileComponentInstancesDataSource"}}}},{"reference":"ApplicationsDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"reference":"ComponentInstancesDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"reference":"ServiceComponentInstancesDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"component":"data2-core@Data2TableDataSource","reference":"FileComponentInstancesDataSource","params":{"table":"fileComponentInstances","schema":[{"component":"data2-core-types@Field","params":{"key":"component","title":"Component","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"system","title":"System","component":"data2-core-primitives@ObjectId"}},{"component":"data2-core-types@Field","params":{"key":"displayName","title":"Display Name","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"params","title":"Params","component":"data2-core-primitives@Object"}},{"component":"data2-core-types@Field","params":{"key":"reference","title":"Reference","component":"data2-core-primitives@String"}}]}},{"component":"data2-core@MemoryDataSource","reference":"EmptyDataSource","params":{"initialData":[]}},{"reference":"ComponentsDataSet","component":"data2-core@DataSet","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"EmptyDataSource"}}}},{"reference":"UserComponentsDataSet","component":"data2-core@DataSet","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"EmptyDataSource"}}}},{"reference":"DataComponentInstancesDataSet","component":"data2-core@DataSet","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"EmptyDataSource"}}}},{"reference":"ServiceComponentInstancesDataSet","component":"data2-core@DataSet","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"EmptyDataSource"}}}},{"reference":"ComponentInstancesDataSet","component":"data2-core@DataSet","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"EmptyDataSource"}}}},{"reference":"ExternalComponentInstancesDataSet","component":"data2-core@DataSet","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"EmptyDataSource"}}}},{"reference":"ApplicationsDataSet","component":"data2-core@DataSet","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"EmptyDataSource"}}}}],"processesParams":{}},"HostApplicationLayer":{"reference":"HostApplicationLayer","availableInstances":[{"_id":"5f15ff190528b92601890f71","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"SystemsTableDataSource"}},"filter":{"domain":{"component":"data2-core-types@Reference","params":{"reference":"domain"}}},"pk":"_id","fields":[{"component":"data2-core-types@FieldReference","params":{"key":"_id"}},{"component":"data2-core-types@FieldReference","params":{"key":"name"}},{"component":"data2-core-types@FieldReference","params":{"key":"domain"}},{"component":"data2-core-types@FieldReference","params":{"key":"visibility"}},{"component":"data2-core-types@FieldReference","params":{"key":{"component":"data2-core-primitives@String","params":{"content":"customDomains"}}},"break":true},{"component":"data2-core-types@FieldReference","params":{"key":{"component":"data2-core-primitives@String","params":{"content":"organization._id"}}},"break":true},{"component":"data2-core-types@FieldReference","params":{"key":{"component":"data2-core-primitives@String","params":{"content":"organization.name"}}},"break":true},{"component":"data2-core-types@FieldReference","params":{"key":{"component":"data2-core-primitives@String","params":{"content":"organization.billingStatus"}}},"break":true},{"component":"data2-core-types@FieldReference","params":{"key":{"component":"data2-core-primitives@String","params":{"content":"organization.publicTrial.active"}}},"break":true}],"pagination":{"size":{"component":"data2-core-primitives@Number","params":{"content":1}}},"staticPagination":{"size":{"component":"data2-core-primitives@Number","params":{"content":1}}},"policies":[{"component":"data2-core-auth@Policy","params":{"allow":{"params":{"actions":[{"params":{"components":[{"params":{"query":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$params.query"}}}},"field":{"component":"data2-core-primitives@String","params":{"content":"_id"}},"fieldType":"string"},"component":"data2@7KkQq0vK4a7D2gg6IVJT7"},{"params":{"query":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$params.query"}}}},"field":{"component":"data2-core-primitives@String","params":{"content":"domain"}},"fieldType":"string"},"component":"data2@7KkQq0vK4a7D2gg6IVJT7"},{"params":{"query":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$params.query"}}}},"field":{"component":"data2-core-primitives@String","params":{"content":"customDomains"}},"fieldType":"string"},"component":"data2@7KkQq0vK4a7D2gg6IVJT7"}]},"component":"data2-core-logical-operators@Or"}]},"component":"data2-core-flow@Series"}}}]},"reference":"SystemsDataSet","updatedAt":"2025-11-05T19:23:47.135Z","createdAt":"2020-07-20T20:31:21.838Z"},{"_id":"5f1601ce0528b92601890f7c","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"pagination":{"size":1000},"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"ComponentsTableDataSource"}},"sort":{"params.package":1,"params.component":1},"pk":"_id","autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}},"staticFilter":{"system":{"exists":{"params":{"content":false},"component":"data2-core-primitives@Boolean"}}},"filter":{"system":{"exists":{"params":{"content":false},"component":"data2-core-primitives@Boolean"}}}},"reference":"ComponentsDataSet","updatedAt":"2025-11-05T19:37:01.935Z","createdAt":"2020-07-20T20:42:54.898Z"},{"_id":"5f9041dbc8da12be8b94aea4","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"pagination":{"size":2000},"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"ComponentsTableDataSource"}},"pk":"_id","autoEdit":true,"master":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"_id"}}},"autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}},"policies":{"params":{"allowGet":{"component":"data2-core-primitives@Boolean","params":{"content":true}}},"component":"data2@hkXy-UhMjhyfptdE6_fpW"}},"reference":"UserComponentsDataSet","updatedAt":"2025-11-06T21:06:58.095Z","createdAt":"2020-07-20T20:44:09.350Z"},{"_id":"65d8c4fabc9dbb8f94de8d53","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"ExternalComponentInstancesTableDataSource"}},"pk":"_id","autoEdit":true,"master":{"params":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"_id"}}},"component":"data2-core-types@DataSetMaster"},"autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}},"policies":{"params":{"allowGet":{"component":"data2-core-primitives@Boolean","params":{"content":true}}},"component":"data2@hkXy-UhMjhyfptdE6_fpW"}},"reference":"ExternalComponentInstancesDataSet","updatedAt":"2025-11-06T21:07:23.742Z","createdAt":"2024-02-23T16:17:01.816Z"},{"reference":"SystemsTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[{"_id":"6a601c3c3a42b34509a601cf","name":"app","domain":"cict-ds","visibility":"private","updatedAt":"2026-07-22T01:26:25.160Z","createdAt":"2026-07-22T01:26:20.475Z"}]}},{"reference":"ComponentsTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[{"_id":"5f52a278a575399a45d239b4","component":"data2-core-types@Component","params":{"package":"data2-core-primitives","component":"Router","interactions":{"component":"data2-core-types@FieldSet","params":{"fields":{"goBack":{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-types@Function"}},"definition":{"component":"data2-core-functions@Function","params":{"body":{"preventEvaluation":true,"component":"data2-core-types@Getter","params":{"module":{"component":"data2-core-types@This","params":{}},"prop":"history.goBack","args":[]}}}},"icon":{"component":"data2-core-primitives@String","params":{"content":"arrow-left"}},"visibility":"public"}},"goTo":{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Function"}},"definition":{"component":"data2-core-functions@Function","params":{"body":{"preventEvaluation":true,"component":"data2-core-types@Getter","params":{"module":{"component":"data2-core-types@This","params":{}},"prop":"history.push","args":[{"component":"data2-core-types@Reference","params":{"reference":"url"}},{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"preserveQuery"}}}}]}},"parameters":[{"component":"data2-core-primitives@String","params":{"content":"url"}},{"component":"data2-core-primitives@String","params":{"content":"preserveQuery"}}]},"break":true},"icon":{"component":"data2-core-primitives@String","params":{"content":"share"}},"visibility":"public","arguments":[{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Path to route"}},"description":{"component":"data2-core-primitives@String","params":{"content":"Path to redirect user"}},"visibility":"public","required":{"component":"data2-core-primitives@Boolean","params":{"content":true}}},"component":"data2-core-types@ComponentParameter"},{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Boolean"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Preserve Query"}},"description":{"component":"data2-core-primitives@String","params":{"content":"Preserve query string parameters  preserve query parameters on navigating."}},"visibility":"public","required":{"component":"data2-core-primitives@Boolean","params":{"content":true}}},"component":"data2-core-types@ComponentParameter"}]}},"open":{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-types@Function"}},"definition":{"component":"data2-core-functions@Function","params":{"body":{"preventEvaluation":true,"component":"data2-core-types@Getter","params":{"module":{"component":"data2-core-types@This","params":{}},"prop":"history.push","args":[{"pathname":{"component":"data2-core-types@Reference","params":{"reference":"value"}}}]}},"parameters":["value"]}},"icon":{"component":"data2-core-primitives@String","params":{"content":"share"}},"visibility":"public","arguments":[{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Link to open"}},"description":{"component":"data2-core-primitives@String","params":{"content":""}},"visibility":"public","required":{"component":"data2-core-primitives@Boolean","params":{"content":true}}},"component":"data2-core-types@ComponentParameter"},{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Target"}},"description":{"component":"data2-core-primitives@String","params":{"content":"Where to open the link"}},"visibility":"public","required":{"component":"data2-core-primitives@Boolean","params":{"content":false}},"oneOf":[{"params":{"content":"_blank"},"component":"data2-core-primitives@String"},{"params":{"content":"_self"},"component":"data2-core-primitives@String"},{"params":{"content":"_parent"},"component":"data2-core-primitives@String"},{"params":{"content":"_top"},"component":"data2-core-primitives@String"}]},"component":"data2-core-types@ComponentParameter"}]}},"close":{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-types@Function"}},"definition":{"component":"data2-core-functions@Function","params":{"body":{"preventEvaluation":true,"component":"data2-core-types@Getter","params":{"module":{"params":{},"component":"data2-core-web@Window"},"prop":"close"}},"parameters":["value"]}},"icon":{"component":"data2-core-primitives@String","params":{"content":"times"}},"visibility":"public","arguments":[{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Link to open"}},"description":{"component":"data2-core-primitives@String","params":{"content":""}},"visibility":"public","required":{"component":"data2-core-primitives@Boolean","params":{"content":true}}},"component":"data2-core-types@ComponentParameter"},{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Target"}},"description":{"component":"data2-core-primitives@String","params":{"content":"Where to open the link"}},"visibility":"public","required":{"component":"data2-core-primitives@Boolean","params":{"content":false}},"oneOf":[{"params":{"content":"_blank"},"component":"data2-core-primitives@String"},{"params":{"content":"_self"},"component":"data2-core-primitives@String"},{"params":{"content":"_parent"},"component":"data2-core-primitives@String"},{"params":{"content":"_top"},"component":"data2-core-primitives@String"}]},"component":"data2-core-types@ComponentParameter"}],"description":{"component":"data2-core-primitives@String","params":{"content":"Closes a window that was opened via router.open."}}}}}}}}},{"_id":"620d28658271aa4129919d89","component":"data2-core-types@Component","params":{"package":"data2-interface-services","component":"DeviceController","interactions":{"params":{"fields":{"postMessage":{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Function"}},"arguments":[{"component":"data2-core-types@ComponentParameter","params":{"component":"data2-core-primitives@String","title":{"component":"data2-core-primitives@String","params":{"content":"data"}}}}]},"component":"data2-core-types@ComponentParameter"},"print":{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Function"}},"arguments":[{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Object"}},"flat":{"component":"data2-core-primitives@Boolean","params":{"content":true}},"parameters":{"zoom":{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Number"}},"title":{"component":"data2-core-primitives@String","params":{"content":"zoom"}},"visibility":"public"}}},"visibility":"public"},"component":"data2-core-types@ComponentParameter"}],"visibility":"public"},"component":"data2-core-types@ComponentParameter"},"share":{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Function"}}},"component":"data2-core-types@ComponentParameter"},"clipboard.copy":{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Function"}},"arguments":[{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}}}}]},"component":"data2-core-types@ComponentParameter"},"clipboard.paste":{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Function"}},"arguments":[{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}}}}]},"component":"data2-core-types@ComponentParameter"},"download":{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Function"}},"visibility":"public","arguments":[{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Filename"}}}},{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Content"}}}},{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Object"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Options"}},"parameters":{"params":{"fields":{"type":{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Mimetype"}}}}}},"component":"data2-core-types@FieldSet"}}}]},"component":"data2-core-types@ComponentParameter"},"downloadUrl":{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Function"}},"visibility":"public","arguments":[{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Filename"}}}},{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Url"}}}}]},"component":"data2-core-types@ComponentParameter"},"promptFiles":{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Function"}},"arguments":[{"component":"data2-core-types@ComponentParameter","params":{"component":"data2-core-primitives@Object","flat":{"component":"data2-core-primitives@Boolean","params":{"content":true}},"parameters":{"params":{"fields":{"multiple":{"component":"data2-core-types@ComponentParameter","params":{"title":{"component":"data2-core-primitives@String","params":{"content":"Multiple"}},"description":{"component":"data2-core-primitives@String","params":{"content":"Whether or not to allow selecting multiple files"}},"component":"data2-core-primitives@Boolean"}},"acceptedFormats":{"component":"data2-core-types@ComponentParameter","params":{"title":{"component":"data2-core-primitives@String","params":{"content":"Accepted Formats"}},"description":{"component":"data2-core-primitives@String","params":{"content":"Accepted file formats"}},"component":"data2-core-primitives@String","list":{"component":"data2-core-primitives@Boolean","params":{"content":true}}}},"timeout":{"component":"data2-core-types@ComponentParameter","params":{"title":{"component":"data2-core-primitives@String","params":{"content":"Timeout"}},"description":{"component":"data2-core-primitives@String","params":{"content":"Max milliseconds to wait for file upload"}},"component":"data2-core-primitives@Number"}}}},"component":"data2-core-types@FieldSet"}}}],"visibility":"public"},"component":"data2-core-types@ComponentParameter"},"meetingRecord":{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Function"}},"visibility":"public","definition":{"params":{"actions":[{"params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"meeting"}},"script":{"component":"data2-core-primitives@String","params":{"content":"(function() {\n  let mediaRecorder;\n  let audioChunks = [];\n  let combinedStream;\n  let audioContext;\n  \n  window.meetingCapture = async function() {\n    try {\n      // Solicitar acesso ao áudio da guia (e vídeo, que será ignorado depois)\n      const tabStream = await navigator.mediaDevices.getDisplayMedia({ \n        video: true, // Necessário para alguns navegadores\n        audio: true\n      });\n      \n      // Remover a trilha de vídeo\n      const tabAudioTrack = tabStream.getAudioTracks()[0];\n      \n      // Solicitar acesso ao microfone\n      const micStream = await navigator.mediaDevices.getUserMedia({ audio: true });\n      const micAudioTrack = micStream.getAudioTracks()[0];\n      \n      // Criar um novo MediaStream com ambas as trilhas de áudio\n      combinedStream = new MediaStream([tabAudioTrack, micAudioTrack]);\n      \n      // Criar um contexto de áudio para misturar os streams\n      audioContext = new AudioContext();\n      const destination = audioContext.createMediaStreamDestination();\n      \n      // Conectar a trilha de áudio da guia\n      const tabSource = audioContext.createMediaStreamSource(new MediaStream([tabAudioTrack]));\n      tabSource.connect(destination);\n      \n      // Conectar a trilha de áudio do microfone\n      const micSource = audioContext.createMediaStreamSource(new MediaStream([micAudioTrack]));\n      micSource.connect(destination);\n      \n      // Iniciar gravação com o stream misturado\n      mediaRecorder = new MediaRecorder(destination.stream);\n      audioChunks = [];\n      mediaRecorder.ondataavailable = (e) => audioChunks.push(e.data);\n      mediaRecorder.start();\n      \n      console.log('Gravação iniciada. Chame meetingCaptureStop() para finalizar.');\n    } catch (error) {\n      console.error('Erro ao iniciar a captura:', error);\n    }\n  };\n  \n  window.meetingCaptureStop = function() {\n    return new Promise((resolve, reject) => {\n      if (!mediaRecorder) {\n        reject('Nenhuma gravação em andamento.');\n        return;\n      }\n      \n      mediaRecorder.onstop = () => {\n        const audioBlob = new Blob(audioChunks, { type: 'audio/webm' });\n        combinedStream.getTracks().forEach(track => track.stop());\n        audioContext.close();\n        \n        resolve(audioBlob);\n        console.log('Gravação finalizada. O arquivo de áudio está pronto para upload.');\n      };\n      \n      mediaRecorder.stop();\n    });\n  };\n})();"}}},"component":"data2-core-web@Script"},{"component":"data2-core-types@Getter","params":{"module":{"params":{},"component":"data2-core-web@Window"},"prop":{"component":"data2-core-primitives@String","params":{"content":"meetingCapture"}}}}]},"component":"data2-core-flow@Series"}},"component":"data2-core-types@ComponentParameter"},"meetingRecordStop":{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Function"}},"visibility":"public","arguments":[{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Filename"}}}},{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Content"}}}},{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Object"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Options"}},"parameters":{"params":{"fields":{"type":{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Mimetype"}}}}}},"component":"data2-core-types@FieldSet"}}}],"definition":{"params":{"actions":[{"component":"data2-core-types@Getter","params":{"module":{"params":{},"component":"data2-core-web@Window"},"prop":{"component":"data2-core-primitives@String","params":{"content":"meetingCaptureStop"}}}}]},"component":"data2-core-flow@Series"}},"component":"data2-core-types@ComponentParameter"},"notify":{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Function"}},"visibility":"private","arguments":[{"component":"data2-core-types@ComponentParameter","params":{"component":"data2-core-primitives@Object","parameters":{"title":{"params":{"component":"data2-core-primitives@String","index":{"component":"data2-core-primitives@Number","params":{"content":0}},"title":{"component":"data2-core-primitives@String","params":{"content":"title"}}},"component":"data2-core-types@ComponentParameter"},"sound":{"params":{"component":"data2-core-types@FileComponentUrlReference","index":{"component":"data2-core-primitives@Number","params":{"content":1}},"title":{"component":"data2-core-primitives@String","params":{"content":"sound"}}},"component":"data2-core-types@ComponentParameter"}},"flat":{"component":"data2-core-primitives@Boolean","params":{"content":true}}}}]},"component":"data2-core-types@ComponentParameter"}}},"component":"data2-core-types@FieldSet"}}},{"_id":"6a60439fb541fb9bbddd41a7","component":"data2-core-types@Component","system":"6a601c3c3a42b34509a601cf","params":{"extends":"data2-core-primitives@Block","component":"CitizenChat","package":"cict-ds","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"const EC={panic:\"#ff3b30\",fear:\"#ff9500\",distress:\"#5e5ce6\",anger:\"#c9302c\",confusion:\"#ffcc00\",calm:\"#34c759\"};\nconst SC={Intake:\"#30b0c7\",Reported:\"#ff3b30\",Dispatched:\"#ff9500\",EnRoute:\"#0a84ff\",OnScene:\"#5e5ce6\",Resolved:\"#34c759\"};\nconst SL={Intake:[\"Intake\",\"接线中\"],Reported:[\"Reported\",\"已报告\"],Dispatched:[\"Dispatched\",\"已派遣\"],EnRoute:[\"En route\",\"前往中\"],OnScene:[\"On scene\",\"已到场\"],Resolved:[\"Resolved\",\"已解决\"]};\nconst T_DISP=4000,T_ENROUTE=49000,T_SCENE=89000;\nfunction phaseOf(el){if(el<T_DISP)return \"Dispatched\";if(el<T_ENROUTE)return \"EnRoute\";if(el<T_SCENE)return \"OnScene\";return \"Resolved\";}\nfunction unitP(el){if(el<=T_DISP)return 0;if(el>=T_ENROUTE)return 1;return (el-T_DISP)/(T_ENROUTE-T_DISP);}\nfunction mdist(a,b){const dy=a[0]-b[0],dx=a[1]-b[1];return Math.sqrt(dy*dy+dx*dx);}\nfunction pointAlong(pts,p){if(!pts||pts.length===0)return null;if(pts.length===1)return pts[0];let total=0;const segs=[];for(let i=1;i<pts.length;i++){const d=mdist(pts[i-1],pts[i]);segs.push(d);total+=d;}if(total<=0)return pts[0];const target=Math.max(0,Math.min(1,p))*total;let acc=0;for(let i=1;i<pts.length;i++){const d=segs[i-1];if(acc+d>=target){const f=d>0?(target-acc)/d:0;return [pts[i-1][0]+(pts[i][0]-pts[i-1][0])*f,pts[i-1][1]+(pts[i][1]-pts[i-1][1])*f];}acc+=d;}return pts[pts.length-1];}\nfunction cmReadout(c){if(!c)return {cls:\"\",txt:\"\"};if(!c.dispatchedAt)return {cls:\"\",txt:(c.status===\"Reported\")?\"Report received · 已收到报告\":\"Awaiting dispatch · 等待派遣\"};const units=c.units||[];const n=units.length||1;const el=Date.now()-c.dispatchedAt;const ph=phaseOf(el);if(ph===\"Resolved\"||c.status===\"Resolved\")return {cls:\"ok\",txt:\"✓ Resolved · 已解决\"};if(ph===\"OnScene\")return {cls:\"\",txt:\"🚒 On scene · 已到场 · \"+n+\" unit\"+(n>1?\"s\":\"\")};if(ph===\"EnRoute\")return {cls:\"\",txt:\"🚒 En route · 前往中 · ETA \"+Math.max(0,Math.ceil((T_ENROUTE-el)/1000))+\"s · \"+n+\" unit\"+(n>1?\"s\":\"\")};return {cls:\"\",txt:\"🚒 Unit dispatched · 消防队已出动 · \"+n+\" unit\"+(n>1?\"s\":\"\")};}\nfunction dstat(inc){if(inc&&inc.dispatchedAt&&inc.status!==\"Resolved\"){return phaseOf(Date.now()-inc.dispatchedAt);}return inc?inc.status:\"Reported\";}\nfunction ease(p){return p*p*(3-2*p);}\nconst LEAF={name:\"leaflet@1.9.4\",css:\"https://cdn.jsdelivr.net/npm/leaflet@1.9.4/dist/leaflet.css\"};\nconst ICE=[{urls:[\"stun:stun.l.google.com:19302\",\"stun:stun1.l.google.com:19302\"]},{urls:[\"turn:openrelay.metered.ca:80\",\"turn:openrelay.metered.ca:443\",\"turn:openrelay.metered.ca:443?transport=tcp\"],username:\"openrelayproject\",credential:\"openrelayproject\"},{urls:[\"turn:openrelay.metered.ca:80?transport=tcp\"],username:\"openrelayproject\",credential:\"openrelayproject\"}];\nfunction un(r){return (r&&typeof r===\"object\"&&r.data!==undefined&&r.reply_en===undefined&&r.items===undefined&&r.ok===undefined)?r.data:r;}\nfunction esc(s){return String(s==null?\"\":s).replace(/&/g,\"&amp;\").replace(/</g,\"&lt;\").replace(/>/g,\"&gt;\");}\nexport default {\n  css:`\n  .page{height:100%;display:flex;align-items:stretch;justify-content:center;background:radial-gradient(1200px 600px at 50% -10%, rgba(255,59,48,.10), transparent 60%), linear-gradient(180deg,#f5f5f7 0%, #ececf0 100%);font-family:-apple-system,\"SF Pro Display\",\"SF Pro Text\",\"PingFang SC\",\"Helvetica Neue\",system-ui,sans-serif;color:#1d1d1f;-webkit-font-smoothing:antialiased;position:relative;overflow:hidden;}\n  .app{width:100%;max-width:480px;height:100%;display:flex;flex-direction:column;background:rgba(255,255,255,.72);backdrop-filter:saturate(180%) blur(30px);-webkit-backdrop-filter:saturate(180%) blur(30px);border-left:1px solid rgba(0,0,0,.06);border-right:1px solid rgba(0,0,0,.06);box-shadow:0 30px 80px rgba(0,0,0,.12);}\n  .splash{position:absolute;inset:0;z-index:50;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:16px;background:linear-gradient(180deg,#ff5a4d,#ff3b30);color:#fff;animation:splashout .7s ease 1.5s forwards;}\n  .splash .sb{width:88px;height:88px;border-radius:26px;display:flex;align-items:center;justify-content:center;font-size:46px;background:rgba(255,255,255,.16);backdrop-filter:blur(10px);box-shadow:0 20px 50px rgba(0,0,0,.25);animation:sbin .7s cubic-bezier(.2,.9,.3,1.3);}\n  .splash h1{font-size:23px;font-weight:750;letter-spacing:-.02em;margin:0;}\n  .splash p{font-size:13px;opacity:.9;margin:0;letter-spacing:.02em;}\n  .splash .ring{width:22px;height:22px;border:2.5px solid rgba(255,255,255,.35);border-top-color:#fff;border-radius:50%;animation:spin .8s linear infinite;margin-top:6px;}\n  .hdr{padding:20px 20px 14px;border-bottom:1px solid rgba(0,0,0,.06);background:rgba(255,255,255,.55);backdrop-filter:blur(20px);}\n  .brandrow{display:flex;align-items:center;gap:10px;}\n  .badge{width:34px;height:34px;border-radius:10px;display:flex;align-items:center;justify-content:center;background:linear-gradient(180deg,#ff5a4d,#ff3b30);box-shadow:0 4px 12px rgba(255,59,48,.35);font-size:18px;}\n  .ttl{font-size:19px;font-weight:700;letter-spacing:-.02em;}\n  .sub{font-size:12px;color:#6e6e73;margin-top:1px;}\n  .toolbar{display:flex;gap:6px;margin-top:12px;align-items:center;}\n  .seg{display:flex;background:rgba(120,120,128,.12);border-radius:9px;padding:2px;}\n  .seg button{border:0;background:transparent;font:inherit;font-size:12px;font-weight:600;color:#3c3c43;padding:5px 12px;border-radius:7px;cursor:pointer;transition:all .2s;}\n  .seg button[data-on]{background:#fff;box-shadow:0 1px 3px rgba(0,0,0,.12);color:#1d1d1f;}\n  .spk{margin-left:auto;border:0;background:rgba(120,120,128,.12);border-radius:9px;padding:6px 10px;font:inherit;font-size:12px;font-weight:600;color:#3c3c43;cursor:pointer;transition:all .2s;}\n  .spk[data-on]{background:rgba(10,132,255,.14);color:#0071e3;}\n  .log{flex:1;overflow:auto;padding:18px 16px;display:flex;flex-direction:column;gap:12px;}\n  .row{display:flex;}.row.me{justify-content:flex-end;}.row.ai{justify-content:flex-start;}\n  .wrap{max-width:82%;display:flex;flex-direction:column;}\n  .me .wrap{align-items:flex-end;}\n  .bub{padding:11px 14px;border-radius:20px;font-size:14.5px;line-height:1.42;animation:pop .28s cubic-bezier(.2,.9,.3,1.2);}\n  .me .bub{background:linear-gradient(180deg,#0a84ff,#0071e3);color:#fff;border-bottom-right-radius:6px;box-shadow:0 4px 14px rgba(10,132,255,.28);}\n  .ai .bub{background:#fff;color:#1d1d1f;border-bottom-left-radius:6px;border:1px solid rgba(0,0,0,.05);box-shadow:0 2px 10px rgba(0,0,0,.05);}\n  .en{font-weight:500;}.zh{margin-top:4px;color:#6e6e73;font-size:13px;}.me .zh{color:rgba(255,255,255,.85);}\n  .emochip{margin-top:5px;font-size:10px;font-weight:700;padding:2px 8px;border-radius:7px;color:#fff;display:inline-flex;align-items:center;gap:4px;align-self:flex-end;}\n  .src{margin-top:7px;display:flex;flex-wrap:wrap;gap:4px;}\n  .chip{font-size:10px;color:#8a8a8e;background:rgba(120,120,128,.10);border-radius:6px;padding:2px 6px;}\n  .thumb{margin-top:6px;border-radius:16px;overflow:hidden;max-width:220px;box-shadow:0 6px 18px rgba(0,0,0,.15);}.thumb img{display:block;width:100%;height:auto;}\n  .vis{margin-top:6px;font-size:11.5px;color:#1d1d1f;background:rgba(52,199,89,.12);border:1px solid rgba(52,199,89,.25);border-radius:10px;padding:8px 10px;}.vis b{color:#248a3d;}\n  .visload{margin-top:6px;font-size:11.5px;color:#6e6e73;background:rgba(120,120,128,.1);border-radius:10px;padding:8px 10px;display:flex;align-items:center;gap:8px;}\n  .shimmer{height:8px;border-radius:4px;flex:1;background:linear-gradient(90deg,#e6e6ea 25%,#f2f2f5 37%,#e6e6ea 63%);background-size:400% 100%;animation:sh 1.4s ease infinite;}\n  .typing{display:inline-flex;gap:4px;align-items:center;padding:4px 2px;}\n  .typing i{width:7px;height:7px;border-radius:50%;background:#c7c7cc;animation:bnc 1.2s infinite;}\n  .typing i:nth-child(2){animation-delay:.15s;}.typing i:nth-child(3){animation-delay:.3s;}\n  .done{margin:4px 0;padding:16px;border-radius:18px;background:#fff;border:1px solid rgba(52,199,89,.3);box-shadow:0 8px 26px rgba(0,0,0,.08);animation:pop .3s ease;}\n  .done h4{font-size:15px;display:flex;align-items:center;gap:8px;color:#248a3d;margin:0;}\n  .kv{display:grid;grid-template-columns:auto 1fr;gap:6px 12px;margin-top:10px;font-size:13px;}\n  .kv .k{color:#8a8a8e;}.kv .v{font-weight:600;text-align:right;}\n  .bar{padding:12px 12px calc(12px + env(safe-area-inset-bottom));border-top:1px solid rgba(0,0,0,.06);display:flex;gap:8px;align-items:flex-end;background:rgba(255,255,255,.7);backdrop-filter:blur(20px);}\n  .icon{width:40px;height:40px;flex:0 0 40px;border-radius:50%;border:0;cursor:pointer;font-size:17px;background:rgba(120,120,128,.14);transition:transform .15s,background .2s;}\n  .icon:active{transform:scale(.9);}\n  .icon.live{background:#ff3b30;color:#fff;animation:micp 1.1s infinite;}\n  .txt{flex:1;min-height:40px;max-height:120px;resize:none;border:1px solid rgba(0,0,0,.1);border-radius:20px;padding:10px 14px;font:inherit;font-size:16px;outline:none;background:#fff;transition:border .2s,box-shadow .2s;}\n  .txt:focus{border-color:#0a84ff;box-shadow:0 0 0 4px rgba(10,132,255,.12);}\n  .send{width:40px;height:40px;flex:0 0 40px;border-radius:50%;border:0;cursor:pointer;font-size:19px;font-weight:700;color:#fff;background:linear-gradient(180deg,#ff5a4d,#ff3b30);box-shadow:0 4px 12px rgba(255,59,48,.35);transition:transform .15s,opacity .2s;}\n  .send:active{transform:scale(.9);}.send[disabled],.icon[disabled]{opacity:.4;cursor:default;}\n  .file{display:none;}\n  .ai.dispatcher .bub{background:linear-gradient(180deg,#ffab2e,#ff9500);color:#fff;border:0;}\n  .rolelbl{font-size:9px;font-weight:700;opacity:.8;text-transform:uppercase;letter-spacing:.04em;display:block;margin-bottom:2px;}\n  .humanbanner{margin:8px 16px 0;padding:8px 12px;border-radius:12px;background:rgba(255,149,0,.14);color:#b35a00;font-size:12px;font-weight:650;text-align:center;}\n  .vidwrap{padding:10px 16px 0;}\n  .vidbtn{width:100%;border:0;border-radius:14px;padding:12px;font:inherit;font-size:14px;font-weight:700;color:#fff;background:linear-gradient(180deg,#ff5a4d,#ff3b30);box-shadow:0 6px 16px rgba(255,59,48,.35);cursor:pointer;display:flex;align-items:center;justify-content:center;gap:8px;transition:transform .15s;}\n  .vidbtn:active{transform:scale(.98);}\n  .selfvid{width:100%;border-radius:14px;background:#000;aspect-ratio:16/9;object-fit:cover;transform:scaleX(-1);box-shadow:0 6px 18px rgba(0,0,0,.25);}\n  .vidrow{display:flex;align-items:center;gap:8px;margin-top:6px;}\n  .livepill{flex:1;font-size:12px;color:#ff3b30;font-weight:700;}\n  .vidbtn.stop{width:auto;padding:8px 14px;font-size:13px;background:rgba(120,120,128,.16);color:#1d1d1f;box-shadow:none;}\n  .vdbgbtn{margin-top:6px;font-size:10px;border:0;background:rgba(120,120,128,.14);border-radius:8px;padding:4px 8px;cursor:pointer;color:#3c3c43;}\n  .vdbg{margin-top:6px;font-size:9.5px;font-family:ui-monospace,monospace;background:#0b0b0f;color:#8fef8f;padding:8px;border-radius:8px;white-space:pre-wrap;max-height:150px;overflow:auto;line-height:1.4;}\n  .cminimap{margin-top:12px;height:180px;border-radius:16px;overflow:hidden;box-shadow:0 6px 18px rgba(0,0,0,.12);background:#eef0f4;position:relative;}\n  .cmstatus{margin-top:8px;display:flex;align-items:center;gap:8px;font-size:12px;font-weight:650;color:#0a3d62;background:rgba(10,132,255,.1);border:1px solid rgba(10,132,255,.22);border-radius:12px;padding:8px 11px;}\n  .cmstatus .dotp{width:8px;height:8px;border-radius:50%;background:#0a84ff;flex:0 0 8px;animation:livep 1.6s infinite;}\n  @keyframes livep{0%,100%{opacity:1;}50%{opacity:.3;}}\n  .leaflet-div-icon{background:transparent!important;border:none!important;}\n  .leaflet-container{font-family:inherit;background:#eef0f4;}\n  .lpin{position:relative;width:26px;height:26px;}\n  .lpin .ring{position:absolute;inset:2px;border-radius:50%;background:var(--c);opacity:.28;animation:cpulse 1.8s infinite;}\n  .lpin .core{position:absolute;inset:6px;border-radius:50%;background:var(--c);border:2px solid #fff;display:flex;align-items:center;justify-content:center;font-size:8px;box-shadow:0 2px 6px rgba(0,0,0,.3);}\n  .lsquad .veh{width:22px;height:22px;border-radius:50%;background:#0a84ff;border:2.5px solid #fff;display:flex;align-items:center;justify-content:center;font-size:11px;box-shadow:0 3px 8px rgba(10,132,255,.5);}\n  @keyframes cpulse{0%{transform:scale(1);opacity:.3;}70%{transform:scale(2);opacity:0;}100%{opacity:0;}}\n  @keyframes pop{from{opacity:0;transform:translateY(6px) scale(.98);}to{opacity:1;transform:none;}}\n  @keyframes bnc{0%,60%,100%{transform:translateY(0);opacity:.5;}30%{transform:translateY(-5px);opacity:1;}}\n  @keyframes sh{0%{background-position:100% 0;}100%{background-position:0 0;}}\n  @keyframes spin{to{transform:rotate(360deg);}}\n  @keyframes micp{0%{box-shadow:0 0 0 0 rgba(255,59,48,.5);}70%{box-shadow:0 0 0 10px rgba(255,59,48,0);}100%{box-shadow:0 0 0 0 rgba(255,59,48,0);}}\n  @keyframes splashout{to{opacity:0;visibility:hidden;}}\n  @keyframes sbin{from{opacity:0;transform:scale(.7);}to{opacity:1;transform:none;}}\n  `,\n  render(d2){\n    const st=d2.state;const turns=st.turns||[];const lang=st.lang||\"en\";if(st.done){try{d2.lib(LEAF);}catch(e){}}\n    const splash=st.splash===false?\"\":`<div class=\"splash\"><div class=\"sb\">🚒</div><h1>Wuhan Fire Brigade</h1><p>武汉消防 · Emergency Report · 火警报告</p><div class=\"ring\"></div></div>`;\n    const bubbles=turns.map((t,i)=>{\n      if(t.role===\"reporter\"){\n        let inner=`<div class=\"bub\"><div class=\"en\">${esc(t.en)}</div>${t.photo?`<div class=\"thumb\"><img src=\"${esc(t.photo)}\"/></div>`:\"\"}${t.visionLoading?`<div class=\"visload\"><div class=\"shimmer\"></div>📸 analyzing…</div>`:\"\"}${t.vision?`<div class=\"vis\"><b>📸 AI vision · 影像分析</b><br>${esc(t.vision.summary_en||\"\")} · ${esc(t.vision.summary_zh||\"\")}</div>`:\"\"}</div>`;\n        let em=\"\";\n        if(t.emotion){const c=EC[t.emotion.emotion]||\"#8a8a8e\";em=`<span class=\"emochip\" style=\"background:${c}\">${esc(t.emotion.label_en)} ${esc(t.emotion.label_zh)} · ${Math.round((Number(t.emotion.intensity)||0)*100)}%</span>`;}\n        return `<div class=\"row me\" data-key=\"t${i}\"><div class=\"wrap\">${inner}${em}</div></div>`;\n      }\n      let src=t.sources&&t.sources.length?`<div class=\"src\">${t.sources.slice(0,4).map(s=>`<span class=\"chip\">${esc(s)}</span>`).join(\"\")}</div>`:\"\";\n      const isD=t.role===\"dispatcher\";const rl=isD?'<span class=\"rolelbl\">Dispatcher 调度员</span>':\"\";\n      return `<div class=\"row ai ${isD?\"dispatcher\":\"\"}\" data-key=\"t${i}\"><div class=\"wrap\"><div class=\"bub\">${rl}<div class=\"en\">${esc(t.en)}</div>${t.zh?`<div class=\"zh\">${esc(t.zh)}</div>`:\"\"}${src}</div></div></div>`;\n    }).join(\"\");\n    const typing=st.busy?`<div class=\"row ai\" data-key=\"typing\"><div class=\"wrap\"><div class=\"bub\"><span class=\"typing\"><i></i><i></i><i></i></span></div></div></div>`:\"\";\n    let done=\"\";\n    if(st.done&&st.incident){const c=st.incident;const cs=dstat(c);const csl=SL[cs]||[\"\",\"\"];const cc=SC[cs]||\"#34c759\";\n      done=`<div class=\"done\" data-key=\"done\"><h4>✓ Incident filed · 已建立警情 #${String(c._id||\"\").slice(-5)}</h4><div style=\"margin:8px 0 4px\"><span style=\"background:${cc}22;color:${cc};font-size:11px;font-weight:700;padding:3px 9px;border-radius:8px\">${csl[0]} · ${csl[1]}</span> <span style=\"font-size:11px;color:#8a8a8e\">live status · 实时状态</span></div><div class=\"kv\"><span class=\"k\">Location 位置</span><span class=\"v\">${esc(c.locationText||\"\")}</span><span class=\"k\">Type 类型</span><span class=\"v\">${esc(c.fireType||\"\")}</span><span class=\"k\">Severity 级别</span><span class=\"v\">${esc(c.severity||\"\")}</span><span class=\"k\">Trapped 被困</span><span class=\"v\">${esc(c.peopleTrapped||\"\")}</span><span class=\"k\">Hazards 危险</span><span class=\"v\">${esc(c.hazards||\"—\")}</span><span class=\"k\">Coordinates 坐标</span><span class=\"v\">${(Number(c.lat)||0).toFixed(4)}, ${(Number(c.lng)||0).toFixed(4)}</span></div><div class=\"cminimap\" data-d2-static></div><div class=\"cmstatus\"><span class=\"dotp\"></span><span class=\"cmtxt\">${esc(cmReadout(c).txt)}</span></div></div>`;\n    }\n    const SR=(typeof window!==\"undefined\")&&(window.SpeechRecognition||window.webkitSpeechRecognition);\n    const voiceOut=st.voiceOut===true;\n    const canVid=!!st.incidentId&&(typeof navigator!==\"undefined\")&&navigator.mediaDevices;\n    const vs=st.vstats||{};const dbgBlock=st.videoOn?`<button class=\"vdbgbtn\">🐞 ${st.vdbgOn?\"hide debug\":\"debug\"}</button>${st.vdbgOn?`<pre class=\"vdbg\">me: ${esc(vs.me||\"-\")}  inc: ${esc(vs.inc||\"-\")}\nstatus: ${esc(st.vidStatus||\"-\")}\\ntracks: ${esc(vs.tracks||\"-\")}  sig: ${esc(vs.sig||\"-\")}\\nice: ${esc(vs.ice||\"-\")}  conn: ${esc(vs.conn||\"-\")}\\ngather: ${esc(vs.gather||\"-\")}\\ncandidates: ${esc(vs.cand||\"(none yet - TURN?)\")}\\n---\\n${esc((st.vlog||[]).join(\"\\n\"))}</pre>`:\"\"}`:\"\";\n    const vidUI=canVid?`<div class=\"vidwrap\">${st.videoOn?`<video class=\"selfvid\" autoplay playsinline muted></video><div class=\"vidrow\"><span class=\"livepill\">🔴 ${esc(st.vidStatus||\"You are live 您正在直播\")}</span><button class=\"vidbtn stop\">⏹ Stop · 结束直播</button></div>${dbgBlock}`:`<button class=\"vidbtn\">📹 Turn on live video · 开启视频</button>`}</div>`:\"\";\n    const humanUI=st.humanControl?`<div class=\"humanbanner\">✋ A human dispatcher has joined · 人工调度员已接入</div>`:\"\";\n    return `<div class=\"page\">${splash}<div class=\"app\"><div class=\"hdr\"><div class=\"brandrow\"><div class=\"badge\">🚒</div><div><div class=\"ttl\">Report a Fire · 报告火灾</div><div class=\"sub\">Wuhan Fire Brigade · 武汉消防 · AI intake</div></div></div><div class=\"toolbar\"><div class=\"seg\"><button class=\"lang\" data-l=\"en\" ${lang===\"en\"?\"data-on\":\"\"}>EN</button><button class=\"lang\" data-l=\"zh\" ${lang===\"zh\"?\"data-on\":\"\"}>中文</button></div><button class=\"spk\" ${voiceOut?\"data-on\":\"\"}>${voiceOut?\"🔊 Voice\":\"🔇 Muted\"}</button></div></div>${humanUI}<div class=\"log\">${bubbles}${typing}${done}</div>${vidUI}<div class=\"bar\"><button class=\"icon cam\" ${st.busy||st.photoBusy?\"disabled\":\"\"}>${st.photoBusy?\"⏳\":\"📷\"}</button>${SR?`<button class=\"icon mic ${st.listening?\"live\":\"\"}\" ${st.busy?\"disabled\":\"\"}>🎤</button>`:\"\"}<input class=\"file\" type=\"file\" accept=\"image/*\" capture=\"environment\"/><textarea class=\"txt\" rows=\"1\" placeholder=\"${st.listening?(lang===\"zh\"?\"聆听中…\":\"Listening…\"):(lang===\"zh\"?\"描述火情…\":\"Describe the fire…\")}\" ${st.busy?\"disabled\":\"\"}></textarea><button class=\"send\" ${st.busy?\"disabled\":\"\"}>↑</button></div></div></div>`;\n  },\n  mounted(d2){\n    if(!d2.state.turns){d2.state.turns=[{role:\"agent\",en:\"Fire Brigade AI here. What is burning, and where in Wuhan? You can type, speak, or attach a photo.\",zh:\"武汉消防 AI。请问哪里着火了？是什么在燃烧？您可以打字、语音或上传照片。\"}];d2.state.lang=\"en\";d2.state.emotions=[];d2.state.splash=true;d2.state.voiceOut=false;}\n    setTimeout(()=>{d2.state.splash=false;},2300);\n    const refreshMine=async()=>{if(!d2.state.incidentId)return;try{const r=un(await d2.rush(\"fire_list\").invoke({}));const items=(r&&r.items)||[];const mine=items.find(i=>i._id===d2.state.incidentId);if(mine){d2.state.incident=mine;d2.state.humanControl=mine.humanControl===true;if(mine.transcript)d2.state.serverTranscript=mine.transcript;const seen=d2.state.seenDisp||{};let added=false;const tt=[...(d2.state.turns||[])];(mine.transcript||[]).forEach(m=>{if(m.role===\"dispatcher\"&&!seen[m.t]){seen[m.t]=1;tt.push({role:\"dispatcher\",en:m.translated||m.en||m.raw||\"\",zh:\"\"});added=true;}});if(added){d2.state.turns=tt;d2.state.seenDisp=seen;}}}catch(e){}};\n    let sock=null,pc=null,localStream=null,selfIv=null,sigSince=\"\";const myId=\"cit-\"+Math.random().toString(36).slice(2,8);\n    const setStat=(k,v)=>{d2.state.vstats={...(d2.state.vstats||{}),[k]:v};};setStat(\"me\",myId);\n    const vlog=(s)=>{const ln=new Date().toISOString().slice(11,19)+\" \"+s;try{console.log(\"[CIT-RTC]\",ln);}catch(e){}d2.state.vlog=[...((d2.state.vlog||[]).slice(-11)),ln];};\n    const emitSig=(p)=>{try{p.from=myId;d2.rush(\"fire_signal\").invoke(p);vlog(\"→ \"+p.t+\" (via server)\");}catch(e){vlog(\"emit ERR \"+(e&&e.message));}};\n    const closePc=()=>{try{if(pc)pc.close();}catch(e){}pc=null;};\n    const wirePc=(incId)=>{let host=0,srflx=0,relay=0;pc.onicecandidate=(e)=>{if(e.candidate){const cc=e.candidate.candidate||\"\";const ty=cc.indexOf(\"typ relay\")>=0?\"relay\":cc.indexOf(\"typ srflx\")>=0?\"srflx\":\"host\";if(ty===\"relay\")relay++;else if(ty===\"srflx\")srflx++;else host++;setStat(\"cand\",`host:${host} srflx:${srflx} relay:${relay}`);emitSig({sig:true,incidentId:incId,t:\"ice\",role:\"caller\",c:e.candidate});}};pc.oniceconnectionstatechange=()=>{setStat(\"ice\",pc.iceConnectionState);vlog(\"ice=\"+pc.iceConnectionState);};pc.onconnectionstatechange=()=>{setStat(\"conn\",pc.connectionState);vlog(\"conn=\"+pc.connectionState);};pc.onicegatheringstatechange=()=>{setStat(\"gather\",pc.iceGatheringState);};};\n    const makeOfferFor=async()=>{const incId=d2.state.incidentId;if(!localStream||!incId)return;closePc();try{pc=new RTCPeerConnection({iceServers:ICE});localStream.getTracks().forEach(t=>pc.addTrack(t,localStream));setStat(\"tracks\",localStream.getTracks().map(t=>t.kind).join(\"+\"));wirePc(incId);const o=await pc.createOffer();await pc.setLocalDescription(o);setStat(\"sig\",pc.signalingState);emitSig({sig:true,incidentId:incId,t:\"offer\",role:\"caller\",sdp:o});vlog(\"offer sent (\"+localStream.getTracks().length+\" tracks)\");}catch(e){d2.state.vidStatus=\"WebRTC error 连接错误\";vlog(\"offer ERR \"+(e&&e.message));}};\n    const onSig=async(p)=>{if(!p||!p.sig||p.incidentId!==d2.state.incidentId||p.role===\"caller\")return;if(!d2.state.videoOn)return;vlog(\"← \"+p.t);try{if(p.t===\"watch-request\"){await makeOfferFor();}else if(p.t===\"answer\"&&pc){await pc.setRemoteDescription(p.sdp);vlog(\"remote answer set\");}else if(p.t===\"ice\"&&pc&&p.c){try{await pc.addIceCandidate(p.c);}catch(e){}}}catch(e){vlog(\"onSig ERR \"+(e&&e.message));}};\n    const startCam=async()=>{const incId=d2.state.incidentId;if(!incId||!(navigator&&navigator.mediaDevices)){d2.state.videoOn=true;d2.state.vidStatus=\"Camera unavailable 摄像头不可用\";return;}try{localStream=await navigator.mediaDevices.getUserMedia({video:true,audio:true});}catch(e){d2.state.videoOn=true;d2.state.vidStatus=\"Camera blocked 摄像头被拒绝\";return;}d2.state.videoOn=true;d2.state.vidStatus=\"You are live 您正在直播\";setStat(\"inc\",String(incId).slice(-6));vlog(\"GO LIVE me=\"+myId+\" inc=\"+incId);sigSince=new Date(Date.now()-20000).toISOString();try{d2.rush(\"fire_save\").invoke({record:{_id:incId,liveVideo:true,liveId:incId}});}catch(e){}emitSig({sig:true,incidentId:incId,t:\"announce\",role:\"caller\"});if(selfIv)clearInterval(selfIv);selfIv=setInterval(()=>{try{const v=d2.$(\".selfvid\");if(v&&localStream&&v.srcObject!==localStream)v.srcObject=localStream;}catch(e){}},500);};\n    const stopCam=()=>{const incId=d2.state.incidentId;try{if(localStream)localStream.getTracks().forEach(t=>{try{t.stop();}catch(e){}});}catch(e){}localStream=null;closePc();if(selfIv){clearInterval(selfIv);selfIv=null;}d2.state.videoOn=false;d2.state.vidStatus=\"\";try{if(incId)d2.rush(\"fire_save\").invoke({record:{_id:incId,liveVideo:false}});}catch(e){}try{if(incId)emitSig({sig:true,incidentId:incId,t:\"end\",role:\"caller\"});}catch(e){}};\n    d2.onUnmount(()=>{try{if(localStream)localStream.getTracks().forEach(t=>t.stop());}catch(e){}closePc();if(selfIv)clearInterval(selfIv);});\n    try{sock=d2.socket(\"feed\");sock.subscribe(\"wuhan\");sock.onMessage((m)=>{const p=(m&&m.data!==undefined)?m.data:m;const room=(m&&(m.room||m.channel))||\"wuhan\";if(d2.state.videoOn){vlog(\"recv[\"+room+\"] \"+((p&&p.sig)?(\"sig/\"+(p.t||\"?\")):\"incident\")+((p&&p.incidentId)?(\" inc=\"+String(p.incidentId).slice(-5)):\"\")+((p&&p.from)?(\" from=\"+p.from):\"\"));}if(p&&p.sig){if(p.from===myId)return;onSig(p);}else{refreshMine();}});}catch(e){}\n    d2.on(\".vidbtn\",\"click\",()=>{if(d2.state.videoOn){stopCam();}else{startCam();}});\n    d2.on(\".vdbgbtn\",\"click\",()=>{d2.state.vdbgOn=!d2.state.vdbgOn;});\n    const mineIv=setInterval(refreshMine,1500);d2.onUnmount(()=>clearInterval(mineIv));const sigPoll=async()=>{if(!d2.state.videoOn||!d2.state.incidentId)return;try{const r=un(await d2.rush(\"fire_signal_poll\").invoke({incidentId:d2.state.incidentId,since:sigSince||\"\"}));const items=(r&&r.items)||[];if(r&&r.now)sigSince=r.now;items.forEach(row=>{const p=(row&&row.body)?row.body:row;if(!p||!p.sig||p.from===myId)return;vlog(\"poll← \"+p.t+(p.from?(\" from=\"+p.from):\"\"));onSig(p);});}catch(e){}};const sigIv=setInterval(sigPoll,1000);d2.onUnmount(()=>clearInterval(sigIv));\n    const fetchStations=async()=>{try{const r=un(await d2.rush(\"fire_stations\").invoke({}));d2.state.stations=(r&&r.items)||[];}catch(e){}};\n    fetchStations();\n    let mmap=null,mL=null,mbuilt=false,mInc=null,mFitted=false;const mSquad={},mRoute={},mRouteGeo={},mRouteFetching={};const stnById=(id)=>(d2.state.stations||[]).find(s=>s._id===id);const fetchRoute=async(c,u)=>{const key=c._id+\":\"+u.stationId;if(mRouteGeo[key]||mRouteFetching[key])return;const s=stnById(u.stationId);if(!s)return;mRouteFetching[key]=true;try{const url=`https://router.project-osrm.org/route/v1/driving/${s.lng},${s.lat};${c.lng},${c.lat}?overview=full&geometries=geojson`;const resp=await fetch(url);const j=await resp.json();const co=j&&j.routes&&j.routes[0]&&j.routes[0].geometry&&j.routes[0].geometry.coordinates;mRouteGeo[key]=(co&&co.length>1)?co.map(x=>[x[1],x[0]]):[[s.lat,s.lng],[c.lat,c.lng]];}catch(e){mRouteGeo[key]=[[s.lat,s.lng],[c.lat,c.lng]];}mRouteFetching[key]=false;};\n    const buildMini=()=>{if(mbuilt)return;const c=d2.state.incident;if(!(d2.state.done&&c&&Number.isFinite(c.lat)&&c.lat>10))return;let LL=null;try{LL=d2.lib(LEAF);}catch(e){}const el=d2.$(\".cminimap\");if(!(LL&&el))return;LL=(LL&&LL.default)||LL;mL=LL;try{mmap=LL.map(el,{zoomControl:false,attributionControl:false,scrollWheelZoom:false}).setView([c.lat,c.lng],14);LL.tileLayer(\"https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png\",{subdomains:\"abcd\",maxZoom:19,attribution:\"© OpenStreetMap © CARTO\"}).addTo(mmap);const ic=LL.divIcon({className:\"\",iconSize:[26,26],iconAnchor:[13,13],html:`<div class=\\\"lpin act\\\" style=\\\"--c:#ff3b30\\\"><span class=\\\"ring\\\"></span><span class=\\\"core\\\">🔥</span></div>`});mInc=LL.marker([c.lat,c.lng],{icon:ic}).addTo(mmap);mbuilt=true;setTimeout(()=>{try{mmap.invalidateSize();}catch(e){}},250);try{const ro=new ResizeObserver(()=>{try{mmap.invalidateSize();}catch(e){}});ro.observe(el);d2.onUnmount(()=>ro.disconnect());}catch(e){}}catch(e){}};\n    const miniIv=setInterval(()=>{if(!mbuilt){buildMini();return;}const c=d2.state.incident;if(!c||!mL||!mmap)return;const units=c.units||[];units.forEach(u=>{const key=c._id+\":\"+u.stationId;const s=stnById(u.stationId);if(!s)return;fetchRoute(c,u);const geo=mRouteGeo[key];if(geo&&!mRoute[key]){try{mRoute[key]=mL.polyline(geo,{color:\"#0a84ff\",weight:2.5,opacity:.5,dashArray:\"1 7\",lineCap:\"round\"}).addTo(mmap);}catch(e){}}else if(geo&&mRoute[key]){try{mRoute[key].setLatLngs(geo);}catch(e){}}if(!mSquad[key]){try{const sic=mL.divIcon({className:\"\",iconSize:[28,28],iconAnchor:[14,14],html:`<div class=\"lsquad\"><span class=\"veh\">🚒</span></div>`});mSquad[key]=mL.marker([s.lat,s.lng],{icon:sic}).addTo(mmap);}catch(e){}}});if(!mFitted&&units.length){try{const pts=[[c.lat,c.lng]];units.forEach(u=>{const s=stnById(u.stationId);if(s)pts.push([s.lat,s.lng]);});if(pts.length>1){mmap.fitBounds(pts,{padding:[26,26],maxZoom:15});mFitted=true;}}catch(e){}}try{const el2=d2.$(\".cmtxt\");if(el2)el2.textContent=cmReadout(c).txt;}catch(e){}},1000);\n    d2.onUnmount(()=>clearInterval(miniIv));\n    d2.raf(()=>{if(!mbuilt||!mmap)return;const c=d2.state.incident;if(!c||!c.dispatchedAt)return;(c.units||[]).forEach(u=>{const key=c._id+\":\"+u.stationId;const mk=mSquad[key];if(!mk)return;const s=stnById(u.stationId);const el=Date.now()-(u.dispatchedAt||c.dispatchedAt);const p=unitP(el);const geo=mRouteGeo[key];let pos=null;if(geo&&geo.length){pos=pointAlong(geo,p);}else if(s){pos=[s.lat+(c.lat-s.lat)*ease(p),s.lng+(c.lng-s.lng)*ease(p)];}if(pos&&Number.isFinite(pos[0])){try{mk.setLatLng(pos);}catch(e){}}});});\n    const speak=(res)=>{try{if(d2.state.voiceOut===true&&typeof window!==\"undefined\"&&window.speechSynthesis){const txt=d2.state.lang===\"zh\"?(res.reply_zh||\"\"):(res.reply_en||\"\");if(!txt)return;const u=new SpeechSynthesisUtterance(txt);u.lang=d2.state.lang===\"zh\"?\"zh-CN\":\"en-US\";u.rate=1.02;window.speechSynthesis.cancel();window.speechSynthesis.speak(u);}}catch(e){}};\n    const send=async(text)=>{\n      const msg=(text||\"\").trim();if(!msg||d2.state.busy)return;\n      const photo=d2.state.photoUrl||null,vision=d2.state.vision||null,pAnalysis=d2.state.photoAnalysis||null,pAddress=d2.state.photoAddress||null;\n      const turns=[...(d2.state.turns||[])];\n      turns.push({role:\"reporter\",en:msg,photo:photo,vision:vision});\n      d2.state.turns=turns;d2.state.busy=true;\n      // clear pending attachment so it does NOT leak onto the next message's bubble\n      d2.state.vision=null;d2.state.photoUrl=null;d2.state.photoAnalysis=null;d2.state.photoAddress=null;\n      const history=turns.map(t=>({role:t.role,text:t.role===\"reporter\"?t.en:`${t.en} / ${t.zh||\"\"}`}));\n      history.pop();\n      try{\n        const res=un(await d2.rush(\"fire_chat\").invoke({message:msg,history:history,lang:d2.state.lang,incidentId:d2.state.incidentId||null,emotions:d2.state.emotions||[],transcript:d2.state.serverTranscript||[],humanControl:d2.state.humanControl===true,photoUrl:photo,photoAnalysis:pAnalysis,photoAddress:pAddress}));\n        if(res.incidentId)d2.state.incidentId=res.incidentId;\n        if(res.transcript)d2.state.serverTranscript=res.transcript;\n        if(res.humanControl!==undefined)d2.state.humanControl=res.humanControl===true;\n        if(res.emotion)d2.state.emotions=[...(d2.state.emotions||[]),res.emotion];\n        const t2=[...d2.state.turns];\n        if(res.emotion){for(let i=t2.length-1;i>=0;i--){if(t2[i].role===\"reporter\"){t2[i]={...t2[i],emotion:res.emotion};break;}}}\n        if(res.reply_en||res.reply_zh){t2.push({role:\"agent\",en:res.reply_en||\"\",zh:res.reply_zh||\"\",sources:res.sources});}\n        d2.state.turns=t2;\n        if(res.done){d2.state.done=true;d2.state.incident=res.incident;d2.state.photoUrl=null;d2.state.photoAnalysis=null;d2.state.photoAddress=null;}\n        speak(res);\n      }catch(e){const t2=[...d2.state.turns];t2.push({role:\"agent\",en:\"Connection error, please retry.\",zh:\"连接错误，请重试。\"});d2.state.turns=t2;}\n      d2.state.busy=false;\n    };\n    let recog=null;\n    const toggleVoice=()=>{\n      const SR=window.SpeechRecognition||window.webkitSpeechRecognition;if(!SR)return;\n      if(d2.state.listening){if(recog){try{recog.stop();}catch(e){}}d2.state.listening=false;return;}\n      try{recog=new SR();}catch(e){return;}\n      recog.lang=d2.state.lang===\"zh\"?\"zh-CN\":\"en-US\";recog.interimResults=true;recog.continuous=false;\n      recog.onresult=(e)=>{let txt=\"\";for(let i=0;i<e.results.length;i++){txt+=e.results[i][0].transcript;}const el=d2.$(\".txt\");if(el)el.value=txt;const last=e.results[e.results.length-1];if(last&&last.isFinal){d2.state.listening=false;const v=txt;if(el)el.value=\"\";send(v);}};\n      recog.onerror=()=>{d2.state.listening=false;};recog.onend=()=>{if(d2.state.listening)d2.state.listening=false;};\n      d2.state.listening=true;try{recog.start();}catch(e){d2.state.listening=false;}\n    };\n    d2.on(\".send\",\"click\",()=>{const el=d2.$(\".txt\");const v=el.value;el.value=\"\";send(v);});\n    d2.on(\".txt\",\"keydown\",(e,el)=>{if(e.key===\"Enter\"&&!e.shiftKey){e.preventDefault();const v=el.value;el.value=\"\";send(v);}});\n    d2.on(\".lang\",\"click\",(e,el)=>{d2.state.lang=el.dataset.l;});\n    d2.on(\".spk\",\"click\",()=>{d2.state.voiceOut=d2.state.voiceOut===false;if(d2.state.voiceOut===false&&window.speechSynthesis)window.speechSynthesis.cancel();});\n    d2.on(\".mic\",\"click\",()=>{toggleVoice();});\n    d2.on(\".cam\",\"click\",()=>{const f=d2.$(\".file\");if(f)f.click();});\n    d2.on(\".file\",\"change\",async(e,el)=>{\n      const f=el.files&&el.files[0];if(!f)return;\n      d2.state.photoBusy=true;\n      d2.state.turns=[...(d2.state.turns||[]),{role:\"reporter\",en:(d2.state.lang===\"zh\"?\"[上传照片中…]\":\"[Uploading photo…]\"),visionLoading:true}];\n      let dataUrl=\"\";try{dataUrl=await new Promise((res,rej)=>{const fr=new FileReader();fr.onload=()=>res(fr.result);fr.onerror=()=>rej(new Error(\"read\"));fr.readAsDataURL(f);});}catch(err){dataUrl=\"\";}\n      let url=\"\",analysis=null;\n      try{const out=await d2.drive(\"media\").uploadFromFiles([f]);url=(out&&out[0]&&out[0].fileUrl)||\"\";}catch(err){url=\"\";}\n      d2.state.photoUrl=url||null;\n      const imgV=dataUrl||url;\n      try{console.log(\"[CIT-PHOTO] dataUrl len:\",(dataUrl||\"\").length,\"driveUrl:\",url);}catch(e){}\n      if(imgV){try{analysis=await Promise.race([d2.assistant(\"fireVision\").ask(\"Analyze this fire-scene photo and read ALL visible text — street signs, road names, shop/building names, plates, landmarks (Chinese and English). Return your JSON object including extractedAddress and textSeen.\",{images:[imgV],json:true}),new Promise((_,rej)=>setTimeout(()=>rej(new Error(\"timeout\")),25000))]);}catch(err){analysis=null;}}\n      try{console.log(\"[CIT-PHOTO] vision result:\",analysis);}catch(e){}\n      let ocrText=\"\";if(url){try{const orr=un(await d2.rush(\"fire_ocr\").invoke({url:url}));ocrText=(orr&&orr.ocrText)||\"\";}catch(err){ocrText=\"\";}}\n      try{console.log(\"[CIT-PHOTO] OCR text:\",ocrText);}catch(e){}\n      const visAddr=(analysis&&typeof analysis===\"object\"&&analysis.extractedAddress)?analysis.extractedAddress:\"\";\n      d2.state.photoAddress=visAddr||ocrText||\"\";\n      try{console.log(\"[CIT-PHOTO] photoAddress =>\",d2.state.photoAddress);}catch(e){}\n      const t2=[...d2.state.turns];for(let i=t2.length-1;i>=0;i--){if(t2[i].visionLoading){t2[i]={role:\"reporter\",en:((url||dataUrl)?(d2.state.lang===\"zh\"?\"[火灾照片]\":\"[Fire photo]\"):(d2.state.lang===\"zh\"?\"[照片上传失败]\":\"[Photo upload failed]\")),photo:url||dataUrl||null,vision:(analysis&&typeof analysis===\"object\")?analysis:null};break;}}d2.state.turns=t2;\n      if(analysis&&typeof analysis===\"object\"){d2.state.vision=analysis;d2.state.photoAnalysis=`whatsBurning=${analysis.whatsBurning}; fireType=${analysis.fireType}; severity=${analysis.severity}; smoke=${analysis.smoke}; peopleVisible=${analysis.peopleVisible}; hazards=${analysis.hazards}; address=${d2.state.photoAddress||\"n/a\"}; signage=${ocrText||\"n/a\"}; ${analysis.summary_en||\"\"} / ${analysis.summary_zh||\"\"}`;}\n      else if(url||dataUrl){d2.state.photoAnalysis=`Photo attached. Signage read: ${ocrText||\"none\"} / 已附照片，识别到标识：${ocrText||\"无\"}`;}\n      else{d2.state.photoAnalysis=\"\";}\n      d2.state.photoBusy=false;el.value=\"\";\n      send((url||dataUrl)?(d2.state.lang===\"zh\"?\"我上传了一张火灾现场照片，请参考。\":\"I attached a photo of the fire scene, please use it.\"):(d2.state.lang===\"zh\"?\"我尝试上传照片但没成功。\":\"I tried to attach a photo but it didn't upload.\"));\n    });\n  },\n  updated(d2){const log=d2.$(\".log\");if(log)log.scrollTop=log.scrollHeight;},\n};"}},"chatApi":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"chatApi"}}}},"vision":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"vision"}}}}}}}},"__d2PrevCode":{"code":"const EC={panic:\"#ff3b30\",fear:\"#ff9500\",distress:\"#5e5ce6\",anger:\"#c9302c\",confusion:\"#ffcc00\",calm:\"#34c759\"};\nconst SC={Intake:\"#30b0c7\",Reported:\"#ff3b30\",Dispatched:\"#ff9500\",EnRoute:\"#0a84ff\",OnScene:\"#5e5ce6\",Resolved:\"#34c759\"};\nconst SL={Intake:[\"Intake\",\"接线中\"],Reported:[\"Reported\",\"已报告\"],Dispatched:[\"Dispatched\",\"已派遣\"],EnRoute:[\"En route\",\"前往中\"],OnScene:[\"On scene\",\"已到场\"],Resolved:[\"Resolved\",\"已解决\"]};\nconst T_DISP=4000,T_ENROUTE=49000,T_SCENE=89000;\nfunction phaseOf(el){if(el<T_DISP)return \"Dispatched\";if(el<T_ENROUTE)return \"EnRoute\";if(el<T_SCENE)return \"OnScene\";return \"Resolved\";}\nfunction unitP(el){if(el<=T_DISP)return 0;if(el>=T_ENROUTE)return 1;return (el-T_DISP)/(T_ENROUTE-T_DISP);}\nfunction mdist(a,b){const dy=a[0]-b[0],dx=a[1]-b[1];return Math.sqrt(dy*dy+dx*dx);}\nfunction pointAlong(pts,p){if(!pts||pts.length===0)return null;if(pts.length===1)return pts[0];let total=0;const segs=[];for(let i=1;i<pts.length;i++){const d=mdist(pts[i-1],pts[i]);segs.push(d);total+=d;}if(total<=0)return pts[0];const target=Math.max(0,Math.min(1,p))*total;let acc=0;for(let i=1;i<pts.length;i++){const d=segs[i-1];if(acc+d>=target){const f=d>0?(target-acc)/d:0;return [pts[i-1][0]+(pts[i][0]-pts[i-1][0])*f,pts[i-1][1]+(pts[i][1]-pts[i-1][1])*f];}acc+=d;}return pts[pts.length-1];}\nfunction cmReadout(c){if(!c)return {cls:\"\",txt:\"\"};if(!c.dispatchedAt)return {cls:\"\",txt:(c.status===\"Reported\")?\"Report received · 已收到报告\":\"Awaiting dispatch · 等待派遣\"};const units=c.units||[];const n=units.length||1;const el=Date.now()-c.dispatchedAt;const ph=phaseOf(el);if(ph===\"Resolved\"||c.status===\"Resolved\")return {cls:\"ok\",txt:\"✓ Resolved · 已解决\"};if(ph===\"OnScene\")return {cls:\"\",txt:\"🚒 On scene · 已到场 · \"+n+\" unit\"+(n>1?\"s\":\"\")};if(ph===\"EnRoute\")return {cls:\"\",txt:\"🚒 En route · 前往中 · ETA \"+Math.max(0,Math.ceil((T_ENROUTE-el)/1000))+\"s · \"+n+\" unit\"+(n>1?\"s\":\"\")};return {cls:\"\",txt:\"🚒 Unit dispatched · 消防队已出动 · \"+n+\" unit\"+(n>1?\"s\":\"\")};}\nfunction dstat(inc){if(inc&&inc.dispatchedAt&&inc.status!==\"Resolved\"){return phaseOf(Date.now()-inc.dispatchedAt);}return inc?inc.status:\"Reported\";}\nfunction ease(p){return p*p*(3-2*p);}\nconst LEAF={name:\"leaflet@1.9.4\",css:\"https://cdn.jsdelivr.net/npm/leaflet@1.9.4/dist/leaflet.css\"};\nconst ICE=[{urls:[\"stun:stun.l.google.com:19302\",\"stun:stun1.l.google.com:19302\"]},{urls:[\"turn:openrelay.metered.ca:80\",\"turn:openrelay.metered.ca:443\",\"turn:openrelay.metered.ca:443?transport=tcp\"],username:\"openrelayproject\",credential:\"openrelayproject\"},{urls:[\"turn:openrelay.metered.ca:80?transport=tcp\"],username:\"openrelayproject\",credential:\"openrelayproject\"}];\nfunction un(r){return (r&&typeof r===\"object\"&&r.data!==undefined&&r.reply_en===undefined&&r.items===undefined&&r.ok===undefined)?r.data:r;}\nfunction esc(s){return String(s==null?\"\":s).replace(/&/g,\"&amp;\").replace(/</g,\"&lt;\").replace(/>/g,\"&gt;\");}\nexport default {\n  css:`\n  .page{height:100%;display:flex;align-items:stretch;justify-content:center;background:radial-gradient(1200px 600px at 50% -10%, rgba(255,59,48,.10), transparent 60%), linear-gradient(180deg,#f5f5f7 0%, #ececf0 100%);font-family:-apple-system,\"SF Pro Display\",\"SF Pro Text\",\"PingFang SC\",\"Helvetica Neue\",system-ui,sans-serif;color:#1d1d1f;-webkit-font-smoothing:antialiased;position:relative;overflow:hidden;}\n  .app{width:100%;max-width:480px;height:100%;display:flex;flex-direction:column;background:rgba(255,255,255,.72);backdrop-filter:saturate(180%) blur(30px);-webkit-backdrop-filter:saturate(180%) blur(30px);border-left:1px solid rgba(0,0,0,.06);border-right:1px solid rgba(0,0,0,.06);box-shadow:0 30px 80px rgba(0,0,0,.12);}\n  .splash{position:absolute;inset:0;z-index:50;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:16px;background:linear-gradient(180deg,#ff5a4d,#ff3b30);color:#fff;animation:splashout .7s ease 1.5s forwards;}\n  .splash .sb{width:88px;height:88px;border-radius:26px;display:flex;align-items:center;justify-content:center;font-size:46px;background:rgba(255,255,255,.16);backdrop-filter:blur(10px);box-shadow:0 20px 50px rgba(0,0,0,.25);animation:sbin .7s cubic-bezier(.2,.9,.3,1.3);}\n  .splash h1{font-size:23px;font-weight:750;letter-spacing:-.02em;margin:0;}\n  .splash p{font-size:13px;opacity:.9;margin:0;letter-spacing:.02em;}\n  .splash .ring{width:22px;height:22px;border:2.5px solid rgba(255,255,255,.35);border-top-color:#fff;border-radius:50%;animation:spin .8s linear infinite;margin-top:6px;}\n  .hdr{padding:20px 20px 14px;border-bottom:1px solid rgba(0,0,0,.06);background:rgba(255,255,255,.55);backdrop-filter:blur(20px);}\n  .brandrow{display:flex;align-items:center;gap:10px;}\n  .badge{width:34px;height:34px;border-radius:10px;display:flex;align-items:center;justify-content:center;background:linear-gradient(180deg,#ff5a4d,#ff3b30);box-shadow:0 4px 12px rgba(255,59,48,.35);font-size:18px;}\n  .ttl{font-size:19px;font-weight:700;letter-spacing:-.02em;}\n  .sub{font-size:12px;color:#6e6e73;margin-top:1px;}\n  .toolbar{display:flex;gap:6px;margin-top:12px;align-items:center;}\n  .seg{display:flex;background:rgba(120,120,128,.12);border-radius:9px;padding:2px;}\n  .seg button{border:0;background:transparent;font:inherit;font-size:12px;font-weight:600;color:#3c3c43;padding:5px 12px;border-radius:7px;cursor:pointer;transition:all .2s;}\n  .seg button[data-on]{background:#fff;box-shadow:0 1px 3px rgba(0,0,0,.12);color:#1d1d1f;}\n  .spk{margin-left:auto;border:0;background:rgba(120,120,128,.12);border-radius:9px;padding:6px 10px;font:inherit;font-size:12px;font-weight:600;color:#3c3c43;cursor:pointer;transition:all .2s;}\n  .spk[data-on]{background:rgba(10,132,255,.14);color:#0071e3;}\n  .log{flex:1;overflow:auto;padding:18px 16px;display:flex;flex-direction:column;gap:12px;}\n  .row{display:flex;}.row.me{justify-content:flex-end;}.row.ai{justify-content:flex-start;}\n  .wrap{max-width:82%;display:flex;flex-direction:column;}\n  .me .wrap{align-items:flex-end;}\n  .bub{padding:11px 14px;border-radius:20px;font-size:14.5px;line-height:1.42;animation:pop .28s cubic-bezier(.2,.9,.3,1.2);}\n  .me .bub{background:linear-gradient(180deg,#0a84ff,#0071e3);color:#fff;border-bottom-right-radius:6px;box-shadow:0 4px 14px rgba(10,132,255,.28);}\n  .ai .bub{background:#fff;color:#1d1d1f;border-bottom-left-radius:6px;border:1px solid rgba(0,0,0,.05);box-shadow:0 2px 10px rgba(0,0,0,.05);}\n  .en{font-weight:500;}.zh{margin-top:4px;color:#6e6e73;font-size:13px;}.me .zh{color:rgba(255,255,255,.85);}\n  .emochip{margin-top:5px;font-size:10px;font-weight:700;padding:2px 8px;border-radius:7px;color:#fff;display:inline-flex;align-items:center;gap:4px;align-self:flex-end;}\n  .src{margin-top:7px;display:flex;flex-wrap:wrap;gap:4px;}\n  .chip{font-size:10px;color:#8a8a8e;background:rgba(120,120,128,.10);border-radius:6px;padding:2px 6px;}\n  .thumb{margin-top:6px;border-radius:16px;overflow:hidden;max-width:220px;box-shadow:0 6px 18px rgba(0,0,0,.15);}.thumb img{display:block;width:100%;height:auto;}\n  .vis{margin-top:6px;font-size:11.5px;color:#1d1d1f;background:rgba(52,199,89,.12);border:1px solid rgba(52,199,89,.25);border-radius:10px;padding:8px 10px;}.vis b{color:#248a3d;}\n  .visload{margin-top:6px;font-size:11.5px;color:#6e6e73;background:rgba(120,120,128,.1);border-radius:10px;padding:8px 10px;display:flex;align-items:center;gap:8px;}\n  .shimmer{height:8px;border-radius:4px;flex:1;background:linear-gradient(90deg,#e6e6ea 25%,#f2f2f5 37%,#e6e6ea 63%);background-size:400% 100%;animation:sh 1.4s ease infinite;}\n  .typing{display:inline-flex;gap:4px;align-items:center;padding:4px 2px;}\n  .typing i{width:7px;height:7px;border-radius:50%;background:#c7c7cc;animation:bnc 1.2s infinite;}\n  .typing i:nth-child(2){animation-delay:.15s;}.typing i:nth-child(3){animation-delay:.3s;}\n  .done{margin:4px 0;padding:16px;border-radius:18px;background:#fff;border:1px solid rgba(52,199,89,.3);box-shadow:0 8px 26px rgba(0,0,0,.08);animation:pop .3s ease;}\n  .done h4{font-size:15px;display:flex;align-items:center;gap:8px;color:#248a3d;margin:0;}\n  .kv{display:grid;grid-template-columns:auto 1fr;gap:6px 12px;margin-top:10px;font-size:13px;}\n  .kv .k{color:#8a8a8e;}.kv .v{font-weight:600;text-align:right;}\n  .bar{padding:12px 12px calc(12px + env(safe-area-inset-bottom));border-top:1px solid rgba(0,0,0,.06);display:flex;gap:8px;align-items:flex-end;background:rgba(255,255,255,.7);backdrop-filter:blur(20px);}\n  .icon{width:40px;height:40px;flex:0 0 40px;border-radius:50%;border:0;cursor:pointer;font-size:17px;background:rgba(120,120,128,.14);transition:transform .15s,background .2s;}\n  .icon:active{transform:scale(.9);}\n  .icon.live{background:#ff3b30;color:#fff;animation:micp 1.1s infinite;}\n  .txt{flex:1;min-height:40px;max-height:120px;resize:none;border:1px solid rgba(0,0,0,.1);border-radius:20px;padding:10px 14px;font:inherit;font-size:16px;outline:none;background:#fff;transition:border .2s,box-shadow .2s;}\n  .txt:focus{border-color:#0a84ff;box-shadow:0 0 0 4px rgba(10,132,255,.12);}\n  .send{width:40px;height:40px;flex:0 0 40px;border-radius:50%;border:0;cursor:pointer;font-size:19px;font-weight:700;color:#fff;background:linear-gradient(180deg,#ff5a4d,#ff3b30);box-shadow:0 4px 12px rgba(255,59,48,.35);transition:transform .15s,opacity .2s;}\n  .send:active{transform:scale(.9);}.send[disabled],.icon[disabled]{opacity:.4;cursor:default;}\n  .file{display:none;}\n  .ai.dispatcher .bub{background:linear-gradient(180deg,#ffab2e,#ff9500);color:#fff;border:0;}\n  .rolelbl{font-size:9px;font-weight:700;opacity:.8;text-transform:uppercase;letter-spacing:.04em;display:block;margin-bottom:2px;}\n  .humanbanner{margin:8px 16px 0;padding:8px 12px;border-radius:12px;background:rgba(255,149,0,.14);color:#b35a00;font-size:12px;font-weight:650;text-align:center;}\n  .vidwrap{padding:10px 16px 0;}\n  .vidbtn{width:100%;border:0;border-radius:14px;padding:12px;font:inherit;font-size:14px;font-weight:700;color:#fff;background:linear-gradient(180deg,#ff5a4d,#ff3b30);box-shadow:0 6px 16px rgba(255,59,48,.35);cursor:pointer;display:flex;align-items:center;justify-content:center;gap:8px;transition:transform .15s;}\n  .vidbtn:active{transform:scale(.98);}\n  .selfvid{width:100%;border-radius:14px;background:#000;aspect-ratio:16/9;object-fit:cover;transform:scaleX(-1);box-shadow:0 6px 18px rgba(0,0,0,.25);}\n  .vidrow{display:flex;align-items:center;gap:8px;margin-top:6px;}\n  .livepill{flex:1;font-size:12px;color:#ff3b30;font-weight:700;}\n  .vidbtn.stop{width:auto;padding:8px 14px;font-size:13px;background:rgba(120,120,128,.16);color:#1d1d1f;box-shadow:none;}\n  .vdbgbtn{margin-top:6px;font-size:10px;border:0;background:rgba(120,120,128,.14);border-radius:8px;padding:4px 8px;cursor:pointer;color:#3c3c43;}\n  .vdbg{margin-top:6px;font-size:9.5px;font-family:ui-monospace,monospace;background:#0b0b0f;color:#8fef8f;padding:8px;border-radius:8px;white-space:pre-wrap;max-height:150px;overflow:auto;line-height:1.4;}\n  .cminimap{margin-top:12px;height:180px;border-radius:16px;overflow:hidden;box-shadow:0 6px 18px rgba(0,0,0,.12);background:#eef0f4;position:relative;}\n  .cmstatus{margin-top:8px;display:flex;align-items:center;gap:8px;font-size:12px;font-weight:650;color:#0a3d62;background:rgba(10,132,255,.1);border:1px solid rgba(10,132,255,.22);border-radius:12px;padding:8px 11px;}\n  .cmstatus .dotp{width:8px;height:8px;border-radius:50%;background:#0a84ff;flex:0 0 8px;animation:livep 1.6s infinite;}\n  @keyframes livep{0%,100%{opacity:1;}50%{opacity:.3;}}\n  .leaflet-div-icon{background:transparent!important;border:none!important;}\n  .leaflet-container{font-family:inherit;background:#eef0f4;}\n  .lpin{position:relative;width:26px;height:26px;}\n  .lpin .ring{position:absolute;inset:2px;border-radius:50%;background:var(--c);opacity:.28;animation:cpulse 1.8s infinite;}\n  .lpin .core{position:absolute;inset:6px;border-radius:50%;background:var(--c);border:2px solid #fff;display:flex;align-items:center;justify-content:center;font-size:8px;box-shadow:0 2px 6px rgba(0,0,0,.3);}\n  .lsquad .veh{width:22px;height:22px;border-radius:50%;background:#0a84ff;border:2.5px solid #fff;display:flex;align-items:center;justify-content:center;font-size:11px;box-shadow:0 3px 8px rgba(10,132,255,.5);}\n  @keyframes cpulse{0%{transform:scale(1);opacity:.3;}70%{transform:scale(2);opacity:0;}100%{opacity:0;}}\n  @keyframes pop{from{opacity:0;transform:translateY(6px) scale(.98);}to{opacity:1;transform:none;}}\n  @keyframes bnc{0%,60%,100%{transform:translateY(0);opacity:.5;}30%{transform:translateY(-5px);opacity:1;}}\n  @keyframes sh{0%{background-position:100% 0;}100%{background-position:0 0;}}\n  @keyframes spin{to{transform:rotate(360deg);}}\n  @keyframes micp{0%{box-shadow:0 0 0 0 rgba(255,59,48,.5);}70%{box-shadow:0 0 0 10px rgba(255,59,48,0);}100%{box-shadow:0 0 0 0 rgba(255,59,48,0);}}\n  @keyframes splashout{to{opacity:0;visibility:hidden;}}\n  @keyframes sbin{from{opacity:0;transform:scale(.7);}to{opacity:1;transform:none;}}\n  `,\n  render(d2){\n    const st=d2.state;const turns=st.turns||[];const lang=st.lang||\"en\";if(st.done){try{d2.lib(LEAF);}catch(e){}}\n    const splash=st.splash===false?\"\":`<div class=\"splash\"><div class=\"sb\">🚒</div><h1>Wuhan Fire Brigade</h1><p>武汉消防 · Emergency Report · 火警报告</p><div class=\"ring\"></div></div>`;\n    const bubbles=turns.map((t,i)=>{\n      if(t.role===\"reporter\"){\n        let inner=`<div class=\"bub\"><div class=\"en\">${esc(t.en)}</div>${t.photo?`<div class=\"thumb\"><img src=\"${esc(t.photo)}\"/></div>`:\"\"}${t.visionLoading?`<div class=\"visload\"><div class=\"shimmer\"></div>📸 analyzing…</div>`:\"\"}${t.vision?`<div class=\"vis\"><b>📸 AI vision · 影像分析</b><br>${esc(t.vision.summary_en||\"\")} · ${esc(t.vision.summary_zh||\"\")}</div>`:\"\"}</div>`;\n        let em=\"\";\n        if(t.emotion){const c=EC[t.emotion.emotion]||\"#8a8a8e\";em=`<span class=\"emochip\" style=\"background:${c}\">${esc(t.emotion.label_en)} ${esc(t.emotion.label_zh)} · ${Math.round((Number(t.emotion.intensity)||0)*100)}%</span>`;}\n        return `<div class=\"row me\" data-key=\"t${i}\"><div class=\"wrap\">${inner}${em}</div></div>`;\n      }\n      let src=t.sources&&t.sources.length?`<div class=\"src\">${t.sources.slice(0,4).map(s=>`<span class=\"chip\">${esc(s)}</span>`).join(\"\")}</div>`:\"\";\n      const isD=t.role===\"dispatcher\";const rl=isD?'<span class=\"rolelbl\">Dispatcher 调度员</span>':\"\";\n      return `<div class=\"row ai ${isD?\"dispatcher\":\"\"}\" data-key=\"t${i}\"><div class=\"wrap\"><div class=\"bub\">${rl}<div class=\"en\">${esc(t.en)}</div>${t.zh?`<div class=\"zh\">${esc(t.zh)}</div>`:\"\"}${src}</div></div></div>`;\n    }).join(\"\");\n    const typing=st.busy?`<div class=\"row ai\" data-key=\"typing\"><div class=\"wrap\"><div class=\"bub\"><span class=\"typing\"><i></i><i></i><i></i></span></div></div></div>`:\"\";\n    let done=\"\";\n    if(st.done&&st.incident){const c=st.incident;const cs=dstat(c);const csl=SL[cs]||[\"\",\"\"];const cc=SC[cs]||\"#34c759\";\n      done=`<div class=\"done\" data-key=\"done\"><h4>✓ Incident filed · 已建立警情 #${String(c._id||\"\").slice(-5)}</h4><div style=\"margin:8px 0 4px\"><span style=\"background:${cc}22;color:${cc};font-size:11px;font-weight:700;padding:3px 9px;border-radius:8px\">${csl[0]} · ${csl[1]}</span> <span style=\"font-size:11px;color:#8a8a8e\">live status · 实时状态</span></div><div class=\"kv\"><span class=\"k\">Location 位置</span><span class=\"v\">${esc(c.locationText||\"\")}</span><span class=\"k\">Type 类型</span><span class=\"v\">${esc(c.fireType||\"\")}</span><span class=\"k\">Severity 级别</span><span class=\"v\">${esc(c.severity||\"\")}</span><span class=\"k\">Trapped 被困</span><span class=\"v\">${esc(c.peopleTrapped||\"\")}</span><span class=\"k\">Hazards 危险</span><span class=\"v\">${esc(c.hazards||\"—\")}</span><span class=\"k\">Coordinates 坐标</span><span class=\"v\">${(Number(c.lat)||0).toFixed(4)}, ${(Number(c.lng)||0).toFixed(4)}</span></div><div class=\"cminimap\" data-d2-static></div><div class=\"cmstatus\"><span class=\"dotp\"></span><span class=\"cmtxt\">${esc(cmReadout(c).txt)}</span></div></div>`;\n    }\n    const SR=(typeof window!==\"undefined\")&&(window.SpeechRecognition||window.webkitSpeechRecognition);\n    const voiceOut=st.voiceOut===true;\n    const canVid=!!st.incidentId&&(typeof navigator!==\"undefined\")&&navigator.mediaDevices;\n    const vs=st.vstats||{};const dbgBlock=st.videoOn?`<button class=\"vdbgbtn\">🐞 ${st.vdbgOn?\"hide debug\":\"debug\"}</button>${st.vdbgOn?`<pre class=\"vdbg\">me: ${esc(vs.me||\"-\")}  inc: ${esc(vs.inc||\"-\")}\nstatus: ${esc(st.vidStatus||\"-\")}\\ntracks: ${esc(vs.tracks||\"-\")}  sig: ${esc(vs.sig||\"-\")}\\nice: ${esc(vs.ice||\"-\")}  conn: ${esc(vs.conn||\"-\")}\\ngather: ${esc(vs.gather||\"-\")}\\ncandidates: ${esc(vs.cand||\"(none yet - TURN?)\")}\\n---\\n${esc((st.vlog||[]).join(\"\\n\"))}</pre>`:\"\"}`:\"\";\n    const vidUI=canVid?`<div class=\"vidwrap\">${st.videoOn?`<video class=\"selfvid\" autoplay playsinline muted></video><div class=\"vidrow\"><span class=\"livepill\">🔴 ${esc(st.vidStatus||\"You are live 您正在直播\")}</span><button class=\"vidbtn stop\">⏹ Stop · 结束直播</button></div>${dbgBlock}`:`<button class=\"vidbtn\">📹 Turn on live video · 开启视频</button>`}</div>`:\"\";\n    const humanUI=st.humanControl?`<div class=\"humanbanner\">✋ A human dispatcher has joined · 人工调度员已接入</div>`:\"\";\n    return `<div class=\"page\">${splash}<div class=\"app\"><div class=\"hdr\"><div class=\"brandrow\"><div class=\"badge\">🚒</div><div><div class=\"ttl\">Report a Fire · 报告火灾</div><div class=\"sub\">Wuhan Fire Brigade · 武汉消防 · AI intake</div></div></div><div class=\"toolbar\"><div class=\"seg\"><button class=\"lang\" data-l=\"en\" ${lang===\"en\"?\"data-on\":\"\"}>EN</button><button class=\"lang\" data-l=\"zh\" ${lang===\"zh\"?\"data-on\":\"\"}>中文</button></div><button class=\"spk\" ${voiceOut?\"data-on\":\"\"}>${voiceOut?\"🔊 Voice\":\"🔇 Muted\"}</button></div></div>${humanUI}<div class=\"log\">${bubbles}${typing}${done}</div>${vidUI}<div class=\"bar\"><button class=\"icon cam\" ${st.busy||st.photoBusy?\"disabled\":\"\"}>${st.photoBusy?\"⏳\":\"📷\"}</button>${SR?`<button class=\"icon mic ${st.listening?\"live\":\"\"}\" ${st.busy?\"disabled\":\"\"}>🎤</button>`:\"\"}<input class=\"file\" type=\"file\" accept=\"image/*\" capture=\"environment\"/><textarea class=\"txt\" rows=\"1\" placeholder=\"${st.listening?(lang===\"zh\"?\"聆听中…\":\"Listening…\"):(lang===\"zh\"?\"描述火情…\":\"Describe the fire…\")}\" ${st.busy?\"disabled\":\"\"}></textarea><button class=\"send\" ${st.busy?\"disabled\":\"\"}>↑</button></div></div></div>`;\n  },\n  mounted(d2){\n    if(!d2.state.turns){d2.state.turns=[{role:\"agent\",en:\"Fire Brigade AI here. What is burning, and where in Wuhan? You can type, speak, or attach a photo.\",zh:\"武汉消防 AI。请问哪里着火了？是什么在燃烧？您可以打字、语音或上传照片。\"}];d2.state.lang=\"en\";d2.state.emotions=[];d2.state.splash=true;d2.state.voiceOut=false;}\n    setTimeout(()=>{d2.state.splash=false;},2300);\n    const refreshMine=async()=>{if(!d2.state.incidentId)return;try{const r=un(await d2.rush(\"fire_list\").invoke({}));const items=(r&&r.items)||[];const mine=items.find(i=>i._id===d2.state.incidentId);if(mine){d2.state.incident=mine;d2.state.humanControl=mine.humanControl===true;if(mine.transcript)d2.state.serverTranscript=mine.transcript;const seen=d2.state.seenDisp||{};let added=false;const tt=[...(d2.state.turns||[])];(mine.transcript||[]).forEach(m=>{if(m.role===\"dispatcher\"&&!seen[m.t]){seen[m.t]=1;tt.push({role:\"dispatcher\",en:m.translated||m.en||m.raw||\"\",zh:\"\"});added=true;}});if(added){d2.state.turns=tt;d2.state.seenDisp=seen;}}}catch(e){}};\n    let sock=null,pc=null,localStream=null,selfIv=null,sigSince=\"\";const myId=\"cit-\"+Math.random().toString(36).slice(2,8);\n    const setStat=(k,v)=>{d2.state.vstats={...(d2.state.vstats||{}),[k]:v};};setStat(\"me\",myId);\n    const vlog=(s)=>{const ln=new Date().toISOString().slice(11,19)+\" \"+s;try{console.log(\"[CIT-RTC]\",ln);}catch(e){}d2.state.vlog=[...((d2.state.vlog||[]).slice(-11)),ln];};\n    const emitSig=(p)=>{try{p.from=myId;d2.rush(\"fire_signal\").invoke(p);vlog(\"→ \"+p.t+\" (via server)\");}catch(e){vlog(\"emit ERR \"+(e&&e.message));}};\n    const closePc=()=>{try{if(pc)pc.close();}catch(e){}pc=null;};\n    const wirePc=(incId)=>{let host=0,srflx=0,relay=0;pc.onicecandidate=(e)=>{if(e.candidate){const cc=e.candidate.candidate||\"\";const ty=cc.indexOf(\"typ relay\")>=0?\"relay\":cc.indexOf(\"typ srflx\")>=0?\"srflx\":\"host\";if(ty===\"relay\")relay++;else if(ty===\"srflx\")srflx++;else host++;setStat(\"cand\",`host:${host} srflx:${srflx} relay:${relay}`);emitSig({sig:true,incidentId:incId,t:\"ice\",role:\"caller\",c:e.candidate});}};pc.oniceconnectionstatechange=()=>{setStat(\"ice\",pc.iceConnectionState);vlog(\"ice=\"+pc.iceConnectionState);};pc.onconnectionstatechange=()=>{setStat(\"conn\",pc.connectionState);vlog(\"conn=\"+pc.connectionState);};pc.onicegatheringstatechange=()=>{setStat(\"gather\",pc.iceGatheringState);};};\n    const makeOfferFor=async()=>{const incId=d2.state.incidentId;if(!localStream||!incId)return;closePc();try{pc=new RTCPeerConnection({iceServers:ICE});localStream.getTracks().forEach(t=>pc.addTrack(t,localStream));setStat(\"tracks\",localStream.getTracks().map(t=>t.kind).join(\"+\"));wirePc(incId);const o=await pc.createOffer();await pc.setLocalDescription(o);setStat(\"sig\",pc.signalingState);emitSig({sig:true,incidentId:incId,t:\"offer\",role:\"caller\",sdp:o});vlog(\"offer sent (\"+localStream.getTracks().length+\" tracks)\");}catch(e){d2.state.vidStatus=\"WebRTC error 连接错误\";vlog(\"offer ERR \"+(e&&e.message));}};\n    const onSig=async(p)=>{if(!p||!p.sig||p.incidentId!==d2.state.incidentId||p.role===\"caller\")return;if(!d2.state.videoOn)return;vlog(\"← \"+p.t);try{if(p.t===\"watch-request\"){await makeOfferFor();}else if(p.t===\"answer\"&&pc){await pc.setRemoteDescription(p.sdp);vlog(\"remote answer set\");}else if(p.t===\"ice\"&&pc&&p.c){try{await pc.addIceCandidate(p.c);}catch(e){}}}catch(e){vlog(\"onSig ERR \"+(e&&e.message));}};\n    const startCam=async()=>{const incId=d2.state.incidentId;if(!incId||!(navigator&&navigator.mediaDevices)){d2.state.videoOn=true;d2.state.vidStatus=\"Camera unavailable 摄像头不可用\";return;}try{localStream=await navigator.mediaDevices.getUserMedia({video:true,audio:true});}catch(e){d2.state.videoOn=true;d2.state.vidStatus=\"Camera blocked 摄像头被拒绝\";return;}d2.state.videoOn=true;d2.state.vidStatus=\"You are live 您正在直播\";setStat(\"inc\",String(incId).slice(-6));vlog(\"GO LIVE me=\"+myId+\" inc=\"+incId);sigSince=new Date(Date.now()-20000).toISOString();try{d2.rush(\"fire_save\").invoke({record:{_id:incId,liveVideo:true,liveId:incId}});}catch(e){}emitSig({sig:true,incidentId:incId,t:\"announce\",role:\"caller\"});if(selfIv)clearInterval(selfIv);selfIv=setInterval(()=>{try{const v=d2.$(\".selfvid\");if(v&&localStream&&v.srcObject!==localStream)v.srcObject=localStream;}catch(e){}},500);};\n    const stopCam=()=>{const incId=d2.state.incidentId;try{if(localStream)localStream.getTracks().forEach(t=>{try{t.stop();}catch(e){}});}catch(e){}localStream=null;closePc();if(selfIv){clearInterval(selfIv);selfIv=null;}d2.state.videoOn=false;d2.state.vidStatus=\"\";try{if(incId)d2.rush(\"fire_save\").invoke({record:{_id:incId,liveVideo:false}});}catch(e){}try{if(incId)emitSig({sig:true,incidentId:incId,t:\"end\",role:\"caller\"});}catch(e){}};\n    d2.onUnmount(()=>{try{if(localStream)localStream.getTracks().forEach(t=>t.stop());}catch(e){}closePc();if(selfIv)clearInterval(selfIv);});\n    try{sock=d2.socket(\"feed\");sock.subscribe(\"wuhan\");sock.onMessage((m)=>{const p=(m&&m.data!==undefined)?m.data:m;const room=(m&&(m.room||m.channel))||\"wuhan\";if(d2.state.videoOn){vlog(\"recv[\"+room+\"] \"+((p&&p.sig)?(\"sig/\"+(p.t||\"?\")):\"incident\")+((p&&p.incidentId)?(\" inc=\"+String(p.incidentId).slice(-5)):\"\")+((p&&p.from)?(\" from=\"+p.from):\"\"));}if(p&&p.sig){if(p.from===myId)return;onSig(p);}else{refreshMine();}});}catch(e){}\n    d2.on(\".vidbtn\",\"click\",()=>{if(d2.state.videoOn){stopCam();}else{startCam();}});\n    d2.on(\".vdbgbtn\",\"click\",()=>{d2.state.vdbgOn=!d2.state.vdbgOn;});\n    const mineIv=setInterval(refreshMine,1500);d2.onUnmount(()=>clearInterval(mineIv));const sigPoll=async()=>{if(!d2.state.videoOn||!d2.state.incidentId)return;try{const r=un(await d2.rush(\"fire_signal_poll\").invoke({incidentId:d2.state.incidentId,since:sigSince||\"\"}));const items=(r&&r.items)||[];if(r&&r.now)sigSince=r.now;items.forEach(row=>{const p=(row&&row.body)?row.body:row;if(!p||!p.sig||p.from===myId)return;vlog(\"poll← \"+p.t+(p.from?(\" from=\"+p.from):\"\"));onSig(p);});}catch(e){}};const sigIv=setInterval(sigPoll,1000);d2.onUnmount(()=>clearInterval(sigIv));\n    const fetchStations=async()=>{try{const r=un(await d2.rush(\"fire_stations\").invoke({}));d2.state.stations=(r&&r.items)||[];}catch(e){}};\n    fetchStations();\n    let mmap=null,mL=null,mbuilt=false,mInc=null,mSquad=null,mRoute=null;\n    const buildMini=()=>{if(mbuilt)return;const c=d2.state.incident;if(!(d2.state.done&&c&&Number.isFinite(c.lat)&&c.lat>10))return;let LL=null;try{LL=d2.lib(LEAF);}catch(e){}const el=d2.$(\".cminimap\");if(!(LL&&el))return;LL=(LL&&LL.default)||LL;mL=LL;try{mmap=LL.map(el,{zoomControl:false,attributionControl:false,scrollWheelZoom:false}).setView([c.lat,c.lng],14);LL.tileLayer(\"https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png\",{subdomains:\"abcd\",maxZoom:19,attribution:\"© OpenStreetMap © CARTO\"}).addTo(mmap);const ic=LL.divIcon({className:\"\",iconSize:[26,26],iconAnchor:[13,13],html:`<div class=\\\"lpin act\\\" style=\\\"--c:#ff3b30\\\"><span class=\\\"ring\\\"></span><span class=\\\"core\\\">🔥</span></div>`});mInc=LL.marker([c.lat,c.lng],{icon:ic}).addTo(mmap);mbuilt=true;setTimeout(()=>{try{mmap.invalidateSize();}catch(e){}},250);}catch(e){}};\n    const miniIv=setInterval(()=>{if(!mbuilt){buildMini();return;}const c=d2.state.incident;if(!c)return;const st=(d2.state.stations||[]).find(s=>s._id===c.assignedStationId);if(c.dispatchedAt&&st){if(!mRoute){try{mRoute=mL.polyline([[st.lat,st.lng],[c.lat,c.lng]],{color:\"#0a84ff\",weight:2,dashArray:\"4 6\",opacity:.6}).addTo(mmap);}catch(e){}}if(!mSquad){try{const sic=mL.divIcon({className:\"\",iconSize:[26,26],iconAnchor:[13,13],html:`<div class=\\\"lsquad\\\"><span class=\\\"veh\\\">🚒</span></div>`});mSquad=mL.marker([st.lat,st.lng],{icon:sic}).addTo(mmap);}catch(e){}}}},1000);\n    d2.onUnmount(()=>clearInterval(miniIv));\n    d2.raf(()=>{if(!mbuilt||!mSquad)return;const c=d2.state.incident;if(!c||!c.dispatchedAt)return;const st=(d2.state.stations||[]).find(s=>s._id===c.assignedStationId);if(!st)return;const e=Date.now()-c.dispatchedAt;let p=e<=1500?0:(e>=11000?1:(e-1500)/9500);const la=st.lat+(c.lat-st.lat)*ease(p);const lo=st.lng+(c.lng-st.lng)*ease(p);try{mSquad.setLatLng([la,lo]);}catch(e2){}});\n    const speak=(res)=>{try{if(d2.state.voiceOut===true&&typeof window!==\"undefined\"&&window.speechSynthesis){const txt=d2.state.lang===\"zh\"?(res.reply_zh||\"\"):(res.reply_en||\"\");if(!txt)return;const u=new SpeechSynthesisUtterance(txt);u.lang=d2.state.lang===\"zh\"?\"zh-CN\":\"en-US\";u.rate=1.02;window.speechSynthesis.cancel();window.speechSynthesis.speak(u);}}catch(e){}};\n    const send=async(text)=>{\n      const msg=(text||\"\").trim();if(!msg||d2.state.busy)return;\n      const photo=d2.state.photoUrl||null,vision=d2.state.vision||null,pAnalysis=d2.state.photoAnalysis||null,pAddress=d2.state.photoAddress||null;\n      const turns=[...(d2.state.turns||[])];\n      turns.push({role:\"reporter\",en:msg,photo:photo,vision:vision});\n      d2.state.turns=turns;d2.state.busy=true;\n      // clear pending attachment so it does NOT leak onto the next message's bubble\n      d2.state.vision=null;d2.state.photoUrl=null;d2.state.photoAnalysis=null;d2.state.photoAddress=null;\n      const history=turns.map(t=>({role:t.role,text:t.role===\"reporter\"?t.en:`${t.en} / ${t.zh||\"\"}`}));\n      history.pop();\n      try{\n        const res=un(await d2.rush(\"fire_chat\").invoke({message:msg,history:history,lang:d2.state.lang,incidentId:d2.state.incidentId||null,emotions:d2.state.emotions||[],transcript:d2.state.serverTranscript||[],humanControl:d2.state.humanControl===true,photoUrl:photo,photoAnalysis:pAnalysis,photoAddress:pAddress}));\n        if(res.incidentId)d2.state.incidentId=res.incidentId;\n        if(res.transcript)d2.state.serverTranscript=res.transcript;\n        if(res.humanControl!==undefined)d2.state.humanControl=res.humanControl===true;\n        if(res.emotion)d2.state.emotions=[...(d2.state.emotions||[]),res.emotion];\n        const t2=[...d2.state.turns];\n        if(res.emotion){for(let i=t2.length-1;i>=0;i--){if(t2[i].role===\"reporter\"){t2[i]={...t2[i],emotion:res.emotion};break;}}}\n        if(res.reply_en||res.reply_zh){t2.push({role:\"agent\",en:res.reply_en||\"\",zh:res.reply_zh||\"\",sources:res.sources});}\n        d2.state.turns=t2;\n        if(res.done){d2.state.done=true;d2.state.incident=res.incident;d2.state.photoUrl=null;d2.state.photoAnalysis=null;d2.state.photoAddress=null;}\n        speak(res);\n      }catch(e){const t2=[...d2.state.turns];t2.push({role:\"agent\",en:\"Connection error, please retry.\",zh:\"连接错误，请重试。\"});d2.state.turns=t2;}\n      d2.state.busy=false;\n    };\n    let recog=null;\n    const toggleVoice=()=>{\n      const SR=window.SpeechRecognition||window.webkitSpeechRecognition;if(!SR)return;\n      if(d2.state.listening){if(recog){try{recog.stop();}catch(e){}}d2.state.listening=false;return;}\n      try{recog=new SR();}catch(e){return;}\n      recog.lang=d2.state.lang===\"zh\"?\"zh-CN\":\"en-US\";recog.interimResults=true;recog.continuous=false;\n      recog.onresult=(e)=>{let txt=\"\";for(let i=0;i<e.results.length;i++){txt+=e.results[i][0].transcript;}const el=d2.$(\".txt\");if(el)el.value=txt;const last=e.results[e.results.length-1];if(last&&last.isFinal){d2.state.listening=false;const v=txt;if(el)el.value=\"\";send(v);}};\n      recog.onerror=()=>{d2.state.listening=false;};recog.onend=()=>{if(d2.state.listening)d2.state.listening=false;};\n      d2.state.listening=true;try{recog.start();}catch(e){d2.state.listening=false;}\n    };\n    d2.on(\".send\",\"click\",()=>{const el=d2.$(\".txt\");const v=el.value;el.value=\"\";send(v);});\n    d2.on(\".txt\",\"keydown\",(e,el)=>{if(e.key===\"Enter\"&&!e.shiftKey){e.preventDefault();const v=el.value;el.value=\"\";send(v);}});\n    d2.on(\".lang\",\"click\",(e,el)=>{d2.state.lang=el.dataset.l;});\n    d2.on(\".spk\",\"click\",()=>{d2.state.voiceOut=d2.state.voiceOut===false;if(d2.state.voiceOut===false&&window.speechSynthesis)window.speechSynthesis.cancel();});\n    d2.on(\".mic\",\"click\",()=>{toggleVoice();});\n    d2.on(\".cam\",\"click\",()=>{const f=d2.$(\".file\");if(f)f.click();});\n    d2.on(\".file\",\"change\",async(e,el)=>{\n      const f=el.files&&el.files[0];if(!f)return;\n      d2.state.photoBusy=true;\n      d2.state.turns=[...(d2.state.turns||[]),{role:\"reporter\",en:(d2.state.lang===\"zh\"?\"[上传照片中…]\":\"[Uploading photo…]\"),visionLoading:true}];\n      let dataUrl=\"\";try{dataUrl=await new Promise((res,rej)=>{const fr=new FileReader();fr.onload=()=>res(fr.result);fr.onerror=()=>rej(new Error(\"read\"));fr.readAsDataURL(f);});}catch(err){dataUrl=\"\";}\n      let url=\"\",analysis=null;\n      try{const out=await d2.drive(\"media\").uploadFromFiles([f]);url=(out&&out[0]&&out[0].fileUrl)||\"\";}catch(err){url=\"\";}\n      d2.state.photoUrl=url||null;\n      const imgV=dataUrl||url;\n      try{console.log(\"[CIT-PHOTO] dataUrl len:\",(dataUrl||\"\").length,\"driveUrl:\",url);}catch(e){}\n      if(imgV){try{analysis=await Promise.race([d2.assistant(\"fireVision\").ask(\"Analyze this fire-scene photo and read ALL visible text — street signs, road names, shop/building names, plates, landmarks (Chinese and English). Return your JSON object including extractedAddress and textSeen.\",{images:[imgV],json:true}),new Promise((_,rej)=>setTimeout(()=>rej(new Error(\"timeout\")),25000))]);}catch(err){analysis=null;}}\n      try{console.log(\"[CIT-PHOTO] vision result:\",analysis);}catch(e){}\n      let ocrText=\"\";if(url){try{const orr=un(await d2.rush(\"fire_ocr\").invoke({url:url}));ocrText=(orr&&orr.ocrText)||\"\";}catch(err){ocrText=\"\";}}\n      try{console.log(\"[CIT-PHOTO] OCR text:\",ocrText);}catch(e){}\n      const visAddr=(analysis&&typeof analysis===\"object\"&&analysis.extractedAddress)?analysis.extractedAddress:\"\";\n      d2.state.photoAddress=visAddr||ocrText||\"\";\n      try{console.log(\"[CIT-PHOTO] photoAddress =>\",d2.state.photoAddress);}catch(e){}\n      const t2=[...d2.state.turns];for(let i=t2.length-1;i>=0;i--){if(t2[i].visionLoading){t2[i]={role:\"reporter\",en:((url||dataUrl)?(d2.state.lang===\"zh\"?\"[火灾照片]\":\"[Fire photo]\"):(d2.state.lang===\"zh\"?\"[照片上传失败]\":\"[Photo upload failed]\")),photo:url||dataUrl||null,vision:(analysis&&typeof analysis===\"object\")?analysis:null};break;}}d2.state.turns=t2;\n      if(analysis&&typeof analysis===\"object\"){d2.state.vision=analysis;d2.state.photoAnalysis=`whatsBurning=${analysis.whatsBurning}; fireType=${analysis.fireType}; severity=${analysis.severity}; smoke=${analysis.smoke}; peopleVisible=${analysis.peopleVisible}; hazards=${analysis.hazards}; address=${d2.state.photoAddress||\"n/a\"}; signage=${ocrText||\"n/a\"}; ${analysis.summary_en||\"\"} / ${analysis.summary_zh||\"\"}`;}\n      else if(url||dataUrl){d2.state.photoAnalysis=`Photo attached. Signage read: ${ocrText||\"none\"} / 已附照片，识别到标识：${ocrText||\"无\"}`;}\n      else{d2.state.photoAnalysis=\"\";}\n      d2.state.photoBusy=false;el.value=\"\";\n      send((url||dataUrl)?(d2.state.lang===\"zh\"?\"我上传了一张火灾现场照片，请参考。\":\"I attached a photo of the fire scene, please use it.\"):(d2.state.lang===\"zh\"?\"我尝试上传照片但没成功。\":\"I tried to attach a photo but it didn't upload.\"));\n    });\n  },\n  updated(d2){const log=d2.$(\".log\");if(log)log.scrollTop=log.scrollHeight;},\n};","at":"2026-07-22T08:48:26.917Z"}}},{"_id":"5ed9bed7b9e0891ce913e884","component":"data2-core-types@Component","params":{"package":"data2-core","component":"DataSource","renderable":{"dimensions":{"disabled":false,"component":"data2-core-types@Dimensions","params":{"width":1366,"exactWidth":false,"exactHeight":false,"height":768}}}}},{"_id":"5f472ae463c680de4ff296e9","component":"data2-core-types@Component","params":{"package":"data2-core","component":"Data2TableDataSource","extends":"data2-core@DataSource","renderable":{"dimensions":{"disabled":false,"component":"data2-core-types@Dimensions","params":{"width":1366,"exactWidth":false,"exactHeight":false,"height":768}}}}}]}},{"reference":"ExternalComponentInstancesTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"_id":"5f060d9b1ca96def42f3c40a","displayName":"Builder AuthStrategy","component":"data2-core@AuthenticationStrategy","system":"5e3b796d6228227ca637d0f4","params":{"credentials":[{"component":"data2-core-types@DataSetColumnReference","params":{"column":"email"}},{"component":"data2-core-types@DataSetColumnReference","params":{"column":"password"}},{"component":"data2-core-types@DataSetColumnReference","params":{"column":"status"}}],"verifier":{"component":"data2-core-types@DataSetReference","params":{"reference":"UsersDataSet"}},"sessionShared":{"component":"data2-core-primitives@Boolean","params":{"content":false}},"password":{"disabled":false,"component":"data2-core-types@DataSetColumnReference","params":{"column":"password"}},"email":{"disabled":false,"component":"data2-core-types@DataSetColumnReference","params":{"column":"email"}},"resetPassword":{"resetEmail":{"artboard":{"params":{"preventEvaluation":true,"reference":"nR6Q9d7qdaPtZhJ28Q8Dy"},"component":"data2-core-types@ArtboardReference"}},"resetSuccessEmail":{"artboard":{"params":{"preventEvaluation":true,"reference":"yPCJBTKo8q1Mw0B_3Kpwl"},"component":"data2-core-types@ArtboardReference"}}},"session":[{"component":"data2-core-types@DataSetColumnReference","params":{"column":"name"}},{"component":"data2-core-types@DataSetColumnReference","params":{"column":"email"}},{"component":"data2-core-types@DataSetColumnReference","params":{"column":"password"}},{"component":"data2-core-types@DataSetColumnReference","params":{"column":"status"}}],"sessionMetadata":{"params":{"actions":[{"params":{"compare":{"params":{"subject":{"params":{"components":[{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$user._id"}}}},{"params":{"comparisonSubject":{"component":"data2-core-primitives@String","params":{"content":"active"}},"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$user.status"}}}}},"component":"data2-core-comparison-operators@Equal","displayName":"is active user"}]},"component":"data2-core-logical-operators@And","displayName":"is active and has _id"}},"component":"data2-core-logical-operators@Not"},"then":{"params":{"message":{"component":"data2-core-primitives@String","params":{"content":"Invalid Credentials"}},"code":{"component":"data2-core-primitives@String","params":{"content":"401"}}},"component":"data2-core-types@Error"}},"component":"data2-core-flow@If","displayName":"check $user"},{"params":{"action":{"params":{"pattern":{"component":"data2-core-primitives@String","params":{"content":"@data2.app"}},"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$user.email"}}}}},"component":"data2-core-functions@Includes","displayName":"isData2User"},"resultName":{"component":"data2-core-primitives@String","params":{"content":"is_data2_user"}}},"component":"data2-core-flow@Step"},{"params":{"action":{"params":{"pattern":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$metadata.d2_app"}}}},"subject":[{"component":"data2-core-primitives@String","params":{"content":"management"}}]},"component":"data2-core-functions@Includes","displayName":"isData2App Exception"},"resultName":{"component":"data2-core-primitives@String","params":{"content":"is_data2_app_exception"}}},"component":"data2-core-flow@Step"},{"params":{"resultName":{"component":"data2-core-primitives@String","params":{"content":"has_access"}},"action":{"params":{"compare":{"params":{"components":[{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"is_data2_user"}}}},{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"is_data2_app_exception"}}}}]},"component":"data2-core-logical-operators@Or"},"else":{"params":{"actions":[{"params":{"actions":[{"params":{"compare":{"params":{"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$metadata.system"}}}}},"component":"data2-core-logical-operators@Not"},"then":{"params":{"message":{"component":"data2-core-primitives@String","params":{"content":"Invalid Credentials"}},"code":{"component":"data2-core-primitives@String","params":{"content":"401"}}},"component":"data2-core-types@Error"}},"component":"data2-core-flow@If","displayName":"check $metadata.system"},{"params":{"module":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"WuUa-VKHhW9uYU0E3-mJ8"}},"prop":"filter","args":[{"_id":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$metadata.system"}}}}}]},"component":"data2-core-types@Interaction"},{"params":{"compare":{"params":{"subject":{"component":"data2-core-types@Getter","params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"WuUa-VKHhW9uYU0E3-mJ8"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"data.records.length"}}}}},"component":"data2-core-logical-operators@Not","displayName":"systems not found"},"then":{"params":{"message":{"component":"data2-core-primitives@String","params":{"content":"Invalid Credentials"}},"code":{"component":"data2-core-primitives@String","params":{"content":"401"}}},"component":"data2-core-types@Error"}},"component":"data2-core-flow@If","displayName":"check system found"},{"params":{"actions":[{"params":{"module":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"Ok6Tsu5XkS7r8PyW_7TyW"}},"prop":"filter","args":[{"user":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$user._id"}}}},"organization":{"component":"data2-core-types@Getter","params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"WuUa-VKHhW9uYU0E3-mJ8"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"cursor.current.organization._id"}}}}}]},"component":"data2-core-types@Interaction"},{"params":{"module":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"NqKAY34n2ffFL64zamp7t"}},"prop":"filter","args":[{"user":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$user._id"}}}},"system":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$metadata.system"}}}}}]},"component":"data2-core-types@Interaction"}]},"component":"data2-core-flow@Parallel"}]},"component":"data2-core-flow@Series","displayName":"common setup"},{"params":{"then":{"params":{"content":true},"component":"data2-core-primitives@Boolean"},"else":{"params":{"content":false},"component":"data2-core-primitives@Boolean"},"compare":{"params":{"components":{"params":{"array":{"params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"WuUa-VKHhW9uYU0E3-mJ8"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"data.records"}}},"component":"data2-core-types@Getter"},"mapper":{"disabled":false,"component":"data2-core-functions@Function","params":{"parameters":[{"component":"data2-core-primitives@String","params":{"content":"system"}}],"body":{"params":{"expression":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"system.visibility"}}}},"defaultCase":{"params":{"content":false},"component":"data2-core-primitives@Boolean"},"cases":[{"component":"data2-core-flow@Case","params":{"expression":{"component":"data2-core-primitives@String","params":{"content":"public"}},"value":{"params":{"components":[{"params":{"array":{"params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"Ok6Tsu5XkS7r8PyW_7TyW"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"data.records"}}},"component":"data2-core-types@Getter"},"filter":{"disabled":false,"component":"data2-core-functions@Function","params":{"parameters":[{"component":"data2-core-primitives@String","params":{"content":"member"}}],"body":{"params":{"components":[{"params":{"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"member.organization._id"}}}},"comparisonSubject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"system.organization._id"}}}}},"component":"data2-core-comparison-operators@Equal","displayName":"is org member"},{"params":{"pattern":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"member.role"}}}},"subject":[{"component":"data2-core-primitives@String","params":{"content":"owner"}},{"component":"data2-core-primitives@String","params":{"content":"billing-owner"}},{"component":"data2-core-primitives@String","params":{"content":"admin"}},{"component":"data2-core-primitives@String","params":{"content":"member"}}]},"component":"data2-core-functions@Includes","displayName":"has role with access"}]},"component":"data2-core-logical-operators@And","displayName":"has org member role with access"}}}},"component":"data2-core-functions@ArrayFind","displayName":"is org member"},{"params":{"components":[{"params":{"array":{"params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"Ok6Tsu5XkS7r8PyW_7TyW"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"data.records"}}},"component":"data2-core-types@Getter"},"filter":{"disabled":false,"component":"data2-core-functions@Function","params":{"parameters":[{"component":"data2-core-primitives@String","params":{"content":"member"}}],"body":{"params":{"components":[{"params":{"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"member.organization._id"}}}},"comparisonSubject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"system.organization._id"}}}}},"component":"data2-core-comparison-operators@Equal","displayName":"is org member"},{"params":{"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"member.role"}}}},"comparisonSubject":{"component":"data2-core-primitives@String","params":{"content":"collaborator"}}},"component":"data2-core-comparison-operators@Equal","displayName":"is collaborator"}]},"component":"data2-core-logical-operators@And","displayName":"is org member and collaborator"}}}},"component":"data2-core-functions@ArrayFind","displayName":"is collaborator"},{"params":{"array":{"params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"NqKAY34n2ffFL64zamp7t"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"data.records"}}},"component":"data2-core-types@Getter"},"filter":{"disabled":false,"component":"data2-core-functions@Function","params":{"parameters":[{"component":"data2-core-primitives@String","params":{"content":"access"}}],"body":{"params":{"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"access.system._id"}}}},"comparisonSubject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"system._id"}}}}},"component":"data2-core-comparison-operators@Equal"}}}},"component":"data2-core-functions@ArrayFind","displayName":"has system access"}]},"component":"data2-core-logical-operators@And","displayName":"is collaborator and has system access"}]},"component":"data2-core-logical-operators@Or"}}},{"component":"data2-core-flow@Case","params":{"expression":{"component":"data2-core-primitives@String","params":{"content":"private"}},"value":{"params":{"components":[{"params":{"array":{"params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"Ok6Tsu5XkS7r8PyW_7TyW"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"data.records"}}},"component":"data2-core-types@Getter"},"filter":{"disabled":false,"component":"data2-core-functions@Function","params":{"parameters":[{"component":"data2-core-primitives@String","params":{"content":"member"}}],"body":{"params":{"components":[{"params":{"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"member.organization._id"}}}},"comparisonSubject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"system.organization._id"}}}}},"component":"data2-core-comparison-operators@Equal","displayName":"is org member"},{"params":{"pattern":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"member.role"}}}},"subject":[{"component":"data2-core-primitives@String","params":{"content":"owner"}},{"component":"data2-core-primitives@String","params":{"content":"admin"}}]},"component":"data2-core-functions@Includes","displayName":"is owner/admin"}]},"component":"data2-core-logical-operators@And","displayName":"has org member role with access"}}}},"component":"data2-core-functions@ArrayFind","displayName":"is owner/admin"},{"params":{"components":[{"params":{"array":{"params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"Ok6Tsu5XkS7r8PyW_7TyW"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"data.records"}}},"component":"data2-core-types@Getter"},"filter":{"disabled":false,"component":"data2-core-functions@Function","params":{"parameters":[{"component":"data2-core-primitives@String","params":{"content":"member"}}],"body":{"params":{"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"member.organization._id"}}}},"comparisonSubject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"system.organization._id"}}}}},"component":"data2-core-comparison-operators@Equal"}}}},"component":"data2-core-functions@ArrayFind","displayName":"is org member"},{"params":{"array":{"params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"NqKAY34n2ffFL64zamp7t"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"data.records"}}},"component":"data2-core-types@Getter"},"filter":{"disabled":false,"component":"data2-core-functions@Function","params":{"parameters":[{"component":"data2-core-primitives@String","params":{"content":"access"}}],"body":{"params":{"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"access.system._id"}}}},"comparisonSubject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"system._id"}}}}},"component":"data2-core-comparison-operators@Equal"}}}},"component":"data2-core-functions@ArrayFind","displayName":"has system access"}]},"component":"data2-core-logical-operators@And","displayName":"is member and has system access"}]},"component":"data2-core-logical-operators@Or","displayName":"is owner/admin or has system access"}}}]},"component":"data2-core-flow@Switch"}}}},"component":"data2-core-functions@ArrayMap"}},"component":"data2-core-logical-operators@And","displayName":"has org member for all systems in request"}},"component":"data2-core-flow@If"}]},"component":"data2-core-flow@Series"},"then":{"params":{"content":true},"component":"data2-core-primitives@Boolean"}},"component":"data2-core-flow@If"}},"component":"data2-core-flow@Step"},{"params":{"then":{"system":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$metadata.system"}}}}},"else":{"params":{"message":{"component":"data2-core-primitives@String","params":{"content":"Invalid Credentials"}},"code":{"component":"data2-core-primitives@String","params":{"content":"401"}}},"component":"data2-core-types@Error"},"compare":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"has_access"}}}}},"component":"data2-core-flow@If"}]},"component":"data2-core-flow@Series"},"sessionExpiresIn":{"component":"data2-core-primitives@Number","params":{"content":604800}},"sessionRenewal":{"component":"data2-core-primitives@Boolean","params":{"content":true}}},"reference":"Data2BuilderAuthentication","updatedAt":"2025-10-28T02:48:49.233Z"},{"_id":"5f060ee51ca96def42f3fbd1","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"UsersTableDataSource"}},"pagination":{"size":{"component":"data2-core-primitives@Number","params":{"content":1}}}},"reference":"UsersDataSet","updatedAt":"2026-03-04T21:16:40.291Z"},{"_id":"68f938cf5fb002e33752a43d","displayName":"InternalApplicationsAuthenticationStrategy","component":"data2-core@AuthenticationStrategy","system":"5e3b796d6228227ca637d0f4","params":{"resetPassword":{"resetEmail":{"artboard":{"params":{"preventEvaluation":true},"component":"data2-core-types@ArtboardReference"}},"resetSuccessEmail":{"artboard":{"params":{"preventEvaluation":true},"component":"data2-core-types@ArtboardReference"}}},"verifier":{"disabled":false,"component":"data2-core-types@DataSetReference","params":{"reference":"InternalApplicationsVerifierDataSet"}},"password":{"disabled":false,"component":"data2-core-types@DataSetColumnReference","params":{"column":"secret"}},"credentials":[{"component":"data2-core-types@FieldReference","params":{"key":"application"}},{"component":"data2-core-types@FieldReference","params":{"key":"secret"}},{"component":"data2-core-types@FieldReference","params":{"key":"status"}}],"session":[{"component":"data2-core-types@FieldReference","params":{"key":"application"}},{"component":"data2-core-types@FieldReference","params":{"key":"secret"}},{"component":"data2-core-types@FieldReference","params":{"key":"status"}}]},"reference":"InternalApplicationsAuthenticationStrategy","updatedAt":"2025-10-22T20:08:54.442Z","createdAt":"2025-10-22T20:04:31.198Z"},{"component":"data2-core@DataSet","reference":"SessionsDataSet","params":{"requiresConfirmation":false,"pk":"key","datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"data2sessionsdatasource"}}}},{"reference":"UsersTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"component":"data2-core@ServerSessionsDataSource","reference":"data2sessionsdatasource","params":{}},{"_id":"5f1600b70528b92601890f75","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"ServiceComponentInstancesTableDataSource"}},"pk":"_id","autoEdit":true,"master":{"params":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"_id"}}},"component":"data2-core-types@DataSetMaster"},"autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}},"policies":{"params":{"allowGet":{"component":"data2-core-primitives@Boolean","params":{"content":true}}},"component":"data2@hkXy-UhMjhyfptdE6_fpW"}},"reference":"ServiceComponentInstancesDataSet","updatedAt":"2025-11-06T21:07:20.208Z","createdAt":"2020-07-20T20:38:15.436Z"},{"_id":"5f1602190528b92601890f7d","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"pagination":{"size":40000},"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"ComponentInstancesTableDataSource"}},"sort":{"_id":1},"pk":"_id","autoEdit":true,"master":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"_id"}}},"autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}},"policies":{"params":{"allowGet":{"component":"data2-core-primitives@Boolean","params":{"content":true}}},"component":"data2@hkXy-UhMjhyfptdE6_fpW"}},"reference":"ComponentInstancesDataSet","updatedAt":"2025-11-06T21:07:07.089Z","createdAt":"2020-07-20T20:44:09.350Z"},{"_id":"5f16017f0528b92601890f7a","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"FileComponentInstancesTableDataSource"}},"pk":"_id","autoEdit":true,"filter":{"domain":{"component":"data2-core-types@Reference","params":{"reference":"clientApplicationDomain"}}},"master":{"params":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"_id"}}},"component":"data2-core-types@DataSetMaster"},"autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}}},"reference":"FileComponentInstancesDataSet","updatedAt":"2023-08-03T16:08:18.193Z","createdAt":"2020-07-20T20:41:35.797Z"},{"_id":"5f1601990528b92601890f7b","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"ApplicationsTableDataSource"}},"pk":"_id","autoEdit":{"component":"data2-core-primitives@Boolean","params":{"content":true}},"master":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"params":{"column":"_id"},"component":"data2-core-types@DataSetColumnReference"}},"autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}}},"reference":"ApplicationsDataSet","updatedAt":"2022-12-13T21:51:13.995Z","createdAt":"2020-07-20T20:42:01.657Z"},{"_id":"5f16172a0528b92601890f85","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"pagination":{"size":{"component":"data2-core-primitives@Number","params":{"content":10000}}},"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"DataComponentInstancesTableDataSource"}},"pk":"_id","autoEdit":true,"master":{"params":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"_id"}}},"component":"data2-core-types@DataSetMaster"},"autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}},"policies":{"params":{"allowGet":{"component":"data2-core-primitives@Boolean","params":{"content":true}}},"component":"data2@hkXy-UhMjhyfptdE6_fpW"}},"reference":"DataComponentInstancesDataSet","updatedAt":"2025-11-06T21:07:12.831Z","createdAt":"2020-07-20T22:14:02.097Z"},{"_id":"60ddc1bbda3861ca65407c5a","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"FileComponentInstancesTableDataSource"}},"pk":"_id","autoEdit":true,"filter":{"domain":{"component":"data2-core-types@Reference","params":{"reference":"clientApplicationDomain"}}},"pagination":{"size":1},"master":{"params":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"_id"}}},"component":"data2-core-types@DataSetMaster"}},"reference":"OneFileComponentInstancesDataSet","updatedAt":"2022-02-09T19:44:38.036Z","createdAt":"2020-07-20T20:41:35.797Z"},{"_id":"63ee3d38b8c9838c62fb05fb","displayName":"DriveFileComponentInstancesDataSet","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"FileComponentInstancesTableDataSource"}},"pk":"_id","autoEdit":true,"filter":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core@Drive"}}},"master":{"params":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"_id"}}},"component":"data2-core-types@DataSetMaster"},"autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}}},"reference":"DriveFileComponentInstancesDataSet","updatedAt":"2025-12-04T21:58:32.367Z","createdAt":"2023-02-16T14:27:07.797Z"},{"reference":"ServiceComponentInstancesTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[{"_id":"6a60418c0968c1e1d6f6abec","component":"data2-core-ai@Assistant","reference":"fireVision","system":"6a601c3c3a42b34509a601cf","params":{"model":"cerebras","_context":{"component":"data2-core-primitives@String","params":{"content":"You are a fire-scene photo analyst for the Wuhan fire brigade. You receive a photo that may show a fire. Analyze the image AND read any visible text/signage to extract WHERE it is. Respond with ONLY this JSON object:\n{\n  \"whatsBurning\": \"building | vehicle | vegetation | other | unclear\",\n  \"fireType\": \"building|vehicle|forest|other\",\n  \"severity\": \"Small / 小 | Medium / 中 | Large / 大\",\n  \"smoke\": \"short note on smoke color and volume\",\n  \"peopleVisible\": \"Yes / 是 | No / 否 | Unknown / 未知\",\n  \"hazards\": \"visible hazards such as gas, chemical, fuel or electrical, else 'none visible'\",\n  \"extractedAddress\": \"any location/address readable from the image — a street sign, shop or building name, road name, building number, plate region, or a recognizable landmark; empty string if none\",\n  \"textSeen\": \"any text or characters visible in the image (signage, banners, plates); empty string if none\",\n  \"summary_en\": \"one concise sentence describing the scene\",\n  \"summary_zh\": \"一句话描述现场\",\n  \"confidence\": \"low | medium | high\"\n}\nJudge severity from visible flame size, smoke volume and color, and the structures involved. Carefully READ any signs, shopfronts, road markings, license plates and landmarks to fill extractedAddress and textSeen. If the image does not show a fire, set whatsBurning to 'unclear'. Use empty strings when nothing is readable — never invent an address."}},"behaviour":"Output STRICTLY a single valid JSON object and nothing else. No markdown, no code fences, no text before or after the JSON.","creativity":15,"json":true}},{"_id":"6a604127d7643e7690f21493","component":"data2-rush@HTTPListener","reference":"fire_chat","system":"6a601c3c3a42b34509a601cf","params":{"enableExecutionLogs":true,"insertLogsDataSet":{"component":"data2-core-types@DataSetReference","params":{"reference":"fire_chatLogInsertDataSet"}},"readLogsDataSet":{"component":"data2-core-types@DataSetReference","params":{"reference":"fire_chatLogReadDataSet"}}}}]}},{"reference":"ComponentInstancesTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[{"_id":"6a6048da3a42b34509a660cd","component":"data2-core-primitives@Artboard","system":"6a601c3c3a42b34509a601cf","displayName":"Citizen Mobile","params":{"title":{"component":"data2-core-primitives@String","params":{"content":"Citizen Mobile"}},"dimensions":{"component":"data2-core-types@Dimensions","params":{"width":390,"height":844}},"position":{"component":"data2-core-types@Position","params":{"x":1778,"y":937,"exactX":1777.51,"exactY":937.07}}},"reference":"GcpOtkdwTbITJ67ZQsbRq"},{"_id":"af96bf8d8f09a21ec540ae43","parent":"6a6048da3a42b34509a660cd","component":"cict-ds@CitizenChat","system":"6a601c3c3a42b34509a601cf","displayName":"CitizenChat","params":{"chatApi":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"fire_chat"}},"vision":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"fireVision"}},"super":{"position":{"component":"data2-core-types@Position","params":{"x":0,"y":0,"freeTransform":true,"left":true,"right":true,"top":true,"bottom":true}},"dimensions":{"component":"data2-core-types@Dimensions","params":{"width":390,"height":844}}}},"reference":"TIW_nTNDpE4da1SwBBdQ6"}]}},{"_id":"5fc4faeec8da12be8bf3d08a","component":"data2-core@Data2TableDataSource","system":"5e3b796d6228227ca637d0f4","params":{"paginate":{"default":1000},"super":{},"table":"fileComponentInstances","schema":[{"component":"data2-core-types@Field","params":{"key":"component","title":"Component","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"system","title":"System","component":"data2-core-primitives@ObjectId"}},{"component":"data2-core-types@Field","params":{"key":"displayName","title":"Display Name","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"params","title":"Params","component":"data2-core-primitives@Object"}},{"component":"data2-core-types@Field","params":{"key":"reference","title":"Reference","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":{"component":"data2-core-primitives@String","params":{"content":"fileId"}},"title":"File ID","component":"data2-core-primitives@ObjectId"},"break":true}],"hooks":{"before":{"all":[{"hook":"softDelete"}],"find":[{"hook":"useCache","options":{"additionalGroupKeys":["$and.0.system","$and.1.system"],"skipCache":true}}],"create":[{"hook":"timestamp","options":{"fields":["createdAt","updatedAt"]}}],"update":[{"hook":"timestamp","options":{"fields":["updatedAt"]}}],"patch":[{"hook":"timestamp","options":{"fields":["updatedAt"]}}]},"after":{"all":[{"hook":"fileUrl","options":{"downloadField":"params.fileUrl","uploadField":"params.uploadFileUrl","enhanceSchema":false}}],"find":[{"hook":"useCache","options":{"additionalGroupKeys":["$and.0.system","$and.1.system"],"skipCache":true}}],"create":[{"hook":"invalidateCache","options":{"additionalGroupKeys":["system"],"secondaryUniqueKeys":["reference"]}},{"hook":"invalidateEnvCache"}],"update":[{"hook":"invalidateCache","options":{"additionalGroupKeys":["system"],"secondaryUniqueKeys":["reference"]}},{"hook":"invalidateEnvCache"}],"patch":[{"hook":"invalidateCache","options":{"additionalGroupKeys":["system"],"secondaryUniqueKeys":["reference"]}},{"hook":"invalidateEnvCache"}],"remove":[{"hook":"invalidateCache","options":{"additionalGroupKeys":["system"],"secondaryUniqueKeys":["reference"]}},{"hook":"invalidateEnvCache"}]}},"multi":["create"],"useEstimatedDocumentCount":true},"reference":"FileComponentInstancesTableDataSource","updatedAt":"2022-12-19T20:42:51.837Z","createdAt":"2020-11-30T13:59:52.294Z"},{"reference":"ApplicationsTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[{"_id":"6a6049273bba43b2373860df","displayName":"Report a Fire (Mobile)","reference":"Fgp-1tER_VxlTVHyCGUyM","params":{"name":{"component":"data2-core-primitives@String","params":{"content":"Report a Fire (Mobile)"}},"shortName":{"component":"data2-core-primitives@String","params":{"content":"Report a Fire (Mobile)"}},"domain":{"component":"data2-core-primitives@String","params":{"content":"m"}},"serverSideRendering":{"component":"data2-core-primitives@Boolean","params":{"content":true}},"entryPoint":{"component":"data2-core-types@ComponentInstanceReference","params":{"component":"data2-core-primitives@Artboard","reference":"GcpOtkdwTbITJ67ZQsbRq"}},"responseHeaders":{"X-Frame-Options":{"component":"data2-core-primitives@String","params":{"content":""}},"Content-Security-Policy":{"component":"data2-core-primitives@String","params":{"content":""}},"X-XSS-Protection":{"component":"data2-core-primitives@String","params":{"content":""}}}},"system":"6a601c3c3a42b34509a601cf","component":"data2-core-primitives@Application"}]}},{"reference":"DataComponentInstancesTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[{"_id":"6a6041260968c1e1d6f6ab2d","component":"data2-core@DataSet","system":"6a601c3c3a42b34509a601cf","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"d2-rush-http-logs--fire_chat"}},"pagination":{"size":20},"sort":{"_id":-1}},"reference":"fire_chatLogReadDataSet","type":"logs"},{"_id":"6a60412690bd4f023e301aea","component":"data2-core@DataSet","system":"6a601c3c3a42b34509a601cf","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"d2-rush-http-logs--fire_chat"}},"pagination":{"size":0}},"reference":"fire_chatLogInsertDataSet","type":"logs"},{"_id":"6a60412690bd4f023e301ae5","component":"data2-core@Data2TableDataSource","system":"6a601c3c3a42b34509a601cf","params":{"table":{"component":"data2-core-primitives@String","params":{"content":"d2-rush-http-logs--fire_chat"}},"multi":["create"],"useEstimatedDocumentCount":true},"reference":"d2-rush-http-logs--fire_chat","type":"logs"}]}},{"reference":"BundlesTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}}],"processesParams":{}}}}