{"context":{"domain":"cubbo-app"},"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":"2026-07-27T14:19:36.810Z"}]}},{"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},{"component":"data2-core-types@FieldReference","params":{"key":{"component":"data2-core-primitives@String","params":{"content":"settings.defaultAccessPolicy"}}},"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":"2026-08-07T21:51:24.037Z","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":"6a7ca6cb11f8a5ec77c18b42","name":"app","domain":"cubbo-app","visibility":"public","updatedAt":"2026-08-12T17:00:59.517Z","createdAt":"2026-08-12T17:00:59.517Z"}]}},{"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":"6a900eee104245c77f31beb1","component":"data2-core-types@Component","system":"6a7ca6cb11f8a5ec77c18b42","params":{"extends":"data2-core-primitives@Block","component":"cubbo-picking-station","package":"cubbo-app","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 GATE_PASSWORD = 'democubodata2';\nconst DRIVE_REF = 'JYUlmIJ1l58RmOJo0q161';\nconst CUBBO_KEY = 'cubbo_demo_2026_k7Rp9xQm';\nconst RUSH_OPTS = { headers: { 'x-api-key': CUBBO_KEY } };\nconst VIDEO_CANDIDATES = [\n  'video/mp4;codecs=avc1.42E01E',\n  'video/mp4',\n  'video/webm;codecs=vp9',\n  'video/webm',\n];\nfunction pickMimeType() {\n  if (!window.MediaRecorder) return '';\n  for (let i = 0; i < VIDEO_CANDIDATES.length; i++) {\n    try { if (MediaRecorder.isTypeSupported(VIDEO_CANDIDATES[i])) return VIDEO_CANDIDATES[i]; } catch (e) {}\n  }\n  return '';\n}\nfunction extFor(mime) { return (mime && mime.indexOf('mp4') !== -1) ? 'mp4' : 'webm'; }\nfunction gateRead() { try { return sessionStorage.getItem('cubboGateOk') === '1'; } catch (e) { return false; } }\nfunction gateWrite() { try { sessionStorage.setItem('cubboGateOk', '1'); } catch (e) {} }\nfunction isItemCode(code) { return /^[0-9]{13}$/.test(String(code || '').trim()); }\nfunction sumBy(list, key) {\n  return (list || []).reduce(function (a, i) { return a + (Number(i[key]) || 0); }, 0);\n}\nfunction pctOf(list) {\n  const exp = sumBy(list, 'expectedQty');\n  const got = sumBy(list, 'pickedQty');\n  return exp > 0 ? Math.round((got * 100) / exp) : 0;\n}\n\nconst LOGO_SVG = (color, h) => `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 91 32\" height=\"${h}\" style=\"color:${color}\"><path d=\"M56.6655 8.91406C57.5045 8.91406 58.2671 8.91406 59.106 8.91406C59.106 8.99025 59.106 9.14263 59.106 9.21882C59.106 10.6664 59.106 12.1141 59.106 13.6379C59.106 13.7141 59.106 13.7903 59.106 13.9426C59.1823 13.8664 59.2586 13.8664 59.2586 13.7903C59.945 13.0283 60.8601 12.6474 61.8516 12.5712C62.6905 12.495 63.5294 12.6474 64.2921 13.0283C65.5124 13.7141 66.4275 14.7807 66.8089 16.1522C67.1902 17.5998 67.1139 18.9712 66.3513 20.2664C65.7412 21.3331 64.9022 22.1712 63.682 22.5522C62.7668 22.8569 61.8516 22.8569 60.9364 22.5522C60.3263 22.3998 59.7924 22.0188 59.3348 21.5617C59.2586 21.4855 59.2586 21.4093 59.106 21.3331C59.0298 21.7141 59.106 22.095 59.106 22.476C58.2671 22.476 57.5045 22.476 56.6655 22.476C56.6655 18.0569 56.6655 13.4855 56.6655 8.91406ZM61.9279 20.495C62.6905 20.495 63.4532 20.1903 63.987 19.4283C64.3684 18.895 64.5209 18.2093 64.5209 17.5236C64.5209 16.9141 64.2921 16.3807 63.9108 15.9236C63.3007 15.1617 62.4617 14.8569 61.5465 15.0093C60.4788 15.0855 59.5636 15.8474 59.2586 16.9141C59.1823 17.295 59.106 17.676 59.1823 18.1331C59.3348 19.5045 60.4025 20.495 61.9279 20.495Z\" fill=\"currentColor\"/><path d=\"M68.8682 8.91406C69.6308 8.91406 70.4697 8.91406 71.3087 8.91406C71.3087 9.14263 71.3087 9.4474 71.3087 9.75216C71.3087 10.0569 71.3087 10.2855 71.3087 10.5903C71.3087 10.895 71.3087 11.1236 71.3087 11.4283C71.3087 11.7331 71.3087 11.9617 71.3087 12.2664C71.3087 12.5712 71.3087 12.7998 71.3087 13.1045C71.3087 13.4093 71.3087 13.6379 71.3087 13.9426C71.3849 13.8664 71.4612 13.7903 71.4612 13.7903C72.1476 13.0283 72.9865 12.6474 74.0542 12.5712C74.8932 12.495 75.7321 12.6474 76.4947 13.0283C77.9438 13.7903 78.7827 15.0093 79.0878 16.6855C79.3166 17.7522 79.2403 18.895 78.7827 19.8855C78.2489 21.1045 77.4099 22.0188 76.1134 22.5522C74.8932 23.0093 73.6729 23.0093 72.5289 22.3998C72.1476 22.2474 71.8425 21.9426 71.5375 21.6379C71.4612 21.5617 71.4612 21.5617 71.3087 21.4093C71.3087 21.7903 71.3087 22.1712 71.3087 22.476C71.0799 22.5522 69.3258 22.5522 68.8682 22.476C68.8682 22.3998 68.8682 9.21882 68.8682 8.91406ZM76.7235 17.676C76.7235 16.9903 76.4947 16.3045 75.9609 15.7712C75.427 15.2379 74.7406 14.9331 73.978 15.0093C73.2916 15.0093 72.6815 15.2379 72.1476 15.695C71.1561 16.6093 71.0799 18.2093 71.6137 19.1998C72.0713 20.0379 72.834 20.495 73.8254 20.5712C74.5118 20.6474 75.1982 20.4188 75.7321 19.9617C76.4185 19.3522 76.7235 18.5903 76.7235 17.676Z\" fill=\"currentColor\"/><path d=\"M43.7765 11.8858C43.0139 12.3429 42.2512 12.8001 41.4885 13.181C41.4885 13.1048 41.4123 13.1048 41.4123 13.1048C40.8021 12.1144 39.9632 11.581 38.8955 11.3525C37.904 11.1239 36.9126 11.2001 35.9974 11.6572C34.9297 12.1905 34.167 13.0286 33.7857 14.1715C33.4806 15.2382 33.4044 16.3048 33.7857 17.3715C34.3195 19.0477 35.5398 19.962 37.2939 20.1905C38.1328 20.2667 38.9718 20.1905 39.7344 19.8858C40.4208 19.581 41.0309 19.1239 41.4123 18.4382C41.4123 18.362 41.4885 18.362 41.4885 18.2858C42.2512 18.7429 43.0139 19.1239 43.7765 19.581C43.7002 19.6572 43.7002 19.7334 43.624 19.8096C42.7851 21.1048 41.5648 22.0191 40.0395 22.4763C38.0566 23.0858 36.1499 22.9334 34.3958 21.9429C32.4892 20.8763 31.3452 19.2001 30.9639 16.9905C30.7351 15.6191 30.8113 14.2477 31.4214 12.9525C32.4129 10.6667 34.0908 9.29531 36.5313 8.76198C38.0566 8.45721 39.5819 8.60959 40.9547 9.29531C42.0224 9.82864 42.9376 10.5905 43.624 11.581C43.624 11.6572 43.7002 11.7334 43.7765 11.8858Z\" fill=\"currentColor\"/><path d=\"M90.7561 17.7523C90.7561 20.6475 88.4682 22.9332 85.5701 22.857C82.7482 22.857 80.4603 20.4951 80.5365 17.5999C80.5365 14.7808 82.9008 12.4951 85.7226 12.4951C88.3919 12.5713 90.7561 14.857 90.7561 17.7523ZM88.2394 17.7523C88.2394 17.1427 88.0868 16.6094 87.7818 16.1523C87.1716 15.3142 86.409 15.0094 85.4175 15.0094C84.5023 15.0856 83.8159 15.4665 83.2821 16.3046C82.977 16.838 82.9008 17.4475 82.977 18.057C83.2058 20.1904 85.4175 21.0285 86.9428 20.1142C87.858 19.5808 88.2394 18.7427 88.2394 17.7523Z\" fill=\"currentColor\"/><path d=\"M47.8186 12.876C47.8186 13.0284 47.8186 13.1046 47.8186 13.1808C47.8186 14.9332 47.8186 16.6855 47.8186 18.3617C47.8186 18.5903 47.8186 18.8951 47.8949 19.1236C48.0474 19.9617 48.6575 20.4951 49.5727 20.4951C49.8778 20.4951 50.1829 20.4951 50.4117 20.4189C51.1743 20.2665 51.6319 19.7332 51.7844 18.9713C51.8607 18.6665 51.8607 18.2855 51.8607 17.9808C51.8607 16.3808 51.8607 14.7808 51.8607 13.1046C51.8607 13.0284 51.8607 12.876 51.8607 12.7998C52.0132 12.7236 53.9199 12.7236 54.3012 12.7998C54.3775 12.9522 54.3775 22.1713 54.3012 22.476C54.1487 22.5522 52.1658 22.5522 51.8607 22.476C51.8607 22.1713 51.8607 21.7903 51.8607 21.4093C51.7844 21.4855 51.7082 21.5617 51.7082 21.5617C51.1743 22.2474 50.4879 22.5522 49.5727 22.7046C48.9626 22.7808 48.3525 22.7808 47.7424 22.5522C46.5221 22.1713 45.7594 21.257 45.3781 20.0379C45.3019 19.657 45.2256 19.1998 45.2256 18.8189C45.2256 16.8379 45.2256 14.9332 45.2256 12.9522C45.2256 12.876 45.2256 12.7998 45.2256 12.7236C46.1408 12.876 46.9797 12.876 47.8186 12.876Z\" fill=\"currentColor\"/><path d=\"M12.8892 21.2572V31.5429L25.3968 26.0572V15.8477L12.8892 21.2572Z\" fill=\"currentColor\"/><path d=\"M12.2788 0.0761719L0 5.4857V15.7714L12.2788 10.2857V0.0761719Z\" fill=\"currentColor\"/><path d=\"M12.8892 0V10.2857L20.5157 13.4095V3.27619L12.8892 0Z\" fill=\"currentColor\"/><path d=\"M12.2788 21.2572L0 15.8477V26.1334L12.2788 31.6191V21.2572Z\" fill=\"currentColor\"/></svg>`;\n\n\nfunction fmtDateTime(iso) {\n  try { return new Date(iso).toLocaleString('pt-BR'); } catch (e) { return iso; }\n}\nfunction esc(s) {\n  return String(s == null ? '' : s).replace(/[&<>\"']/g, (c) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;', \"'\": '&#39;' }[c]));\n}\n\nexport default {\n  css: `\n    :host { display:block; height:100%; width:100%; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Inter,Roboto,sans-serif; }\n    .app { height:100%; width:100%; background:#F4F5FA; display:flex; flex-direction:column; }\n    .topbar { background:#0B1120; color:#fff; padding:14px 24px; display:flex; align-items:center; justify-content:space-between; flex-shrink:0; }\n    .topbar-left { display:flex; align-items:center; gap:14px; }\n    .topbar-title { font-size:14px; font-weight:600; color:#C7CBE0; letter-spacing:.02em; border-left:1px solid #2A2F45; padding-left:14px; }\n    .operator-badge { font-size:12px; color:#9CA3D4; background:#161B2E; border:1px solid #262B45; padding:5px 12px; border-radius:999px; }\n    .gate-wrap { flex:1; display:flex; align-items:center; justify-content:center; padding:24px; }\n    .gate-card { background:#fff; border:1px solid #E4E6F0; border-radius:16px; padding:40px; width:100%; max-width:380px; text-align:center; }\n    .logo-chip { display:inline-flex; align-items:center; justify-content:center; background:#0B1120; border-radius:10px; padding:10px 16px; }\n    .gate-card input { width:100%; box-sizing:border-box; padding:12px 14px; border-radius:10px; border:1px solid #D6D9EA; font-size:15px; margin-top:18px; text-align:center; letter-spacing:.05em; }\n    .gate-card input:focus { outline:none; border-color:#4338CA; }\n    .btn { background:#4338CA; color:#fff; border:none; border-radius:10px; padding:12px 20px; font-size:14px; font-weight:600; cursor:pointer; }\n    .btn:hover { background:#3730A3; }\n    .btn:disabled { background:#C7CBE0; cursor:not-allowed; }\n    .btn-secondary { background:#fff; color:#4338CA; border:1px solid #4338CA; }\n    .btn-secondary:hover { background:#EEF0FE; }\n    .gate-error { color:#DC2626; font-size:13px; margin-top:10px; min-height:16px; }\n    .main { flex:1; display:grid; grid-template-columns:1fr 380px; gap:0; overflow:hidden; position:relative; }\n    .video-pane { background:#000; position:relative; display:flex; align-items:center; justify-content:center; overflow:hidden; }\n    .video-pane video { display:none; }\n    .video-pane canvas { width:100%; height:100%; object-fit:cover; display:block; }\n    .video-hint { position:absolute; bottom:20px; left:calc((100% - 380px) / 2); transform:translateX(-50%); background:rgba(11,17,32,.75); color:#fff; padding:8px 16px; border-radius:999px; font-size:13px; z-index:2; pointer-events:none; }\n    .side { background:#fff; border-left:1px solid #E4E6F0; padding:24px; overflow-y:auto; display:flex; flex-direction:column; gap:16px; }\n    .side h3 { margin:0; font-size:13px; text-transform:uppercase; letter-spacing:.06em; color:#8B8FA8; }\n    .field label { display:block; font-size:12px; color:#5B5F78; margin-bottom:6px; font-weight:600; }\n    .field input { width:100%; box-sizing:border-box; padding:10px 12px; border-radius:8px; border:1px solid #D6D9EA; font-size:14px; }\n    .field input:focus { outline:none; border-color:#4338CA; }\n    .manual-row { display:flex; gap:8px; }\n    .manual-row input { flex:1; }\n    .divider { height:1px; background:#EEF0F5; margin:4px 0; }\n    .spinner { width:28px; height:28px; border-radius:50%; border:3px solid #E4E6F0; border-top-color:#4338CA; animation:spin 0.8s linear infinite; margin:0 auto; }\n    @keyframes spin { to { transform:rotate(360deg); } }\n    .center-msg { text-align:center; color:#5B5F78; font-size:13px; padding:20px 0; }\n    .order-card { background:#F8F8FC; border:1px solid #E4E6F0; border-radius:12px; padding:16px; }\n    .order-card .name { font-size:15px; font-weight:700; color:#0B1120; }\n    .order-card .code { font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:12px; color:#4338CA; margin-top:2px; }\n    .order-card .meta { font-size:12.5px; color:#5B5F78; margin-top:8px; line-height:1.6; }\n    .items-list { font-size:12.5px; color:#333750; margin-top:8px; padding-left:16px; }\n    .weight-box { background:#0B1120; border-radius:12px; padding:18px; text-align:center; }\n    .weight-box .lbl { font-size:11px; color:#9CA3D4; text-transform:uppercase; letter-spacing:.08em; }\n    .weight-box .val { font-size:34px; font-weight:800; color:#fff; margin:4px 0; font-variant-numeric:tabular-nums; }\n    .weight-box input[type=range] { width:100%; margin-top:10px; accent-color:#818CF8; }\n    .status-chip { display:inline-flex; align-items:center; gap:6px; font-size:12px; font-weight:600; padding:5px 10px; border-radius:999px; }\n    .status-chip.rec { background:#FEE2E2; color:#B91C1C; }\n    .status-chip.ok { background:#DCFCE7; color:#15803D; }\n    .dot { width:7px; height:7px; border-radius:50%; background:currentColor; }\n    .rec-pulse { animation:pulse 1.2s ease-in-out infinite; }\n    @keyframes pulse { 0%,100%{opacity:1} 50%{opacity:.35} }\n    .done-card { text-align:center; padding:12px 0; }\n    .done-card .check { width:52px; height:52px; border-radius:50%; background:#DCFCE7; color:#15803D; display:flex; align-items:center; justify-content:center; margin:0 auto 12px; font-size:26px; }\n    .link-row { margin-top:14px; }\n    .link-row a { color:#4338CA; font-size:13px; font-weight:600; text-decoration:none; }\n    .link-row a:hover { text-decoration:underline; }\n    .err-box { background:#FEF2F2; border:1px solid #FCA5A5; color:#B91C1C; border-radius:10px; padding:12px; font-size:13px; }\n    .prog-head { display:flex; align-items:baseline; justify-content:space-between; }\n    .prog-head .n { font-size:22px; font-weight:800; color:#0B1120; font-variant-numeric:tabular-nums; }\n    .prog-head .p { font-size:13px; font-weight:700; color:#4338CA; }\n    .prog-track { height:8px; background:#E4E6F0; border-radius:99px; margin-top:8px; overflow:hidden; }\n    .prog-fill { height:100%; background:#4338CA; border-radius:99px; transition:width .25s ease; }\n    .prog-fill.full { background:#15803D; }\n    .ck { display:flex; gap:12px; align-items:flex-start; padding:10px 12px; border:1px solid #E4E6F0; border-radius:10px; background:#fff; }\n    .ck + .ck { margin-top:8px; }\n    .ck-qty { flex-shrink:0; font-size:13px; font-weight:800; font-variant-numeric:tabular-nums; padding:3px 8px; border-radius:7px; background:#F1F2F8; color:#5B5F78; }\n    .ck.ok { border-color:#BBF7D0; background:#F6FEF9; }\n    .ck.ok .ck-qty { background:#DCFCE7; color:#15803D; }\n    .ck.part { border-color:#FDE68A; background:#FFFDF5; }\n    .ck.part .ck-qty { background:#FEF3C7; color:#92600B; }\n    .ck-name { font-size:13px; font-weight:600; color:#1F2233; line-height:1.35; }\n    .ck-sku { font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:11px; color:#8B8FA8; margin-top:3px; }\n    .scan-hint { font-size:12px; color:#8B8FA8; text-align:center; padding:2px 0 4px; }\n    .dv { border:1px solid #FDE68A; background:#FFFDF5; border-radius:10px; padding:12px; }\n    .dv + .dv { margin-top:10px; }\n    .dv-name { font-size:13px; font-weight:700; color:#0B1120; }\n    .dv-gap { font-size:12px; color:#92600B; margin:4px 0 8px; }\n    .dv select, .dv input { width:100%; box-sizing:border-box; padding:9px 10px; border-radius:8px; border:1px solid #D6D9EA; font-size:13px; background:#fff; }\n    .dv input { margin-top:8px; }\n    .dv select:focus, .dv input:focus { outline:none; border-color:#4338CA; }\n    .blocked-card { background:#FFFBEB; border:1px solid #FDE68A; border-radius:12px; padding:18px; }\n    .blocked-card .t { font-size:15px; font-weight:800; color:#92600B; }\n    .blocked-card .d { font-size:12.5px; color:#7C4A03; margin-top:8px; line-height:1.7; }\n    .status-chip.warn { background:#FEF3C7; color:#92600B; }\n    .divergence-note { background:#FEF3C7; border:1px solid #FDE68A; border-radius:10px; padding:10px 12px; font-size:12.5px; color:#7C4A03; }\n    .order-card .pend { font-size:12px; color:#92600B; font-weight:600; margin-top:6px; }\n    .awaiting-box { background:#FEF3C7; border:1px solid #FDE68A; color:#7C4A03; border-radius:10px; padding:10px 12px; font-size:12.5px; line-height:1.5; }\n    .awaiting-box .dot-inline { display:inline-block; width:8px; height:8px; border-radius:50%; background:#F59E0B; margin-right:6px; animation:pulse 1.2s ease-in-out infinite; }\n    .weight-box.awaiting { outline:2px solid #F59E0B; outline-offset:2px; }\n    .weight-box.awaiting .lbl { color:#FCD34D; }\n  `,\n  render(d2) {\n    const s = d2.state;\n    if (!s.unlocked) {\n      return `\n        <div class=\"app\">\n          <div class=\"gate-wrap\">\n            <div class=\"gate-card\">\n              <div class=\"logo-chip\">${LOGO_SVG('#fff', 26)}</div>\n              <div style=\"margin-top:14px;font-size:14px;color:#5B5F78;\">Estação de Picking &mdash; acesso restrito</div>\n              <input class=\"js-gate-input\" type=\"password\" placeholder=\"Senha de acesso\" />\n              <div class=\"gate-error\">${esc(s.gateError || '')}</div>\n              <div style=\"margin-top:6px;\"><button class=\"btn js-gate-submit\" style=\"width:100%;\">Entrar</button></div>\n            </div>\n          </div>\n        </div>`;\n    }\n\n    const stage = s.stage || 'idle';\n    const o = s.order || {};\n    const cl = s.checklist || [];\n    const exp = sumBy(cl, 'expectedQty');\n    const got = sumBy(cl, 'pickedQty');\n    const pct = pctOf(cl);\n    const full = exp > 0 && got >= exp;\n    const reasons = s.reasons || [];\n    const weight = Number(s.weight) || 0;\n    let side = '';\n\n    const progHtml = `\n      <div>\n        <div class=\"prog-head\"><div class=\"n\">${got}/${exp} itens</div><div class=\"p\">${pct}%</div></div>\n        <div class=\"prog-track\"><div class=\"prog-fill ${full ? 'full' : ''}\" style=\"width:${pct}%;\"></div></div>\n      </div>`;\n\n    if (stage === 'idle') {\n      side = `\n        <h3>Operador</h3>\n        <div class=\"field\"><label>Nome do operador</label><input class=\"js-operator-input\" type=\"text\" placeholder=\"Digite seu nome\" value=\"${esc(s.operatorName || '')}\" /></div>\n        <div class=\"divider\"></div>\n        <h3>Leitura do pedido</h3>\n        <div class=\"center-msg\">Aponte a câmera para o código de barras do <strong>pedido</strong> na folha. A leitura carrega os itens esperados e inicia a gravação.</div>\n        <div class=\"manual-row\">\n          <input class=\"js-manual-code\" type=\"text\" placeholder=\"ou digite o código (CUB-2601)\" />\n          <button class=\"btn btn-secondary js-manual-scan\">Ler</button>\n        </div>\n        ${s.scanError ? `<div class=\"err-box\">${esc(s.scanError)}</div>` : ''}\n        ${s.cameraError ? `<div class=\"err-box\">${esc(s.cameraError)}</div>` : ''}\n      `;\n    } else if (stage === 'looking-up') {\n      side = `<div class=\"spinner\"></div><div class=\"center-msg\">Consultando o pedido...</div>`;\n    } else if (stage === 'blocked') {\n      const b = s.blockedInfo || {};\n      side = `\n        <div class=\"status-chip warn\"><span class=\"dot\"></span> JÁ SEPARADO</div>\n        <div class=\"blocked-card\">\n          <div class=\"t\">${esc(b.orderCode)} já foi separado</div>\n          <div class=\"d\">\n            ${esc(b.customerName || '')}<br/>\n            Operador: <strong>${esc(b.pickedBy || '—')}</strong><br/>\n            ${b.pickedAt ? fmtDateTime(b.pickedAt) : ''}<br/>\n            Completude registrada: <strong>${b.completionPct != null ? b.completionPct + '%' : '—'}</strong>\n          </div>\n        </div>\n        <div class=\"center-msg\">Esta folha já rodou. Bipe outra folha direto, ou resete a demo no Painel Operacional.</div>\n        <button class=\"btn btn-secondary js-reset-btn\" style=\"width:100%;\">Ler outro pedido</button>\n      `;\n    } else if (stage === 'picking') {\n      const ck = cl.map((it) => {\n        const done = it.pickedQty >= it.expectedQty;\n        const cls = done ? 'ok' : (it.pickedQty > 0 ? 'part' : '');\n        return `<div class=\"ck ${cls}\" data-key=\"${esc(it.ean)}\">\n            <div class=\"ck-qty\">${it.pickedQty}/${it.expectedQty}</div>\n            <div class=\"ck-body\"><div class=\"ck-name\">${esc(it.name)}</div><div class=\"ck-sku\">${esc(it.sku)} &middot; ${esc(it.ean)}</div></div>\n          </div>`;\n      }).join('');\n      side = `\n        <div class=\"status-chip rec\"><span class=\"dot rec-pulse\"></span> GRAVANDO</div>\n        <div class=\"order-card\">\n          <div class=\"name\">${esc(o.customerName)}</div>\n          <div class=\"code\">${esc(o.orderCode)} &middot; caixa ${esc(o.boxCode)}</div>\n          <div class=\"meta\">${esc(o.shippingAddress)}<br/>${esc(o.city)}/${esc(o.state)} &middot; ${esc(o.carrier)}</div>\n        </div>\n        ${progHtml}\n        <h3>Conferência</h3>\n        ${s.awaitingItem\n          ? `<div class=\"awaiting-box\"><span class=\"dot-inline\"></span><strong>${esc(s.awaitingItem.name)}</strong> bipado — coloque na caixa. A balança precisa registrar o aumento de peso para confirmar.</div>`\n          : `<div class=\"scan-hint\">${full ? 'Caixa completa — pode finalizar.' : 'Bipe cada item na folha. Faltam ' + (exp - got) + ' unidade(s).'}</div>`}\n        ${ck}\n        <div class=\"manual-row\">\n          <input class=\"js-manual-code\" type=\"text\" placeholder=\"ou digite o EAN do item\" />\n          <button class=\"btn btn-secondary js-manual-scan\">Ler</button>\n        </div>\n        <div class=\"weight-box${s.awaitingItem ? ' awaiting' : ''}\">\n          <div class=\"lbl\">Peso da balança</div>\n          <div class=\"val\"><span class=\"js-weight-display\">${weight.toFixed(2)}</span> kg</div>\n          <input class=\"js-weight-slider\" type=\"range\" min=\"0\" max=\"5\" step=\"0.05\" value=\"${weight}\" />\n        </div>\n        <button class=\"btn js-finish-btn\" style=\"width:100%;\">${full ? 'Finalizar Picking' : 'Finalizar com divergência (' + got + '/' + exp + ')'}</button>\n      `;\n    } else if (stage === 'divergence') {\n      const draft = s.divDraft || {};\n      const missing = cl.filter((it) => it.pickedQty < it.expectedQty);\n      const dv = missing.map((it) => {\n        const d = draft[it.sku] || {};\n        let needNote = false;\n        for (let i = 0; i < reasons.length; i++) {\n          if (reasons[i].code === d.reasonCode && reasons[i].requiresNote) needNote = true;\n        }\n        const opts = reasons.map((r) => `<option value=\"${esc(r.code)}\"${r.code === d.reasonCode ? ' selected' : ''}>${esc(r.label)}</option>`).join('');\n        return `<div class=\"dv\" data-key=\"${esc(it.sku)}\">\n            <div class=\"dv-name\">${esc(it.name)}</div>\n            <div class=\"dv-gap\">conferido ${it.pickedQty} de ${it.expectedQty} &middot; faltou ${it.expectedQty - it.pickedQty}</div>\n            <select class=\"js-div-reason\" data-sku=\"${esc(it.sku)}\"><option value=\"\">Selecione o motivo...</option>${opts}</select>\n            ${needNote ? `<input class=\"js-div-note\" data-sku=\"${esc(it.sku)}\" placeholder=\"Observação (obrigatória)\" value=\"${esc(d.note || '')}\" />` : ''}\n          </div>`;\n      }).join('');\n      side = `\n        <div class=\"status-chip warn\"><span class=\"dot rec-pulse\"></span> GRAVANDO &middot; DIVERGÊNCIA</div>\n        <div class=\"divergence-note\">A caixa está incompleta. Registre o motivo de cada item faltante — sem isso o picking não é finalizado.</div>\n        ${progHtml}\n        ${dv}\n        ${s.divError ? `<div class=\"err-box\">${esc(s.divError)}</div>` : ''}\n        <button class=\"btn js-div-confirm\" style=\"width:100%;\">Confirmar e finalizar</button>\n        <button class=\"btn btn-secondary js-div-back\" style=\"width:100%;\">Voltar e continuar bipando</button>\n      `;\n    } else if (stage === 'uploading') {\n      side = `<div class=\"spinner\"></div><div class=\"center-msg\">Enviando vídeo e salvando o registro...</div>`;\n    } else if (stage === 'done') {\n      const hadDiv = !!s.lastHasDivergence;\n      side = `\n        <div class=\"done-card\">\n          <div class=\"check\"${hadDiv ? ' style=\"background:#FEF3C7;color:#92600B;\"' : ''}>${hadDiv ? '!' : '&#10003;'}</div>\n          <div style=\"font-weight:700;font-size:15px;\">${hadDiv ? 'Registrado com divergência' : 'Picking registrado'}</div>\n          <div class=\"center-msg\" style=\"margin-top:4px;\">${esc(s.lastOrderCode || '')} &middot; ${s.lastPct != null ? s.lastPct : 0}% conferido</div>\n          <div class=\"link-row\">${s.lastVideoUrl ? `<a href=\"${esc(s.lastVideoUrl)}\" target=\"_blank\" rel=\"noopener\">Abrir vídeo &rarr;</a>` : '<span style=\"font-size:12px;color:#8B8FA8;\">Vídeo indisponível no Drive</span>'}</div>\n        </div>\n        <div class=\"scan-hint\">Pode bipar a próxima folha direto.</div>\n        <button class=\"btn btn-secondary js-reset-btn\" style=\"width:100%;\">Novo Picking</button>\n      `;\n    } else if (stage === 'error') {\n      side = `<div class=\"err-box\">${esc(s.errorMsg || 'Ocorreu um erro.')}</div><button class=\"btn btn-secondary js-reset-btn\" style=\"width:100%;margin-top:10px;\">Tentar novamente</button>`;\n    }\n\n    const showHint = (stage === 'idle' || stage === 'looking-up');\n    return `\n      <div class=\"app\">\n        <div class=\"topbar\">\n          <div class=\"topbar-left\">\n            ${LOGO_SVG('#fff', 22)}\n            <div class=\"topbar-title\">Estação de Picking</div>\n          </div>\n          ${s.operatorName ? `<div class=\"operator-badge\">${esc(s.operatorName)}</div>` : ''}\n        </div>\n        <div class=\"main\">\n          <div class=\"video-pane\" data-d2-static>\n            <video class=\"js-video\" autoplay playsinline muted></video>\n            <canvas class=\"js-canvas\"></canvas>\n          </div>\n          ${showHint ? '<div class=\"video-hint\">Aguardando leitura do pedido...</div>' : ''}\n          <div class=\"side\">${side}</div>\n        </div>\n      </div>\n    `;\n  },\n  mounted(d2, root) {\n    let cameraInitialized = false;\n    let stream = null;\n    let recordingActive = false;\n    let recordingStartedAtIso = null;\n    let recordingStartedAtMs = 0;\n    let mediaRecorder = null;\n    let chunks = [];\n    let mimeType = '';\n    let detectInterval = null;\n    let detector = null;\n    let scanLocked = false;\n    let finishing = false;\n    // Cooldown do leitor: o detector roda a cada ~400ms, então um código parado\n    // na frente da câmera dispararia várias leituras. Janela DESLIZANTE: enquanto\n    // o mesmo código continua em cena, nada re-dispara; só depois de sumir ~2s.\n    let lastCam = { code: '', at: 0 };\n    let audioCtx = null;\n\n    function beep(kind) {\n      try {\n        const AC = window.AudioContext || window.webkitAudioContext;\n        if (!AC) return;\n        if (!audioCtx) audioCtx = new AC();\n        if (audioCtx.state === 'suspended') audioCtx.resume();\n        const t0 = audioCtx.currentTime;\n        const tone = (freq, start, dur, type, gain) => {\n          const o = audioCtx.createOscillator();\n          const g = audioCtx.createGain();\n          o.type = type;\n          o.frequency.value = freq;\n          g.gain.setValueAtTime(gain, t0 + start);\n          g.gain.exponentialRampToValueAtTime(0.001, t0 + start + dur);\n          o.connect(g);\n          g.connect(audioCtx.destination);\n          o.start(t0 + start);\n          o.stop(t0 + start + dur + 0.02);\n        };\n        if (kind === 'ok') {\n          tone(1046, 0, 0.09, 'sine', 0.25);\n          tone(1568, 0.09, 0.13, 'sine', 0.25);\n        } else if (kind === 'read') {\n          tone(784, 0, 0.08, 'sine', 0.2);\n        } else {\n          tone(196, 0, 0.28, 'square', 0.16);\n        }\n      } catch (e) { /* som é conforto, nunca erro */ }\n    }\n\n    // Espelho de closure lido a cada frame pelo canvas — evita ler d2.state\n    // dentro do rAF (leitura de state assina re-render).\n    const ui = { stage: 'idle', order: null, checklist: [], weight: 0, flash: null, banner: null };\n\n    function syncFromState() {\n      ui.stage = d2.state.stage || 'idle';\n      ui.order = d2.state.order || null;\n      ui.checklist = d2.state.checklist || [];\n    }\n\n    function roundRect(ctx, x, y, w, h, r) {\n      ctx.beginPath();\n      ctx.moveTo(x + r, y);\n      ctx.arcTo(x + w, y, x + w, y + h, r);\n      ctx.arcTo(x + w, y + h, x, y + h, r);\n      ctx.arcTo(x, y + h, x, y, r);\n      ctx.arcTo(x, y, x + w, y, r);\n      ctx.closePath();\n    }\n\n    function drawLoop() {\n      const videoEl = d2.$('.js-video');\n      const canvasEl = d2.$('.js-canvas');\n      if (!videoEl || !canvasEl || !videoEl.videoWidth) return true;\n      if (canvasEl.width !== videoEl.videoWidth) {\n        canvasEl.width = videoEl.videoWidth;\n        canvasEl.height = videoEl.videoHeight;\n      }\n      const ctx = canvasEl.getContext('2d');\n      const w = canvasEl.width;\n      const h = canvasEl.height;\n      ctx.drawImage(videoEl, 0, 0, w, h);\n      if (!recordingActive) return true;\n\n      const pad = Math.max(16, w * 0.02);\n      const exp = sumBy(ui.checklist, 'expectedQty');\n      const got = sumBy(ui.checklist, 'pickedQty');\n      const pct = exp > 0 ? Math.round((got * 100) / exp) : 0;\n\n      // REC + cronômetro (topo esquerdo)\n      const elapsed = Math.max(0, Math.floor((Date.now() - recordingStartedAtMs) / 1000));\n      const mm = String(Math.floor(elapsed / 60)).padStart(2, '0');\n      const ss = String(elapsed % 60).padStart(2, '0');\n      ctx.fillStyle = 'rgba(11,17,32,0.72)';\n      roundRect(ctx, pad, pad, w * 0.22, h * 0.07, 10);\n      ctx.fill();\n      ctx.fillStyle = '#EF4444';\n      ctx.beginPath();\n      ctx.arc(pad + 16, pad + (h * 0.07) / 2, 6, 0, Math.PI * 2);\n      ctx.fill();\n      ctx.fillStyle = '#fff';\n      ctx.font = `bold ${Math.max(13, h * 0.03)}px sans-serif`;\n      ctx.fillText(`REC ${mm}:${ss}`, pad + 30, pad + (h * 0.07) / 2 + 5);\n\n      // Códigos (topo direito)\n      if (ui.order) {\n        const label = `${ui.order.boxCode} · ${ui.order.orderCode}`;\n        ctx.font = `${Math.max(12, h * 0.025)}px monospace`;\n        const tw = ctx.measureText(label).width;\n        ctx.fillStyle = 'rgba(11,17,32,0.72)';\n        roundRect(ctx, w - tw - pad - 24, pad, tw + 24, h * 0.055, 8);\n        ctx.fill();\n        ctx.fillStyle = '#fff';\n        ctx.fillText(label, w - tw - pad - 12, pad + (h * 0.055) * 0.68);\n      }\n\n      // Placa inferior: contador + peso + barra de completude\n      const plateH = h * 0.13;\n      const plateY = h - plateH - pad;\n      ctx.fillStyle = 'rgba(11,17,32,0.78)';\n      roundRect(ctx, pad, plateY, w - pad * 2, plateH, 12);\n      ctx.fill();\n\n      ctx.fillStyle = '#9CA3D4';\n      ctx.font = `${Math.max(11, plateH * 0.15)}px sans-serif`;\n      ctx.fillText('COMPLETUDE DA CAIXA', pad + 18, plateY + plateH * 0.24);\n      ctx.fillStyle = '#fff';\n      ctx.font = `bold ${Math.max(20, plateH * 0.32)}px sans-serif`;\n      ctx.fillText(`${got}/${exp} itens · ${pct}%`, pad + 18, plateY + plateH * 0.55);\n\n      const wLabel = `${ui.weight.toFixed(2)} kg`;\n      ctx.font = `bold ${Math.max(18, plateH * 0.3)}px sans-serif`;\n      const wtw = ctx.measureText(wLabel).width;\n      ctx.fillStyle = '#fff';\n      ctx.fillText(wLabel, w - pad - 18 - wtw, plateY + plateH * 0.55);\n      ctx.fillStyle = '#9CA3D4';\n      ctx.font = `${Math.max(11, plateH * 0.15)}px sans-serif`;\n      const bl = 'PESO DA BALANÇA';\n      const bltw = ctx.measureText(bl).width;\n      ctx.fillText(bl, w - pad - 18 - bltw, plateY + plateH * 0.24);\n\n      // Trilho + preenchimento\n      const trackX = pad + 18;\n      const trackW = w - pad * 2 - 36;\n      const trackH = Math.max(8, plateH * 0.14);\n      const trackY = plateY + plateH - trackH - plateH * 0.16;\n      ctx.fillStyle = 'rgba(255,255,255,0.18)';\n      roundRect(ctx, trackX, trackY, trackW, trackH, trackH / 2);\n      ctx.fill();\n      const fillW = Math.max(trackH, (trackW * Math.min(100, pct)) / 100);\n      ctx.fillStyle = pct >= 100 ? '#22C55E' : '#818CF8';\n      roundRect(ctx, trackX, trackY, fillW, trackH, trackH / 2);\n      ctx.fill();\n\n      // Flash do último bipe (centro superior)\n      if (ui.flash && Date.now() < ui.flash.until) {\n        const colors = { ok: 'rgba(22,163,74,0.94)', over: 'rgba(180,120,10,0.94)', bad: 'rgba(185,28,28,0.94)' };\n        ctx.font = `bold ${Math.max(16, h * 0.032)}px sans-serif`;\n        const t = ui.flash.text;\n        const ftw = ctx.measureText(t).width;\n        const bw = ftw + 44;\n        const bh = h * 0.062;\n        const bx = (w - bw) / 2;\n        const by = pad + h * 0.09;\n        ctx.fillStyle = colors[ui.flash.kind] || colors.ok;\n        roundRect(ctx, bx, by, bw, bh, 10);\n        ctx.fill();\n        ctx.fillStyle = '#fff';\n        ctx.fillText(t, bx + 22, by + bh * 0.68);\n      }\n\n      // Faixa de divergência (fica no vídeo enquanto o motivo é escolhido)\n      if (ui.banner) {\n        ctx.font = `bold ${Math.max(15, h * 0.028)}px sans-serif`;\n        const btw = ctx.measureText(ui.banner).width;\n        const bw2 = btw + 40;\n        const bh2 = h * 0.058;\n        ctx.fillStyle = 'rgba(146,96,11,0.94)';\n        roundRect(ctx, (w - bw2) / 2, plateY - bh2 - 12, bw2, bh2, 10);\n        ctx.fill();\n        ctx.fillStyle = '#fff';\n        ctx.fillText(ui.banner, (w - bw2) / 2 + 20, plateY - bh2 - 12 + bh2 * 0.68);\n      }\n      return true;\n    }\n\n    async function initCamera() {\n      if (cameraInitialized) return;\n      cameraInitialized = true;\n      try {\n        stream = await navigator.mediaDevices.getUserMedia({ video: { facingMode: 'environment' }, audio: false });\n      } catch (e1) {\n        try { stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: false }); }\n        catch (e2) { d2.setState({ cameraError: 'Não foi possível acessar a câmera: ' + (e2 && e2.message ? e2.message : e2) }); return; }\n      }\n      const videoEl = d2.$('.js-video');\n      if (videoEl) { videoEl.srcObject = stream; await videoEl.play().catch(() => {}); }\n      d2.raf(drawLoop);\n\n      if ('BarcodeDetector' in window) {\n        try {\n          detector = new window.BarcodeDetector({ formats: ['qr_code', 'code_128', 'ean_13', 'ean_8', 'code_39', 'upc_a', 'upc_e'] });\n        } catch (e) { detector = null; }\n      }\n      if (!detector) {\n        d2.setState({ cameraError: 'Este navegador não tem leitor de código de barras (só Chrome/Edge). Use o campo manual.' });\n      } else {\n        detectInterval = setInterval(async () => {\n          const v = d2.$('.js-video');\n          if (!v || !v.videoWidth) return;\n          try {\n            const codes = await detector.detect(v);\n            if (codes && codes.length) {\n              const raw = String(codes[0].rawValue || '').trim();\n              const nowT = Date.now();\n              if (raw && raw === lastCam.code && (nowT - lastCam.at) < 2000) {\n                lastCam.at = nowT; // ainda em cena — renova a janela, não re-dispara\n                return;\n              }\n              lastCam = { code: raw, at: nowT };\n              onScanned(raw);\n            }\n          } catch (e) { /* erros transientes de detecção */ }\n        }, 400);\n      }\n      d2.onUnmount(() => {\n        if (detectInterval) clearInterval(detectInterval);\n        if (stream) stream.getTracks().forEach((t) => t.stop());\n        if (mediaRecorder && mediaRecorder.state === 'recording') mediaRecorder.stop();\n      });\n    }\n\n    function flash(kind, text) {\n      const now = Date.now();\n      if (ui.flash && ui.flash.text === text && now - ui.flash.shownAt < 1200) return;\n      ui.flash = { kind, text, until: now + 1400, shownAt: now };\n    }\n\n    function resetToIdle() {\n      ui.order = null;\n      ui.checklist = [];\n      ui.flash = null;\n      ui.banner = null;\n      ui.weight = 0;\n      scanLocked = false;\n      recordingActive = false;\n      finishing = false;\n      chunks = [];\n      d2.setState({\n        stage: 'idle', order: null, checklist: [], scanTrail: [], reasons: [],\n        blockedInfo: null, divDraft: {}, divError: '', weight: 0, awaitingItem: null,\n        lastVideoUrl: '', errorMsg: '', scanError: '', cameraError: '',\n      });\n      ui.stage = 'idle';\n    }\n\n    // ---- Roteamento do bipe -------------------------------------------------\n    function onScanned(raw) {\n      const code = String(raw || '').trim();\n      if (!code) return;\n      const stage = d2.state.stage || 'idle';\n      if (stage === 'picking' || stage === 'divergence') {\n        if (isItemCode(code)) { onItemScanned(code); return; }\n        beep('no');\n        flash('bad', 'Finalize este pedido antes de ler outro');\n        return;\n      }\n      // Nas telas de fim de ciclo, bipar OUTRA folha emenda o próximo picking\n      // sem tocar na tela. A MESMA folha (ainda no campo da câmera) é ignorada,\n      // senão o detector re-dispara a cada 400ms.\n      if (stage === 'blocked' || stage === 'done') {\n        if (isItemCode(code)) return;\n        const prev = stage === 'blocked'\n          ? ((d2.state.blockedInfo || {}).orderCode || '')\n          : (d2.state.lastOrderCode || '');\n        if (code === prev) return;\n        resetToIdle();\n        onOrderScanned(code);\n        return;\n      }\n      if (stage !== 'idle') return;\n      if (isItemCode(code)) {\n        beep('no');\n        d2.setState({ scanError: 'Esse é um código de item. Bipe primeiro o código do pedido, no topo da folha.' });\n        return;\n      }\n      onOrderScanned(code);\n    }\n\n    async function onOrderScanned(orderCode) {\n      if (scanLocked || recordingActive) return;\n      const opEl = d2.$('.js-operator-input');\n      const operatorName = (opEl && opEl.value) || d2.state.operatorName;\n      if (!operatorName) { d2.setState({ scanError: 'Informe o nome do operador antes de ler o pedido.' }); return; }\n      scanLocked = true;\n      d2.setState({ operatorName, stage: 'looking-up', scanError: '', cameraError: '' });\n      try {\n        const res = await d2.rush('cubbo-order-fetch').invoke({ orderCode }, RUSH_OPTS);\n        const out = (res && res.data) || {};\n        if (!out.found) {\n          scanLocked = false;\n          beep('no');\n          d2.setState({ stage: 'idle', scanError: `Pedido ${orderCode} não encontrado. Confira o código na folha.` });\n          return;\n        }\n        if (out.blocked) {\n          scanLocked = false;\n          beep('no');\n          d2.setState({ stage: 'blocked', blockedInfo: out.order || {} });\n          return;\n        }\n        const order = out.order || {};\n        const checklist = (order.expectedItems || []).map((it) => ({\n          sku: it.sku, name: it.name, ean: it.ean, expectedQty: Number(it.qty) || 0, pickedQty: 0,\n        }));\n        startRecording(order, checklist, out.reasons || []);\n      } catch (e) {\n        scanLocked = false;\n        d2.setState({ stage: 'error', errorMsg: 'Falha ao consultar o pedido: ' + (e && e.message ? e.message : e) });\n      }\n    }\n\n    function onItemScanned(ean) {\n      const cl = (d2.state.checklist || []).map((i) => ({ sku: i.sku, name: i.name, ean: i.ean, expectedQty: i.expectedQty, pickedQty: i.pickedQty }));\n      let hit = null;\n      for (let i = 0; i < cl.length; i++) { if (cl[i].ean === ean) hit = cl[i]; }\n      const trail = (d2.state.scanTrail || []).slice();\n      const at = new Date().toISOString();\n      if (!hit) {\n        trail.push({ ean, at, verdict: 'not_in_order' });\n        beep('no');\n        flash('bad', 'Item não pertence a este pedido');\n        d2.setState({ scanTrail: trail });\n        return;\n      }\n      if (hit.pickedQty >= hit.expectedQty) {\n        trail.push({ ean, at, verdict: 'over_qty' });\n        beep('no');\n        flash('over', `Quantidade já completa: ${hit.name}`);\n        d2.setState({ scanTrail: trail });\n        return;\n      }\n      // Gate da balança: o bipe NÃO conta ainda — o item só é confirmado\n      // quando a balança registrar aumento de peso (prova de que entrou na caixa).\n      const aw = d2.state.awaitingItem;\n      if (aw) {\n        if (aw.ean === ean) {\n          flash('over', 'Coloque o item na caixa — aguardando a balança');\n        } else {\n          beep('no');\n          flash('bad', 'Confirme o item anterior na balança antes de bipar outro');\n        }\n        return;\n      }\n      beep('read');\n      flash('over', `${hit.name} — coloque na caixa`);\n      ui.banner = 'COLOQUE NA CAIXA · AGUARDANDO BALANÇA';\n      const patch = { awaitingItem: { sku: hit.sku, name: hit.name, ean: ean, baseline: ui.weight } };\n      if (d2.state.stage === 'divergence') {\n        // o slider da balança só existe na conferência — volta pra ela\n        patch.stage = 'picking';\n        patch.divError = '';\n        ui.stage = 'picking';\n      }\n      d2.setState(patch);\n    }\n\n    // A balança subiu: o item bipado entrou na caixa — agora sim conta.\n    function confirmAwaitingItem(aw) {\n      const cl = (d2.state.checklist || []).map((i) => ({ sku: i.sku, name: i.name, ean: i.ean, expectedQty: i.expectedQty, pickedQty: i.pickedQty }));\n      let hit = null;\n      for (let i = 0; i < cl.length; i++) { if (cl[i].ean === aw.ean) hit = cl[i]; }\n      const trail = (d2.state.scanTrail || []).slice();\n      const delta = Math.round((ui.weight - aw.baseline) * 100) / 100;\n      if (hit && hit.pickedQty < hit.expectedQty) {\n        hit.pickedQty = hit.pickedQty + 1;\n        trail.push({ ean: aw.ean, at: new Date().toISOString(), verdict: 'ok', weightDeltaKg: delta });\n        beep('ok');\n        flash('ok', `${hit.name} ${hit.pickedQty}/${hit.expectedQty} · +${delta.toFixed(2)} kg`);\n      }\n      ui.checklist = cl;\n      ui.banner = null;\n      d2.setState({ checklist: cl, scanTrail: trail, awaitingItem: null });\n    }\n\n    function startRecording(order, checklist, reasons) {\n      ui.weight = 0;\n      ui.flash = null;\n      ui.banner = null;\n      ui.order = order;\n      ui.checklist = checklist;\n      scanLocked = false;\n      recordingActive = true;\n      recordingStartedAtMs = Date.now();\n      recordingStartedAtIso = new Date().toISOString();\n      chunks = [];\n      const canvasEl = d2.$('.js-canvas');\n      const canvasStream = canvasEl.captureStream(30);\n      mimeType = pickMimeType();\n      try {\n        mediaRecorder = mimeType ? new MediaRecorder(canvasStream, { mimeType }) : new MediaRecorder(canvasStream);\n      } catch (e) {\n        mediaRecorder = new MediaRecorder(canvasStream);\n      }\n      mediaRecorder.ondataavailable = (e) => { if (e.data && e.data.size > 0) chunks.push(e.data); };\n      mediaRecorder.start(1000);\n      beep('ok');\n      d2.setState({ stage: 'picking', order, checklist, reasons, scanTrail: [], weight: 0, divDraft: {}, divError: '', awaitingItem: null });\n      ui.stage = 'picking';\n    }\n\n    // ---- Peso: closure para o frame, state só no release -------------------\n    d2.on('.js-weight-slider', 'input', (e) => {\n      ui.weight = parseFloat(e.target.value) || 0;\n      const disp = d2.$('.js-weight-display');\n      if (disp) disp.textContent = ui.weight.toFixed(2);\n      const aw = d2.state.awaitingItem;\n      if (aw && ui.weight >= (aw.baseline + 0.04)) confirmAwaitingItem(aw);\n    });\n    d2.on('.js-weight-slider', 'change', (e) => {\n      ui.weight = parseFloat(e.target.value) || 0;\n      d2.setState({ weight: ui.weight });\n    });\n\n    d2.on('.js-operator-input', 'change', (e) => { d2.setState({ operatorName: e.target.value }); });\n\n    d2.on('.js-manual-scan', 'click', () => {\n      const el = d2.$('.js-manual-code');\n      const val = el && el.value.trim();\n      if (val) { el.value = ''; onScanned(val); }\n    });\n    d2.on('.js-manual-code', 'keydown', (e) => {\n      if (e.key === 'Enter') { const b = d2.$('.js-manual-scan'); if (b) b.click(); }\n    });\n\n    // ---- Finalização ------------------------------------------------------\n    d2.on('.js-finish-btn', 'click', () => {\n      const cl = d2.state.checklist || [];\n      const exp = sumBy(cl, 'expectedQty');\n      const got = sumBy(cl, 'pickedQty');\n      if (got >= exp) { doFinish([]); return; }\n      ui.banner = 'AGUARDANDO MOTIVO DA DIVERGÊNCIA';\n      d2.setState({ stage: 'divergence', divError: '' });\n      ui.stage = 'divergence';\n    });\n\n    d2.on('.js-div-back', 'click', () => {\n      ui.banner = null;\n      d2.setState({ stage: 'picking', divError: '' });\n      ui.stage = 'picking';\n    });\n\n    d2.on('.js-div-reason', 'change', (e) => {\n      const sku = e.target.getAttribute('data-sku');\n      const draft = Object.assign({}, d2.state.divDraft || {});\n      draft[sku] = Object.assign({}, draft[sku] || {}, { reasonCode: e.target.value });\n      d2.setState({ divDraft: draft, divError: '' });\n    });\n    d2.on('.js-div-note', 'input', (e) => {\n      const sku = e.target.getAttribute('data-sku');\n      const draft = Object.assign({}, d2.state.divDraft || {});\n      draft[sku] = Object.assign({}, draft[sku] || {}, { note: e.target.value });\n      d2.setState({ divDraft: draft });\n    });\n\n    d2.on('.js-div-confirm', 'click', () => {\n      const cl = d2.state.checklist || [];\n      const reasons = d2.state.reasons || [];\n      const draft = d2.state.divDraft || {};\n      const missing = cl.filter((it) => it.pickedQty < it.expectedQty);\n      const divergences = [];\n      for (let i = 0; i < missing.length; i++) {\n        const it = missing[i];\n        const d = draft[it.sku] || {};\n        if (!d.reasonCode) {\n          d2.setState({ divError: `Escolha o motivo para \"${it.name}\".` });\n          return;\n        }\n        let label = d.reasonCode;\n        let needNote = false;\n        for (let j = 0; j < reasons.length; j++) {\n          if (reasons[j].code === d.reasonCode) { label = reasons[j].label; needNote = !!reasons[j].requiresNote; }\n        }\n        if (needNote && !(d.note && d.note.trim())) {\n          d2.setState({ divError: `O motivo escolhido para \"${it.name}\" exige uma observação.` });\n          return;\n        }\n        divergences.push({\n          sku: it.sku, name: it.name, ean: it.ean,\n          expectedQty: it.expectedQty, pickedQty: it.pickedQty,\n          reasonCode: d.reasonCode, reasonLabel: label, note: (d.note || '').trim(),\n        });\n      }\n      if (divergences.length === 0) { doFinish([]); return; }\n      ui.banner = 'DIVERGÊNCIA: ' + divergences[0].reasonLabel;\n      // deixa a faixa aparecer no vídeo antes de encerrar a gravação\n      setTimeout(() => doFinish(divergences), 1600);\n    });\n\n    function doFinish(divergences) {\n      if (finishing) return;\n      const order = d2.state.order || {};\n      if (!order.orderCode) {\n        d2.setState({ stage: 'error', errorMsg: 'Pedido não identificado. Leia a folha novamente.' });\n        return;\n      }\n      finishing = true;\n      recordingActive = false;\n      ui.banner = null;\n      d2.setState({ stage: 'uploading', awaitingItem: null });\n      ui.stage = 'uploading';\n      const persist = async () => {\n        try {\n          const blob = chunks.length ? new Blob(chunks, { type: mimeType || 'video/webm' }) : null;\n          const finishedAt = new Date().toISOString();\n          const durationSec = Math.max(1, Math.round((Date.now() - recordingStartedAtMs) / 1000));\n          let videoUrl = '';\n          if (blob) {\n            try {\n              const name = `picking-${order.orderCode}-${Date.now()}.${extFor(mimeType)}`;\n              const file = new File([blob], name, { type: mimeType || 'video/webm' });\n              const uploaded = await d2.drive(DRIVE_REF).uploadFromFiles([file]);\n              videoUrl = (uploaded && uploaded[0] && uploaded[0].fileUrl) || '';\n            } catch (driveErr) {\n              videoUrl = '';\n            }\n          }\n          const cl = d2.state.checklist || [];\n          const res = await d2.rush('cubbo-picking-finish').invoke({\n            orderCode: order.orderCode,\n            operatorName: d2.state.operatorName,\n            measuredWeightKg: ui.weight,\n            videoUrl,\n            startedAt: recordingStartedAtIso,\n            finishedAt,\n            durationSec,\n            checklist: cl,\n            scanTrail: d2.state.scanTrail || [],\n            divergences: divergences || [],\n          }, RUSH_OPTS);\n          const out = (res && res.data) || {};\n          if (out.ok !== true) {\n            throw new Error(out.error || 'Resposta inesperada do servidor.');\n          }\n          ui.banner = null;\n          finishing = false;\n          beep('ok');\n          d2.setState({\n            stage: 'done',\n            lastVideoUrl: videoUrl,\n            lastOrderCode: order.orderCode,\n            lastPct: out.completionPct,\n            lastHasDivergence: out.hasDivergence,\n          });\n          ui.stage = 'done';\n        } catch (e) {\n          finishing = false;\n          d2.setState({ stage: 'error', errorMsg: 'Falha ao finalizar o picking: ' + (e && e.message ? e.message : e) });\n          ui.stage = 'error';\n        }\n      };\n      if (mediaRecorder && mediaRecorder.state === 'recording') {\n        mediaRecorder.onstop = persist;\n        mediaRecorder.stop();\n      } else {\n        // sem gravador (permissão negada / navegador sem MediaRecorder):\n        // registra o picking sem vídeo em vez de travar a tela\n        persist();\n      }\n    }\n\n    d2.on('.js-reset-btn', 'click', resetToIdle);\n\n    d2.on('.js-gate-submit', 'click', () => {\n      const val = d2.$('.js-gate-input') ? d2.$('.js-gate-input').value : '';\n      if (val === GATE_PASSWORD) {\n        gateWrite();\n        d2.setState({ unlocked: true, stage: 'idle', gateError: '' });\n        setTimeout(() => initCamera(), 0);\n      } else {\n        d2.setState({ gateError: 'Senha incorreta.' });\n      }\n    });\n    d2.on('.js-gate-input', 'keydown', (e) => {\n      if (e.key === 'Enter') { const b = d2.$('.js-gate-submit'); if (b) b.click(); }\n    });\n\n    syncFromState();\n    if (gateRead()) {\n      d2.setState({ unlocked: true, stage: 'idle' });\n      setTimeout(() => initCamera(), 0);\n    }\n  },\n};"}}}}}}}},{"_id":"6a900fdd342fe6365bfed6af","component":"data2-core-types@Component","system":"6a7ca6cb11f8a5ec77c18b42","params":{"extends":"data2-core-primitives@Block","component":"cubbo-ops-panel","package":"cubbo-app","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 GATE_PASSWORD = 'democubodata2';\nconst RESET_TOKEN = 'cubbo-demo-2026';\nconst CUBBO_KEY = 'cubbo_demo_2026_k7Rp9xQm';\nconst SEARCH_URL = 'https://cubbo-app.data2apis.com/rush/cubbo-picking-search';\n\nconst LOGO_SVG = (color, h) => `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 91 32\" height=\"${h}\" style=\"color:${color}\"><path d=\"M56.6655 8.91406C57.5045 8.91406 58.2671 8.91406 59.106 8.91406C59.106 8.99025 59.106 9.14263 59.106 9.21882C59.106 10.6664 59.106 12.1141 59.106 13.6379C59.106 13.7141 59.106 13.7903 59.106 13.9426C59.1823 13.8664 59.2586 13.8664 59.2586 13.7903C59.945 13.0283 60.8601 12.6474 61.8516 12.5712C62.6905 12.495 63.5294 12.6474 64.2921 13.0283C65.5124 13.7141 66.4275 14.7807 66.8089 16.1522C67.1902 17.5998 67.1139 18.9712 66.3513 20.2664C65.7412 21.3331 64.9022 22.1712 63.682 22.5522C62.7668 22.8569 61.8516 22.8569 60.9364 22.5522C60.3263 22.3998 59.7924 22.0188 59.3348 21.5617C59.2586 21.4855 59.2586 21.4093 59.106 21.3331C59.0298 21.7141 59.106 22.095 59.106 22.476C58.2671 22.476 57.5045 22.476 56.6655 22.476C56.6655 18.0569 56.6655 13.4855 56.6655 8.91406ZM61.9279 20.495C62.6905 20.495 63.4532 20.1903 63.987 19.4283C64.3684 18.895 64.5209 18.2093 64.5209 17.5236C64.5209 16.9141 64.2921 16.3807 63.9108 15.9236C63.3007 15.1617 62.4617 14.8569 61.5465 15.0093C60.4788 15.0855 59.5636 15.8474 59.2586 16.9141C59.1823 17.295 59.106 17.676 59.1823 18.1331C59.3348 19.5045 60.4025 20.495 61.9279 20.495Z\" fill=\"currentColor\"/><path d=\"M68.8682 8.91406C69.6308 8.91406 70.4697 8.91406 71.3087 8.91406C71.3087 9.14263 71.3087 9.4474 71.3087 9.75216C71.3087 10.0569 71.3087 10.2855 71.3087 10.5903C71.3087 10.895 71.3087 11.1236 71.3087 11.4283C71.3087 11.7331 71.3087 11.9617 71.3087 12.2664C71.3087 12.5712 71.3087 12.7998 71.3087 13.1045C71.3087 13.4093 71.3087 13.6379 71.3087 13.9426C71.3849 13.8664 71.4612 13.7903 71.4612 13.7903C72.1476 13.0283 72.9865 12.6474 74.0542 12.5712C74.8932 12.495 75.7321 12.6474 76.4947 13.0283C77.9438 13.7903 78.7827 15.0093 79.0878 16.6855C79.3166 17.7522 79.2403 18.895 78.7827 19.8855C78.2489 21.1045 77.4099 22.0188 76.1134 22.5522C74.8932 23.0093 73.6729 23.0093 72.5289 22.3998C72.1476 22.2474 71.8425 21.9426 71.5375 21.6379C71.4612 21.5617 71.4612 21.5617 71.3087 21.4093C71.3087 21.7903 71.3087 22.1712 71.3087 22.476C71.0799 22.5522 69.3258 22.5522 68.8682 22.476C68.8682 22.3998 68.8682 9.21882 68.8682 8.91406ZM76.7235 17.676C76.7235 16.9903 76.4947 16.3045 75.9609 15.7712C75.427 15.2379 74.7406 14.9331 73.978 15.0093C73.2916 15.0093 72.6815 15.2379 72.1476 15.695C71.1561 16.6093 71.0799 18.2093 71.6137 19.1998C72.0713 20.0379 72.834 20.495 73.8254 20.5712C74.5118 20.6474 75.1982 20.4188 75.7321 19.9617C76.4185 19.3522 76.7235 18.5903 76.7235 17.676Z\" fill=\"currentColor\"/><path d=\"M43.7765 11.8858C43.0139 12.3429 42.2512 12.8001 41.4885 13.181C41.4885 13.1048 41.4123 13.1048 41.4123 13.1048C40.8021 12.1144 39.9632 11.581 38.8955 11.3525C37.904 11.1239 36.9126 11.2001 35.9974 11.6572C34.9297 12.1905 34.167 13.0286 33.7857 14.1715C33.4806 15.2382 33.4044 16.3048 33.7857 17.3715C34.3195 19.0477 35.5398 19.962 37.2939 20.1905C38.1328 20.2667 38.9718 20.1905 39.7344 19.8858C40.4208 19.581 41.0309 19.1239 41.4123 18.4382C41.4123 18.362 41.4885 18.362 41.4885 18.2858C42.2512 18.7429 43.0139 19.1239 43.7765 19.581C43.7002 19.6572 43.7002 19.7334 43.624 19.8096C42.7851 21.1048 41.5648 22.0191 40.0395 22.4763C38.0566 23.0858 36.1499 22.9334 34.3958 21.9429C32.4892 20.8763 31.3452 19.2001 30.9639 16.9905C30.7351 15.6191 30.8113 14.2477 31.4214 12.9525C32.4129 10.6667 34.0908 9.29531 36.5313 8.76198C38.0566 8.45721 39.5819 8.60959 40.9547 9.29531C42.0224 9.82864 42.9376 10.5905 43.624 11.581C43.624 11.6572 43.7002 11.7334 43.7765 11.8858Z\" fill=\"currentColor\"/><path d=\"M90.7561 17.7523C90.7561 20.6475 88.4682 22.9332 85.5701 22.857C82.7482 22.857 80.4603 20.4951 80.5365 17.5999C80.5365 14.7808 82.9008 12.4951 85.7226 12.4951C88.3919 12.5713 90.7561 14.857 90.7561 17.7523ZM88.2394 17.7523C88.2394 17.1427 88.0868 16.6094 87.7818 16.1523C87.1716 15.3142 86.409 15.0094 85.4175 15.0094C84.5023 15.0856 83.8159 15.4665 83.2821 16.3046C82.977 16.838 82.9008 17.4475 82.977 18.057C83.2058 20.1904 85.4175 21.0285 86.9428 20.1142C87.858 19.5808 88.2394 18.7427 88.2394 17.7523Z\" fill=\"currentColor\"/><path d=\"M47.8186 12.876C47.8186 13.0284 47.8186 13.1046 47.8186 13.1808C47.8186 14.9332 47.8186 16.6855 47.8186 18.3617C47.8186 18.5903 47.8186 18.8951 47.8949 19.1236C48.0474 19.9617 48.6575 20.4951 49.5727 20.4951C49.8778 20.4951 50.1829 20.4951 50.4117 20.4189C51.1743 20.2665 51.6319 19.7332 51.7844 18.9713C51.8607 18.6665 51.8607 18.2855 51.8607 17.9808C51.8607 16.3808 51.8607 14.7808 51.8607 13.1046C51.8607 13.0284 51.8607 12.876 51.8607 12.7998C52.0132 12.7236 53.9199 12.7236 54.3012 12.7998C54.3775 12.9522 54.3775 22.1713 54.3012 22.476C54.1487 22.5522 52.1658 22.5522 51.8607 22.476C51.8607 22.1713 51.8607 21.7903 51.8607 21.4093C51.7844 21.4855 51.7082 21.5617 51.7082 21.5617C51.1743 22.2474 50.4879 22.5522 49.5727 22.7046C48.9626 22.7808 48.3525 22.7808 47.7424 22.5522C46.5221 22.1713 45.7594 21.257 45.3781 20.0379C45.3019 19.657 45.2256 19.1998 45.2256 18.8189C45.2256 16.8379 45.2256 14.9332 45.2256 12.9522C45.2256 12.876 45.2256 12.7998 45.2256 12.7236C46.1408 12.876 46.9797 12.876 47.8186 12.876Z\" fill=\"currentColor\"/><path d=\"M12.8892 21.2572V31.5429L25.3968 26.0572V15.8477L12.8892 21.2572Z\" fill=\"currentColor\"/><path d=\"M12.2788 0.0761719L0 5.4857V15.7714L12.2788 10.2857V0.0761719Z\" fill=\"currentColor\"/><path d=\"M12.8892 0V10.2857L20.5157 13.4095V3.27619L12.8892 0Z\" fill=\"currentColor\"/><path d=\"M12.2788 21.2572L0 15.8477V26.1334L12.2788 31.6191V21.2572Z\" fill=\"currentColor\"/></svg>`;\n\nfunction esc(s) {\n  return String(s == null ? '' : s).replace(/[&<>\"']/g, (c) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;', \"'\": '&#39;' }[c]));\n}\nfunction fmtDateTime(iso) {\n  if (!iso) return '—';\n  try {\n    const d = new Date(iso);\n    return d.toLocaleDateString('pt-BR') + ' ' + d.toLocaleTimeString('pt-BR', { hour: '2-digit', minute: '2-digit' });\n  } catch (e) { return String(iso); }\n}\nfunction fmtClock(iso) {\n  if (!iso) return '—';\n  try { return new Date(iso).toLocaleTimeString('pt-BR', { hour: '2-digit', minute: '2-digit', second: '2-digit' }); } catch (e) { return String(iso); }\n}\nfunction fmtDur(sec) {\n  if (sec == null || sec === '') return '—';\n  const n = Number(sec);\n  if (!isFinite(n)) return '—';\n  if (n < 60) return n + 's';\n  const m = Math.floor(n / 60);\n  const r = n % 60;\n  return m + 'm' + (r < 10 ? '0' : '') + r + 's';\n}\nfunction plural(n, one, many) { return n === 1 ? one : many; }\nfunction clampPct(v) {\n  const n = Number(v);\n  if (!isFinite(n)) return 0;\n  return Math.max(0, Math.min(100, Math.round(n)));\n}\nconst VERDICT = {\n  ok: { label: 'Conferido', cls: 'v-ok' },\n  not_in_order: { label: 'Fora do pedido', cls: 'v-bad' },\n  over_qty: { label: 'Quantidade acima', cls: 'v-warn' },\n};\n\nfunction chipHtml(o) {\n  const st = o.status || 'pending';\n  const pct = clampPct(o.completionPct);\n  let cls = 'pend';\n  let label = 'pode bipar';\n  if (st === 'picked') { cls = 'ok'; label = 'separado ' + pct + '%'; }\n  else if (st === 'picked_with_divergence') { cls = 'div'; label = 'divergência ' + pct + '%'; }\n  const tip = [o.customerName, (o.city || '') + (o.city && o.state ? '/' : '') + (o.state || ''), (o.itemsCount || 0) + ' ' + plural(o.itemsCount || 0, 'item', 'itens')]\n    .filter(Boolean).join(' · ');\n  return `<div class=\"chip ${cls}\" data-key=\"${esc(o.orderCode)}\" title=\"${esc(tip)}\">\n    <span class=\"chip-code\">${esc(o.orderCode)}</span>\n    <span class=\"chip-lbl\">${esc(label)}</span>\n  </div>`;\n}\n\nfunction bandHtml(s) {\n  const orders = (s.orders || []).slice().sort((a, b) => String(a.orderCode).localeCompare(String(b.orderCode)));\n  const total = s.ordersTotal || orders.length || 0;\n  const picked = s.ordersPicked == null ? orders.filter((o) => o.status && o.status !== 'pending').length : s.ordersPicked;\n  const pending = s.ordersPending == null ? Math.max(0, total - picked) : s.ordersPending;\n\n  const resetZone = s.resetConfirm ? `\n      <div class=\"reset-confirm\">\n        <span class=\"reset-hint\">Digite <b>RESET</b> para confirmar</span>\n        <input class=\"js-reset-input mono-input\" type=\"text\" placeholder=\"RESET\" autocomplete=\"off\" spellcheck=\"false\" />\n        <button class=\"btn btn-danger js-reset-go\" disabled>${s.resetBusy ? 'Resetando…' : 'Confirmar reset'}</button>\n        <button class=\"btn btn-ghost js-reset-cancel\" ${s.resetBusy ? 'disabled' : ''}>Cancelar</button>\n      </div>` : `\n      <div class=\"band-actions\">\n        <button class=\"btn btn-ghost js-refresh\">${s.ordersLoading || s.loading ? 'Atualizando…' : 'Atualizar'}</button>\n        <button class=\"btn btn-danger-ghost js-reset-open\">Resetar demo</button>\n      </div>`;\n\n  const notice = s.resetError\n    ? `<div class=\"note note-bad\">${esc(s.resetError)}</div>`\n    : (s.resetResult\n      ? `<div class=\"note note-ok\">${esc(s.resetResult.deleted)} ${plural(s.resetResult.deleted, 'registro apagado', 'registros apagados')}, ${esc(s.resetResult.orders)} ${plural(s.resetResult.orders, 'pedido devolvido', 'pedidos devolvidos')} para pendente${s.resetResult.at ? ' · ' + esc(fmtClock(s.resetResult.at)) : ''}. As folhas impressas voltaram a valer.</div>`\n      : '');\n\n  return `\n    <div class=\"card band\">\n      <div class=\"band-head\">\n        <div>\n          <div class=\"band-stat\"><b>${esc(picked)}</b> de <b>${esc(total)}</b> ${plural(total, 'pedido separado', 'pedidos separados')} <span class=\"sep\">·</span> <b>${esc(pending)}</b> ${plural(pending, 'folha ainda válida', 'folhas ainda válidas')}</div>\n          <div class=\"band-sub\">Cada pedido corresponde a uma folha A4 impressa. Resetar a demo devolve as 12 folhas ao estado inicial.</div>\n        </div>\n        ${resetZone}\n      </div>\n      ${notice}\n      ${s.ordersError ? `<div class=\"note note-bad\">${esc(s.ordersError)}</div>` : ''}\n      ${orders.length\n        ? `<div class=\"chips\">${orders.map(chipHtml).join('')}</div>`\n        : `<div class=\"chips-empty\">${s.ordersLoading ? 'Lendo o estado dos pedidos…' : 'Estado dos pedidos indisponível.'}</div>`}\n      <div class=\"legend\">\n        <span><i class=\"dot dot-pend\"></i>pendente — pode bipar</span>\n        <span><i class=\"dot dot-ok\"></i>separado integralmente</span>\n        <span><i class=\"dot dot-div\"></i>separado com divergência</span>\n      </div>\n    </div>`;\n}\n\nfunction detailHtml(o) {\n  const chk = o.checklist || [];\n  const divs = o.divergences || [];\n  const trail = o.scanTrail || [];\n\n  const chkRows = chk.map((it) => {\n    const exp = Number(it.expectedQty || 0);\n    const got = Number(it.pickedQty || 0);\n    const miss = got < exp;\n    return `<tr class=\"${miss ? 'miss-row' : ''}\">\n      <td>\n        <div class=\"${miss ? 'miss' : 'item-name'}\">${esc(it.name)}</div>\n        <div class=\"mono muted\">${esc(it.sku)} · ${esc(it.ean)}</div>\n      </td>\n      <td class=\"qty ${miss ? 'miss' : ''}\">${got}/${exp}${miss ? ` <span class=\"tag tag-bad\">faltou ${exp - got}</span>` : ''}</td>\n    </tr>`;\n  }).join('');\n\n  const divBlocks = divs.length ? divs.map((dv) => `\n    <div class=\"dv\">\n      <span class=\"tag tag-warn\">${esc(dv.reasonLabel || dv.reasonCode || 'Divergência')}</span>\n      <div class=\"dv-item\">${esc(dv.name)} <span class=\"mono muted\">${esc(dv.sku)}</span></div>\n      <div class=\"muted\">Esperado ${esc(dv.expectedQty)} · conferido ${esc(dv.pickedQty)}</div>\n      ${dv.note ? `<div class=\"dv-note\">“${esc(dv.note)}”</div>` : ''}\n    </div>`).join('') : '<div class=\"muted\">Nenhuma. Pedido conferido integralmente.</div>';\n\n  const trailRows = trail.map((t, i) => {\n    const v = VERDICT[t.verdict] || { label: String(t.verdict || '—'), cls: 'v-warn' };\n    return `<tr>\n      <td class=\"muted mono\">${i + 1}</td>\n      <td class=\"mono\">${esc(t.ean)}</td>\n      <td class=\"muted\">${esc(fmtClock(t.at))}</td>\n      <td><span class=\"vp ${v.cls}\" data-verdict=\"${esc(t.verdict)}\">${esc(v.label)}</span></td>\n    </tr>`;\n  }).join('');\n\n  return `<tr class=\"detail\" data-key=\"detail-${esc(o._id)}\">\n    <td colspan=\"11\">\n      <div class=\"detail-in\">\n        <div class=\"panel\">\n          <div class=\"panel-title\">Checklist &mdash; ${chk.length} ${plural(chk.length, 'SKU', 'SKUs')} · ${esc(o.pickedCount == null ? 0 : o.pickedCount)}/${esc(o.expectedCount == null ? 0 : o.expectedCount)} unidades conferidas</div>\n          <table class=\"mini\">${chkRows || '<tr><td class=\"muted\">Sem checklist gravado.</td></tr>'}</table>\n        </div>\n        <div class=\"panel\">\n          <div class=\"panel-title\">Divergências &mdash; ${divs.length}</div>\n          ${divBlocks}\n        </div>\n        <div class=\"panel\">\n          <div class=\"panel-title\">Rastro de bipes &mdash; ${trail.length}</div>\n          <table class=\"mini\">${trailRows || '<tr><td class=\"muted\">Sem bipes gravados.</td></tr>'}</table>\n          <div class=\"panel-foot\">Bipes marcados como <b>Fora do pedido</b> são leituras de itens que não pertencem a este pedido.</div>\n        </div>\n      </div>\n    </td>\n  </tr>`;\n}\n\nfunction rowHtml(o, expanded) {\n  const pct = clampPct(o.completionPct);\n  const full = pct >= 100 && !o.hasDivergence;\n  const divs = o.divergences || [];\n  const first = divs[0];\n  return `<tr class=\"row js-row${expanded ? ' open' : ''}\" data-key=\"${esc(o._id)}\" data-id=\"${esc(o._id)}\">\n    <td class=\"nowrap\"><span class=\"caret\">${expanded ? '▾' : '▸'}</span> ${esc(fmtDateTime(o.createdAt))}</td>\n    <td>${esc(o.operatorName)}</td>\n    <td class=\"mono\">${esc(o.orderCode)}</td>\n    <td class=\"mono\">${esc(o.boxCode)}</td>\n    <td>${esc(o.customerName)}<br/><span class=\"mono muted\">${esc(o.customerCode)}</span></td>\n    <td class=\"nowrap\">${esc(o.city)}${o.city && o.state ? '/' : ''}${esc(o.state)}</td>\n    <td class=\"nowrap\">\n      <div class=\"pct ${full ? 'pct-ok' : 'pct-warn'}\">${pct}%</div>\n      <div class=\"bar\"><i class=\"${full ? 'fill-ok' : 'fill-warn'}\" style=\"width:${pct}%\"></i></div>\n    </td>\n    <td>${o.hasDivergence && first\n      ? `<span class=\"tag tag-warn\">${esc(first.reasonLabel || first.reasonCode || 'Divergência')}</span>${divs.length > 1 ? `<span class=\"more\">+${divs.length - 1}</span>` : ''}`\n      : '<span class=\"dash\">—</span>'}</td>\n    <td class=\"nowrap\">${o.measuredWeightKg != null ? esc(Number(o.measuredWeightKg).toFixed(2)) + ' kg' : '<span class=\"dash\">—</span>'}</td>\n    <td class=\"nowrap\">${esc(fmtDur(o.durationSec))}</td>\n    <td class=\"nowrap\">${o.videoUrl\n      ? `<a class=\"vlink\" href=\"${esc(o.videoUrl)}\" target=\"_blank\" rel=\"noopener\">Ver vídeo &rarr;</a>`\n      : '<span class=\"dash\">—</span>'}</td>\n  </tr>`;\n}\n\nexport default {\n  css: `\n    :host { display:block; height:100%; width:100%; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Inter,Roboto,sans-serif; }\n    .app { height:100%; width:100%; background:#F4F5FA; display:flex; flex-direction:column; }\n    .topbar { background:#0B1120; color:#fff; padding:14px 24px; display:flex; align-items:center; justify-content:space-between; flex-shrink:0; }\n    .topbar-left { display:flex; align-items:center; gap:14px; }\n    .topbar-title { font-size:14px; font-weight:600; color:#C7CBE0; letter-spacing:.02em; border-left:1px solid #2A2F45; padding-left:14px; }\n    .topbar-right { font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:11.5px; color:#6E77A0; }\n    .gate-wrap { flex:1; display:flex; align-items:center; justify-content:center; padding:24px; }\n    .gate-card { background:#fff; border:1px solid #E4E6F0; border-radius:16px; padding:40px; width:100%; max-width:380px; text-align:center; }\n    .logo-chip { display:inline-flex; align-items:center; justify-content:center; background:#0B1120; border-radius:10px; padding:10px 16px; }\n    .gate-card input { width:100%; box-sizing:border-box; padding:12px 14px; border-radius:10px; border:1px solid #D6D9EA; font-size:15px; margin-top:18px; text-align:center; letter-spacing:.05em; }\n    .gate-card input:focus { outline:none; border-color:#4338CA; }\n    .gate-error { color:#DC2626; font-size:13px; margin-top:10px; min-height:16px; }\n    .content { flex:1; overflow-y:auto; padding:24px 32px 32px; }\n\n    .btn { background:#4338CA; color:#fff; border:none; border-radius:10px; padding:10px 16px; font-size:13.5px; font-weight:600; cursor:pointer; }\n    .btn:hover { background:#3730A3; }\n    .btn:disabled { opacity:.45; cursor:default; }\n    .btn-ghost { background:#fff; color:#3F4460; border:1px solid #D6D9EA; }\n    .btn-ghost:hover { background:#F4F5FA; }\n    .btn-danger-ghost { background:#fff; color:#B91C1C; border:1px solid #F0C9C9; }\n    .btn-danger-ghost:hover { background:#FEE2E2; }\n    .btn-danger { background:#B91C1C; }\n    .btn-danger:hover { background:#991B1B; }\n\n    .card { background:#fff; border:1px solid #E4E6F0; border-radius:14px; }\n    .band { padding:18px 20px; margin-bottom:20px; }\n    .band-head { display:flex; align-items:flex-start; justify-content:space-between; gap:20px; flex-wrap:wrap; }\n    .band-stat { font-size:15px; color:#1F2233; }\n    .band-stat b { font-weight:700; }\n    .band-stat .sep { color:#C3C7DA; margin:0 4px; }\n    .band-sub { font-size:12.5px; color:#8B8FA8; margin-top:4px; max-width:520px; }\n    .band-actions { display:flex; gap:8px; flex-shrink:0; }\n    .reset-confirm { display:flex; align-items:center; gap:8px; flex-wrap:wrap; flex-shrink:0; }\n    .reset-hint { font-size:12.5px; color:#8B8FA8; }\n    .reset-hint b { color:#B91C1C; font-family:ui-monospace,SFMono-Regular,Menlo,monospace; }\n    .mono-input { width:120px; box-sizing:border-box; padding:9px 12px; border-radius:10px; border:1px solid #D6D9EA; font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:13px; letter-spacing:.08em; text-transform:uppercase; }\n    .mono-input:focus { outline:none; border-color:#B91C1C; }\n\n    .note { margin-top:14px; font-size:13px; padding:9px 12px; border-radius:10px; }\n    .note-ok { background:#DCFCE7; color:#15803D; }\n    .note-bad { background:#FEE2E2; color:#B91C1C; }\n\n    .chips { margin-top:16px; display:grid; grid-template-columns:repeat(auto-fill,minmax(124px,1fr)); gap:8px; }\n    .chip { border:1px solid #E4E6F0; border-radius:10px; padding:8px 10px; display:flex; flex-direction:column; gap:2px; background:#F8F8FC; }\n    .chip-code { font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:12.5px; font-weight:700; color:#3F4460; }\n    .chip-lbl { font-size:10.5px; text-transform:uppercase; letter-spacing:.04em; color:#8B8FA8; font-weight:600; }\n    .chip.ok { background:#DCFCE7; border-color:#BBF7D0; }\n    .chip.ok .chip-code { color:#15803D; }\n    .chip.ok .chip-lbl { color:#15803D; }\n    .chip.div { background:#FEF3C7; border-color:#FDE68A; }\n    .chip.div .chip-code { color:#92600B; }\n    .chip.div .chip-lbl { color:#92600B; }\n    .chips-empty { margin-top:16px; font-size:13px; color:#8B8FA8; }\n    .legend { margin-top:12px; display:flex; gap:16px; flex-wrap:wrap; font-size:11.5px; color:#8B8FA8; }\n    .legend span { display:inline-flex; align-items:center; gap:6px; }\n    .dot { width:8px; height:8px; border-radius:3px; display:inline-block; }\n    .dot-pend { background:#D6D9EA; }\n    .dot-ok { background:#15803D; }\n    .dot-div { background:#D69E14; }\n\n    .section-head { display:flex; align-items:baseline; justify-content:space-between; gap:16px; margin:0 0 12px; flex-wrap:wrap; }\n    .section-title { font-size:15px; font-weight:700; color:#1F2233; }\n    .section-count { font-size:12.5px; color:#8B8FA8; }\n    .search-row { display:flex; gap:10px; max-width:520px; }\n    .search-row input { flex:1; box-sizing:border-box; padding:10px 14px; border-radius:10px; border:1px solid #D6D9EA; font-size:14px; }\n    .search-row input:focus { outline:none; border-color:#4338CA; }\n\n    .table-wrap { overflow-x:auto; background:#fff; border:1px solid #E4E6F0; border-radius:12px; }\n    table.main { width:100%; border-collapse:collapse; }\n    th { text-align:left; font-size:11px; text-transform:uppercase; letter-spacing:.05em; color:#8B8FA8; background:#F8F8FC; padding:11px 14px; border-bottom:1px solid #E4E6F0; white-space:nowrap; }\n    td { padding:12px 14px; font-size:13px; color:#1F2233; border-bottom:1px solid #F0F1F6; vertical-align:top; }\n    tr:last-child td { border-bottom:none; }\n    tr.row { cursor:pointer; }\n    tr.row:hover td { background:#FAFAFE; }\n    tr.row.open td { background:#F6F7FD; border-bottom-color:#E4E6F0; }\n    .caret { color:#8B8FA8; font-size:10px; margin-right:2px; }\n    .nowrap { white-space:nowrap; }\n    .mono { font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:12px; color:#4338CA; }\n    .muted { color:#8B8FA8; }\n    .item-name { color:#1F2233; }\n    .dash { color:#C3C7DA; }\n    .vlink { color:#4338CA; font-weight:600; text-decoration:none; font-size:12.5px; }\n    .vlink:hover { text-decoration:underline; }\n    .pct { font-size:13px; font-weight:700; margin-bottom:5px; }\n    .pct-ok { color:#15803D; }\n    .pct-warn { color:#92600B; }\n    .bar { width:68px; height:4px; background:#EDEEF5; border-radius:999px; overflow:hidden; }\n    .bar i { display:block; height:100%; border-radius:999px; }\n    .fill-ok { background:#15803D; }\n    .fill-warn { background:#D69E14; }\n    .tag { display:inline-block; font-size:11px; font-weight:700; padding:3px 8px; border-radius:999px; }\n    .tag-warn { background:#FEF3C7; color:#92600B; }\n    .tag-bad { background:#FEE2E2; color:#B91C1C; }\n    .more { font-size:11px; font-weight:700; color:#92600B; margin-left:6px; }\n\n    tr.detail td { background:#FBFBFE; padding:0; border-bottom:1px solid #E4E6F0; }\n    .detail-in { padding:18px 20px; display:grid; grid-template-columns:repeat(auto-fit,minmax(268px,1fr)); gap:22px; }\n    .panel-title { font-size:11px; text-transform:uppercase; letter-spacing:.05em; color:#8B8FA8; font-weight:700; margin-bottom:9px; }\n    .panel-foot { font-size:11.5px; color:#8B8FA8; margin-top:9px; }\n    table.mini { width:100%; border-collapse:collapse; }\n    table.mini td { padding:6px 8px 6px 0; font-size:12.5px; border-bottom:1px solid #EFF0F6; vertical-align:top; }\n    table.mini tr:last-child td { border-bottom:none; }\n    .qty { font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:12.5px; text-align:right; white-space:nowrap; color:#3F4460; }\n    .miss { color:#B91C1C; font-weight:700; }\n    tr.miss-row td:first-child { box-shadow:inset 2px 0 0 #B91C1C; padding-left:8px; }\n    .dv { border-left:2px solid #FDE68A; padding:2px 0 2px 10px; margin-bottom:12px; }\n    .dv:last-child { margin-bottom:0; }\n    .dv-item { font-size:12.5px; color:#1F2233; margin-top:6px; }\n    .dv-note { font-size:12.5px; color:#5B5F78; background:#F8F8FC; border-radius:8px; padding:6px 9px; margin-top:6px; }\n    .vp { display:inline-block; font-size:10.5px; font-weight:700; padding:2px 7px; border-radius:999px; white-space:nowrap; }\n    .v-ok { background:#DCFCE7; color:#15803D; }\n    .v-warn { background:#FEF3C7; color:#92600B; }\n    .v-bad { background:#FEE2E2; color:#B91C1C; }\n\n    .empty { text-align:center; padding:56px 20px; color:#8B8FA8; font-size:13px; background:#fff; border:1px solid #E4E6F0; border-radius:12px; }\n    .api-box { margin-top:24px; background:#0B1120; border-radius:14px; padding:20px 24px; }\n    .api-box .lbl { font-size:11px; text-transform:uppercase; letter-spacing:.06em; color:#818CF8; font-weight:700; }\n    .api-box .desc { font-size:12.5px; color:#9CA3D4; margin:6px 0 12px; max-width:640px; }\n    .api-box code { display:block; background:#161B2E; color:#D7DAF0; font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:12px; padding:12px 14px; border-radius:8px; white-space:pre-wrap; word-break:break-all; }\n  `,\n  render(d2) {\n    const s = d2.state;\n    if (!s.unlocked) {\n      return `\n        <div class=\"app\">\n          <div class=\"gate-wrap\">\n            <div class=\"gate-card\">\n              <div class=\"logo-chip\">${LOGO_SVG('#fff', 26)}</div>\n              <div style=\"margin-top:14px;font-size:14px;color:#5B5F78;\">Painel Operacional &mdash; acesso restrito</div>\n              <input class=\"js-gate-input\" type=\"password\" placeholder=\"Senha de acesso\" />\n              <div class=\"gate-error\">${esc(s.gateError || '')}</div>\n              <div style=\"margin-top:6px;\"><button class=\"btn js-gate-submit\" style=\"width:100%;\">Entrar</button></div>\n            </div>\n          </div>\n        </div>`;\n    }\n\n    const rows = s.rows || [];\n    const expandedId = s.expandedId || null;\n    const body = rows.map((o) => rowHtml(o, expandedId === o._id) + (expandedId === o._id ? detailHtml(o) : '')).join('');\n\n    return `\n      <div class=\"app\">\n        <div class=\"topbar\">\n          <div class=\"topbar-left\">\n            ${LOGO_SVG('#fff', 22)}\n            <div class=\"topbar-title\">Painel Operacional</div>\n          </div>\n          <div class=\"topbar-right\">cubbo-app.data2apis.com</div>\n        </div>\n        <div class=\"content\">\n          ${bandHtml(s)}\n\n          <div class=\"section-head\">\n            <div>\n              <div class=\"section-title\">Pickings registrados</div>\n              <div class=\"section-count\">${s.loading ? 'Carregando…' : `${rows.length} ${plural(rows.length, 'registro', 'registros')}${s.query ? ` para “${esc(s.query)}”` : ''}`}</div>\n            </div>\n            <div class=\"search-row\">\n              <input class=\"js-search-input\" type=\"text\" placeholder=\"Pedido, caixa, cliente ou operador…\" value=\"${esc(s.query || '')}\" />\n              <button class=\"btn js-search-btn\">Buscar</button>\n            </div>\n          </div>\n          ${\n            s.loading ? '<div class=\"empty\">Carregando…</div>' :\n            rows.length ? `\n            <div class=\"table-wrap\">\n              <table class=\"main\">\n                <thead><tr>\n                  <th>Quando</th><th>Operador</th><th>Pedido</th><th>Caixa</th><th>Cliente</th><th>Cidade/UF</th><th>Completude</th><th>Divergência</th><th>Peso</th><th>Duração</th><th>Vídeo</th>\n                </tr></thead>\n                <tbody>${body}</tbody>\n              </table>\n            </div>\n            <div class=\"section-count\" style=\"margin-top:10px;\">Clique em uma linha para abrir o checklist, as divergências e o rastro de bipes.</div>` :\n            `<div class=\"empty\">${s.query\n              ? `Nenhum picking encontrado para “${esc(s.query)}”.`\n              : 'Nenhum picking registrado ainda. Bipe uma caixa na Estação de Picking para gerar o primeiro registro.'}</div>`\n          }\n          <div class=\"api-box\">\n            <div class=\"lbl\">Acesso via API</div>\n            <div class=\"desc\">Os mesmos dados deste painel estão disponíveis via API REST, autenticada por chave, para integração com o WMS ou o ERP do cliente.</div>\n            <code>curl -X POST ${SEARCH_URL} \\\\\n  -H \"Content-Type: application/json\" \\\\\n  -H \"x-api-key: ${CUBBO_KEY}\" \\\\\n  -d '{\"q\": \"CUB-\"}'</code>\n          </div>\n        </div>\n      </div>\n    `;\n  },\n  mounted(d2) {\n    const opts = { headers: { 'x-api-key': CUBBO_KEY } };\n\n    async function loadOrders() {\n      d2.setState({ ordersLoading: true });\n      try {\n        const res = await d2.rush('cubbo-orders-status').invoke({}, opts);\n        const out = (res && res.data) || {};\n        d2.setState({\n          ordersLoading: false,\n          ordersError: '',\n          orders: out.orders || [],\n          ordersTotal: out.total || 0,\n          ordersPending: out.pending || 0,\n          ordersPicked: out.picked || 0,\n        });\n      } catch (e) {\n        d2.setState({ ordersLoading: false, ordersError: 'Não foi possível ler o estado dos 12 pedidos.' });\n      }\n    }\n\n    async function doSearch(q) {\n      d2.setState({ loading: true, query: q || '' });\n      try {\n        const res = await d2.rush('cubbo-picking-search').invoke({ q: q || '' }, opts);\n        const out = (res && res.data) || {};\n        d2.setState({ loading: false, rows: out.data || [], searchError: '' });\n      } catch (e) {\n        d2.setState({ loading: false, rows: [], searchError: 'Falha ao buscar os pickings.' });\n      }\n    }\n\n    function loadAllData() {\n      loadOrders();\n      doSearch(d2.state.query || '');\n    }\n\n    async function runReset() {\n      const el = d2.$('.js-reset-input');\n      const typed = el ? String(el.value || '').trim().toUpperCase() : '';\n      if (typed !== 'RESET') { d2.setState({ resetError: 'Digite RESET para confirmar.' }); return; }\n      d2.setState({ resetBusy: true, resetError: '', resetResult: null });\n      try {\n        const res = await d2.rush('cubbo-demo-reset').invoke({ token: RESET_TOKEN }, opts);\n        const out = (res && res.data) || {};\n        d2.setState({\n          resetBusy: false,\n          resetConfirm: false,\n          expandedId: null,\n          resetResult: { deleted: out.recordsDeleted || 0, orders: out.ordersReset || 0, at: out.at || '' },\n        });\n        loadAllData();\n      } catch (e) {\n        d2.setState({ resetBusy: false, resetError: 'Falha ao resetar a demo. Tente novamente.' });\n      }\n    }\n\n    d2.on('.js-search-btn', 'click', () => {\n      const el = d2.$('.js-search-input');\n      doSearch(el ? el.value : '');\n    });\n    d2.on('.js-search-input', 'keydown', (e) => {\n      if (e.key === 'Enter') {\n        const el = d2.$('.js-search-input');\n        doSearch(el ? el.value : '');\n      }\n    });\n    d2.on('.js-refresh', 'click', () => { loadAllData(); });\n\n    d2.on('.js-reset-open', 'click', () => { d2.setState({ resetConfirm: true, resetError: '', resetResult: null }); });\n    d2.on('.js-reset-cancel', 'click', () => { d2.setState({ resetConfirm: false, resetError: '' }); });\n    d2.on('.js-reset-input', 'input', () => {\n      const el = d2.$('.js-reset-input');\n      const btn = d2.$('.js-reset-go');\n      if (el && btn) btn.disabled = String(el.value || '').trim().toUpperCase() !== 'RESET';\n    });\n    d2.on('.js-reset-input', 'keydown', (e) => { if (e.key === 'Enter') runReset(); });\n    d2.on('.js-reset-go', 'click', () => { runReset(); });\n\n    d2.on('.js-row', 'click', (e) => {\n      const t = e.target;\n      if (!t || !t.closest) return;\n      if (t.closest('a')) return;\n      const tr = t.closest('.js-row');\n      const id = tr ? tr.getAttribute('data-id') : null;\n      if (!id) return;\n      d2.setState({ expandedId: d2.state.expandedId === id ? null : id });\n    });\n\n    d2.on('.js-gate-submit', 'click', () => {\n      const val = d2.$('.js-gate-input') ? d2.$('.js-gate-input').value : '';\n      if (val === GATE_PASSWORD) {\n        sessionStorage.setItem('cubboGateOk', '1');\n        d2.setState({ unlocked: true, gateError: '' });\n        loadAllData();\n      } else {\n        d2.setState({ gateError: 'Senha incorreta.' });\n      }\n    });\n    d2.on('.js-gate-input', 'keydown', (e) => { if (e.key === 'Enter') d2.$('.js-gate-submit').click(); });\n\n    if (sessionStorage.getItem('cubboGateOk') === '1') {\n      d2.setState({ unlocked: true });\n      loadAllData();\n    }\n  },\n};\n"}}}}}}}},{"_id":"6a901014266a8719ecfc9e0a","component":"data2-core-types@Component","system":"6a7ca6cb11f8a5ec77c18b42","params":{"extends":"data2-core-primitives@Block","component":"cubbo-track-lookup","package":"cubbo-app","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 GATE_PASSWORD = 'democubodata2';\nconst CUBBO_KEY = 'cubbo_demo_2026_k7Rp9xQm';\n\nconst LOGO_SVG = (color, h) => `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 91 32\" height=\"${h}\" style=\"color:${color}\"><path d=\"M56.6655 8.91406C57.5045 8.91406 58.2671 8.91406 59.106 8.91406C59.106 8.99025 59.106 9.14263 59.106 9.21882C59.106 10.6664 59.106 12.1141 59.106 13.6379C59.106 13.7141 59.106 13.7903 59.106 13.9426C59.1823 13.8664 59.2586 13.8664 59.2586 13.7903C59.945 13.0283 60.8601 12.6474 61.8516 12.5712C62.6905 12.495 63.5294 12.6474 64.2921 13.0283C65.5124 13.7141 66.4275 14.7807 66.8089 16.1522C67.1902 17.5998 67.1139 18.9712 66.3513 20.2664C65.7412 21.3331 64.9022 22.1712 63.682 22.5522C62.7668 22.8569 61.8516 22.8569 60.9364 22.5522C60.3263 22.3998 59.7924 22.0188 59.3348 21.5617C59.2586 21.4855 59.2586 21.4093 59.106 21.3331C59.0298 21.7141 59.106 22.095 59.106 22.476C58.2671 22.476 57.5045 22.476 56.6655 22.476C56.6655 18.0569 56.6655 13.4855 56.6655 8.91406ZM61.9279 20.495C62.6905 20.495 63.4532 20.1903 63.987 19.4283C64.3684 18.895 64.5209 18.2093 64.5209 17.5236C64.5209 16.9141 64.2921 16.3807 63.9108 15.9236C63.3007 15.1617 62.4617 14.8569 61.5465 15.0093C60.4788 15.0855 59.5636 15.8474 59.2586 16.9141C59.1823 17.295 59.106 17.676 59.1823 18.1331C59.3348 19.5045 60.4025 20.495 61.9279 20.495Z\" fill=\"currentColor\"/><path d=\"M68.8682 8.91406C69.6308 8.91406 70.4697 8.91406 71.3087 8.91406C71.3087 9.14263 71.3087 9.4474 71.3087 9.75216C71.3087 10.0569 71.3087 10.2855 71.3087 10.5903C71.3087 10.895 71.3087 11.1236 71.3087 11.4283C71.3087 11.7331 71.3087 11.9617 71.3087 12.2664C71.3087 12.5712 71.3087 12.7998 71.3087 13.1045C71.3087 13.4093 71.3087 13.6379 71.3087 13.9426C71.3849 13.8664 71.4612 13.7903 71.4612 13.7903C72.1476 13.0283 72.9865 12.6474 74.0542 12.5712C74.8932 12.495 75.7321 12.6474 76.4947 13.0283C77.9438 13.7903 78.7827 15.0093 79.0878 16.6855C79.3166 17.7522 79.2403 18.895 78.7827 19.8855C78.2489 21.1045 77.4099 22.0188 76.1134 22.5522C74.8932 23.0093 73.6729 23.0093 72.5289 22.3998C72.1476 22.2474 71.8425 21.9426 71.5375 21.6379C71.4612 21.5617 71.4612 21.5617 71.3087 21.4093C71.3087 21.7903 71.3087 22.1712 71.3087 22.476C71.0799 22.5522 69.3258 22.5522 68.8682 22.476C68.8682 22.3998 68.8682 9.21882 68.8682 8.91406ZM76.7235 17.676C76.7235 16.9903 76.4947 16.3045 75.9609 15.7712C75.427 15.2379 74.7406 14.9331 73.978 15.0093C73.2916 15.0093 72.6815 15.2379 72.1476 15.695C71.1561 16.6093 71.0799 18.2093 71.6137 19.1998C72.0713 20.0379 72.834 20.495 73.8254 20.5712C74.5118 20.6474 75.1982 20.4188 75.7321 19.9617C76.4185 19.3522 76.7235 18.5903 76.7235 17.676Z\" fill=\"currentColor\"/><path d=\"M43.7765 11.8858C43.0139 12.3429 42.2512 12.8001 41.4885 13.181C41.4885 13.1048 41.4123 13.1048 41.4123 13.1048C40.8021 12.1144 39.9632 11.581 38.8955 11.3525C37.904 11.1239 36.9126 11.2001 35.9974 11.6572C34.9297 12.1905 34.167 13.0286 33.7857 14.1715C33.4806 15.2382 33.4044 16.3048 33.7857 17.3715C34.3195 19.0477 35.5398 19.962 37.2939 20.1905C38.1328 20.2667 38.9718 20.1905 39.7344 19.8858C40.4208 19.581 41.0309 19.1239 41.4123 18.4382C41.4123 18.362 41.4885 18.362 41.4885 18.2858C42.2512 18.7429 43.0139 19.1239 43.7765 19.581C43.7002 19.6572 43.7002 19.7334 43.624 19.8096C42.7851 21.1048 41.5648 22.0191 40.0395 22.4763C38.0566 23.0858 36.1499 22.9334 34.3958 21.9429C32.4892 20.8763 31.3452 19.2001 30.9639 16.9905C30.7351 15.6191 30.8113 14.2477 31.4214 12.9525C32.4129 10.6667 34.0908 9.29531 36.5313 8.76198C38.0566 8.45721 39.5819 8.60959 40.9547 9.29531C42.0224 9.82864 42.9376 10.5905 43.624 11.581C43.624 11.6572 43.7002 11.7334 43.7765 11.8858Z\" fill=\"currentColor\"/><path d=\"M90.7561 17.7523C90.7561 20.6475 88.4682 22.9332 85.5701 22.857C82.7482 22.857 80.4603 20.4951 80.5365 17.5999C80.5365 14.7808 82.9008 12.4951 85.7226 12.4951C88.3919 12.5713 90.7561 14.857 90.7561 17.7523ZM88.2394 17.7523C88.2394 17.1427 88.0868 16.6094 87.7818 16.1523C87.1716 15.3142 86.409 15.0094 85.4175 15.0094C84.5023 15.0856 83.8159 15.4665 83.2821 16.3046C82.977 16.838 82.9008 17.4475 82.977 18.057C83.2058 20.1904 85.4175 21.0285 86.9428 20.1142C87.858 19.5808 88.2394 18.7427 88.2394 17.7523Z\" fill=\"currentColor\"/><path d=\"M47.8186 12.876C47.8186 13.0284 47.8186 13.1046 47.8186 13.1808C47.8186 14.9332 47.8186 16.6855 47.8186 18.3617C47.8186 18.5903 47.8186 18.8951 47.8949 19.1236C48.0474 19.9617 48.6575 20.4951 49.5727 20.4951C49.8778 20.4951 50.1829 20.4951 50.4117 20.4189C51.1743 20.2665 51.6319 19.7332 51.7844 18.9713C51.8607 18.6665 51.8607 18.2855 51.8607 17.9808C51.8607 16.3808 51.8607 14.7808 51.8607 13.1046C51.8607 13.0284 51.8607 12.876 51.8607 12.7998C52.0132 12.7236 53.9199 12.7236 54.3012 12.7998C54.3775 12.9522 54.3775 22.1713 54.3012 22.476C54.1487 22.5522 52.1658 22.5522 51.8607 22.476C51.8607 22.1713 51.8607 21.7903 51.8607 21.4093C51.7844 21.4855 51.7082 21.5617 51.7082 21.5617C51.1743 22.2474 50.4879 22.5522 49.5727 22.7046C48.9626 22.7808 48.3525 22.7808 47.7424 22.5522C46.5221 22.1713 45.7594 21.257 45.3781 20.0379C45.3019 19.657 45.2256 19.1998 45.2256 18.8189C45.2256 16.8379 45.2256 14.9332 45.2256 12.9522C45.2256 12.876 45.2256 12.7998 45.2256 12.7236C46.1408 12.876 46.9797 12.876 47.8186 12.876Z\" fill=\"currentColor\"/><path d=\"M12.8892 21.2572V31.5429L25.3968 26.0572V15.8477L12.8892 21.2572Z\" fill=\"currentColor\"/><path d=\"M12.2788 0.0761719L0 5.4857V15.7714L12.2788 10.2857V0.0761719Z\" fill=\"currentColor\"/><path d=\"M12.8892 0V10.2857L20.5157 13.4095V3.27619L12.8892 0Z\" fill=\"currentColor\"/><path d=\"M12.2788 21.2572L0 15.8477V26.1334L12.2788 31.6191V21.2572Z\" fill=\"currentColor\"/></svg>`;\n\nfunction esc(s) {\n  return String(s == null ? '' : s).replace(/[&<>\"']/g, (c) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;', \"'\": '&#39;' }[c]));\n}\nfunction fmtDateTime(iso) {\n  if (!iso) return '—';\n  try {\n    const d = new Date(iso);\n    if (isNaN(d.getTime())) return String(iso);\n    return d.toLocaleString('pt-BR', { day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit' });\n  } catch (e) { return String(iso); }\n}\nfunction fmtDur(sec) {\n  if (sec == null || isNaN(Number(sec))) return '—';\n  const s = Math.round(Number(sec));\n  if (s < 60) return s + 's';\n  return Math.floor(s / 60) + 'm ' + String(s % 60).padStart(2, '0') + 's';\n}\nfunction fmtKg(n) {\n  return n == null || isNaN(Number(n)) ? '—' : Number(n).toFixed(2) + ' kg';\n}\nfunction fmtTime(iso) {\n  if (!iso) return '';\n  try {\n    const d = new Date(iso);\n    if (isNaN(d.getTime())) return '';\n    return d.toLocaleTimeString('pt-BR', { hour: '2-digit', minute: '2-digit', second: '2-digit' });\n  } catch (e) { return ''; }\n}\n\nconst VERDICT = {\n  ok: { label: 'Item conferido', cls: 'v-ok' },\n  not_in_order: { label: 'Item não pertence ao pedido', cls: 'v-bad' },\n  over_qty: { label: 'Quantidade acima do pedido', cls: 'v-bad' },\n};\n\n// Traduz o estado da caixa para linguagem de cliente.\nfunction bannerFor(o, p) {\n  const st = o.status;\n  if (st === 'pending' || (!p && st !== 'picked' && st !== 'picked_with_divergence')) {\n    return {\n      tone: 'b-neutral', glyph: '⋯',\n      title: 'Pedido ainda em separação no CD',\n      sub: 'A conferência ainda não começou. Quando a caixa for separada, o vídeo e o checklist item por item aparecem aqui.',\n    };\n  }\n  const expected = p && p.expectedCount != null ? p.expectedCount : o.itemsCount;\n  const picked = p && p.pickedCount != null ? p.pickedCount : (o.itemsCount != null ? o.itemsCount : null);\n  const divs = (p && p.divergences) || [];\n  const incomplete = st === 'picked_with_divergence' || (p && p.hasDivergence) || (o.completionPct != null && o.completionPct < 100);\n  const counts = (picked == null ? '—' : picked) + ' de ' + (expected == null ? '—' : expected) + ' itens';\n  if (incomplete) {\n    let sub = 'Consulte o detalhe da conferência abaixo.';\n    if (divs.length === 1) {\n      sub = 'Motivo registrado pelo operador: ' + (divs[0].reasonLabel || divs[0].reasonCode || 'não informado') + '.';\n    } else if (divs.length > 1) {\n      sub = divs.length + ' itens com divergência registrada pelo operador — veja o motivo de cada um abaixo.';\n    }\n    return { tone: 'b-warn', glyph: '!', title: 'Pedido enviado incompleto · ' + counts + ' conferidos', sub: sub };\n  }\n  return {\n    tone: 'b-ok', glyph: '✓',\n    title: 'Pedido conferido e enviado completo · ' + counts,\n    sub: 'Cada item foi bipado e gravado em vídeo na estação de picking antes de a caixa ser fechada.',\n  };\n}\n\nexport default {\n  css: `\n    :host { display:block; height:100%; width:100%; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Inter,Roboto,sans-serif; }\n    .app { height:100%; width:100%; background:#F4F5FA; display:flex; flex-direction:column; }\n    .topbar { background:#0B1120; color:#fff; padding:14px 24px; display:flex; align-items:center; justify-content:space-between; flex-shrink:0; }\n    .topbar-left { display:flex; align-items:center; gap:14px; }\n    .topbar-title { font-size:14px; font-weight:600; color:#C7CBE0; letter-spacing:.02em; border-left:1px solid #2A2F45; padding-left:14px; }\n    .gate-wrap { flex:1; display:flex; align-items:center; justify-content:center; padding:24px; }\n    .gate-card { background:#fff; border:1px solid #E4E6F0; border-radius:16px; padding:40px; width:100%; max-width:380px; text-align:center; }\n    .logo-chip { display:inline-flex; align-items:center; justify-content:center; background:#0B1120; border-radius:10px; padding:10px 16px; }\n    .gate-card input { width:100%; box-sizing:border-box; padding:12px 14px; border-radius:10px; border:1px solid #D6D9EA; font-size:15px; margin-top:18px; text-align:center; letter-spacing:.05em; }\n    .gate-card input:focus { outline:none; border-color:#4338CA; }\n    .btn { background:#4338CA; color:#fff; border:none; border-radius:10px; padding:11px 18px; font-size:14px; font-weight:600; cursor:pointer; white-space:nowrap; }\n    .btn:hover { background:#3730A3; }\n    .btn[disabled] { background:#A5A3D8; cursor:default; }\n    .gate-error { color:#DC2626; font-size:13px; margin-top:10px; min-height:16px; }\n    .content { flex:1; overflow-y:auto; padding:32px; }\n    .wrap { max-width:1040px; margin:0 auto; }\n    .intro { max-width:1040px; margin:0 auto 20px; }\n    .intro h1 { margin:0; font-size:23px; font-weight:700; color:#0B1120; letter-spacing:-.01em; }\n    .intro p { margin:7px 0 0; font-size:14px; color:#5B5F78; line-height:1.6; max-width:640px; }\n    .search-card { background:#fff; border:1px solid #E4E6F0; border-radius:14px; padding:22px 24px; max-width:1040px; margin:0 auto 20px; }\n    .search-card h2 { margin:0 0 14px; font-size:13px; text-transform:uppercase; letter-spacing:.06em; color:#8B8FA8; }\n    .search-grid { display:grid; grid-template-columns:1fr 1fr auto; gap:12px; align-items:end; }\n    .search-grid .fld label { display:block; font-size:12px; color:#5B5F78; margin-bottom:6px; font-weight:600; }\n    .search-grid input { width:100%; box-sizing:border-box; padding:11px 12px; border-radius:9px; border:1px solid #D6D9EA; font-size:14px; font-family:ui-monospace,SFMono-Regular,Menlo,monospace; }\n    .search-grid input:focus { outline:none; border-color:#4338CA; }\n    .search-err { max-width:1040px; margin:-8px auto 18px; color:#B42318; background:#FEF2F2; border:1px solid #FECACA; border-radius:10px; padding:11px 14px; font-size:13.5px; }\n    .banner { max-width:1040px; margin:0 auto 20px; display:flex; gap:14px; align-items:flex-start; border-radius:14px; padding:18px 22px; border:1px solid; }\n    .banner .bi { width:26px; height:26px; border-radius:50%; display:flex; align-items:center; justify-content:center; font-size:14px; font-weight:700; flex-shrink:0; line-height:1; }\n    .banner .bt { font-size:16px; font-weight:700; line-height:1.35; }\n    .banner .bs { font-size:13.5px; margin-top:5px; line-height:1.55; opacity:.92; }\n    .b-ok { background:#DCFCE7; border-color:#BBF7D0; color:#15803D; }\n    .b-ok .bi { background:#15803D; color:#fff; }\n    .b-warn { background:#FEF3C7; border-color:#FDE68A; color:#92600B; }\n    .b-warn .bi { background:#92600B; color:#fff; }\n    .b-neutral { background:#EEF0F8; border-color:#E4E6F0; color:#3B3F55; }\n    .b-neutral .bi { background:#5B5F78; color:#fff; }\n    .result { max-width:1040px; margin:0 auto; display:grid; grid-template-columns:1fr 1fr; gap:20px; align-items:start; }\n    .card { background:#fff; border:1px solid #E4E6F0; border-radius:14px; padding:22px 24px; }\n    .card h3 { margin:0; font-size:13px; text-transform:uppercase; letter-spacing:.06em; color:#8B8FA8; }\n    .cust-name { font-size:18px; font-weight:700; color:#0B1120; margin-top:10px; }\n    .cust-meta { font-size:13.5px; color:#5B5F78; margin-top:8px; line-height:1.8; }\n    .mono { font-family:ui-monospace,SFMono-Regular,Menlo,monospace; color:#4338CA; }\n    .sec { margin-top:24px; }\n    .sec h4 { margin:0 0 2px; font-size:13px; text-transform:uppercase; letter-spacing:.06em; color:#8B8FA8; font-weight:600; }\n    .sec .hint { font-size:12.5px; color:#B0B3C6; margin-bottom:4px; }\n    .timeline { margin-top:16px; list-style:none; padding:0; }\n    .timeline li { position:relative; padding:0 0 20px 26px; border-left:2px solid #E4E6F0; }\n    .timeline li:last-child { border-color:transparent; padding-bottom:0; }\n    .timeline li::before { content:''; position:absolute; left:-7px; top:2px; width:12px; height:12px; border-radius:50%; background:#4338CA; border:2px solid #fff; box-shadow:0 0 0 1px #4338CA; }\n    .timeline li.past::before { background:#C7CBE0; box-shadow:0 0 0 1px #C7CBE0; }\n    .timeline .st { font-size:13.5px; font-weight:600; color:#0B1120; }\n    .timeline .lo { font-size:12px; color:#8B8FA8; margin-top:2px; }\n    .timeline .ti { font-size:11.5px; color:#B0B3C6; margin-top:2px; font-family:ui-monospace,SFMono-Regular,Menlo,monospace; }\n    video { width:100%; height:auto; max-height:360px; border-radius:10px; background:#000; display:block; margin-top:14px; }\n    .stat-row { display:flex; gap:10px; margin-top:16px; }\n    .stat { flex:1; background:#F8F8FC; border:1px solid #E4E6F0; border-radius:10px; padding:10px 12px; text-align:center; }\n    .stat .v { font-size:15px; font-weight:700; color:#0B1120; }\n    .stat .l { font-size:10.5px; text-transform:uppercase; letter-spacing:.05em; color:#8B8FA8; margin-top:3px; }\n    .no-video { padding:34px 18px; text-align:center; background:#F8F8FC; border:1px dashed #D6D9EA; border-radius:10px; margin-top:14px; }\n    .no-video .nv-t { font-size:13.5px; color:#5B5F78; font-weight:600; }\n    .no-video .nv-s { font-size:12.5px; color:#8B8FA8; margin-top:5px; line-height:1.5; }\n    .ck-row { display:flex; align-items:center; gap:12px; padding:11px 0; border-bottom:1px solid #F0F1F7; }\n    .ck-row:last-child { border-bottom:none; padding-bottom:0; }\n    .ck-main { flex:1; min-width:0; }\n    .ck-name { font-size:13.5px; font-weight:600; color:#0B1120; line-height:1.4; }\n    .ck-sku { font-size:11.5px; color:#8B8FA8; margin-top:3px; font-family:ui-monospace,SFMono-Regular,Menlo,monospace; }\n    .qty { font-size:13px; font-weight:700; padding:5px 10px; border-radius:8px; font-family:ui-monospace,SFMono-Regular,Menlo,monospace; flex-shrink:0; }\n    .qty-ok { background:#DCFCE7; color:#15803D; }\n    .qty-warn { background:#FEF3C7; color:#92600B; }\n    .qty-plain { background:#EEF0F8; color:#5B5F78; }\n    .dv-card { background:#FFFBEB; border:1px solid #FDE68A; border-left:4px solid #92600B; border-radius:12px; padding:16px 18px; margin-top:12px; }\n    .dv-tag { font-size:10.5px; font-weight:700; text-transform:uppercase; letter-spacing:.07em; color:#92600B; }\n    .dv-name { font-size:14.5px; font-weight:700; color:#0B1120; margin-top:6px; line-height:1.35; }\n    .dv-reason { font-size:13.5px; color:#92600B; font-weight:600; margin-top:9px; line-height:1.45; }\n    .dv-note { font-size:13px; color:#5B5F78; margin-top:7px; line-height:1.55; border-left:2px solid #FDE68A; padding-left:10px; }\n    .dv-qty { font-size:11.5px; color:#8B8FA8; margin-top:9px; font-family:ui-monospace,SFMono-Regular,Menlo,monospace; }\n    .bip { display:flex; align-items:center; gap:10px; font-size:12px; padding:7px 0; border-bottom:1px solid #F5F6FA; }\n    .bip:last-child { border-bottom:none; }\n    .bip .bp-t { color:#B0B3C6; font-family:ui-monospace,SFMono-Regular,Menlo,monospace; flex-shrink:0; }\n    .bip .bp-e { flex:1; font-family:ui-monospace,SFMono-Regular,Menlo,monospace; color:#5B5F78; min-width:0; overflow:hidden; text-overflow:ellipsis; }\n    .bip .bp-v { font-size:11px; padding:3px 8px; border-radius:6px; flex-shrink:0; }\n    .v-ok { background:#F1F5F9; color:#5B5F78; }\n    .v-bad { background:#FEF3C7; color:#92600B; }\n    .empty { max-width:1040px; margin:0 auto; text-align:center; padding:52px 24px; color:#8B8FA8; font-size:13.5px; line-height:1.7; background:#fff; border:1px solid #E4E6F0; border-radius:14px; }\n    .empty strong { display:block; color:#0B1120; font-size:15px; font-weight:700; margin-bottom:8px; }\n    @media (max-width: 900px) {\n      .content { padding:20px 16px; }\n      .result { grid-template-columns:1fr; }\n      .search-grid { grid-template-columns:1fr; }\n      .search-grid .btn { width:100%; }\n      .intro h1 { font-size:20px; }\n      .stat-row { flex-wrap:wrap; }\n      .stat { min-width:calc(50% - 5px); }\n    }\n  `,\n  render(d2) {\n    const s = d2.state;\n\n    if (!s.unlocked) {\n      return `\n        <div class=\"app\">\n          <div class=\"gate-wrap\">\n            <div class=\"gate-card\">\n              <div class=\"logo-chip\">${LOGO_SVG('#fff', 26)}</div>\n              <div style=\"margin-top:14px;font-size:14px;color:#5B5F78;\">Rastreio &mdash; acesso restrito</div>\n              <input class=\"js-gate-input\" type=\"password\" placeholder=\"Senha de acesso\" />\n              <div class=\"gate-error\">${esc(s.gateError || '')}</div>\n              <div style=\"margin-top:6px;\"><button class=\"btn js-gate-submit\" style=\"width:100%;\">Entrar</button></div>\n            </div>\n          </div>\n        </div>`;\n    }\n\n    let bodyHtml = '';\n\n    if (!s.searched) {\n      bodyHtml = `\n        <div class=\"empty\">\n          <strong>Informe os dois códigos para consultar</strong>\n          Eles estão no e-mail de confirmação do pedido: o código do cliente e o código do pedido.\n        </div>`;\n    } else if (s.found === false) {\n      bodyHtml = `\n        <div class=\"empty\">\n          <strong>Não encontramos esse pedido</strong>\n          Nenhum pedido <span class=\"mono\">${esc(s.orderCode || '')}</span> foi localizado para o cliente <span class=\"mono\">${esc(s.customerCode || '')}</span>.<br/>\n          Confira se os dois códigos são do mesmo pedido e tente novamente.\n        </div>`;\n    } else if (s.found && s.order) {\n      const o = s.order;\n      const p = s.picking || null;\n      const b = bannerFor(o, p);\n\n      const events = (o.trackingEvents || []).slice().reverse();\n      const timelineHtml = events.length\n        ? events.map((ev, i) => `\n            <li class=\"${i === 0 ? 'now' : 'past'}\" data-key=\"${esc(String(ev.timestamp) + '|' + String(ev.status))}\">\n              <div class=\"st\">${esc(ev.status)}</div>\n              <div class=\"lo\">${esc(ev.location)}</div>\n              <div class=\"ti\">${esc(fmtDateTime(ev.timestamp))}</div>\n            </li>`).join('')\n        : '<li class=\"past\"><div class=\"st\">Sem eventos registrados</div></li>';\n\n      const orderCard = `\n        <div class=\"card\">\n          <h3>Pedido</h3>\n          <div class=\"cust-name\">${esc(o.customerName)}</div>\n          <div class=\"cust-meta\">\n            Pedido <span class=\"mono\">${esc(o.orderCode)}</span> &middot; Cliente <span class=\"mono\">${esc(o.customerCode)}</span><br/>\n            Caixa <span class=\"mono\">${esc(o.boxCode)}</span> &middot; ${esc(o.itemsCount == null ? '—' : o.itemsCount)} ${o.itemsCount === 1 ? 'item' : 'itens'} &middot; ${esc(fmtKg(o.declaredWeightKg))} declarados<br/>\n            ${esc(o.shippingAddress)} &mdash; ${esc(o.city)}/${esc(o.state)}<br/>\n            Transportadora: ${esc(o.carrier)}\n          </div>\n          <div class=\"sec\">\n            <h4>Rastreio</h4>\n            <div class=\"hint\">Do mais recente para o mais antigo.</div>\n            <ul class=\"timeline\">${timelineHtml}</ul>\n          </div>\n        </div>`;\n\n      let proofCard;\n      if (p) {\n        const divs = p.divergences || [];\n        const checklistHtml = (p.checklist || []).map((it) => {\n          const done = Number(it.pickedQty) === Number(it.expectedQty);\n          return `\n            <div class=\"ck-row\" data-key=\"${esc(it.sku)}\">\n              <div class=\"ck-main\">\n                <div class=\"ck-name\">${esc(it.name)}</div>\n                <div class=\"ck-sku\">SKU ${esc(it.sku)} &middot; EAN ${esc(it.ean)}</div>\n              </div>\n              <div class=\"qty ${done ? 'qty-ok' : 'qty-warn'}\">${esc(it.pickedQty)}/${esc(it.expectedQty)}</div>\n            </div>`;\n        }).join('');\n\n        const divHtml = divs.map((dv) => `\n          <div class=\"dv-card\" data-key=\"${esc(dv.sku)}\">\n            <div class=\"dv-tag\">Item enviado a menos</div>\n            <div class=\"dv-name\">${esc(dv.name)}</div>\n            <div class=\"dv-reason\">${esc(dv.reasonLabel || dv.reasonCode || 'Motivo não informado')}</div>\n            ${dv.note ? `<div class=\"dv-note\">${esc(dv.note)}</div>` : ''}\n            <div class=\"dv-qty\">Enviado ${esc(dv.pickedQty)} de ${esc(dv.expectedQty)} &middot; SKU ${esc(dv.sku)}</div>\n          </div>`).join('');\n\n        const bipsHtml = (p.scanTrail || []).map((sc, i) => {\n          const v = VERDICT[sc.verdict] || { label: String(sc.verdict || ''), cls: 'v-ok' };\n          return `\n            <div class=\"bip\" data-key=\"${esc(String(sc.at) + '|' + String(sc.ean) + '|' + i)}\">\n              <div class=\"bp-t\">${esc(fmtTime(sc.at))}</div>\n              <div class=\"bp-e\">${esc(sc.ean)}</div>\n              <div class=\"bp-v ${v.cls}\">${esc(v.label)}</div>\n            </div>`;\n        }).join('');\n\n        proofCard = `\n          <div class=\"card\">\n            <h3>A conferência desta caixa</h3>\n            ${p.videoUrl\n              ? `<video src=\"${esc(p.videoUrl)}\" controls preload=\"metadata\" playsinline></video>`\n              : `<div class=\"no-video\">\n                   <div class=\"nv-t\">Vídeo não disponível para esta caixa</div>\n                   <div class=\"nv-s\">A gravação não ficou retida para este pedido. O checklist abaixo é o registro do que foi bipado item por item.</div>\n                 </div>`}\n            <div class=\"stat-row\">\n              <div class=\"stat\"><div class=\"v\">${esc(p.completionPct == null ? '—' : p.completionPct + '%')}</div><div class=\"l\">Conferido</div></div>\n              <div class=\"stat\"><div class=\"v\">${esc(fmtKg(p.measuredWeightKg))}</div><div class=\"l\">Peso medido</div></div>\n              <div class=\"stat\"><div class=\"v\">${esc(p.operatorName || '—')}</div><div class=\"l\">Operador</div></div>\n              <div class=\"stat\"><div class=\"v\">${esc(fmtDur(p.durationSec))}</div><div class=\"l\">Duração</div></div>\n            </div>\n            ${divs.length ? `\n              <div class=\"sec\">\n                <h4>O que faltou nesta caixa</h4>\n                <div class=\"hint\">Motivo registrado pelo operador no momento da separação.</div>\n                ${divHtml}\n              </div>` : ''}\n            <div class=\"sec\">\n              <h4>Checklist de conferência</h4>\n              <div class=\"hint\">Conferido em ${esc(fmtDateTime(p.finishedAt || o.pickedAt))}.</div>\n              ${checklistHtml || '<div class=\"hint\">Nenhum item registrado.</div>'}\n            </div>\n            ${bipsHtml ? `\n              <div class=\"sec\">\n                <h4>Registro de bipes</h4>\n                <div class=\"hint\">Cada leitura de código de barras na estação, na ordem em que aconteceu.</div>\n                ${bipsHtml}\n              </div>` : ''}\n          </div>`;\n      } else {\n        const itemsHtml = (o.expectedItems || []).map((it) => `\n          <div class=\"ck-row\" data-key=\"${esc(it.sku)}\">\n            <div class=\"ck-main\">\n              <div class=\"ck-name\">${esc(it.name)}</div>\n              <div class=\"ck-sku\">SKU ${esc(it.sku)} &middot; EAN ${esc(it.ean)}</div>\n            </div>\n            <div class=\"qty qty-plain\">${esc(it.qty)}x</div>\n          </div>`).join('');\n        proofCard = `\n          <div class=\"card\">\n            <h3>O que este pedido deve conter</h3>\n            <div class=\"hint\" style=\"margin-top:8px;\">A caixa ainda não foi separada. Estes são os itens previstos no pedido.</div>\n            <div class=\"sec\" style=\"margin-top:14px;\">\n              ${itemsHtml || '<div class=\"hint\">Nenhum item informado no pedido.</div>'}\n            </div>\n            <div class=\"no-video\">\n              <div class=\"nv-t\">Vídeo não disponível para esta caixa</div>\n              <div class=\"nv-s\">O vídeo da conferência é gravado no momento da separação no CD.</div>\n            </div>\n          </div>`;\n      }\n\n      bodyHtml = `\n        <div class=\"banner ${b.tone}\">\n          <div class=\"bi\">${esc(b.glyph)}</div>\n          <div>\n            <div class=\"bt\">${esc(b.title)}</div>\n            <div class=\"bs\">${esc(b.sub)}</div>\n          </div>\n        </div>\n        <div class=\"result\">\n          ${orderCard}\n          ${proofCard}\n        </div>`;\n    }\n\n    return `\n      <div class=\"app\">\n        <div class=\"topbar\">\n          <div class=\"topbar-left\">\n            ${LOGO_SVG('#fff', 22)}\n            <div class=\"topbar-title\">Rastreio &amp; Suporte</div>\n          </div>\n        </div>\n        <div class=\"content\">\n          <div class=\"intro\">\n            <h1>Acompanhe seu pedido</h1>\n            <p>Veja onde a caixa está, o vídeo da conferência no centro de distribuição e o checklist do que foi separado item por item.</p>\n          </div>\n          <div class=\"search-card\">\n            <h2>Consultar pedido</h2>\n            <div class=\"search-grid\">\n              <div class=\"fld\"><label>Código do cliente</label><input class=\"js-customer-code\" type=\"text\" placeholder=\"CLI-40118\" value=\"${esc(s.customerCode || '')}\" /></div>\n              <div class=\"fld\"><label>Código do pedido</label><input class=\"js-order-code\" type=\"text\" placeholder=\"CUB-2601\" value=\"${esc(s.orderCode || '')}\" /></div>\n              <button class=\"btn js-track-btn\" ${s.loading ? 'disabled' : ''}>${s.loading ? 'Consultando…' : 'Consultar'}</button>\n            </div>\n          </div>\n          ${s.error ? `<div class=\"search-err\">${esc(s.error)}</div>` : ''}\n          ${bodyHtml}\n        </div>\n      </div>\n    `;\n  },\n  mounted(d2, root) {\n    async function doTrack() {\n      const elC = d2.$('.js-customer-code');\n      const elO = d2.$('.js-order-code');\n      const customerCode = ((elC && elC.value) || '').trim().toUpperCase();\n      const orderCode = ((elO && elO.value) || '').trim().toUpperCase();\n\n      if (!customerCode || !orderCode) {\n        d2.setState({ error: 'Informe o código do cliente e o código do pedido — os dois são obrigatórios.', customerCode, orderCode });\n        return;\n      }\n\n      d2.setState({ error: '', loading: true, customerCode, orderCode });\n      try {\n        const res = await d2.rush('cubbo-track').invoke(\n          { customerCode, orderCode },\n          { headers: { 'x-api-key': CUBBO_KEY } }\n        );\n        const out = (res && res.data) || {};\n        if (out.found) {\n          d2.setState({ loading: false, searched: true, found: true, reason: '', order: out.order, picking: out.picking || null, error: '' });\n        } else if (out.reason === 'missing_codes') {\n          d2.setState({ loading: false, searched: false, found: null, order: null, picking: null, error: 'Informe o código do cliente e o código do pedido — os dois são obrigatórios.' });\n        } else {\n          d2.setState({ loading: false, searched: true, found: false, reason: out.reason || 'not_found', order: null, picking: null, error: '' });\n        }\n      } catch (e) {\n        d2.setState({ loading: false, error: 'Não foi possível consultar agora: ' + (e && e.message ? e.message : String(e)) });\n      }\n    }\n\n    d2.on('.js-track-btn', 'click', doTrack);\n    d2.on('.js-customer-code', 'keydown', (e) => { if (e.key === 'Enter') doTrack(); });\n    d2.on('.js-order-code', 'keydown', (e) => { if (e.key === 'Enter') doTrack(); });\n\n    d2.on('.js-gate-submit', 'click', () => {\n      const val = d2.$('.js-gate-input') ? d2.$('.js-gate-input').value : '';\n      if (val === GATE_PASSWORD) {\n        try { sessionStorage.setItem('cubboGateOk', '1'); } catch (e) {}\n        d2.setState({ unlocked: true, gateError: '' });\n      } else {\n        d2.setState({ gateError: 'Senha incorreta.' });\n      }\n    });\n    d2.on('.js-gate-input', 'keydown', (e) => { if (e.key === 'Enter') d2.$('.js-gate-submit').click(); });\n\n    let gateOk = false;\n    try { gateOk = sessionStorage.getItem('cubboGateOk') === '1'; } catch (e) {}\n    if (gateOk) {\n      d2.setState({ unlocked: true });\n    }\n  },\n};\n"}}}}}}}},{"_id":"6a973dff6aa0c19502f8f3bb","component":"data2-core-types@Component","system":"6a7ca6cb11f8a5ec77c18b42","params":{"extends":"data2-core-primitives@Block","component":"cubbo-deck-proposta","package":"cubbo-app","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 FONT_CSS = `@font-face{font-family:'AkzExt';src:url(https://cubbo-app.data2.media/file/srqewPHDXeGRgZhcxbNTO) format('opentype');font-weight:400;font-display:block}@font-face{font-family:'AkzExtLight';src:url(https://cubbo-app.data2.media/file/N5dQOTH2HQhtLG9qsPgQt) format('opentype');font-weight:300;font-display:block}`\nconst PASS='democubodata2'\nconst OPEN=false\nconst LD2='https://cubbo-app.data2.media/file/oIm_sfREXoAktie-EAbGp'\nconst RING='https://cubbo-app.data2.media/file/-VJJX4Ck1dhZMQT0SIWIY'\n\nconst CUBBO = (cls) => `<svg class=\"${cls||''}\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 91 32\" role=\"img\" aria-label=\"Cubbo\"><path d=\"M56.6655 8.91406C57.5045 8.91406 58.2671 8.91406 59.106 8.91406C59.106 8.99025 59.106 9.14263 59.106 9.21882C59.106 10.6664 59.106 12.1141 59.106 13.6379C59.106 13.7141 59.106 13.7903 59.106 13.9426C59.1823 13.8664 59.2586 13.8664 59.2586 13.7903C59.945 13.0283 60.8601 12.6474 61.8516 12.5712C62.6905 12.495 63.5294 12.6474 64.2921 13.0283C65.5124 13.7141 66.4275 14.7807 66.8089 16.1522C67.1902 17.5998 67.1139 18.9712 66.3513 20.2664C65.7412 21.3331 64.9022 22.1712 63.682 22.5522C62.7668 22.8569 61.8516 22.8569 60.9364 22.5522C60.3263 22.3998 59.7924 22.0188 59.3348 21.5617C59.2586 21.4855 59.2586 21.4093 59.106 21.3331C59.0298 21.7141 59.106 22.095 59.106 22.476C58.2671 22.476 57.5045 22.476 56.6655 22.476C56.6655 18.0569 56.6655 13.4855 56.6655 8.91406ZM61.9279 20.495C62.6905 20.495 63.4532 20.1903 63.987 19.4283C64.3684 18.895 64.5209 18.2093 64.5209 17.5236C64.5209 16.9141 64.2921 16.3807 63.9108 15.9236C63.3007 15.1617 62.4617 14.8569 61.5465 15.0093C60.4788 15.0855 59.5636 15.8474 59.2586 16.9141C59.1823 17.295 59.106 17.676 59.1823 18.1331C59.3348 19.5045 60.4025 20.495 61.9279 20.495Z\" fill=\"currentColor\"/><path d=\"M68.8682 8.91406C69.6308 8.91406 70.4697 8.91406 71.3087 8.91406C71.3087 9.14263 71.3087 9.4474 71.3087 9.75216C71.3087 10.0569 71.3087 10.2855 71.3087 10.5903C71.3087 10.895 71.3087 11.1236 71.3087 11.4283C71.3087 11.7331 71.3087 11.9617 71.3087 12.2664C71.3087 12.5712 71.3087 12.7998 71.3087 13.1045C71.3087 13.4093 71.3087 13.6379 71.3087 13.9426C71.3849 13.8664 71.4612 13.7903 71.4612 13.7903C72.1476 13.0283 72.9865 12.6474 74.0542 12.5712C74.8932 12.495 75.7321 12.6474 76.4947 13.0283C77.9438 13.7903 78.7827 15.0093 79.0878 16.6855C79.3166 17.7522 79.2403 18.895 78.7827 19.8855C78.2489 21.1045 77.4099 22.0188 76.1134 22.5522C74.8932 23.0093 73.6729 23.0093 72.5289 22.3998C72.1476 22.2474 71.8425 21.9426 71.5375 21.6379C71.4612 21.5617 71.4612 21.5617 71.3087 21.4093C71.3087 21.7903 71.3087 22.1712 71.3087 22.476C71.0799 22.5522 69.3258 22.5522 68.8682 22.476C68.8682 22.3998 68.8682 9.21882 68.8682 8.91406ZM76.7235 17.676C76.7235 16.9903 76.4947 16.3045 75.9609 15.7712C75.427 15.2379 74.7406 14.9331 73.978 15.0093C73.2916 15.0093 72.6815 15.2379 72.1476 15.695C71.1561 16.6093 71.0799 18.2093 71.6137 19.1998C72.0713 20.0379 72.834 20.495 73.8254 20.5712C74.5118 20.6474 75.1982 20.4188 75.7321 19.9617C76.4185 19.3522 76.7235 18.5903 76.7235 17.676Z\" fill=\"currentColor\"/><path d=\"M43.7765 11.8858C43.0139 12.3429 42.2512 12.8001 41.4885 13.181C41.4885 13.1048 41.4123 13.1048 41.4123 13.1048C40.8021 12.1144 39.9632 11.581 38.8955 11.3525C37.904 11.1239 36.9126 11.2001 35.9974 11.6572C34.9297 12.1905 34.167 13.0286 33.7857 14.1715C33.4806 15.2382 33.4044 16.3048 33.7857 17.3715C34.3195 19.0477 35.5398 19.962 37.2939 20.1905C38.1328 20.2667 38.9718 20.1905 39.7344 19.8858C40.4208 19.581 41.0309 19.1239 41.4123 18.4382C41.4123 18.362 41.4885 18.362 41.4885 18.2858C42.2512 18.7429 43.0139 19.1239 43.7765 19.581C43.7002 19.6572 43.7002 19.7334 43.624 19.8096C42.7851 21.1048 41.5648 22.0191 40.0395 22.4763C38.0566 23.0858 36.1499 22.9334 34.3958 21.9429C32.4892 20.8763 31.3452 19.2001 30.9639 16.9905C30.7351 15.6191 30.8113 14.2477 31.4214 12.9525C32.4129 10.6667 34.0908 9.29531 36.5313 8.76198C38.0566 8.45721 39.5819 8.60959 40.9547 9.29531C42.0224 9.82864 42.9376 10.5905 43.624 11.581C43.624 11.6572 43.7002 11.7334 43.7765 11.8858Z\" fill=\"currentColor\"/><path d=\"M90.7561 17.7523C90.7561 20.6475 88.4682 22.9332 85.5701 22.857C82.7482 22.857 80.4603 20.4951 80.5365 17.5999C80.5365 14.7808 82.9008 12.4951 85.7226 12.4951C88.3919 12.5713 90.7561 14.857 90.7561 17.7523ZM88.2394 17.7523C88.2394 17.1427 88.0868 16.6094 87.7818 16.1523C87.1716 15.3142 86.409 15.0094 85.4175 15.0094C84.5023 15.0856 83.8159 15.4665 83.2821 16.3046C82.977 16.838 82.9008 17.4475 82.977 18.057C83.2058 20.1904 85.4175 21.0285 86.9428 20.1142C87.858 19.5808 88.2394 18.7427 88.2394 17.7523Z\" fill=\"currentColor\"/><path d=\"M47.8186 12.876C47.8186 13.0284 47.8186 13.1046 47.8186 13.1808C47.8186 14.9332 47.8186 16.6855 47.8186 18.3617C47.8186 18.5903 47.8186 18.8951 47.8949 19.1236C48.0474 19.9617 48.6575 20.4951 49.5727 20.4951C49.8778 20.4951 50.1829 20.4951 50.4117 20.4189C51.1743 20.2665 51.6319 19.7332 51.7844 18.9713C51.8607 18.6665 51.8607 18.2855 51.8607 17.9808C51.8607 16.3808 51.8607 14.7808 51.8607 13.1046C51.8607 13.0284 51.8607 12.876 51.8607 12.7998C52.0132 12.7236 53.9199 12.7236 54.3012 12.7998C54.3775 12.9522 54.3775 22.1713 54.3012 22.476C54.1487 22.5522 52.1658 22.5522 51.8607 22.476C51.8607 22.1713 51.8607 21.7903 51.8607 21.4093C51.7844 21.4855 51.7082 21.5617 51.7082 21.5617C51.1743 22.2474 50.4879 22.5522 49.5727 22.7046C48.9626 22.7808 48.3525 22.7808 47.7424 22.5522C46.5221 22.1713 45.7594 21.257 45.3781 20.0379C45.3019 19.657 45.2256 19.1998 45.2256 18.8189C45.2256 16.8379 45.2256 14.9332 45.2256 12.9522C45.2256 12.876 45.2256 12.7998 45.2256 12.7236C46.1408 12.876 46.9797 12.876 47.8186 12.876Z\" fill=\"currentColor\"/><path d=\"M12.8892 21.2572V31.5429L25.3968 26.0572V15.8477L12.8892 21.2572Z\" fill=\"currentColor\"/><path d=\"M12.2788 0.0761719L0 5.4857V15.7714L12.2788 10.2857V0.0761719Z\" fill=\"currentColor\"/><path d=\"M12.8892 0V10.2857L20.5157 13.4095V3.27619L12.8892 0Z\" fill=\"currentColor\"/><path d=\"M12.2788 21.2572L0 15.8477V26.1334L12.2788 31.6191V21.2572Z\" fill=\"currentColor\"/></svg>`\n\nconst CUBE = `<svg class=\"cube\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 25.4 31.7\" aria-hidden=\"true\"><path d=\"M12.8892 21.2572V31.5429L25.3968 26.0572V15.8477L12.8892 21.2572Z\" fill=\"currentColor\"/><path d=\"M12.2788 0.0761719L0 5.4857V15.7714L12.2788 10.2857V0.0761719Z\" fill=\"currentColor\"/><path d=\"M12.8892 0V10.2857L20.5157 13.4095V3.27619L12.8892 0Z\" fill=\"currentColor\"/><path d=\"M12.2788 21.2572L0 15.8477V26.1334L12.2788 31.6191V21.2572Z\" fill=\"currentColor\"/></svg>`\n\n// Fundo \"bancada\" — composição navy + indigo, grade técnica, cubo em marca d'água\nconst BANCADA = `<div class=\"bg\"><div class=\"grid\"></div>${CUBE}</div>`\n\nconst GATE = `<div class=\"gwrap\">\n  ${BANCADA}\n  <div class=\"gcard\">\n    <div class=\"glock\"><img src=\"${LD2}\" style=\"height:22px\" alt=\"Data²\"><span>+</span>${CUBBO('gcb')}</div>\n    <div class=\"gsub\">Proposta · Picking com evidência</div>\n    <input class=\"ginput\" type=\"password\" placeholder=\"Senha de acesso\" autocomplete=\"off\"/>\n    <button class=\"gbtn\">Entrar</button>\n    <div class=\"gerr\">Senha incorreta — tente novamente.</div>\n  </div>\n</div>`\n\nconst DECK = `<div class=\"deckwrap\">\n<header>\n  <img class=\"d2\" src=\"${LD2}\" alt=\"Data²\">\n  ${CUBBO('cb')}\n</header>\n<div class=\"counter\" id=\"counter\">01 — 15</div>\n<div class=\"hint\">↓ navegue</div>\n<nav class=\"dots\" id=\"dots\" aria-label=\"Slides\"></nav>\n\n<div class=\"deckroot\">\n<!-- 01 · CAPA -->\n<section class=\"capa\" id=\"capa\">\n  <div class=\"frame rv\">\n    ${BANCADA}\n    <div class=\"mid\">\n      <div class=\"lockup\">\n        <img class=\"d2m\" src=\"${LD2}\" alt=\"Data²\">\n        <span class=\"plus\">+</span>\n        ${CUBBO('cbm')}\n      </div>\n      <div class=\"sub\">Picking com evidência · vídeo, bipe e peso em cada caixa</div>\n    </div>\n  </div>\n  <div class=\"caption rv\">\n    <div class=\"frase-cap\">We build Data² while imagining a world where things just … work.</div>\n    <div class=\"meta\">Proposta · Setembro 2026</div>\n  </div>\n</section>\n\n<!-- ÍNDICE -->\n<section id=\"indice\">\n  <div class=\"eyebrow rv\">Índice</div>\n  <div class=\"indice rv\">\n    <a href=\"#data2\"><span class=\"n\">01</span><span class=\"t\">Quem somos</span></a>\n    <a href=\"#consultoria\"><span class=\"n\">02</span><span class=\"t\">Como trabalhamos</span></a>\n    <a href=\"#tese\"><span class=\"n\">03</span><span class=\"t\">A proposta</span></a>\n    <a href=\"#conceito\"><span class=\"n\">04</span><span class=\"t\">O conceito</span></a>\n    <a href=\"#arquitetura\"><span class=\"n\">05</span><span class=\"t\">Arquitetura e integração</span></a>\n    <a href=\"#pratica\"><span class=\"n\">06</span><span class=\"t\">Na prática</span></a>\n    <a href=\"#demo\"><span class=\"n\">07</span><span class=\"t\">A demo · já no ar</span></a>\n    <a href=\"#sprint\"><span class=\"n\">08</span><span class=\"t\">A sprint · O que vamos construir</span></a>\n    <a href=\"#kpis\"><span class=\"n\">09</span><span class=\"t\">O que vamos medir</span></a>\n    <a href=\"#cronograma\"><span class=\"n\">10</span><span class=\"t\">Cronograma</span></a>\n    <a href=\"#investimento\"><span class=\"n\">11</span><span class=\"t\">Investimento</span></a>\n    <a href=\"#kickoff\"><span class=\"n\">12</span><span class=\"t\">Antes do kickoff</span></a>\n  </div>\n</section>\n\n<!-- 02 · DATA² -->\n<section id=\"data2\">\n  <div class=\"eyebrow rv\">Data² · Filosofia e tecnologia</div>\n  <div class=\"split\" style=\"align-items:end;margin-bottom:clamp(26px,5vh,52px)\">\n    <div>\n      <img class=\"logofull rv\" src=\"${LD2}\" alt=\"Data²\">\n      <h2 class=\"rv\" style=\"font-size:clamp(24px,3.2vw,46px);line-height:1.14;max-width:16ch\">Necessidade elevada à produção.</h2>\n    </div>\n    <div style=\"display:flex;flex-direction:column;align-items:flex-start;gap:clamp(20px,3.4vh,32px)\">\n      <img class=\"ring rv\" src=\"${RING}\" alt=\"\">\n      <p class=\"apoio destaque rv\" style=\"margin-top:0\">Construímos a Data² imaginando um mundo onde as coisas simplesmente … funcionam. Uma plataforma onde dados, lógica, interfaces e agentes de IA vivem no mesmo runtime — a ideia que o time de operações descreve hoje é a solução que ele opera amanhã.</p>\n    </div>\n  </div>\n  <div class=\"prods rv\">\n    <div class=\"p\"><div class=\"pn\"><span class=\"dot\" style=\"background:#FA48DC\"></span>Domain</div><p>A inteligência: conversa, decide e raciocina sobre o negócio.</p></div>\n    <div class=\"p\"><div class=\"pn\"><span class=\"dot\" style=\"background:#4866FA\"></span>UI</div><p>Interfaces completas, geradas e evoluídas na plataforma.</p></div>\n    <div class=\"p\"><div class=\"pn\"><span class=\"dot\" style=\"background:#FA4848\"></span>Registry</div><p>Os dados: pedidos, pickings, milhões de registros tipados.</p></div>\n    <div class=\"p\"><div class=\"pn\"><span class=\"dot\" style=\"background:#8448FA\"></span>Rush</div><p>Escuta tudo que entra: eventos, webhooks, bipes.</p></div>\n    <div class=\"p\"><div class=\"pn\"><span class=\"dot\" style=\"background:#48FAFA\"></span>Connect</div><p>Integra tudo que sai: WMS, transportadoras, APIs, e-mail.</p></div>\n    <div class=\"p\"><div class=\"pn\"><span class=\"dot\" style=\"background:#48FAA1\"></span>ID</div><p>Identidade, permissões e políticas de acesso.</p></div>\n    <div class=\"p\"><div class=\"pn\"><span class=\"dot\" style=\"background:#BFFA48\"></span>Cashier</div><p>Transaciona: pagamentos, cobrança, conciliação.</p></div>\n    <div class=\"p\"><div class=\"pn\"><span class=\"dot\" style=\"background:#FADC48\"></span>Media</div><p>Guarda e gera mídia: vídeo, imagem, documento.</p></div>\n  </div>\n</section>\n\n<!-- 03 · CONSULTORIA / SPRINTS -->\n<section id=\"consultoria\">\n  <div class=\"eyebrow rv\">Como trabalhamos</div>\n  <div class=\"split\" style=\"align-items:start;margin-bottom:clamp(30px,6vh,60px)\">\n    <h2 class=\"rv\" style=\"font-size:clamp(28px,4vw,56px);line-height:1.12;max-width:16ch\">Sprints que começam num KPI e terminam em produção.</h2>\n    <p class=\"apoio rv\" style=\"margin-top:0\">Nada de projetos de um ano. Cada sprint ataca um problema medível, com escopo fechado, custo conhecido e resultado rodando em semanas.</p>\n  </div>\n  <div class=\"pilares\">\n    <div class=\"pilar rv d2\"><span class=\"k\">01 · KPI</span><div class=\"t\">Escolhemos o número que precisa mexer</div><p>Erro de separação, custo de reenvio, tempo de disputa. O sprint nasce de um indicador de operação — não de um levantamento de requisitos.</p></div>\n    <div class=\"pilar rv d3\"><span class=\"k\">02 · Sprint</span><div class=\"t\">Semanas, com escopo e custo fechados</div><p>Time sênior da Data² desenha e constrói direto na plataforma. Quem projeta é quem entrega — o know-how não se perde em repasses.</p></div>\n    <div class=\"pilar rv d4\"><span class=\"k\">03 · Produção</span><div class=\"t\">Entrega medida no mesmo KPI</div><p>O sprint termina com a solução em produção e o indicador sendo acompanhado. O que funciona, escala na onda seguinte.</p></div>\n  </div>\n</section>\n\n<!-- 05 · STATEMENT -->\n<section class=\"statement\" id=\"tese\">\n  <div class=\"eyebrow rv\">A proposta</div>\n  <div class=\"split\">\n    <h1 class=\"rv\">Cada caixa que sai do CD, com prova.</h1>\n    <p class=\"apoio destaque rv\">Quando um cliente diz que faltou item, hoje a operação não tem como mostrar o que foi pra caixa. A proposta: uma estação de picking que confere cada item por bipe e peso, grava tudo em vídeo e entrega a evidência pra operação e pro cliente final — em segundos.</p>\n  </div>\n</section>\n\n<!-- 06 · CONCEITO -->\n<section id=\"conceito\">\n  <div class=\"eyebrow rv\">O conceito</div>\n  <div class=\"split\" style=\"align-items:start;margin-bottom:clamp(30px,6vh,60px)\">\n    <h2 class=\"rv\" style=\"font-size:clamp(28px,4vw,60px);line-height:1.12;max-width:15ch\">Conferir, provar e mostrar — no mesmo fluxo.</h2>\n    <p class=\"apoio rv\" style=\"margin-top:0\">Nenhuma etapa extra pro operador. A conferência que ele já faz vira registro: o bipe confirma o item, a balança confirma a caixa, a câmera confirma tudo.</p>\n  </div>\n  <div class=\"pilares\">\n    <div class=\"pilar rv d2\"><span class=\"k\">Conferir</span><div class=\"t\">Bipe e balança, item por item</div><p>O operador bipa a folha do pedido e os itens esperados aparecem. Cada EAN bipado é validado na hora — pertence ao pedido? quantidade certa? — e a balança confirma que foi pra caixa.</p></div>\n    <div class=\"pilar rv d3\"><span class=\"k\">Provar</span><div class=\"t\">Vídeo com carimbo de tudo</div><p>A gravação começa no bipe do pedido e termina na caixa fechada — com REC, cronômetro, códigos, completude e peso gravados na imagem. Caixa incompleta só fecha com motivo registrado.</p></div>\n    <div class=\"pilar rv d4\"><span class=\"k\">Mostrar</span><div class=\"t\">Evidência pra operação e pro cliente</div><p>O painel mostra cada picking com checklist, divergências, rastro de bipes e vídeo. O cliente final consulta o pedido e vê o que foi enviado — antes de precisar reclamar.</p></div>\n  </div>\n</section>\n\n<!-- 07 · ARQUITETURA -->\n<section id=\"arquitetura\">\n  <div class=\"eyebrow rv\">Arquitetura e integração</div>\n  <div class=\"split\" style=\"align-items:start;margin-bottom:clamp(24px,4vh,44px)\">\n    <h2 class=\"rv\" style=\"font-size:clamp(26px,3.6vw,52px);line-height:1.12;max-width:16ch\">Aceleramos porque a demo já está no ar.</h2>\n    <p class=\"apoio rv\" style=\"margin-top:0\">As três telas da proposta já rodam hoje na Data² — estação, painel e rastreio — com pedidos de teste e folhas pra bipar. A sprint pluga isso na operação da Cubbo: pedidos entram por integração, vídeos ficam na nuvem, eventos voltam pro WMS e pro cliente. Integramos por leitura; nada do que roda hoje é alterado.</p>\n  </div>\n  <div class=\"arq rv\">\n    <div class=\"col\">\n      <div class=\"col-h\">Sistemas Cubbo · intocados</div>\n      <div class=\"box\"><div class=\"bn\">WMS / OMS</div><div class=\"bd\">Pedidos, itens esperados, caixa, transportadora</div></div>\n      <div class=\"box\"><div class=\"bn\">Transportadoras</div><div class=\"bd\">Eventos de coleta, rota e entrega</div></div>\n      <div class=\"box\"><div class=\"bn\">Lojas dos clientes</div><div class=\"bd\">Shopify, VTEX, Nuvemshop… — origem do pedido e onde o consumidor acompanha</div></div>\n      <div class=\"box\"><div class=\"bn\">Hardware da bancada</div><div class=\"bd\">Leitor de código de barras, balança e câmera</div></div>\n    </div>\n    <div class=\"link\"><span>leitura · API</span></div>\n    <div class=\"core\">\n      <div class=\"ch\">Data² · engine já publicada</div>\n      <div class=\"box\"><div class=\"bn\">Estação de picking</div><div class=\"bd\">Bipe, balança e vídeo num só fluxo, com as regras do pedido — recusa o que não pertence, bloqueia o já separado</div></div>\n      <div class=\"box\"><div class=\"bn\">Registro de evidência</div><div class=\"bd\">Checklist, divergências com motivo, rastro de bipes, peso, duração e vídeo por pedido</div></div>\n      <div class=\"box\"><div class=\"bn\">Rastreio e eventos</div><div class=\"bd\">Consulta do cliente final e evento \"separado e embalado\" devolvido ao WMS e à transportadora</div></div>\n    </div>\n    <div class=\"link\"><span>operação</span></div>\n    <div class=\"col\">\n      <div class=\"col-h\">Quem usa</div>\n      <div class=\"box\"><div class=\"bn\">Operador do CD</div><div class=\"bd\">Uma tela na bancada, sem etapa extra</div></div>\n      <div class=\"box\"><div class=\"bn\">Time de operações</div><div class=\"bd\">Painel com busca, detalhe e vídeo de cada picking</div></div>\n      <div class=\"box\"><div class=\"bn\">Cliente final e lojista</div><div class=\"bd\">Rastreio com vídeo e checklist do que foi enviado</div></div>\n    </div>\n  </div>\n</section>\n\n<!-- 08 · NA PRÁTICA -->\n<section id=\"pratica\">\n  <div class=\"eyebrow rv\">Na prática · hoje × com a estação</div>\n  <div class=\"split\" style=\"align-items:start;margin-bottom:clamp(18px,3vh,32px)\">\n    <h2 class=\"rv\" style=\"font-size:clamp(26px,3.6vw,52px);line-height:1.12;max-width:16ch\">A diferença que a operação sente.</h2>\n    <p class=\"apoio rv\" style=\"margin-top:0\">Dois momentos comuns do dia a dia do CD, lado a lado: o caminho de hoje e a mesma tarefa com a estação.</p>\n  </div>\n  <div class=\"comps rv\">\n    <div class=\"comp\">\n      <div class=\"ctit\">Cliente diz que faltou item</div>\n      <div class=\"hj\">\n        <div class=\"lk\">Hoje · horas ou dias</div>\n        <ul class=\"steps\">\n          <li>O consumidor reclama com a loja; a loja aciona a Cubbo</li>\n          <li>Operações procura quem separou, quando e como — e não encontra evidência</li>\n          <li>Reenvia o item ou reembolsa: o custo fica com quem não errou</li>\n        </ul>\n      </div>\n      <div class=\"cn\">\n        <div class=\"lk\">Com a estação · segundos</div>\n        <div class=\"demo est\">\n          <div class=\"ebanner ok\"><span class=\"bi\">✓</span><div><div class=\"bt\">Pedido conferido e enviado completo · 5 de 5 itens</div><div class=\"bs\">Cada item foi bipado e gravado em vídeo antes de a caixa fechar.</div></div></div>\n          <div class=\"estats\"><span><b>02:14</b> de vídeo</span><span><b>1,82 kg</b> na balança</span><span><b>5</b> bipes OK</span></div>\n        </div>\n      </div>\n    </div>\n    <div class=\"comp\">\n      <div class=\"ctit\">Separar um pedido</div>\n      <div class=\"hj\">\n        <div class=\"lk\">Hoje · folha e olho</div>\n        <ul class=\"steps\">\n          <li>O operador recebe a folha impressa e coleta os itens</li>\n          <li>Confere visualmente, sem registro de quem, quando ou o quê</li>\n          <li>Fecha a caixa — se faltou algo, ninguém sabe até o cliente abrir</li>\n        </ul>\n      </div>\n      <div class=\"cn\">\n        <div class=\"lk\">Com a estação · um fluxo</div>\n        <div class=\"demo est\">\n          <div class=\"eh\"><span class=\"chip rec\"><i></i>Gravando</span><span class=\"ecode\">CUB-2607 · caixa BX-1187</span></div>\n          <div class=\"eprog\"><div class=\"en\">3/3 itens <b>100%</b></div><div class=\"etrack\"><i style=\"width:100%\"></i></div></div>\n          <div class=\"erow ok\"><span class=\"eq\">2/2</span><span>Camiseta básica preta — M</span></div>\n          <div class=\"erow ok\"><span class=\"eq\">1/1</span><span>Boné logo bordado</span></div>\n          <div class=\"ewt\">Balança <b>1,82 kg</b> · declarado 1,80 kg</div>\n        </div>\n      </div>\n    </div>\n  </div>\n</section>\n\n<!-- 09 · DEMO -->\n<section id=\"demo\">\n  <div class=\"eyebrow rv\">A demo · já no ar</div>\n  <div class=\"split\" style=\"align-items:start;margin-bottom:clamp(24px,4vh,44px)\">\n    <h2 class=\"rv\" style=\"font-size:clamp(26px,3.6vw,52px);line-height:1.12;max-width:16ch\">Você pode testar agora.</h2>\n    <p class=\"apoio rv\" style=\"margin-top:0\">As três telas rodam hoje na Data², com 12 pedidos de teste e folhas A4 pra bipar. Abra em qualquer navegador — a senha é a mesma desta proposta.</p>\n  </div>\n  <div class=\"apps rv\">\n    <a class=\"app\" href=\"https://picking.cubbo-app.data2.app/\" target=\"_blank\" rel=\"noopener\">\n      <span class=\"ak\">01 · Bancada</span>\n      <span class=\"at\">Estação de Picking</span>\n      <span class=\"ad\">Câmera, bipe, balança e vídeo num só fluxo. Roda em notebook ou tablet — aponte pro código da folha e a gravação começa.</span>\n      <span class=\"au\">picking.cubbo-app.data2.app ↗</span>\n    </a>\n    <a class=\"app\" href=\"https://painel.cubbo-app.data2.app/\" target=\"_blank\" rel=\"noopener\">\n      <span class=\"ak\">02 · Operações</span>\n      <span class=\"at\">Painel Operacional</span>\n      <span class=\"ad\">Cada picking com operador, completude, divergências, rastro de bipes, peso, duração e vídeo. Estado dos 12 pedidos e reset da demo.</span>\n      <span class=\"au\">painel.cubbo-app.data2.app ↗</span>\n    </a>\n    <a class=\"app\" href=\"https://rastreio.cubbo-app.data2.app/\" target=\"_blank\" rel=\"noopener\">\n      <span class=\"ak\">03 · Cliente final</span>\n      <span class=\"at\">Rastreio</span>\n      <span class=\"ad\">Código do cliente + código do pedido: status, linha do tempo, vídeo da separação e o checklist do que foi enviado — em linguagem de cliente.</span>\n      <span class=\"au\">rastreio.cubbo-app.data2.app ↗</span>\n    </a>\n  </div>\n</section>\n\n<!-- 10 · SPRINT -->\n<section id=\"sprint\">\n  <div class=\"eyebrow rv\">O que vamos construir · <b>Sprint única · R$ 50.000</b></div>\n  <div class=\"split\" style=\"align-items:start;margin-bottom:clamp(16px,2.6vh,28px)\">\n    <h2 class=\"rv\" style=\"font-size:clamp(26px,3.4vw,48px);line-height:1.12;max-width:16ch\">Da demo pra produção, em uma sprint.</h2>\n    <p class=\"apoio rv\" style=\"margin-top:0\">Tudo que a demo mostra, rodando no CD com pedidos reais, hardware de verdade e integração com os sistemas da Cubbo. O que já está validado entra pronto; o que é novo, construímos na sprint.</p>\n  </div>\n  <div class=\"leg rv\"><span><i class=\"ok\"></i>Validado — já roda na demo</span><span><i class=\"nv\"></i>Novo — o que vamos construir</span></div>\n  <div class=\"frentes rv\">\n    <div class=\"f\"><div class=\"fn\">Estação de picking <span class=\"ct\">5 validados · 3 novos</span></div>\n      <div class=\"fi ok\">Leitura da folha do pedido e carga dos itens esperados</div>\n      <div class=\"fi ok\">Bipe de cada item com validação: fora do pedido, quantidade acima</div>\n      <div class=\"fi ok\">Balança confirmando cada item colocado na caixa</div>\n      <div class=\"fi ok\">Checklist e completude em tempo real, com som de OK e de erro</div>\n      <div class=\"fi ok\">Bloqueio de pedido já separado — a folha só roda uma vez</div>\n      <div class=\"fi nv\">Leitor de código de barras e balança reais (USB/serial) no lugar da simulação</div>\n      <div class=\"fi nv\">Câmera fixa da bancada e múltiplas estações por CD</div>\n      <div class=\"fi nv\">Login do operador (ID) no lugar do nome digitado</div>\n    </div>\n    <div class=\"f\"><div class=\"fn\">Vídeo e evidência <span class=\"ct\">3 validados · 2 novos</span></div>\n      <div class=\"fi ok\">Gravação do bipe do pedido até a caixa fechada</div>\n      <div class=\"fi ok\">Carimbo na imagem: REC, cronômetro, códigos, completude e peso</div>\n      <div class=\"fi ok\">Upload e link do vídeo no registro do picking</div>\n      <div class=\"fi nv\">Armazenamento e retenção dimensionados pro volume do CD</div>\n      <div class=\"fi nv\">Compressão e fila de upload resiliente à rede instável do CD</div>\n    </div>\n    <div class=\"f\"><div class=\"fn\">Divergências <span class=\"ct\">2 validados · 1 novo</span></div>\n      <div class=\"fi ok\">Caixa incompleta só fecha com motivo por item faltante</div>\n      <div class=\"fi ok\">Observação obrigatória nos motivos que exigem</div>\n      <div class=\"fi nv\">Catálogo de motivos mantido pelo time de operações, sem depender da Data²</div>\n    </div>\n    <div class=\"f\"><div class=\"fn\">Painel operacional <span class=\"ct\">3 validados · 2 novos</span></div>\n      <div class=\"fi ok\">Lista de pickings: operador, cliente, completude, peso, duração e vídeo</div>\n      <div class=\"fi ok\">Busca e detalhe — checklist, divergências e rastro de bipes</div>\n      <div class=\"fi ok\">Estado de cada pedido: pendente, separado, com divergência</div>\n      <div class=\"fi nv\">Filtros por período, operador, CD e lojista + exportação</div>\n      <div class=\"fi nv\">Alertas de divergência recorrente por operador, SKU ou lojista</div>\n    </div>\n    <div class=\"f\"><div class=\"fn\">Rastreio do cliente final <span class=\"ct\">2 validados · 2 novos</span></div>\n      <div class=\"fi ok\">Consulta por cliente + pedido: status, vídeo e checklist</div>\n      <div class=\"fi ok\">Divergência explicada em linguagem de cliente</div>\n      <div class=\"fi nv\">Link do rastreio no e-mail / WhatsApp de \"pedido enviado\"</div>\n      <div class=\"fi nv\">Versão embarcável na página de rastreio do lojista</div>\n    </div>\n    <div class=\"f\"><div class=\"fn\">Integração <span class=\"ct\">3 novos</span></div>\n      <div class=\"fi nv\">Pedidos e itens esperados vindos do WMS/OMS da Cubbo</div>\n      <div class=\"fi nv\">Evento \"separado e embalado\" devolvido ao WMS e à transportadora</div>\n      <div class=\"fi nv\">Eventos de rastreio da transportadora na linha do tempo do cliente</div>\n      <div class=\"fnote\">Integramos por leitura e eventos; nada do que roda hoje no WMS é alterado.</div>\n    </div>\n    <div class=\"f\"><div class=\"fn\">Indicadores <span class=\"ct\">1 novo</span></div>\n      <div class=\"fi nv\">Dashboard com os 6 KPIs, medindo desde o 1º dia do piloto</div>\n    </div>\n    <div class=\"f\"><div class=\"demo est\">\n      <div class=\"eh\"><span class=\"chip warn\"><i></i>Divergência</span><span class=\"ecode\">CUB-2611 · caixa BX-1190</span></div>\n      <div class=\"eprog\"><div class=\"en\">4/5 itens <b>80%</b></div><div class=\"etrack\"><i class=\"warn\" style=\"width:80%\"></i></div></div>\n      <div class=\"erow ok\"><span class=\"eq\">3/3</span><span>Meia cano médio — kit 3</span></div>\n      <div class=\"erow part\"><span class=\"eq\">1/2</span><span>Camiseta básica branca — G</span></div>\n      <div class=\"ereason\">Motivo registrado: <b>Sem estoque na posição</b> · \"reposição solicitada\"</div>\n    </div></div>\n  </div>\n</section>\n\n<!-- 11 · KPIS -->\n<section id=\"kpis\">\n  <div class=\"eyebrow rv\">O que vamos medir</div>\n  <div class=\"split\" style=\"align-items:start;margin-bottom:clamp(24px,4vh,44px)\">\n    <h2 class=\"rv\" style=\"font-size:clamp(26px,3.6vw,52px);line-height:1.12;max-width:16ch\">Cada sprint começa num número. Estes são os nossos.</h2>\n    <p class=\"apoio rv\" style=\"margin-top:0\">Seis indicadores pra validar juntos no kickoff — o dashboard entra na sprint, medindo desde o primeiro dia do piloto. Onde a Cubbo já tem número, ele entra como linha de base.</p>\n  </div>\n  <div class=\"kpis seis rv\">\n    <div class=\"k\"><div class=\"kt\">Erro de separação</div><p>Pedidos com reclamação de item faltante ou trocado, sobre o total expedido pela estação.</p><div class=\"kb\">Meta: cair já no piloto</div></div>\n    <div class=\"k\"><div class=\"kt\">Divergência na origem</div><p>Caixas incompletas fechadas com motivo antes de sair do CD — o problema descoberto pela Cubbo, não pelo cliente.</p></div>\n    <div class=\"k\"><div class=\"kt\">Tempo de resolução de disputa</div><p>Da reclamação do cliente à resposta com evidência em mãos.</p><div class=\"kb\">Hoje: horas ou dias → com vídeo, minutos</div></div>\n    <div class=\"k\"><div class=\"kt\">Custo de reenvio e reembolso</div><p>Itens reenviados ou reembolsados por erro que a Cubbo não conseguiu comprovar.</p></div>\n    <div class=\"k\"><div class=\"kt\">Tempo de picking por pedido</div><p>Do bipe da folha à caixa fechada — a conferência não pode custar produtividade.</p></div>\n    <div class=\"k\"><div class=\"kt\">Cobertura de evidência</div><p>Pedidos expedidos com vídeo, checklist e peso registrados.</p><div class=\"kb\">Meta: 100% do que passa pela estação</div></div>\n  </div>\n</section>\n\n<!-- 12 · CRONOGRAMA -->\n<section id=\"cronograma\">\n  <div class=\"eyebrow rv\">Cronograma</div>\n  <h2 class=\"rv\" style=\"font-size:clamp(24px,3vw,44px);margin-bottom:clamp(10px,2vh,20px)\">Kickoff em 15 de setembro. Piloto no ar em 13 de outubro.</h2>\n  <p class=\"rv lead\" style=\"color:var(--muted);font-size:14.5px;max-width:56ch;line-height:1.7;margin-bottom:clamp(26px,5vh,54px)\">O piloto roda numa bancada do CD, com pedidos reais — a operação sente a diferença antes da sprint acabar.</p>\n  <div class=\"ondas rv\">\n    <div class=\"onda\"><div class=\"fase\">15 de setembro</div><div class=\"t\">Kickoff</div><ul><li>Mobilização, acessos ao WMS e escolha do CD e da bancada piloto</li><li>Hardware da bancada: leitor, balança e câmera</li><li>KPIs e linha de base validados com operações</li></ul></div>\n    <div class=\"onda\"><div class=\"fase\">13 de outubro</div><div class=\"t\">Piloto no ar</div><ul><li>Estação rodando com pedidos reais numa bancada</li><li>Painel e rastreio com dado real; homologação junto com o time Cubbo</li><li>Dashboard dos 6 KPIs medindo desde o 1º dia</li></ul></div>\n    <div class=\"onda\"><div class=\"fase\">Na sequência</div><div class=\"t\">Escala</div><ul><li>Mais bancadas e CDs, sem retrabalho</li><li>Rastreio embarcado nas lojas dos lojistas</li><li>Alertas e melhoria contínua a partir dos dados do piloto</li></ul></div>\n  </div>\n</section>\n\n<!-- 13 · INVESTIMENTO -->\n<section id=\"investimento\">\n  <div class=\"eyebrow rv\">Investimento</div>\n  <div class=\"custos rv\">\n    <div class=\"row\"><div><div class=\"t\">Sprint — Picking com evidência</div><div class=\"d\">Estação de picking, vídeo e evidência, divergências, painel operacional, rastreio do cliente final, integrações com WMS e transportadora, dashboard de KPIs.</div></div><div class=\"v\">R$ 50.000</div></div>\n    <div class=\"row\"><div><div class=\"t\">Analista Data² dedicado</div><div class=\"d\">Opcional — um analista full-time na solução: rotinas de sustentação garantidas, melhoria contínua e resposta imediata, como extensão do time Cubbo.</div></div><div class=\"v\">R$ 26.000<em> /mês</em></div></div>\n    <div class=\"row total\"><div><div class=\"t\">Operação da solução</div><div class=\"d\">Infraestrutura e armazenamento de vídeo dimensionados no piloto — o custo por pedido é medido com volume real e apresentado antes da escala.</div></div><div class=\"v\" style=\"font-size:clamp(15px,1.5vw,22px)\">medido no piloto</div></div>\n  </div>\n  <p class=\"cond rv\">Faturamento por sprint entregue.</p>\n</section>\n\n<!-- 14 · ANTES DO KICKOFF -->\n<section id=\"kickoff\">\n  <div class=\"eyebrow rv\">Antes do kickoff · 15 de setembro</div>\n  <div class=\"split\" style=\"align-items:start;margin-bottom:clamp(24px,4vh,44px)\">\n    <h2 class=\"rv\" style=\"font-size:clamp(26px,3.6vw,52px);line-height:1.12;max-width:16ch\">O que fechamos juntos até lá.</h2>\n    <p class=\"apoio rv\" style=\"margin-top:0\">Nada aqui muda o escopo — são decisões e desbloqueios que deixam o caminho livre pra sprint correr no ritmo combinado.</p>\n  </div>\n  <div class=\"pilares dois\">\n    <div class=\"pilar rv d2\"><span class=\"k\">Decidimos juntos</span>\n      <ul class=\"klist\">\n        <li><b>CD e bancada piloto</b> — qual estação, qual turno, quantos operadores</li>\n        <li><b>Retenção de vídeo</b> — por quanto tempo guardar e quem acessa</li>\n        <li><b>Rastreio pro cliente final</b> — direto da Cubbo ou embarcado na loja do lojista</li>\n        <li><b>Motivos de divergência</b> — a lista oficial da operação</li>\n      </ul>\n    </div>\n    <div class=\"pilar rv d3\"><span class=\"k\">Desbloqueios do lado Cubbo</span>\n      <ul class=\"klist\">\n        <li><b>Tech</b> — acesso de leitura ao WMS/OMS (pedidos, itens, caixa) e o evento de retorno</li>\n        <li><b>Hardware</b> — leitor, balança com saída digital e câmera na bancada piloto</li>\n        <li><b>Transportadoras</b> — de onde vêm os eventos de rastreio hoje</li>\n        <li><b>Operação</b> — um líder de operações como dono do piloto e da homologação</li>\n      </ul>\n    </div>\n  </div>\n</section>\n\n<!-- 15 · FECHAMENTO -->\n<section class=\"dark fecho\" data-dark id=\"fim\">\n  ${BANCADA}\n  <div class=\"mid\">\n    <img class=\"ring branco rv\" style=\"width:52px\" src=\"${RING}\" alt=\"\">\n    <p class=\"frase rv\">We build Data² while imagining a world where things just <i>…</i> work.</p>\n    <div class=\"lockup rv\"><img class=\"d2m\" style=\"height:26px\" src=\"${LD2}\" alt=\"Data²\"><span class=\"plus\" style=\"font-size:20px\">+</span>${CUBBO('cbm cbm-s')}</div>\n    <div class=\"sub rv\">gui@data2.app · data2.app</div>\n  </div>\n</section>\n</div>\n</div>`\n\nfunction injectFonts(){\n  try{\n    if(!document.getElementById('akz-deck-fonts')){\n      const st=document.createElement('style'); st.id='akz-deck-fonts'; st.textContent=FONT_CSS\n      document.head.appendChild(st)\n    }\n  }catch(e){}\n}\n\nfunction initDeck(d2){\n  const wrap=d2.$('.deckwrap'); if(!wrap||wrap.dataset.init) return\n  wrap.dataset.init='1'\n  const rootEl=wrap.querySelector('.deckroot')\n  const slides=[].slice.call(rootEl.querySelectorAll('section'))\n  const dots=wrap.querySelector('.dots'), counter=wrap.querySelector('.counter')\n  const pad=n=>(n<10?'0':'')+n\n  let cur=0\n  counter.textContent=pad(1)+' — '+pad(slides.length)\n  slides.forEach((s,i)=>{const a=document.createElement('a');a.href='#'+s.id;a.setAttribute('aria-label','Slide '+(i+1));dots.appendChild(a)})\n  const links=[].slice.call(dots.children)\n  if(links[0])links[0].classList.add('on')\n  const setActive=i=>{if(i===cur)return;cur=i;counter.textContent=pad(cur+1)+' — '+pad(slides.length);links.forEach((l,k)=>l.classList.toggle('on',k===cur));wrap.classList.toggle('on-dark',slides[cur].hasAttribute('data-dark'));wrap.classList.toggle('last',cur===slides.length-1)}\n  // reveal: dispara assim que o slide encosta na viewport — funciona mesmo se o slide for mais alto que a tela; one-way\n  const revIO=new IntersectionObserver(es=>{es.forEach(e=>{if(e.isIntersecting){e.target.classList.add('in');revIO.unobserve(e.target)}})},{root:rootEl,rootMargin:'0px 0px 12% 0px',threshold:.01})\n  slides.forEach(s=>revIO.observe(s))\n  // slide ativo: pega o mais visivel, com faixas tolerantes pra nunca travar\n  const ratios=new Array(slides.length).fill(0)\n  const actIO=new IntersectionObserver(es=>{es.forEach(e=>{const i=slides.indexOf(e.target);if(i>-1)ratios[i]=e.isIntersecting?e.intersectionRatio:0});let bi=cur,bv=-1;ratios.forEach((r,i)=>{if(r>bv){bv=r;bi=i}});if(bv>0)setActive(bi)},{root:rootEl,threshold:[0,.15,.35,.55,.75,1]})\n  slides.forEach(s=>actIO.observe(s))\n  // rede de seguranca: se o observer nao rodar, mostra tudo\n  setTimeout(()=>{if(!rootEl.querySelector('section.in'))slides.forEach(s=>s.classList.add('in'))},500)\n  const rm=(typeof matchMedia==='function')&&matchMedia('(prefers-reduced-motion: reduce)').matches\n  const go=i=>{i=Math.max(0,Math.min(slides.length-1,i));slides[i].scrollIntoView({behavior:rm?'auto':'smooth'})}\n  wrap.addEventListener('click',ev=>{\n    const a=ev.target.closest&&ev.target.closest('a[href^=\"#\"]'); if(!a)return\n    ev.preventDefault()\n    const id=a.getAttribute('href').slice(1)\n    const t=slides.find(s=>s.id===id); if(t)t.scrollIntoView({behavior:rm?'auto':'smooth'})\n  })\n  window.addEventListener('keydown',e=>{\n    if(!wrap.isConnected)return\n    if(e.target&&/^(INPUT|TEXTAREA)$/.test(e.target.tagName))return\n    if(e.key==='ArrowDown'||e.key==='ArrowRight'||e.key==='PageDown'||e.key===' '){e.preventDefault();go(cur+1)}\n    if(e.key==='ArrowUp'||e.key==='ArrowLeft'||e.key==='PageUp'){e.preventDefault();go(cur-1)}\n    if(e.key==='Home'){e.preventDefault();go(0)}\n    if(e.key==='End'){e.preventDefault();go(slides.length-1)}\n  })\n}\n\nexport default {\n  css:`\n  :host,.deckwrap,.gwrap{\n    --navy:#0B1120;\n    --navy-2:#141A33;\n    --paper:#F7F7FB;\n    --ink:#0B1120;\n    --muted:#5B5F78;\n    --indigo:#4338CA;\n    --indigo-soft:#818CF8;\n    --bad:#B91C1C;\n    --warn:#92600B;\n    --ok:#15803D;\n    --linha:rgba(11,17,32,.13);\n    --mx:clamp(20px,4vw,56px);\n    --ext:'AkzExt','Helvetica Neue',Helvetica,Arial,sans-serif;\n    --lt:'AkzExtLight','Helvetica Neue',Helvetica,Arial,sans-serif;\n    --sf:-apple-system,BlinkMacSystemFont,'SF Pro Text','Inter','Helvetica Neue',Helvetica,Arial,sans-serif;\n  }\n  *{box-sizing:border-box;margin:0;padding:0}\n\n  .deckwrap{background:var(--paper);color:var(--ink);font-family:var(--lt);-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}\n\n  /* ---------- chrome ---------- */\n  header{position:absolute;inset:0 0 auto 0;z-index:40;display:flex;justify-content:space-between;align-items:center;padding:22px var(--mx) 34px;pointer-events:none;background:linear-gradient(to bottom,var(--paper) 52%,rgba(247,247,251,0))}\n  .deckwrap.on-dark header{background:none}\n  header img{height:16px;display:block;filter:brightness(0);opacity:.92}\n  header svg.cb{height:20px;width:auto;display:block;color:var(--ink)}\n  .deckwrap.on-dark header img{filter:none;opacity:1}\n  .deckwrap.on-dark header svg.cb{color:#fff}\n  .counter{position:absolute;z-index:40;left:var(--mx);bottom:22px;font-family:var(--lt);font-size:11px;letter-spacing:.22em;color:var(--muted)}\n  .deckwrap.on-dark .counter{color:rgba(255,255,255,.75)}\n  nav.dots{position:absolute;z-index:40;right:clamp(14px,2.4vw,32px);top:50%;transform:translateY(-50%);display:flex;flex-direction:column;gap:14px}\n  nav.dots a{width:6px;height:6px;border-radius:50%;background:var(--muted);opacity:.35;transition:opacity .3s,transform .3s}\n  nav.dots a.on{opacity:1;transform:scale(1.5);background:var(--indigo)}\n  .deckwrap.on-dark nav.dots a{background:#fff}\n  .deckwrap.on-dark nav.dots a.on{background:#fff}\n  .hint{position:absolute;z-index:40;right:var(--mx);bottom:22px;font-size:11px;letter-spacing:.22em;color:var(--muted);text-transform:uppercase;transition:opacity .4s}\n  .deckwrap.last .hint{opacity:0}\n  .deckwrap.on-dark .hint{color:rgba(255,255,255,.6)}\n\n  /* ---------- slide base ---------- */\n  section{min-height:100%;scroll-snap-align:start;position:relative;display:flex;flex-direction:column;justify-content:center;padding:clamp(84px,12vh,140px) clamp(20px,7vw,120px);overflow:hidden}\n  .eyebrow{font-size:12px;letter-spacing:.3em;text-transform:uppercase;color:var(--muted);margin-bottom:clamp(20px,4vh,44px)}\n  .eyebrow b{font-weight:400;color:var(--indigo)}\n\n  .rv{opacity:0;transform:translateY(26px);transition:opacity .9s cubic-bezier(.2,.6,.2,1),transform .9s cubic-bezier(.2,.6,.2,1)}\n  section.in .rv{opacity:1;transform:none}\n  section.in .rv:nth-child(2),section.in .d2{transition-delay:.12s}\n  section.in .rv:nth-child(3),section.in .d3{transition-delay:.24s}\n  section.in .rv:nth-child(4),section.in .d4{transition-delay:.36s}\n  section.in .rv:nth-child(5),section.in .d5{transition-delay:.48s}\n  section.in .rv:nth-child(6),section.in .d6{transition-delay:.6s}\n\n  /* ---------- bancada: fundo navy composto (capa, gate e fechamento) ---------- */\n  .bg{position:absolute;inset:0;z-index:0;overflow:hidden;background:\n    radial-gradient(ellipse 70% 60% at 18% 85%,rgba(67,56,202,.62),transparent 62%),\n    radial-gradient(ellipse 50% 45% at 88% 12%,rgba(129,140,248,.30),transparent 60%),\n    linear-gradient(135deg,#0B1120 0%,#111735 55%,#1B1A4A 100%)}\n  .bg .grid{position:absolute;inset:0;background-image:linear-gradient(rgba(255,255,255,.055) 1px,transparent 1px),linear-gradient(90deg,rgba(255,255,255,.055) 1px,transparent 1px);background-size:64px 64px;mask-image:radial-gradient(ellipse 85% 80% at 50% 50%,#000 30%,transparent 100%);-webkit-mask-image:radial-gradient(ellipse 85% 80% at 50% 50%,#000 30%,transparent 100%)}\n  .bg .cube{position:absolute;right:-4%;bottom:-14%;height:118%;width:auto;color:#fff;opacity:.055}\n  .dark{color:#fff}\n  .dark .mid{position:relative;z-index:1;display:flex;flex-direction:column;align-items:center;text-align:center;gap:34px}\n  .lockup{display:flex;align-items:center;gap:clamp(18px,3vw,34px)}\n  .lockup img{display:block}\n  .lockup .d2m{height:clamp(30px,4.6vw,54px)}\n  .lockup svg.cbm{height:clamp(30px,4.4vw,52px);width:auto;display:block;color:#fff}\n  .lockup svg.cbm-s{height:26px}\n  .lockup .plus{font-family:var(--lt);font-size:clamp(22px,3vw,36px);line-height:1;opacity:.9}\n  .dark .sub{font-family:var(--lt);font-size:clamp(13px,1.4vw,17px);letter-spacing:.14em;text-transform:uppercase;opacity:.92}\n\n  /* ---------- statement ---------- */\n  h1,h2{font-family:var(--ext);font-weight:400;text-wrap:balance}\n  .statement h1{font-size:clamp(34px,5.6vw,86px);line-height:1.08;letter-spacing:-.01em;max-width:16ch}\n  .apoio{max-width:44ch;font-size:clamp(15px,1.5vw,19px);line-height:1.65;color:var(--muted)}\n  .split{display:grid;grid-template-columns:1.4fr .8fr;gap:clamp(28px,6vw,90px);align-items:end}\n  .split>*{min-width:0}\n  @media(max-width:820px){.split{grid-template-columns:1fr}}\n\n  /* ---------- pilares ---------- */\n  .pilares{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(22px,3.4vw,56px);border-top:1px solid var(--linha);padding-top:clamp(26px,5vh,52px)}\n  .pilar .t{font-family:var(--ext);font-size:clamp(17px,1.7vw,23px);line-height:1.3;margin-bottom:16px}\n  .pilar p{font-size:14.5px;line-height:1.7;color:var(--muted)}\n  .pilar .k{display:block;font-size:11px;letter-spacing:.26em;color:var(--indigo);text-transform:uppercase;margin-bottom:18px}\n  @media(max-width:820px){.pilares{grid-template-columns:1fr}}\n\n  /* ---------- demo: mini estação ---------- */\n  .demo{border:1px solid var(--linha);border-radius:18px;padding:clamp(12px,1.6vh,18px);display:flex;flex-direction:column;gap:8px;background:#fff}\n  .demo.est{gap:10px;font-family:var(--sf)}\n  .est .eh{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap}\n  .est .chip{display:inline-flex;align-items:center;gap:6px;font-size:10.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;padding:4px 9px;border-radius:999px}\n  .est .chip i{width:6px;height:6px;border-radius:50%;background:currentColor;display:inline-block}\n  .est .chip.rec{background:#FEE2E2;color:var(--bad)}\n  .est .chip.rec i{animation:pulse 1.2s ease-in-out infinite}\n  .est .chip.warn{background:#FEF3C7;color:var(--warn)}\n  @keyframes pulse{0%,100%{opacity:1}50%{opacity:.3}}\n  .est .ecode{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px;color:var(--indigo)}\n  .est .eprog .en{display:flex;justify-content:space-between;align-items:baseline;font-size:13px;font-weight:700;color:var(--ink);font-variant-numeric:tabular-nums}\n  .est .eprog .en b{color:var(--indigo);font-size:12px}\n  .est .etrack{height:6px;background:#E4E6F0;border-radius:99px;margin-top:6px;overflow:hidden}\n  .est .etrack i{display:block;height:100%;background:var(--ok);border-radius:99px}\n  .est .etrack i.warn{background:#D69E14}\n  .est .erow{display:flex;align-items:center;gap:10px;font-size:12px;color:#1F2233;padding:7px 10px;border:1px solid #E4E6F0;border-radius:10px;background:#F8F8FC}\n  .est .erow.ok{border-color:#BBF7D0;background:#F6FEF9}\n  .est .erow.part{border-color:#FDE68A;background:#FFFDF5}\n  .est .eq{font-weight:800;font-size:11.5px;font-variant-numeric:tabular-nums;padding:2px 7px;border-radius:6px;background:#F1F2F8;color:var(--muted);flex:none}\n  .est .erow.ok .eq{background:#DCFCE7;color:var(--ok)}\n  .est .erow.part .eq{background:#FEF3C7;color:var(--warn)}\n  .est .ewt{font-size:11.5px;color:var(--muted);text-align:center;padding-top:2px}\n  .est .ewt b{color:var(--ink);font-weight:700}\n  .est .ereason{font-size:11.5px;color:#7C4A03;background:#FEF3C7;border:1px solid #FDE68A;border-radius:8px;padding:7px 10px;line-height:1.5}\n  .est .ereason b{font-weight:700}\n  .est .ebanner{display:flex;gap:10px;align-items:flex-start;border-radius:12px;padding:12px 14px;border:1px solid}\n  .est .ebanner.ok{background:#DCFCE7;border-color:#BBF7D0;color:var(--ok)}\n  .est .ebanner .bi{width:20px;height:20px;border-radius:50%;background:var(--ok);color:#fff;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:700;flex:none;line-height:1}\n  .est .ebanner .bt{font-size:12.5px;font-weight:700;line-height:1.35}\n  .est .ebanner .bs{font-size:11.5px;margin-top:4px;line-height:1.5;opacity:.9}\n  .est .estats{display:flex;gap:8px}\n  .est .estats span{flex:1;background:#F8F8FC;border:1px solid #E4E6F0;border-radius:10px;padding:8px 10px;text-align:center;font-size:10.5px;color:var(--muted);line-height:1.5}\n  .est .estats b{display:block;font-size:13px;color:var(--ink);font-weight:700;font-variant-numeric:tabular-nums}\n\n  /* ---------- arquitetura ---------- */\n  .arq{display:grid;grid-template-columns:1fr 44px 1.15fr 44px 1fr;gap:clamp(10px,1.2vw,18px);align-items:stretch;border-top:1px solid var(--linha);padding-top:clamp(24px,4vh,44px)}\n  .arq .col{display:flex;flex-direction:column;gap:10px}\n  .arq .col-h{font-size:10.5px;letter-spacing:.24em;text-transform:uppercase;color:var(--muted);margin-bottom:8px;line-height:1.5}\n  .arq .box{border:1px solid var(--linha);border-radius:14px;padding:13px 15px}\n  .arq .box .bn{font-family:var(--ext);font-size:12.5px;line-height:1.4}\n  .arq .box .bd{font-size:11.5px;color:var(--muted);margin-top:4px;line-height:1.5}\n  .arq .core{background:var(--navy);color:#fff;border-radius:18px;padding:clamp(16px,2.4vh,26px);display:flex;flex-direction:column;gap:12px;height:100%}\n  .arq .core .ch{font-size:10.5px;letter-spacing:.24em;text-transform:uppercase;color:var(--indigo-soft)}\n  .arq .core .box{border-color:rgba(255,255,255,.22)}\n  .arq .core .box .bd{color:rgba(255,255,255,.72)}\n  .arq .link{position:relative;display:flex;align-items:center;justify-content:center}\n  .arq .link::before{content:'';position:absolute;left:-6px;right:-6px;top:50%;height:1px;background:var(--muted);opacity:.5}\n  .arq .link span{position:relative;background:var(--paper);font-size:9px;letter-spacing:.2em;text-transform:uppercase;color:var(--muted);transform:rotate(-90deg);white-space:nowrap;padding:0 6px}\n  @media(max-width:900px){.arq{grid-template-columns:1fr}.arq .link{min-height:34px}.arq .link::before{left:50%;right:auto;top:0;bottom:0;width:1px;height:auto}.arq .link span{transform:none}}\n\n  /* ---------- cronograma ---------- */\n  .ondas{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(22px,3vw,48px);position:relative;padding-top:clamp(30px,5vh,52px)}\n  .ondas::before{content:'';position:absolute;top:0;left:0;right:0;height:1px;background:var(--linha)}\n  .onda{position:relative}\n  .onda::before{content:'';position:absolute;top:calc(-1 * clamp(30px,5vh,52px));left:0;width:9px;height:9px;border-radius:50%;background:var(--indigo);transform:translateY(-4px)}\n  .onda .fase{font-size:11px;letter-spacing:.26em;text-transform:uppercase;color:var(--muted);margin-bottom:10px}\n  .onda .t{font-family:var(--ext);font-size:clamp(17px,1.8vw,24px);margin-bottom:18px}\n  .onda ul{list-style:none}\n  .onda li{font-size:14px;line-height:1.6;color:var(--muted);padding:9px 0;border-bottom:1px solid var(--linha)}\n  .pilares.dois{grid-template-columns:1fr 1fr}\n  @media(max-width:820px){.ondas{grid-template-columns:1fr}.onda::before{display:none}.pilares.dois{grid-template-columns:1fr}}\n\n  /* ---------- investimento ---------- */\n  .custos{border-top:1px solid var(--linha);max-width:880px}\n  .custos .row{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:baseline;gap:24px;padding:clamp(18px,3vh,30px) 0;border-bottom:1px solid var(--linha)}\n  .custos .row .t{font-family:var(--ext);font-size:clamp(16px,1.7vw,22px)}\n  .custos .row .d{font-size:13.5px;color:var(--muted);margin-top:8px;max-width:52ch;line-height:1.6}\n  .custos .row .v{font-family:var(--ext);font-size:clamp(20px,2.4vw,34px);font-variant-numeric:tabular-nums;white-space:nowrap}\n  .custos .row .v em{font-style:normal;color:var(--muted);font-family:var(--lt);font-size:.55em;letter-spacing:.1em}\n  .custos .total .v{color:var(--indigo)}\n  .cond{margin-top:clamp(22px,4vh,40px);font-size:13px;line-height:1.7;color:var(--muted);max-width:60ch}\n\n  /* ---------- capa emoldurada ---------- */\n  .capa{padding:clamp(72px,10vh,104px) var(--mx) clamp(62px,9vh,88px);background:var(--paper)}\n  .capa .frame{position:relative;border-radius:clamp(18px,2.4vw,30px);overflow:hidden;flex:1;min-height:min(58vh,640px);display:flex;align-items:center;justify-content:center;color:#fff;background:var(--navy)}\n  .capa .frame .mid{position:relative;z-index:1;display:flex;flex-direction:column;align-items:center;text-align:center;gap:30px}\n  .capa .frame .sub{font-family:var(--lt);font-size:clamp(12px,1.3vw,16px);letter-spacing:.16em;text-transform:uppercase;opacity:.92}\n  .capa .caption{display:flex;justify-content:space-between;align-items:baseline;gap:24px;padding:clamp(16px,2.6vh,26px) 0 0;flex-wrap:wrap}\n  .capa .caption .frase-cap{font-family:var(--lt);font-size:clamp(14px,1.55vw,19px);color:var(--ink);letter-spacing:.01em}\n  .capa .caption .meta{font-size:11px;letter-spacing:.24em;text-transform:uppercase;color:var(--muted)}\n\n  /* ---------- domain expert ---------- */\n  .expert{border:1px solid var(--linha);border-radius:20px;padding:clamp(22px,3.4vh,36px);display:flex;flex-direction:column;gap:5px;max-width:400px;justify-self:end;background:#fff}\n  .expert .mono{width:54px;height:54px;border-radius:50%;background:var(--navy);color:#fff;font-family:var(--ext);font-size:16px;display:flex;align-items:center;justify-content:center;margin-bottom:16px;letter-spacing:.06em}\n  .expert .nome{font-family:var(--ext);font-size:clamp(18px,1.9vw,25px)}\n  .expert .firma{font-size:11px;letter-spacing:.26em;text-transform:uppercase;color:var(--indigo);margin:4px 0 12px}\n  .expert p{font-size:13.5px;line-height:1.68;color:var(--muted)}\n  @media(max-width:820px){.expert{justify-self:start}}\n\n  /* fechamento */\n  .fecho .mid{gap:44px}\n  .fecho .frase{font-family:var(--lt);font-size:clamp(16px,1.8vw,25px);line-height:1.65;letter-spacing:.025em;max-width:44ch;text-wrap:balance}\n  .fecho .frase i{font-style:normal;opacity:.65}\n\n  /* ---------- ring ---------- */\n  .ring{width:clamp(54px,5.4vw,80px);height:auto;display:block}\n  .ring.branco{filter:brightness(0) invert(1)}\n\n  .apoio::before{content:'';display:block;width:36px;height:2px;background:var(--indigo);margin-bottom:18px}\n  .apoio.destaque{color:var(--ink);font-size:clamp(16px,1.7vw,21px);line-height:1.6}\n\n  /* ---------- índice ---------- */\n  .indice{display:grid;grid-template-columns:1fr 1fr;gap:0 clamp(28px,5vw,90px);border-top:1px solid var(--linha)}\n  .indice a{display:flex;align-items:baseline;gap:18px;padding:clamp(13px,2.2vh,22px) 0;border-bottom:1px solid var(--linha);text-decoration:none;color:var(--ink)}\n  .indice a .n{font-family:var(--lt);font-size:11px;letter-spacing:.18em;color:var(--muted);min-width:28px;transition:color .25s}\n  .indice a .t{font-family:var(--ext);font-size:clamp(16px,1.9vw,26px);line-height:1.25;transition:transform .3s cubic-bezier(.2,.6,.2,1)}\n  .indice a:hover .n,.indice a:focus-visible .n{color:var(--indigo)}\n  .indice a:hover .t,.indice a:focus-visible .t{transform:translateX(6px)}\n  @media(max-width:820px){.indice{grid-template-columns:1fr}}\n\n  /* leitura longa em SF; Akzidenz fica pra assinatura e impacto */\n  .apoio,.pilar p,.onda li,.custos .row .d,.cond,.arq .box .bd,.expert p,.lead{font-family:var(--sf)}\n\n  /* ---------- data²: logo full + produtos ---------- */\n  .logofull{height:clamp(38px,5.4vw,66px);width:auto;filter:brightness(0);display:block;margin-bottom:clamp(20px,3.4vh,34px)}\n  .prods{display:grid;grid-template-columns:repeat(4,1fr);border-top:1px solid var(--linha)}\n  .prods .p{padding:clamp(14px,2vh,20px) 20px clamp(14px,2vh,20px) 0;border-bottom:1px solid var(--linha)}\n  .prods .pn{display:flex;align-items:center;gap:9px;font-family:var(--ext);font-size:clamp(12.5px,1.1vw,14.5px)}\n  .prods .dot{width:8px;height:8px;border-radius:50%;flex:none}\n  .prods .p p{font-family:var(--sf);font-size:12.5px;color:var(--muted);line-height:1.55;margin-top:6px}\n  @media(max-width:900px){.prods{grid-template-columns:1fr 1fr}}\n\n  /* ---------- frentes da sprint (validado × novo) ---------- */\n  .leg{display:flex;gap:26px;flex-wrap:wrap;margin-bottom:clamp(18px,3vh,30px);font-family:var(--sf);font-size:12.5px;color:var(--muted)}\n  .leg span{display:flex;align-items:center;gap:8px}\n  .leg i{width:9px;height:9px;border-radius:50%;display:inline-block}\n  .leg .ok{background:var(--ok)}\n  .leg .nv{background:var(--indigo)}\n  .frentes{display:grid;grid-template-columns:1fr 1fr;border-top:1px solid var(--linha);column-gap:clamp(24px,4vw,64px)}\n  .frentes .f{border-bottom:1px solid var(--linha);padding:clamp(12px,1.8vh,18px) 0}\n  .frentes .fn{font-family:var(--ext);font-size:clamp(13px,1.2vw,15.5px);margin-bottom:8px;display:flex;justify-content:space-between;gap:12px;align-items:baseline}\n  .frentes .fn .ct{font-family:var(--sf);font-size:10.5px;color:var(--muted);white-space:nowrap;letter-spacing:.04em}\n  .frentes .fi{display:flex;gap:8px;align-items:baseline;font-family:var(--sf);font-size:12px;line-height:1.5;color:var(--ink);padding:2.5px 0}\n  .frentes .fi::before{content:'';width:6px;height:6px;border-radius:50%;flex:none;position:relative;top:-1px}\n  .frentes .fi.ok::before{background:var(--ok)}\n  .frentes .fi.nv::before{background:var(--indigo)}\n  .frentes .fnote{font-family:var(--sf);font-size:11px;color:var(--muted);margin-top:7px;line-height:1.5}\n  .frentes .demo{margin:clamp(12px,1.8vh,18px) 0;align-self:start}\n  @media(max-width:900px){.frentes{grid-template-columns:1fr}}\n\n  /* ---------- apps da demo ---------- */\n  .apps{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(14px,2vw,28px);border-top:1px solid var(--linha);padding-top:clamp(22px,4vh,40px)}\n  .app{display:flex;flex-direction:column;gap:10px;text-decoration:none;color:var(--ink);border:1px solid var(--linha);border-radius:18px;padding:clamp(18px,2.6vh,28px);background:#fff;transition:transform .3s cubic-bezier(.2,.6,.2,1),border-color .3s,box-shadow .3s}\n  .app:hover,.app:focus-visible{transform:translateY(-4px);border-color:var(--indigo);box-shadow:0 18px 40px rgba(67,56,202,.12)}\n  .app .ak{font-size:10.5px;letter-spacing:.26em;text-transform:uppercase;color:var(--indigo)}\n  .app .at{font-family:var(--ext);font-size:clamp(16px,1.6vw,22px);line-height:1.25}\n  .app .ad{font-family:var(--sf);font-size:12.5px;line-height:1.6;color:var(--muted);flex:1}\n  .app .au{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px;color:var(--indigo);margin-top:6px}\n  @media(max-width:900px){.apps{grid-template-columns:1fr}}\n\n  /* ---------- hoje × com a estação ---------- */\n  .comps{display:flex;flex-direction:column;gap:clamp(18px,3vh,32px)}\n  .comp{display:grid;grid-template-columns:1fr 1fr;gap:clamp(18px,3vw,48px);border-top:1px solid var(--linha);padding-top:clamp(14px,2.2vh,22px)}\n  .comp .ctit{grid-column:1/-1;font-family:var(--ext);font-size:clamp(15px,1.6vw,20px)}\n  .comp .lk{font-family:var(--lt);font-size:10.5px;letter-spacing:.24em;text-transform:uppercase;margin-bottom:12px}\n  .comp .hj .lk{color:var(--bad)}\n  .comp .cn .lk{color:var(--ok)}\n  .steps{list-style:none;counter-reset:s;display:flex;flex-direction:column;gap:9px}\n  .steps li{font-family:var(--sf);font-size:12.5px;line-height:1.55;color:var(--muted);display:flex;gap:10px;align-items:baseline}\n  .steps li::before{counter-increment:s;content:counter(s);font-family:var(--lt);font-size:10px;color:var(--bad);border:1px solid currentColor;border-radius:50%;width:17px;height:17px;display:flex;align-items:center;justify-content:center;flex:none;position:relative;top:2px}\n  @media(max-width:820px){.comp{grid-template-columns:1fr}}\n\n  .klist{list-style:none;margin-top:6px}\n  .klist li{font-family:var(--sf);font-size:13.5px;line-height:1.6;color:var(--ink);padding:10px 0;border-bottom:1px solid var(--linha)}\n  .klist li b{font-weight:600}\n\n  /* ---------- kpis ---------- */\n  .kpis{display:grid;grid-template-columns:repeat(4,1fr);border-top:1px solid var(--linha)}\n  .kpis.seis{grid-template-columns:repeat(3,1fr)}\n  .kpis .k{padding:clamp(16px,2.6vh,26px) 22px clamp(16px,2.6vh,26px) 0;border-bottom:1px solid var(--linha)}\n  .kpis .k .kt{font-family:var(--ext);font-size:clamp(13.5px,1.25vw,16px);line-height:1.35}\n  .kpis .k p{font-family:var(--sf);font-size:12.5px;color:var(--muted);line-height:1.6;margin-top:8px}\n  .kpis .k .kb{font-family:var(--sf);font-size:11.5px;color:var(--indigo);margin-top:8px;line-height:1.5}\n  @media(max-width:900px){.kpis,.kpis.seis{grid-template-columns:1fr 1fr}}\n  @media(max-width:600px){.kpis,.kpis.seis{grid-template-columns:1fr}}\n\n  /* ---------- mobile ---------- */\n  @media(max-width:820px){\n    .deckroot{scroll-snap-type:y proximity}\n    nav.dots{display:none}\n    section{padding:72px 20px 82px}\n    .counter,.hint{bottom:16px}\n    .capa{padding:60px var(--mx) 96px}\n    .capa .frame{min-height:42svh}\n    .capa .frame .mid{gap:18px;padding:0 20px}\n    .capa .frame .sub{font-size:10.5px;letter-spacing:.12em;text-wrap:balance;line-height:1.7}\n    .capa .lockup{gap:14px}\n    .capa .lockup .d2m{height:25px}\n    .capa .lockup svg.cbm{height:24px}\n    .capa .lockup .plus{font-size:17px}\n    .capa .caption{flex-direction:column;align-items:flex-start;gap:10px;padding:18px 2px 0}\n    .capa .caption .frase-cap{font-size:15px;line-height:1.5;max-width:34ch}\n    .eyebrow{margin-bottom:18px}\n    .fecho .frase{font-size:15px}\n    .bg .cube{height:70%;right:-20%}\n  }\n\n  :focus-visible{outline:2px solid var(--indigo);outline-offset:4px}\n  @media (prefers-reduced-motion:reduce){\n    .deckroot{scroll-behavior:auto}\n    .rv{opacity:1;transform:none;transition:none}\n    .est .chip.rec i{animation:none}\n  }\n\n  .deckwrap{position:relative;height:100vh;height:100svh;overflow:hidden}\n  .deckroot{position:absolute;inset:0;overflow-y:auto;overflow-x:hidden;scroll-snap-type:y proximity;scroll-behavior:smooth;-webkit-overflow-scrolling:touch;overscroll-behavior-y:contain}\n\n  /* ---------- gate ---------- */\n  .gwrap{position:relative;height:100vh;height:100svh;overflow:hidden;display:flex;align-items:center;justify-content:center;background:var(--navy);font-family:var(--lt)}\n  .gcard{position:relative;z-index:1;background:var(--paper);border-radius:20px;padding:40px 36px 32px;width:min(380px,88vw);text-align:center;box-shadow:0 30px 80px rgba(0,0,0,.45)}\n  .glock{display:flex;align-items:center;justify-content:center;gap:12px;margin-bottom:14px}\n  .glock img{filter:brightness(0);display:block}\n  .glock svg.gcb{height:22px;width:auto;display:block;color:var(--ink)}\n  .glock span{font-family:var(--lt);font-size:15px;color:var(--ink)}\n  .gsub{font-family:var(--lt);font-size:10px;letter-spacing:.24em;text-transform:uppercase;color:var(--muted);margin-bottom:26px}\n  .ginput{width:100%;box-sizing:border-box;padding:13px 14px;border:1px solid var(--linha);border-radius:10px;background:#fff;font-size:15px;text-align:center;outline:none;font-family:var(--sf);color:var(--ink)}\n  .ginput:focus{border-color:var(--indigo);box-shadow:0 0 0 3px rgba(67,56,202,.16)}\n  .gbtn{width:100%;margin-top:12px;padding:13px;border:none;border-radius:10px;background:var(--indigo);color:#fff;font-size:12px;letter-spacing:.24em;text-transform:uppercase;cursor:pointer;font-family:var(--lt)}\n  .gbtn:hover{background:#3730A3}\n  .gerr{display:none;color:var(--bad);font-size:13px;margin-top:12px;font-family:var(--sf)}\n  .shake{animation:gsh .4s}\n  @keyframes gsh{0%,100%{transform:translateX(0)}20%{transform:translateX(-9px)}40%{transform:translateX(9px)}60%{transform:translateX(-5px)}80%{transform:translateX(5px)}}\n`,\n  render(d2){\n    return d2.state.unlocked ? DECK : GATE\n  },\n  mounted(d2){\n    injectFonts()\n    let ok=OPEN\n    try{ if(sessionStorage.getItem('deckCubboUnlocked')==='1') ok=true }catch(e){}\n    try{ if((location.search||'').indexOf('k='+PASS)>-1) ok=true }catch(e){}\n    const check=()=>{\n      const inp=d2.$('.ginput'); if(!inp) return\n      if(inp.value===PASS){\n        try{sessionStorage.setItem('deckCubboUnlocked','1')}catch(e){}\n        d2.state.unlocked=true\n      } else {\n        const c=d2.$('.gcard'), er=d2.$('.gerr')\n        if(er)er.style.display='block'\n        if(c){c.classList.remove('shake');void c.offsetWidth;c.classList.add('shake')}\n        if(inp.select)inp.select()\n      }\n    }\n    d2.on('.gbtn','click',check)\n    d2.on('.ginput','keydown',e=>{if(e.key==='Enter')check()})\n    if(ok) d2.state.unlocked=true\n    initDeck(d2)\n  },\n  updated(d2){\n    initDeck(d2)\n  }\n}\n"}}}}}}}}]}},{"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}},"identityProviders":[{"provider":{"component":"data2-core-primitives@String","params":{"content":"GOOGLE"}},"clientId":{"component":"data2-core-primitives@String","params":{"content":"55470861603-22pvfc1t49lp8cjnbfk71s5ct9hp1q1v.apps.googleusercontent.com"}}}]},"reference":"Data2BuilderAuthentication","updatedAt":"2026-08-06T19:31:23.557Z"},{"_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":"6a97072431ee6e52db18ff6f","component":"data2-rush@HTTPListener","reference":"cubbo-order-fetch","system":"6a7ca6cb11f8a5ec77c18b42","params":{},"deleteMetadata":{}},{"_id":"6a900c95fc5194539bd0d7b0","component":"data2-rush@HTTPListener","reference":"cubbo-picking-finish","system":"6a7ca6cb11f8a5ec77c18b42","params":{},"deleteMetadata":{}},{"_id":"6a970763181d63b9c3c3b973","component":"data2-rush@HTTPListener","reference":"cubbo-orders-status","system":"6a7ca6cb11f8a5ec77c18b42","params":{},"deleteMetadata":{}},{"_id":"6a905102df8d51bdac4db3f1","component":"data2-rush@HTTPListener","reference":"cubbo-picking-search","system":"6a7ca6cb11f8a5ec77c18b42","params":{},"deleteMetadata":{}},{"_id":"6a97075bdb111ff24b7037d8","component":"data2-rush@HTTPListener","reference":"cubbo-demo-reset","system":"6a7ca6cb11f8a5ec77c18b42","params":{},"deleteMetadata":{}},{"_id":"6a900c9986e1247c3f52b034","component":"data2-rush@HTTPListener","reference":"cubbo-track","system":"6a7ca6cb11f8a5ec77c18b42","params":{},"deleteMetadata":{}}]}},{"reference":"ComponentInstancesTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[{"_id":"6a90101952abf2e812e25b1f","component":"data2-core-primitives@Artboard","system":"6a7ca6cb11f8a5ec77c18b42","displayName":"📊 Cubbo Picking — Painel Operacional","params":{"title":{"component":"data2-core-primitives@String","params":{"content":"📊 Cubbo Picking — Painel Operacional"}},"dimensions":{"component":"data2-core-types@Dimensions","params":{"width":1440,"height":900}},"position":{"component":"data2-core-types@Position","params":{"x":-44,"y":1692,"exactX":-43.96,"exactY":1692.3200000000002}}},"reference":"pRGAvOAV_UCNruFFbrMcA","deleteMetadata":{}},{"_id":"ba0ef1f746ef4a4292c71f7d","parent":"6a90101952abf2e812e25b1f","component":"cubbo-app@cubbo-ops-panel","system":"6a7ca6cb11f8a5ec77c18b42","displayName":"Ops Panel","params":{"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":1440,"height":900}}},"pickingSearch":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"cubbo-picking-search"}},"ordersStatus":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"cubbo-orders-status"}},"demoReset":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"cubbo-demo-reset"}}},"reference":"xuUPfVdG3e0Ne7OjWHe9x","deleteMetadata":{}}]}},{"_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":"6a901029266a8719ecfc9e26","displayName":"Cubbo Picking — Painel Operacional","reference":"K3lhIKX8xAcniOUmFncQj","params":{"domain":{"component":"data2-core-primitives@String","params":{"content":"painel"}},"entryPoint":{"component":"data2-core-types@ComponentInstanceReference","params":{"component":"data2-core-primitives@Artboard","reference":"pRGAvOAV_UCNruFFbrMcA"}}},"system":"6a7ca6cb11f8a5ec77c18b42","component":"data2-core-primitives@Application"}]}},{"reference":"DataComponentInstancesTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"reference":"BundlesTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}}],"processesParams":{}}}}