{"context":{"domain":"ai-playground"},"layers":{"ApplicationLayer":{"reference":"ApplicationLayer","availableInstances":[{"reference":"ComponentsDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"component":"data2-core@DataSet","reference":"SystemsDataSet","params":{"filter":{"domain":"data2"},"pagination":{"size":1},"datasource":{"component":"data2-core-types@ProcessReference","params":{"reference":"SystemsDataSource"}}}},{"reference":"ExternalComponentInstancesDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"reference":"SystemsDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[{"_id":"5e3b796d6228227ca637d0f4","name":"data2","domain":"data2","organization":"62292184611f480b3191c37c","visibility":"public","updatedAt":"2022-03-09T02:01:26.213Z"}]}},{"reference":"OrganizationsDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"reference":"DataComponentInstancesDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"component":"data2-core@DataSet","reference":"OneFileComponentInstancesDataSet","params":{"pagination":{"size":1},"master":{"dataset":{"component":"data2-core-types@ProcessReference","params":{"reference":"SystemsDataSet"}},"localField":"system","masterField":"_id"},"datasource":{"component":"data2-core-types@ProcessReference","params":{"reference":"FileComponentInstancesDataSource"}}}},{"reference":"ApplicationsDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"reference":"ComponentInstancesDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"reference":"ServiceComponentInstancesDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"component":"data2-core@Data2TableDataSource","reference":"FileComponentInstancesDataSource","params":{"table":"fileComponentInstances","schema":[{"component":"data2-core-types@Field","params":{"key":"component","title":"Component","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"system","title":"System","component":"data2-core-primitives@ObjectId"}},{"component":"data2-core-types@Field","params":{"key":"displayName","title":"Display Name","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"params","title":"Params","component":"data2-core-primitives@Object"}},{"component":"data2-core-types@Field","params":{"key":"reference","title":"Reference","component":"data2-core-primitives@String"}}]}},{"component":"data2-core@MemoryDataSource","reference":"EmptyDataSource","params":{"initialData":[]}},{"reference":"ComponentsDataSet","component":"data2-core@DataSet","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"EmptyDataSource"}}}},{"reference":"UserComponentsDataSet","component":"data2-core@DataSet","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"EmptyDataSource"}}}},{"reference":"DataComponentInstancesDataSet","component":"data2-core@DataSet","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"EmptyDataSource"}}}},{"reference":"ServiceComponentInstancesDataSet","component":"data2-core@DataSet","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"EmptyDataSource"}}}},{"reference":"ComponentInstancesDataSet","component":"data2-core@DataSet","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"EmptyDataSource"}}}},{"reference":"ExternalComponentInstancesDataSet","component":"data2-core@DataSet","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"EmptyDataSource"}}}},{"reference":"ApplicationsDataSet","component":"data2-core@DataSet","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"EmptyDataSource"}}}}],"processesParams":{}},"HostApplicationLayer":{"reference":"HostApplicationLayer","availableInstances":[{"_id":"5f15ff190528b92601890f71","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"SystemsTableDataSource"}},"filter":{"domain":{"component":"data2-core-types@Reference","params":{"reference":"domain"}}},"pk":"_id","fields":[{"component":"data2-core-types@FieldReference","params":{"key":"_id"}},{"component":"data2-core-types@FieldReference","params":{"key":"name"}},{"component":"data2-core-types@FieldReference","params":{"key":"domain"}},{"component":"data2-core-types@FieldReference","params":{"key":"visibility"}},{"component":"data2-core-types@FieldReference","params":{"key":{"component":"data2-core-primitives@String","params":{"content":"customDomains"}}},"break":true},{"component":"data2-core-types@FieldReference","params":{"key":{"component":"data2-core-primitives@String","params":{"content":"organization._id"}}},"break":true},{"component":"data2-core-types@FieldReference","params":{"key":{"component":"data2-core-primitives@String","params":{"content":"organization.name"}}},"break":true},{"component":"data2-core-types@FieldReference","params":{"key":{"component":"data2-core-primitives@String","params":{"content":"organization.billingStatus"}}},"break":true},{"component":"data2-core-types@FieldReference","params":{"key":{"component":"data2-core-primitives@String","params":{"content":"organization.publicTrial.active"}}},"break":true}],"pagination":{"size":{"component":"data2-core-primitives@Number","params":{"content":1}}},"staticPagination":{"size":{"component":"data2-core-primitives@Number","params":{"content":1}}},"policies":[{"component":"data2-core-auth@Policy","params":{"allow":{"params":{"actions":[{"params":{"components":[{"params":{"query":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$params.query"}}}},"field":{"component":"data2-core-primitives@String","params":{"content":"_id"}},"fieldType":"string"},"component":"data2@7KkQq0vK4a7D2gg6IVJT7"},{"params":{"query":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$params.query"}}}},"field":{"component":"data2-core-primitives@String","params":{"content":"domain"}},"fieldType":"string"},"component":"data2@7KkQq0vK4a7D2gg6IVJT7"},{"params":{"query":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$params.query"}}}},"field":{"component":"data2-core-primitives@String","params":{"content":"customDomains"}},"fieldType":"string"},"component":"data2@7KkQq0vK4a7D2gg6IVJT7"}]},"component":"data2-core-logical-operators@Or"}]},"component":"data2-core-flow@Series"}}}]},"reference":"SystemsDataSet","updatedAt":"2025-11-05T19:23:47.135Z","createdAt":"2020-07-20T20:31:21.838Z"},{"_id":"5f1601ce0528b92601890f7c","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"pagination":{"size":1000},"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"ComponentsTableDataSource"}},"sort":{"params.package":1,"params.component":1},"pk":"_id","autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}},"staticFilter":{"system":{"exists":{"params":{"content":false},"component":"data2-core-primitives@Boolean"}}},"filter":{"system":{"exists":{"params":{"content":false},"component":"data2-core-primitives@Boolean"}}}},"reference":"ComponentsDataSet","updatedAt":"2025-11-05T19:37:01.935Z","createdAt":"2020-07-20T20:42:54.898Z"},{"_id":"5f9041dbc8da12be8b94aea4","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"pagination":{"size":2000},"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"ComponentsTableDataSource"}},"pk":"_id","autoEdit":true,"master":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"_id"}}},"autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}},"policies":{"params":{"allowGet":{"component":"data2-core-primitives@Boolean","params":{"content":true}}},"component":"data2@hkXy-UhMjhyfptdE6_fpW"}},"reference":"UserComponentsDataSet","updatedAt":"2025-11-06T21:06:58.095Z","createdAt":"2020-07-20T20:44:09.350Z"},{"_id":"65d8c4fabc9dbb8f94de8d53","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"ExternalComponentInstancesTableDataSource"}},"pk":"_id","autoEdit":true,"master":{"params":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"_id"}}},"component":"data2-core-types@DataSetMaster"},"autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}},"policies":{"params":{"allowGet":{"component":"data2-core-primitives@Boolean","params":{"content":true}}},"component":"data2@hkXy-UhMjhyfptdE6_fpW"}},"reference":"ExternalComponentInstancesDataSet","updatedAt":"2025-11-06T21:07:23.742Z","createdAt":"2024-02-23T16:17:01.816Z"},{"reference":"SystemsTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[{"_id":"6a11aec3b70f2dc40823369a","name":"ai-playground","domain":"ai-playground","visibility":"public","updatedAt":"2026-05-23T13:42:33.945Z","createdAt":"2026-05-23T13:42:27.995Z"}]}},{"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":"6a2406675016b5606af1c295","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","package":"ai-playground","component":"DVrB-hORW4IaqHWRtOGkl","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n    .wrap{font:13px -apple-system,system-ui,sans-serif;height:100%;overflow:auto;background:#fff}\n    .it{padding:10px 14px;border-bottom:1px solid #eef0f3;cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n    .it:hover{background:#f7f9fc}\n    .it[data-sel]{background:#eaf2ff;font-weight:600;color:#0a5}\n    .msg{padding:14px;color:#9aa3ad}\n  `,\n  render(d2) {\n    const ds = d2.data()\n    if (!ds) return '<div class=\"msg\">No dataset bound</div>'\n    if (ds.loading) return '<div class=\"msg\">Loading…</div>'\n    const rows = ds.records()\n    if (!rows.length) return '<div class=\"msg\">No data</div>'\n    const label = (r) => r.name || r.title || r.email || r.label || r.displayName ||\n      (Object.values(r).find((v) => typeof v === 'string') || r._id)\n    return '<div class=\"wrap\">' + rows.map((r) =>\n      `<div class=\"it\" data-id=\"${r._id}\" ${ds.isSelected(r) ? 'data-sel' : ''}>${label(r)}</div>`\n    ).join('') + '</div>'\n  },\n  mounted(d2) {\n    d2.on('.it', 'click', (e, el) => { d2.data().select(el.dataset.id) })\n  },\n}\n"}},"dataset":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"dataset"}}}}}}}}}},{"_id":"6a2a0f03423ea7d761bcc3ca","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","package":"ai-playground","component":"kHelloWaveZx7qP2","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n    .stage{display:flex;align-items:center;justify-content:center;gap:1px;height:100%;\n      font:800 36px -apple-system,system-ui,sans-serif;user-select:none;overflow:hidden;\n      background:radial-gradient(circle at 50% 120%, rgba(0,0,0,0.04), transparent)}\n    .ch{display:inline-block;will-change:transform;transition:color .2s}\n  `,\n  render(d2) {\n    const text = d2.param('text', 'Hello, Data²!')\n    const color = d2.param('color') || '#7c4dff'\n    const chars = String(text).split('').map((c, i) =>\n      `<span class=\"ch\" data-i=\"${i}\" style=\"color:${color}\">${c === ' ' ? '&nbsp;' : c}</span>`\n    ).join('')\n    return `<div class=\"stage\">${chars}</div>`\n  },\n  mounted(d2) {\n    let raf, t0 = null\n    const loop = (ts) => {\n      if (t0 == null) t0 = ts\n      const speed = Number(d2.param('speed', 1)) || 1          // read fresh → reactive\n      const t = ((ts - t0) / 1000) * speed\n      d2.$$('.ch').forEach((el) => {\n        const i = Number(el.getAttribute('data-i'))\n        const y = Math.sin(t * 3 + i * 0.5) * 10\n        const r = Math.sin(t * 2 + i * 0.4) * 8\n        el.style.transform = `translateY(${y.toFixed(2)}px) rotate(${r.toFixed(2)}deg)`\n      })\n      raf = requestAnimationFrame(loop)\n    }\n    raf = requestAnimationFrame(loop)\n    d2.onUnmount(() => cancelAnimationFrame(raf))\n  },\n}\n"}},"text":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"text"}}}},"color":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"color"}}}},"speed":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"speed"}}}}}}}}}},{"_id":"6a2a0fdf130ebdb8d437ae71","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","package":"ai-playground","component":"kFitTextQ9w2eR5t","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 esc = (s) => String(s).replace(/[&<>\"]/g, (c) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;' }[c]))\n\nfunction fit(d2) {\n  const box = d2.$('.fit')\n  const span = d2.$('.txt')\n  if (!box || !span) return\n  const max = Number(d2.param('maxSize', 160)) || 160\n  let lo = 6, hi = max, best = 6\n  const fits = (px) => {\n    span.style.fontSize = px + 'px'\n    return span.scrollWidth <= box.clientWidth && span.scrollHeight <= box.clientHeight\n  }\n  while (lo <= hi) {\n    const m = (lo + hi) >> 1\n    if (fits(m)) { best = m; lo = m + 1 } else { hi = m - 1 }\n  }\n  span.style.fontSize = best + 'px'\n}\n\nexport default {\n  css: `\n    .fit{display:flex;align-items:center;justify-content:center;height:100%;width:100%;\n      box-sizing:border-box;padding:8px;overflow:hidden}\n    .txt{font-family:-apple-system,system-ui,sans-serif;font-weight:800;line-height:1.05;\n      text-align:center;white-space:pre-wrap;word-break:break-word}\n  `,\n  render(d2) {\n    const text = d2.param('text', 'Type something…')\n    const color = d2.param('color') || '#111827'\n    return `<div class=\"fit\"><span class=\"txt\" style=\"color:${color}\">${esc(text)}</span></div>`\n  },\n  mounted(d2, root) {\n    if (typeof ResizeObserver !== 'undefined') {\n      const ro = new ResizeObserver(() => fit(d2))\n      ro.observe(root)\n      d2.onUnmount(() => ro.disconnect())\n    }\n  },\n  updated(d2) { fit(d2) },\n}\n"}},"text":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"text"}}}},"color":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"color"}}}},"maxSize":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"maxSize"}}}}}}}}}},{"_id":"6a2a21f00304bf52d5c03647","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kDataListZ1","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n    .tl{font:14px/1.4 -apple-system,system-ui,Segoe UI,sans-serif;height:100%;display:flex;\n        flex-direction:column;background:#fff;color:#1a1d24;overflow:hidden}\n    .tl-hd{padding:16px 18px 12px;border-bottom:1px solid #eef0f4;flex:0 0 auto}\n    .hd-row{display:flex;align-items:center;gap:8px}\n    .tl-title{font-size:17px;font-weight:700;letter-spacing:-.01em;display:flex;align-items:center;gap:8px}\n    .tl-title .dot{width:9px;height:9px;border-radius:50%;background:var(--accent,#6c5ce7);\n        box-shadow:0 0 0 4px color-mix(in srgb,var(--accent,#6c5ce7) 18%,transparent)}\n    .tl-count{font-size:12px;color:#8a92a0;font-weight:500}\n    .add{margin-left:auto;font-size:12px;font-weight:600;padding:7px 13px;border-radius:9px;border:none;\n        background:var(--accent,#6c5ce7);color:#fff;cursor:pointer;transition:.12s}\n    .add:hover{filter:brightness(1.08);transform:translateY(-1px)}\n    .add:active{transform:none}\n    .tl-search{margin-top:12px;position:relative}\n    .tl-search input{width:100%;box-sizing:border-box;padding:9px 12px 9px 34px;border:1px solid #e3e7ee;\n        border-radius:10px;font:inherit;background:#f8fafc;transition:.15s;outline:none}\n    .tl-search input:focus{border-color:var(--accent,#6c5ce7);background:#fff;\n        box-shadow:0 0 0 3px color-mix(in srgb,var(--accent,#6c5ce7) 15%,transparent)}\n    .tl-search .ic{position:absolute;left:11px;top:50%;transform:translateY(-50%);color:#9aa3b2;font-size:13px}\n    .tl-tools{display:flex;gap:6px;margin-top:10px;flex-wrap:wrap;align-items:center}\n    .chip{font-size:12px;font-weight:600;padding:5px 11px;border-radius:999px;border:1px solid #e3e7ee;\n        background:#fff;color:#5a6472;cursor:pointer;transition:.12s;user-select:none}\n    .chip:hover{border-color:#cfd6e0;color:#2b313b}\n    .chip[data-on]{background:var(--accent,#6c5ce7);border-color:var(--accent,#6c5ce7);color:#fff}\n    .chip .c{opacity:.7;margin-left:4px;font-weight:500}\n    .sp{flex:1}\n    .sort{font-size:12px;color:#8a92a0;cursor:pointer;padding:5px 9px;border-radius:8px;user-select:none;\n        border:1px solid #e3e7ee;background:#fff}\n    .sort:hover{background:#f1f4f8;color:#2b313b}\n    .tl-list{flex:1 1 auto;overflow:auto;padding:8px}\n    .row{padding:9px 10px;border-radius:11px;transition:.13s;border:1px solid transparent;margin-bottom:2px}\n    .row:hover{background:#f7f9fc;border-color:#eef0f4}\n    .row[data-open]{background:color-mix(in srgb,var(--accent,#6c5ce7) 7%,#fff);\n        border-color:color-mix(in srgb,var(--accent,#6c5ce7) 32%,#fff)}\n    .row-head{display:flex;align-items:flex-start;gap:11px;cursor:pointer}\n    .pri{flex:0 0 auto;width:28px;height:28px;border-radius:8px;display:flex;align-items:center;\n        justify-content:center;font-size:11px;font-weight:800;color:#fff;margin-top:1px}\n    .body{flex:1;min-width:0}\n    .ttl{font-weight:600;font-size:14px;letter-spacing:-.01em;display:flex;align-items:center;gap:8px}\n    .ttl .txt{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n    .badge{flex:0 0 auto;font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;\n        padding:3px 7px;border-radius:6px;line-height:1}\n    .tags{margin-top:6px;display:flex;gap:5px;flex-wrap:wrap}\n    .tag{font-size:11px;color:#6b7480;background:#eef1f6;padding:2px 8px;border-radius:6px}\n    .editor{margin-top:11px;padding:13px;border-radius:10px;background:#f8fafc;border:1px solid #eef0f4;\n        display:flex;flex-direction:column;gap:11px;animation:fade .18s ease}\n    @keyframes fade{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}\n    .fld{display:flex;flex-direction:column;gap:5px}\n    .fld label{font-size:10.5px;font-weight:700;color:#8a92a0;text-transform:uppercase;letter-spacing:.05em}\n    .fld input{padding:8px 10px;border:1px solid #e3e7ee;border-radius:8px;font:inherit;outline:none;background:#fff}\n    .fld input:focus{border-color:var(--accent,#6c5ce7);box-shadow:0 0 0 3px color-mix(in srgb,var(--accent,#6c5ce7) 14%,transparent)}\n    .seg{display:flex;gap:6px}\n    .seg button{flex:1;padding:7px;border:1px solid #e3e7ee;border-radius:8px;background:#fff;\n        font:inherit;font-size:12px;font-weight:600;color:#5a6472;cursor:pointer;transition:.12s}\n    .seg button:hover{border-color:#cfd6e0}\n    .seg button[data-on]{background:var(--accent,#6c5ce7);border-color:var(--accent,#6c5ce7);color:#fff}\n    .ed-actions{display:flex;justify-content:flex-end}\n    .del{font-size:12px;font-weight:600;color:#ef4444;background:#fff;border:1px solid #fecaca;\n        padding:7px 13px;border-radius:8px;cursor:pointer;transition:.12s}\n    .del:hover{background:#fef2f2}\n    .empty{padding:44px 20px;text-align:center;color:#9aa3b2;font-size:13px}\n    .empty .big{font-size:30px;margin-bottom:8px;opacity:.5}\n  `,\n\n  // Reactive: every d2.state / d2.data read here re-runs render automatically.\n  render(d2) {\n    const ds = d2.data()\n    const accent = d2.param('accent') || '#6c5ce7'\n    const heading = d2.param('heading', 'Items')\n    const esc = (s) => String(s == null ? '' : s)\n      .replace(/[&<>\"]/g, (c) => ({ '&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;' }[c]))\n    const shell = (inner) => `<div class=\"tl\" style=\"--accent:${accent}\">${inner}</div>`\n\n    if (!ds) return shell('<div class=\"empty\"><div class=\"big\">&#8709;</div>Nenhum dataset vinculado</div>')\n\n    const S = d2.state\n    const q = (S.q || '').toLowerCase()\n    const status = S.status || 'all'\n    const sort = S.sort || 'priority'\n    const SORT_LBL = { priority:'prioridade', title:'título', status:'status' }\n    const PRI = { 1:{bg:'#ef4444',t:'P1'}, 2:{bg:'#f59e0b',t:'P2'}, 3:{bg:'#10b981',t:'P3'} }\n    const STA = { todo:{bg:'#eef1f6',fg:'#5a6472',t:'todo'}, doing:{bg:'#dbeafe',fg:'#1d4ed8',t:'doing'},\n                  done:{bg:'#dcfce7',fg:'#15803d',t:'done'} }\n    const norm = (r) => ({\n      title: r.title || r.name || r.label || r.displayName || '(sem título)',\n      status: r.status, priority: Number(r.priority) || 0,\n      tags: Array.isArray(r.tags) ? r.tags : []\n    })\n\n    const chipDef = [['all','Todos'],['todo','A fazer'],['doing','Fazendo'],['done','Feito']]\n    const buildChips = (counts) => chipDef.map(([k, lbl]) =>\n      `<span class=\"chip\" data-chip=\"${k}\" ${status === k ? 'data-on' : ''}>${lbl}<span class=\"c\">${counts[k] || 0}</span></span>`\n    ).join('') + `<span class=\"sp\"></span><span class=\"sort\" data-sort>&#8645; ${SORT_LBL[sort]}</span>`\n\n    const header = (count, chipsHtml) => `\n      <div class=\"tl-hd\">\n        <div class=\"hd-row\">\n          <div class=\"tl-title\"><span class=\"dot\"></span>${esc(heading)}</div>\n          <span class=\"tl-count\">${count}</span>\n          <button class=\"add\" data-add>+ Nova</button>\n        </div>\n        <div class=\"tl-search\"><span class=\"ic\">&#128269;</span>\n          <input data-q type=\"text\" placeholder=\"Buscar por t&iacute;tulo ou tag&hellip;\" value=\"${esc(S.q || '')}\" />\n        </div>\n        <div class=\"tl-tools\">${chipsHtml}</div>\n      </div>`\n\n    if (ds.loading) {\n      return shell(header('…', buildChips({ all:0 })) + '<div class=\"tl-list\"><div class=\"empty\"><div class=\"big\">&#9203;</div>Carregando&hellip;</div></div>')\n    }\n\n    const recs = ds.records()\n    const counts = { all: recs.length, todo:0, doing:0, done:0 }\n    recs.forEach((r) => { if (counts[r.status] != null) counts[r.status]++ })\n\n    let rows = recs.map((r) => ({ r, f: norm(r) }))\n      .filter(({ f }) => {\n        if (status !== 'all' && f.status !== status) return false\n        if (q) { const hay = (f.title + ' ' + f.tags.join(' ')).toLowerCase(); if (!hay.includes(q)) return false }\n        return true\n      })\n      .sort((a, b) => {\n        if (sort === 'priority') return (a.f.priority || 9) - (b.f.priority || 9)\n        if (sort === 'title') return a.f.title.localeCompare(b.f.title)\n        if (sort === 'status') { const o = {todo:0,doing:1,done:2}; return (o[a.f.status] ?? 9) - (o[b.f.status] ?? 9) }\n        return 0\n      })\n\n    const editor = (r, f) => `\n      <div class=\"editor\">\n        <div class=\"fld\"><label>T&iacute;tulo</label>\n          <input data-edit-title data-id=\"${r._id}\" value=\"${esc(f.title)}\" /></div>\n        <div class=\"fld\"><label>Status</label>\n          <div class=\"seg\">${['todo','doing','done'].map((v) =>\n            `<button data-set-status data-id=\"${r._id}\" data-val=\"${v}\" ${r.status === v ? 'data-on' : ''}>${STA[v].t}</button>`).join('')}</div></div>\n        <div class=\"fld\"><label>Prioridade</label>\n          <div class=\"seg\">${[1,2,3].map((v) =>\n            `<button data-set-pri data-id=\"${r._id}\" data-val=\"${v}\" ${Number(r.priority) === v ? 'data-on' : ''}>P${v}</button>`).join('')}</div></div>\n        <div class=\"fld\"><label>Tags (separadas por v&iacute;rgula)</label>\n          <input data-edit-tags data-id=\"${r._id}\" value=\"${esc(f.tags.join(', '))}\" /></div>\n        <div class=\"ed-actions\"><button class=\"del\" data-del data-id=\"${r._id}\">&#128465; Excluir</button></div>\n      </div>`\n\n    const list = !rows.length\n      ? '<div class=\"empty\"><div class=\"big\">&#128269;</div>Nada encontrado</div>'\n      : rows.map(({ r, f }) => {\n          const p = PRI[f.priority] || { bg:'#cbd5e1', t:'–' }\n          const s = STA[f.status] || { bg:'#eef1f6', fg:'#5a6472', t: f.status || '?' }\n          const open = String(S.sel) === String(r._id)\n          const tags = f.tags.map((t) => `<span class=\"tag\">#${esc(t)}</span>`).join('')\n          return `<div class=\"row\" ${open ? 'data-open' : ''}>\n            <div class=\"row-head\" data-row=\"${r._id}\">\n              <div class=\"pri\" style=\"background:${p.bg}\">${p.t}</div>\n              <div class=\"body\">\n                <div class=\"ttl\"><span class=\"txt\">${esc(f.title)}</span>\n                  <span class=\"badge\" style=\"background:${s.bg};color:${s.fg}\">${esc(s.t)}</span></div>\n                ${tags ? `<div class=\"tags\">${tags}</div>` : ''}\n              </div>\n            </div>\n            ${open ? editor(r, f) : ''}\n          </div>`\n        }).join('')\n\n    return shell(header(rows.length + (rows.length === 1 ? ' item' : ' itens'), buildChips(counts)) + `<div class=\"tl-list\">${list}</div>`)\n  },\n\n  // Events: delegated + auto-cleaned. State writes re-render; data writes persist to the table + re-render.\n  mounted(d2) {\n    const ds = () => d2.data()\n\n    // --- UI state (re-renders, no persistence) ---\n    d2.on('[data-q]', 'input', (e, el) => { d2.state.q = el.value })\n    d2.on('[data-chip]', 'click', (e, el) => { d2.state.status = el.getAttribute('data-chip') })\n    d2.on('[data-sort]', 'click', () => {\n      const o = ['priority', 'title', 'status']\n      const cur = d2.state.sort || 'priority'\n      d2.state.sort = o[(o.indexOf(cur) + 1) % o.length]\n    })\n    d2.on('[data-row]', 'click', (e, el) => {\n      const id = el.getAttribute('data-row')\n      d2.state.sel = String(d2.state.sel) === String(id) ? null : id\n    })\n\n    // --- Writes to the underlying table (persist + reactive refresh) ---\n    d2.on('[data-add]', 'click', () => {\n      ds().create({ title: 'Nova tarefa', status: 'todo', priority: 2, tags: [] })\n    })\n    d2.on('[data-edit-title]', 'change', (e, el) => {\n      ds().update({ _id: el.getAttribute('data-id'), title: el.value })\n    })\n    d2.on('[data-set-status]', 'click', (e, el) => {\n      ds().update({ _id: el.getAttribute('data-id'), status: el.getAttribute('data-val') })\n    })\n    d2.on('[data-set-pri]', 'click', (e, el) => {\n      ds().update({ _id: el.getAttribute('data-id'), priority: Number(el.getAttribute('data-val')) })\n    })\n    d2.on('[data-edit-tags]', 'change', (e, el) => {\n      const tags = el.value.split(',').map((t) => t.trim()).filter(Boolean)\n      ds().update({ _id: el.getAttribute('data-id'), tags })\n    })\n    d2.on('[data-del]', 'click', (e, el) => {\n      ds().remove(el.getAttribute('data-id'))\n      d2.state.sel = null\n    })\n  }\n}\n"}},"dataset":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"dataset"}}}},"heading":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"heading"}}}},"accent":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"accent"}}}}}}}}}},{"_id":"6a2ab1220a295549283953d6","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kLeaderboardEx1","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n    .lb{font:14px/1.4 -apple-system,system-ui,Segoe UI,sans-serif;height:100%;display:flex;\n        flex-direction:column;background:#0f1117;color:#e8ebf2;overflow:hidden}\n    .lb-hd{padding:18px 20px 14px;flex:0 0 auto;display:flex;align-items:center;gap:10px;\n        border-bottom:1px solid #1c2030}\n    .lb-title{font-size:18px;font-weight:800;letter-spacing:-.02em;display:flex;align-items:center;gap:9px}\n    .lb-title .spark{font-size:18px;filter:drop-shadow(0 0 6px var(--accent,#ffd13b))}\n    .toggle{margin-left:auto;font-size:12px;font-weight:700;color:#9aa3b8;cursor:pointer;user-select:none;\n        padding:6px 11px;border-radius:8px;border:1px solid #262c40;background:#161a26;transition:.13s}\n    .toggle:hover{color:#e8ebf2;border-color:#39415c}\n    .lb-list{flex:1 1 auto;overflow:auto;padding:10px 12px;display:flex;flex-direction:column;gap:7px}\n    .pl{position:relative;display:flex;align-items:center;gap:13px;padding:11px 14px;border-radius:13px;\n        background:#161a26;border:1px solid #1f2436;cursor:pointer;overflow:hidden;transition:.14s}\n    .pl:hover{border-color:#39415c;transform:translateY(-1px)}\n    .pl[data-sel]{border-color:var(--accent,#ffd13b);box-shadow:0 0 0 1px var(--accent,#ffd13b)}\n    .bar{position:absolute;inset:0 auto 0 0;width:var(--w,0%);\n        background:linear-gradient(90deg, color-mix(in srgb,var(--accent,#ffd13b) 26%,transparent), transparent);\n        transition:width .55s cubic-bezier(.22,1,.36,1);z-index:0}\n    .pl > *{position:relative;z-index:1}\n    .rank{flex:0 0 auto;width:30px;text-align:center;font-size:15px;font-weight:800;color:#6b7488}\n    .rank.medal{font-size:20px}\n    .ava{flex:0 0 auto;width:38px;height:38px;border-radius:11px;background:#0f1117;display:flex;\n        align-items:center;justify-content:center;font-size:21px;border:1px solid #262c40}\n    .info{flex:1;min-width:0}\n    .nm{font-weight:700;font-size:15px;letter-spacing:-.01em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n    .sub{font-size:11.5px;color:#7c8499;margin-top:2px}\n    .val{flex:0 0 auto;font-weight:800;font-size:16px;font-variant-numeric:tabular-nums;color:var(--accent,#ffd13b)}\n    .empty{padding:50px 20px;text-align:center;color:#6b7488;font-size:13px}\n    .empty .big{font-size:32px;margin-bottom:8px;opacity:.6}\n  `,\n\n  render(d2) {\n    const esc = (s) => String(s == null ? '' : s).replace(/[&<>\"]/g,\n      (c) => ({ '&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;' }[c]))\n    let accent = '#ffd13b', title = 'Leaderboard'\n    try {\n      accent = d2.param('accent') || '#ffd13b'\n      title = d2.param('title', 'Leaderboard')\n    } catch (e) {}\n    const shell = (inner) => `<div class=\"lb\" style=\"--accent:${accent}\">${inner}</div>`\n    const msg = (icon, txt) => shell(`<div class=\"lb-hd\"><div class=\"lb-title\"><span class=\"spark\">&#9889;</span>${esc(title)}</div></div><div class=\"empty\"><div class=\"big\">${icon}</div>${esc(txt)}</div>`)\n\n    try {\n      const ds = d2.data ? d2.data() : null\n      if (!ds || typeof ds.records !== 'function') return msg('&#8709;', 'Nenhum dataset vinculado')\n\n      let recs = []\n      try { recs = ds.records() || [] } catch (e) { recs = [] }\n      if (ds.loading && !recs.length) return msg('&#9203;', 'Carregando…')\n      if (!recs.length) return msg('&#128203;', 'Tabela vazia')\n\n      // Field resolution: explicit params, else auto-detect from the first record.\n      const sample = recs[0] || {}\n      const guess = (pred) => Object.keys(sample).find((k) => k !== '_id' && pred(sample[k]))\n      let labelKey = 'name', valueKey = 'score', iconKey = ''\n      try {\n        labelKey = d2.param('labelField') || guess((v) => typeof v === 'string') || 'name'\n        valueKey = d2.param('valueField') || guess((v) => typeof v === 'number') || 'score'\n        iconKey  = d2.param('iconField') || ''\n      } catch (e) {}\n\n      const S = d2.state || {}\n      const dir = S.dir || 'desc'\n      const sel = S.sel\n      const rows = recs.map((r) => ({\n        raw: r, label: r[labelKey], value: Number(r[valueKey]) || 0, icon: iconKey ? r[iconKey] : ''\n      })).sort((a, b) => dir === 'desc' ? b.value - a.value : a.value - b.value)\n\n      let max = 1\n      for (const r of rows) if (r.value > max) max = r.value\n      const MEDALS = { 1:'&#129351;', 2:'&#129352;', 3:'&#129353;' }\n\n      const list = rows.map((row, i) => {\n        const rank = i + 1\n        const medal = (dir === 'desc' && MEDALS[rank]) ? `<span class=\"rank medal\">${MEDALS[rank]}</span>` : `<span class=\"rank\">${rank}</span>`\n        const w = (row.value / max * 100).toFixed(1)\n        const isSel = String(sel) === String(row.raw && row.raw._id)\n        const ava = row.icon ? `<div class=\"ava\">${esc(row.icon)}</div>` : ''\n        return `<div class=\"pl\" data-row=\"${esc(row.raw && row.raw._id)}\" ${isSel ? 'data-sel' : ''} style=\"--w:${w}%\">\n          <div class=\"bar\"></div>${medal}${ava}\n          <div class=\"info\"><div class=\"nm\">${esc(row.label)}</div><div class=\"sub\">${esc(valueKey)}</div></div>\n          <div class=\"val\">${Number(row.value).toLocaleString('pt-BR')}</div>\n        </div>`\n      }).join('')\n\n      return shell(`\n        <div class=\"lb-hd\">\n          <div class=\"lb-title\"><span class=\"spark\">&#9889;</span>${esc(title)}</div>\n          <span class=\"toggle\" data-toggle>${dir === 'desc' ? '&#9660; maiores' : '&#9650; menores'}</span>\n        </div>\n        <div class=\"lb-list\">${list}</div>`)\n    } catch (err) {\n      return msg('&#9888;', 'Erro ao renderizar: ' + (err && err.message ? err.message : err))\n    }\n  },\n\n  mounted(d2) {\n    try {\n      d2.on('[data-toggle]', 'click', () => {\n        try { d2.state.dir = (d2.state.dir || 'desc') === 'desc' ? 'asc' : 'desc' } catch (e) {}\n      })\n      d2.on('[data-row]', 'click', (e, el) => {\n        try {\n          const id = el.getAttribute('data-row')\n          d2.state.sel = String(d2.state.sel) === String(id) ? null : id\n        } catch (e) {}\n      })\n    } catch (e) {}\n  }\n}\n"}},"dataset":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"dataset"}}}},"labelField":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"labelField"}}}},"valueField":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"valueField"}}}},"iconField":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"iconField"}}}},"accent":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"accent"}}}},"title":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"title"}}}}}}}}}},{"_id":"6a2c2eb86cf1e528661ea2f2","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kDataGridEx","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n    .gx{font:13px/1.35 -apple-system,system-ui,Segoe UI,sans-serif;height:100%;display:flex;\n        flex-direction:column;background:#fff;color:#1f2329;overflow:hidden}\n    .gx-hd{display:flex;align-items:center;gap:10px;padding:12px 14px;border-bottom:1px solid #e6e8ec;flex:0 0 auto}\n    .gx-title{font-size:15px;font-weight:700;display:flex;align-items:center;gap:8px}\n    .gx-title .dot{width:8px;height:8px;border-radius:2px;background:var(--accent,#1f8a4c)}\n    .gx-count{font-size:12px;color:#8a9099}\n    .gx-boom{margin-left:auto;font-size:12px;font-weight:800;letter-spacing:.03em;padding:6px 14px;border-radius:7px;\n        border:1px solid #c81e2b;background:#ef2b39;color:#fff;cursor:pointer;transition:.12s;\n        box-shadow:0 1px 2px rgba(225,29,42,.4);text-transform:lowercase}\n    .gx-boom:hover{background:#e11d2a}\n    .gx-boom:active{transform:translateY(1px)}\n    .gx-add{font-size:12px;font-weight:600;padding:6px 11px;border-radius:7px;\n        border:1px solid var(--accent,#1f8a4c);background:var(--accent,#1f8a4c);color:#fff;cursor:pointer;transition:.12s}\n    .gx-add:hover{filter:brightness(1.07)}\n    .gx-scroll{flex:1 1 auto;overflow:auto}\n    table.gx-t{border-collapse:separate;border-spacing:0;min-width:100%}\n    .gx-t th,.gx-t td{border-right:1px solid #eaecef;border-bottom:1px solid #eaecef;padding:0;height:30px}\n    .gx-t thead th{position:sticky;top:0;z-index:3;background:#f6f7f9;font-weight:600;color:#5a626d;text-align:left;\n        font-size:11.5px;letter-spacing:.02em;padding:0 9px;white-space:nowrap;border-bottom:1px solid #d8dbe0}\n    .gut{position:sticky;left:0;z-index:2;background:#f6f7f9;color:#9aa0a8;text-align:center;width:42px;min-width:42px;\n        font-size:11px;font-variant-numeric:tabular-nums}\n    thead .gut{z-index:4}\n    tbody tr:hover .gut{background:#eef0f3;color:#5a626d}\n    .gv{display:inline-block}\n    .cell{padding:0 9px;line-height:30px;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;cursor:cell;\n        max-width:280px;min-width:90px}\n    .cell.num{text-align:right;font-variant-numeric:tabular-nums}\n    .cell:hover{background:#f3f8f5}\n    td[data-sel]{box-shadow:inset 0 0 0 2px var(--accent,#1f8a4c)}\n    .cell-in{width:100%;height:30px;box-sizing:border-box;border:none;outline:none;padding:0 8px;font:inherit;background:#fff}\n    .cell-in.num{text-align:right}\n    .bool{display:flex;align-items:center;justify-content:center;height:30px;cursor:pointer}\n    .delx{position:sticky;right:0;z-index:2;width:32px;min-width:32px;text-align:center;color:#cfd3d8;\n        cursor:pointer;background:#fff;line-height:30px}\n    .delx:hover{color:#ef4444;background:#fef2f2}\n    tbody tr:hover .delx{color:#9aa0a8}\n    .empty{padding:46px;text-align:center;color:#9aa0a8;font-size:13px}\n  `,\n\n  render(d2) {\n    const esc = (s) => String(s == null ? '' : s).replace(/[&<>\"]/g,\n      (c) => ({ '&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;' }[c]))\n    let accent = '#1f8a4c', title = 'Grid'\n    try { accent = d2.param('accent') || '#1f8a4c'; title = d2.param('title', 'Grid') } catch (e) {}\n    const shell = (inner) => `<div class=\"gx\" style=\"--accent:${accent}\">${inner}</div>`\n    const humanize = (k) => String(k).replace(/[_-]+/g, ' ').replace(/\\b\\w/g, (c) => c.toUpperCase())\n\n    try {\n      const ds = d2.data ? d2.data() : null\n      if (!ds || typeof ds.records !== 'function')\n        return shell('<div class=\"gx-hd\"><div class=\"gx-title\"><span class=\"dot\"></span>' + esc(title) + '</div></div><div class=\"empty\">Nenhum dataset vinculado</div>')\n\n      let recs = []\n      try { recs = ds.records() || [] } catch (e) { recs = [] }\n\n      const fmeta = {}\n      try {\n        const fs = ds.fields ? ds.fields() : []\n        if (Array.isArray(fs)) fs.forEach((f) => { if (f && f.key) fmeta[f.key] = { title: f.title, type: f.type } })\n      } catch (e) {}\n\n      const HIDE = new Set(['_id', 'createdAt', 'updatedAt'])\n      let cols = String((() => { try { return d2.param('columns') || '' } catch (e) { return '' } })())\n        .split(',').map((s) => s.trim()).filter(Boolean)\n      if (!cols.length) {\n        const seen = new Set()\n        recs.forEach((r) => Object.keys(r).forEach((k) => seen.add(k)))\n        if (!seen.size) Object.keys(fmeta).forEach((k) => seen.add(k))\n        cols = [...seen].filter((k) => !HIDE.has(k) && !k.startsWith('d2_'))\n      }\n\n      const coltype = (col) => {\n        if (fmeta[col] && fmeta[col].type) return fmeta[col].type\n        for (const r of recs) { const v = r[col]; if (v != null) {\n          if (Array.isArray(v)) return 'array'\n          if (typeof v === 'number') return 'number'\n          if (typeof v === 'boolean') return 'boolean'\n          return 'string'\n        } }\n        return 'string'\n      }\n      const colTitle = (col) => (fmeta[col] && fmeta[col].title) || humanize(col)\n      const display = (v, type) => {\n        if (v == null || v === '') return ''\n        if (Array.isArray(v)) return v.join(', ')\n        if (type === 'boolean') return v ? '✓' : ''\n        if (typeof v === 'object') return JSON.stringify(v)\n        return String(v)\n      }\n\n      const S = d2.state || {}\n      const editKey = S.edit, selKey = S.sel\n\n      const cellHtml = (r, col) => {\n        const type = coltype(col)\n        const key = r._id + '::' + col\n        const v = r[col]\n        if (type === 'boolean')\n          return `<td><div class=\"bool\"><input type=\"checkbox\" data-bool data-id=\"${esc(r._id)}\" data-col=\"${esc(col)}\" ${v ? 'checked' : ''}></div></td>`\n        if (String(editKey) === key) {\n          let raw = type === 'array' ? (Array.isArray(v) ? v.join(', ') : '')\n                  : type === 'date'  ? (v ? String(v).slice(0, 10) : '')\n                  : (v == null ? '' : String(v))\n          const it = type === 'number' ? 'number' : type === 'date' ? 'date' : 'text'\n          return `<td data-sel><input class=\"cell-in ${type === 'number' ? 'num' : ''}\" data-cellinput\n            data-id=\"${esc(r._id)}\" data-col=\"${esc(col)}\" data-type=\"${type}\" type=\"${it}\" value=\"${esc(raw)}\"></td>`\n        }\n        const sel = String(selKey) === key\n        return `<td ${sel ? 'data-sel' : ''}><div class=\"cell ${type === 'number' ? 'num' : ''}\"\n          data-cell data-id=\"${esc(r._id)}\" data-col=\"${esc(col)}\">${esc(display(v, type))}</div></td>`\n      }\n\n      const head = `<tr><th class=\"gut\"><span class=\"gv\">#</span></th>${cols.map((c) => `<th><span class=\"gv\">${esc(colTitle(c))}</span></th>`).join('')}<th class=\"delx\"></th></tr>`\n      const body = recs.map((r, ri) => `<tr>\n        <td class=\"gut\"><span class=\"gv\">${ri + 1}</span></td>\n        ${cols.map((c) => cellHtml(r, c)).join('')}\n        <td class=\"delx\" data-delrow data-id=\"${esc(r._id)}\"><span class=\"gv\">&#10005;</span></td>\n      </tr>`).join('')\n\n      const table = `<table class=\"gx-t\"><thead>${head}</thead><tbody>${body}</tbody></table>`\n      const grid = recs.length ? table : `${table}<div class=\"empty\">Sem linhas — clique em “+ linha”.</div>`\n\n      return shell(`\n        <div class=\"gx-hd\">\n          <div class=\"gx-title\"><span class=\"dot\"></span>${esc(title)}</div>\n          <span class=\"gx-count\">${recs.length} &times; ${cols.length} col</span>\n          <button class=\"gx-boom\" data-korn>korn</button>\n          <button class=\"gx-add\" data-addrow>+ linha</button>\n        </div>\n        <div class=\"gx-scroll\">${grid}</div>`)\n    } catch (err) {\n      return shell('<div class=\"empty\">Erro ao renderizar: ' + esc(err && err.message ? err.message : err) + '</div>')\n    }\n  },\n\n  mounted(d2) {\n    const ds = () => d2.data()\n    const $ = (s) => { try { return d2.root.querySelector(s) } catch (e) { return null } }\n    let suppress = false\n\n    // ===== KORN: circles -> rotating rainbow 3D sphere (Nyan trail) -> back =====\n    const NY = ['#ff2b2b', '#ff9e2c', '#ffe02c', '#3ad32c', '#2ca7ff', '#9b5cff']\n    const colorFor = (uy) => { let b = Math.floor(((uy + 1) / 2) * NY.length); if (b < 0) b = 0; if (b > NY.length - 1) b = NY.length - 1; return NY[b] }\n    let raf = null, parts = null, mode = 'idle', off = false, ang = 0, g = 0, cxG = 0, cyG = 0, Rg = 0\n    const setKornBtn = (on) => { const b = $('[data-korn]'); if (b) b.innerHTML = on ? 'korn &#9632;' : 'korn' }\n\n    function startKorn() {\n      const root = d2.root, scroll = $('.gx-scroll'); if (!root || !scroll) return\n      const sr = scroll.getBoundingClientRect()\n      cxG = sr.left + scroll.clientWidth / 2; cyG = sr.top + scroll.clientHeight / 2\n      Rg = Math.min(scroll.clientWidth, scroll.clientHeight) * 0.36\n      const els = Array.prototype.slice.call(root.querySelectorAll('.cell, .bool, .gv'))\n      const N = Math.max(1, els.length), GA = 2.399963229, D = 20\n      parts = els.map((el, i) => {\n        const r = el.getBoundingClientRect()\n        const uy = 1 - (i / Math.max(1, N - 1)) * 2, rr = Math.sqrt(Math.max(0, 1 - uy * uy)), th = i * GA\n        const ux = Math.cos(th) * rr, uz = Math.sin(th) * rr\n        const cx0 = r.left + r.width / 2, cy0 = r.top + r.height / 2\n        const col = colorFor(uy)\n        el.style.transition = 'background .45s ease, color .35s ease, border-radius .45s ease, box-shadow .45s ease'\n        el.style.position = 'fixed'; el.style.left = (cx0 - D / 2) + 'px'; el.style.top = (cy0 - D / 2) + 'px'\n        el.style.width = D + 'px'; el.style.height = D + 'px'; el.style.margin = '0'; el.style.padding = '0'\n        el.style.boxSizing = 'border-box'; el.style.overflow = 'hidden'; el.style.zIndex = '2147483000'\n        el.style.transformOrigin = 'center'; el.style.pointerEvents = 'none'\n        el.style.border = 'none'; el.style.borderRadius = '50%'\n        el.style.background = col; el.style.color = 'transparent'; el.style.boxShadow = '0 0 10px ' + col + '88'\n        return { el, cx0, cy0, ux, uy, uz, spd: 0.5 + (i % 6) * 0.13, spin0: (i * 53) % 360 }\n      })\n      off = false; g = 0; ang = 0; mode = 'on'; setKornBtn(true)\n      if (raf) cancelAnimationFrame(raf); raf = requestAnimationFrame(loop)\n    }\n\n    function loop(ts) {\n      g += ((off ? 0 : 1) - g) * 0.06; ang += 0.013\n      const tilt = 0.5, ct = Math.cos(tilt), st = Math.sin(tilt), ca = Math.cos(ang), sa = Math.sin(ang)\n      for (const p of parts) {\n        const x = p.ux * ca + p.uz * sa, z = -p.ux * sa + p.uz * ca, y = p.uy\n        const y2 = y * ct - z * st, z2 = y * st + z * ct\n        const tx = cxG + x * Rg, ty = cyG + y2 * Rg\n        const depth = 0.5 + ((z2 + 1) / 2) * 0.85\n        const curX = p.cx0 + (tx - p.cx0) * g, curY = p.cy0 + (ty - p.cy0) * g\n        const sc = 1 + (depth - 1) * g\n        const spin = p.spin0 + ts * 0.16 * p.spd\n        p.el.style.transform = `translate(${(curX - p.cx0).toFixed(1)}px,${(curY - p.cy0).toFixed(1)}px) scale(${sc.toFixed(3)}) rotateZ(${spin.toFixed(1)}deg)`\n        p.el.style.opacity = (1 - g * (1 - (0.4 + 0.6 * ((z2 + 1) / 2)))).toFixed(2)\n      }\n      if (off && g < 0.02) { cleanupKorn(); return }\n      raf = requestAnimationFrame(loop)\n    }\n\n    function cleanupKorn() {\n      if (raf) cancelAnimationFrame(raf); raf = null\n      if (parts) for (const p of parts) { p.el.style.cssText = '' }\n      parts = null; mode = 'idle'; off = false; setKornBtn(false)\n    }\n\n    try {\n      d2.on('[data-korn]', 'click', () => { if (mode !== 'on') startKorn(); else off = !off })\n\n      d2.on('[data-cell]', 'click', (e, el) => {\n        const k = el.getAttribute('data-id') + '::' + el.getAttribute('data-col')\n        d2.state.sel = k; d2.state.edit = k\n      })\n      d2.on('[data-cellinput]', 'keydown', (e, el) => {\n        if (e.key === 'Enter') { e.preventDefault(); el.blur() }\n        else if (e.key === 'Escape') { suppress = true; el.blur() }\n      })\n      d2.on('[data-cellinput]', 'change', (e, el) => {\n        if (suppress) { suppress = false; d2.state.edit = null; return }\n        try {\n          const type = el.getAttribute('data-type'), col = el.getAttribute('data-col'), id = el.getAttribute('data-id')\n          let val = el.value\n          if (type === 'number') val = val.trim() === '' ? null : Number(val)\n          else if (type === 'array') val = val.split(',').map((s) => s.trim()).filter(Boolean)\n          ds().update({ _id: id, [col]: val })\n        } catch (err) {}\n        d2.state.edit = null\n      })\n      d2.on('[data-bool]', 'change', (e, el) => {\n        try { ds().update({ _id: el.getAttribute('data-id'), [el.getAttribute('data-col')]: !!el.checked }) } catch (err) {}\n      })\n      d2.on('[data-addrow]', 'click', () => { try { ds().create({}) } catch (err) {} })\n      d2.on('[data-delrow]', 'click', (e, el) => {\n        try { ds().remove(el.getAttribute('data-id')); d2.state.edit = null; d2.state.sel = null } catch (err) {}\n      })\n\n      d2.onUnmount(() => { try { if (raf) cancelAnimationFrame(raf); if (parts) for (const p of parts) p.el.style.cssText = '' } catch (e) {} })\n    } catch (e) {}\n  },\n\n  updated(d2, root) {\n    try {\n      const el = root && root.querySelector ? root.querySelector('[data-cellinput]') : null\n      if (el && document.activeElement !== el) { el.focus(); if (el.select) el.select() }\n    } catch (e) {}\n  }\n}\n"}},"dataset":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"dataset"}}}},"columns":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"columns"}}}},"accent":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"accent"}}}},"title":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"title"}}}}}}}}}},{"_id":"6a2c329c58bb101c9092b199","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kDeckEx","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n    .dk{font:14px/1.4 -apple-system,system-ui,Segoe UI,sans-serif;height:100%;display:flex;flex-direction:column;\n        background:#0a0c12;color:#e8ebf2;overflow:hidden;position:relative}\n    .dk-bar{display:flex;align-items:center;gap:8px;padding:10px 12px;border-bottom:1px solid #181c28;flex:0 0 auto;flex-wrap:wrap}\n    .dk-bar .t{font-weight:700;font-size:14px;margin-right:4px}\n    .dk-bar .pos{font-size:12px;color:#8a93a8;font-variant-numeric:tabular-nums}\n    .btn{font-size:12px;font-weight:600;padding:6px 10px;border-radius:7px;border:1px solid #262c3c;background:#141925;\n        color:#cfd5e2;cursor:pointer;transition:.12s;user-select:none}\n    .btn:hover{background:#1b2230;border-color:#3a4256;color:#fff}\n    .btn[data-on]{background:#1b2230;border-color:#3a4256;color:#fff}\n    .btn.nav{padding:6px 11px;font-size:14px}\n    .btn.play{margin-left:auto;background:var(--accent,#ffd13b);border-color:var(--accent,#ffd13b);color:#0a0c12}\n    .btn.play:hover{filter:brightness(1.08);background:var(--accent,#ffd13b);color:#0a0c12}\n    .btn.danger:hover{background:#3a1620;border-color:#7f1d2e;color:#fda4af}\n    .dk-main{flex:1 1 auto;display:flex;min-height:0}\n    .stage-wrap{flex:1 1 auto;display:flex;align-items:center;justify-content:center;padding:18px;min-width:0;min-height:0}\n    .stage{width:100%;max-height:100%;aspect-ratio:16/9;border-radius:14px;overflow:hidden;position:relative;\n        box-shadow:0 16px 50px rgba(0,0,0,.55);container-type:size}\n    .strip{flex:0 0 auto;width:158px;overflow-y:auto;padding:10px;display:flex;flex-direction:column;gap:9px;\n        border-left:1px solid #181c28;background:#080a0f}\n    .thumb{position:relative;aspect-ratio:16/9;border-radius:8px;overflow:hidden;cursor:pointer;\n        border:2px solid transparent;container-type:size;flex:0 0 auto}\n    .thumb[data-on]{border-color:var(--accent,#ffd13b)}\n    .thumb .num{position:absolute;top:3px;left:5px;z-index:3;font-size:9px;color:#fff;opacity:.7;text-shadow:0 1px 2px rgba(0,0,0,.6)}\n    .slide{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:center;padding:7% 8%;box-sizing:border-box;color:#fff}\n    .slide.free{padding:0;display:block}\n    .el{position:absolute;cursor:grab;user-select:none;touch-action:none;max-width:96%}\n    .el:active{cursor:grabbing}\n    .el.sel{outline:2px solid var(--sa,#ffd13b);outline-offset:3px;border-radius:2px}\n    .el .txt{display:block;line-height:1.12}\n    .handle{position:absolute;right:-8px;bottom:-8px;width:15px;height:15px;border-radius:50%;background:var(--sa,#ffd13b);\n        border:2px solid #0a0c12;cursor:nwse-resize;z-index:2}\n    .conv{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,.22)}\n    .slide .h{font-size:9cqh;font-weight:800;line-height:1.04;letter-spacing:-.02em}\n    .slide .sub{font-size:3.8cqh;opacity:.82;margin-top:2.4cqh;font-weight:500}\n    .slide .emoji{font-size:15cqh;line-height:1}\n    .slide.s-cover{align-items:flex-start}.slide.s-cover .emoji{margin-bottom:2cqh}.slide.s-cover .sub{color:var(--sa,#ffd13b);opacity:1}\n    .slide.s-bullets .h{font-size:7cqh}\n    .slide.s-bullets ul{margin:4.5cqh 0 0;padding:0;list-style:none;display:flex;flex-direction:column;gap:2.6cqh}\n    .slide.s-bullets li{font-size:4.4cqh;display:flex;gap:2cqh;align-items:flex-start;line-height:1.2}\n    .slide.s-bullets li::before{content:'';flex:0 0 auto;width:1.5cqh;height:1.5cqh;margin-top:1.5cqh;border-radius:50%;background:var(--sa,#ffd13b)}\n    .slide.s-state{align-items:center;text-align:center}\n    .slide.s-state .big{font-size:7.5cqh;font-weight:700;line-height:1.18;white-space:pre-wrap}\n    .slide.s-state .sub{margin-top:4cqh;color:var(--sa,#ffd13b);opacity:1;font-size:3.4cqh}\n    .slide.s-split{flex-direction:row;align-items:center;gap:7%}\n    .slide.s-split .left{flex:1 1 auto}.slide.s-split .left .h{font-size:7cqh}\n    .slide.s-split .left .text{font-size:4cqh;opacity:.85;margin-top:3cqh;line-height:1.3}\n    .slide.s-split .right{flex:0 0 36%;display:flex;align-items:center;justify-content:center}.slide.s-split .right .emoji{font-size:26cqh}\n    @keyframes inNext{from{opacity:0;transform:translateX(7%) scale(.985)}to{opacity:1;transform:none}}\n    @keyframes inPrev{from{opacity:0;transform:translateX(-7%) scale(.985)}to{opacity:1;transform:none}}\n    .stage .slide.anim-next{animation:inNext .42s cubic-bezier(.22,1,.36,1)}\n    .stage .slide.anim-prev{animation:inPrev .42s cubic-bezier(.22,1,.36,1)}\n    .dk-edit{flex:0 0 auto;max-height:46%;overflow-y:auto;border-top:1px solid #181c28;padding:11px 12px;background:#080a0f;display:flex;flex-direction:column;gap:11px}\n    .ins-hd{display:flex;align-items:center;gap:8px;flex-wrap:wrap}\n    .ins-hd .lbl{font-size:11px;font-weight:700;color:#8a93a8;text-transform:uppercase;letter-spacing:.05em}\n    .ins-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:11px}\n    .fld{display:flex;flex-direction:column;gap:5px;min-width:0}.fld.wide{grid-column:1 / -1}\n    .fld label{font-size:10px;font-weight:700;color:#8a93a8;text-transform:uppercase;letter-spacing:.05em}\n    .fld input[type=text],.fld textarea{background:#0d1018;color:#e8ebf2;border:1px solid #232a3a;border-radius:8px;padding:8px 10px;font:inherit;font-size:13px;outline:none;box-sizing:border-box;width:100%}\n    .fld input:focus,.fld textarea:focus{border-color:var(--accent,#ffd13b)}\n    .fld textarea{min-height:54px;resize:vertical;line-height:1.4}\n    .fld input[type=range]{width:100%}\n    .seg{display:flex;gap:6px;flex-wrap:wrap}\n    .seg button{padding:7px 11px;border:1px solid #262c3c;border-radius:7px;background:#141925;color:#cfd5e2;font:inherit;font-size:12px;font-weight:600;cursor:pointer}\n    .seg button[data-on]{background:var(--accent,#ffd13b);border-color:var(--accent,#ffd13b);color:#0a0c12}\n    .colorrow{display:flex;align-items:center;gap:9px;flex-wrap:wrap}\n    .sw{width:40px;height:30px;border-radius:7px;border:1px solid #ffffff22;flex:0 0 auto}\n    input[type=color]{width:40px;height:30px;border:1px solid #232a3a;border-radius:7px;background:#0d1018;padding:2px;cursor:pointer}\n    .chips{display:flex;gap:6px;flex-wrap:wrap}\n    .chip2{width:28px;height:28px;border-radius:7px;border:1px solid #ffffff22;cursor:pointer;transition:.12s}\n    .chip2:hover{transform:scale(1.12);border-color:#fff}\n    .hint{color:#6b7488;font-size:12px;padding:6px 0}\n    .present{position:fixed;inset:0;z-index:2147483600;background:#000;display:flex;align-items:center;justify-content:center;outline:none}\n    .present .stage{width:min(100vw,177.78vh);height:min(56.25vw,100vh);max-height:100vh;border-radius:0;box-shadow:none}\n    .p-exit{position:fixed;top:16px;right:18px;z-index:5;font-size:13px;color:#fff8;background:#ffffff14;border:none;border-radius:8px;padding:7px 12px;cursor:pointer;backdrop-filter:blur(6px)}\n    .p-exit:hover{color:#fff;background:#ffffff22}\n    .p-dots{position:fixed;bottom:18px;left:50%;transform:translateX(-50%);z-index:5;display:flex;gap:8px}\n    .p-dots i{width:8px;height:8px;border-radius:50%;background:#ffffff35;transition:.2s}.p-dots i[data-on]{background:#fff;width:22px;border-radius:4px}\n    .p-arrow{position:fixed;top:50%;transform:translateY(-50%);z-index:5;font-size:30px;color:#ffffff44;cursor:pointer;padding:10px 16px;user-select:none}\n    .p-arrow:hover{color:#fff}.p-arrow.l{left:8px}.p-arrow.r{right:8px}\n    .empty{flex:1;display:flex;align-items:center;justify-content:center;color:#6b7488;font-size:13px}\n  `,\n\n  render(d2) {\n    const esc = (s) => String(s == null ? '' : s).replace(/[&<>\"]/g, (c) => ({ '&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;' }[c]))\n    const nl = (s) => esc(s).replace(/\\n/g, '<br>')\n    const isHex = (v) => typeof v === 'string' && /^#([0-9a-f]{3}|[0-9a-f]{6})$/i.test(v)\n    const GRADS = ['#0b1020', '#0a0a0f', 'radial-gradient(circle at 30% 15%, #1e293b, #060810)',\n      'linear-gradient(135deg,#4c1d95,#9333ea)', 'linear-gradient(135deg,#0ea5e9,#2563eb)',\n      'linear-gradient(135deg,#f97316,#db2777)', 'linear-gradient(135deg,#10b981,#0d9488)', 'linear-gradient(135deg,#1e293b,#0f172a)']\n    let accent = '#ffd13b'\n    try { accent = d2.param('accent') || '#ffd13b' } catch (e) {}\n\n    try {\n      const tf = (() => { try { return d2.param('titleField') || 'titulo' } catch (e) { return 'titulo' } })()\n      const cf = (() => { try { return d2.param('contentField') || 'conteudo' } catch (e) { return 'conteudo' } })()\n      const of = (() => { try { return d2.param('orderField') || 'ordem' } catch (e) { return 'ordem' } })()\n\n      const ds = d2.data ? d2.data() : null\n      const root0 = `<div class=\"dk\" style=\"--accent:${accent}\">`\n      if (!ds || typeof ds.records !== 'function') return root0 + '<div class=\"empty\">Nenhum dataset vinculado</div></div>'\n\n      let recs = []\n      try { recs = ds.records() || [] } catch (e) { recs = [] }\n      const slides = recs.slice().sort((a, b) => (Number(a[of]) || 0) - (Number(b[of]) || 0)).map((r) => {\n        let data = {}, err = null\n        try { data = JSON.parse(r[cf] || '{}') || {} } catch (e) { err = e.message; data = {} }\n        return { id: r._id, titulo: r[tf] || '', raw: r[cf] || '', data, err }\n      })\n\n      const S = d2.state || {}\n      const n = slides.length\n      let cur = Number(S.cur) || 0\n      if (cur < 0) cur = 0; if (cur > n - 1) cur = Math.max(0, n - 1)\n      const dir = S.dir === 'prev' ? 'prev' : 'next'\n      const present = S.mode === 'present'\n      const editing = !!S.editing\n      const selEl = String(S.el)\n\n      const elHtml = (el2, selected, interactive) => {\n        const sz = Number(el2.size) || 6\n        const pos = `left:${Number(el2.x) || 0}%;top:${Number(el2.y) || 0}%;`\n        const handle = (selected && interactive) ? `<div class=\"handle\" data-resize=\"${esc(el2.id)}\"></div>` : ''\n        if (el2.type === 'emoji')\n          return `<div class=\"el ${selected ? 'sel' : ''}\" data-el=\"${esc(el2.id)}\" style=\"${pos}\"><span class=\"txt\" style=\"font-size:${sz}cqh\">${esc(el2.text || '⭐')}</span>${handle}</div>`\n        const w = el2.w != null ? `width:${Number(el2.w)}%;` : ''\n        return `<div class=\"el ${selected ? 'sel' : ''}\" data-el=\"${esc(el2.id)}\" style=\"${pos}${w}\"><span class=\"txt\" style=\"font-size:${sz}cqh;color:${esc(el2.color || '#fff')};font-weight:${Number(el2.weight) || 700};text-align:${esc(el2.align || 'left')};white-space:pre-wrap\">${nl(el2.text || '')}</span>${handle}</div>`\n      }\n\n      const layoutInner = (d) => {\n        const layout = d.layout || 'cover'\n        const heading = d.heading != null ? d.heading : ''\n        if (layout === 'bullets') {\n          const items = (Array.isArray(d.bullets) ? d.bullets : []).map((b) => `<li>${esc(b)}</li>`).join('')\n          return { cls: 's-bullets', html: `<div class=\"h\">${esc(heading)}</div><ul>${items}</ul>` }\n        }\n        if (layout === 'statement' || layout === 'quote')\n          return { cls: 's-state', html: `<div class=\"big\">${nl(d.text || heading)}</div>${d.subheading ? `<div class=\"sub\">${esc(d.subheading)}</div>` : ''}` }\n        if (layout === 'split')\n          return { cls: 's-split', html: `<div class=\"left\"><div class=\"h\">${esc(heading)}</div>${d.text ? `<div class=\"text\">${nl(d.text)}</div>` : ''}</div><div class=\"right\"><div class=\"emoji\">${esc(d.emoji || '✨')}</div></div>` }\n        return { cls: 's-cover', html: `${d.emoji ? `<div class=\"emoji\">${esc(d.emoji)}</div>` : ''}<div class=\"h\">${esc(heading)}</div>${d.subheading ? `<div class=\"sub\">${esc(d.subheading)}</div>` : ''}` }\n      }\n\n      const slideHtml = (s, animate, interactive) => {\n        const d = s.data || {}\n        const bg = d.bg || '#0b1020', sa = d.accent || accent\n        const anim = animate ? ` anim-${dir}` : ''\n        if (Array.isArray(d.elements) && d.elements.length) {\n          const body = d.elements.map((e2) => elHtml(e2, interactive && selEl === String(e2.id), interactive)).join('')\n          return `<div class=\"slide free${anim}\" ${interactive ? 'data-canvas' : ''} style=\"background:${esc(bg)};--sa:${esc(sa)}\" data-k=\"${cur}\">${body}</div>`\n        }\n        const lo = layoutInner(d)\n        const conv = interactive ? `<div class=\"conv\"><button class=\"btn\" data-convert>&#10022; Tornar element-editável</button></div>` : ''\n        return `<div class=\"slide ${lo.cls}${anim}\" style=\"background:${esc(bg)};--sa:${esc(sa)}\" data-k=\"${cur}\">${lo.html}${conv}</div>`\n      }\n\n      if (!n) return root0 + `<div class=\"dk-bar\"><span class=\"t\">Deck</span><button class=\"btn play\" data-add style=\"margin-left:auto\">+ slide</button></div><div class=\"empty\">Sem slides — crie o primeiro.</div></div>`\n\n      const curSlide = slides[cur]\n\n      if (present) {\n        const dots = slides.map((s, i) => `<i ${i === cur ? 'data-on' : ''}></i>`).join('')\n        return root0 + `<div class=\"present\" data-present tabindex=\"0\"><div class=\"stage\" data-advance>${slideHtml(curSlide, true, false)}</div>\n          <div class=\"p-arrow l\" data-prev>&#8249;</div><div class=\"p-arrow r\" data-next>&#8250;</div>\n          <button class=\"p-exit\" data-exit>Esc &times;</button><div class=\"p-dots\">${dots}</div></div></div>`\n      }\n\n      const strip = slides.map((s, i) => `<div class=\"thumb\" data-thumb data-idx=\"${i}\" ${i === cur ? 'data-on' : ''}><span class=\"num\">${i + 1}</span>${slideHtml(s, false, false)}</div>`).join('')\n\n      let editor = ''\n      if (editing) {\n        const D = curSlide.data || {}\n        const chips = GRADS.map((g) => `<div class=\"chip2\" data-bg data-val=\"${esc(g)}\" style=\"background:${esc(g)}\" title=\"${esc(g)}\"></div>`).join('')\n        const slideFlds = `\n          <div class=\"fld wide\"><label>Fundo do slide</label><div class=\"colorrow\">\n            <div class=\"sw\" style=\"background:${esc(D.bg || '#0b1020')}\"></div>\n            <input type=\"color\" data-set=\"bg\" value=\"${isHex(D.bg) ? D.bg : '#0b1020'}\">\n            <div class=\"chips\">${chips}</div></div></div>\n          <div class=\"fld\"><label>Destaque</label><div class=\"colorrow\"><input type=\"color\" data-set=\"accent\" value=\"${isHex(D.accent) ? D.accent : '#ffd13b'}\"></div></div>`\n\n        let elFlds = '<div class=\"fld wide hint\">Clique num elemento do slide para arrastar e editar. Use a alça ◣ para o tamanho.</div>'\n        const els = Array.isArray(D.elements) ? D.elements : []\n        const sel = els.find((e2) => String(e2.id) === selEl)\n        if (sel) {\n          if (sel.type === 'emoji') {\n            elFlds = `\n              <div class=\"fld\"><label>Emoji</label><input type=\"text\" data-elset=\"text\" value=\"${esc(sel.text || '')}\"></div>\n              <div class=\"fld\"><label>Tamanho ${Math.round(Number(sel.size) || 6)}</label><input type=\"range\" min=\"3\" max=\"40\" step=\"0.5\" value=\"${Number(sel.size) || 18}\" data-elset=\"size\"></div>\n              <div class=\"fld wide\"><button class=\"btn danger\" data-eldel>&#128465; Excluir elemento</button></div>`\n          } else {\n            const wseg = [['400','Leve'],['600','Médio'],['800','Forte']].map(([v, l]) => `<button data-elseg=\"weight\" data-val=\"${v}\" ${String(Number(sel.weight) || 700) === v ? 'data-on' : ''}>${l}</button>`).join('')\n            const aseg = [['left','⌫'],['center','≡'],['right','⌦']].map(([v, l]) => `<button data-elseg=\"align\" data-val=\"${v}\" ${(sel.align || 'left') === v ? 'data-on' : ''}>${l}</button>`).join('')\n            elFlds = `\n              <div class=\"fld wide\"><label>Texto</label><textarea data-elset=\"text\">${esc(sel.text || '')}</textarea></div>\n              <div class=\"fld\"><label>Tamanho ${Math.round(Number(sel.size) || 6)}</label><input type=\"range\" min=\"2\" max=\"20\" step=\"0.3\" value=\"${Number(sel.size) || 6}\" data-elset=\"size\"></div>\n              <div class=\"fld\"><label>Largura ${Math.round(Number(sel.w) || 80)}%</label><input type=\"range\" min=\"15\" max=\"96\" step=\"1\" value=\"${Number(sel.w) || 80}\" data-elset=\"w\"></div>\n              <div class=\"fld\"><label>Cor</label><div class=\"colorrow\"><input type=\"color\" data-elset=\"color\" value=\"${isHex(sel.color) ? sel.color : '#ffffff'}\"></div></div>\n              <div class=\"fld\"><label>Peso</label><div class=\"seg\">${wseg}</div></div>\n              <div class=\"fld\"><label>Alinhar</label><div class=\"seg\">${aseg}</div></div>\n              <div class=\"fld wide\"><button class=\"btn danger\" data-eldel>&#128465; Excluir elemento</button></div>`\n          }\n        }\n        editor = `<div class=\"dk-edit\">\n          <div class=\"ins-hd\"><span class=\"lbl\">Editar slide ${cur + 1}</span>\n            <button class=\"btn\" data-addtext>+ Texto</button>\n            <button class=\"btn\" data-addemoji>+ Emoji</button>\n            <button class=\"btn\" data-editjson style=\"margin-left:auto\">Fechar</button></div>\n          <div class=\"ins-grid\">${slideFlds}${elFlds}</div></div>`\n      }\n\n      return root0 + `\n        <div class=\"dk-bar\">\n          <span class=\"t\">Deck</span>\n          <button class=\"btn nav\" data-prev>&#8249;</button><span class=\"pos\">${cur + 1} / ${n}</span><button class=\"btn nav\" data-next>&#8250;</button>\n          <button class=\"btn\" data-add>+ slide</button>\n          <button class=\"btn danger\" data-del data-id=\"${esc(curSlide.id)}\">&#128465;</button>\n          <button class=\"btn\" data-editjson ${editing ? 'data-on' : ''}>&#9998; Editar</button>\n          <button class=\"btn play\" data-present>&#9654; Apresentar</button>\n        </div>\n        <div class=\"dk-main\">\n          <div class=\"stage-wrap\"><div class=\"stage\" data-keys tabindex=\"0\">${slideHtml(curSlide, true, true)}</div></div>\n          <div class=\"strip\">${strip}</div>\n        </div>${editor}</div>`\n    } catch (err) {\n      return `<div class=\"dk\" style=\"--accent:${accent}\"><div class=\"empty\">Erro: ${esc(err && err.message ? err.message : err)}</div></div>`\n    }\n  },\n\n  mounted(d2) {\n    const ds = () => d2.data()\n    const $ = (s) => { try { return d2.root.querySelector(s) } catch (e) { return null } }\n    const P = (k, fb) => { try { return d2.param(k) || fb } catch (e) { return fb } }\n    const CF = () => P('contentField', 'conteudo'), OF = () => P('orderField', 'ordem'), TF = () => P('titleField', 'titulo')\n    const uid = () => 'e' + Math.random().toString(36).slice(2, 8)\n    const count = () => { try { return (ds().records() || []).length } catch (e) { return 0 } }\n    const getCur = () => Number((d2.state || {}).cur) || 0\n    const go = (delta) => { const n = count(); if (!n) return; let c = getCur() + delta; if (c < 0) c = 0; if (c > n - 1) c = n - 1; d2.state.dir = delta < 0 ? 'prev' : 'next'; d2.state.cur = c }\n    const curRec = () => { try { const of = OF(); return (ds().records() || []).slice().sort((a, b) => (Number(a[of]) || 0) - (Number(b[of]) || 0))[getCur()] || null } catch (e) { return null } }\n    const curData = () => { const rec = curRec(); if (!rec) return { rec: null, data: {} }; let data = {}; try { data = JSON.parse(rec[CF()] || '{}') || {} } catch (e) {} return { rec, data } }\n    const save = (rec, data) => { try { ds().update({ _id: rec._id, [CF()]: JSON.stringify(data) }) } catch (e) {} }\n    const applyPatch = (partial) => { const { rec, data } = curData(); if (!rec) return; Object.assign(data, partial); save(rec, data) }\n    const selId = () => String((d2.state || {}).el)\n    const patchEl = (id, partial) => { const { rec, data } = curData(); if (!rec) return; data.elements = (data.elements || []).map((e2) => String(e2.id) === String(id) ? Object.assign({}, e2, partial) : e2); save(rec, data) }\n    const pushEl = (elem) => { const { rec, data } = curData(); if (!rec) return; data.elements = (data.elements || []).slice(); data.elements.push(elem); save(rec, data); d2.state.el = elem.id }\n    const mkText = () => ({ id: uid(), type: 'text', x: 12, y: 42, w: 60, size: 7, text: 'Novo texto', color: '#ffffff', weight: 700, align: 'left' })\n    const mkEmoji = () => ({ id: uid(), type: 'emoji', x: 44, y: 38, size: 16, text: '⭐' })\n    const toElements = (d) => {\n      const els = [], sa = isHexLike(d.accent) ? d.accent : '#ffd13b'\n      const T = (x, y, w, size, text, color, weight, align) => ({ id: uid(), type: 'text', x, y, w, size, text, color, weight, align })\n      const lay = d.layout || 'cover'\n      if (lay === 'bullets') { if (d.heading) els.push(T(8, 12, 84, 7, d.heading, '#fff', 800, 'left')); const bl = Array.isArray(d.bullets) ? d.bullets : []; els.push(T(8, 34, 84, 4.4, bl.map((b) => '• ' + b).join('\\n'), '#fff', 500, 'left')) }\n      else if (lay === 'statement' || lay === 'quote') { els.push(T(10, 34, 80, 7, d.text || d.heading || '', '#fff', 700, 'center')); if (d.subheading) els.push(T(10, 66, 80, 3.4, d.subheading, sa, 600, 'center')) }\n      else if (lay === 'split') { if (d.heading) els.push(T(8, 30, 48, 7, d.heading, '#fff', 800, 'left')); if (d.text) els.push(T(8, 50, 48, 4, d.text, '#fff', 500, 'left')); els.push({ id: uid(), type: 'emoji', x: 68, y: 32, size: 24, text: d.emoji || '✨' }) }\n      else { if (d.emoji) els.push({ id: uid(), type: 'emoji', x: 8, y: 14, size: 15, text: d.emoji }); if (d.heading != null) els.push(T(8, 42, 82, 9, d.heading, '#fff', 800, 'left')); if (d.subheading) els.push(T(8, 66, 82, 3.8, d.subheading, sa, 500, 'left')) }\n      return els\n    }\n    const isHexLike = (v) => typeof v === 'string' && /^#([0-9a-f]{3}|[0-9a-f]{6})$/i.test(v)\n\n    let drag = null\n\n    try {\n      d2.on('[data-prev]', 'click', () => go(-1))\n      d2.on('[data-next]', 'click', () => go(1))\n      d2.on('[data-advance]', 'click', () => go(1))\n      d2.on('[data-thumb]', 'click', (e, el) => { const i = Number(el.getAttribute('data-idx')) || 0; d2.state.dir = i < getCur() ? 'prev' : 'next'; d2.state.cur = i; d2.state.el = null })\n      d2.on('[data-present]', 'click', () => { d2.state.mode = 'present' })\n      d2.on('[data-exit]', 'click', () => { d2.state.mode = 'edit'; try { if (document.fullscreenElement) document.exitFullscreen() } catch (e) {} })\n      d2.on('[data-editjson]', 'click', () => { d2.state.editing = !(d2.state || {}).editing })\n      d2.on('[data-convert]', 'click', () => { const { data } = curData(); applyPatch({ elements: toElements(data) }) })\n\n      // slide-level + element inspector\n      d2.on('[data-bg]', 'click', (e, el) => applyPatch({ bg: el.getAttribute('data-val') }))\n      d2.on('[data-set]', 'change', (e, el) => applyPatch({ [el.getAttribute('data-set')]: el.value }))\n      d2.on('[data-elset]', 'change', (e, el) => { const k = el.getAttribute('data-elset'); let v = el.value; if (k === 'size' || k === 'w') v = Number(v); patchEl(selId(), { [k]: v }) })\n      d2.on('[data-elseg]', 'click', (e, el) => patchEl(selId(), { [el.getAttribute('data-elseg')]: el.getAttribute('data-val') }))\n      d2.on('[data-eldel]', 'click', () => { const { rec, data } = curData(); if (!rec) return; data.elements = (data.elements || []).filter((e2) => String(e2.id) !== selId()); save(rec, data); d2.state.el = null })\n      d2.on('[data-addtext]', 'click', () => pushEl(mkText()))\n      d2.on('[data-addemoji]', 'click', () => pushEl(mkEmoji()))\n\n      // ---- free transform: drag to move ----\n      d2.on('[data-el]', 'pointerdown', (e, el) => {\n        if (e.target && e.target.getAttribute && e.target.getAttribute('data-resize')) return\n        const canvas = $('[data-canvas]'); if (!canvas) return\n        const r = canvas.getBoundingClientRect()\n        drag = { kind: 'move', id: el.getAttribute('data-el'), el, sx: e.clientX, sy: e.clientY, ox: parseFloat(el.style.left) || 0, oy: parseFloat(el.style.top) || 0, W: r.width || 1, H: r.height || 1, moved: false }\n        try { el.setPointerCapture(e.pointerId) } catch (_) {}\n      })\n      d2.on('[data-el]', 'pointermove', (e, el) => {\n        if (!drag || drag.kind !== 'move' || drag.id !== el.getAttribute('data-el')) return\n        if (Math.abs(e.clientX - drag.sx) > 2 || Math.abs(e.clientY - drag.sy) > 2) drag.moved = true\n        const nx = Math.max(0, Math.min(96, drag.ox + (e.clientX - drag.sx) / drag.W * 100))\n        const ny = Math.max(0, Math.min(94, drag.oy + (e.clientY - drag.sy) / drag.H * 100))\n        el.style.left = nx + '%'; el.style.top = ny + '%'; drag.nx = nx; drag.ny = ny\n      })\n      d2.on('[data-el]', 'pointerup', (e, el) => {\n        if (!drag || drag.id !== el.getAttribute('data-el')) return\n        try { el.releasePointerCapture(e.pointerId) } catch (_) {}\n        if (drag.moved) patchEl(drag.id, { x: Math.round(drag.nx * 10) / 10, y: Math.round(drag.ny * 10) / 10 })\n        else d2.state.el = drag.id\n        drag = null\n      })\n\n      // ---- resize handle: drag = font size ----\n      d2.on('[data-resize]', 'pointerdown', (e, el) => {\n        e.stopPropagation()\n        const id = el.getAttribute('data-resize'); const { data } = curData()\n        const elem = (data.elements || []).find((x) => String(x.id) === String(id))\n        const canvas = $('[data-canvas]'); const H = canvas ? canvas.getBoundingClientRect().height || 1 : 1\n        drag = { kind: 'size', id, sy: e.clientY, size0: Number(elem && elem.size) || 6, H, node: el.parentElement }\n        try { el.setPointerCapture(e.pointerId) } catch (_) {}\n      })\n      d2.on('[data-resize]', 'pointermove', (e, el) => {\n        if (!drag || drag.kind !== 'size') return\n        let ns = drag.size0 + (e.clientY - drag.sy) / drag.H * 100\n        ns = Math.max(2, Math.min(40, ns)); drag.ns = ns\n        const txt = drag.node && drag.node.querySelector('.txt'); if (txt) txt.style.fontSize = ns + 'cqh'\n      })\n      d2.on('[data-resize]', 'pointerup', (e, el) => {\n        if (!drag || drag.kind !== 'size') return\n        try { el.releasePointerCapture(e.pointerId) } catch (_) {}\n        patchEl(drag.id, { size: Math.round((drag.ns || drag.size0) * 10) / 10 }); drag = null\n      })\n\n      // click empty canvas = deselect\n      d2.on('[data-canvas]', 'pointerdown', (e, el) => { if (e.target === el) d2.state.el = null })\n\n      d2.on('[data-add]', 'click', () => {\n        let maxo = 0; try { (ds().records() || []).forEach((r) => { const o = Number(r[OF()]) || 0; if (o > maxo) maxo = o }) } catch (e) {}\n        const tpl = JSON.stringify({ bg: '#0b1020', accent: '#ffd13b', elements: [{ id: uid(), type: 'text', x: 8, y: 40, w: 80, size: 9, text: 'Novo slide', color: '#ffffff', weight: 800, align: 'left' }] })\n        try { ds().create({ [TF()]: 'Novo slide', [CF()]: tpl, [OF()]: maxo + 1 }) } catch (e) {}\n        d2.state.dir = 'next'; d2.state.cur = count(); d2.state.el = null\n      })\n      d2.on('[data-del]', 'click', (e, el) => { try { ds().remove(el.getAttribute('data-id')) } catch (e) {} const c = getCur(); if (c > 0) d2.state.cur = c - 1 })\n\n      const onKey = (ev) => {\n        const m = (d2.state || {}).mode\n        if (ev.key === 'ArrowRight' || ev.key === ' ' || ev.key === 'PageDown') { ev.preventDefault(); go(1) }\n        else if (ev.key === 'ArrowLeft' || ev.key === 'PageUp') { ev.preventDefault(); go(-1) }\n        else if (ev.key === 'Escape' && m === 'present') { d2.state.mode = 'edit'; try { if (document.fullscreenElement) document.exitFullscreen() } catch (e) {} }\n      }\n      d2.on('[data-keys]', 'keydown', (e) => onKey(e))\n      d2.on('[data-present]', 'keydown', (e) => onKey(e))\n      d2.onUnmount(() => { try { if (document.fullscreenElement) document.exitFullscreen() } catch (e) {} })\n    } catch (e) {}\n  },\n\n  updated(d2, root) {\n    try {\n      const present = (d2.state || {}).mode === 'present'\n      if (present && root && root.querySelector) {\n        const ov = root.querySelector('[data-present]')\n        if (ov && !document.fullscreenElement && ov.requestFullscreen) { try { ov.requestFullscreen() } catch (e) {} }\n        if (ov && document.activeElement !== ov) ov.focus()\n      }\n    } catch (e) {}\n  }\n}\n"}},"dataset":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"dataset"}}}},"titleField":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"titleField"}}}},"contentField":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"contentField"}}}},"orderField":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"orderField"}}}},"accent":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"accent"}}}}}}}}}},{"_id":"6a2c55e21b7164341d2d7ae7","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kLiquidChat","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n    .lq{position:relative;height:100%;display:flex;flex-direction:column;overflow:hidden;\n        font:14px/1.45 -apple-system,system-ui,Segoe UI,sans-serif;color:#eef0ff;\n        background:linear-gradient(160deg,#0a1022,#141c3a 55%,#0a0f20)}\n    .blob-bg{position:absolute;inset:0;overflow:hidden;pointer-events:none;filter:blur(46px);opacity:.45;z-index:0}\n    .blob-bg i{position:absolute;border-radius:50%;mix-blend-mode:screen;animation:float 16s ease-in-out infinite}\n    .blob-bg i:nth-child(1){width:240px;height:240px;background:var(--accent,#7c5cff);left:-50px;top:8%}\n    .blob-bg i:nth-child(2){width:200px;height:200px;background:#22d3ee;right:-40px;bottom:6%;animation-delay:-6s}\n    .blob-bg i:nth-child(3){width:150px;height:150px;background:#ff5ca8;left:40%;top:42%;animation-delay:-11s}\n    @keyframes float{0%,100%{transform:translate(0,0) scale(1)}50%{transform:translate(24px,-28px) scale(1.18)}}\n    .hd{position:relative;z-index:2;display:flex;align-items:center;gap:10px;padding:14px 18px;\n        border-bottom:1px solid rgba(255,255,255,.08);backdrop-filter:blur(8px)}\n    .hd .av{width:30px;height:30px;border-radius:50%;background:var(--accent,#7c5cff);display:flex;\n        align-items:center;justify-content:center;font-size:16px;box-shadow:0 0 16px var(--accent,#7c5cff)}\n    .hd .nm{font-weight:700;font-size:15px}.hd .st{font-size:11px;color:#8ea0c8}\n    .stream{position:relative;z-index:1;flex:1 1 auto;overflow-y:auto;padding:18px 16px 8px;display:flex;flex-direction:column;gap:12px}\n    .msg{display:flex;max-width:82%}\n    .msg.user{align-self:flex-end;justify-content:flex-end}\n    .msg.bot{align-self:flex-start}\n    .bubble{position:relative;padding:11px 15px;font-size:14px;line-height:1.4;white-space:pre-wrap;word-break:break-word;\n        animation:blob 9s ease-in-out infinite;box-shadow:0 6px 22px rgba(0,0,0,.28)}\n    .msg.user .bubble{background:linear-gradient(135deg,var(--accent,#7c5cff),color-mix(in srgb,var(--accent,#7c5cff) 60%,#000));\n        color:#fff;border-bottom-right-radius:7px}\n    .msg.bot .bubble{background:rgba(255,255,255,.09);border:1px solid rgba(255,255,255,.12);\n        backdrop-filter:blur(10px);color:#eef0ff;border-bottom-left-radius:7px}\n    @keyframes blob{0%,100%{border-radius:22px 24px 22px 22px}33%{border-radius:26px 20px 24px 18px}66%{border-radius:20px 26px 18px 24px}}\n    .stream > .msg:last-child .bubble{animation:pour .55s cubic-bezier(.22,1,.36,1) both, blob 9s ease-in-out .55s infinite}\n    @keyframes pour{0%{opacity:0;transform:translateY(38px) scale(.45);filter:blur(9px)}\n      55%{opacity:1;transform:translateY(-6px) scale(1.05);filter:blur(0)}100%{transform:none}}\n    .typing{display:inline-flex;gap:7px;padding:14px 18px;filter:url(#lqgoo)}\n    .typing span{width:11px;height:11px;border-radius:50%;background:#cdd6ff;animation:tdot 1s infinite}\n    .typing span:nth-child(2){animation-delay:.16s}.typing span:nth-child(3){animation-delay:.32s}\n    @keyframes tdot{0%,100%{transform:translateY(0);opacity:.55}50%{transform:translateY(-7px);opacity:1}}\n    .composer{position:relative;z-index:2;display:flex;align-items:flex-end;gap:10px;padding:12px 14px;\n        border-top:1px solid rgba(255,255,255,.08);backdrop-filter:blur(8px)}\n    .composer .wrap{flex:1;display:flex;align-items:center;background:rgba(255,255,255,.08);\n        border:1px solid rgba(255,255,255,.14);border-radius:22px;padding:4px 6px 4px 16px;transition:.15s}\n    .composer .wrap:focus-within{border-color:var(--accent,#7c5cff);box-shadow:0 0 0 3px color-mix(in srgb,var(--accent,#7c5cff) 24%,transparent)}\n    .composer textarea{flex:1;resize:none;border:none;outline:none;background:transparent;color:#eef0ff;\n        font:inherit;line-height:1.4;max-height:120px;padding:8px 0}\n    .composer textarea::placeholder{color:#7e8cb0}\n    .send{flex:0 0 auto;width:42px;height:42px;border-radius:50%;border:none;cursor:pointer;color:#fff;font-size:17px;\n        background:var(--accent,#7c5cff);box-shadow:0 6px 18px color-mix(in srgb,var(--accent,#7c5cff) 55%,transparent);\n        transition:.14s;display:flex;align-items:center;justify-content:center}\n    .send:hover{transform:translateY(-2px) scale(1.05)}.send:active{transform:scale(.94)}\n    .send[disabled]{opacity:.5;cursor:default;transform:none}\n    .empty{flex:1;display:flex;align-items:center;justify-content:center;color:#7e8cb0;font-size:13px}\n  `,\n\n  render(d2) {\n    const esc = (s) => String(s == null ? '' : s).replace(/[&<>\"]/g, (c) => ({ '&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;' }[c]))\n    let accent = '#7c5cff', botName = 'Liquid Bot'\n    try { accent = d2.param('accent') || '#7c5cff'; botName = d2.param('botName', 'Liquid Bot') } catch (e) {}\n    const goo = `<svg width=\"0\" height=\"0\" aria-hidden=\"true\" style=\"position:absolute\"><defs><filter id=\"lqgoo\"><feGaussianBlur in=\"SourceGraphic\" stdDeviation=\"4\" result=\"b\"/><feColorMatrix in=\"b\" mode=\"matrix\" values=\"1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 18 -7\"/></filter></defs></svg>`\n    const blobs = `<div class=\"blob-bg\"><i></i><i></i><i></i></div>`\n    const head = `<div class=\"hd\"><div class=\"av\">🫧</div><div><div class=\"nm\">${esc(botName)}</div><div class=\"st\">online · líquido</div></div></div>`\n\n    try {\n      const S = d2.state || {}\n      const th = (() => { try { return d2.param('thread') || 'main' } catch (e) { return 'main' } })()\n      const ds = d2.data ? d2.data() : null\n      let recs = []\n      try { recs = ds && ds.records ? ds.records() || [] : [] } catch (e) { recs = [] }\n      const msgs = recs.filter((r) => (r.thread || 'main') === th)\n        .sort((a, b) => String(a._id) < String(b._id) ? -1 : String(a._id) > String(b._id) ? 1 : 0)\n\n      const bubble = (role, content) => `<div class=\"msg ${role === 'user' ? 'user' : 'bot'}\"><div class=\"bubble\">${esc(content)}</div></div>`\n      let stream = msgs.map((m) => bubble(m.role, m.content)).join('')\n      if (S.pending) stream += bubble('user', S.pending)\n      if (S.sending) stream += `<div class=\"msg bot\"><div class=\"bubble\" style=\"padding:0;background:rgba(255,255,255,.07)\"><div class=\"typing\"><span></span><span></span><span></span></div></div></div>`\n      if (!stream) stream = '<div class=\"empty\">Diga oi 👋</div>'\n\n      const composer = `<div class=\"composer\">\n        <div class=\"wrap\"><textarea data-input rows=\"1\" placeholder=\"Escreva e veja virar bolha…\"></textarea></div>\n        <button class=\"send\" data-send ${S.sending ? 'disabled' : ''}>${S.sending ? '…' : '➤'}</button>\n      </div>`\n\n      return `<div class=\"lq\" style=\"--accent:${accent}\">${goo}${blobs}${head}<div class=\"stream\" data-stream>${stream}</div>${composer}</div>`\n    } catch (err) {\n      return `<div class=\"lq\" style=\"--accent:${accent}\">${head}<div class=\"empty\">Erro: ${esc(err && err.message ? err.message : err)}</div></div>`\n    }\n  },\n\n  mounted(d2) {\n    const $ = (s) => { try { return d2.root.querySelector(s) } catch (e) { return null } }\n    const P = (k, fb) => { try { return d2.param(k) || fb } catch (e) { return fb } }\n    const endpoint = () => P('endpoint', 'https://ai-playground.data2apis.com/rush/liquidReply')\n    const thread = () => P('thread', 'main')\n\n    async function send() {\n      const ta = $('[data-input]'); if (!ta) return\n      const text = (ta.value || '').trim()\n      if (!text || (d2.state || {}).sending) return\n      ta.value = ''; ta.style.height = 'auto'\n      d2.state.pending = text\n      d2.state.sending = true\n      try {\n        await fetch(endpoint(), { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ content: text, thread: thread() }) })\n      } catch (e) {}\n      d2.state.pending = null\n      d2.state.sending = false\n      try { const h = d2.data(); if (h && h.refresh) h.refresh() } catch (e) {}\n    }\n\n    try {\n      d2.on('[data-send]', 'click', () => send())\n      d2.on('[data-input]', 'keydown', (e, el) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); send() } })\n      d2.on('[data-input]', 'input', (e, el) => { el.style.height = 'auto'; el.style.height = Math.min(120, el.scrollHeight) + 'px' })\n    } catch (e) {}\n  },\n\n  updated(d2, root) {\n    try {\n      const st = root && root.querySelector ? root.querySelector('[data-stream]') : null\n      if (st) st.scrollTop = st.scrollHeight\n    } catch (e) {}\n  }\n}\n"}},"dataset":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"dataset"}}}},"endpoint":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"endpoint"}}}},"thread":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"thread"}}}},"accent":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"accent"}}}},"botName":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"botName"}}}}}}}}}},{"_id":"6a2c964c5284d6e4f9090c9c","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kFlix","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n    .fx{position:relative;height:100%;overflow-y:auto;overflow-x:hidden;\n        background:#141414;color:#fff;font-family:-apple-system,system-ui,sans-serif}\n    .fx::-webkit-scrollbar{width:8px}.fx::-webkit-scrollbar-thumb{background:#333;border-radius:4px}\n    .top{position:sticky;top:0;z-index:30;display:flex;align-items:center;gap:18px;padding:14px 22px;\n        background:linear-gradient(180deg,rgba(20,20,20,.96),rgba(20,20,20,0));pointer-events:none}\n    .brand{font-weight:900;font-size:20px;letter-spacing:-.5px;color:var(--a,#e50914);text-shadow:0 2px 12px rgba(0,0,0,.5)}\n    .nav{display:flex;gap:16px;font-size:13px;color:#e5e5e5;opacity:.85}\n    .hero-host{display:block;height:62%;min-height:320px;margin-top:-66px;overflow:hidden;position:relative}\n    .rows{position:relative;z-index:5;margin-top:-44px;padding-bottom:32px}\n    .row{margin:18px 0}\n    .row h3{font-size:16px;font-weight:700;color:#e5e5e5;margin:0 0 4px;padding:0 22px}\n    .track-wrap{position:relative}\n    .track{display:flex;gap:8px;overflow-x:auto;padding:28px 22px;scroll-behavior:smooth;scrollbar-width:none}\n    .track::-webkit-scrollbar{display:none}\n    .card-host{flex:0 0 auto;width:158px;aspect-ratio:2/3;border-radius:7px;overflow:hidden}\n    .arrow{position:absolute;top:28px;bottom:28px;width:42px;z-index:8;border:none;cursor:pointer;\n        color:#fff;font-size:22px;background:rgba(20,20,20,.5);opacity:0;transition:.18s}\n    .track-wrap:hover .arrow{opacity:1}.arrow:hover{background:rgba(20,20,20,.82)}\n    .arrow.l{left:0}.arrow.r{right:0}\n    .empty{display:flex;align-items:center;justify-content:center;height:100%;color:#666;font-size:14px}\n  `,\n\n  render(d2) {\n    const esc = (s) => String(s == null ? '' : s).replace(/[&<>\"]/g, c => ({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c]))\n    const stripTags = (s) => String(s == null ? '' : s).replace(/<[^>]*>/g, '').replace(/\\s+/g, ' ').trim()\n    const yr = (v) => { const m = String(v == null ? '' : v).match(/\\d{4}/); return m ? m[0] : '' }\n    let accent = '#e50914', brand = 'DATA2-FLIX'\n    try { accent = d2.param('accent') || '#e50914'; brand = d2.param('brand', 'DATA2-FLIX') } catch(e) {}\n\n    try {\n      const ds = d2.data ? d2.data() : null\n      if (!ds || typeof ds.records !== 'function')\n        return `<div class=\"fx\" style=\"--a:${accent}\"><div class=\"empty\">Nenhum dataset vinculado</div></div>`\n      let recs = []\n      try { recs = ds.records() || [] } catch(e) { recs = [] }\n      if (ds.loading && !recs.length)\n        return `<div class=\"fx\" style=\"--a:${accent}\"><div class=\"empty\">Carregando catálogo…</div></div>`\n      if (!recs.length)\n        return `<div class=\"fx\" style=\"--a:${accent}\"><div class=\"empty\">Catálogo vazio</div></div>`\n\n      const mv = (r, i) => {\n        const imgObj = r.image && typeof r.image === 'object'\n        const img = imgObj ? (r.image.original || r.image.medium) : null\n        const rt = r.rating\n        const rating = (rt && typeof rt === 'object') ? (Number(rt.average) || 0) : Number(rt != null ? rt : 0)\n        const genres = Array.isArray(r.genres) ? r.genres : (Array.isArray(r.generos) ? r.generos : [])\n        const poster = r.poster || r.capa || img || r.backdrop || ''\n        return {\n          _id: r._id != null ? r._id : (r.id != null ? String(r.id) : 'i' + i),\n          id:  r._id != null ? r._id : (r.id != null ? String(r.id) : 'i' + i),\n          title: r.title || r.name || r.titulo || 'Sem título',\n          year: yr(r.year || r.ano || r.premiered),\n          genres,\n          rating,\n          duration: Number(r.duration != null ? r.duration : (r.runtime || r.averageRuntime)) || 0,\n          description: stripTags(r.description || r.sinopse || r.summary || ''),\n          poster,\n          backdrop: r.backdrop || img || poster,\n          category: r.category || r.categoria || genres[0] || r.type || 'Destaques',\n          trending: !!(r.trending || r.emAlta) || rating >= 8.5\n        }\n      }\n      const movies = recs.map(mv)\n\n      const order = [], byCat = {}\n      movies.forEach(m => {\n        if (!byCat[m.category]) { byCat[m.category] = []; order.push(m.category) }\n        byCat[m.category].push(m)\n      })\n\n      const trend = movies.filter(m => m.trending)\n      const heroPool = trend.length ? trend : movies\n      const hero = heroPool[(Number(d2.state.hero) || 0) % heroPool.length]\n\n      const selId = d2.shared.get('flix:sel', null)\n      const selMovie = selId ? movies.find(m => String(m.id) === String(selId) || String(m._id) === String(selId)) : null\n\n      // hero: pass style explicitly so the placeholder fills .hero-host\n      const heroNode = d2.render('ai-playground@kFlixHero',\n        { record: hero, accent },\n        { key: 'hero', style: 'display:block;width:100%;height:100%' }\n      )\n\n      // cards: .card-host sets the slot dimensions\n      const rows = order.map(cat => {\n        const cards = byCat[cat].map(m =>\n          d2.render('ai-playground@kFlixCard',\n            { record: m, accent },\n            { key: String(m.id), class: 'card-host' }\n          )\n        ).join('')\n        return `<div class=\"row\">\n          <h3>${esc(cat)}</h3>\n          <div class=\"track-wrap\">\n            <button class=\"arrow l\" data-cat=\"${esc(cat)}\" data-dir=\"-1\">&#8249;</button>\n            <div class=\"track\" data-track=\"${esc(cat)}\">${cards}</div>\n            <button class=\"arrow r\" data-cat=\"${esc(cat)}\" data-dir=\"1\">&#8250;</button>\n          </div>\n        </div>`\n      }).join('')\n\n      const modalNode = selMovie\n        ? d2.render('ai-playground@kFlixModal', { record: selMovie, accent }, { key: 'modal' })\n        : ''\n\n      return `<div class=\"fx\" style=\"--a:${accent}\">\n        <div class=\"top\">\n          <span class=\"brand\">${esc(brand)}</span>\n          <div class=\"nav\"><span>Início</span><span>Séries</span><span>Filmes</span><span>Minha lista</span></div>\n        </div>\n        <div class=\"hero-host\">${heroNode}</div>\n        <div class=\"rows\">${rows}</div>\n        ${modalNode}\n      </div>`\n    } catch(err) {\n      return `<div class=\"fx\" style=\"--a:${accent}\"><div class=\"empty\">Erro: ${esc(err && err.message ? err.message : err)}</div></div>`\n    }\n  },\n\n  mounted(d2) {\n    try {\n      d2.on('[data-dir]', 'click', (e, el) => {\n        const cat = el.getAttribute('data-cat')\n        const dir = Number(el.getAttribute('data-dir')) || 1\n        const track = d2.root.querySelector(`[data-track=\"${cat}\"]`)\n        if (track) track.scrollBy({ left: dir * Math.round(track.clientWidth * 0.78), behavior: 'smooth' })\n      })\n      let h = 0\n      const t = setInterval(() => { h++; try { d2.state.hero = h } catch(e) {} }, 7000)\n      d2.onUnmount(() => clearInterval(t))\n    } catch(e) {}\n  }\n}\n"}},"dataset":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"dataset"}}}},"brand":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"brand"}}}},"accent":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"accent"}}}}}}}}}},{"_id":"6a2cb790dbf815e74e982cca","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kFlixCard","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n    .card{position:relative;width:100%;height:100%;border-radius:7px;overflow:hidden;cursor:pointer;\n        background:#222;transition:transform .25s ease,box-shadow .25s ease}\n    .card img{width:100%;height:100%;object-fit:cover;display:block}\n    .card:hover{transform:scale(1.1);box-shadow:0 14px 34px rgba(0,0,0,.7)}\n    .cap{position:absolute;inset:auto 0 0;padding:22px 10px 9px;opacity:0;transition:.2s;\n        background:linear-gradient(0deg,rgba(0,0,0,.9),transparent)}\n    .card:hover .cap{opacity:1}\n    .cap .t{font:700 12.5px -apple-system,sans-serif;color:#fff;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n    .cap .m{font:600 11px -apple-system,sans-serif;color:#46d369;margin-top:2px}\n    .rk{position:absolute;top:6px;left:6px;background:var(--a,#e50914);color:#fff;\n        font:800 10px -apple-system,sans-serif;padding:2px 6px;border-radius:4px;letter-spacing:.04em}\n  `,\n  render(d2) {\n    const esc = (s) => String(s == null ? '' : s).replace(/[&<>\"]/g, c => ({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c]))\n    let accent = '#e50914'\n    try { accent = d2.param('accent') || '#e50914' } catch(e) {}\n    const r = d2.params.record || {}\n    return `<div class=\"card\" data-click style=\"--a:${accent}\">\n      ${r.trending ? `<span class=\"rk\">EM ALTA</span>` : ''}\n      <img src=\"${esc(r.poster)}\" alt=\"${esc(r.title)}\" loading=\"lazy\">\n      <div class=\"cap\">\n        <div class=\"t\">${esc(r.title)}</div>\n        <div class=\"m\">${r.rating ? '★ ' + Number(r.rating).toFixed(1) : ''}${r.year ? ' · ' + r.year : ''}</div>\n      </div>\n    </div>`\n  },\n  mounted(d2) {\n    try {\n      d2.on('[data-click]', 'click', () => {\n        const r = d2.params.record || {}\n        d2.shared.set('flix:sel', String(r._id || r.id || ''), { global: true })\n      })\n    } catch(e) {}\n  }\n}\n"}},"record":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"record"}}}},"accent":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"accent"}}}}}}}}}},{"_id":"6a2cb79eed4fc677c35fdba3","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kFlixHero","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n    .hero{position:relative;width:100%;height:100%;display:flex;align-items:flex-end;\n        padding:0 22px 28px;box-sizing:border-box;overflow:hidden}\n    .bg{position:absolute;inset:0;background-size:cover;background-position:center 25%}\n    .scrim{position:absolute;inset:0;\n        background:linear-gradient(90deg,rgba(20,20,20,.93) 0%,rgba(20,20,20,.55) 38%,transparent 70%),\n                   linear-gradient(0deg,#141414 2%,transparent 42%)}\n    .info{position:relative;z-index:2;max-width:54%;color:#fff;font-family:-apple-system,sans-serif}\n    h1{font-size:38px;font-weight:900;line-height:1.02;letter-spacing:-1px;margin:0 0 11px;\n        text-shadow:0 3px 16px rgba(0,0,0,.7)}\n    .meta{display:flex;align-items:center;gap:12px;font-size:13px;color:#d2d2d2;margin-bottom:12px;flex-wrap:wrap}\n    .match{color:#46d369;font-weight:700}\n    .desc{font-size:14.5px;color:#dcdcdc;max-width:520px;display:-webkit-box;-webkit-line-clamp:3;\n        -webkit-box-orient:vertical;overflow:hidden;text-shadow:0 1px 8px rgba(0,0,0,.5);margin-bottom:18px}\n    .btns{display:flex;gap:12px}\n    .b{display:inline-flex;align-items:center;gap:8px;border:none;cursor:pointer;\n        font:700 15px -apple-system,sans-serif;padding:10px 22px;border-radius:6px;transition:.15s}\n    .b.play{background:#fff;color:#141414}.b.play:hover{background:#dadada}\n    .b.more{background:rgba(109,109,110,.7);color:#fff}.b.more:hover{background:rgba(109,109,110,.45)}\n  `,\n  render(d2) {\n    const esc = (s) => String(s == null ? '' : s).replace(/[&<>\"]/g, c => ({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c]))\n    const r = d2.params.record || {}\n    const rat = Number(r.rating) || 0\n    const match = Math.min(99, Math.round(rat * 9.5 + 5)) + '% relevante'\n    const dur = r.duration ? (r.duration >= 60 ? `${Math.floor(r.duration/60)}h ${r.duration%60}m` : `${r.duration}m`) : ''\n    return `<div class=\"hero\">\n      <div class=\"bg\" style=\"background-image:url('${esc(r.backdrop || r.poster)}')\"></div>\n      <div class=\"scrim\"></div>\n      <div class=\"info\">\n        <h1>${esc(r.title)}</h1>\n        <div class=\"meta\">\n          <span class=\"match\">${match}</span>\n          ${r.year ? `<span>${r.year}</span>` : ''}\n          ${dur ? `<span>${dur}</span>` : ''}\n          ${rat ? `<span>★ ${rat.toFixed(1)}</span>` : ''}\n        </div>\n        <div class=\"desc\">${esc(r.description)}</div>\n        <div class=\"btns\">\n          <button class=\"b play\" data-click>&#9654; Assistir</button>\n          <button class=\"b more\" data-click>&#9432; Mais informações</button>\n        </div>\n      </div>\n    </div>`\n  },\n  mounted(d2) {\n    try {\n      d2.on('[data-click]', 'click', () => {\n        const r = d2.params.record || {}\n        d2.shared.set('flix:sel', String(r._id || r.id || ''), { global: true })\n      })\n    } catch(e) {}\n  }\n}\n"}},"record":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"record"}}}},"accent":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"accent"}}}}}}}}}},{"_id":"6a2cb7b161efae759d5c2e97","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kFlixModal","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n    .ov{position:fixed;inset:0;z-index:200;display:flex;align-items:center;justify-content:center;\n        background:rgba(0,0,0,.72);backdrop-filter:blur(3px);padding:24px;animation:fi .18s ease;\n        font-family:-apple-system,sans-serif}\n    @keyframes fi{from{opacity:0}to{opacity:1}}\n    .sheet{position:relative;width:min(720px,94%);max-height:92%;overflow-y:auto;background:#181818;\n        border-radius:10px;box-shadow:0 24px 80px rgba(0,0,0,.85);animation:rise .28s cubic-bezier(.22,1,.36,1);color:#fff}\n    @keyframes rise{from{opacity:0;transform:translateY(28px) scale(.97)}to{opacity:1;transform:none}}\n    .hd{position:relative;aspect-ratio:16/8;background-size:cover;background-position:center 25%;\n        border-radius:10px 10px 0 0;overflow:hidden}\n    .hd .sc{position:absolute;inset:0;background:linear-gradient(0deg,#181818,transparent 58%)}\n    .hd h2{position:absolute;left:28px;bottom:18px;z-index:2;margin:0;font-size:30px;font-weight:900;\n        text-shadow:0 3px 14px rgba(0,0,0,.7)}\n    .x{position:absolute;top:12px;right:12px;z-index:3;width:34px;height:34px;border-radius:50%;\n        border:none;background:rgba(24,24,24,.85);color:#fff;font-size:16px;cursor:pointer;\n        display:flex;align-items:center;justify-content:center;transition:.12s}\n    .x:hover{background:#333}\n    .bd{padding:18px 28px 26px}\n    .meta{display:flex;align-items:center;gap:12px;font-size:13px;color:#bcbcbc;margin-bottom:14px;flex-wrap:wrap}\n    .match{color:#46d369;font-weight:700}\n    .age{border:1px solid #555;padding:1px 7px;border-radius:3px;font-size:11px}\n    .play{display:inline-flex;align-items:center;gap:8px;border:none;cursor:pointer;\n        font:700 15px inherit;padding:10px 22px;border-radius:6px;background:#fff;color:#141414;\n        margin-bottom:16px;transition:.12s}\n    .play:hover{background:#dadada}\n    .desc{font-size:14.5px;color:#e2e2e2;line-height:1.5;margin:0 0 16px;white-space:pre-wrap}\n    .chips{display:flex;flex-wrap:wrap;gap:7px}\n    .chip{font-size:12px;color:#cfcfcf;background:#2a2a2a;padding:4px 10px;border-radius:20px}\n  `,\n  render(d2) {\n    const esc = (s) => String(s == null ? '' : s).replace(/[&<>\"]/g, c => ({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c]))\n    const r = d2.params.record || {}\n    if (!r.title) return `<div></div>`\n    const rat = Number(r.rating) || 0\n    const match = Math.min(99, Math.round(rat * 9.5 + 5)) + '% relevante'\n    const dur = r.duration ? (r.duration >= 60 ? `${Math.floor(r.duration/60)}h ${r.duration%60}m` : `${r.duration}m`) : ''\n    const genres = Array.isArray(r.genres) ? r.genres : []\n    return `<div class=\"ov\" data-ov>\n      <div class=\"sheet\">\n        <button class=\"x\" data-close>&times;</button>\n        <div class=\"hd\" style=\"background-image:url('${esc(r.backdrop || r.poster)}')\">\n          <div class=\"sc\"></div><h2>${esc(r.title)}</h2>\n        </div>\n        <div class=\"bd\">\n          <div class=\"meta\">\n            <span class=\"match\">${match}</span>\n            ${r.year ? `<span>${r.year}</span>` : ''}\n            <span class=\"age\">${rat >= 8 ? '16' : '12'}</span>\n            ${dur ? `<span>${dur}</span>` : ''}\n            ${rat ? `<span>★ ${rat.toFixed(1)}</span>` : ''}\n          </div>\n          <button class=\"play\">&#9654; Assistir</button>\n          <p class=\"desc\">${esc(r.description || 'Sem sinopse.')}</p>\n          <div class=\"chips\">${genres.map(g => `<span class=\"chip\">${esc(g)}</span>`).join('')}</div>\n        </div>\n      </div>\n    </div>`\n  },\n  mounted(d2) {\n    const close = () => { try { d2.shared.set('flix:sel', null, { global: true }) } catch(e) {} }\n    try {\n      d2.on('[data-close]', 'click', close)\n      d2.on('[data-ov]', 'click', (e, el) => { if (e.target === el) close() })\n    } catch(e) {}\n  }\n}\n"}},"record":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"record"}}}},"accent":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"accent"}}}}}}}}}},{"_id":"6a2cd23c1b1e52cefa115a07","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"o2y8Xud9vKItdawnt0Nfz","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function hashStr(s){let h=2166136261;for(let i=0;i<s.length;i++){h^=s.charCodeAt(i);h=Math.imul(h,16777619);}return h>>>0;}\nfunction series(seed,up){const p=[];let v=0.5,s=seed||1;for(let i=0;i<18;i++){s=(Math.imul(s,1103515245)+12345)>>>0;const r=(s/4294967295)-0.5;v=Math.max(0.12,Math.min(0.9,v+r*0.15+(up?0.018:-0.018)));p.push(v);}return p;}\nfunction spark(pts,color){const n=pts.length,W=120,H=38,pad=3;const x=i=>(i/(n-1))*W;const y=v=>H-pad-v*(H-pad*2);let line='';pts.forEach((v,i)=>{line+=(i?'L':'M')+x(i).toFixed(1)+' '+y(v).toFixed(1)+' ';});const area=line+'L'+W+' '+H+' L0 '+H+' Z';return '<svg class=\"spk\" viewBox=\"0 0 '+W+' '+H+'\" preserveAspectRatio=\"none\"><defs><linearGradient id=\"kgrad\" x1=\"0\" x2=\"0\" y1=\"0\" y2=\"1\"><stop offset=\"0\" stop-color=\"'+color+'\" stop-opacity=\"0.16\"/><stop offset=\"1\" stop-color=\"'+color+'\" stop-opacity=\"0\"/></linearGradient></defs><path d=\"'+area+'\" fill=\"url(#kgrad)\"/><path d=\"'+line+'\" fill=\"none\" stroke=\"'+color+'\" stroke-width=\"1.5\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/></svg>';}\nfunction fmtVal(v,f){const n=Number(v)||0;if(f==='currency')return n.toLocaleString('pt-BR',{style:'currency',currency:'BRL',maximumFractionDigits:0});if(f==='percent')return n.toLocaleString('pt-BR',{minimumFractionDigits:1,maximumFractionDigits:1})+'%';if(f==='compact')return n.toLocaleString('pt-BR',{notation:'compact',maximumFractionDigits:1});return n.toLocaleString('pt-BR');}\nexport default {\n  css: `\n    .kpi{position:relative;overflow:hidden;height:100%;box-sizing:border-box;background:#fff;border:1px solid #EAECF0;border-radius:12px;padding:16px 18px 14px;display:flex;flex-direction:column;gap:7px;box-shadow:0 1px 2px rgba(16,24,40,.05);font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif}\n    .kpi .label{font-size:11px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:#98A2B3}\n    .kpi .val{font-size:26px;font-weight:600;color:#101828;letter-spacing:-.02em;font-variant-numeric:tabular-nums;line-height:1.1}\n    .kpi .bot{display:flex;align-items:center;gap:7px;font-size:12px;position:relative;z-index:1}\n    .kpi .delta{font-weight:600;display:inline-flex;align-items:center;gap:3px}\n    .kpi .delta.pos{color:#12B76A}\n    .kpi .delta.neg{color:#F04438}\n    .kpi .vs{color:#98A2B3}\n    .kpi .spk{position:absolute;left:0;right:0;bottom:0;width:100%;height:38px}\n  `,\n  render(d2){\n    const label=d2.param('label','Métrica');\n    const value=d2.param('value',0);\n    const delta=Number(d2.param('delta',0));\n    const format=d2.param('format','number');\n    const up=delta>=0;\n    const color=up?'#12B76A':'#F04438';\n    const pts=series(hashStr(label),up);\n    return '<div class=\"kpi\">'+\n      '<span class=\"label\">'+label+'</span>'+\n      '<span class=\"val\">'+fmtVal(value,format)+'</span>'+\n      '<div class=\"bot\"><span class=\"delta '+(up?'pos':'neg')+'\">'+(up?'▲':'▼')+' '+Math.abs(delta).toFixed(1)+'%</span>'+\n      '<span class=\"vs\">vs. período anterior</span></div>'+\n      spark(pts,color)+\n    '</div>';\n  }\n}"}},"label":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"label"}}}},"value":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"value"}}}},"delta":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"delta"}}}},"format":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"format"}}}}}}}}}},{"_id":"6a2cd23d58bb101c9093c120","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"2XVaNABM4viNiNHExpOHs","package":"ai-playground","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 PAL=[['#EEF4FF','#3538CD'],['#ECFDF3','#027A48'],['#FEF3F2','#B42318'],['#FFFAEB','#B54708'],['#F4F3FF','#5925DC'],['#F0F9FF','#026AA2']];\nfunction initials(name){const p=String(name||'').trim().split(/\\s+/);return (((p[0]||'')[0]||'')+((p[1]||'')[0]||'')).toUpperCase()||'?';}\nexport default {\n  css: `\n    .card{height:100%;box-sizing:border-box;background:#fff;border:1px solid #EAECF0;border-radius:12px;display:flex;flex-direction:column;box-shadow:0 1px 2px rgba(16,24,40,.05);overflow:hidden;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif}\n    .hd{display:flex;align-items:center;justify-content:space-between;padding:15px 18px;border-bottom:1px solid #F2F4F7}\n    .hd .t{font-size:14px;font-weight:600;color:#101828}\n    .hd .ct{font-size:12px;font-weight:500;color:#475467;background:#F2F4F7;padding:2px 9px;border-radius:999px}\n    .list{flex:1;overflow:auto}\n    .row{display:flex;align-items:center;gap:12px;padding:11px 18px;border-bottom:1px solid #F9FAFB;transition:background .15s}\n    .row:last-child{border-bottom:none}\n    .row:hover{background:#FCFCFD}\n    .ava{width:36px;height:36px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:13px;font-weight:600;flex:0 0 auto}\n    .who{flex:1;min-width:0}\n    .nm{font-size:13.5px;font-weight:500;color:#101828;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n    .rl{font-size:12px;color:#667085;margin-top:1px}\n    .st{display:flex;align-items:center;gap:6px;font-size:12px;color:#475467;flex:0 0 auto}\n    .dot{width:7px;height:7px;border-radius:50%;flex:0 0 auto}\n    .empty{padding:28px;color:#98A2B3;font-size:13px;text-align:center}\n  `,\n  render(d2){\n    const ds=d2.data();\n    const title=d2.param('title','Equipe');\n    const STA={online:['#12B76A','Ativo'],away:['#F79009','Ausente'],offline:['#98A2B3','Offline']};\n    if(!ds) return '<div class=\"card\"><div class=\"hd\"><span class=\"t\">'+title+'</span></div><div class=\"empty\">Sem dataset</div></div>';\n    const recs=ds.records();\n    const rows=recs.length?recs.map((r,i)=>{\n      const pal=PAL[i%PAL.length];const st=STA[r.status]||STA.offline;\n      return '<div class=\"row\" data-key=\"'+r._id+'\">'+\n        '<div class=\"ava\" style=\"background:'+pal[0]+';color:'+pal[1]+'\">'+initials(r.name)+'</div>'+\n        '<div class=\"who\"><div class=\"nm\">'+(r.name||'')+'</div><div class=\"rl\">'+(r.role||'')+'</div></div>'+\n        '<div class=\"st\"><span class=\"dot\" style=\"background:'+st[0]+'\"></span>'+st[1]+'</div>'+\n      '</div>';\n    }).join(''):'<div class=\"empty\">Sem membros</div>';\n    return '<div class=\"card\"><div class=\"hd\"><span class=\"t\">'+title+'</span><span class=\"ct\">'+recs.length+' membros</span></div><div class=\"list\">'+rows+'</div></div>';\n  }\n}"}},"dataset":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"dataset"}}}},"title":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"title"}}}}}}}}}},{"_id":"6a2cd23f1b1e52cefa115a10","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"jqNAuSJt7UG4L-cGrT9t4","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function rel(ts){const d=new Date(ts);if(isNaN(d.getTime()))return '';const diff=(Date.now()-d.getTime())/1000;if(diff<60)return 'agora';if(diff<3600)return 'há '+Math.floor(diff/60)+'min';if(diff<86400)return 'há '+Math.floor(diff/3600)+'h';return 'há '+Math.floor(diff/86400)+'d';}\nexport default {\n  css: `\n    .card{height:100%;box-sizing:border-box;background:#fff;border:1px solid #EAECF0;border-radius:12px;display:flex;flex-direction:column;box-shadow:0 1px 2px rgba(16,24,40,.05);overflow:hidden;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif}\n    .hd{padding:15px 18px;border-bottom:1px solid #F2F4F7}\n    .hd .t{font-size:14px;font-weight:600;color:#101828}\n    .list{flex:1;overflow:auto;padding:16px 18px 6px}\n    .ev{position:relative;padding:0 0 16px 20px;border-left:2px solid #EAECF0;margin-left:5px}\n    .ev:last-child{border-left-color:transparent;padding-bottom:2px}\n    .dot{position:absolute;left:-7px;top:1px;width:12px;height:12px;border-radius:50%;border:2px solid #fff;box-shadow:0 0 0 1px #EAECF0}\n    .top{display:flex;justify-content:space-between;gap:8px;align-items:baseline}\n    .who{font-size:13px;font-weight:600;color:#101828}\n    .tm{font-size:11px;color:#98A2B3;white-space:nowrap}\n    .act{font-size:12.5px;color:#475467;margin-top:2px;line-height:1.4}\n    .empty{padding:28px;color:#98A2B3;font-size:13px;text-align:center}\n  `,\n  render(d2){\n    const ds=d2.data();\n    const title=d2.param('title','Atividade recente');\n    const TYPE={success:'#12B76A',info:'#2E90FA',update:'#F79009',warning:'#F04438'};\n    if(!ds) return '<div class=\"card\"><div class=\"hd\"><span class=\"t\">'+title+'</span></div><div class=\"empty\">Sem dataset</div></div>';\n    const recs=ds.records();\n    const evs=recs.length?recs.map(r=>{\n      const c=TYPE[r.type]||'#98A2B3';\n      return '<div class=\"ev\" data-key=\"'+r._id+'\"><span class=\"dot\" style=\"background:'+c+'\"></span>'+\n        '<div class=\"top\"><span class=\"who\">'+(r.user||'')+'</span><span class=\"tm\">'+rel(r.timestamp)+'</span></div>'+\n        '<div class=\"act\">'+(r.action||'')+'</div></div>';\n    }).join(''):'<div class=\"empty\">Sem atividades</div>';\n    return '<div class=\"card\"><div class=\"hd\"><span class=\"t\">'+title+'</span></div><div class=\"list\">'+evs+'</div></div>';\n  }\n}"}},"dataset":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"dataset"}}}},"title":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"title"}}}}}}}}}},{"_id":"6a2d2c90ed4fc677c36047ec","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kDashboard","package":"ai-playground","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 KPI='ai-playground@o2y8Xud9vKItdawnt0Nfz';\nconst TEAM='ai-playground@2XVaNABM4viNiNHExpOHs';\nconst TL='ai-playground@jqNAuSJt7UG4L-cGrT9t4';\nconst FMT={'Receita':'currency','Conversão':'percent'};\nexport default {\n  css: `\n    .dash{height:100%;box-sizing:border-box;overflow:auto;background:#F7F8FA;padding:26px 30px;display:flex;flex-direction:column;gap:20px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;color:#101828}\n    .hd{display:flex;justify-content:space-between;align-items:flex-end;gap:16px;flex-wrap:wrap}\n    .hd h1{margin:0;font-size:21px;font-weight:600;letter-spacing:-.02em}\n    .hd .sb{margin:3px 0 0;font-size:13px;color:#667085}\n    .hd .badge{font-size:12px;font-weight:500;color:#027A48;background:#ECFDF3;border:1px solid #ABEFC6;padding:4px 11px;border-radius:999px;display:inline-flex;align-items:center;gap:6px}\n    .hd .badge .pip{width:7px;height:7px;border-radius:50%;background:#12B76A}\n    .kpis{display:grid;grid-template-columns:repeat(4,1fr);grid-auto-rows:148px;gap:16px}\n    .cols{display:grid;grid-template-columns:1.5fr 1fr;gap:16px;flex:1;min-height:320px}\n    .c-main,.c-side{min-height:0}\n    @media (max-width:900px){.kpis{grid-template-columns:repeat(2,1fr)}.cols{grid-template-columns:1fr}}\n  `,\n  render(d2){\n    const title=d2.param('title','Visão Geral');\n    const m=d2.data('metrics');\n    const recs=m?m.records():[];\n    const kpis=recs.length\n      ? recs.map(r=>d2.render(KPI,{label:r.metric,value:r.value,delta:r.trend,format:FMT[r.metric]||'number'},{key:r._id})).join('')\n      : '';\n    const team=d2.render(TEAM,{dataset:d2.params.users,title:'Equipe'},{key:'team'});\n    const tl=d2.render(TL,{dataset:d2.params.activity,title:'Atividade recente'},{key:'tl'});\n    return '<div class=\"dash\">'+\n      '<header class=\"hd\"><div><h1>'+title+'</h1><p class=\"sb\">Resumo operacional consolidado</p></div>'+\n      '<span class=\"badge\"><span class=\"pip\"></span>Em tempo real</span></header>'+\n      '<section class=\"kpis\">'+kpis+'</section>'+\n      '<section class=\"cols\"><div class=\"c-main\">'+team+'</div><div class=\"c-side\">'+tl+'</div></section>'+\n    '</div>';\n  }\n}"}},"metrics":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"metrics"}}}},"users":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"users"}}}},"activity":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"activity"}}}},"title":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"title"}}}}}}}}}},{"_id":"6a2d366261efae759d5c9b5e","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kBarChart","package":"ai-playground","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 DATA=[['Jan',32],['Fev',45],['Mar',38],['Abr',52],['Mai',49],['Jun',63]];\nexport default {\n  css: `\n    .wrap{height:100%;box-sizing:border-box;background:#fff;border:1px solid #EAECF0;border-radius:14px;padding:18px 20px;display:flex;flex-direction:column;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;box-shadow:0 1px 2px rgba(16,24,40,.05)}\n    .title{font-size:13px;font-weight:600;color:#101828;margin-bottom:2px}\n    .title .unit{color:#98A2B3;font-weight:500}\n    .bars{flex:1;display:flex;align-items:flex-end;gap:10px;padding-top:18px}\n    .col{flex:1;display:flex;flex-direction:column;align-items:center;gap:7px;height:100%;justify-content:flex-end}\n    .bar{width:100%;border-radius:6px 6px 0 0;background:linear-gradient(180deg,#818CF8,#6366F1);position:relative;transform-origin:bottom;animation:grow .6s cubic-bezier(.2,.8,.2,1) both;transition:filter .15s}\n    .col:hover .bar{filter:brightness(1.1)}\n    .bar .v{position:absolute;top:-18px;left:50%;transform:translateX(-50%);font-size:11px;font-weight:600;color:#475467;opacity:0;transition:opacity .15s}\n    .col:hover .bar .v{opacity:1}\n    .lb{font-size:11px;color:#98A2B3;font-weight:500}\n    @keyframes grow{from{transform:scaleY(0)}to{transform:scaleY(1)}}\n  `,\n  render(d2){\n    const max=Math.max.apply(null,DATA.map(function(d){return d[1];}));\n    const bars=DATA.map(function(d,i){\n      var h=(d[1]/max)*100;\n      return '<div class=\"col\"><div class=\"bar\" style=\"height:'+h+'%;animation-delay:'+(i*70)+'ms\"><span class=\"v\">'+d[1]+'</span></div><span class=\"lb\">'+d[0]+'</span></div>';\n    }).join('');\n    return '<div class=\"wrap\"><div class=\"title\">Receita por mês <span class=\"unit\">(R$ mil)</span></div><div class=\"bars\">'+bars+'</div></div>';\n  }\n}"}}}}}}}},{"_id":"6a2d366bed4fc677c3604fc1","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kDonut","package":"ai-playground","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 SEG=[['Direto',40,'#6366F1'],['Orgânico',28,'#22C55E'],['Social',18,'#F59E0B'],['Email',14,'#EC4899']];\nexport default {\n  css: `\n    .wrap{height:100%;box-sizing:border-box;background:#fff;border:1px solid #EAECF0;border-radius:14px;padding:18px 20px;display:flex;flex-direction:column;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;box-shadow:0 1px 2px rgba(16,24,40,.05)}\n    .title{font-size:13px;font-weight:600;color:#101828;margin-bottom:8px}\n    .row{flex:1;display:flex;align-items:center;gap:18px}\n    .ring{width:128px;height:128px;flex:0 0 auto}\n    .arc{transition:stroke-width .15s;cursor:pointer}\n    .arc:hover{stroke-width:17}\n    .big{font-size:22px;font-weight:700;fill:#101828;text-anchor:middle;font-family:inherit}\n    .sm{font-size:9px;fill:#98A2B3;text-anchor:middle;text-transform:uppercase;letter-spacing:.08em;font-family:inherit}\n    .legend{flex:1;display:flex;flex-direction:column;gap:9px}\n    .li{display:flex;align-items:center;gap:8px;font-size:12.5px;color:#475467}\n    .li b{margin-left:auto;color:#101828;font-variant-numeric:tabular-nums}\n    .sw{width:10px;height:10px;border-radius:3px;flex:0 0 auto}\n  `,\n  render(d2){\n    var total=SEG.reduce(function(s,x){return s+x[1];},0);\n    var R=42,C=2*Math.PI*R,off=0;\n    var arcs=SEG.map(function(s){\n      var len=(s[1]/total)*C;\n      var el='<circle class=\"arc\" cx=\"60\" cy=\"60\" r=\"'+R+'\" fill=\"none\" stroke=\"'+s[2]+'\" stroke-width=\"14\" stroke-linecap=\"round\" stroke-dasharray=\"'+(len-2).toFixed(2)+' '+(C-len+2).toFixed(2)+'\" stroke-dashoffset=\"'+(-off).toFixed(2)+'\" transform=\"rotate(-90 60 60)\"/>';\n      off+=len; return el;\n    }).join('');\n    var legend=SEG.map(function(s){return '<div class=\"li\"><span class=\"sw\" style=\"background:'+s[2]+'\"></span>'+s[0]+'<b>'+Math.round(s[1]/total*100)+'%</b></div>';}).join('');\n    return '<div class=\"wrap\"><div class=\"title\">Aquisição de tráfego</div><div class=\"row\"><svg class=\"ring\" viewBox=\"0 0 120 120\">'+arcs+'<text class=\"big\" x=\"60\" y=\"58\">'+total+'</text><text class=\"sm\" x=\"60\" y=\"72\">visitas</text></svg><div class=\"legend\">'+legend+'</div></div></div>';\n  }\n}"}}}}}}}},{"_id":"6a2d36721b1e52cefa11a272","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kCounter","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n    .wrap{height:100%;box-sizing:border-box;background:#fff;border:1px solid #EAECF0;border-radius:14px;padding:20px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;box-shadow:0 1px 2px rgba(16,24,40,.05)}\n    .label{font-size:11px;font-weight:600;letter-spacing:.07em;text-transform:uppercase;color:#98A2B3}\n    .num{font-size:42px;font-weight:700;color:#101828;letter-spacing:-.02em;font-variant-numeric:tabular-nums;line-height:1}\n    .btn{margin-top:10px;font-size:12px;font-weight:600;color:#6366F1;background:#EEF2FF;border:none;padding:8px 14px;border-radius:8px;cursor:pointer;transition:background .15s}\n    .btn:hover{background:#E0E7FF}\n  `,\n  render(d2){\n    var target=(d2.state.t==null)?12480:d2.state.t;\n    var s=d2.spring('count',target,{stiffness:130,damping:20});\n    var val=Math.round(s.value);\n    return '<div class=\"wrap\"><div class=\"label\">Usuários ativos</div><div class=\"num\">'+val.toLocaleString('pt-BR')+'</div><button class=\"btn\" data-go>Animar novamente</button></div>';\n  },\n  mounted(d2){\n    d2.on('[data-go]','click',function(){\n      d2.spring('count').jump(0);\n      var opts=[12480,8650,15230,9870];\n      var n=(d2.state.n||0)+1; d2.state.n=n;\n      d2.state.t=opts[n%opts.length];\n    });\n  }\n}"}}}}}}}},{"_id":"6a2d36797938117e38f2b8e0","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kLike","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n    .wrap{height:100%;box-sizing:border-box;background:#fff;border:1px solid #EAECF0;border-radius:14px;padding:20px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;box-shadow:0 1px 2px rgba(16,24,40,.05)}\n    .heart{font-size:52px;line-height:1;color:#D0D5DD;background:none;border:none;cursor:pointer;padding:0;will-change:transform;transition:color .2s}\n    .heart.on{color:#F0436A}\n    .cnt{font-size:14px;font-weight:600;color:#101828;font-variant-numeric:tabular-nums}\n    .hint{font-size:11px;color:#98A2B3}\n  `,\n  render(d2){\n    var liked=!!d2.state.liked;\n    var s=d2.spring('pop',liked?1:0.001,{stiffness:520,damping:9});\n    var sc=(0.7+s.value*0.55).toFixed(3);\n    var count=(d2.state.count==null)?2483:d2.state.count;\n    return '<div class=\"wrap\"><button class=\"heart '+(liked?'on':'')+'\" data-like style=\"transform:scale('+sc+')\">&#10084;</button><div class=\"cnt\">'+count.toLocaleString('pt-BR')+' curtidas</div><div class=\"hint\">d2.spring com overshoot — clique</div></div>';\n  },\n  mounted(d2){\n    d2.on('[data-like]','click',function(){\n      var liked=!d2.state.liked; d2.state.liked=liked;\n      var base=(d2.state.count==null)?2483:d2.state.count;\n      d2.state.count=base+(liked?1:-1);\n      d2.spring('pop').jump(liked?0.001:1);\n    });\n  }\n}"}}}}}}}},{"_id":"6a2d368a1b7164341d2e92f1","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kSlider","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n    .wrap{height:100%;box-sizing:border-box;background:#fff;border:1px solid #EAECF0;border-radius:14px;padding:22px 24px;display:flex;flex-direction:column;justify-content:center;gap:16px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;box-shadow:0 1px 2px rgba(16,24,40,.05)}\n    .head{display:flex;justify-content:space-between;align-items:baseline;font-size:13px;color:#475467;font-weight:500}\n    .head b{font-size:18px;color:#101828;font-variant-numeric:tabular-nums}\n    .track{position:relative;height:8px;border-radius:999px;background:#EAECF0;cursor:pointer;touch-action:none}\n    .fill{position:absolute;left:0;top:0;bottom:0;border-radius:999px;background:linear-gradient(90deg,#818CF8,#6366F1)}\n    .thumb{position:absolute;top:50%;width:20px;height:20px;border-radius:50%;background:#fff;border:2px solid #6366F1;box-shadow:0 1px 4px rgba(16,24,40,.2);transform:translate(-50%,-50%);transition:transform .1s}\n    .thumb:active{transform:translate(-50%,-50%) scale(1.15)}\n    .hint{font-size:11px;color:#98A2B3}\n  `,\n  render(d2){\n    var v=(d2.state.v==null)?60:d2.state.v;\n    return '<div class=\"wrap\"><div class=\"head\"><span>Volume</span><b>'+v+'%</b></div><div class=\"track\" data-track><div class=\"fill\" style=\"width:'+v+'%\"></div><div class=\"thumb\" data-thumb style=\"left:'+v+'%\"></div></div><div class=\"hint\">arraste — escreve em d2.state</div></div>';\n  },\n  mounted(d2){\n    var dragging=false;\n    function setFrom(x){ var t=d2.$('[data-track]'); if(!t)return; var r=t.getBoundingClientRect(); var p=(x-r.left)/r.width; p=Math.max(0,Math.min(1,p)); d2.state.v=Math.round(p*100); }\n    d2.on('[data-track]','pointerdown',function(e){ dragging=true; setFrom(e.clientX); });\n    d2.on(window,'pointermove',function(e){ if(dragging) setFrom(e.clientX); });\n    d2.on(window,'pointerup',function(){ dragging=false; });\n  }\n}"}}}}}}}},{"_id":"6a2d368d61efae759d5c9b7e","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kRating","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n    .wrap{height:100%;box-sizing:border-box;background:#fff;border:1px solid #EAECF0;border-radius:14px;padding:20px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;box-shadow:0 1px 2px rgba(16,24,40,.05)}\n    .title{font-size:13px;font-weight:600;color:#101828}\n    .stars{display:flex;gap:6px}\n    .star{font-size:30px;color:#E4E7EC;cursor:pointer;transition:color .12s,transform .12s}\n    .star.on{color:#FDB022}\n    .star:hover{transform:scale(1.15)}\n    .lbl{font-size:12px;color:#667085;height:16px;font-weight:500}\n  `,\n  render(d2){\n    var val=d2.state.val||0, hov=d2.state.hov||0, show=hov||val;\n    var L=['passe o mouse','Ruim','Regular','Bom','Muito bom','Excelente'];\n    var stars=[1,2,3,4,5].map(function(i){return '<span class=\"star '+(i<=show?'on':'')+'\" data-star=\"'+i+'\">&#9733;</span>';}).join('');\n    return '<div class=\"wrap\"><div class=\"title\">Avalie sua experiência</div><div class=\"stars\" data-stars>'+stars+'</div><div class=\"lbl\">'+L[show]+'</div></div>';\n  },\n  mounted(d2){\n    d2.on('[data-star]','mouseover',function(e,el){ d2.state.hov=+el.getAttribute('data-star'); });\n    d2.on('[data-stars]','mouseleave',function(){ d2.state.hov=0; });\n    d2.on('[data-star]','click',function(e,el){ d2.state.val=+el.getAttribute('data-star'); });\n  }\n}"}}}}}}}},{"_id":"6a2d369abaacaeb32628d03e","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kLiveSearch","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>\"]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c];});}\nexport default {\n  css: `\n    .wrap{height:100%;box-sizing:border-box;background:#fff;border:1px solid #EAECF0;border-radius:14px;display:flex;flex-direction:column;overflow:hidden;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;box-shadow:0 1px 2px rgba(16,24,40,.05)}\n    .top{padding:14px 16px;border-bottom:1px solid #F2F4F7;display:flex;flex-direction:column;gap:8px}\n    .srow{position:relative}\n    .srow input{width:100%;box-sizing:border-box;padding:8px 12px 8px 32px;border:1px solid #E4E7EC;border-radius:9px;font:inherit;font-size:13px;outline:none;transition:border .15s,box-shadow .15s}\n    .srow input:focus{border-color:#6366F1;box-shadow:0 0 0 3px rgba(99,102,241,.12)}\n    .srow .ic{position:absolute;left:11px;top:50%;transform:translateY(-50%);color:#98A2B3;font-size:13px}\n    .meta{font-size:11px;color:#98A2B3}\n    .list{flex:1;overflow:auto}\n    .r{display:flex;align-items:center;gap:10px;padding:9px 16px;border-bottom:1px solid #F9FAFB}\n    .r:last-child{border-bottom:none}\n    .p{font-size:13px;font-weight:500;color:#101828}\n    .s{font-size:12px;color:#667085;margin-left:auto}\n    .empty{padding:24px;text-align:center;color:#98A2B3;font-size:13px}\n  `,\n  render(d2){\n    var ds=d2.data();\n    if(!ds) return '<div class=\"wrap\"><div class=\"empty\">Sem dataset</div></div>';\n    var q=(d2.state.q||'').toLowerCase();\n    var recs=ds.records();\n    var keys=recs.length?Object.keys(recs[0]).filter(function(k){return k!=='_id'&&k.indexOf('d2_')!==0;}):[];\n    var k1=keys[0],k2=keys[1];\n    var filtered=recs.filter(function(r){return !q||JSON.stringify(r).toLowerCase().indexOf(q)>=0;});\n    var rows=filtered.length?filtered.slice(0,40).map(function(r){return '<div class=\"r\"><span class=\"p\">'+esc(r[k1])+'</span>'+(k2?'<span class=\"s\">'+esc(r[k2])+'</span>':'')+'</div>';}).join(''):'<div class=\"empty\">Nada encontrado</div>';\n    return '<div class=\"wrap\"><div class=\"top\"><div class=\"srow\"><span class=\"ic\">&#128269;</span><input data-q placeholder=\"Buscar…\" value=\"'+esc(d2.state.q||'')+'\"/></div><div class=\"meta\">'+filtered.length+' de '+recs.length+' registros</div></div><div class=\"list\">'+rows+'</div></div>';\n  },\n  mounted(d2){\n    d2.on('[data-q]','input',function(e,el){ d2.state.q=el.value; });\n  }\n}"}},"dataset":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"dataset"}}}}}}}}}},{"_id":"6a2d36a2911a2eb6b8164fac","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kAskAI","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>\"]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c];});}\nexport default {\n  css: `\n    .wrap{height:100%;box-sizing:border-box;background:#fff;border:1px solid #EAECF0;border-radius:14px;padding:16px;display:flex;flex-direction:column;gap:10px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;box-shadow:0 1px 2px rgba(16,24,40,.05)}\n    .title{font-size:13px;font-weight:600;color:#101828}\n    .ans{flex:1;min-height:0;overflow:auto;background:#F9FAFB;border:1px solid #F2F4F7;border-radius:10px;padding:12px;font-size:13px;line-height:1.5;color:#344054;white-space:pre-wrap}\n    .ans.ph{color:#98A2B3}\n    .inrow{display:flex;gap:8px}\n    .inrow input{flex:1;min-width:0;padding:9px 12px;border:1px solid #E4E7EC;border-radius:9px;font:inherit;font-size:13px;outline:none}\n    .inrow input:focus{border-color:#6366F1;box-shadow:0 0 0 3px rgba(99,102,241,.12)}\n    .inrow button{padding:9px 16px;border:none;border-radius:9px;background:#6366F1;color:#fff;font:inherit;font-size:13px;font-weight:600;cursor:pointer;transition:filter .15s}\n    .inrow button:hover{filter:brightness(1.06)}\n    .inrow button:disabled{opacity:.6;cursor:default}\n  `,\n  render(d2){\n    var ref=d2.param('assistant','l1-plain');\n    var a=d2.assistant(ref);\n    var ans=a.answer||'', busy=a.busy;\n    var body=ans?esc(ans):(busy?'Pensando…':'A resposta da IA aparece aqui.');\n    return '<div class=\"wrap\"><div class=\"title\">Pergunte à IA</div><div class=\"ans'+(ans?'':' ph')+'\">'+body+'</div><div class=\"inrow\"><input data-q placeholder=\"Ex: o que é uma API REST?\" value=\"'+esc(d2.state.q||'')+'\"/><button data-send '+(busy?'disabled':'')+'>'+(busy?'…':'Enviar')+'</button></div></div>';\n  },\n  mounted(d2){\n    function ask(){ var q=(d2.state.q||'').trim(); if(q) d2.assistant(d2.param('assistant','l1-plain')).ask(q); }\n    d2.on('[data-q]','input',function(e,el){ d2.state.q=el.value; });\n    d2.on('[data-q]','keydown',function(e){ if(e.key==='Enter') ask(); });\n    d2.on('[data-send]','click',ask);\n  }\n}"}},"assistant":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"assistant"}}}}}}}}}},{"_id":"6a2d36ca58bb101c90940a63","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kLab","package":"ai-playground","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 EX=[\n  {n:'K1',t:'Bar Chart',d:'SVG · barras animadas',r:'kBarChart'},\n  {n:'K2',t:'Donut Chart',d:'SVG · arcos + legenda',r:'kDonut'},\n  {n:'K3',t:'Animated Counter',d:'d2.spring · roll-up',r:'kCounter'},\n  {n:'K4',t:'Like',d:'d2.spring · overshoot',r:'kLike'},\n  {n:'K5',t:'Range Slider',d:'d2.state · pointer drag',r:'kSlider'},\n  {n:'K6',t:'Star Rating',d:'d2.state · hover preview',r:'kRating'},\n  {n:'K7',t:'Live Search',d:'d2.data · filtro por tecla',r:'kLiveSearch'},\n  {n:'K8',t:'Ask AI',d:'d2.assistant · streaming',r:'kAskAI'}\n];\nexport default {\n  css: `\n    .lab{height:100%;box-sizing:border-box;overflow:auto;background:#F7F8FA;padding:26px 30px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;color:#101828}\n    .hd{margin-bottom:20px}\n    .hd h1{margin:0;font-size:21px;font-weight:600;letter-spacing:-.02em}\n    .hd p{margin:5px 0 0;font-size:13px;color:#667085}\n    .grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:18px}\n    .cell{display:flex;flex-direction:column;gap:10px}\n    .cap{display:flex;align-items:center;gap:8px}\n    .cap .b{font-size:11px;font-weight:700;color:#6366F1;background:#EEF2FF;padding:2px 8px;border-radius:6px}\n    .cap .t{font-size:14px;font-weight:600;color:#101828}\n    .cap .d{font-size:12px;color:#98A2B3;margin-left:auto;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}\n    .host{height:300px}\n  `,\n  render(d2){\n    var contacts=d2.params.contacts;\n    var tiles=EX.map(function(e){\n      var params={};\n      if(e.r==='kLiveSearch') params={dataset:contacts};\n      if(e.r==='kAskAI') params={assistant:'l1-plain'};\n      var child=d2.render('ai-playground@'+e.r, params, {key:e.r});\n      return '<div class=\"cell\"><div class=\"cap\"><span class=\"b\">'+e.n+'</span><span class=\"t\">'+e.t+'</span><span class=\"d\">'+e.d+'</span></div><div class=\"host\">'+child+'</div></div>';\n    }).join('');\n    return '<div class=\"lab\"><div class=\"hd\"><h1>Code Components · Laboratório</h1><p>Galeria de estudo — cada cartão é um code component independente exercitando o harness d2.*</p></div><div class=\"grid\">'+tiles+'</div></div>';\n  }\n}"}},"contacts":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"contacts"}}}}}}}}}},{"_id":"6a2d37e69b58f90d1c2295bc","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kLineChart","package":"ai-playground","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 DATA=[12,19,15,27,22,34,29,41,38,33,45,52];\nconst MON=['Jan','Fev','Mar','Abr','Mai','Jun','Jul','Ago','Set','Out','Nov','Dez'];\nexport default {\n  css: `\n    .wrap{height:100%;box-sizing:border-box;background:#fff;border:1px solid #EAECF0;border-radius:14px;padding:18px 20px;display:flex;flex-direction:column;gap:8px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;box-shadow:0 1px 2px rgba(16,24,40,.05)}\n    .title{font-size:13px;font-weight:600;color:#101828}\n    .cv{position:relative;flex:1;min-height:0}\n    .svg{width:100%;height:100%;display:block;cursor:crosshair}\n    .tip{position:absolute;top:0;transform:translateX(-50%);background:#101828;color:#fff;font-size:11px;padding:3px 8px;border-radius:6px;white-space:nowrap;pointer-events:none}\n    .tip b{font-variant-numeric:tabular-nums}\n  `,\n  render(d2){\n    var W=320,H=150,pad=10;\n    var max=Math.max.apply(null,DATA),min=Math.min.apply(null,DATA),rng=(max-min)||1;\n    var x=function(i){return pad+(i/(DATA.length-1))*(W-2*pad);};\n    var y=function(v){return H-pad-((v-min)/rng)*(H-2*pad);};\n    var line='';DATA.forEach(function(v,i){line+=(i?'L':'M')+x(i).toFixed(1)+' '+y(v).toFixed(1)+' ';});\n    var area=line+'L'+x(DATA.length-1).toFixed(1)+' '+H+' L'+x(0).toFixed(1)+' '+H+' Z';\n    var ai=d2.state.ai;\n    var cross='';\n    if(ai!=null){cross='<line x1=\"'+x(ai).toFixed(1)+'\" y1=\"'+pad+'\" x2=\"'+x(ai).toFixed(1)+'\" y2=\"'+(H-pad)+'\" stroke=\"#E4E7EC\" stroke-width=\"1\"/><circle cx=\"'+x(ai).toFixed(1)+'\" cy=\"'+y(DATA[ai]).toFixed(1)+'\" r=\"4.5\" fill=\"#6366F1\" stroke=\"#fff\" stroke-width=\"2\"/>';}\n    var tip=ai!=null?'<div class=\"tip\" style=\"left:'+(x(ai)/W*100).toFixed(1)+'%\">'+MON[ai]+': <b>'+DATA[ai]+'</b></div>':'';\n    return '<div class=\"wrap\"><div class=\"title\">Crescimento mensal</div><div class=\"cv\">'+tip+'<svg class=\"svg\" data-svg viewBox=\"0 0 '+W+' '+H+'\" preserveAspectRatio=\"none\"><defs><linearGradient id=\"lg\" x1=\"0\" x2=\"0\" y1=\"0\" y2=\"1\"><stop offset=\"0\" stop-color=\"#6366F1\" stop-opacity=\".2\"/><stop offset=\"1\" stop-color=\"#6366F1\" stop-opacity=\"0\"/></linearGradient></defs><path d=\"'+area+'\" fill=\"url(#lg)\"/><path d=\"'+line+'\" fill=\"none\" stroke=\"#6366F1\" stroke-width=\"2\" stroke-linejoin=\"round\"/>'+cross+'</svg></div></div>';\n  },\n  mounted(d2){\n    d2.on('[data-svg]','mousemove',function(e){var svg=d2.$('[data-svg]');if(!svg)return;var r=svg.getBoundingClientRect();var p=(e.clientX-r.left)/r.width;var i=Math.round(p*(DATA.length-1));d2.state.ai=Math.max(0,Math.min(DATA.length-1,i));});\n    d2.on('[data-svg]','mouseleave',function(){d2.state.ai=null;});\n  }\n}"}}}}}}}},{"_id":"6a2d37e6dbf815e74e98a41e","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kHeatmap","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n    .wrap{height:100%;box-sizing:border-box;background:#fff;border:1px solid #EAECF0;border-radius:14px;padding:18px 20px;display:flex;flex-direction:column;gap:12px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;box-shadow:0 1px 2px rgba(16,24,40,.05)}\n    .title{font-size:13px;font-weight:600;color:#101828}\n    .grid{flex:1;display:grid;gap:3px;grid-auto-flow:column;grid-template-rows:repeat(7,1fr);min-height:0}\n    .cell{border-radius:2px;transition:transform .1s}\n    .cell:hover{transform:scale(1.3);outline:1.5px solid #6366F1;position:relative;z-index:1}\n    .foot{display:flex;align-items:center;gap:6px;font-size:11px;color:#98A2B3;justify-content:flex-end}\n    .lg{width:11px;height:11px;border-radius:2px}\n  `,\n  render(d2){\n    var cols=20,rows=7,colors=['#EBEDF0','#C6E5D0','#82C99A','#42A35F','#1E7A3C'];\n    var cells='';\n    for(var c=0;c<cols;c++){for(var r=0;r<rows;r++){var seed=(r*7+c*13+c*c)%17;var v=seed%5;cells+='<div class=\"cell\" style=\"background:'+colors[v]+'\" title=\"'+v+' contribuições\"></div>';}}\n    var legend=colors.map(function(c){return '<span class=\"lg\" style=\"background:'+c+'\"></span>';}).join('');\n    return '<div class=\"wrap\"><div class=\"title\">Contribuições · 20 semanas</div><div class=\"grid\">'+cells+'</div><div class=\"foot\">menos '+legend+' mais</div></div>';\n  }\n}"}}}}}}}},{"_id":"6a2d37eb1b1e52cefa11a3b4","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kGauge","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n    .wrap{height:100%;box-sizing:border-box;background:#fff;border:1px solid #EAECF0;border-radius:14px;padding:18px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;box-shadow:0 1px 2px rgba(16,24,40,.05)}\n    .title{font-size:13px;font-weight:600;color:#101828}\n    .gw{position:relative;width:160px;height:96px}\n    .gw svg{width:100%;height:100%}\n    .pv{position:absolute;left:0;right:0;bottom:2px;text-align:center;font-size:30px;font-weight:700;color:#101828;font-variant-numeric:tabular-nums}\n    .btn{font-size:12px;font-weight:600;color:#6366F1;background:#EEF2FF;border:none;padding:8px 14px;border-radius:8px;cursor:pointer}\n    .btn:hover{background:#E0E7FF}\n  `,\n  render(d2){\n    var target=d2.state.t==null?72:d2.state.t;\n    var s=d2.spring('g',target,{stiffness:110,damping:20});\n    var pct=Math.max(0,Math.min(100,s.value));\n    var R=66,C=Math.PI*R,dash=(pct/100)*C;\n    var color=pct<40?'#F04438':pct<70?'#F79009':'#12B76A';\n    return '<div class=\"wrap\"><div class=\"title\">Meta atingida</div><div class=\"gw\"><svg viewBox=\"0 0 160 96\"><path d=\"M14 86 A66 66 0 0 1 146 86\" fill=\"none\" stroke=\"#EAECF0\" stroke-width=\"12\" stroke-linecap=\"round\"/><path d=\"M14 86 A66 66 0 0 1 146 86\" fill=\"none\" stroke=\"'+color+'\" stroke-width=\"12\" stroke-linecap=\"round\" stroke-dasharray=\"'+dash.toFixed(1)+' '+(C-dash).toFixed(1)+'\"/></svg><div class=\"pv\">'+Math.round(pct)+'%</div></div><button class=\"btn\" data-go>Sortear meta</button></div>';\n  },\n  mounted(d2){\n    d2.on('[data-go]','click',function(){var opts=[72,38,91,55,84,28];var n=(d2.state.n||0)+1;d2.state.n=n;d2.state.t=opts[n%opts.length];});\n  }\n}"}}}}}}}},{"_id":"6a2d37f458bb101c90940b31","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kSparkGrid","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function hh(s){var h=2166136261;for(var i=0;i<s.length;i++){h^=s.charCodeAt(i);h=Math.imul(h,16777619);}return h>>>0;}\nfunction ser(seed){var p=[],v=.5,s=seed||1;for(var i=0;i<14;i++){s=(Math.imul(s,1103515245)+12345)>>>0;v=Math.max(.1,Math.min(.9,v+((s/4294967295)-.5)*.45));p.push(v);}return p;}\nfunction spk(pts,col){var n=pts.length,W=92,H=26;var x=function(i){return (i/(n-1))*W;};var y=function(v){return H-2-v*(H-4);};var d='';pts.forEach(function(v,i){d+=(i?'L':'M')+x(i).toFixed(1)+' '+y(v).toFixed(1)+' ';});return '<svg class=\"spk\" viewBox=\"0 0 '+W+' '+H+'\" preserveAspectRatio=\"none\"><path d=\"'+d+'\" fill=\"none\" stroke=\"'+col+'\" stroke-width=\"1.5\" stroke-linejoin=\"round\"/></svg>';}\nconst ITEMS=[['Receita','#6366F1','R$ 84k'],['Sessões','#22C55E','12,4k'],['Pedidos','#F59E0B','328'],['Ticket','#EC4899','R$ 256'],['Churn','#F04438','2,1%'],['NPS','#06B6D4','71']];\nexport default {\n  css: `\n    .wrap{height:100%;box-sizing:border-box;background:#fff;border:1px solid #EAECF0;border-radius:14px;padding:18px 20px;display:flex;flex-direction:column;gap:12px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;box-shadow:0 1px 2px rgba(16,24,40,.05)}\n    .title{font-size:13px;font-weight:600;color:#101828}\n    .mg{flex:1;display:grid;grid-template-columns:1fr 1fr;gap:10px;min-height:0}\n    .mc{border:1px solid #F2F4F7;border-radius:10px;padding:10px 12px;display:flex;flex-direction:column;gap:2px}\n    .ml{font-size:11px;color:#98A2B3;font-weight:500}\n    .mv{font-size:16px;font-weight:700;color:#101828;font-variant-numeric:tabular-nums}\n    .spk{width:100%;height:26px;margin-top:4px}\n  `,\n  render(d2){\n    var cards=ITEMS.map(function(it){return '<div class=\"mc\"><div class=\"ml\">'+it[0]+'</div><div class=\"mv\">'+it[2]+'</div>'+spk(ser(hh(it[0])),it[1])+'</div>';}).join('');\n    return '<div class=\"wrap\"><div class=\"title\">Indicadores</div><div class=\"mg\">'+cards+'</div></div>';\n  }\n}"}}}}}}}},{"_id":"6a2d37fcbaacaeb32628d180","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kRadar","package":"ai-playground","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 AX=[['Velocidade',80],['Força',65],['Defesa',92],['Magia',55],['Sorte',70],['Stamina',78]];\nexport default {\n  css: `\n    .wrap{height:100%;box-sizing:border-box;background:#fff;border:1px solid #EAECF0;border-radius:14px;padding:18px 20px;display:flex;flex-direction:column;gap:8px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;box-shadow:0 1px 2px rgba(16,24,40,.05)}\n    .title{font-size:13px;font-weight:600;color:#101828}\n    .rc{flex:1;display:flex;align-items:center;justify-content:center;min-height:0}\n    .rc svg{height:100%;max-height:180px}\n    .ax{font-size:8px;fill:#667085;text-anchor:middle;font-family:inherit}\n  `,\n  render(d2){\n    var n=AX.length,cx=85,cy=88,R=58;\n    function pt(i,r){var a=(Math.PI*2*i/n)-Math.PI/2;return [(cx+Math.cos(a)*r).toFixed(1),(cy+Math.sin(a)*r).toFixed(1)];}\n    var rings='';[0.25,0.5,0.75,1].forEach(function(f){var p=AX.map(function(_,i){return pt(i,R*f).join(',');}).join(' ');rings+='<polygon points=\"'+p+'\" fill=\"none\" stroke=\"#EAECF0\" stroke-width=\"1\"/>';});\n    var axes='';AX.forEach(function(_,i){var e=pt(i,R);axes+='<line x1=\"'+cx+'\" y1=\"'+cy+'\" x2=\"'+e[0]+'\" y2=\"'+e[1]+'\" stroke=\"#EAECF0\" stroke-width=\"1\"/>';});\n    var poly=AX.map(function(a,i){return pt(i,R*(a[1]/100)).join(',');}).join(' ');\n    var labels=AX.map(function(a,i){var e=pt(i,R+13);return '<text class=\"ax\" x=\"'+e[0]+'\" y=\"'+e[1]+'\">'+a[0]+'</text>';}).join('');\n    return '<div class=\"wrap\"><div class=\"title\">Atributos do personagem</div><div class=\"rc\"><svg viewBox=\"0 0 170 176\">'+rings+axes+'<polygon points=\"'+poly+'\" fill=\"rgba(99,102,241,.2)\" stroke=\"#6366F1\" stroke-width=\"2\"/>'+labels+'</svg></div></div>';\n  }\n}"}}}}}}}},{"_id":"6a2d383861efae759d5c9cde","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kBubble","package":"ai-playground","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 BUB=[['SP',62,48,40],['RJ',45,72,30],['MG',38,35,26],['RS',72,28,22],['PR',28,62,18],['BA',82,68,16],['SC',52,88,14]];\nexport default {\n  css: `\n    .wrap{height:100%;box-sizing:border-box;background:#fff;border:1px solid #EAECF0;border-radius:14px;padding:18px 20px;display:flex;flex-direction:column;gap:8px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;box-shadow:0 1px 2px rgba(16,24,40,.05)}\n    .title{font-size:13px;font-weight:600;color:#101828}\n    .cv{flex:1;min-height:0;display:flex;align-items:center;justify-content:center}\n    .svg{width:100%;height:100%}\n    .lab{font-size:12px;color:#475467;font-weight:500;height:16px}\n    .lab.dim{color:#98A2B3;font-weight:400}\n  `,\n  render(d2){\n    var sel=d2.state.sel;\n    var circles=BUB.map(function(b,i){var cx=20+b[1]/100*160,cy=115-b[2]/100*100,r=b[3]/10+3,on=sel===i;return '<g style=\"cursor:pointer\"><circle data-b=\"'+i+'\" cx=\"'+cx+'\" cy=\"'+cy+'\" r=\"'+r.toFixed(1)+'\" fill=\"rgba(99,102,241,'+(on?'.85':'.4')+')\" stroke=\"#6366F1\" stroke-width=\"'+(on?2:1)+'\" style=\"transition:.15s\"/><text x=\"'+cx+'\" y=\"'+(cy+3)+'\" font-size=\"7\" fill=\"#3538CD\" text-anchor=\"middle\" style=\"pointer-events:none;font-family:sans-serif\">'+b[0]+'</text></g>';}).join('');\n    var lab=sel!=null?'<div class=\"lab\">'+BUB[sel][0]+' — '+BUB[sel][3]+'k clientes</div>':'<div class=\"lab dim\">clique numa bolha</div>';\n    return '<div class=\"wrap\"><div class=\"title\">Clientes por região</div><div class=\"cv\"><svg class=\"svg\" viewBox=\"0 0 200 130\">'+circles+'</svg></div>'+lab+'</div>';\n  },\n  mounted(d2){\n    d2.on('[data-b]','click',function(e,el){d2.state.sel=+el.getAttribute('data-b');});\n  }\n}"}}}}}}}},{"_id":"6a2d38425284d6e4f909aaaf","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kParticles","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n    .wrap{position:relative;width:100%;height:100%;overflow:hidden;border-radius:inherit}\n    .cv{display:block;width:100%;height:100%;touch-action:none;cursor:crosshair}\n    .hud{position:absolute;left:14px;top:12px;font:11px/1.5 ui-monospace,SFMono-Regular,monospace;color:rgba(255,255,255,.5);pointer-events:none;letter-spacing:.04em}\n    .hud b{color:rgba(255,255,255,.85)}\n    .tip{position:absolute;left:14px;bottom:12px;font:11px ui-monospace,monospace;color:rgba(255,255,255,.4);pointer-events:none;text-transform:uppercase;letter-spacing:.08em}\n  `,\n  render(d2){\n    const bg = d2.param('bg', '#06060e');\n    return `<div class=\"wrap\" style=\"background:${bg}\">\n      <canvas class=\"cv\" data-d2-static></canvas>\n      <div class=\"hud\"></div>\n      <div class=\"tip\">drag to move emitter · click to burst</div>\n    </div>`;\n  },\n  mounted(d2, root){\n    const cv = d2.$('.cv'); const ctx = cv.getContext('2d');\n    const hud = d2.$('.hud');\n    const clamp = (v,a,b) => Math.max(a, Math.min(b, v));\n    const TAU = Math.PI * 2;\n\n    function colorStr(v, fb){\n      if (v == null) return fb;\n      if (typeof v === 'string') return v;\n      if (v.params && v.params.rgba) return v.params.rgba;\n      if (v.rgba) return v.rgba;\n      return fb;\n    }\n    function parseColor(s, fb){\n      s = (s == null ? '' : String(s)).trim();\n      if (!s) s = fb;\n      if (s[0] === '#'){\n        let h = s.slice(1);\n        if (h.length === 3) h = h.split('').map(c => c + c).join('');\n        const n = parseInt(h, 16);\n        if (isFinite(n)) return [(n>>16)&255, (n>>8)&255, n&255, 1];\n        return parseColor(fb, '#ffffff');\n      }\n      const m = s.match(/rgba?\\(([^)]+)\\)/i);\n      if (m){ const p = m[1].split(',').map(x => parseFloat(x)); return [p[0]||0, p[1]||0, p[2]||0, (p[3]==null?1:p[3])]; }\n      return parseColor(fb, '#ffffff');\n    }\n\n    let W=0, H=0, dpr=1;\n    let particles = [];\n    let emitAcc = 0, lastT = 0;\n    const emitter = { x:0, y:0, inside:false };\n\n    function size(){\n      dpr = window.devicePixelRatio || 1;\n      W = cv.clientWidth; H = cv.clientHeight;\n      cv.width = Math.max(1, Math.round(W*dpr));\n      cv.height = Math.max(1, Math.round(H*dpr));\n      ctx.setTransform(1,0,0,1,0,0); ctx.scale(dpr,dpr);\n      emitter.x = W/2; emitter.y = H*0.82;\n    }\n\n    function emitOne(ex, ey, sc, ec, burst){\n      const shape = d2.param('shape', 'cone');\n      const dir = Number(d2.param('direction', 0)) || 0;\n      const spread = Number(d2.param('spread', 30)) || 0;\n      const spd0 = Number(d2.param('startSpeed', 200)) || 0;\n      const sJit = clamp(Number(d2.param('speedJitter', 0.5)) || 0, 0, 1);\n      const rad = Number(d2.param('spawnRadius', 50)) || 0;\n      const s0 = Number(d2.param('startSize', 8)) || 1;\n      const s1 = Number(d2.param('endSize', 0.5)) || 0;\n      const szJit = clamp(Number(d2.param('sizeJitter', 0.4)) || 0, 0, 1);\n      const life0 = Number(d2.param('lifetime', 1.7)) || 1;\n      const lJit = clamp(Number(d2.param('lifetimeJitter', 0.4)) || 0, 0, 1);\n\n      let speed = spd0 * (1 - sJit*Math.random());\n      let px = ex, py = ey, vx, vy;\n      const base = dir * Math.PI/180;\n      const theta = base + (Math.random()-0.5) * spread * Math.PI/180;\n\n      if (shape === 'edge'){\n        px = Math.random()*W; py = -10; vx = (Math.random()-0.5)*40; vy = Math.abs(speed);\n      } else if (shape === 'circle' || shape === 'sphere'){\n        const a = Math.random()*TAU;\n        const rr = shape === 'sphere' ? Math.sqrt(Math.random())*rad : rad;\n        px = ex + Math.cos(a)*rr; py = ey + Math.sin(a)*rr;\n        vx = Math.cos(a)*speed; vy = Math.sin(a)*speed;\n      } else if (shape === 'box'){\n        px = ex + (Math.random()-0.5)*rad*2; py = ey + (Math.random()-0.5)*rad*2;\n        vx = Math.sin(theta)*speed; vy = -Math.cos(theta)*speed;\n      } else {\n        vx = Math.sin(theta)*speed; vy = -Math.cos(theta)*speed;\n      }\n      if (burst){ const a = Math.random()*TAU; const bs = spd0*(0.6+0.9*Math.random()); vx = Math.cos(a)*bs; vy = Math.sin(a)*bs; }\n\n      particles.push({\n        x:px, y:py, vx, vy, age:0,\n        life: life0 * (1 - lJit*Math.random()),\n        size0: s0 * (1 - szJit*Math.random()*0.6),\n        size1: s1,\n        r:sc[0], g:sc[1], b:sc[2], er:ec[0], eg:ec[1], eb:ec[2]\n      });\n    }\n\n    function frame(t){\n      let dt = lastT ? (t - lastT)/1000 : 0;\n      lastT = t;\n      dt = clamp(dt, 0, 0.05);\n      const time = t/1000;\n\n      const rate = Math.max(0, Number(d2.param('emissionRate', 240)) || 0);\n      const maxP = Math.max(10, Number(d2.param('maxParticles', 1400)) || 0);\n      const gravity = Number(d2.param('gravity', 130)) || 0;\n      const turb = Number(d2.param('turbulence', 35)) || 0;\n      const follow = d2.param('followPointer', true);\n      const sc = parseColor(colorStr(d2.param('startColor'), '#ffd56a'), '#ffd56a');\n      const ec = parseColor(colorStr(d2.param('endColor'), '#ff2e6e'), '#ff2e6e');\n\n      const ex = (follow && emitter.inside) ? emitter.x : W/2;\n      const ey = (follow && emitter.inside) ? emitter.y : H*0.82;\n\n      emitAcc += rate * dt;\n      let guard = 0;\n      while (emitAcc >= 1 && particles.length < maxP && guard < 2000){\n        emitOne(ex, ey, sc, ec, false); emitAcc -= 1; guard++;\n      }\n      if (emitAcc > 1) emitAcc = 1;\n\n      for (let i = particles.length - 1; i >= 0; i--){\n        const p = particles[i];\n        p.age += dt;\n        if (p.age >= p.life){ particles.splice(i, 1); continue; }\n        p.vy += gravity * dt;\n        p.vx += Math.sin(p.y*0.012 + time*1.3) * turb * dt;\n        p.vy += Math.cos(p.x*0.012 + time*1.1) * turb * dt;\n        p.x += p.vx * dt; p.y += p.vy * dt;\n      }\n\n      const bgRaw = colorStr(d2.param('bg'), '#06060e');\n      const bg = parseColor(bgRaw, '#06060e');\n      const transparent = /transparent|none/i.test(bgRaw) || bg[3] === 0;\n      const trail = clamp(Number(d2.param('trail', 0.2)) || 0, 0, 0.96);\n      const fade = clamp(1 - trail, 0.04, 1);\n      ctx.globalAlpha = 1;\n      if (transparent){\n        // erase prior frame's alpha (trail-aware) so particles float over a transparent canvas\n        ctx.globalCompositeOperation = 'destination-out';\n        ctx.fillStyle = 'rgba(0,0,0,' + fade + ')';\n        ctx.fillRect(0, 0, W, H);\n      } else {\n        ctx.globalCompositeOperation = 'source-over';\n        ctx.fillStyle = 'rgba(' + bg[0] + ',' + bg[1] + ',' + bg[2] + ',' + fade + ')';\n        ctx.fillRect(0, 0, W, H);\n      }\n\n      ctx.globalCompositeOperation = d2.param('additive', true) ? 'lighter' : 'source-over';\n      for (const p of particles){\n        const lt = p.age / p.life;\n        const size = Math.max(0.4, p.size0 + (p.size1 - p.size0) * lt);\n        const a = (1 - lt) * (1 - lt);\n        const r = Math.round(p.r + (p.er - p.r) * lt);\n        const g = Math.round(p.g + (p.eg - p.g) * lt);\n        const b = Math.round(p.b + (p.eb - p.b) * lt);\n        const grd = ctx.createRadialGradient(p.x, p.y, 0, p.x, p.y, size);\n        grd.addColorStop(0, 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')');\n        grd.addColorStop(0.45, 'rgba(' + r + ',' + g + ',' + b + ',' + (a*0.5) + ')');\n        grd.addColorStop(1, 'rgba(' + r + ',' + g + ',' + b + ',0)');\n        ctx.fillStyle = grd;\n        ctx.beginPath(); ctx.arc(p.x, p.y, size, 0, TAU); ctx.fill();\n      }\n      ctx.globalCompositeOperation = 'source-over';\n\n      if (hud) hud.innerHTML = '<b>' + particles.length + '</b> particles &nbsp; ' +\n        Math.round(rate) + '/s &nbsp; ' + (d2.param('shape','cone'));\n    }\n\n    size();\n\n    if (typeof ResizeObserver !== 'undefined'){\n      const ro = new ResizeObserver(() => size());\n      ro.observe(root); d2.onUnmount(() => ro.disconnect());\n    }\n    d2.on(cv, 'pointermove', (e) => {\n      const rct = cv.getBoundingClientRect();\n      emitter.x = e.clientX - rct.left; emitter.y = e.clientY - rct.top; emitter.inside = true;\n    });\n    d2.on(cv, 'pointerleave', () => { emitter.inside = false; });\n    d2.on(cv, 'pointerdown', (e) => {\n      const rct = cv.getBoundingClientRect();\n      const bx = e.clientX - rct.left, by = e.clientY - rct.top;\n      const sc = parseColor(colorStr(d2.param('startColor'), '#ffd56a'), '#ffd56a');\n      const ec = parseColor(colorStr(d2.param('endColor'), '#ff2e6e'), '#ff2e6e');\n      const n = Math.max(10, Number(d2.param('burstCount', 140)) || 0);\n      const maxP = Math.max(10, Number(d2.param('maxParticles', 1400)) || 0);\n      for (let i = 0; i < n && particles.length < maxP; i++) emitOne(bx, by, sc, ec, true);\n    });\n\n    d2.raf(frame);\n  },\n}"}},"emissionRate":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"emissionRate"}}}},"maxParticles":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"maxParticles"}}}},"lifetime":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"lifetime"}}}},"lifetimeJitter":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"lifetimeJitter"}}}},"startSpeed":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"startSpeed"}}}},"speedJitter":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"speedJitter"}}}},"gravity":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"gravity"}}}},"direction":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"direction"}}}},"spread":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"spread"}}}},"startSize":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"startSize"}}}},"endSize":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"endSize"}}}},"sizeJitter":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"sizeJitter"}}}},"startColor":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"startColor"}}}},"endColor":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"endColor"}}}},"turbulence":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"turbulence"}}}},"shape":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"shape"}}}},"spawnRadius":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"spawnRadius"}}}},"additive":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"additive"}}}},"trail":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"trail"}}}},"followPointer":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"followPointer"}}}},"burstCount":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"burstCount"}}}},"bg":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"bg"}}}}}}}}}},{"_id":"6a2d384d911a2eb6b8165102","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kConfetti","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n    .wrap{height:100%;box-sizing:border-box;border:1px solid #EAECF0;border-radius:14px;overflow:hidden;position:relative;background:#fff;box-shadow:0 1px 2px rgba(16,24,40,.05)}\n    canvas{width:100%;height:100%;display:block}\n    .btn{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);font:600 14px -apple-system,sans-serif;color:#fff;background:#6366F1;border:none;padding:11px 20px;border-radius:10px;cursor:pointer;box-shadow:0 4px 14px rgba(99,102,241,.4)}\n    .btn:hover{filter:brightness(1.07)}\n  `,\n  render(d2){ return '<div class=\"wrap\"><canvas data-cv></canvas><button class=\"btn\" data-go>🎉 Comemorar</button></div>'; },\n  mounted(d2){\n    var cv=d2.$('[data-cv]'); if(!cv) return;\n    var ctx=cv.getContext('2d');\n    var DPR=Math.min(window.devicePixelRatio||1,2);\n    function size(){var r=cv.getBoundingClientRect();cv.width=Math.max(1,r.width*DPR);cv.height=Math.max(1,r.height*DPR);}\n    size();\n    var parts=[],COL=['#6366F1','#EC4899','#F59E0B','#22C55E','#06B6D4','#F04438'];\n    function burst(){size();var cx=cv.width/2,cy=cv.height/2;for(var i=0;i<120;i++){var a=Math.random()*6.2832,sp=(Math.random()*6+2)*DPR;parts.push({x:cx,y:cy,vx:Math.cos(a)*sp,vy:Math.sin(a)*sp-3*DPR,g:0.15*DPR,life:1,c:COL[i%COL.length],s:(Math.random()*4+2)*DPR,rot:Math.random()*6.28});}}\n    d2.on('[data-go]','click',burst);\n    d2.raf(function(){\n      ctx.clearRect(0,0,cv.width,cv.height);\n      for(var i=parts.length-1;i>=0;i--){var p=parts[i];p.vy+=p.g;p.x+=p.vx;p.y+=p.vy;p.life-=0.008;p.rot+=0.1;if(p.life<=0||p.y>cv.height+20){parts.splice(i,1);continue;}ctx.save();ctx.globalAlpha=Math.max(0,p.life);ctx.translate(p.x,p.y);ctx.rotate(p.rot);ctx.fillStyle=p.c;ctx.fillRect(-p.s/2,-p.s/2,p.s,p.s*0.6);ctx.restore();}\n    });\n  }\n}"}}}}}}}},{"_id":"6a2d38539b58f90d1c229646","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kBlob","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n    .wrap{height:100%;box-sizing:border-box;border:1px solid #EAECF0;border-radius:14px;background:#fff;display:flex;align-items:center;justify-content:center;box-shadow:0 1px 2px rgba(16,24,40,.05);overflow:hidden}\n    .wrap svg{width:75%;height:75%}\n  `,\n  render(d2){ return '<div class=\"wrap\"><svg viewBox=\"0 0 200 200\"><defs><linearGradient id=\"bgrad\" x1=\"0\" x2=\"1\" y1=\"0\" y2=\"1\"><stop offset=\"0\" stop-color=\"#818CF8\"/><stop offset=\"1\" stop-color=\"#EC4899\"/></linearGradient></defs><path data-blob fill=\"url(#bgrad)\"/></svg></div>'; },\n  mounted(d2){\n    var N=8,cx=100,cy=100,base=62;\n    d2.raf(function(t){\n      var el=d2.$('[data-blob]'); if(!el) return;\n      var pts=[];\n      for(var i=0;i<N;i++){var ang=(Math.PI*2*i/N);var r=base+Math.sin(t/600+i*1.7)*14+Math.cos(t/900+i)*8;pts.push([cx+Math.cos(ang)*r,cy+Math.sin(ang)*r]);}\n      var d='M '+((pts[0][0]+pts[N-1][0])/2).toFixed(1)+' '+((pts[0][1]+pts[N-1][1])/2).toFixed(1)+' ';\n      for(var i=0;i<N;i++){var cur=pts[i],nxt=pts[(i+1)%N];var mx=((cur[0]+nxt[0])/2).toFixed(1),my=((cur[1]+nxt[1])/2).toFixed(1);d+='Q '+cur[0].toFixed(1)+' '+cur[1].toFixed(1)+' '+mx+' '+my+' ';}\n      d+='Z';\n      el.setAttribute('d',d);\n    });\n  }\n}"}}}}}}}},{"_id":"6a2d385ded4fc677c3605185","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kTypewriter","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>\"]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c];});}\nconst PHRASES=['Code components = HTML + CSS + JS.','d2.* dá acesso reativo a dados e estado.','SVG e canvas que block trees não fazem.','Tudo isolado num shadow root.'];\nexport default {\n  css: `\n    .wrap{height:100%;box-sizing:border-box;border:1px solid #EAECF0;border-radius:14px;background:#0B1020;display:flex;flex-direction:column;justify-content:center;padding:24px;gap:10px;box-shadow:0 1px 2px rgba(16,24,40,.05);font-family:ui-monospace,SFMono-Regular,Menlo,monospace}\n    .dots{display:flex;gap:6px}\n    .dots i{width:10px;height:10px;border-radius:50%;display:block}\n    .tx{font-size:15px;color:#A5B4FC;line-height:1.5;min-height:46px}\n    .cur{display:inline-block;width:8px;height:17px;background:#818CF8;vertical-align:-3px;animation:bl 1s steps(2) infinite}\n    @keyframes bl{0%,50%{opacity:1}50.01%,100%{opacity:0}}\n  `,\n  render(d2){\n    var txt=d2.state.txt||'';\n    return '<div class=\"wrap\"><div class=\"dots\"><i style=\"background:#F04438\"></i><i style=\"background:#F59E0B\"></i><i style=\"background:#22C55E\"></i></div><div class=\"tx\">'+esc(txt)+'<span class=\"cur\"></span></div></div>';\n  },\n  mounted(d2){\n    var pi=0,ci=0,dir=1,last=0,pause=0;\n    d2.raf(function(t){\n      if(t<pause) return;\n      if(t-last<60) return; last=t;\n      var ph=PHRASES[pi];\n      if(dir>0){ci++; if(ci>=ph.length){dir=-1;pause=t+1100;}} else {ci--; if(ci<=0){ci=0;dir=1;pi=(pi+1)%PHRASES.length;pause=t+300;}}\n      d2.state.txt=ph.slice(0,ci);\n    });\n  }\n}"}}}}}}}},{"_id":"6a2d38bebaacaeb32628d21c","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kKanban","package":"ai-playground","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 INIT={todo:[{id:1,t:'Login OAuth'},{id:2,t:'Dark mode'},{id:3,t:'Export CSV'}],doing:[{id:4,t:'API v2'},{id:5,t:'Onboarding'}],done:[{id:6,t:'Deploy CI/CD'}]};\nconst COLS=[['todo','A fazer','#98A2B3'],['doing','Fazendo','#2E90FA'],['done','Feito','#12B76A']];\nexport default {\n  css: `\n    .wrap{height:100%;box-sizing:border-box;background:#fff;border:1px solid #EAECF0;border-radius:14px;padding:16px 18px;display:flex;flex-direction:column;gap:12px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;box-shadow:0 1px 2px rgba(16,24,40,.05)}\n    .title{font-size:13px;font-weight:600;color:#101828}\n    .board{flex:1;display:grid;grid-template-columns:repeat(3,1fr);gap:10px;min-height:0}\n    .col{background:#F9FAFB;border:1px solid #F2F4F7;border-radius:10px;padding:8px;display:flex;flex-direction:column;gap:7px;overflow:auto}\n    .ch{display:flex;align-items:center;gap:6px;font-size:11px;font-weight:600;color:#475467}\n    .dotc{width:8px;height:8px;border-radius:50%}\n    .cnt{margin-left:auto;color:#98A2B3}\n    .cards{display:flex;flex-direction:column;gap:6px;min-height:24px;flex:1}\n    .card{background:#fff;border:1px solid #E4E7EC;border-radius:8px;padding:9px 10px;font-size:12.5px;color:#101828;cursor:grab;box-shadow:0 1px 2px rgba(16,24,40,.04);transition:box-shadow .15s}\n    .card:hover{box-shadow:0 2px 8px rgba(16,24,40,.1)}\n  `,\n  render(d2){\n    var data=d2.state.cols||INIT;\n    var cols=COLS.map(function(c){\n      var items=(data[c[0]]||[]).map(function(it){return '<div class=\"card\" draggable=\"true\" data-card=\"'+it.id+'\" data-col=\"'+c[0]+'\">'+it.t+'</div>';}).join('');\n      return '<div class=\"col\" data-col=\"'+c[0]+'\"><div class=\"ch\"><span class=\"dotc\" style=\"background:'+c[2]+'\"></span>'+c[1]+'<span class=\"cnt\">'+(data[c[0]]||[]).length+'</span></div><div class=\"cards\">'+items+'</div></div>';\n    }).join('');\n    return '<div class=\"wrap\"><div class=\"title\">Kanban · arraste os cartões entre colunas</div><div class=\"board\">'+cols+'</div></div>';\n  },\n  mounted(d2){\n    var drag=null;\n    d2.on('[data-card]','dragstart',function(e,el){drag={id:+el.getAttribute('data-card'),from:el.getAttribute('data-col')};el.style.opacity='.4';});\n    d2.on('[data-card]','dragend',function(e,el){el.style.opacity='';});\n    d2.on('.col','dragover',function(e){e.preventDefault();});\n    d2.on('.col','drop',function(e,el){\n      e.preventDefault(); if(!drag) return;\n      var to=el.getAttribute('data-col'); if(to===drag.from){drag=null;return;}\n      var cur=d2.state.cols||INIT, next={}, moved=null;\n      COLS.forEach(function(c){next[c[0]]=(cur[c[0]]||[]).filter(function(it){if(it.id===drag.id){moved=it;return false;}return true;});});\n      if(moved) next[to]=next[to].concat([moved]);\n      d2.state.cols=next; drag=null;\n    });\n  }\n}"}}}}}}}},{"_id":"6a2d38c55284d6e4f909aafe","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kSortable","package":"ai-playground","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 INIT=['Comprar leite','Pagar contas','Ligar pro dentista','Responder e-mails','Treinar 30 min'];\nexport default {\n  css: `\n    .wrap{height:100%;box-sizing:border-box;background:#fff;border:1px solid #EAECF0;border-radius:14px;padding:16px 18px;display:flex;flex-direction:column;gap:12px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;box-shadow:0 1px 2px rgba(16,24,40,.05)}\n    .title{font-size:13px;font-weight:600;color:#101828}\n    .list{flex:1;display:flex;flex-direction:column;gap:7px;overflow:auto}\n    .item{display:flex;align-items:center;gap:10px;background:#F9FAFB;border:1px solid #F2F4F7;border-radius:9px;padding:11px 12px;font-size:13px;color:#101828;cursor:grab;transition:box-shadow .15s,background .15s}\n    .item:hover{background:#fff;box-shadow:0 2px 8px rgba(16,24,40,.08)}\n    .grip{color:#D0D5DD;font-size:14px;letter-spacing:-2px}\n  `,\n  render(d2){\n    var list=d2.state.list||INIT;\n    var items=list.map(function(t,i){return '<div class=\"item\" draggable=\"true\" data-i=\"'+i+'\"><span class=\"grip\">&#10303;</span>'+t+'</div>';}).join('');\n    return '<div class=\"wrap\"><div class=\"title\">Lista ordenável · arraste pra reordenar</div><div class=\"list\">'+items+'</div></div>';\n  },\n  mounted(d2){\n    var from=null;\n    d2.on('[data-i]','dragstart',function(e,el){from=+el.getAttribute('data-i');el.style.opacity='.4';});\n    d2.on('[data-i]','dragend',function(e,el){el.style.opacity='';from=null;});\n    d2.on('[data-i]','dragover',function(e){e.preventDefault();});\n    d2.on('[data-i]','dragenter',function(e,el){\n      var to=+el.getAttribute('data-i'); if(from==null||to===from) return;\n      var list=(d2.state.list||INIT).slice(); var m=list.splice(from,1)[0]; list.splice(to,0,m); d2.state.list=list; from=to;\n    });\n  }\n}"}}}}}}}},{"_id":"6a2d38d7baacaeb32628d23b","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kSwipe","package":"ai-playground","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 CARDS=[{t:'Pico do Itacolomi',s:'Trilha · 4,2km',e:'⛰️'},{t:'Praia do Rosa',s:'Surf · SC',e:'🏖️'},{t:'Cânion Fortaleza',s:'Mirante 900m',e:'🏞️'},{t:'Cataratas do Iguaçu',s:'Patrimônio natural',e:'💦'}];\nexport default {\n  css: `\n    .wrap{height:100%;box-sizing:border-box;background:#F7F8FA;border:1px solid #EAECF0;border-radius:14px;padding:16px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;box-shadow:0 1px 2px rgba(16,24,40,.05);overflow:hidden}\n    .stack{position:relative;width:200px;height:200px}\n    .card{position:absolute;inset:0;background:#fff;border:1px solid #EAECF0;border-radius:16px;box-shadow:0 8px 24px rgba(16,24,40,.12);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;cursor:grab;touch-action:none;user-select:none}\n    .card.behind{transform:scale(.93) translateY(10px);box-shadow:0 4px 12px rgba(16,24,40,.08);z-index:0}\n    .card.fly-r{animation:flyR .4s forwards}\n    .card.fly-l{animation:flyL .4s forwards}\n    @keyframes flyR{to{transform:translateX(420px) rotate(22deg);opacity:0}}\n    @keyframes flyL{to{transform:translateX(-420px) rotate(-22deg);opacity:0}}\n    .emoji{font-size:60px}\n    .ct{font-size:16px;font-weight:700;color:#101828}\n    .cs{font-size:12px;color:#667085}\n    .badge{position:absolute;top:16px;font-size:13px;font-weight:800;letter-spacing:.05em;padding:4px 10px;border-radius:7px;border:2px solid}\n    .badge.like{right:14px;color:#12B76A;border-color:#12B76A;transform:rotate(12deg)}\n    .badge.nope{left:14px;color:#F04438;border-color:#F04438;transform:rotate(-12deg)}\n    .hint{font-size:11px;color:#98A2B3}\n    .done{align-items:center;justify-content:center}\n    .big{font-size:48px;color:#12B76A}\n    .rb{font-size:12px;font-weight:600;color:#6366F1;background:#EEF2FF;border:none;padding:8px 14px;border-radius:8px;cursor:pointer}\n  `,\n  render(d2){\n    var idx=d2.state.idx||0;\n    if(idx>=CARDS.length) return '<div class=\"wrap done\"><div class=\"big\">&#10003;</div><div style=\"font:600 14px sans-serif;color:#101828\">Você viu tudo!</div><button class=\"rb\" data-reset>Recomeçar</button></div>';\n    var dx=d2.state.dx||0, dragging=d2.state.dragging, fly=d2.state.fly||0;\n    var rot=(dx/18).toFixed(1);\n    var cls='card'+(fly>0?' fly-r':'')+(fly<0?' fly-l':'');\n    var style=fly?'':('transform:translateX('+dx+'px) rotate('+rot+'deg);transition:'+(dragging?'none':'transform .3s cubic-bezier(.2,.8,.2,1)'));\n    var c=CARDS[idx];\n    var likeOp=Math.max(0,Math.min(1,dx/100)).toFixed(2), nopeOp=Math.max(0,Math.min(1,-dx/100)).toFixed(2);\n    var behind=idx+1<CARDS.length?'<div class=\"card behind\"><div class=\"emoji\">'+CARDS[idx+1].e+'</div></div>':'';\n    return '<div class=\"wrap\"><div class=\"stack\">'+behind+'<div class=\"'+cls+'\" data-card style=\"'+style+'\"><div class=\"badge like\" style=\"opacity:'+likeOp+'\">CURTIR</div><div class=\"badge nope\" style=\"opacity:'+nopeOp+'\">PULAR</div><div class=\"emoji\">'+c.e+'</div><div class=\"ct\">'+c.t+'</div><div class=\"cs\">'+c.s+'</div></div></div><div class=\"hint\">arraste para os lados</div></div>';\n  },\n  mounted(d2){\n    var sx=0;\n    d2.on('[data-card]','pointerdown',function(e,el){if(d2.state.fly)return;d2.state.dragging=true;sx=e.clientX;if(el.setPointerCapture)el.setPointerCapture(e.pointerId);});\n    d2.on(window,'pointermove',function(e){if(d2.state.dragging)d2.state.dx=e.clientX-sx;});\n    d2.on(window,'pointerup',function(){if(!d2.state.dragging)return;d2.state.dragging=false;var dx=d2.state.dx||0;if(dx>100)d2.state.fly=1;else if(dx<-100)d2.state.fly=-1;else d2.state.dx=0;});\n    d2.on('[data-card]','animationend',function(){d2.state.idx=(d2.state.idx||0)+1;d2.state.fly=0;d2.state.dx=0;});\n    d2.on('[data-reset]','click',function(){d2.state.idx=0;d2.state.dx=0;d2.state.fly=0;});\n  }\n}"}}}}}}}},{"_id":"6a2d38e51b7164341d2e94ad","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kColorPicker","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function hsv2rgb(h,s,v){var c=v*s,x=c*(1-Math.abs((h/60)%2-1)),m=v-c,r,g,b;if(h<60){r=c;g=x;b=0;}else if(h<120){r=x;g=c;b=0;}else if(h<180){r=0;g=c;b=x;}else if(h<240){r=0;g=x;b=c;}else if(h<300){r=x;g=0;b=c;}else{r=c;g=0;b=x;}return [Math.round((r+m)*255),Math.round((g+m)*255),Math.round((b+m)*255)];}\nfunction hx(rgb){return '#'+rgb.map(function(v){return ('0'+v.toString(16)).slice(-2);}).join('').toUpperCase();}\nexport default {\n  css: `\n    .wrap{height:100%;box-sizing:border-box;background:#fff;border:1px solid #EAECF0;border-radius:14px;padding:16px 18px;display:flex;flex-direction:column;gap:12px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;box-shadow:0 1px 2px rgba(16,24,40,.05)}\n    .title{font-size:13px;font-weight:600;color:#101828}\n    .box{flex:1;min-height:0;border-radius:10px;position:relative;cursor:crosshair;touch-action:none}\n    .ring{position:absolute;width:14px;height:14px;border-radius:50%;border:2px solid #fff;box-shadow:0 0 0 1px rgba(0,0,0,.3);transform:translate(-50%,-50%);pointer-events:none}\n    .hue{height:14px;border-radius:999px;position:relative;cursor:pointer;touch-action:none;background:linear-gradient(to right,#f00,#ff0,#0f0,#0ff,#00f,#f0f,#f00)}\n    .hthumb{position:absolute;top:50%;width:18px;height:18px;border-radius:50%;background:#fff;box-shadow:0 1px 4px rgba(0,0,0,.3);transform:translate(-50%,-50%);pointer-events:none}\n    .out{display:flex;align-items:center;gap:10px}\n    .sw{width:32px;height:32px;border-radius:8px;border:1px solid rgba(0,0,0,.1)}\n    .out b{font-size:15px;color:#101828;font-family:ui-monospace,Menlo,monospace}\n  `,\n  render(d2){\n    var h=d2.state.h==null?260:d2.state.h, s=d2.state.s==null?.72:d2.state.s, v=d2.state.v==null?.9:d2.state.v;\n    var hueHex=hx(hsv2rgb(h,1,1)), col=hx(hsv2rgb(h,s,v));\n    var boxBg='linear-gradient(to top,#000,rgba(0,0,0,0)),linear-gradient(to right,#fff,'+hueHex+')';\n    return '<div class=\"wrap\"><div class=\"title\">Color Picker · HSV</div><div class=\"box\" data-box style=\"background:'+boxBg+'\"><div class=\"ring\" style=\"left:'+(s*100)+'%;top:'+((1-v)*100)+'%;background:'+col+'\"></div></div><div class=\"hue\" data-hue><div class=\"hthumb\" style=\"left:'+(h/360*100)+'%\"></div></div><div class=\"out\"><span class=\"sw\" style=\"background:'+col+'\"></span><b>'+col+'</b></div></div>';\n  },\n  mounted(d2){\n    var dragBox=false,dragHue=false;\n    function setBox(x,y){var b=d2.$('[data-box]');if(!b)return;var r=b.getBoundingClientRect();d2.state.s=Math.max(0,Math.min(1,(x-r.left)/r.width));d2.state.v=1-Math.max(0,Math.min(1,(y-r.top)/r.height));}\n    function setHue(x){var b=d2.$('[data-hue]');if(!b)return;var r=b.getBoundingClientRect();d2.state.h=Math.max(0,Math.min(360,(x-r.left)/r.width*360));}\n    d2.on('[data-box]','pointerdown',function(e){dragBox=true;setBox(e.clientX,e.clientY);});\n    d2.on('[data-hue]','pointerdown',function(e){dragHue=true;setHue(e.clientX);});\n    d2.on(window,'pointermove',function(e){if(dragBox)setBox(e.clientX,e.clientY);if(dragHue)setHue(e.clientX);});\n    d2.on(window,'pointerup',function(){dragBox=false;dragHue=false;});\n  }\n}"}}}}}}}},{"_id":"6a2d38ee9b58f90d1c2296bb","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kDualRange","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n    .wrap{height:100%;box-sizing:border-box;background:#fff;border:1px solid #EAECF0;border-radius:14px;padding:22px 24px;display:flex;flex-direction:column;justify-content:center;gap:18px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;box-shadow:0 1px 2px rgba(16,24,40,.05)}\n    .head{display:flex;justify-content:space-between;align-items:baseline;font-size:13px;color:#475467;font-weight:500}\n    .head b{font-size:16px;color:#101828;font-variant-numeric:tabular-nums}\n    .track{position:relative;height:8px;border-radius:999px;background:#EAECF0;cursor:pointer;touch-action:none}\n    .fill{position:absolute;top:0;bottom:0;border-radius:999px;background:linear-gradient(90deg,#818CF8,#6366F1)}\n    .thumb{position:absolute;top:50%;width:20px;height:20px;border-radius:50%;background:#fff;border:2px solid #6366F1;box-shadow:0 1px 4px rgba(16,24,40,.2);transform:translate(-50%,-50%);cursor:grab}\n    .thumb:active{cursor:grabbing;transform:translate(-50%,-50%) scale(1.15)}\n    .hint{font-size:11px;color:#98A2B3}\n  `,\n  render(d2){\n    var lo=d2.state.lo==null?25:d2.state.lo, hi=d2.state.hi==null?75:d2.state.hi;\n    return '<div class=\"wrap\"><div class=\"head\"><span>Faixa de preço</span><b>R$ '+lo+' – R$ '+hi+'</b></div><div class=\"track\" data-track><div class=\"fill\" style=\"left:'+lo+'%;right:'+(100-hi)+'%\"></div><div class=\"thumb\" data-thumb=\"lo\" style=\"left:'+lo+'%\"></div><div class=\"thumb\" data-thumb=\"hi\" style=\"left:'+hi+'%\"></div></div><div class=\"hint\">dois polegares — escreve min/max em d2.state</div></div>';\n  },\n  mounted(d2){\n    var active=null;\n    function setFrom(x){var t=d2.$('[data-track]');if(!t)return;var r=t.getBoundingClientRect();var p=Math.round(Math.max(0,Math.min(100,(x-r.left)/r.width*100)));var lo=d2.state.lo==null?25:d2.state.lo,hi=d2.state.hi==null?75:d2.state.hi;if(active==='lo')d2.state.lo=Math.min(p,hi);else d2.state.hi=Math.max(p,lo);}\n    d2.on('[data-thumb]','pointerdown',function(e,el){active=el.getAttribute('data-thumb');});\n    d2.on(window,'pointermove',function(e){if(active)setFrom(e.clientX);});\n    d2.on(window,'pointerup',function(){active=null;});\n  }\n}"}}}}}}}},{"_id":"6a2d3941ed4fc677c360523e","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kSignature","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n    .wrap{height:100%;box-sizing:border-box;background:#fff;border:1px solid #EAECF0;border-radius:14px;padding:16px 18px;display:flex;flex-direction:column;gap:10px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;box-shadow:0 1px 2px rgba(16,24,40,.05)}\n    .hd{display:flex;align-items:center;justify-content:space-between}\n    .title{font-size:13px;font-weight:600;color:#101828}\n    .clr{font-size:12px;font-weight:600;color:#F04438;background:#FEF3F2;border:none;padding:6px 12px;border-radius:7px;cursor:pointer}\n    .clr:hover{background:#FEE4E2}\n    canvas{flex:1;min-height:0;border:1px dashed #D0D5DD;border-radius:10px;background:#FCFCFD;cursor:crosshair;touch-action:none}\n  `,\n  render(d2){ return '<div class=\"wrap\"><div class=\"hd\"><span class=\"title\">Assinatura</span><button class=\"clr\" data-clear>Limpar</button></div><canvas data-cv></canvas></div>'; },\n  mounted(d2){\n    var cv=d2.$('[data-cv]'); if(!cv) return;\n    var ctx=cv.getContext('2d');\n    var DPR=Math.min(window.devicePixelRatio||1,2);\n    var r=cv.getBoundingClientRect(); cv.width=r.width*DPR; cv.height=r.height*DPR;\n    ctx.scale(DPR,DPR); ctx.lineCap='round'; ctx.lineJoin='round'; ctx.lineWidth=2.5; ctx.strokeStyle='#1E293B';\n    var drawing=false,last=null;\n    function pos(e){var b=cv.getBoundingClientRect();return [e.clientX-b.left,e.clientY-b.top];}\n    d2.on('[data-cv]','pointerdown',function(e){drawing=true;last=pos(e);if(cv.setPointerCapture)cv.setPointerCapture(e.pointerId);});\n    d2.on('[data-cv]','pointermove',function(e){if(!drawing)return;var p=pos(e);ctx.beginPath();ctx.moveTo(last[0],last[1]);ctx.lineTo(p[0],p[1]);ctx.stroke();last=p;});\n    d2.on(window,'pointerup',function(){drawing=false;});\n    d2.on('[data-clear]','click',function(){ctx.clearRect(0,0,cv.width,cv.height);});\n  }\n}"}}}}}}}},{"_id":"6a2d394c61efae759d5c9de0","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kEditTable","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>\"]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c];});}\nexport default {\n  css: `\n    .wrap{height:100%;box-sizing:border-box;background:#fff;border:1px solid #EAECF0;border-radius:14px;display:flex;flex-direction:column;overflow:hidden;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;box-shadow:0 1px 2px rgba(16,24,40,.05)}\n    .title{font-size:13px;font-weight:600;color:#101828;padding:15px 16px;border-bottom:1px solid #F2F4F7}\n    .list{flex:1;overflow:auto}\n    .row{display:flex;align-items:center;gap:10px;padding:8px 16px;border-bottom:1px solid #F9FAFB}\n    .row:last-child{border-bottom:none}\n    .row input[type=checkbox]{width:16px;height:16px;accent-color:#6366F1;cursor:pointer;flex:0 0 auto}\n    .tin{flex:1;min-width:0;border:1px solid transparent;background:transparent;border-radius:6px;padding:5px 7px;font:inherit;font-size:13px;color:#101828;outline:none}\n    .tin:hover{border-color:#EAECF0}\n    .tin:focus{border-color:#6366F1;background:#fff;box-shadow:0 0 0 3px rgba(99,102,241,.1)}\n    .row.done .tin{color:#98A2B3;text-decoration:line-through}\n    .own{font-size:12px;color:#667085;flex:0 0 auto}\n    .pri{font-size:10px;font-weight:700;padding:2px 7px;border-radius:5px;flex:0 0 auto}\n    .p1{background:#FEF3F2;color:#B42318}.p2{background:#FFFAEB;color:#B54708}.p3{background:#ECFDF3;color:#027A48}\n    .empty{padding:30px;text-align:center;color:#98A2B3;font-size:13px}\n  `,\n  render(d2){\n    var ds=d2.data();\n    if(!ds) return '<div class=\"wrap\"><div class=\"empty\">Sem dataset</div></div>';\n    var recs=ds.records();\n    if(!recs.length) return '<div class=\"wrap\"><div class=\"title\">Tarefas</div><div class=\"empty\">Carregando…</div></div>';\n    var rows=recs.map(function(r){return '<div class=\"row'+(r.done?' done':'')+'\"><input type=\"checkbox\" data-done data-id=\"'+r._id+'\" '+(r.done?'checked':'')+'/><input class=\"tin\" data-task data-id=\"'+r._id+'\" value=\"'+esc(r.task)+'\"/><span class=\"own\">'+esc(r.owner)+'</span><span class=\"pri p'+(r.priority||2)+'\">P'+(r.priority||2)+'</span></div>';}).join('');\n    return '<div class=\"wrap\"><div class=\"title\">Tarefas · edição inline persiste no dataset</div><div class=\"list\">'+rows+'</div></div>';\n  },\n  mounted(d2){\n    d2.on('[data-done]','change',function(e,el){d2.data().update({_id:el.getAttribute('data-id'),done:el.checked});});\n    d2.on('[data-task]','change',function(e,el){d2.data().update({_id:el.getAttribute('data-id'),task:el.value});});\n  }\n}"}},"dataset":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"dataset"}}}}}}}}}},{"_id":"6a2d39575284d6e4f909ab7c","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kPivot","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n    .wrap{height:100%;box-sizing:border-box;background:#fff;border:1px solid #EAECF0;border-radius:14px;padding:16px 18px;display:flex;flex-direction:column;gap:10px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;box-shadow:0 1px 2px rgba(16,24,40,.05)}\n    .title{font-size:13px;font-weight:600;color:#101828}\n    .list{flex:1;display:flex;flex-direction:column;gap:9px;justify-content:center;min-height:0}\n    .row{display:flex;align-items:center;gap:10px;font-size:12.5px}\n    .pl{width:78px;color:#475467;font-weight:500;flex:0 0 auto}\n    .barw{flex:1;background:#F2F4F7;border-radius:6px;height:22px;overflow:hidden}\n    .bar{height:100%;border-radius:6px;background:linear-gradient(90deg,#818CF8,#6366F1);min-width:2px;transition:width .4s ease}\n    .n{width:30px;text-align:right;color:#98A2B3;flex:0 0 auto}\n    .mrr{width:78px;text-align:right;font-weight:600;color:#101828;font-variant-numeric:tabular-nums;flex:0 0 auto}\n    .foot{font-size:12px;color:#667085;border-top:1px solid #F2F4F7;padding-top:9px}\n    .foot b{color:#101828}\n    .empty{padding:30px;text-align:center;color:#98A2B3;font-size:13px}\n  `,\n  render(d2){\n    var ds=d2.data();\n    if(!ds) return '<div class=\"wrap\"><div class=\"empty\">Sem dataset</div></div>';\n    var recs=ds.records();\n    if(!recs.length) return '<div class=\"wrap\"><div class=\"title\">MRR por plano</div><div class=\"empty\">Carregando…</div></div>';\n    var g={};\n    recs.forEach(function(r){var k=r.plano||'—';if(!g[k])g[k]={n:0,mrr:0};g[k].n++;g[k].mrr+=(+r.mrr||0);});\n    var keys=Object.keys(g).sort(function(a,b){return g[b].mrr-g[a].mrr;});\n    var max=Math.max.apply(null,keys.map(function(k){return g[k].mrr;}))||1;\n    var rows=keys.map(function(k){var w=(g[k].mrr/max*100).toFixed(0);return '<div class=\"row\"><span class=\"pl\">'+k+'</span><div class=\"barw\"><div class=\"bar\" style=\"width:'+w+'%\"></div></div><span class=\"n\">'+g[k].n+'</span><span class=\"mrr\">R$ '+g[k].mrr.toLocaleString('pt-BR')+'</span></div>';}).join('');\n    var tot=recs.reduce(function(s,r){return s+(+r.mrr||0);},0);\n    return '<div class=\"wrap\"><div class=\"title\">MRR por plano · agregação client-side</div><div class=\"list\">'+rows+'</div><div class=\"foot\">Total: <b>R$ '+tot.toLocaleString('pt-BR')+'</b> em '+recs.length+' clientes</div></div>';\n  }\n}"}},"dataset":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"dataset"}}}}}}}}}},{"_id":"6a2d3964911a2eb6b81651f3","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kChat","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>\"]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c];});}\nexport default {\n  css: `\n    .wrap{height:100%;box-sizing:border-box;background:#fff;border:1px solid #EAECF0;border-radius:14px;display:flex;flex-direction:column;overflow:hidden;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;box-shadow:0 1px 2px rgba(16,24,40,.05)}\n    .title{font-size:13px;font-weight:600;color:#101828;padding:14px 16px;border-bottom:1px solid #F2F4F7}\n    .msgs{flex:1;overflow:auto;padding:14px 16px;display:flex;flex-direction:column;gap:8px}\n    .b{max-width:80%;padding:8px 12px;border-radius:12px;font-size:13px;line-height:1.45;white-space:pre-wrap}\n    .b.user{align-self:flex-end;background:#6366F1;color:#fff;border-bottom-right-radius:4px}\n    .b.assistant{align-self:flex-start;background:#F2F4F7;color:#101828;border-bottom-left-radius:4px}\n    .b.streaming{opacity:.85}\n    .empty{margin:auto;color:#98A2B3;font-size:13px;text-align:center}\n    .inrow{display:flex;gap:8px;padding:12px 14px;border-top:1px solid #F2F4F7}\n    .inrow input{flex:1;min-width:0;padding:9px 12px;border:1px solid #E4E7EC;border-radius:9px;font:inherit;font-size:13px;outline:none}\n    .inrow input:focus{border-color:#6366F1;box-shadow:0 0 0 3px rgba(99,102,241,.1)}\n    .inrow button{padding:9px 16px;border:none;border-radius:9px;background:#6366F1;color:#fff;font:inherit;font-size:13px;font-weight:600;cursor:pointer}\n    .inrow button:disabled{opacity:.5;cursor:default}\n  `,\n  render(d2){\n    var ref=d2.param('assistant','l1-plain');\n    var msgs=d2.state.msgs||[];\n    var a=d2.assistant(ref);\n    var bubbles=msgs.map(function(m){return '<div class=\"b '+m.role+'\">'+esc(m.content)+'</div>';}).join('');\n    if(d2.state.streaming){bubbles+='<div class=\"b assistant streaming\">'+esc(a.answer||'…')+'</div>';}\n    if(!msgs.length&&!d2.state.streaming){bubbles='<div class=\"empty\">Converse com a IA — multi-turn, com histórico.</div>';}\n    return '<div class=\"wrap\"><div class=\"title\">Chat IA · streaming + memória</div><div class=\"msgs\" data-msgs>'+bubbles+'</div><div class=\"inrow\"><input data-q placeholder=\"Escreva uma mensagem…\" value=\"'+esc(d2.state.q||'')+'\" '+(d2.state.streaming?'disabled':'')+'/><button data-send '+(d2.state.streaming?'disabled':'')+'>Enviar</button></div></div>';\n  },\n  mounted(d2){\n    function send(){\n      if(d2.state.streaming) return;\n      var q=(d2.state.q||'').trim(); if(!q) return;\n      var ref=d2.param('assistant','l1-plain');\n      var msgs=(d2.state.msgs||[]).concat([{role:'user',content:q}]);\n      d2.state.msgs=msgs; d2.state.q=''; d2.state.streaming=true;\n      d2.assistant(ref).reply(msgs).then(function(ans){d2.state.msgs=(d2.state.msgs||[]).concat([{role:'assistant',content:ans}]);d2.state.streaming=false;}).catch(function(){d2.state.streaming=false;});\n    }\n    d2.on('[data-q]','input',function(e,el){d2.state.q=el.value;});\n    d2.on('[data-q]','keydown',function(e){if(e.key==='Enter')send();});\n    d2.on('[data-send]','click',send);\n  },\n  updated(d2){var m=d2.$('[data-msgs]');if(m)m.scrollTop=m.scrollHeight;}\n}"}},"assistant":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"assistant"}}}}}}}}}},{"_id":"6a2d3976baacaeb32628d2d9","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kCmdK","package":"ai-playground","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 CMDS=[{i:'🏠',t:'Ir para Início'},{i:'📊',t:'Abrir Dashboard'},{i:'👥',t:'Ver Equipe'},{i:'⚙️',t:'Configurações'},{i:'🔎',t:'Buscar arquivos'},{i:'🌙',t:'Alternar tema'},{i:'📤',t:'Exportar dados'},{i:'🚪',t:'Sair'}];\nfunction filt(q){q=(q||'').toLowerCase();return CMDS.filter(function(c){return !q||c.t.toLowerCase().indexOf(q)>=0;});}\nexport default {\n  css: `\n    .wrap{height:100%;box-sizing:border-box;background:#101828;border:1px solid #EAECF0;border-radius:14px;position:relative;overflow:hidden;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;box-shadow:0 1px 2px rgba(16,24,40,.05)}\n    .center{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px}\n    .kbd{font:600 16px ui-monospace,Menlo,monospace;color:#fff;background:rgba(255,255,255,.1);border:1px solid rgba(255,255,255,.2);padding:8px 16px;border-radius:10px}\n    .ht{font-size:12px;color:#98A2B3}\n    .last{font-size:12px;color:#A5B4FC}\n    .last b{color:#fff}\n    .overlay{position:absolute;inset:0;background:rgba(8,12,24,.6);display:flex;align-items:flex-start;justify-content:center;padding-top:26px}\n    .palette{width:88%;background:#1E2536;border:1px solid #344054;border-radius:12px;overflow:hidden;box-shadow:0 16px 40px rgba(0,0,0,.5)}\n    .pin{width:100%;box-sizing:border-box;padding:13px 16px;background:transparent;border:none;border-bottom:1px solid #344054;color:#fff;font:inherit;font-size:14px;outline:none}\n    .cmds{max-height:150px;overflow:auto;padding:6px}\n    .cmd{display:flex;align-items:center;gap:10px;padding:9px 11px;border-radius:8px;font-size:13px;color:#E4E7EC;cursor:pointer}\n    .cmd.on{background:#6366F1}\n    .ci{font-size:15px}\n    .noc{padding:16px;text-align:center;color:#667085;font-size:13px}\n    .pf{padding:8px 12px;border-top:1px solid #344054;font-size:10.5px;color:#667085}\n  `,\n  render(d2){\n    var open=d2.state.open,q=d2.state.q||'',sel=d2.state.sel||0,last=d2.state.last;\n    if(!open) return '<div class=\"wrap\"><div class=\"center\"><div class=\"kbd\">&#8984; K</div><div class=\"ht\">abra o command palette</div>'+(last?'<div class=\"last\">última ação: <b>'+last+'</b></div>':'')+'</div></div>';\n    var list=filt(q);\n    var items=list.length?list.map(function(c,i){return '<div class=\"cmd'+(i===sel?' on':'')+'\" data-cmd=\"'+i+'\"><span class=\"ci\">'+c.i+'</span>'+c.t+'</div>';}).join(''):'<div class=\"noc\">Nada encontrado</div>';\n    return '<div class=\"wrap\"><div class=\"overlay\"><div class=\"palette\"><input class=\"pin\" data-q placeholder=\"Digite um comando…\" value=\"'+q+'\"/><div class=\"cmds\">'+items+'</div><div class=\"pf\">&#8593;&#8595; navegar · &#8629; selecionar · esc fechar</div></div></div></div>';\n  },\n  mounted(d2){\n    function exec(){var list=filt(d2.state.q||'');var c=list[d2.state.sel||0];if(c){d2.state.last=c.t;d2.state.open=false;d2.state.q='';d2.state.sel=0;}}\n    d2.on(window,'keydown',function(e){\n      if((e.metaKey||e.ctrlKey)&&(e.key==='k'||e.key==='K')){e.preventDefault();d2.state.open=!d2.state.open;d2.state.q='';d2.state.sel=0;return;}\n      if(!d2.state.open)return;\n      var list=filt(d2.state.q||'');\n      if(e.key==='Escape'){d2.state.open=false;}\n      else if(e.key==='ArrowDown'){e.preventDefault();d2.state.sel=Math.min((d2.state.sel||0)+1,list.length-1);}\n      else if(e.key==='ArrowUp'){e.preventDefault();d2.state.sel=Math.max((d2.state.sel||0)-1,0);}\n      else if(e.key==='Enter'){exec();}\n    });\n    d2.on('[data-q]','input',function(e,el){d2.state.q=el.value;d2.state.sel=0;});\n    d2.on('[data-cmd]','click',function(e,el){d2.state.sel=+el.getAttribute('data-cmd');exec();});\n  },\n  updated(d2){if(d2.state.open){var i=d2.$('[data-q]');if(i&&document.activeElement!==i){try{i.focus();}catch(e){}}}}\n}"}}}}}}}},{"_id":"6a2d3993911a2eb6b8165219","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kLab2","package":"ai-playground","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 EX=[\n  {n:'K9',t:'Line Chart',d:'SVG · tooltip no cursor',r:'kLineChart'},\n  {n:'K10',t:'Heatmap',d:'grid · escala de cor',r:'kHeatmap'},\n  {n:'K11',t:'Gauge',d:'SVG arc · d2.spring',r:'kGauge'},\n  {n:'K12',t:'Spark Grid',d:'small multiples',r:'kSparkGrid'},\n  {n:'K13',t:'Radar Chart',d:'SVG · trigonometria',r:'kRadar'},\n  {n:'K14',t:'Bubble Chart',d:'SVG · scatter clicável',r:'kBubble'},\n  {n:'K15',t:'Particles',d:'canvas · d2.raf',r:'kParticles'},\n  {n:'K16',t:'Confetti',d:'canvas · física',r:'kConfetti'},\n  {n:'K17',t:'Morphing Blob',d:'SVG morph · d2.raf',r:'kBlob'},\n  {n:'K18',t:'Typewriter',d:'d2.raf · datilografia',r:'kTypewriter'},\n  {n:'K19',t:'Kanban',d:'drag & drop entre colunas',r:'kKanban'},\n  {n:'K20',t:'Sortable List',d:'arrastar para reordenar',r:'kSortable'},\n  {n:'K21',t:'Swipe Cards',d:'gesto · fly-out',r:'kSwipe'},\n  {n:'K22',t:'Color Picker',d:'HSV · pointer 2D',r:'kColorPicker'},\n  {n:'K23',t:'Dual Range',d:'2 polegares · min/max',r:'kDualRange'},\n  {n:'K24',t:'Signature Pad',d:'canvas · desenho livre',r:'kSignature'},\n  {n:'K25',t:'Editable Table',d:'d2.data().update persiste',r:'kEditTable'},\n  {n:'K26',t:'Pivot / Aggregate',d:'agregação ao vivo',r:'kPivot'},\n  {n:'K27',t:'AI Chat',d:'d2.assistant · multi-turn',r:'kChat'},\n  {n:'K28',t:'Command Palette',d:'⌘K · teclado',r:'kCmdK'}\n];\nexport default {\n  css: `\n    .lab{height:100%;box-sizing:border-box;overflow:auto;background:#F7F8FA;padding:26px 30px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;color:#101828}\n    .hd{margin-bottom:20px}\n    .hd h1{margin:0;font-size:21px;font-weight:600;letter-spacing:-.02em}\n    .hd p{margin:5px 0 0;font-size:13px;color:#667085}\n    .grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:18px}\n    .cell{display:flex;flex-direction:column;gap:10px}\n    .cap{display:flex;align-items:center;gap:8px}\n    .cap .b{font-size:11px;font-weight:700;color:#6366F1;background:#EEF2FF;padding:2px 8px;border-radius:6px}\n    .cap .t{font-size:14px;font-weight:600;color:#101828}\n    .cap .d{font-size:12px;color:#98A2B3;margin-left:auto;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}\n    .host{height:320px}\n  `,\n  render(d2){\n    var tasks=d2.params.tasks, clientes=d2.params.clientes;\n    var tiles=EX.map(function(e){\n      var params={};\n      if(e.r==='kEditTable') params={dataset:tasks};\n      if(e.r==='kPivot') params={dataset:clientes};\n      if(e.r==='kChat') params={assistant:'l1-plain'};\n      var child=d2.render('ai-playground@'+e.r, params, {key:e.r});\n      return '<div class=\"cell\"><div class=\"cap\"><span class=\"b\">'+e.n+'</span><span class=\"t\">'+e.t+'</span><span class=\"d\">'+e.d+'</span></div><div class=\"host\">'+child+'</div></div>';\n    }).join('');\n    return '<div class=\"lab\"><div class=\"hd\"><h1>Code Components · Laboratório II</h1><p>Nível avançado — dataviz interativa, canvas/d2.raf, drag &amp; drop, gestos, persistência e IA</p></div><div class=\"grid\">'+tiles+'</div></div>';\n  }\n}"}},"tasks":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"tasks"}}}},"clientes":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"clientes"}}}}}}}}}},{"_id":"6a2d7a99ed4fc677c360a6b3","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kBoids","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `.wrap{height:100%;border:1px solid #EAECF0;border-radius:14px;overflow:hidden;position:relative;background:#0B1020}.cv{width:100%;height:100%;display:block}.cap{position:absolute;left:12px;bottom:10px;color:rgba(255,255,255,.55);font:500 11px -apple-system,sans-serif;pointer-events:none}`,\n  render(){ return '<div class=\"wrap\"><canvas class=\"cv\" data-d2-static></canvas><span class=\"cap\">Boids · flocking</span></div>'; },\n  mounted(d2){\n    var cv=d2.$('.cv'),ctx=cv.getContext('2d');\n    function size(){var dpr=window.devicePixelRatio||1;cv.width=cv.clientWidth*dpr;cv.height=cv.clientHeight*dpr;ctx.setTransform(1,0,0,1,0,0);ctx.scale(dpr,dpr);}\n    size();d2._size=size;\n    var N=70,b=[];for(var i=0;i<N;i++)b.push({x:Math.random()*cv.clientWidth,y:Math.random()*cv.clientHeight,vx:(Math.random()-.5)*2,vy:(Math.random()-.5)*2});\n    d2.raf(function(){\n      var w=cv.clientWidth,h=cv.clientHeight;ctx.fillStyle='rgba(11,16,32,.22)';ctx.fillRect(0,0,w,h);\n      for(var i=0;i<N;i++){var bi=b[i],cx=0,cy=0,ax=0,ay=0,sx=0,sy=0,n=0;\n        for(var j=0;j<N;j++){if(i===j)continue;var dx=b[j].x-bi.x,dy=b[j].y-bi.y,d=Math.sqrt(dx*dx+dy*dy);if(d<52&&d>0){cx+=b[j].x;cy+=b[j].y;ax+=b[j].vx;ay+=b[j].vy;if(d<22){sx-=dx/d;sy-=dy/d;}n++;}}\n        if(n){cx/=n;cy/=n;ax/=n;ay/=n;bi.vx+=(cx-bi.x)*0.0009+(ax-bi.vx)*0.045+sx*0.07;bi.vy+=(cy-bi.y)*0.0009+(ay-bi.vy)*0.045+sy*0.07;}\n        var sp=Math.sqrt(bi.vx*bi.vx+bi.vy*bi.vy),mx=2.6;if(sp>mx){bi.vx=bi.vx/sp*mx;bi.vy=bi.vy/sp*mx;}\n        bi.x+=bi.vx;bi.y+=bi.vy;if(bi.x<0)bi.x+=w;if(bi.x>w)bi.x-=w;if(bi.y<0)bi.y+=h;if(bi.y>h)bi.y-=h;\n        var ang=Math.atan2(bi.vy,bi.vx);ctx.save();ctx.translate(bi.x,bi.y);ctx.rotate(ang);ctx.fillStyle='hsl('+((i*5)%360)+',80%,68%)';ctx.beginPath();ctx.moveTo(6,0);ctx.lineTo(-4,3);ctx.lineTo(-4,-3);ctx.closePath();ctx.fill();ctx.restore();}\n    });\n  },\n  updated(d2){d2._size&&d2._size();}\n}"}}}}}}}},{"_id":"6a2d7a999b58f90d1c22ebab","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kCloth","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n    .wrap{position:relative;width:100%;height:100%;overflow:hidden;border-radius:inherit}\n    .cv{display:block;width:100%;height:100%;touch-action:none;cursor:grab}\n    .cv:active{cursor:grabbing}\n    .wrap.drag .cv{filter:brightness(1.1)}\n    .badge{position:absolute;left:14px;bottom:12px;font:11px/1.5 ui-monospace,monospace;color:rgba(255,255,255,.5);pointer-events:none;letter-spacing:.05em}\n    .badge b{color:rgba(255,255,255,.85)}\n  `,\n  render(d2){\n    const bg = d2.param('bg', '#0a0a12');\n    return `<div class=\"wrap\" style=\"background:${bg}\">\n      <canvas class=\"cv\" data-d2-static></canvas>\n      <div class=\"badge\">cloth · <b>arraste</b> empurra · <b>hover</b> = luz · <b>dbl-click</b> reset · ${d2.state.nrm||'normal: procedural'}</div>\n      <input class=\"file\" type=\"file\" accept=\"image/*\" hidden />\n    </div>`;\n  },\n  mounted(d2, root){\n    const cv = d2.$('.cv'); const ctx = cv.getContext('2d');\n    const aCan=document.createElement('canvas'), aCtx=aCan.getContext('2d',{willReadFrequently:true});\n    const nCan=document.createElement('canvas'), nCtx=nCan.getContext('2d',{willReadFrequently:true});\n    const litCan=document.createElement('canvas'), litCtx=litCan.getContext('2d');\n    const clamp=(v,a,b)=>Math.max(a,Math.min(b,v));\n    const num=(v,fb)=>{ const n=Number(v); return isFinite(n)?n:fb; };\n\n    let W=0,H=0,dpr=1, cols=0,rows=0,spacing=0, points=[], sticks=[];\n    let img=null,imgReady=false, nimg=null,nReady=false, lastTex=null,lastNrm=null, lastC=-1,lastR=-1;\n    let W0=0,H0=0, aData=null,nData=null,litData=null, buffersReady=false;\n    const mouse={x:0,y:0,px:0,py:0,down:false,grab:null};\n    const light={x:128,y:96,z:140};\n\n    function colorStr(v,fb){ if(v==null)return fb; if(typeof v==='string')return v; if(v.params&&v.params.rgba)return v.params.rgba; if(v.rgba)return v.rgba; return fb; }\n    function parseColor(s,fb){ s=(s==null?'':String(s)).trim(); if(!s)s=fb;\n      if(s[0]==='#'){ let h=s.slice(1); if(h.length===3)h=h.split('').map(c=>c+c).join(''); const n=parseInt(h,16); if(isFinite(n))return [(n>>16)&255,(n>>8)&255,n&255]; return parseColor(fb,'#9aa3b2'); }\n      const m=s.match(/rgba?\\(([^)]+)\\)/i); if(m){ const p=m[1].split(',').map(parseFloat); return [p[0]||0,p[1]||0,p[2]||0]; }\n      return parseColor(fb,'#9aa3b2'); }\n\n    function size(){ dpr=window.devicePixelRatio||1; W=cv.clientWidth; H=cv.clientHeight;\n      cv.width=Math.max(1,Math.round(W*dpr)); cv.height=Math.max(1,Math.round(H*dpr)); ctx.setTransform(1,0,0,1,0,0); ctx.scale(dpr,dpr); }\n\n    function genFabric(w,h){\n      const id=new ImageData(w,h), d=id.data, k=Math.PI*2/7;\n      const Hf=(x,y)=> Math.sin(x*k)*0.5 + Math.sin(y*k)*0.5 + Math.sin((x+y)*k*0.5)*0.25;\n      for(let y=0;y<h;y++) for(let x=0;x<w;x++){\n        const hl=Hf(x-1,y),hr=Hf(x+1,y),hu=Hf(x,y-1),hd=Hf(x,y+1);\n        let nx=(hl-hr), ny=(hu-hd), nz=1.2; const m=Math.hypot(nx,ny,nz)||1; nx/=m;ny/=m;nz/=m;\n        const i=(y*w+x)*4; d[i]=(nx*0.5+0.5)*255; d[i+1]=(ny*0.5+0.5)*255; d[i+2]=(nz*0.5+0.5)*255; d[i+3]=255;\n      }\n      return id;\n    }\n    function flatColor(w,h,c){ const id=new ImageData(w,h),d=id.data; for(let i=0;i<d.length;i+=4){ d[i]=c[0];d[i+1]=c[1];d[i+2]=c[2];d[i+3]=255; } return id; }\n\n    function buildBuffers(){\n      const acc=parseColor(colorStr(d2.param('accent'),'#9aa3b2'),'#9aa3b2');\n      let bw=256,bh=256;\n      if(img){ const sc=Math.min(1,256/Math.max(img.width,img.height)); bw=Math.max(8,Math.round(img.width*sc)); bh=Math.max(8,Math.round(img.height*sc)); }\n      else if(nimg){ const sc=Math.min(1,256/Math.max(nimg.width,nimg.height)); bw=Math.max(8,Math.round(nimg.width*sc)); bh=Math.max(8,Math.round(nimg.height*sc)); }\n      W0=bw; H0=bh; aCan.width=nCan.width=litCan.width=W0; aCan.height=nCan.height=litCan.height=H0;\n      if(img){ aCtx.clearRect(0,0,W0,H0); aCtx.drawImage(img,0,0,W0,H0); try{ aData=aCtx.getImageData(0,0,W0,H0); }catch(e){ aData=flatColor(W0,H0,acc); } }\n      else aData=flatColor(W0,H0,acc);\n      if(nimg){ nCtx.clearRect(0,0,W0,H0); nCtx.drawImage(nimg,0,0,W0,H0); try{ nData=nCtx.getImageData(0,0,W0,H0); }catch(e){ nData=genFabric(W0,H0); } }\n      else nData=genFabric(W0,H0);\n      litData=litCtx.createImageData(W0,H0);\n      light.x=W0*0.55; light.y=H0*0.35; light.z=Math.max(W0,H0)*0.6;\n      buffersReady=true;\n    }\n\n    function relight(t){\n      if(!buffersReady) return;\n      const w=W0,h=H0, out=litData.data, a=aData.data, nd=nData.data;\n      const amb=clamp(num(d2.param('ambient',0.35),0.35),0,1);\n      const dif=clamp(num(d2.param('diffuse',0.95),0.95),0,4);\n      const specS=clamp(num(d2.param('specStrength',0.6),0.6),0,4);\n      const shin=clamp(num(d2.param('shininess',24),24),1,200);\n      const nStr=clamp(num(d2.param('normalStrength',1),1),0,4);\n      const inv=d2.param('invertGreen',true)?-1:1;\n      const lc=parseColor(colorStr(d2.param('lightColor'),'#fff1d0'),'#fff1d0');\n      const lx=light.x, ly=light.y, lz=light.z;\n      for(let p=0,i=0;p<w*h;p++,i+=4){\n        let nx=(nd[i]/127.5-1)*nStr, ny=(nd[i+1]/127.5-1)*nStr*inv, nz=nd[i+2]/127.5-1;\n        const nm=Math.hypot(nx,ny,nz)||1; nx/=nm;ny/=nm;nz/=nm;\n        const px=p%w, py=(p/w)|0;\n        let Lx=lx-px, Ly=ly-py, Lz=lz; const ld=Math.hypot(Lx,Ly,Lz)||1; Lx/=ld;Ly/=ld;Lz/=ld;\n        let ndl=nx*Lx+ny*Ly+nz*Lz; if(ndl<0)ndl=0;\n        let Hx=Lx,Hy=Ly,Hz=Lz+1; const hd=Math.hypot(Hx,Hy,Hz)||1; Hx/=hd;Hy/=hd;Hz/=hd;\n        let ndh=nx*Hx+ny*Hy+nz*Hz; if(ndh<0)ndh=0; const spec=Math.pow(ndh,shin)*specS;\n        const it=amb+dif*ndl;\n        let r=a[i]*it+lc[0]*spec, g=a[i+1]*it+lc[1]*spec, b=a[i+2]*it+lc[2]*spec;\n        out[i]=r>255?255:r; out[i+1]=g>255?255:g; out[i+2]=b>255?255:b; out[i+3]=255;\n      }\n      litCtx.putImageData(litData,0,0);\n    }\n\n    function loadTex(){ const url=(d2.param('textureUrl','')||'').trim(); if(url===lastTex)return; lastTex=url;\n      if(!url){ img=null;imgReady=false; buildBuffers(); return; }\n      const im=new Image(); im.crossOrigin='anonymous'; im.onload=()=>{ img=im;imgReady=true; buildBuffers(); }; im.onerror=()=>{ img=null;imgReady=false; buildBuffers(); }; im.src=url; }\n    function loadNrm(){ const url=(d2.param('normalMap','')||'').trim(); if(url===lastNrm)return; lastNrm=url;\n      if(!url){ nimg=null;nReady=false; d2.setState({nrm:'normal: procedural'}); buildBuffers(); return; }\n      const im=new Image(); im.crossOrigin='anonymous'; im.onload=()=>{ nimg=im;nReady=true; d2.setState({nrm:'normal: '+url.split('/').pop().split('?')[0]}); buildBuffers(); }; im.onerror=()=>{ nimg=null; d2.setState({nrm:'normal: (CORS/erro)'}); buildBuffers(); }; im.src=url; }\n    function loadNrmFile(file){ if(!file)return; const r=new FileReader(); r.onload=()=>{ const im=new Image(); im.onload=()=>{ nimg=im;nReady=true; lastNrm='__file'; d2.setState({nrm:'normal: '+file.name}); buildBuffers(); }; im.src=r.result; }; r.readAsDataURL(file); }\n\n    function build(){\n      cols=Math.max(2,Math.min(70,Math.round(d2.param('cols',26)))); rows=Math.max(2,Math.min(70,Math.round(d2.param('rows',18)))); lastC=cols;lastR=rows;\n      const clothW=Math.min(W*0.82,(H*0.78)*(cols/rows)); spacing=clothW/cols;\n      const startX=(W-spacing*cols)/2, startY=Math.max(spacing*0.6,(H-spacing*rows)*0.32);\n      points=[];\n      for(let y=0;y<=rows;y++) for(let x=0;x<=cols;x++){ const px=startX+x*spacing,py=startY+y*spacing; points.push({x:px,y:py,ox:px,oy:py,pinned:false}); }\n      const idx=(x,y)=>y*(cols+1)+x;\n      if(d2.param('pinTop',true)){ for(let x=0;x<=cols;x++) points[idx(x,0)].pinned=true; }\n      else if(d2.param('pinCorners',false)){ points[idx(0,0)].pinned=true; points[idx(cols,0)].pinned=true; }\n      sticks=[];\n      for(let y=0;y<=rows;y++) for(let x=0;x<=cols;x++){ if(x<cols)sticks.push([idx(x,y),idx(x+1,y),spacing]); if(y<rows)sticks.push([idx(x,y),idx(x,y+1),spacing]); }\n    }\n\n    function simulate(t){\n      const g=(num(d2.param('gravity',0.45),0.45))*0.55; const windAmt=num(d2.param('wind',0.15),0.15);\n      let damp=num(d2.param('damping',0.99),0.99); damp=clamp(damp,0.85,0.999);\n      const iter=Math.max(1,Math.min(10,Math.round(num(d2.param('stiffness',4),4))));\n      const wind=windAmt*(0.55+0.45*Math.sin(t/760))*spacing*0.05;\n      for(const p of points){ if(p.pinned)continue; const vx=(p.x-p.ox)*damp, vy=(p.y-p.oy)*damp; p.ox=p.x;p.oy=p.y; p.x+=vx+wind; p.y+=vy+g; }\n      if(mouse.down&&mouse.grab){ mouse.grab.x=mouse.x; mouse.grab.y=mouse.y; mouse.grab.ox=mouse.px; mouse.grab.oy=mouse.py; }\n      for(let k=0;k<iter;k++){ for(const s of sticks){ const a=points[s[0]],b=points[s[1]]; const dx=b.x-a.x,dy=b.y-a.y; const d=Math.sqrt(dx*dx+dy*dy)||0.0001; const diff=((s[2]-d)/d)*0.5; const ox=dx*diff,oy=dy*diff; if(!a.pinned){a.x-=ox;a.y-=oy;} if(!b.pinned){b.x+=ox;b.y+=oy;} }\n        for(const p of points){ if(p.pinned)continue; if(p.y>H-1){ p.y=H-1; p.ox=p.x+(p.x-p.ox)*0.4; } } }\n    }\n\n    function drawTri(im,x0,y0,x1,y1,x2,y2,u0,v0,u1,v1,u2,v2){\n      ctx.save(); const cx=(x0+x1+x2)/3,cy=(y0+y1+y2)/3,ex=1.012;\n      ctx.beginPath(); ctx.moveTo(cx+(x0-cx)*ex,cy+(y0-cy)*ex); ctx.lineTo(cx+(x1-cx)*ex,cy+(y1-cy)*ex); ctx.lineTo(cx+(x2-cx)*ex,cy+(y2-cy)*ex); ctx.closePath(); ctx.clip();\n      const a1=u1-u0,b1=v1-v0,a2=u2-u0,b2=v2-v0, dx1=x1-x0,dy1=y1-y0,dx2=x2-x0,dy2=y2-y0, det=a1*b2-a2*b1;\n      if(Math.abs(det)>1e-6){ const ia=(b2*dx1-b1*dx2)/det,ib=(b2*dy1-b1*dy2)/det,ic=(a1*dx2-a2*dx1)/det,id=(a1*dy2-a2*dy1)/det,ie=x0-ia*u0-ic*v0,iff=y0-ib*u0-id*v0;\n        ctx.transform(ia,ib,ic,id,ie,iff); ctx.drawImage(im,0,0); }\n      ctx.restore();\n    }\n\n    function draw(){\n      ctx.clearRect(0,0,W,H); const idx=(x,y)=>y*(cols+1)+x; const showMesh=d2.param('showMesh',false);\n      const tex = buffersReady ? litCan : null;\n      if(tex){ const iw=W0,ih=H0; ctx.imageSmoothingEnabled=true;\n        for(let y=0;y<rows;y++) for(let x=0;x<cols;x++){\n          const p00=points[idx(x,y)],p10=points[idx(x+1,y)],p01=points[idx(x,y+1)],p11=points[idx(x+1,y+1)];\n          const u0=x/cols*iw,u1=(x+1)/cols*iw,v0=y/rows*ih,v1=(y+1)/rows*ih;\n          drawTri(tex,p00.x,p00.y,p10.x,p10.y,p11.x,p11.y,u0,v0,u1,v0,u1,v1);\n          drawTri(tex,p00.x,p00.y,p11.x,p11.y,p01.x,p01.y,u0,v0,u1,v1,u0,v1);\n        }\n      }\n      if(showMesh){ ctx.strokeStyle='rgba(255,255,255,0.16)'; ctx.lineWidth=0.6; ctx.beginPath();\n        for(const s of sticks){ const a=points[s[0]],b=points[s[1]]; ctx.moveTo(a.x,a.y); ctx.lineTo(b.x,b.y); } ctx.stroke(); }\n    }\n\n    function relPos(e){ const r=cv.getBoundingClientRect(); return { x:e.clientX-r.left, y:e.clientY-r.top }; }\n\n    size(); build(); buildBuffers(); loadTex(); loadNrm();\n\n    if(typeof ResizeObserver!=='undefined'){ const ro=new ResizeObserver(()=>{ size(); build(); }); ro.observe(root); d2.onUnmount(()=>ro.disconnect()); }\n    d2.on('.wrap','dragover',(e)=>{ e.preventDefault(); root.querySelector('.wrap')&&root.querySelector('.wrap').classList.add('drag'); });\n    d2.on('.wrap','dragleave',()=>{ root.querySelector('.wrap')&&root.querySelector('.wrap').classList.remove('drag'); });\n    d2.on('.wrap','drop',(e)=>{ e.preventDefault(); root.querySelector('.wrap')&&root.querySelector('.wrap').classList.remove('drag'); loadNrmFile(e.dataTransfer&&e.dataTransfer.files&&e.dataTransfer.files[0]); });\n\n    d2.on(cv,'pointerdown',(e)=>{ const p=relPos(e); mouse.down=true; mouse.x=mouse.px=p.x; mouse.y=mouse.py=p.y;\n      let best=null,bd=1e9; for(const pt of points){ if(pt.pinned)continue; const dx=pt.x-p.x,dy=pt.y-p.y,d=dx*dx+dy*dy; if(d<bd){bd=d;best=pt;} }\n      mouse.grab=(bd<spacing*spacing*9)?best:null; cv.setPointerCapture&&cv.setPointerCapture(e.pointerId); });\n    d2.on(cv,'pointermove',(e)=>{ if(!buffersReady)return; const p=relPos(e); light.x=clamp(p.x/W,0,1)*W0; light.y=clamp(p.y/H,0,1)*H0; });\n    d2.on(window,'pointermove',(e)=>{ if(!mouse.down)return; const p=relPos(e); mouse.px=mouse.x;mouse.py=mouse.y; mouse.x=p.x;mouse.y=p.y; });\n    d2.on(window,'pointerup',()=>{ mouse.down=false; mouse.grab=null; });\n    d2.on(cv,'dblclick',()=>{ size(); build(); });\n\n    d2.raf((t)=>{\n      loadTex(); loadNrm();\n      const c=Math.max(2,Math.min(70,Math.round(d2.param('cols',26)))), r=Math.max(2,Math.min(70,Math.round(d2.param('rows',18))));\n      if(c!==lastC||r!==lastR) build();\n      if(d2.param('autoOrbit',true) && !mouse.down && buffersReady){ const a=t/1600; light.x=W0*0.5+Math.cos(a)*W0*0.32; light.y=H0*0.5+Math.sin(a)*H0*0.3; }\n      light.z=clamp(num(d2.param('lightZ',0.6),0.6),0.05,3)*Math.max(W0,H0);\n      simulate(t); relight(t); draw();\n    });\n  },\n}"}},"textureUrl":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"textureUrl"}}}},"normalMap":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"normalMap"}}}},"cols":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"cols"}}}},"rows":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"rows"}}}},"gravity":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"gravity"}}}},"wind":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"wind"}}}},"damping":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"damping"}}}},"stiffness":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"stiffness"}}}},"pinTop":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"pinTop"}}}},"pinCorners":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"pinCorners"}}}},"showMesh":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"showMesh"}}}},"lightColor":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"lightColor"}}}},"ambient":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"ambient"}}}},"diffuse":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"diffuse"}}}},"specStrength":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"specStrength"}}}},"shininess":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"shininess"}}}},"lightZ":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"lightZ"}}}},"normalStrength":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"normalStrength"}}}},"invertGreen":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"invertGreen"}}}},"autoOrbit":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"autoOrbit"}}}},"bg":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"bg"}}}},"accent":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"accent"}}}}}}}}}},{"_id":"6a2d7a9a911a2eb6b8169d73","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kOrbits","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `.wrap{height:100%;border:1px solid #EAECF0;border-radius:14px;overflow:hidden;position:relative;background:radial-gradient(circle at 50% 50%,#1a1438,#05060f)}.cv{width:100%;height:100%;display:block}.cap{position:absolute;left:12px;bottom:10px;color:rgba(255,255,255,.55);font:500 11px -apple-system,sans-serif;pointer-events:none}`,\n  render(){ return '<div class=\"wrap\"><canvas class=\"cv\" data-d2-static></canvas><span class=\"cap\">Órbitas · gravidade</span></div>'; },\n  mounted(d2){\n    var cv=d2.$('.cv'),ctx=cv.getContext('2d');\n    function size(){var dpr=window.devicePixelRatio||1;cv.width=cv.clientWidth*dpr;cv.height=cv.clientHeight*dpr;ctx.setTransform(1,0,0,1,0,0);ctx.scale(dpr,dpr);}\n    size();d2._size=size;\n    var cx=cv.clientWidth/2,cy=cv.clientHeight/2,GM=2600,COL=['#FDB022','#6366F1','#22C55E','#EC4899','#06B6D4'],bodies=[];\n    for(var i=0;i<5;i++){var r=34+i*20,a=Math.random()*6.28,v=Math.sqrt(GM/r);bodies.push({x:cx+Math.cos(a)*r,y:cy+Math.sin(a)*r,vx:-Math.sin(a)*v,vy:Math.cos(a)*v,c:COL[i]});}\n    d2.raf(function(){\n      var w=cv.clientWidth,h=cv.clientHeight;cx=w/2;cy=h/2;ctx.fillStyle='rgba(5,6,15,.28)';ctx.fillRect(0,0,w,h);\n      ctx.fillStyle='#FDB022';ctx.shadowColor='#FDB022';ctx.shadowBlur=18;ctx.beginPath();ctx.arc(cx,cy,7,0,6.2832);ctx.fill();ctx.shadowBlur=0;\n      for(var i=0;i<bodies.length;i++){var bd=bodies[i],dx=cx-bd.x,dy=cy-bd.y,d2d=dx*dx+dy*dy,d=Math.sqrt(d2d)||1,f=GM/d2d;bd.vx+=f*dx/d;bd.vy+=f*dy/d;bd.x+=bd.vx*0.016;bd.y+=bd.vy*0.016;ctx.fillStyle=bd.c;ctx.beginPath();ctx.arc(bd.x,bd.y,3.5,0,6.2832);ctx.fill();}\n    });\n  },\n  updated(d2){d2._size&&d2._size();}\n}"}}}}}}}},{"_id":"6a2d7a9a1b1e52cefa11f624","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kMetaballs","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `.wrap{height:100%;border:1px solid #EAECF0;border-radius:14px;overflow:hidden;position:relative;background:#0B1020}.cv{width:100%;height:100%;display:block}.cap{position:absolute;left:12px;bottom:10px;color:rgba(255,255,255,.55);font:500 11px -apple-system,sans-serif;pointer-events:none}`,\n  render(){ return '<div class=\"wrap\"><svg class=\"cv\" viewBox=\"0 0 200 200\" preserveAspectRatio=\"xMidYMid slice\"><defs><filter id=\"goo\"><feGaussianBlur in=\"SourceGraphic\" stdDeviation=\"6\" result=\"b\"/><feColorMatrix in=\"b\" mode=\"matrix\" values=\"1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 20 -9\"/></filter><linearGradient id=\"mbg\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\"><stop offset=\"0\" stop-color=\"#818CF8\"/><stop offset=\"1\" stop-color=\"#EC4899\"/></linearGradient></defs><g class=\"goo\" filter=\"url(#goo)\"></g></svg><span class=\"cap\">Metaballs · SVG gooey</span></div>'; },\n  mounted(d2){\n    var g=d2.$('.goo'); if(!g) return;\n    var N=7,balls=[];for(var i=0;i<N;i++)balls.push({phx:Math.random()*6.28,phy:Math.random()*6.28,r:13+Math.random()*12,sx:28+Math.random()*46,sy:28+Math.random()*46});\n    g.innerHTML=balls.map(function(b,i){return '<circle id=\"mb'+i+'\" fill=\"url(#mbg)\" r=\"'+b.r.toFixed(0)+'\"/>';}).join('');\n    d2.raf(function(t){for(var i=0;i<N;i++){var b=balls[i],x=100+Math.sin(t/900+b.phx)*b.sx,y=100+Math.cos(t/1100+b.phy)*b.sy,c=d2.$('#mb'+i);if(c){c.setAttribute('cx',x.toFixed(1));c.setAttribute('cy',y.toFixed(1));}}});\n  }\n}"}}}}}}}},{"_id":"6a2d7a9abaacaeb32629238c","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kLife","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `.wrap{height:100%;border:1px solid #EAECF0;border-radius:14px;overflow:hidden;position:relative;background:#0B1020}.cv{position:absolute;inset:0;width:100%;height:100%;display:block;cursor:cell}.ctl{position:absolute;right:10px;top:10px;display:flex;gap:6px}.ctl button{font:600 11px -apple-system,sans-serif;background:rgba(255,255,255,.1);color:#fff;border:1px solid rgba(255,255,255,.2);border-radius:7px;padding:5px 9px;cursor:pointer}.ctl button:hover{background:rgba(255,255,255,.2)}`,\n  render(d2){ var p=d2.state.paused; return '<div class=\"wrap\"><canvas class=\"cv\" data-d2-static></canvas><div class=\"ctl\"><button data-r>Aleatório</button><button data-c>Limpar</button><button data-p>'+(p?'▶ Play':'❚❚ Pause')+'</button></div></div>'; },\n  mounted(d2){\n    var cv=d2.$('.cv'),ctx=cv.getContext('2d'),CELL=11,cols=0,rows=0,grid=[];\n    function size(){var dpr=window.devicePixelRatio||1;cv.width=cv.clientWidth*dpr;cv.height=cv.clientHeight*dpr;ctx.setTransform(1,0,0,1,0,0);ctx.scale(dpr,dpr);cols=Math.floor(cv.clientWidth/CELL);rows=Math.floor(cv.clientHeight/CELL);}\n    function rnd(){grid=[];for(var i=0;i<cols*rows;i++)grid.push(Math.random()<0.28?1:0);}\n    size();d2._size=size;rnd();\n    function step(){var ng=new Array(cols*rows);for(var y=0;y<rows;y++)for(var x=0;x<cols;x++){var n=0;for(var dy=-1;dy<=1;dy++)for(var dx=-1;dx<=1;dx++){if(!dx&&!dy)continue;var nx=(x+dx+cols)%cols,ny=(y+dy+rows)%rows;n+=grid[ny*cols+nx];}var c=grid[y*cols+x];ng[y*cols+x]=(c&&(n===2||n===3))||(!c&&n===3)?1:0;}grid=ng;}\n    function draw(){var w=cv.clientWidth,h=cv.clientHeight;ctx.fillStyle='#0B1020';ctx.fillRect(0,0,w,h);for(var y=0;y<rows;y++)for(var x=0;x<cols;x++){if(grid[y*cols+x]){ctx.fillStyle='hsl('+((x+y)*3%360)+',75%,62%)';ctx.fillRect(x*CELL+1,y*CELL+1,CELL-2,CELL-2);}}}\n    var last=0;\n    d2.raf(function(t){if(!d2.state.paused&&t-last>110){last=t;step();}draw();});\n    d2.on('.cv','pointerdown',function(e){var r=cv.getBoundingClientRect(),x=Math.floor((e.clientX-r.left)/CELL),y=Math.floor((e.clientY-r.top)/CELL);if(x>=0&&x<cols&&y>=0&&y<rows){grid[y*cols+x]=grid[y*cols+x]?0:1;}});\n    d2.on('[data-r]','click',rnd);\n    d2.on('[data-c]','click',function(){grid=new Array(cols*rows).fill(0);});\n    d2.on('[data-p]','click',function(){d2.state.paused=!d2.state.paused;});\n  },\n  updated(d2){d2._size&&d2._size();}\n}"}}}}}}}},{"_id":"6a2d7a9a58bb101c90945dff","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kFireworks","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `.wrap{height:100%;border:1px solid #EAECF0;border-radius:14px;overflow:hidden;position:relative;background:#05060f}.cv{width:100%;height:100%;display:block;cursor:pointer}.cap{position:absolute;left:12px;bottom:10px;color:rgba(255,255,255,.55);font:500 11px -apple-system,sans-serif;pointer-events:none}`,\n  render(){ return '<div class=\"wrap\"><canvas class=\"cv\" data-d2-static></canvas><span class=\"cap\">Fogos · clique pra lançar</span></div>'; },\n  mounted(d2){\n    var cv=d2.$('.cv'),ctx=cv.getContext('2d');\n    function size(){var dpr=window.devicePixelRatio||1;cv.width=cv.clientWidth*dpr;cv.height=cv.clientHeight*dpr;ctx.setTransform(1,0,0,1,0,0);ctx.scale(dpr,dpr);}\n    size();d2._size=size;\n    var rockets=[],parts=[];\n    function launch(tx){var w=cv.clientWidth,h=cv.clientHeight;rockets.push({x:tx==null?40+Math.random()*(w-80):tx,y:h,ty:40+Math.random()*(h*0.45),hue:Math.floor(Math.random()*360)});}\n    function boom(x,y,hue){for(var i=0;i<60;i++){var a=Math.random()*6.2832,s=Math.random()*3+1;parts.push({x:x,y:y,vx:Math.cos(a)*s,vy:Math.sin(a)*s,life:1,hue:hue+Math.random()*30-15});}}\n    d2.on('.cv','pointerdown',function(e){var r=cv.getBoundingClientRect();launch(e.clientX-r.left);});\n    var last=0;\n    d2.raf(function(t){var w=cv.clientWidth,h=cv.clientHeight;if(t-last>900){last=t;launch();}ctx.fillStyle='rgba(5,6,15,.22)';ctx.fillRect(0,0,w,h);\n      for(var i=rockets.length-1;i>=0;i--){var rk=rockets[i];rk.y-=6;ctx.fillStyle='hsl('+rk.hue+',90%,70%)';ctx.fillRect(rk.x-1.5,rk.y-1.5,3,3);if(rk.y<=rk.ty){boom(rk.x,rk.y,rk.hue);rockets.splice(i,1);}}\n      for(var i=parts.length-1;i>=0;i--){var p=parts[i];p.vy+=0.04;p.x+=p.vx;p.y+=p.vy;p.life-=0.012;if(p.life<=0){parts.splice(i,1);continue;}ctx.globalAlpha=Math.max(0,p.life);ctx.fillStyle='hsl('+p.hue+',90%,'+(55+p.life*20)+'%)';ctx.fillRect(p.x,p.y,2.4,2.4);}ctx.globalAlpha=1;\n    });\n  },\n  updated(d2){d2._size&&d2._size();}\n}"}}}}}}}},{"_id":"6a2d7b127938117e38f3081b","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kMatrix","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `.wrap{height:100%;border:1px solid #EAECF0;border-radius:14px;overflow:hidden;position:relative;background:#050806}.cv{width:100%;height:100%;display:block}.cap{position:absolute;left:12px;bottom:10px;color:rgba(155,255,155,.5);font:500 11px -apple-system,sans-serif;pointer-events:none}`,\n  render(){ return '<div class=\"wrap\"><canvas class=\"cv\" data-d2-static></canvas><span class=\"cap\">Matrix rain</span></div>'; },\n  mounted(d2){\n    var cv=d2.$('.cv'),ctx=cv.getContext('2d'),F=14,cols=0,drops=[];\n    function size(){var dpr=window.devicePixelRatio||1;cv.width=cv.clientWidth*dpr;cv.height=cv.clientHeight*dpr;ctx.setTransform(1,0,0,1,0,0);ctx.scale(dpr,dpr);cols=Math.floor(cv.clientWidth/F);drops=[];for(var i=0;i<cols;i++)drops[i]=Math.random()*-40;}\n    size(); if(typeof ResizeObserver!=='undefined'){var ro=new ResizeObserver(size);ro.observe(cv);d2.onUnmount(function(){ro.disconnect();});}\n    var CH='アイウエオカキ0123456789ABCDEF';var last=0;\n    d2.raf(function(t){if(t-last<55)return;last=t;var w=cv.clientWidth,h=cv.clientHeight;ctx.fillStyle='rgba(5,8,6,.09)';ctx.fillRect(0,0,w,h);ctx.font=F+'px monospace';for(var i=0;i<cols;i++){var ch=CH[Math.floor(Math.random()*CH.length)],x=i*F,y=drops[i]*F;ctx.fillStyle='#cfffd0';ctx.fillText(ch,x,y);drops[i]++;if(y>h&&Math.random()>0.975)drops[i]=Math.random()*-20;}});\n  }\n}"}}}}}}}},{"_id":"6a2d7b12dbf815e74e98fb1b","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kStarfield","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `.wrap{height:100%;border:1px solid #EAECF0;border-radius:14px;overflow:hidden;position:relative;background:#03040a}.cv{width:100%;height:100%;display:block}.cap{position:absolute;left:12px;bottom:10px;color:rgba(255,255,255,.5);font:500 11px -apple-system,sans-serif;pointer-events:none}`,\n  render(){ return '<div class=\"wrap\"><canvas class=\"cv\" data-d2-static></canvas><span class=\"cap\">Starfield · warp</span></div>'; },\n  mounted(d2){\n    var cv=d2.$('.cv'),ctx=cv.getContext('2d'),N=260,stars=[];\n    function size(){var dpr=window.devicePixelRatio||1;cv.width=cv.clientWidth*dpr;cv.height=cv.clientHeight*dpr;ctx.setTransform(1,0,0,1,0,0);ctx.scale(dpr,dpr);}\n    function init(){stars=[];for(var i=0;i<N;i++)stars.push({x:Math.random()*2-1,y:Math.random()*2-1,z:Math.random()*0.9+0.1});}\n    size();init(); if(typeof ResizeObserver!=='undefined'){var ro=new ResizeObserver(size);ro.observe(cv);d2.onUnmount(function(){ro.disconnect();});}\n    d2.raf(function(){var w=cv.clientWidth,h=cv.clientHeight,cx=w/2,cy=h/2;ctx.fillStyle='rgba(3,4,10,.35)';ctx.fillRect(0,0,w,h);for(var i=0;i<N;i++){var s=stars[i];s.z-=0.007;if(s.z<=0.02){s.x=Math.random()*2-1;s.y=Math.random()*2-1;s.z=1;}var sx=cx+(s.x/s.z)*cx,sy=cy+(s.y/s.z)*cy,r=(1-s.z)*2.6;if(sx>=0&&sx<w&&sy>=0&&sy<h){ctx.fillStyle='rgba(255,255,255,'+(1-s.z).toFixed(2)+')';ctx.beginPath();ctx.arc(sx,sy,r,0,6.2832);ctx.fill();}}});\n  }\n}"}}}}}}}},{"_id":"6a2d7b12911a2eb6b8169e30","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kFlowField","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `.wrap{height:100%;border:1px solid #EAECF0;border-radius:14px;overflow:hidden;position:relative;background:#0a0612}.cv{width:100%;height:100%;display:block}.cap{position:absolute;left:12px;bottom:10px;color:rgba(255,255,255,.5);font:500 11px -apple-system,sans-serif;pointer-events:none}`,\n  render(){ return '<div class=\"wrap\"><canvas class=\"cv\" data-d2-static></canvas><span class=\"cap\">Flow field</span></div>'; },\n  mounted(d2){\n    var cv=d2.$('.cv'),ctx=cv.getContext('2d'),N=420,ps=[];\n    function size(){var dpr=window.devicePixelRatio||1;cv.width=cv.clientWidth*dpr;cv.height=cv.clientHeight*dpr;ctx.setTransform(1,0,0,1,0,0);ctx.scale(dpr,dpr);}\n    function init(){ps=[];for(var i=0;i<N;i++)ps.push({x:Math.random()*cv.clientWidth,y:Math.random()*cv.clientHeight,h:Math.random()*60+180});}\n    size();init(); if(typeof ResizeObserver!=='undefined'){var ro=new ResizeObserver(size);ro.observe(cv);d2.onUnmount(function(){ro.disconnect();});}\n    d2.raf(function(t){var w=cv.clientWidth,h=cv.clientHeight;ctx.fillStyle='rgba(10,6,18,.06)';ctx.fillRect(0,0,w,h);for(var i=0;i<N;i++){var p=ps[i],ang=(Math.sin(p.x*0.008)+Math.cos(p.y*0.008)+t*0.0004)*Math.PI*2;p.x+=Math.cos(ang)*1.3;p.y+=Math.sin(ang)*1.3;if(p.x<0)p.x+=w;if(p.x>w)p.x-=w;if(p.y<0)p.y+=h;if(p.y>h)p.y-=h;ctx.fillStyle='hsla('+(p.h+t*0.01)+',85%,65%,.8)';ctx.fillRect(p.x,p.y,1.6,1.6);}});\n  }\n}"}}}}}}}},{"_id":"6a2d7b13ed4fc677c360a77a","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kForceGraph","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `.wrap{height:100%;border:1px solid #EAECF0;border-radius:14px;overflow:hidden;position:relative;background:#0B1020}.cv{width:100%;height:100%;display:block;cursor:grab;touch-action:none}.cap{position:absolute;left:12px;bottom:10px;color:rgba(255,255,255,.5);font:500 11px -apple-system,sans-serif;pointer-events:none}`,\n  render(){ return '<div class=\"wrap\"><canvas class=\"cv\" data-d2-static></canvas><span class=\"cap\">Force-directed graph (arraste)</span></div>'; },\n  mounted(d2){\n    var cv=d2.$('.cv'),ctx=cv.getContext('2d'),N=16,nodes=[],edges=[];\n    function size(){var dpr=window.devicePixelRatio||1;cv.width=cv.clientWidth*dpr;cv.height=cv.clientHeight*dpr;ctx.setTransform(1,0,0,1,0,0);ctx.scale(dpr,dpr);}\n    size(); for(var i=0;i<N;i++)nodes.push({x:Math.random()*cv.clientWidth,y:Math.random()*cv.clientHeight,vx:0,vy:0,h:(i*30)%360});\n    for(var i=1;i<N;i++){edges.push([i,Math.floor(Math.random()*i)]);} for(var k=0;k<5;k++)edges.push([Math.floor(Math.random()*N),Math.floor(Math.random()*N)]);\n    if(typeof ResizeObserver!=='undefined'){var ro=new ResizeObserver(size);ro.observe(cv);d2.onUnmount(function(){ro.disconnect();});}\n    var drag=null;\n    function pos(e){var r=cv.getBoundingClientRect();return [e.clientX-r.left,e.clientY-r.top];}\n    d2.on('.cv','pointerdown',function(e){var p=pos(e),bd=600;drag=null;for(var i=0;i<N;i++){var d=(nodes[i].x-p[0])*(nodes[i].x-p[0])+(nodes[i].y-p[1])*(nodes[i].y-p[1]);if(d<bd){bd=d;drag=i;}}if(cv.setPointerCapture)cv.setPointerCapture(e.pointerId);});\n    d2.on(window,'pointermove',function(e){if(drag==null)return;var p=pos(e);nodes[drag].x=p[0];nodes[drag].y=p[1];nodes[drag].vx=0;nodes[drag].vy=0;});\n    d2.on(window,'pointerup',function(){drag=null;});\n    d2.raf(function(){var w=cv.clientWidth,h=cv.clientHeight,cx=w/2,cy=h/2;\n      for(var i=0;i<N;i++){for(var j=i+1;j<N;j++){var dx=nodes[j].x-nodes[i].x,dy=nodes[j].y-nodes[i].y,d=Math.sqrt(dx*dx+dy*dy)||1,f=900/(d*d);nodes[i].vx-=f*dx/d;nodes[i].vy-=f*dy/d;nodes[j].vx+=f*dx/d;nodes[j].vy+=f*dy/d;}}\n      for(var e=0;e<edges.length;e++){var a=nodes[edges[e][0]],b=nodes[edges[e][1]];if(a===b)continue;var dx=b.x-a.x,dy=b.y-a.y,d=Math.sqrt(dx*dx+dy*dy)||1,f=(d-70)*0.01;a.vx+=f*dx/d;a.vy+=f*dy/d;b.vx-=f*dx/d;b.vy-=f*dy/d;}\n      ctx.fillStyle='#0B1020';ctx.fillRect(0,0,w,h);ctx.strokeStyle='rgba(129,140,248,.3)';ctx.lineWidth=1;ctx.beginPath();for(var e=0;e<edges.length;e++){var a=nodes[edges[e][0]],b=nodes[edges[e][1]];ctx.moveTo(a.x,a.y);ctx.lineTo(b.x,b.y);}ctx.stroke();\n      for(var i=0;i<N;i++){var nd=nodes[i];if(i!==drag){nd.vx+=(cx-nd.x)*0.0006;nd.vy+=(cy-nd.y)*0.0006;nd.vx*=0.85;nd.vy*=0.85;nd.x+=nd.vx;nd.y+=nd.vy;}ctx.fillStyle='hsl('+nd.h+',75%,64%)';ctx.beginPath();ctx.arc(nd.x,nd.y,6,0,6.2832);ctx.fill();}\n    });\n  }\n}"}}}}}}}},{"_id":"6a2d7b1358bb101c90945eb8","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kMandelbrot","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `.wrap{height:100%;border:1px solid #EAECF0;border-radius:14px;overflow:hidden;position:relative;background:#000}.cv{width:100%;height:100%;display:block}.cap{position:absolute;left:12px;bottom:10px;color:rgba(255,255,255,.6);font:500 11px -apple-system,sans-serif;pointer-events:none}`,\n  render(){ return '<div class=\"wrap\"><canvas class=\"cv\" data-d2-static></canvas><span class=\"cap\">Mandelbrot</span></div>'; },\n  mounted(d2){\n    var cv=d2.$('.cv'),ctx=cv.getContext('2d');\n    function draw(){var W=Math.max(1,Math.floor(cv.clientWidth)),H=Math.max(1,Math.floor(cv.clientHeight));cv.width=W;cv.height=H;var img=ctx.createImageData(W,H),data=img.data,maxI=90,cxr=-0.6,cyr=0,scale=3.2/W;\n      for(var py=0;py<H;py++){for(var px=0;px<W;px++){var x0=cxr+(px-W/2)*scale,y0=cyr+(py-H/2)*scale,x=0,y=0,i=0;while(x*x+y*y<=4&&i<maxI){var xt=x*x-y*y+x0;y=2*x*y+y0;x=xt;i++;}var idx=(py*W+px)*4;if(i===maxI){data[idx]=8;data[idx+1]=8;data[idx+2]=18;}else{var hh=(i/maxI);data[idx]=Math.floor(9*(1-hh)*hh*hh*hh*255);data[idx+1]=Math.floor(15*(1-hh)*(1-hh)*hh*hh*255);data[idx+2]=Math.floor(8.5*(1-hh)*(1-hh)*(1-hh)*hh*255);}data[idx+3]=255;}}\n      ctx.putImageData(img,0,0);}\n    draw(); if(typeof ResizeObserver!=='undefined'){var ro=new ResizeObserver(function(){draw();});ro.observe(cv);d2.onUnmount(function(){ro.disconnect();});}\n  }\n}"}}}}}}}},{"_id":"6a2d7b13baacaeb32629246a","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kCube3D","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `.wrap{height:100%;border:1px solid #EAECF0;border-radius:14px;overflow:hidden;position:relative;background:radial-gradient(circle at 50% 40%,#1b1b2e,#0a0a14)}.cv{width:100%;height:100%;display:block}.cap{position:absolute;left:12px;bottom:10px;color:rgba(255,255,255,.5);font:500 11px -apple-system,sans-serif;pointer-events:none}`,\n  render(){ return '<div class=\"wrap\"><canvas class=\"cv\" data-d2-static></canvas><span class=\"cap\">Cubo 3D · wireframe</span></div>'; },\n  mounted(d2){\n    var cv=d2.$('.cv'),ctx=cv.getContext('2d');\n    function size(){var dpr=window.devicePixelRatio||1;cv.width=cv.clientWidth*dpr;cv.height=cv.clientHeight*dpr;ctx.setTransform(1,0,0,1,0,0);ctx.scale(dpr,dpr);}\n    size(); if(typeof ResizeObserver!=='undefined'){var ro=new ResizeObserver(size);ro.observe(cv);d2.onUnmount(function(){ro.disconnect();});}\n    var V=[[-1,-1,-1],[1,-1,-1],[1,1,-1],[-1,1,-1],[-1,-1,1],[1,-1,1],[1,1,1],[-1,1,1]];\n    var E=[[0,1],[1,2],[2,3],[3,0],[4,5],[5,6],[6,7],[7,4],[0,4],[1,5],[2,6],[3,7]];\n    d2.raf(function(t){var w=cv.clientWidth,h=cv.clientHeight,cx=w/2,cy=h/2,S=Math.min(w,h)*0.26,ax=t/1400,ay=t/1000;ctx.clearRect(0,0,w,h);var P=[];for(var i=0;i<8;i++){var x=V[i][0],y=V[i][1],z=V[i][2];var y1=y*Math.cos(ax)-z*Math.sin(ax),z1=y*Math.sin(ax)+z*Math.cos(ax);var x1=x*Math.cos(ay)-z1*Math.sin(ay),z2=x*Math.sin(ay)+z1*Math.cos(ay);var pe=3/(3+z2);P.push([cx+x1*S*pe,cy+y1*S*pe]);}ctx.strokeStyle='#818CF8';ctx.lineWidth=2;ctx.lineJoin='round';ctx.beginPath();for(var e=0;e<E.length;e++){var a=P[E[e][0]],b=P[E[e][1]];ctx.moveTo(a[0],a[1]);ctx.lineTo(b[0],b[1]);}ctx.stroke();for(var i=0;i<8;i++){ctx.fillStyle='#EC4899';ctx.beginPath();ctx.arc(P[i][0],P[i][1],3,0,6.2832);ctx.fill();}});\n  }\n}"}}}}}}}},{"_id":"6a2d7b60ed4fc677c360a7ef","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kGlobe","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `.wrap{height:100%;border:1px solid #EAECF0;border-radius:14px;overflow:hidden;position:relative;background:radial-gradient(circle at 50% 50%,#0d1530,#05060f)}.cv{width:100%;height:100%;display:block}.cap{position:absolute;left:12px;bottom:10px;color:rgba(255,255,255,.5);font:500 11px -apple-system,sans-serif;pointer-events:none}`,\n  render(){ return '<div class=\"wrap\"><canvas class=\"cv\" data-d2-static></canvas><span class=\"cap\">Globo de pontos · 3D</span></div>'; },\n  mounted(d2){\n    var cv=d2.$('.cv'),ctx=cv.getContext('2d'),N=520,pts=[];\n    function size(){var dpr=window.devicePixelRatio||1;cv.width=cv.clientWidth*dpr;cv.height=cv.clientHeight*dpr;ctx.setTransform(1,0,0,1,0,0);ctx.scale(dpr,dpr);}\n    size(); for(var i=0;i<N;i++){var y=1-(i/(N-1))*2,r=Math.sqrt(1-y*y),th=i*2.399963;pts.push([Math.cos(th)*r,y,Math.sin(th)*r]);}\n    if(typeof ResizeObserver!=='undefined'){var ro=new ResizeObserver(size);ro.observe(cv);d2.onUnmount(function(){ro.disconnect();});}\n    d2.raf(function(t){var w=cv.clientWidth,h=cv.clientHeight,cx=w/2,cy=h/2,S=Math.min(w,h)*0.36,ay=t/2200;ctx.clearRect(0,0,w,h);for(var i=0;i<N;i++){var x=pts[i][0],y=pts[i][1],z=pts[i][2];var x1=x*Math.cos(ay)-z*Math.sin(ay),z1=x*Math.sin(ay)+z*Math.cos(ay);var pe=2/(2+z1),sx=cx+x1*S*pe,sy=cy+y*S*pe,al=(z1+1)/2;ctx.fillStyle='rgba('+Math.floor(129+z1*60)+','+Math.floor(140+y*40)+',248,'+(0.25+al*0.75).toFixed(2)+')';ctx.beginPath();ctx.arc(sx,sy,(0.6+al*1.8),0,6.2832);ctx.fill();}});\n  }\n}"}}}}}}}},{"_id":"6a2d7b60dbf815e74e98fb7d","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kSpirograph","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `.wrap{height:100%;border:1px solid #EAECF0;border-radius:14px;overflow:hidden;position:relative;background:#08060f}.cv{width:100%;height:100%;display:block}.cap{position:absolute;left:12px;bottom:10px;color:rgba(255,255,255,.5);font:500 11px -apple-system,sans-serif;pointer-events:none}`,\n  render(){ return '<div class=\"wrap\"><canvas class=\"cv\" data-d2-static></canvas><span class=\"cap\">Spirograph</span></div>'; },\n  mounted(d2){\n    var cv=d2.$('.cv'),ctx=cv.getContext('2d');\n    function size(){var dpr=window.devicePixelRatio||1;cv.width=cv.clientWidth*dpr;cv.height=cv.clientHeight*dpr;ctx.setTransform(1,0,0,1,0,0);ctx.scale(dpr,dpr);ctx.fillStyle='#08060f';ctx.fillRect(0,0,cv.clientWidth,cv.clientHeight);}\n    size(); if(typeof ResizeObserver!=='undefined'){var ro=new ResizeObserver(size);ro.observe(cv);d2.onUnmount(function(){ro.disconnect();});}\n    var a=0,R=1,r=0.27,p=0.75,prev=null,steps=0;\n    d2.raf(function(t){var w=cv.clientWidth,h=cv.clientHeight,cx=w/2,cy=h/2,S=Math.min(w,h)*0.42;for(var k=0;k<6;k++){a+=0.06;var x=cx+S*((R-r)*Math.cos(a)+p*r*Math.cos((R-r)/r*a));var y=cy+S*((R-r)*Math.sin(a)-p*r*Math.sin((R-r)/r*a));if(prev){ctx.strokeStyle='hsl('+((a*12)%360)+',85%,62%)';ctx.lineWidth=1.2;ctx.beginPath();ctx.moveTo(prev[0],prev[1]);ctx.lineTo(x,y);ctx.stroke();}prev=[x,y];steps++;}if(steps>2600){ctx.fillStyle='rgba(8,6,15,.5)';ctx.fillRect(0,0,w,h);steps=0;}});\n  }\n}"}}}}}}}},{"_id":"6a2d7b60ed4fc677c360a7f6","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kClock","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `.wrap{height:100%;border:1px solid #EAECF0;border-radius:14px;overflow:hidden;position:relative;background:#fff;display:flex;align-items:center;justify-content:center}.cv{width:100%;height:100%;display:block}.cap{position:absolute;left:12px;bottom:10px;color:#98A2B3;font:500 11px -apple-system,sans-serif;pointer-events:none}`,\n  render(){ return '<div class=\"wrap\"><canvas class=\"cv\" data-d2-static></canvas><span class=\"cap\">Relógio · ao vivo</span></div>'; },\n  mounted(d2){\n    var cv=d2.$('.cv'),ctx=cv.getContext('2d');\n    function size(){var dpr=window.devicePixelRatio||1;cv.width=cv.clientWidth*dpr;cv.height=cv.clientHeight*dpr;ctx.setTransform(1,0,0,1,0,0);ctx.scale(dpr,dpr);}\n    size(); if(typeof ResizeObserver!=='undefined'){var ro=new ResizeObserver(size);ro.observe(cv);d2.onUnmount(function(){ro.disconnect();});}\n    d2.raf(function(){var w=cv.clientWidth,h=cv.clientHeight,cx=w/2,cy=h/2,R=Math.min(w,h)*0.42;ctx.clearRect(0,0,w,h);ctx.strokeStyle='#EAECF0';ctx.lineWidth=2;ctx.beginPath();ctx.arc(cx,cy,R,0,6.2832);ctx.stroke();for(var i=0;i<12;i++){var a=i/12*6.2832-Math.PI/2;ctx.strokeStyle='#101828';ctx.lineWidth=i%3===0?2.5:1;ctx.beginPath();ctx.moveTo(cx+Math.cos(a)*R*0.86,cy+Math.sin(a)*R*0.86);ctx.lineTo(cx+Math.cos(a)*R*0.96,cy+Math.sin(a)*R*0.96);ctx.stroke();}var d=new Date(),ms=d.getMilliseconds()/1000,s=(d.getSeconds()+ms),m=d.getMinutes()+s/60,hr=(d.getHours()%12)+m/60;function hand(ang,len,wd,col){ang=ang-Math.PI/2;ctx.strokeStyle=col;ctx.lineWidth=wd;ctx.lineCap='round';ctx.beginPath();ctx.moveTo(cx,cy);ctx.lineTo(cx+Math.cos(ang)*len,cy+Math.sin(ang)*len);ctx.stroke();}hand(hr/12*6.2832,R*0.5,5,'#101828');hand(m/60*6.2832,R*0.72,3.5,'#475467');hand(s/60*6.2832,R*0.82,1.5,'#F04438');ctx.fillStyle='#F04438';ctx.beginPath();ctx.arc(cx,cy,4,0,6.2832);ctx.fill();});\n  }\n}"}}}}}}}},{"_id":"6a2d7b617938117e38f3087e","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kRipples","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `.wrap{height:100%;border:1px solid #EAECF0;border-radius:14px;overflow:hidden;position:relative;background:#06121f}.cv{width:100%;height:100%;display:block;cursor:pointer}.cap{position:absolute;left:12px;bottom:10px;color:rgba(255,255,255,.5);font:500 11px -apple-system,sans-serif;pointer-events:none}`,\n  render(){ return '<div class=\"wrap\"><canvas class=\"cv\" data-d2-static></canvas><span class=\"cap\">Ondas · clique na água</span></div>'; },\n  mounted(d2){\n    var cv=d2.$('.cv'),ctx=cv.getContext('2d'),rips=[];\n    function size(){var dpr=window.devicePixelRatio||1;cv.width=cv.clientWidth*dpr;cv.height=cv.clientHeight*dpr;ctx.setTransform(1,0,0,1,0,0);ctx.scale(dpr,dpr);}\n    size(); if(typeof ResizeObserver!=='undefined'){var ro=new ResizeObserver(size);ro.observe(cv);d2.onUnmount(function(){ro.disconnect();});}\n    function add(x,y){rips.push({x:x,y:y,r:0,life:1,hue:180+Math.random()*60});}\n    d2.on('.cv','pointerdown',function(e){var r=cv.getBoundingClientRect();add(e.clientX-r.left,e.clientY-r.top);});\n    var last=0;\n    d2.raf(function(t){var w=cv.clientWidth,h=cv.clientHeight;if(t-last>1300){last=t;add(Math.random()*w,Math.random()*h);}ctx.fillStyle='rgba(6,18,31,.12)';ctx.fillRect(0,0,w,h);for(var i=rips.length-1;i>=0;i--){var rp=rips[i];rp.r+=2.2;rp.life-=0.012;if(rp.life<=0){rips.splice(i,1);continue;}for(var k=0;k<3;k++){ctx.strokeStyle='hsla('+rp.hue+',80%,65%,'+(rp.life*0.5).toFixed(2)+')';ctx.lineWidth=1.4;ctx.beginPath();ctx.arc(rp.x,rp.y,Math.max(0,rp.r-k*9),0,6.2832);ctx.stroke();}}});\n  }\n}"}}}}}}}},{"_id":"6a2d7b611b7164341d2ee332","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kAudioBars","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `.wrap{height:100%;border:1px solid #EAECF0;border-radius:14px;overflow:hidden;position:relative;background:#0a0a16}.cv{width:100%;height:100%;display:block}.cap{position:absolute;left:12px;top:10px;color:rgba(255,255,255,.5);font:500 11px -apple-system,sans-serif;pointer-events:none}`,\n  render(){ return '<div class=\"wrap\"><canvas class=\"cv\" data-d2-static></canvas><span class=\"cap\">Visualizer</span></div>'; },\n  mounted(d2){\n    var cv=d2.$('.cv'),ctx=cv.getContext('2d'),N=42;\n    function size(){var dpr=window.devicePixelRatio||1;cv.width=cv.clientWidth*dpr;cv.height=cv.clientHeight*dpr;ctx.setTransform(1,0,0,1,0,0);ctx.scale(dpr,dpr);}\n    size(); if(typeof ResizeObserver!=='undefined'){var ro=new ResizeObserver(size);ro.observe(cv);d2.onUnmount(function(){ro.disconnect();});}\n    d2.raf(function(t){var w=cv.clientWidth,h=cv.clientHeight;ctx.clearRect(0,0,w,h);var bw=w/N,T=t/1000;for(var i=0;i<N;i++){var v=(Math.sin(T*4+i*0.5)*0.5+0.5)*(Math.sin(T*1.7+i*0.3)*0.3+0.7)*(Math.sin(T*9+i)*0.2+0.8);var bh=v*h*0.82,x=i*bw,y=h-bh;var g=ctx.createLinearGradient(0,y,0,h);g.addColorStop(0,'hsl('+(200+i*4)+',90%,65%)');g.addColorStop(1,'hsl('+(280+i*4)+',90%,55%)');ctx.fillStyle=g;ctx.fillRect(x+1.5,y,bw-3,bh);ctx.fillStyle='hsla('+(200+i*4)+',90%,75%,.5)';ctx.fillRect(x+1.5,y-3,bw-3,3);}});\n  }\n}"}}}}}}}},{"_id":"6a2d7b61911a2eb6b8169e9d","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kPlasma","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `.wrap{height:100%;border:1px solid #EAECF0;border-radius:14px;overflow:hidden;position:relative;background:#000}.cv{width:100%;height:100%;display:block;image-rendering:pixelated}.cap{position:absolute;left:12px;bottom:10px;color:rgba(255,255,255,.6);font:500 11px -apple-system,sans-serif;pointer-events:none}`,\n  render(){ return '<div class=\"wrap\"><canvas class=\"cv\" width=\"110\" height=\"80\" data-d2-static></canvas><span class=\"cap\">Plasma</span></div>'; },\n  mounted(d2){\n    var cv=d2.$('.cv'),ctx=cv.getContext('2d'),W=110,H=80,img=ctx.createImageData(W,H),data=img.data,last=0;\n    d2.raf(function(t){if(t-last<33)return;last=t;var tt=t/1000;for(var y=0;y<H;y++){for(var x=0;x<W;x++){var v=Math.sin(x/16+tt)+Math.sin(y/12+tt*1.3)+Math.sin((x+y)/16+tt)+Math.sin(Math.sqrt((x-W/2)*(x-W/2)+(y-H/2)*(y-H/2))/10-tt*1.6);var idx=(y*W+x)*4;data[idx]=Math.floor(128+127*Math.sin(v*Math.PI));data[idx+1]=Math.floor(128+127*Math.sin(v*Math.PI+2.094));data[idx+2]=Math.floor(128+127*Math.sin(v*Math.PI+4.188));data[idx+3]=255;}}ctx.putImageData(img,0,0);});\n  }\n}"}}}}}}}},{"_id":"6a2d7bc7911a2eb6b8169f49","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kCalendar","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `.wrap{height:100%;box-sizing:border-box;background:#fff;border:1px solid #EAECF0;border-radius:14px;padding:16px 18px;display:flex;flex-direction:column;gap:10px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;box-shadow:0 1px 2px rgba(16,24,40,.05)}\n    .hd{display:flex;align-items:center;justify-content:space-between}.hd .mo{font-size:14px;font-weight:600;color:#101828}.hd button{width:26px;height:26px;border:1px solid #EAECF0;background:#fff;border-radius:7px;cursor:pointer;color:#475467}.hd button:hover{background:#F9FAFB}\n    .grid{flex:1;display:grid;grid-template-columns:repeat(7,1fr);grid-auto-rows:1fr;gap:3px}\n    .dow{font-size:10px;font-weight:600;color:#98A2B3;text-align:center;text-transform:uppercase}\n    .day{display:flex;align-items:center;justify-content:center;font-size:12.5px;color:#344054;border-radius:8px;cursor:pointer}.day:hover{background:#F2F4F7}.day.today{background:#6366F1;color:#fff;font-weight:700}.day.sel{outline:2px solid #6366F1}.day.empty{cursor:default}`,\n  render(d2){\n    var now=new Date();var y=d2.state.y==null?now.getFullYear():d2.state.y,m=d2.state.m==null?now.getMonth():d2.state.m;\n    var MON=['Janeiro','Fevereiro','Março','Abril','Maio','Junho','Julho','Agosto','Setembro','Outubro','Novembro','Dezembro'];\n    var first=new Date(y,m,1).getDay(),dim=new Date(y,m+1,0).getDate();\n    var cells=['D','S','T','Q','Q','S','S'].map(function(d){return '<div class=\"dow\">'+d+'</div>';});\n    for(var i=0;i<first;i++)cells.push('<div class=\"day empty\"></div>');\n    for(var d=1;d<=dim;d++){var isT=(y===now.getFullYear()&&m===now.getMonth()&&d===now.getDate()),isS=d2.state.sel===d;cells.push('<div class=\"day'+(isT?' today':'')+(isS&&!isT?' sel':'')+'\" data-d=\"'+d+'\">'+d+'</div>');}\n    return '<div class=\"wrap\"><div class=\"hd\"><button data-prev>‹</button><span class=\"mo\">'+MON[m]+' '+y+'</span><button data-next>›</button></div><div class=\"grid\">'+cells.join('')+'</div></div>';\n  },\n  mounted(d2){\n    function shift(dir){var now=new Date();var y=d2.state.y==null?now.getFullYear():d2.state.y,m=(d2.state.m==null?now.getMonth():d2.state.m)+dir;if(m<0){m=11;y--;}if(m>11){m=0;y++;}d2.state.y=y;d2.state.m=m;}\n    d2.on('[data-prev]','click',function(){shift(-1);});\n    d2.on('[data-next]','click',function(){shift(1);});\n    d2.on('[data-d]','click',function(e,el){d2.state.sel=+el.getAttribute('data-d');});\n  }\n}"}}}}}}}},{"_id":"6a2d7bc7ed4fc677c360a87f","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kMarkdown","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;'}[c];});}\nfunction md(src){var out=[],lines=String(src).split('\\n'),inList=false;\n  function inline(t){return t.replace(/\\*\\*([^*]+)\\*\\*/g,'<b>$1</b>').replace(/\\*([^*]+)\\*/g,'<i>$1</i>').replace(/`([^`]+)`/g,'<code>$1</code>').replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g,'<a href=\"$2\">$1</a>');}\n  for(var i=0;i<lines.length;i++){var l=esc(lines[i]);\n    if(/^### /.test(l)){if(inList){out.push('</ul>');inList=false;}out.push('<h3>'+inline(l.slice(4))+'</h3>');}\n    else if(/^## /.test(l)){if(inList){out.push('</ul>');inList=false;}out.push('<h2>'+inline(l.slice(3))+'</h2>');}\n    else if(/^# /.test(l)){if(inList){out.push('</ul>');inList=false;}out.push('<h1>'+inline(l.slice(2))+'</h1>');}\n    else if(/^[-*] /.test(l)){if(!inList){out.push('<ul>');inList=true;}out.push('<li>'+inline(l.slice(2))+'</li>');}\n    else if(l.trim()===''){if(inList){out.push('</ul>');inList=false;}}\n    else{if(inList){out.push('</ul>');inList=false;}out.push('<p>'+inline(l)+'</p>');}}\n  if(inList)out.push('</ul>');return out.join('');}\nexport default {\n  css: `.wrap{height:100%;box-sizing:border-box;background:#fff;border:1px solid #EAECF0;border-radius:14px;overflow:hidden;display:flex;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;box-shadow:0 1px 2px rgba(16,24,40,.05)}\n    .ed{flex:1;border:none;outline:none;resize:none;padding:14px;font:13px/1.5 ui-monospace,SFMono-Regular,Menlo,monospace;color:#344054;background:#FCFCFD;border-right:1px solid #F2F4F7}\n    .pv{flex:1;overflow:auto;padding:6px 16px;color:#101828}\n    .pv h1{font-size:20px;margin:10px 0 6px}.pv h2{font-size:16px;margin:10px 0 6px}.pv h3{font-size:14px;margin:8px 0 4px}.pv p{font-size:13px;line-height:1.55;margin:6px 0;color:#475467}.pv ul{margin:6px 0;padding-left:20px}.pv li{font-size:13px;color:#475467;margin:2px 0}.pv code{background:#F2F4F7;padding:1px 5px;border-radius:4px;font-size:12px;font-family:ui-monospace,Menlo,monospace}.pv a{color:#6366F1}.pv b{color:#101828}`,\n  render(d2){\n    var src=d2.state.src==null?'# Markdown ao vivo\\n\\nDigite à **esquerda**, veja o preview à *direita*.\\n\\n## Recursos\\n- Listas\\n- `código inline`\\n- [links](https://data2.app)\\n\\nTudo via d2.state + parser próprio.':d2.state.src;\n    return '<div class=\"wrap\"><textarea class=\"ed\" data-src>'+esc(src)+'</textarea><div class=\"pv\">'+md(src)+'</div></div>';\n  },\n  mounted(d2){\n    d2.on('[data-src]','input',function(e,el){d2.state.src=el.value;});\n  }\n}"}}}}}}}},{"_id":"6a2d7bc79b58f90d1c22ed86","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kOrgChart","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"var TREE={n:'CEO',c:[{n:'CTO',c:[{n:'Eng Lead',c:[{n:'Dev'},{n:'Dev'}]},{n:'QA'}]},{n:'CFO',c:[{n:'Contábil'}]},{n:'CMO',c:[{n:'Growth'},{n:'Design'}]}]};\nfunction node(n){var kids=n.c&&n.c.length?'<div class=\"kids\">'+n.c.map(node).join('')+'</div>':'';return '<div class=\"li\"><div class=\"card\">'+n.n+'</div>'+kids+'</div>';}\nexport default {\n  css: `.wrap{height:100%;box-sizing:border-box;background:#fff;border:1px solid #EAECF0;border-radius:14px;padding:16px;overflow:auto;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;box-shadow:0 1px 2px rgba(16,24,40,.05)}\n    .tree{display:flex;justify-content:center;min-width:100%}\n    .li{display:flex;flex-direction:column;align-items:center;position:relative;padding:14px 8px 0}\n    .li::before{content:'';position:absolute;top:0;left:50%;width:1px;height:14px;background:#D0D5DD}\n    .tree>.li::before{display:none}\n    .card{background:linear-gradient(135deg,#EEF2FF,#fff);border:1px solid #C7D2FE;border-radius:9px;padding:7px 13px;font-size:12.5px;font-weight:600;color:#3730A3;white-space:nowrap;box-shadow:0 1px 2px rgba(16,24,40,.05)}\n    .kids{display:flex;position:relative;padding-top:14px}\n    .kids::before{content:'';position:absolute;top:0;left:0;right:0;height:1px;background:#D0D5DD;margin:0 50%}\n    .kids>.li::after{content:'';position:absolute;top:0;left:0;right:0;height:14px}`,\n  render(d2){ return '<div class=\"wrap\"><div class=\"tree\">'+node(TREE)+'</div></div>'; }\n}"}}}}}}}},{"_id":"6a2d7bc8baacaeb32629254c","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kBeforeAfter","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `.wrap{height:100%;border:1px solid #EAECF0;border-radius:14px;overflow:hidden;position:relative;background:#000;cursor:ew-resize;touch-action:none;user-select:none}\n    .wrap img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;pointer-events:none}\n    .top{clip-path:inset(0 var(--clip) 0 0)}\n    .div{position:absolute;top:0;bottom:0;width:2px;background:#fff;box-shadow:0 0 8px rgba(0,0,0,.4);pointer-events:none}\n    .knob{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:32px;height:32px;border-radius:50%;background:#fff;box-shadow:0 2px 8px rgba(0,0,0,.3);display:flex;align-items:center;justify-content:center;color:#475467;font-size:13px}\n    .tag{position:absolute;top:10px;font:600 11px -apple-system,sans-serif;color:#fff;background:rgba(0,0,0,.5);padding:3px 8px;border-radius:6px;pointer-events:none}`,\n  render(d2){\n    var pos=d2.state.pos==null?50:d2.state.pos;\n    return '<div class=\"wrap\" data-wrap style=\"--clip:'+(100-pos)+'%\"><img src=\"https://picsum.photos/seed/d2labx/640/420\"/><img class=\"top\" src=\"https://picsum.photos/seed/d2labx/640/420?grayscale\"/><span class=\"tag\" style=\"left:10px\">P&B</span><span class=\"tag\" style=\"right:10px\">Cor</span><div class=\"div\" style=\"left:'+pos+'%\"></div><div class=\"knob\" style=\"left:'+pos+'%\">↔</div></div>';\n  },\n  mounted(d2){\n    var drag=false;\n    function set(x){var w=d2.$('[data-wrap]');if(!w)return;var r=w.getBoundingClientRect();d2.state.pos=Math.max(0,Math.min(100,(x-r.left)/r.width*100));}\n    d2.on('[data-wrap]','pointerdown',function(e){drag=true;set(e.clientX);});\n    d2.on(window,'pointermove',function(e){if(drag)set(e.clientX);});\n    d2.on(window,'pointerup',function(){drag=false;});\n  }\n}"}}}}}}}},{"_id":"6a2d7bc861efae759d5cf18b","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kCoverflow","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"var ITEMS=[{e:'🎧',c:'#6366F1'},{e:'🎸',c:'#EC4899'},{e:'🎹',c:'#F59E0B'},{e:'🥁',c:'#22C55E'},{e:'🎺',c:'#06B6D4'},{e:'🎻',c:'#8B5CF6'},{e:'🎤',c:'#F04438'}];\nexport default {\n  css: `.wrap{height:100%;border:1px solid #EAECF0;border-radius:14px;overflow:hidden;position:relative;background:linear-gradient(180deg,#1a1a2e,#0d0d18);display:flex;align-items:center;justify-content:center;perspective:900px}\n    .stage{position:relative;width:100%;height:60%;transform-style:preserve-3d}\n    .cd{position:absolute;top:50%;left:50%;width:120px;height:120px;margin:-60px;border-radius:16px;display:flex;align-items:center;justify-content:center;font-size:54px;box-shadow:0 12px 30px rgba(0,0,0,.5);transition:transform .4s cubic-bezier(.2,.8,.2,1),opacity .4s;cursor:pointer}\n    .nav{position:absolute;bottom:14px;left:50%;transform:translateX(-50%);display:flex;gap:8px}\n    .nav button{width:30px;height:30px;border-radius:50%;border:1px solid rgba(255,255,255,.25);background:rgba(255,255,255,.1);color:#fff;cursor:pointer;font-size:14px}\n    .nav button:hover{background:rgba(255,255,255,.2)}`,\n  render(d2){\n    var idx=d2.state.idx==null?Math.floor(ITEMS.length/2):d2.state.idx;\n    var cards=ITEMS.map(function(it,i){var off=i-idx,abs=Math.abs(off);var tf='translateX('+(off*60)+'px) translateZ('+(-abs*120)+'px) rotateY('+(off*-42)+'deg)';return '<div class=\"cd\" data-i=\"'+i+'\" style=\"background:linear-gradient(135deg,'+it.c+',#222);transform:'+tf+';opacity:'+(abs>2.5?0:1-abs*0.18)+';z-index:'+(100-abs)+'\">'+it.e+'</div>';}).join('');\n    return '<div class=\"wrap\"><div class=\"stage\">'+cards+'</div><div class=\"nav\"><button data-prev>‹</button><button data-next>›</button></div></div>';\n  },\n  mounted(d2){\n    function go(d){var idx=d2.state.idx==null?Math.floor(ITEMS.length/2):d2.state.idx;d2.state.idx=Math.max(0,Math.min(ITEMS.length-1,idx+d));}\n    d2.on('[data-prev]','click',function(){go(-1);});\n    d2.on('[data-next]','click',function(){go(1);});\n    d2.on('[data-i]','click',function(e,el){d2.state.idx=+el.getAttribute('data-i');});\n  }\n}"}}}}}}}},{"_id":"6a2d7bc89b58f90d1c22ed8d","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kRadialMenu","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"var ITEMS=[{i:'✏️',l:'Editar'},{i:'🗑️',l:'Excluir'},{i:'📋',l:'Copiar'},{i:'🔗',l:'Link'},{i:'⭐',l:'Favoritar'},{i:'📤',l:'Enviar'}];\nexport default {\n  css: `.wrap{height:100%;border:1px solid #EAECF0;border-radius:14px;overflow:hidden;position:relative;background:#0f1424;display:flex;align-items:center;justify-content:center}\n    .center{position:relative;width:0;height:0}\n    .fab{position:absolute;left:-28px;top:-28px;width:56px;height:56px;border-radius:50%;border:none;background:linear-gradient(135deg,#6366F1,#8B5CF6);color:#fff;font-size:24px;cursor:pointer;box-shadow:0 6px 18px rgba(99,102,241,.5);transition:transform .3s;z-index:5}\n    .fab.open{transform:rotate(135deg)}\n    .item{position:absolute;left:-22px;top:-22px;width:44px;height:44px;border-radius:50%;background:#fff;border:1px solid #EAECF0;display:flex;align-items:center;justify-content:center;font-size:18px;cursor:pointer;box-shadow:0 3px 10px rgba(0,0,0,.3);transition:transform .35s cubic-bezier(.2,.9,.3,1.2),opacity .3s;opacity:0}\n    .item:hover{background:#EEF2FF}\n    .lbl{position:absolute;left:50%;bottom:16px;transform:translateX(-50%);color:#A5B4FC;font:500 12px -apple-system,sans-serif}`,\n  render(d2){\n    var open=d2.state.open,R=92;\n    var items=ITEMS.map(function(it,i){var a=(-Math.PI/2)-(i-(ITEMS.length-1)/2)*(Math.PI/(ITEMS.length-1))* -1;var ang=Math.PI+ (i/(ITEMS.length-1))*Math.PI;var x=open?Math.cos(ang)*R:0,y=open?Math.sin(ang)*R:0;return '<button class=\"item\" data-i=\"'+i+'\" title=\"'+it.l+'\" style=\"transform:translate('+x.toFixed(0)+'px,'+y.toFixed(0)+'px);opacity:'+(open?1:0)+';transition-delay:'+(open?i*0.04:0)+'s\">'+it.i+'</button>';}).join('');\n    var lbl=d2.state.last?'<div class=\"lbl\">última ação: '+d2.state.last+'</div>':'<div class=\"lbl\">toque no +</div>';\n    return '<div class=\"wrap\"><div class=\"center\">'+items+'<button class=\"fab'+(open?' open':'')+'\" data-fab>+</button></div>'+lbl+'</div>';\n  },\n  mounted(d2){\n    d2.on('[data-fab]','click',function(){d2.state.open=!d2.state.open;});\n    d2.on('[data-i]','click',function(e,el){d2.state.last=ITEMS[+el.getAttribute('data-i')].l;d2.state.open=false;});\n  }\n}"}}}}}}}},{"_id":"6a2d7c33911a2eb6b816a00d","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kWizard","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"var STEPS=[{t:'Conta',d:'Dados de acesso'},{t:'Perfil',d:'Sobre você'},{t:'Plano',d:'Escolha do plano'},{t:'Revisão',d:'Confirme tudo'}];\nexport default {\n  css: `.wrap{height:100%;box-sizing:border-box;background:#fff;border:1px solid #EAECF0;border-radius:14px;padding:20px;display:flex;flex-direction:column;gap:16px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;box-shadow:0 1px 2px rgba(16,24,40,.05)}\n    .steps{display:flex;align-items:center}\n    .st{display:flex;flex-direction:column;align-items:center;gap:5px;flex:0 0 auto}\n    .dot{width:30px;height:30px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:13px;font-weight:700;background:#F2F4F7;color:#98A2B3;border:2px solid #F2F4F7;transition:.2s}\n    .dot.on{background:#6366F1;color:#fff;border-color:#6366F1}.dot.done{background:#ECFDF3;color:#027A48;border-color:#ABEFC6}\n    .stl{font-size:10px;color:#98A2B3;font-weight:600}.st.on .stl{color:#6366F1}\n    .bar{flex:1;height:2px;background:#F2F4F7;margin:0 4px;margin-bottom:18px}.bar.done{background:#6366F1}\n    .body{flex:1;display:flex;flex-direction:column;justify-content:center;gap:6px}.body h3{margin:0;font-size:18px;color:#101828}.body p{margin:0;font-size:13px;color:#667085}\n    .nav{display:flex;justify-content:space-between}\n    .nav button{padding:9px 18px;border-radius:9px;font:inherit;font-size:13px;font-weight:600;cursor:pointer;border:1px solid #EAECF0;background:#fff;color:#475467}\n    .nav button.pri{background:#6366F1;color:#fff;border-color:#6366F1}.nav button:disabled{opacity:.4;cursor:default}`,\n  render(d2){\n    var s=d2.state.step||0;\n    var steps='';for(var i=0;i<STEPS.length;i++){steps+='<div class=\"st'+(i===s?' on':'')+'\"><div class=\"dot'+(i===s?' on':'')+(i<s?' done':'')+'\">'+(i<s?'✓':(i+1))+'</div><span class=\"stl\">'+STEPS[i].t+'</span></div>';if(i<STEPS.length-1)steps+='<div class=\"bar'+(i<s?' done':'')+'\"></div>';}\n    var done=s>=STEPS.length;\n    var body=done?'<h3>✅ Tudo pronto!</h3><p>Onboarding concluído com sucesso.</p>':'<h3>'+STEPS[s].t+'</h3><p>'+STEPS[s].d+'</p>';\n    return '<div class=\"wrap\"><div class=\"steps\">'+steps+'</div><div class=\"body\">'+body+'</div><div class=\"nav\"><button data-back '+(s===0?'disabled':'')+'>Voltar</button><button class=\"pri\" data-next>'+(s>=STEPS.length-1?'Concluir':'Avançar')+'</button></div></div>';\n  },\n  mounted(d2){\n    d2.on('[data-back]','click',function(){d2.state.step=Math.max(0,(d2.state.step||0)-1);});\n    d2.on('[data-next]','click',function(){d2.state.step=Math.min(STEPS.length,(d2.state.step||0)+1);});\n  }\n}"}}}}}}}},{"_id":"6a2d7c34ed4fc677c360a953","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kTagInput","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>\"]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c];});}\nvar SUGG=['React','Vue','Svelte','Angular','Node.js','Deno','Rust','Go','Python','TypeScript','GraphQL','PostgreSQL','MongoDB','Redis','Docker','Kubernetes'];\nexport default {\n  css: `.wrap{height:100%;box-sizing:border-box;background:#fff;border:1px solid #EAECF0;border-radius:14px;padding:18px;display:flex;flex-direction:column;gap:8px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;box-shadow:0 1px 2px rgba(16,24,40,.05)}\n    .title{font-size:13px;font-weight:600;color:#101828}\n    .field{display:flex;flex-wrap:wrap;gap:6px;align-items:center;border:1px solid #E4E7EC;border-radius:10px;padding:8px;min-height:24px}.field:focus-within{border-color:#6366F1;box-shadow:0 0 0 3px rgba(99,102,241,.1)}\n    .tag{display:inline-flex;align-items:center;gap:5px;background:#EEF2FF;color:#3730A3;font-size:12px;font-weight:600;padding:4px 4px 4px 9px;border-radius:7px}\n    .tag b{cursor:pointer;width:15px;height:15px;border-radius:4px;display:flex;align-items:center;justify-content:center;background:rgba(55,48,163,.12)}\n    .field input{flex:1;min-width:80px;border:none;outline:none;font:inherit;font-size:13px;padding:3px}\n    .sugg{display:flex;flex-wrap:wrap;gap:6px}\n    .chip{font-size:12px;color:#475467;background:#F2F4F7;padding:4px 10px;border-radius:7px;cursor:pointer}.chip:hover{background:#E4E7EC}`,\n  render(d2){\n    var tags=d2.state.tags||['React','TypeScript'],q=d2.state.q||'';\n    var tagh=tags.map(function(t,i){return '<span class=\"tag\">'+esc(t)+'<b data-rm=\"'+i+'\">×</b></span>';}).join('');\n    var avail=SUGG.filter(function(s){return tags.indexOf(s)<0&&(!q||s.toLowerCase().indexOf(q.toLowerCase())>=0);}).slice(0,8);\n    var sugg=avail.map(function(s){return '<span class=\"chip\" data-add=\"'+esc(s)+'\">+ '+esc(s)+'</span>';}).join('');\n    return '<div class=\"wrap\"><div class=\"title\">Tecnologias</div><div class=\"field\" data-field>'+tagh+'<input data-q placeholder=\"digite e Enter…\" value=\"'+esc(q)+'\"/></div><div class=\"sugg\">'+sugg+'</div></div>';\n  },\n  mounted(d2){\n    function add(t){t=(t||'').trim();if(!t)return;var tags=(d2.state.tags||['React','TypeScript']).slice();if(tags.indexOf(t)<0)tags.push(t);d2.state.tags=tags;d2.state.q='';}\n    d2.on('[data-q]','input',function(e,el){d2.state.q=el.value;});\n    d2.on('[data-q]','keydown',function(e,el){if(e.key==='Enter')add(el.value);else if(e.key==='Backspace'&&!el.value){var tags=(d2.state.tags||[]).slice();tags.pop();d2.state.tags=tags;}});\n    d2.on('[data-add]','click',function(e,el){add(el.getAttribute('data-add'));});\n    d2.on('[data-rm]','click',function(e,el){var tags=(d2.state.tags||[]).slice();tags.splice(+el.getAttribute('data-rm'),1);d2.state.tags=tags;});\n  }\n}"}}}}}}}},{"_id":"6a2d7c34baacaeb3262925f5","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kVirtualList","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"var N=10000,RH=36;\nexport default {\n  css: `.wrap{height:100%;box-sizing:border-box;background:#fff;border:1px solid #EAECF0;border-radius:14px;display:flex;flex-direction:column;overflow:hidden;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;box-shadow:0 1px 2px rgba(16,24,40,.05)}\n    .hd{padding:13px 16px;border-bottom:1px solid #F2F4F7;font-size:13px;font-weight:600;color:#101828;display:flex;justify-content:space-between}.hd span{color:#98A2B3;font-weight:500;font-size:12px}\n    .vp{flex:1;overflow-y:auto;position:relative}\n    .spacer{position:relative;width:100%}\n    .row{position:absolute;left:0;right:0;height:36px;display:flex;align-items:center;gap:10px;padding:0 16px;border-bottom:1px solid #F9FAFB;box-sizing:border-box}\n    .av{width:22px;height:22px;border-radius:50%;flex:0 0 auto;font-size:10px;font-weight:700;color:#fff;display:flex;align-items:center;justify-content:center}\n    .nm{font-size:13px;color:#101828}.id{margin-left:auto;font-size:11px;color:#98A2B3;font-variant-numeric:tabular-nums}`,\n  render(d2){\n    var scroll=d2.state.scroll||0,vh=d2.state.vh||320;\n    var start=Math.max(0,Math.floor(scroll/RH)-6),end=Math.min(N,Math.ceil((scroll+vh)/RH)+6);\n    var rows='';for(var i=start;i<end;i++){var hue=(i*53)%360;rows+='<div class=\"row\" data-key=\"r'+i+'\" style=\"top:'+(i*RH)+'px\"><span class=\"av\" style=\"background:hsl('+hue+',60%,55%)\">'+((i%97)+1)+'</span><span class=\"nm\">Registro #'+(i+1)+'</span><span class=\"id\">'+i.toString(16).toUpperCase()+'</span></div>';}\n    return '<div class=\"wrap\"><div class=\"hd\">Lista virtual <span>'+N.toLocaleString('pt-BR')+' itens · só ~30 no DOM</span></div><div class=\"vp\" data-vp><div class=\"spacer\" style=\"height:'+(N*RH)+'px\">'+rows+'</div></div></div>';\n  },\n  mounted(d2){\n    var vp=d2.$('[data-vp]');\n    if(vp){ d2.state.vh=vp.clientHeight||320; d2.on(vp,'scroll',function(){ d2.state.scroll=vp.scrollTop; d2.state.vh=vp.clientHeight; }); }\n  },\n  updated(d2){ if(!d2.state.vh){ var vp=d2.$('[data-vp]'); if(vp&&vp.clientHeight) d2.state.vh=vp.clientHeight; } }\n}"}}}}}}}},{"_id":"6a2d7c34dbf815e74e98fcc2","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kTerminal","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;'}[c];});}\nexport default {\n  css: `.wrap{height:100%;box-sizing:border-box;background:#0c0f1a;border:1px solid #EAECF0;border-radius:14px;display:flex;flex-direction:column;overflow:hidden;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;box-shadow:0 1px 2px rgba(16,24,40,.05)}\n    .bar{display:flex;gap:6px;padding:10px 12px;border-bottom:1px solid #1c2233}.bar i{width:11px;height:11px;border-radius:50%;display:block}\n    .scr{flex:1;overflow:auto;padding:12px;font-size:12.5px;line-height:1.5}\n    .ln{white-space:pre-wrap;word-break:break-word}.cmd{color:#9bdcff}.out{color:#cfd6e0}.err{color:#ff8585}.dim{color:#5b6577}\n    .inl{display:flex;align-items:center;gap:8px;padding:0 12px 12px}\n    .ps{color:#7CFFB2}.inl input{flex:1;background:none;border:none;outline:none;color:#e6edf3;font:inherit;font-size:12.5px}`,\n  render(d2){\n    var lines=d2.state.lines||[{t:'dim',x:'data2 shell v1.0 — digite \"help\"'}];\n    var body=lines.map(function(l){return '<div class=\"ln '+l.t+'\">'+esc(l.x)+'</div>';}).join('');\n    return '<div class=\"wrap\"><div class=\"bar\"><i style=\"background:#ff5f56\"></i><i style=\"background:#ffbd2e\"></i><i style=\"background:#27c93f\"></i></div><div class=\"scr\" data-scr>'+body+'</div><div class=\"inl\"><span class=\"ps\">❯</span><input data-cmd autofocus value=\"'+esc(d2.state.cmd||'')+'\"/></div></div>';\n  },\n  mounted(d2){\n    function run(raw){var cmd=(raw||'').trim();var lines=(d2.state.lines||[]).slice();lines.push({t:'cmd',x:'❯ '+cmd});var a=cmd.split(/\\s+/),c=a[0];\n      if(c==='help')lines.push({t:'out',x:'comandos: help, ls, date, whoami, echo <txt>, about, clear'});\n      else if(c==='ls')lines.push({t:'out',x:'dashboard/  components/  lab/  README.md'});\n      else if(c==='date')lines.push({t:'out',x:new Date().toString()});\n      else if(c==='whoami')lines.push({t:'out',x:'guilherme @ data2'});\n      else if(c==='echo')lines.push({t:'out',x:a.slice(1).join(' ')});\n      else if(c==='about')lines.push({t:'out',x:'Terminal fake feito como code component (d2.state + d2.on).'});\n      else if(c==='clear'){d2.state.lines=[];d2.state.cmd='';return;}\n      else if(c==='')         {}\n      else lines.push({t:'err',x:'comando não encontrado: '+c});\n      d2.state.lines=lines;d2.state.cmd='';}\n    d2.on('[data-cmd]','input',function(e,el){d2.state.cmd=el.value;});\n    d2.on('[data-cmd]','keydown',function(e,el){if(e.key==='Enter')run(el.value);});\n  },\n  updated(d2){var s=d2.$('[data-scr]');if(s)s.scrollTop=s.scrollHeight;}\n}"}}}}}}}},{"_id":"6a2d7c351b7164341d2ee494","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kAiImage","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>\"]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c];});}\nfunction imgUrl(s){if(!s)return null;s=String(s);var m=s.match(/!\\[[^\\]]*\\]\\(([^)]+)\\)/);if(m)return m[1];m=s.match(/data:image\\/[a-zA-Z0-9+;=,_/-]+/);if(m)return m[0];m=s.match(/https?:\\/\\/[^\\s)\"'<>]+/);if(m)return m[0];return null;}\nexport default {\n  css: `.wrap{height:100%;box-sizing:border-box;background:#fff;border:1px solid #EAECF0;border-radius:14px;padding:16px;display:flex;flex-direction:column;gap:10px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;box-shadow:0 1px 2px rgba(16,24,40,.05)}\n    .title{font-size:13px;font-weight:600;color:#101828}\n    .canvas{flex:1;min-height:0;border-radius:10px;background:#F2F4F7;display:flex;align-items:center;justify-content:center;overflow:auto;color:#98A2B3;font-size:13px;text-align:center;padding:8px}\n    .canvas img{width:100%;height:100%;object-fit:cover;border-radius:8px}\n    .txt{font-size:12px;color:#475467;white-space:pre-wrap;line-height:1.5}\n    .inrow{display:flex;gap:8px}.inrow input{flex:1;min-width:0;padding:9px 12px;border:1px solid #E4E7EC;border-radius:9px;font:inherit;font-size:13px;outline:none}.inrow input:focus{border-color:#6366F1;box-shadow:0 0 0 3px rgba(99,102,241,.1)}\n    .inrow button{padding:9px 16px;border:none;border-radius:9px;background:#6366F1;color:#fff;font:inherit;font-size:13px;font-weight:600;cursor:pointer}.inrow button:disabled{opacity:.5;cursor:default}`,\n  render(d2){\n    var a=d2.assistant(d2.param('assistant','l7-image'));\n    var busy=a.busy, ans=a.answer||'';\n    var url=imgUrl(ans);\n    var canvas=url?'<img src=\"'+esc(url)+'\"/>':(busy?'Gerando imagem…':(ans?'<div class=\"txt\">'+esc(ans)+'</div>':'A imagem gerada aparece aqui'));\n    return '<div class=\"wrap\"><div class=\"title\">Gerador de imagem (IA)</div><div class=\"canvas\">'+canvas+'</div><div class=\"inrow\"><input data-q placeholder=\"ex: um gato astronauta, neon\" value=\"'+esc(d2.state.q||'')+'\" '+(busy?'disabled':'')+'/><button data-go '+(busy?'disabled':'')+'>'+(busy?'…':'Gerar')+'</button></div></div>';\n  },\n  mounted(d2){\n    function go(){var q=(d2.state.q||'').trim();if(!q)return;d2.assistant(d2.param('assistant','l7-image')).draw(q);}\n    d2.on('[data-q]','input',function(e,el){d2.state.q=el.value;});\n    d2.on('[data-q]','keydown',function(e){if(e.key==='Enter')go();});\n    d2.on('[data-go]','click',go);\n  }\n}"}},"assistant":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"assistant"}}}}}}}}}},{"_id":"6a2d7c35911a2eb6b816a018","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kAiPalette","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>\"]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c];});}\nfunction parse(s){if(!s)return null;var obj=null;try{obj=JSON.parse(s);}catch(e){var m=String(s).match(/\\{[\\s\\S]*\\}/);if(m){try{obj=JSON.parse(m[0]);}catch(e2){}}}\n  if(obj){var keys=['primary','accent','neutralDark','neutralLight'],cols=[];keys.forEach(function(k){if(typeof obj[k]==='string'&&/#[0-9a-fA-F]{6}/.test(obj[k]))cols.push({k:k,v:obj[k].match(/#[0-9a-fA-F]{6}/)[0]});});if(cols.length>=2)return {cols:cols,rationale:obj.rationale};}\n  var hx=String(s).match(/#[0-9a-fA-F]{6}/g);return hx&&hx.length>=2?{cols:hx.slice(0,5).map(function(v){return {k:'',v:v};}),rationale:null}:null;}\nexport default {\n  css: `.wrap{height:100%;box-sizing:border-box;background:#fff;border:1px solid #EAECF0;border-radius:14px;padding:16px;display:flex;flex-direction:column;gap:10px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;box-shadow:0 1px 2px rgba(16,24,40,.05)}\n    .title{font-size:13px;font-weight:600;color:#101828}\n    .pal{flex:1;min-height:0;display:flex;border-radius:10px;overflow:hidden;border:1px solid #F2F4F7}\n    .sw{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:flex-end;padding-bottom:8px;gap:2px;color:rgba(255,255,255,.95);font:600 9px ui-monospace,Menlo,monospace;text-shadow:0 1px 2px rgba(0,0,0,.4)}\n    .sw small{opacity:.85;font-size:8px;text-transform:uppercase}\n    .ph{flex:1;display:flex;align-items:center;justify-content:center;color:#98A2B3;font-size:13px}\n    .rat{font-size:11px;color:#667085;font-style:italic;min-height:14px}\n    .inrow{display:flex;gap:8px}.inrow input{flex:1;min-width:0;padding:9px 12px;border:1px solid #E4E7EC;border-radius:9px;font:inherit;font-size:13px;outline:none}.inrow input:focus{border-color:#6366F1;box-shadow:0 0 0 3px rgba(99,102,241,.1)}\n    .inrow button{padding:9px 16px;border:none;border-radius:9px;background:#6366F1;color:#fff;font:inherit;font-size:13px;font-weight:600;cursor:pointer}.inrow button:disabled{opacity:.5;cursor:default}`,\n  render(d2){\n    var a=d2.assistant(d2.param('assistant','l6-colors'));\n    var busy=a.busy, ans=a.answer||'';\n    var pr=parse(ans);\n    var pal=pr?pr.cols.map(function(c){return '<div class=\"sw\" style=\"background:'+esc(c.v)+'\">'+(c.k?'<small>'+c.k+'</small>':'')+esc(c.v)+'</div>';}).join(''):'<div class=\"ph\">'+(busy?'Gerando paleta…':'descreva um tema e gere')+'</div>';\n    var rat=pr&&pr.rationale?'<div class=\"rat\">'+esc(pr.rationale)+'</div>':'<div class=\"rat\"></div>';\n    return '<div class=\"wrap\"><div class=\"title\">Paleta de cores (IA)</div><div class=\"pal\">'+pal+'</div>'+rat+'<div class=\"inrow\"><input data-q placeholder=\"ex: pôr do sol tropical\" value=\"'+esc(d2.state.q||'')+'\" '+(busy?'disabled':'')+'/><button data-go '+(busy?'disabled':'')+'>'+(busy?'…':'Gerar')+'</button></div></div>';\n  },\n  mounted(d2){\n    function go(){var q=(d2.state.q||'').trim();if(!q)return;d2.assistant(d2.param('assistant','l6-colors')).ask('Mood: '+q);}\n    d2.on('[data-q]','input',function(e,el){d2.state.q=el.value;});\n    d2.on('[data-q]','keydown',function(e){if(e.key==='Enter')go();});\n    d2.on('[data-go]','click',go);\n  }\n}"}},"assistant":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"assistant"}}}}}}}}}},{"_id":"6a2d7c4ced4fc677c360a970","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kLab3","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"var EX=[\n  ['K29','Boids','flocking · canvas','kBoids'],['K30','Cloth','verlet · arraste','kCloth'],['K31','Órbitas','gravidade n-body','kOrbits'],\n  ['K32','Metaballs','SVG gooey','kMetaballs'],['K33','Game of Life','autômato celular','kLife'],['K34','Fogos','partículas','kFireworks'],\n  ['K35','Matrix','rain','kMatrix'],['K36','Starfield','warp 3D','kStarfield'],['K37','Flow Field','campo de fluxo','kFlowField'],\n  ['K38','Force Graph','grafo · arraste','kForceGraph'],['K39','Mandelbrot','fractal','kMandelbrot'],['K40','Cubo 3D','wireframe','kCube3D'],\n  ['K41','Globo','pontos 3D','kGlobe'],['K42','Spirograph','curva','kSpirograph'],['K43','Relógio','ao vivo','kClock'],\n  ['K44','Ondas','ripples · clique','kRipples'],['K45','Visualizer','barras','kAudioBars'],['K46','Plasma','pixel field','kPlasma'],\n  ['K47','Calendário','navegável','kCalendar'],['K48','Markdown','editor + preview','kMarkdown'],['K49','Org Chart','árvore recursiva','kOrgChart'],\n  ['K50','Before/After','slider de imagem','kBeforeAfter'],['K51','Coverflow','carrossel 3D','kCoverflow'],['K52','Radial Menu','menu em arco','kRadialMenu'],\n  ['K53','Wizard','stepper','kWizard'],['K54','Tag Input','autocomplete','kTagInput'],['K55','Virtual List','10k itens','kVirtualList'],\n  ['K56','Terminal','shell fake','kTerminal'],['K57','AI Image','d2.assistant.draw','kAiImage'],['K58','AI Palette','d2.assistant json','kAiPalette']\n];\nexport default {\n  css: `\n    .lab{height:100%;box-sizing:border-box;overflow:auto;background:#F7F8FA;padding:26px 30px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;color:#101828}\n    .hd{margin-bottom:20px}\n    .hd h1{margin:0;font-size:21px;font-weight:600;letter-spacing:-.02em}\n    .hd p{margin:5px 0 0;font-size:13px;color:#667085}\n    .grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(340px,1fr));gap:18px}\n    .cell{display:flex;flex-direction:column;gap:10px}\n    .cap{display:flex;align-items:center;gap:8px}\n    .cap .b{font-size:11px;font-weight:700;color:#6366F1;background:#EEF2FF;padding:2px 8px;border-radius:6px}\n    .cap .t{font-size:14px;font-weight:600;color:#101828}\n    .cap .d{font-size:12px;color:#98A2B3;margin-left:auto;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}\n    .host{height:300px}\n  `,\n  render(d2){\n    var tiles=EX.map(function(e){\n      var params={};\n      if(e[3]==='kAiImage') params={assistant:'l7-image'};\n      if(e[3]==='kAiPalette') params={assistant:'l6-colors'};\n      var child=d2.render('ai-playground@'+e[3], params, {key:e[3]});\n      return '<div class=\"cell\"><div class=\"cap\"><span class=\"b\">'+e[0]+'</span><span class=\"t\">'+e[1]+'</span><span class=\"d\">'+e[2]+'</span></div><div class=\"host\">'+child+'</div></div>';\n    }).join('');\n    return '<div class=\"lab\"><div class=\"hd\"><h1>Code Components · Laboratório III</h1><p>Mind-blowing — simulação física, fractais, 3D, canvas/d2.raf, UI complexa e IA generativa</p></div><div class=\"grid\">'+tiles+'</div></div>';\n  }\n}"}}}}}}}},{"_id":"6a2d883b9b58f90d1c2301ba","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kWhatsApp","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>\"]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c];});}\nfunction ft(ts){var d=new Date(ts);if(isNaN(d.getTime()))return '';return String(d.getHours()).padStart(2,'0')+':'+String(d.getMinutes()).padStart(2,'0');}\nexport default {\n  css: `\n    .wa{height:100%;display:flex;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;background:#fff;overflow:hidden}\n    .side{width:340px;flex:0 0 auto;display:flex;flex-direction:column;border-right:1px solid #e9edef;background:#fff}\n    .shead{padding:16px 16px 10px;font-size:17px;font-weight:700;color:#111b21;background:#f0f2f5}\n    .search{padding:8px 12px;background:#f0f2f5}\n    .search input{width:100%;box-sizing:border-box;padding:8px 12px;border:none;border-radius:8px;background:#fff;font:inherit;font-size:13px;outline:none}\n    .list{flex:1;overflow:auto}\n    .chat{display:flex;gap:12px;padding:11px 14px;cursor:pointer;border-bottom:1px solid #f5f6f6}\n    .chat:hover{background:#f5f6f6}.chat.on{background:#f0f2f5}\n    .av{width:46px;height:46px;border-radius:50%;background:#dfe5e7;display:flex;align-items:center;justify-content:center;font-size:24px;flex:0 0 auto}\n    .ci{flex:1;min-width:0}\n    .crow{display:flex;justify-content:space-between;align-items:baseline}\n    .cn{font-size:15px;font-weight:600;color:#111b21}.ct{font-size:11px;color:#667781}\n    .cl{font-size:13px;color:#667781;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin-top:2px}\n    .panel{flex:1;display:flex;flex-direction:column;min-width:0;background:#efeae2}\n    .empty{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;color:#667781;font-size:15px;background:#f0f2f5}\n    .ebig{font-size:60px;opacity:.4}\n    .phead{display:flex;align-items:center;gap:12px;padding:10px 16px;background:#f0f2f5;border-bottom:1px solid #e9edef;flex:0 0 auto}\n    .pn{font-size:16px;font-weight:600;color:#111b21}.ps{font-size:12px;color:#667781}\n    .msgs{flex:1;overflow:auto;padding:18px 8%;display:flex;flex-direction:column;gap:4px}\n    .brow{display:flex}.brow.me{justify-content:flex-end}\n    .bub{max-width:65%;padding:6px 9px 8px;border-radius:8px;font-size:14px;line-height:1.35;color:#111b21;box-shadow:0 1px 1px rgba(0,0,0,.08);position:relative;white-space:pre-wrap;word-break:break-word}\n    .brow.in .bub{background:#fff;border-top-left-radius:2px}\n    .brow.me .bub{background:#d9fdd3;border-top-right-radius:2px}\n    .bt{font-size:10px;color:#667781;float:right;margin:6px 0 -2px 10px}\n    .typing{color:#667781;font-style:italic}\n    .composer{display:flex;gap:8px;align-items:center;padding:10px 14px;background:#f0f2f5;flex:0 0 auto}\n    .composer input{flex:1;padding:10px 14px;border:none;border-radius:20px;background:#fff;font:inherit;font-size:14px;outline:none}\n    .composer button{width:42px;height:42px;border-radius:50%;border:none;background:#00a884;color:#fff;font-size:16px;cursor:pointer;flex:0 0 auto}\n    .composer button:disabled{opacity:.5;cursor:default}\n    .composer button:hover:not(:disabled){background:#06cf9c}\n  `,\n  render(d2){\n    var contacts=d2.data('contacts'), msgs=d2.data('messages');\n    var cs=contacts?contacts.records():[], ms=msgs?msgs.records():[];\n    var active=d2.state.chat, q=(d2.state.q||'').toLowerCase();\n    function lastOf(cid){var a=ms.filter(function(m){return m.chatId===cid;}).slice().sort(function(x,y){return new Date(x.ts)-new Date(y.ts);});return a.length?a[a.length-1]:null;}\n    var items=cs.filter(function(c){return !q||(c.name||'').toLowerCase().indexOf(q)>=0;}).map(function(c){\n      var last=lastOf(c.chatId),on=active===c.chatId;\n      return '<div class=\"chat'+(on?' on':'')+'\" data-chat=\"'+esc(c.chatId)+'\"><div class=\"av\">'+esc(c.avatar||'👤')+'</div><div class=\"ci\"><div class=\"crow\"><span class=\"cn\">'+esc(c.name)+'</span><span class=\"ct\">'+(last?ft(last.ts):'')+'</span></div><div class=\"cl\">'+(last?esc(last.text):esc(c.about||''))+'</div></div></div>';\n    }).join('');\n    var panel;\n    if(!active){ panel='<div class=\"empty\"><div class=\"ebig\">💬</div><div>Selecione uma conversa para começar</div></div>'; }\n    else {\n      var c=cs.filter(function(x){return x.chatId===active;})[0]||{};\n      var conv=ms.filter(function(m){return m.chatId===active;}).slice().sort(function(x,y){return new Date(x.ts)-new Date(y.ts);});\n      var bubbles=conv.map(function(m){var me=m.role==='user';return '<div class=\"brow '+(me?'me':'in')+'\"><div class=\"bub\">'+esc(m.text)+'<span class=\"bt\">'+ft(m.ts)+'</span></div></div>';}).join('');\n      if(d2.state.sending) bubbles+='<div class=\"brow in\"><div class=\"bub typing\">digitando…</div></div>';\n      panel='<div class=\"phead\"><div class=\"av\" style=\"width:40px;height:40px;font-size:20px\">'+esc(c.avatar||'👤')+'</div><div><div class=\"pn\">'+esc(c.name||'')+'</div><div class=\"ps\">'+(c.online?'online':esc(c.about||''))+'</div></div></div><div class=\"msgs\" data-msgs>'+bubbles+'</div><div class=\"composer\"><input data-draft placeholder=\"Mensagem\" value=\"'+esc(d2.state.draft||'')+'\"/><button data-send '+(d2.state.sending?'disabled':'')+'>➤</button></div>';\n    }\n    return '<div class=\"wa\"><div class=\"side\"><div class=\"shead\">WhatsApp</div><div class=\"search\"><input data-q placeholder=\"Buscar ou começar nova conversa\" value=\"'+esc(d2.state.q||'')+'\"/></div><div class=\"list\">'+items+'</div></div><div class=\"panel\">'+panel+'</div></div>';\n  },\n  mounted(d2){\n    d2.on('[data-chat]','click',function(e,el){d2.state.chat=el.getAttribute('data-chat');});\n    d2.on('[data-q]','input',function(e,el){d2.state.q=el.value;});\n    d2.on('[data-draft]','input',function(e,el){d2.state.draft=el.value;});\n    function send(){\n      var t=(d2.state.draft||'').trim(),cid=d2.state.chat;\n      if(!t||!cid||d2.state.sending)return;\n      var ds=d2.data('messages');\n      var prior=ds.records().filter(function(m){return m.chatId===cid;}).slice().sort(function(a,b){return new Date(a.ts)-new Date(b.ts);});\n      var history=prior.map(function(m){return {role:(m.role==='user'?'user':'assistant'),content:String(m.text||'')};});\n      history.push({role:'user',content:t});\n      ds.create({chatId:cid,role:'user',text:t,ts:new Date().toISOString()});\n      d2.state.draft=''; d2.state.sending=true;\n      var bot=d2.assistant(d2.params.bot);\n      Promise.resolve(bot.reply(history)).then(function(ans){\n        return ds.create({chatId:cid,role:'assistant',text:String(ans==null?'…':ans),ts:new Date().toISOString()});\n      }).then(function(){ d2.state.sending=false; ds.refresh(); }).catch(function(){ d2.state.sending=false; ds.refresh(); });\n    }\n    d2.on('[data-send]','click',send);\n    d2.on('[data-draft]','keydown',function(e){if(e.key==='Enter')send();});\n  },\n  updated(d2){var m=d2.$('[data-msgs]');if(m)m.scrollTop=m.scrollHeight;}\n}"}},"contacts":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"contacts"}}}},"messages":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"messages"}}}},"bot":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"bot"}}}}}}}}}},{"_id":"6a2d89361b7164341d2ef81f","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kAsana","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>\"]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c];});}\nvar COLS=[['todo','A fazer','#98A2B3'],['doing','Em progresso','#2E90FA'],['blocked','Bloqueado','#F04438'],['done','Concluído','#12B76A']];\nvar PRI={1:['#FEE4E2','#B42318','P1'],2:['#FEF0C7','#B54708','P2'],3:['#D1FADF','#027A48','P3']};\nexport default {\n  css: `\n    .board{height:100%;box-sizing:border-box;background:#F4F5F7;padding:20px 24px;display:flex;flex-direction:column;gap:16px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;overflow:hidden}\n    .bhead h1{margin:0;font-size:20px;font-weight:700;color:#172B4D}\n    .bhead .sub{font-size:13px;color:#6B778C}\n    .cols{flex:1;display:grid;grid-template-columns:repeat(4,1fr);gap:14px;min-height:0}\n    .col{background:#EBECF0;border-radius:12px;display:flex;flex-direction:column;min-height:0}\n    .colh{display:flex;align-items:center;gap:8px;padding:12px 14px;font-size:12px;font-weight:700;color:#5E6C84;text-transform:uppercase;letter-spacing:.04em}\n    .dot{width:8px;height:8px;border-radius:50%}.cnt{margin-left:auto;background:#fff;color:#5E6C84;padding:1px 8px;border-radius:10px}\n    .cards{flex:1;overflow:auto;padding:0 8px 8px;display:flex;flex-direction:column;gap:8px}\n    .card{background:#fff;border-radius:9px;padding:11px 12px;box-shadow:0 1px 2px rgba(9,30,66,.12);cursor:grab}\n    .card:hover{box-shadow:0 3px 8px rgba(9,30,66,.18)}\n    .ct{font-size:13.5px;color:#172B4D;line-height:1.35;margin-bottom:9px}\n    .cf{display:flex;align-items:center;gap:7px}\n    .pri{font-size:10px;font-weight:700;padding:2px 7px;border-radius:4px}\n    .proj{font-size:11px;color:#6B778C}.asg{margin-left:auto;font-size:18px}\n  `,\n  render(d2){\n    var ds=d2.data(); var recs=ds?ds.records():[];\n    var cols=COLS.map(function(c){\n      var items=recs.filter(function(t){return (t.status||'todo')===c[0];});\n      var cards=items.map(function(t){var p=PRI[t.priority]||PRI[2];return '<div class=\"card\" draggable=\"true\" data-id=\"'+t._id+'\"><div class=\"ct\">'+esc(t.title)+'</div><div class=\"cf\"><span class=\"pri\" style=\"background:'+p[0]+';color:'+p[1]+'\">'+p[2]+'</span><span class=\"proj\">'+esc(t.project||'')+'</span><span class=\"asg\" title=\"'+esc(t.assignee||'')+'\">'+esc(t.avatar||'👤')+'</span></div></div>';}).join('');\n      return '<div class=\"col\" data-col=\"'+c[0]+'\"><div class=\"colh\"><span class=\"dot\" style=\"background:'+c[2]+'\"></span>'+c[1]+'<span class=\"cnt\">'+items.length+'</span></div><div class=\"cards\">'+cards+'</div></div>';\n    }).join('');\n    return '<div class=\"board\"><div class=\"bhead\"><h1>Lançamento do Produto</h1><span class=\"sub\">'+recs.length+' tarefas · arraste os cartões entre colunas (persiste no dataset)</span></div><div class=\"cols\">'+cols+'</div></div>';\n  },\n  mounted(d2){\n    var drag=null;\n    d2.on('[data-id]','dragstart',function(e,el){drag=el.getAttribute('data-id');el.style.opacity='.4';});\n    d2.on('[data-id]','dragend',function(e,el){el.style.opacity='';});\n    d2.on('.col','dragover',function(e){e.preventDefault();});\n    d2.on('.col','drop',function(e,el){e.preventDefault();if(!drag)return;var st=el.getAttribute('data-col');var rec=d2.data().records().filter(function(r){return r._id===drag;})[0];if(rec&&rec.status!==st)d2.data().update({_id:drag,status:st});drag=null;});\n  }\n}"}},"dataset":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"dataset"}}}}}}}}}},{"_id":"6a2d89361b7164341d2ef826","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kContactCenter","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>\"]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c];});}\nfunction mmss(s){s=Math.round(s||0);return Math.floor(s/60)+':'+String(s%60).padStart(2,'0');}\nexport default {\n  css: `\n    .cc{height:100%;box-sizing:border-box;background:#0B1220;color:#E5EAF2;padding:20px 24px;display:flex;flex-direction:column;gap:16px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;overflow:auto}\n    .hd{display:flex;align-items:center;justify-content:space-between}\n    .hd h1{margin:0;font-size:19px;font-weight:700}.hd .live{font-size:12px;color:#22C55E;display:flex;align-items:center;gap:6px}.hd .pip{width:8px;height:8px;border-radius:50%;background:#22C55E;animation:p 1.6s infinite}@keyframes p{0%,100%{opacity:1}50%{opacity:.4}}\n    .kpis{display:grid;grid-template-columns:repeat(5,1fr);gap:12px}\n    .kpi{background:#141d30;border:1px solid #1f2a42;border-radius:12px;padding:14px 16px}\n    .kl{font-size:11px;color:#8595b3;text-transform:uppercase;letter-spacing:.05em}\n    .kv{font-size:26px;font-weight:800;margin-top:6px;font-variant-numeric:tabular-nums}\n    .cols{flex:1;display:grid;grid-template-columns:1.2fr 1fr;gap:16px;min-height:0}\n    .panel{background:#141d30;border:1px solid #1f2a42;border-radius:12px;display:flex;flex-direction:column;overflow:hidden}\n    .ph{padding:13px 16px;font-size:13px;font-weight:700;border-bottom:1px solid #1f2a42;display:flex;justify-content:space-between}\n    .ph small{color:#8595b3;font-weight:500}\n    .list{flex:1;overflow:auto}\n    .row{display:flex;align-items:center;gap:11px;padding:10px 16px;border-bottom:1px solid #1a2438}\n    .av{width:34px;height:34px;border-radius:50%;background:#1f2a42;display:flex;align-items:center;justify-content:center;font-size:18px;flex:0 0 auto}\n    .nm{font-size:13.5px;font-weight:600}.meta{font-size:11px;color:#8595b3;margin-top:1px}\n    .sdot{width:8px;height:8px;border-radius:50%;flex:0 0 auto}\n    .right{margin-left:auto;text-align:right;font-size:12px;color:#aab6cf;font-variant-numeric:tabular-nums}\n    .pill{font-size:10px;font-weight:700;padding:2px 7px;border-radius:5px}\n    .wait{font-weight:700;font-variant-numeric:tabular-nums}\n  `,\n  render(d2){\n    var ag=(d2.data('agents')&&d2.data('agents').records())||[];\n    var cl=(d2.data('calls')&&d2.data('calls').records())||[];\n    var queued=cl.filter(function(c){return c.status==='queued';}).slice().sort(function(a,b){return (b.waitSec||0)-(a.waitSec||0);});\n    var active=cl.filter(function(c){return c.status==='active';});\n    var online=ag.filter(function(a){return a.status!=='offline';});\n    var ah=ag.filter(function(a){return a.aht>0;});var avgAht=ah.length?Math.round(ah.reduce(function(s,a){return s+a.aht;},0)/ah.length):0;\n    var cz=ag.filter(function(a){return a.csat>0;});var avgCsat=cz.length?(cz.reduce(function(s,a){return s+a.csat;},0)/cz.length).toFixed(1):'—';\n    var SC={available:'#22C55E',busy:'#F59E0B',away:'#94a3b8',offline:'#475569'};\n    var SENT={pos:['#0c3a24','#4ade80','positivo'],neu:['#2a3147','#94a3b8','neutro'],neg:['#3a1620','#f87171','negativo']};\n    var kpi=function(l,v,c){return '<div class=\"kpi\"><div class=\"kl\">'+l+'</div><div class=\"kv\" style=\"color:'+(c||'#E5EAF2')+'\">'+v+'</div></div>';};\n    var kpis=kpi('Em espera',queued.length,queued.length>2?'#f87171':'#E5EAF2')+kpi('Em atendimento',active.length,'#60a5fa')+kpi('TMA médio',mmss(avgAht))+kpi('CSAT médio',avgCsat,'#4ade80')+kpi('Agentes online',online.length+'/'+ag.length);\n    var qrows=queued.length?queued.map(function(c){var s=SENT[c.sentiment]||SENT.neu;var crit=c.waitSec>90;return '<div class=\"row\"><div class=\"av\">⏳</div><div><div class=\"nm\">'+esc(c.customer)+'</div><div class=\"meta\">'+esc(c.queue)+'</div></div><div class=\"right\"><span class=\"pill\" style=\"background:'+s[0]+';color:'+s[1]+'\">'+s[2]+'</span><div class=\"wait\" style=\"color:'+(crit?'#f87171':'#aab6cf')+'\">'+mmss(c.waitSec)+'</div></div></div>';}).join(''):'<div class=\"row\"><div class=\"meta\">Fila vazia 🎉</div></div>';\n    var arows=ag.map(function(a){return '<div class=\"row\"><div class=\"av\">'+esc(a.avatar||'👤')+'</div><div><div class=\"nm\">'+esc(a.name)+'</div><div class=\"meta\">'+a.handled+' atend. · TMA '+mmss(a.aht)+'</div></div><div class=\"right\"><span class=\"sdot\" style=\"background:'+(SC[a.status]||'#475569')+';display:inline-block;margin-right:5px\"></span>'+(a.csat>0?'★ '+a.csat:'—')+'</div></div>';}).join('');\n    return '<div class=\"cc\"><div class=\"hd\"><h1>📞 Central de Atendimento</h1><span class=\"live\"><span class=\"pip\"></span>ao vivo</span></div><div class=\"kpis\">'+kpis+'</div><div class=\"cols\"><div class=\"panel\"><div class=\"ph\">Fila de espera <small>'+queued.length+' aguardando</small></div><div class=\"list\">'+qrows+'</div></div><div class=\"panel\"><div class=\"ph\">Agentes <small>'+online.length+' online</small></div><div class=\"list\">'+arows+'</div></div></div></div>';\n  }\n}"}},"agents":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"agents"}}}},"calls":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"calls"}}}}}}}}}},{"_id":"6a2d8aff9b58f90d1c2305e5","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kCRM","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>\"]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c];});}\nfunction money(n){n=Number(n)||0;return n>=1000?'R$ '+(n/1000).toFixed(0)+'k':'R$ '+n;}\nvar COLS=[['lead','Lead','#94a3b8'],['qualified','Qualificado','#3b82f6'],['proposal','Proposta','#f59e0b'],['won','Ganho','#22c55e'],['lost','Perdido','#ef4444']];\nexport default {\n  css: `\n    .crm{height:100%;box-sizing:border-box;background:#0f172a;padding:18px 22px;display:flex;flex-direction:column;gap:14px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;overflow:hidden;color:#e2e8f0}\n    .hd h1{margin:0;font-size:19px;font-weight:700}.hd .sub{font-size:13px;color:#94a3b8}\n    .cols{flex:1;display:grid;grid-template-columns:repeat(5,1fr);gap:12px;min-height:0}\n    .col{background:#1e293b;border-radius:11px;display:flex;flex-direction:column;min-height:0}\n    .colh{padding:11px 13px;border-bottom:1px solid #334155}\n    .ct{display:flex;align-items:center;gap:7px;font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:.04em}\n    .dot{width:8px;height:8px;border-radius:50%}.cv{font-size:13px;color:#94a3b8;margin-top:3px;font-variant-numeric:tabular-nums}\n    .cards{flex:1;overflow:auto;padding:8px;display:flex;flex-direction:column;gap:7px}\n    .card{background:#0f172a;border:1px solid #334155;border-radius:9px;padding:10px 11px;cursor:grab}\n    .card:hover{border-color:#475569}\n    .cco{font-size:13.5px;font-weight:600;color:#f1f5f9}\n    .cval{font-size:15px;font-weight:800;color:#4ade80;margin:4px 0;font-variant-numeric:tabular-nums}\n    .cf{display:flex;align-items:center;justify-content:space-between;font-size:11px;color:#94a3b8}\n  `,\n  render(d2){\n    var ds=d2.data(); var recs=ds?ds.records():[];\n    var cols=COLS.map(function(c){\n      var items=recs.filter(function(t){return (t.stage||'lead')===c[0];});\n      var sum=items.reduce(function(s,t){return s+(Number(t.value)||0);},0);\n      var cards=items.map(function(t){return '<div class=\"card\" draggable=\"true\" data-id=\"'+t._id+'\"><div class=\"cco\">'+esc(t.company)+'</div><div class=\"cval\">'+money(t.value)+'</div><div class=\"cf\"><span>'+esc(t.contact||'')+'</span><span title=\"'+esc(t.owner||'')+'\">'+esc(t.avatar||'👤')+'</span></div></div>';}).join('');\n      return '<div class=\"col\" data-col=\"'+c[0]+'\"><div class=\"colh\"><div class=\"ct\"><span class=\"dot\" style=\"background:'+c[2]+'\"></span>'+c[1]+' ('+items.length+')</div><div class=\"cv\">'+money(sum)+'</div></div><div class=\"cards\">'+cards+'</div></div>';\n    }).join('');\n    var total=recs.filter(function(t){return t.stage!=='lost';}).reduce(function(s,t){return s+(Number(t.value)||0);},0);\n    return '<div class=\"crm\"><div class=\"hd\"><h1>Pipeline de Vendas</h1><span class=\"sub\">'+recs.length+' negócios · '+money(total)+' em aberto · arraste para mover de etapa</span></div><div class=\"cols\">'+cols+'</div></div>';\n  },\n  mounted(d2){\n    var drag=null;\n    d2.on('[data-id]','dragstart',function(e,el){drag=el.getAttribute('data-id');el.style.opacity='.4';});\n    d2.on('[data-id]','dragend',function(e,el){el.style.opacity='';});\n    d2.on('.col','dragover',function(e){e.preventDefault();});\n    d2.on('.col','drop',function(e,el){e.preventDefault();if(!drag)return;var st=el.getAttribute('data-col');var rec=d2.data().records().filter(function(r){return r._id===drag;})[0];if(rec&&rec.stage!==st)d2.data().update({_id:drag,stage:st});drag=null;});\n  }\n}"}},"dataset":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"dataset"}}}}}}}}}},{"_id":"6a2d8affdbf815e74e991456","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kHelpdesk","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>\"]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c];});}\nvar PR={alta:['#FEE4E2','#B42318'],media:['#FEF0C7','#B54708'],baixa:['#EFF8FF','#175CD3']};\nvar ST={open:['#FEF3F2','#B42318','Aberto'],pending:['#FFFAEB','#B54708','Pendente'],closed:['#ECFDF3','#027A48','Resolvido']};\nexport default {\n  css: `\n    .hd{height:100%;box-sizing:border-box;display:flex;background:#fff;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;overflow:hidden;color:#101828}\n    .list{width:330px;flex:0 0 auto;border-right:1px solid #EAECF0;display:flex;flex-direction:column}\n    .lh{padding:15px 16px;font-size:15px;font-weight:700;border-bottom:1px solid #F2F4F7}\n    .items{flex:1;overflow:auto}\n    .it{padding:12px 16px;border-bottom:1px solid #F2F4F7;cursor:pointer}.it:hover{background:#F9FAFB}.it.on{background:#EFF8FF}\n    .isub{font-size:13.5px;font-weight:600;margin-bottom:3px}\n    .imeta{display:flex;align-items:center;gap:6px;font-size:11px;color:#667085}\n    .pill{font-size:10px;font-weight:700;padding:1px 7px;border-radius:5px}\n    .detail{flex:1;display:flex;flex-direction:column;min-width:0}\n    .empty{flex:1;display:flex;align-items:center;justify-content:center;color:#98A2B3;font-size:14px}\n    .dh{padding:18px 22px;border-bottom:1px solid #F2F4F7}\n    .dh h2{margin:0 0 6px;font-size:18px}.dh .dm{font-size:12px;color:#667085}\n    .body{padding:18px 22px;flex:1;overflow:auto}\n    .msg{background:#F9FAFB;border:1px solid #F2F4F7;border-radius:10px;padding:14px;font-size:14px;line-height:1.5;color:#344054}\n    .reply{padding:14px 22px;border-top:1px solid #F2F4F7;display:flex;flex-direction:column;gap:8px}\n    .reply textarea{width:100%;box-sizing:border-box;min-height:70px;border:1px solid #E4E7EC;border-radius:9px;padding:10px;font:inherit;font-size:13px;resize:vertical;outline:none}\n    .reply textarea:focus{border-color:#6366F1;box-shadow:0 0 0 3px rgba(99,102,241,.1)}\n    .ra{display:flex;gap:8px;align-items:center}\n    .ai{background:#6366F1;color:#fff;border:none;padding:9px 14px;border-radius:8px;font:inherit;font-size:13px;font-weight:600;cursor:pointer}.ai:disabled{opacity:.5}\n    .snd{background:#fff;color:#475467;border:1px solid #E4E7EC;padding:9px 14px;border-radius:8px;font:inherit;font-size:13px;font-weight:600;cursor:pointer}\n  `,\n  render(d2){\n    var ds=d2.data(); var recs=ds?ds.records():[];\n    var sel=d2.state.sel;\n    var items=recs.map(function(t){var p=PR[t.priority]||PR.media,s=ST[t.status]||ST.open;return '<div class=\"it'+(sel===t._id?' on':'')+'\" data-id=\"'+t._id+'\"><div class=\"isub\">'+esc(t.subject)+'</div><div class=\"imeta\"><span class=\"pill\" style=\"background:'+p[0]+';color:'+p[1]+'\">'+esc(t.priority)+'</span><span class=\"pill\" style=\"background:'+s[0]+';color:'+s[1]+'\">'+s[2]+'</span><span>'+esc(t.customer)+'</span></div></div>';}).join('');\n    var detail;\n    var t=recs.filter(function(x){return x._id===sel;})[0];\n    if(!t){ detail='<div class=\"empty\">Selecione um ticket</div>'; }\n    else { detail='<div class=\"dh\"><h2>'+esc(t.subject)+'</h2><div class=\"dm\">'+esc(t.customer)+' · '+esc(t.category||'')+' · prioridade '+esc(t.priority)+'</div></div><div class=\"body\"><div class=\"msg\">'+esc(t.body)+'</div></div><div class=\"reply\"><textarea data-draft placeholder=\"Escreva ou gere uma resposta…\">'+esc(d2.state.draft||'')+'</textarea><div class=\"ra\"><button class=\"ai\" data-ai '+(d2.state.busy?'disabled':'')+'>'+(d2.state.busy?'Gerando…':'✨ Sugerir resposta (IA)')+'</button><button class=\"snd\">Enviar</button></div></div>'; }\n    return '<div class=\"hd\"><div class=\"list\"><div class=\"lh\">Tickets ('+recs.length+')</div><div class=\"items\">'+items+'</div></div><div class=\"detail\">'+detail+'</div></div>';\n  },\n  mounted(d2){\n    d2.on('[data-id]','click',function(e,el){d2.state.sel=el.getAttribute('data-id');d2.state.draft='';});\n    d2.on('[data-draft]','input',function(e,el){d2.state.draft=el.value;});\n    d2.on('[data-ai]','click',function(){\n      var t=d2.data().records().filter(function(x){return x._id===d2.state.sel;})[0];if(!t||d2.state.busy)return;\n      d2.state.busy=true;\n      var prompt='Assunto: '+t.subject+'\\nCliente: '+t.customer+'\\nMensagem do cliente: '+t.body+'\\n\\nEscreva uma resposta de suporte.';\n      Promise.resolve(d2.assistant(d2.params.suggest).ask(prompt)).then(function(ans){d2.state.draft=String(ans==null?'':ans);d2.state.busy=false;}).catch(function(){d2.state.busy=false;});\n    });\n  }\n}"}},"dataset":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"dataset"}}}},"suggest":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"suggest"}}}}}}}}}},{"_id":"6a2d8b009b58f90d1c2305ed","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kRecipe","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>\"]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c];});}\nexport default {\n  css: `\n    .rb{height:100%;box-sizing:border-box;display:flex;background:#fffaf5;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;overflow:hidden;color:#3d2c1e}\n    .grid{flex:1;overflow:auto;padding:18px;display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));grid-auto-rows:130px;gap:14px;align-content:start}\n    .rc{background:#fff;border:1px solid #f0e6d8;border-radius:14px;padding:14px;cursor:pointer;display:flex;flex-direction:column;justify-content:space-between;box-shadow:0 1px 3px rgba(0,0,0,.05);transition:.15s}\n    .rc:hover{transform:translateY(-3px);box-shadow:0 6px 16px rgba(0,0,0,.1)}.rc.on{border-color:#e8833a;box-shadow:0 0 0 2px #e8833a}\n    .re{font-size:34px}.rn{font-size:13px;font-weight:700;line-height:1.25}.rm{font-size:11px;color:#a18a72;margin-top:3px}\n    .panel{width:380px;flex:0 0 auto;border-left:1px solid #f0e6d8;background:#fff;display:flex;flex-direction:column;overflow:hidden}\n    .gen{padding:16px;border-bottom:1px solid #f5ece0;background:#fff7ef}\n    .gen .gt{font-size:13px;font-weight:700;margin-bottom:8px;color:#b15a1a}\n    .gen .gr{display:flex;gap:8px}\n    .gen input{flex:1;min-width:0;padding:9px 12px;border:1px solid #ecddc9;border-radius:9px;font:inherit;font-size:13px;outline:none}\n    .gen button{background:#e8833a;color:#fff;border:none;padding:9px 14px;border-radius:9px;font:inherit;font-size:13px;font-weight:700;cursor:pointer}.gen button:disabled{opacity:.5}\n    .det{flex:1;overflow:auto;padding:18px}\n    .det h2{margin:0 0 4px;font-size:19px}.det .meta{font-size:12px;color:#a18a72;margin-bottom:14px}\n    .det h4{margin:14px 0 6px;font-size:12px;text-transform:uppercase;letter-spacing:.05em;color:#b15a1a}\n    .det p{font-size:13.5px;line-height:1.6;color:#5c4a39;white-space:pre-wrap;margin:0}\n    .ph{color:#a18a72;font-size:13px}\n  `,\n  render(d2){\n    var ds=d2.data(); var recs=ds?ds.records():[];\n    var sel=d2.state.sel;\n    var cards=recs.map(function(r){return '<div class=\"rc'+(sel===r._id?' on':'')+'\" data-id=\"'+r._id+'\"><div class=\"re\">'+esc(r.emoji||'🍽️')+'</div><div><div class=\"rn\">'+esc(r.name)+'</div><div class=\"rm\">'+esc(r.difficulty||'')+' · '+(r.time||'?')+' min</div></div></div>';}).join('');\n    var det;\n    if(d2.state.gen){ det='<h2>✨ Receita gerada</h2><div class=\"meta\">por IA</div><p>'+esc(d2.state.gen)+'</p>'; }\n    else { var r=recs.filter(function(x){return x._id===sel;})[0];\n      if(!r){ det='<div class=\"ph\">Selecione uma receita ou gere uma nova com IA.</div>'; }\n      else { det='<h2>'+esc(r.emoji||'')+' '+esc(r.name)+'</h2><div class=\"meta\">'+esc(r.difficulty||'')+' · '+(r.time||'?')+' min</div><h4>Ingredientes</h4><p>'+esc(r.ingredients||'')+'</p><h4>Modo de preparo</h4><p>'+esc(r.steps||'')+'</p>'; } }\n    return '<div class=\"rb\"><div class=\"grid\">'+cards+'</div><div class=\"panel\"><div class=\"gen\"><div class=\"gt\">👩‍🍳 Gerar receita com IA</div><div class=\"gr\"><input data-q placeholder=\"ex: algo com frango\" value=\"'+esc(d2.state.q||'')+'\"/><button data-go '+(d2.state.busy?'disabled':'')+'>'+(d2.state.busy?'…':'Gerar')+'</button></div></div><div class=\"det\">'+det+'</div></div></div>';\n  },\n  mounted(d2){\n    d2.on('[data-id]','click',function(e,el){d2.state.sel=el.getAttribute('data-id');d2.state.gen=null;});\n    d2.on('[data-q]','input',function(e,el){d2.state.q=el.value;});\n    function gen(){var q=(d2.state.q||'').trim();if(!q||d2.state.busy)return;d2.state.busy=true;Promise.resolve(d2.assistant(d2.params.chef).ask('Crie uma receita: '+q)).then(function(ans){d2.state.gen=String(ans==null?'':ans);d2.state.sel=null;d2.state.busy=false;}).catch(function(){d2.state.busy=false;});}\n    d2.on('[data-go]','click',gen);\n    d2.on('[data-q]','keydown',function(e){if(e.key==='Enter')gen();});\n  }\n}"}},"dataset":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"dataset"}}}},"chef":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"chef"}}}}}}}}}},{"_id":"6a2d8b00baacaeb326293baf","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kExpense","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>\"]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c];});}\nvar CAT={'Alimentação':'#f59e0b','Transporte':'#3b82f6','Lazer':'#ec4899','Casa':'#8b5cf6','Saúde':'#22c55e','Outros':'#94a3b8'};\nfunction brl(n){return 'R$ '+(Number(n)||0).toLocaleString('pt-BR',{minimumFractionDigits:2,maximumFractionDigits:2});}\nexport default {\n  css: `\n    .ex{height:100%;box-sizing:border-box;display:flex;background:#f8fafc;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;overflow:hidden;color:#0f172a}\n    .left{width:360px;flex:0 0 auto;border-right:1px solid #e2e8f0;background:#fff;display:flex;flex-direction:column;padding:20px;gap:16px}\n    .tot{text-align:center}.tot .tl{font-size:12px;color:#64748b;text-transform:uppercase;letter-spacing:.05em}.tot .tv{font-size:32px;font-weight:800;font-variant-numeric:tabular-nums}\n    .donut{display:flex;justify-content:center}\n    .leg{display:flex;flex-direction:column;gap:5px}\n    .lr{display:flex;align-items:center;gap:8px;font-size:12px;color:#475569}.lr b{margin-left:auto;font-variant-numeric:tabular-nums;color:#0f172a}\n    .sw{width:10px;height:10px;border-radius:3px}\n    .form{margin-top:auto;display:flex;flex-direction:column;gap:8px;border-top:1px solid #f1f5f9;padding-top:14px}\n    .form input{padding:9px 11px;border:1px solid #e2e8f0;border-radius:8px;font:inherit;font-size:13px;outline:none}\n    .frow{display:flex;gap:8px}.frow input{flex:1;min-width:0}\n    .catbox{display:flex;gap:8px;align-items:center}\n    .catpill{font-size:12px;font-weight:600;padding:4px 10px;border-radius:7px;background:#f1f5f9;color:#475569}\n    .bcat{background:#eef2ff;color:#4338ca;border:none;padding:8px 11px;border-radius:8px;font:inherit;font-size:12px;font-weight:600;cursor:pointer}.bcat:disabled{opacity:.5}\n    .badd{background:#4f46e5;color:#fff;border:none;padding:10px;border-radius:8px;font:inherit;font-size:13px;font-weight:700;cursor:pointer}\n    .list{flex:1;overflow:auto;padding:14px 18px}\n    .lh{font-size:13px;font-weight:700;color:#0f172a;margin-bottom:10px}\n    .row{display:flex;align-items:center;gap:11px;padding:10px 0;border-bottom:1px solid #f1f5f9}\n    .ci{width:34px;height:34px;border-radius:9px;display:flex;align-items:center;justify-content:center;flex:0 0 auto}\n    .rd{font-size:13.5px;font-weight:500}.rc{font-size:11px;color:#64748b}\n    .ra{margin-left:auto;font-size:14px;font-weight:700;font-variant-numeric:tabular-nums}\n  `,\n  render(d2){\n    var ds=d2.data(); var recs=ds?ds.records():[];\n    var total=recs.reduce(function(s,r){return s+(Number(r.amount)||0);},0);\n    var byCat={};recs.forEach(function(r){var c=r.category||'Outros';byCat[c]=(byCat[c]||0)+(Number(r.amount)||0);});\n    var cats=Object.keys(byCat).sort(function(a,b){return byCat[b]-byCat[a];});\n    var R=52,C=2*Math.PI*R,off=0;\n    var arcs=cats.map(function(c){var frac=total?byCat[c]/total:0,len=frac*C;var el='<circle cx=\"70\" cy=\"70\" r=\"'+R+'\" fill=\"none\" stroke=\"'+(CAT[c]||'#94a3b8')+'\" stroke-width=\"16\" stroke-dasharray=\"'+len.toFixed(2)+' '+(C-len).toFixed(2)+'\" stroke-dashoffset=\"'+(-off).toFixed(2)+'\" transform=\"rotate(-90 70 70)\"/>';off+=len;return el;}).join('');\n    var leg=cats.map(function(c){return '<div class=\"lr\"><span class=\"sw\" style=\"background:'+(CAT[c]||'#94a3b8')+'\"></span>'+esc(c)+'<b>'+brl(byCat[c])+'</b></div>';}).join('');\n    var rows=recs.slice().reverse().map(function(r){var col=CAT[r.category]||'#94a3b8';return '<div class=\"row\"><div class=\"ci\" style=\"background:'+col+'22;color:'+col+'\">●</div><div><div class=\"rd\">'+esc(r.description)+'</div><div class=\"rc\">'+esc(r.category||'Outros')+'</div></div><div class=\"ra\">'+brl(r.amount)+'</div></div>';}).join('');\n    var cat=d2.state.cat;\n    return '<div class=\"ex\"><div class=\"left\"><div class=\"tot\"><div class=\"tl\">Total do mês</div><div class=\"tv\">'+brl(total)+'</div></div><div class=\"donut\"><svg viewBox=\"0 0 140 140\" style=\"width:140px;height:140px\">'+arcs+'</svg></div><div class=\"leg\">'+leg+'</div><div class=\"form\"><input data-desc placeholder=\"Descrição do gasto\" value=\"'+esc(d2.state.desc||'')+'\"/><div class=\"frow\"><input data-amt type=\"number\" placeholder=\"Valor\" value=\"'+esc(d2.state.amt||'')+'\"/><button class=\"bcat\" data-cat '+(d2.state.busy?'disabled':'')+'>'+(d2.state.busy?'…':'✨ Categorizar')+'</button></div>'+(cat?'<div class=\"catbox\"><span class=\"catpill\" style=\"background:'+(CAT[cat]||'#f1f5f9')+'22;color:'+(CAT[cat]||'#475569')+'\">'+esc(cat)+'</span></div>':'')+'<button class=\"badd\" data-add>Adicionar gasto</button></div></div><div class=\"list\"><div class=\"lh\">Transações ('+recs.length+')</div>'+rows+'</div></div>';\n  },\n  mounted(d2){\n    d2.on('[data-desc]','input',function(e,el){d2.state.desc=el.value;});\n    d2.on('[data-amt]','input',function(e,el){d2.state.amt=el.value;});\n    d2.on('[data-cat]','click',function(){var dsc=(d2.state.desc||'').trim();if(!dsc||d2.state.busy)return;d2.state.busy=true;Promise.resolve(d2.assistant(d2.params.categorizer).ask(dsc)).then(function(ans){d2.state.cat=String(ans==null?'Outros':ans).trim();d2.state.busy=false;}).catch(function(){d2.state.cat='Outros';d2.state.busy=false;});});\n    d2.on('[data-add]','click',function(){var dsc=(d2.state.desc||'').trim(),amt=Number(d2.state.amt)||0;if(!dsc||!amt)return;d2.data().create({description:dsc,amount:amt,category:d2.state.cat||'Outros',date:new Date().toISOString()});d2.state.desc='';d2.state.amt='';d2.state.cat=null;d2.data().refresh();});\n  }\n}"}},"dataset":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"dataset"}}}},"categorizer":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"categorizer"}}}}}}}}}},{"_id":"6a2d8bc3e303c67716fa1ec2","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kPokedex","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>\"]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c];});}\nfunction idOf(u){var p=String(u||'').split('/').filter(Boolean);return p[p.length-1]||'0';}\nfunction cap(s){s=String(s||'').replace(/-/g,' ');return s.charAt(0).toUpperCase()+s.slice(1);}\nexport default {\n  css: `\n    .pk{height:100%;box-sizing:border-box;background:#f2f4f8;display:flex;flex-direction:column;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;overflow:hidden}\n    .hd{display:flex;align-items:center;gap:18px;padding:16px 22px;background:#dc0a2d;color:#fff;box-shadow:0 2px 8px rgba(0,0,0,.15);z-index:1}\n    .hd h1{margin:0;font-size:22px;font-weight:800;letter-spacing:-.01em}\n    .hd input{margin-left:auto;width:280px;padding:9px 14px;border:none;border-radius:20px;font:inherit;font-size:14px;outline:none}\n    .grid{flex:1;overflow:auto;padding:18px;display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));grid-auto-rows:170px;gap:14px;align-content:start}\n    .pc{background:linear-gradient(160deg,#fff,#eef1f6);border:1px solid #e3e7ee;border-radius:14px;display:flex;flex-direction:column;align-items:center;justify-content:center;position:relative;transition:.15s;box-shadow:0 1px 3px rgba(0,0,0,.05)}\n    .pc:hover{transform:translateY(-4px);box-shadow:0 10px 24px rgba(0,0,0,.12)}\n    .pid{position:absolute;top:8px;right:11px;font-size:11px;font-weight:700;color:#9aa3b2}\n    .pc img{width:96px;height:96px;object-fit:contain;image-rendering:auto}\n    .pn{font-size:13.5px;font-weight:700;color:#2b313b;margin-top:4px}\n    .empty{grid-column:1/-1;text-align:center;color:#9aa3b2;padding:50px;font-size:14px}\n  `,\n  render(d2){\n    var ds=d2.data(); var recs=ds?ds.records():[];\n    var q=(d2.state.q||'').toLowerCase();\n    var list=recs.filter(function(p){return !q||String(p.name||'').toLowerCase().indexOf(q)>=0;});\n    var cards=list.map(function(p){var id=idOf(p.url);var spr='https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/'+id+'.png';return '<div class=\"pc\"><span class=\"pid\">#'+String(id).padStart(3,'0')+'</span><img loading=\"lazy\" src=\"'+spr+'\" alt=\"'+esc(p.name)+'\"/><div class=\"pn\">'+esc(cap(p.name))+'</div></div>';}).join('');\n    return '<div class=\"pk\"><div class=\"hd\"><h1>⚡ Pokédex</h1><input data-q placeholder=\"Buscar Pokémon…\" value=\"'+esc(d2.state.q||'')+'\"/></div><div class=\"grid\">'+(list.length?cards:'<div class=\"empty\">Carregando da PokéAPI (Connect)…</div>')+'</div></div>';\n  },\n  mounted(d2){ d2.on('[data-q]','input',function(e,el){d2.state.q=el.value;}); }\n}"}},"dataset":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"dataset"}}}}}}}}}},{"_id":"6a2d8ce09b58f90d1c230949","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kSpotify","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>\"]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c];});}\nfunction mmss(s){s=Math.round(s||0);return Math.floor(s/60)+':'+String(s%60).padStart(2,'0');}\nexport default {\n  css: `\n    .sp{height:100%;box-sizing:border-box;display:flex;flex-direction:column;background:#121212;color:#fff;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;overflow:hidden}\n    .main{flex:1;display:flex;min-height:0}\n    .list{flex:1;overflow:auto;padding:20px 24px}\n    .h1{font-size:22px;font-weight:800;margin:0 0 16px}\n    .tr{display:flex;align-items:center;gap:14px;padding:8px 10px;border-radius:7px;cursor:pointer}\n    .tr:hover{background:#1a1a1a}.tr.on{background:#232323}\n    .num{width:18px;color:#9aa;font-size:13px;text-align:right;flex:0 0 auto}\n    .cov{width:42px;height:42px;border-radius:5px;flex:0 0 auto}\n    .ti{flex:1;min-width:0}.tt{font-size:14px;font-weight:600;color:#fff}.ta{font-size:12px;color:#9aa}\n    .dur{font-size:12px;color:#9aa;font-variant-numeric:tabular-nums}\n    .now{width:320px;flex:0 0 auto;background:#181818;padding:24px;display:flex;flex-direction:column;align-items:center;gap:16px;border-left:1px solid #282828}\n    .bigcov{width:220px;height:220px;border-radius:10px;box-shadow:0 12px 40px rgba(0,0,0,.5);display:flex;align-items:flex-end;padding:14px;box-sizing:border-box;font-size:40px}\n    .nt{font-size:20px;font-weight:800;text-align:center}.na{font-size:14px;color:#9aa}\n    .bar{width:100%;height:4px;background:#404040;border-radius:2px;overflow:hidden}.fill{height:100%;width:35%;background:#1db954}\n    .ctrls{display:flex;align-items:center;gap:22px;font-size:18px;color:#fff}\n    .play{width:52px;height:52px;border-radius:50%;background:#1db954;color:#000;border:none;font-size:20px;cursor:pointer;display:flex;align-items:center;justify-content:center}\n    .ph{color:#9aa;font-size:14px;text-align:center;margin:auto}\n  `,\n  render(d2){\n    var ds=d2.data(); var recs=ds?ds.records():[];\n    var cur=d2.state.cur, playing=d2.state.playing;\n    var rows=recs.map(function(t,i){var on=cur===t._id;return '<div class=\"tr'+(on?' on':'')+'\" data-id=\"'+t._id+'\"><span class=\"num\">'+(on&&playing?'▶':(i+1))+'</span><div class=\"cov\" style=\"background:linear-gradient(135deg,'+esc(t.color||'#444')+',#111)\"></div><div class=\"ti\"><div class=\"tt\">'+esc(t.title)+'</div><div class=\"ta\">'+esc(t.artist)+'</div></div><span class=\"dur\">'+mmss(t.duration)+'</span></div>';}).join('');\n    var c=recs.filter(function(x){return x._id===cur;})[0];\n    var now=c?'<div class=\"bigcov\" style=\"background:linear-gradient(135deg,'+esc(c.color||'#444')+',#111)\">🎵</div><div><div class=\"nt\">'+esc(c.title)+'</div><div class=\"na\">'+esc(c.artist)+' · '+esc(c.album)+'</div></div><div class=\"bar\"><div class=\"fill\"></div></div><div class=\"ctrls\">⏮<button class=\"play\" data-play>'+(playing?'❚❚':'▶')+'</button>⏭</div>':'<div class=\"ph\">Selecione uma faixa para tocar</div>';\n    return '<div class=\"sp\"><div class=\"main\"><div class=\"list\"><h1 class=\"h1\">🎧 Sua Biblioteca</h1>'+rows+'</div><div class=\"now\">'+now+'</div></div></div>';\n  },\n  mounted(d2){\n    d2.on('[data-id]','click',function(e,el){d2.state.cur=el.getAttribute('data-id');d2.state.playing=true;});\n    d2.on('[data-play]','click',function(){d2.state.playing=!d2.state.playing;});\n  }\n}"}},"dataset":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"dataset"}}}}}}}}}},{"_id":"6a2d8ce11b7164341d2efd56","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kNotion","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;'}[c];});}\nfunction md(src){var out=[],lines=String(src||'').split('\\n'),inL=false;function inl(t){return t.replace(/\\*\\*([^*]+)\\*\\*/g,'<b>$1</b>').replace(/`([^`]+)`/g,'<code>$1</code>');}for(var i=0;i<lines.length;i++){var l=esc(lines[i]);if(/^## /.test(l)){if(inL){out.push('</ul>');inL=false;}out.push('<h2>'+inl(l.slice(3))+'</h2>');}else if(/^# /.test(l)){if(inL){out.push('</ul>');inL=false;}out.push('<h1>'+inl(l.slice(2))+'</h1>');}else if(/^- /.test(l)){if(!inL){out.push('<ul>');inL=true;}out.push('<li>'+inl(l.slice(2))+'</li>');}else if(l.trim()===''){if(inL){out.push('</ul>');inL=false;}}else{if(inL){out.push('</ul>');inL=false;}out.push('<p>'+inl(l)+'</p>');}}if(inL)out.push('</ul>');return out.join('');}\nexport default {\n  css: `\n    .no{height:100%;box-sizing:border-box;display:flex;background:#fff;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;overflow:hidden;color:#37352f}\n    .side{width:260px;flex:0 0 auto;background:#fbfbfa;border-right:1px solid #ededec;padding:14px 8px;overflow:auto}\n    .st{font-size:12px;font-weight:600;color:#9b9a97;padding:6px 10px;text-transform:uppercase;letter-spacing:.04em}\n    .pg{display:flex;align-items:center;gap:8px;padding:7px 10px;border-radius:6px;cursor:pointer;font-size:14px}\n    .pg:hover{background:#efefee}.pg.on{background:#e9e9e7;font-weight:600}\n    .pi{font-size:16px}\n    .doc{flex:1;overflow:auto;padding:48px 70px}\n    .doc h1{font-size:32px;font-weight:800;margin:0 0 14px}.doc h2{font-size:21px;margin:22px 0 8px}\n    .doc p{font-size:15px;line-height:1.7;color:#37352f;margin:7px 0}.doc ul{margin:8px 0;padding-left:24px}.doc li{font-size:15px;line-height:1.7;margin:3px 0}\n    .doc code{background:#f1f1ef;padding:2px 6px;border-radius:4px;font-size:13px;font-family:ui-monospace,Menlo,monospace}.doc b{font-weight:700}\n    .ttl{display:flex;align-items:center;gap:12px;margin-bottom:8px}.ttl .big{font-size:42px}\n  `,\n  render(d2){\n    var ds=d2.data(); var recs=ds?ds.records():[];\n    var sel=d2.state.sel||(recs[0]&&recs[0]._id);\n    var nav=recs.map(function(p){return '<div class=\"pg'+(sel===p._id?' on':'')+'\" data-id=\"'+p._id+'\"><span class=\"pi\">'+esc(p.icon||'📄')+'</span>'+esc(p.title)+'</div>';}).join('');\n    var pg=recs.filter(function(x){return x._id===sel;})[0];\n    var doc=pg?'<div class=\"ttl\"><span class=\"big\">'+esc(pg.icon||'')+'</span></div>'+md(pg.content):'<p>Sem páginas</p>';\n    return '<div class=\"no\"><div class=\"side\"><div class=\"st\">Workspace</div>'+nav+'</div><div class=\"doc\">'+doc+'</div></div>';\n  },\n  mounted(d2){ d2.on('[data-id]','click',function(e,el){d2.state.sel=el.getAttribute('data-id');}); }\n}"}},"dataset":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"dataset"}}}}}}}}}},{"_id":"6a2d8ce11b1e52cefa121178","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kBanking","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;'}[c];});}\nfunction brl(n){return (Number(n)||0).toLocaleString('pt-BR',{style:'currency',currency:'BRL'});}\nexport default {\n  css: `\n    .bk{height:100%;box-sizing:border-box;display:flex;background:#0a0e1a;color:#e8edf5;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;overflow:hidden}\n    .left{flex:1;padding:24px 28px;overflow:auto}\n    .bal{background:linear-gradient(135deg,#4f46e5,#7c3aed);border-radius:18px;padding:24px;margin-bottom:18px}\n    .bl{font-size:13px;opacity:.85}.bv{font-size:38px;font-weight:800;margin-top:4px;font-variant-numeric:tabular-nums}\n    .kpis{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin-bottom:20px}\n    .kpi{background:#141a2e;border:1px solid #232c45;border-radius:13px;padding:16px}\n    .kl{font-size:12px;color:#8b97b5}.kv{font-size:22px;font-weight:800;margin-top:5px;font-variant-numeric:tabular-nums}\n    .ct{font-size:13px;font-weight:700;color:#8b97b5;text-transform:uppercase;letter-spacing:.04em;margin:6px 0 12px}\n    .bars{display:flex;flex-direction:column;gap:9px}\n    .brow{display:flex;align-items:center;gap:10px;font-size:12.5px}\n    .bn{width:96px;color:#aab4cf;flex:0 0 auto}\n    .bw{flex:1;background:#1a2138;border-radius:6px;height:18px;overflow:hidden}.bf{height:100%;background:linear-gradient(90deg,#6366f1,#a855f7)}\n    .bamt{width:90px;text-align:right;font-variant-numeric:tabular-nums;flex:0 0 auto}\n    .right{width:380px;flex:0 0 auto;background:#0d1322;border-left:1px solid #1c2438;display:flex;flex-direction:column}\n    .rh{padding:18px 20px;font-size:14px;font-weight:700;border-bottom:1px solid #1c2438}\n    .list{flex:1;overflow:auto}\n    .tx{display:flex;align-items:center;gap:12px;padding:12px 20px;border-bottom:1px solid #161d30}\n    .ti{width:36px;height:36px;border-radius:10px;display:flex;align-items:center;justify-content:center;font-size:16px;flex:0 0 auto}\n    .td{font-size:13.5px;font-weight:500}.tc{font-size:11px;color:#8b97b5}\n    .tam{margin-left:auto;font-weight:700;font-variant-numeric:tabular-nums}\n  `,\n  render(d2){\n    var ds=d2.data(); var recs=ds?ds.records():[];\n    var inc=recs.filter(function(t){return t.type==='in';}).reduce(function(s,t){return s+(Number(t.amount)||0);},0);\n    var out=recs.filter(function(t){return t.type==='out';}).reduce(function(s,t){return s+(Number(t.amount)||0);},0);\n    var bal=inc-out;\n    var byCat={};recs.filter(function(t){return t.type==='out';}).forEach(function(t){var c=t.category||'Outros';byCat[c]=(byCat[c]||0)+(Number(t.amount)||0);});\n    var cats=Object.keys(byCat).sort(function(a,b){return byCat[b]-byCat[a];});var mx=Math.max.apply(null,cats.map(function(c){return byCat[c];}))||1;\n    var bars=cats.map(function(c){return '<div class=\"brow\"><span class=\"bn\">'+esc(c)+'</span><div class=\"bw\"><div class=\"bf\" style=\"width:'+(byCat[c]/mx*100).toFixed(0)+'%\"></div></div><span class=\"bamt\">'+brl(byCat[c])+'</span></div>';}).join('');\n    var rows=recs.slice().reverse().map(function(t){var io=t.type==='in';return '<div class=\"tx\"><div class=\"ti\" style=\"background:'+(io?'#0c2a1c':'#2a1320')+';color:'+(io?'#4ade80':'#f87171')+'\">'+(io?'↓':'↑')+'</div><div><div class=\"td\">'+esc(t.description)+'</div><div class=\"tc\">'+esc(t.category||'')+'</div></div><div class=\"tam\" style=\"color:'+(io?'#4ade80':'#e8edf5')+'\">'+(io?'+':'-')+brl(t.amount)+'</div></div>';}).join('');\n    return '<div class=\"bk\"><div class=\"left\"><div class=\"bal\"><div class=\"bl\">Saldo disponível</div><div class=\"bv\">'+brl(bal)+'</div></div><div class=\"kpis\"><div class=\"kpi\"><div class=\"kl\">↓ Entradas</div><div class=\"kv\" style=\"color:#4ade80\">'+brl(inc)+'</div></div><div class=\"kpi\"><div class=\"kl\">↑ Saídas</div><div class=\"kv\" style=\"color:#f87171\">'+brl(out)+'</div></div></div><div class=\"ct\">Gastos por categoria</div><div class=\"bars\">'+bars+'</div></div><div class=\"right\"><div class=\"rh\">Transações recentes</div><div class=\"list\">'+rows+'</div></div></div>';\n  }\n}"}},"dataset":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"dataset"}}}}}}}}}},{"_id":"6a2d8ce1dbf815e74e99177d","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kHabits","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;'}[c];});}\nexport default {\n  css: `\n    .hb{height:100%;box-sizing:border-box;background:#f8fafc;padding:24px 28px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;overflow:auto;color:#0f172a}\n    .hd h1{margin:0;font-size:22px;font-weight:800}.hd p{margin:4px 0 20px;font-size:13px;color:#64748b}\n    .grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:16px}\n    .card{background:#fff;border:1px solid #e2e8f0;border-radius:16px;padding:18px;box-shadow:0 1px 3px rgba(0,0,0,.04)}\n    .top{display:flex;align-items:center;gap:10px}\n    .em{font-size:30px}.nm{font-size:15px;font-weight:700;flex:1}\n    .streak{font-size:13px;color:#f59e0b;font-weight:700;margin:12px 0 8px}\n    .prog{height:7px;background:#f1f5f9;border-radius:4px;overflow:hidden}.pf{height:100%;background:linear-gradient(90deg,#10b981,#34d399)}\n    .pm{font-size:11px;color:#94a3b8;margin-top:5px}\n    .btn{width:100%;margin-top:14px;padding:10px;border-radius:10px;border:none;font:inherit;font-size:13px;font-weight:700;cursor:pointer;transition:.15s}\n    .btn.todo{background:#eef2ff;color:#4f46e5}.btn.todo:hover{background:#e0e7ff}\n    .btn.done{background:#10b981;color:#fff}\n  `,\n  render(d2){\n    var ds=d2.data(); var recs=ds?ds.records():[];\n    var doneCount=recs.filter(function(h){return h.doneToday;}).length;\n    var cards=recs.map(function(h){var pct=Math.min(100,Math.round((h.streak||0)/(h.target||7)*100));return '<div class=\"card\"><div class=\"top\"><span class=\"em\">'+esc(h.emoji||'✅')+'</span><span class=\"nm\">'+esc(h.name)+'</span></div><div class=\"streak\">🔥 '+(h.streak||0)+' dias seguidos</div><div class=\"prog\"><div class=\"pf\" style=\"width:'+pct+'%\"></div></div><div class=\"pm\">meta: '+(h.target||7)+' dias/semana</div><button class=\"btn '+(h.doneToday?'done':'todo')+'\" data-id=\"'+h._id+'\">'+(h.doneToday?'✓ Feito hoje':'Marcar como feito')+'</button></div>';}).join('');\n    return '<div class=\"hb\"><div class=\"hd\"><h1>Meus Hábitos</h1><p>'+doneCount+' de '+recs.length+' concluídos hoje · continue assim!</p></div><div class=\"grid\">'+cards+'</div></div>';\n  },\n  mounted(d2){\n    d2.on('[data-id]','click',function(e,el){var id=el.getAttribute('data-id');var h=d2.data().records().filter(function(x){return x._id===id;})[0];if(!h)return;var nd=!h.doneToday;d2.data().update({_id:id,doneToday:nd,streak:Math.max(0,(h.streak||0)+(nd?1:-1))});});\n  }\n}"}},"dataset":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"dataset"}}}}}}}}}},{"_id":"6a2d8ce2baacaeb326293ee7","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kSocial","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>\"]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c];});}\nfunction rel(ts){var d=new Date(ts);if(isNaN(d.getTime()))return '';var df=(Date.now()-d.getTime())/1000;if(df<60)return 'agora';if(df<3600)return Math.floor(df/60)+'min';if(df<86400)return Math.floor(df/3600)+'h';return Math.floor(df/86400)+'d';}\nexport default {\n  css: `\n    .so{height:100%;box-sizing:border-box;display:flex;justify-content:center;background:#000;color:#e7e9ea;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;overflow:hidden}\n    .col{width:600px;max-width:100%;border-left:1px solid #2f3336;border-right:1px solid #2f3336;display:flex;flex-direction:column}\n    .hd{padding:14px 18px;font-size:19px;font-weight:800;border-bottom:1px solid #2f3336;backdrop-filter:blur(4px)}\n    .comp{display:flex;gap:12px;padding:14px 18px;border-bottom:10px solid #16181c}\n    .av{width:44px;height:44px;border-radius:50%;background:#16181c;display:flex;align-items:center;justify-content:center;font-size:22px;flex:0 0 auto}\n    .cin{flex:1;display:flex;flex-direction:column;gap:8px}\n    .cin textarea{background:none;border:none;outline:none;color:#e7e9ea;font:inherit;font-size:18px;resize:none;min-height:48px}\n    .cb{align-self:flex-end;background:#1d9bf0;color:#fff;border:none;padding:8px 18px;border-radius:20px;font:inherit;font-weight:700;cursor:pointer}.cb:disabled{opacity:.5}\n    .feed{flex:1;overflow:auto}\n    .post{display:flex;gap:12px;padding:14px 18px;border-bottom:1px solid #2f3336}\n    .pb{flex:1;min-width:0}\n    .pr{display:flex;align-items:center;gap:6px;font-size:14px}\n    .pa{font-weight:700}.ph{color:#71767b}.pt{color:#71767b}\n    .ptx{font-size:15px;line-height:1.4;margin:3px 0 10px;white-space:pre-wrap;word-break:break-word}\n    .acts{display:flex;gap:60px;color:#71767b;font-size:13px}\n    .act{display:flex;align-items:center;gap:7px;cursor:pointer}\n    .act:hover{color:#1d9bf0}.act.liked{color:#f91880}.act.rt:hover{color:#00ba7c}\n  `,\n  render(d2){\n    var ds=d2.data(); var recs=ds?ds.records():[];\n    var liked=d2.state.liked||{};\n    var posts=recs.slice().sort(function(a,b){return new Date(b.ts)-new Date(a.ts);}).map(function(p){var isL=liked[p._id];return '<div class=\"post\"><div class=\"av\">'+esc(p.avatar||'👤')+'</div><div class=\"pb\"><div class=\"pr\"><span class=\"pa\">'+esc(p.author)+'</span><span class=\"ph\">@'+esc(p.handle)+'</span><span class=\"pt\">· '+rel(p.ts)+'</span></div><div class=\"ptx\">'+esc(p.text)+'</div><div class=\"acts\"><span class=\"act rt\" data-rt=\"'+p._id+'\">🔁 '+(p.reposts||0)+'</span><span class=\"act'+(isL?' liked':'')+'\" data-like=\"'+p._id+'\">'+(isL?'❤️':'🤍')+' '+(p.likes||0)+'</span></div></div></div>';}).join('');\n    return '<div class=\"so\"><div class=\"col\"><div class=\"hd\">Início</div><div class=\"comp\"><div class=\"av\">😎</div><div class=\"cin\"><textarea data-draft placeholder=\"O que está acontecendo?\">'+esc(d2.state.draft||'')+'</textarea><button class=\"cb\" data-post>Postar</button></div></div><div class=\"feed\">'+posts+'</div></div></div>';\n  },\n  mounted(d2){\n    d2.on('[data-draft]','input',function(e,el){d2.state.draft=el.value;});\n    d2.on('[data-like]','click',function(e,el){var id=el.getAttribute('data-like');var liked=Object.assign({},d2.state.liked||{});var p=d2.data().records().filter(function(x){return x._id===id;})[0];if(!p)return;var was=liked[id];liked[id]=!was;d2.state.liked=liked;d2.data().update({_id:id,likes:Math.max(0,(p.likes||0)+(was?-1:1))});});\n    d2.on('[data-rt]','click',function(e,el){var id=el.getAttribute('data-rt');var p=d2.data().records().filter(function(x){return x._id===id;})[0];if(!p)return;d2.data().update({_id:id,reposts:(p.reposts||0)+1});});\n    d2.on('[data-post]','click',function(){var t=(d2.state.draft||'').trim();if(!t)return;d2.data().create({author:'Você',handle:'voce',avatar:'😎',text:t,likes:0,reposts:0,ts:new Date().toISOString()});d2.state.draft='';d2.data().refresh();});\n  }\n}"}},"dataset":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"dataset"}}}}}}}}}},{"_id":"6a2d8e1bdbf815e74e991a3c","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kCalApp","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>\"]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c];});}\nexport default {\n  css: `\n    .ca{height:100%;box-sizing:border-box;background:#fff;padding:20px 24px;display:flex;flex-direction:column;gap:14px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;color:#1f2937;overflow:hidden}\n    .hd{display:flex;align-items:baseline;gap:12px}.hd h1{margin:0;font-size:22px;font-weight:800}.hd .sub{font-size:13px;color:#9ca3af}\n    .dow{display:grid;grid-template-columns:repeat(7,1fr);gap:6px}\n    .dn{text-align:center;font-size:11px;font-weight:700;color:#9ca3af;text-transform:uppercase;padding-bottom:4px}\n    .grid{flex:1;display:grid;grid-template-columns:repeat(7,1fr);grid-auto-rows:1fr;gap:6px;min-height:0}\n    .cell{border:1px solid #f0f1f3;border-radius:9px;padding:6px;display:flex;flex-direction:column;gap:3px;overflow:hidden}\n    .cell.empty{border:none}\n    .dnum{font-size:12px;font-weight:600;color:#6b7280}\n    .cell.today .dnum{background:#4f46e5;color:#fff;width:22px;height:22px;border-radius:50%;display:flex;align-items:center;justify-content:center}\n    .ev{font-size:10px;font-weight:600;color:#fff;padding:2px 5px;border-radius:4px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n  `,\n  render(d2){\n    var ds=d2.data(); var recs=ds?ds.records():[];\n    var y=2026,m=5;\n    var first=new Date(y,m,1).getDay(),dim=new Date(y,m+1,0).getDate();\n    var today=15;\n    var dn=['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'].map(function(d){return '<div class=\"dn\">'+d+'</div>';}).join('');\n    var cells='';\n    for(var i=0;i<first;i++)cells+='<div class=\"cell empty\"></div>';\n    for(var d=1;d<=dim;d++){\n      var evs=recs.filter(function(e){return e.day===d;}).map(function(e){return '<div class=\"ev\" style=\"background:'+esc(e.color||'#6b7280')+'\" title=\"'+esc(e.time+' '+e.title)+'\">'+esc(e.title)+'</div>';}).join('');\n      cells+='<div class=\"cell'+(d===today?' today':'')+'\"><div class=\"dnum\">'+d+'</div>'+evs+'</div>';\n    }\n    return '<div class=\"ca\"><div class=\"hd\"><h1>Junho 2026</h1><span class=\"sub\">'+recs.length+' eventos</span></div><div class=\"dow\">'+dn+'</div><div class=\"grid\">'+cells+'</div></div>';\n  }\n}"}},"dataset":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"dataset"}}}}}}}}}},{"_id":"6a2d8e1bed4fc677c360c5e0","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kJobs","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>\"]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c];});}\nvar MOD={'Remoto':['#dcfce7','#15803d'],'Híbrido':['#dbeafe','#1d4ed8'],'Presencial':['#fef3c7','#b45309']};\nexport default {\n  css: `\n    .jb{height:100%;box-sizing:border-box;background:#f8fafc;padding:24px 28px;display:flex;flex-direction:column;gap:16px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;color:#0f172a;overflow:hidden}\n    .hd{display:flex;align-items:center;gap:14px}.hd h1{margin:0;font-size:22px;font-weight:800}\n    .filt{display:flex;gap:8px;margin-left:auto}\n    .chip{font-size:12px;font-weight:600;padding:6px 13px;border-radius:20px;border:1px solid #e2e8f0;background:#fff;color:#475569;cursor:pointer}.chip.on{background:#4f46e5;color:#fff;border-color:#4f46e5}\n    .list{flex:1;overflow:auto;display:flex;flex-direction:column;gap:12px}\n    .job{display:flex;gap:16px;background:#fff;border:1px solid #e2e8f0;border-radius:14px;padding:18px 20px;align-items:center;box-shadow:0 1px 2px rgba(0,0,0,.04);transition:.15s}\n    .job:hover{border-color:#cbd5e1;box-shadow:0 4px 12px rgba(0,0,0,.07)}\n    .logo{width:52px;height:52px;border-radius:12px;background:#f1f5f9;display:flex;align-items:center;justify-content:center;font-size:26px;flex:0 0 auto}\n    .ji{flex:1;min-width:0}\n    .jt{font-size:16px;font-weight:700}.jc{font-size:13px;color:#64748b;margin-top:2px}\n    .tags{display:flex;gap:6px;margin-top:8px;flex-wrap:wrap}.tag{font-size:11px;color:#475569;background:#f1f5f9;padding:2px 9px;border-radius:6px}\n    .jr{text-align:right;flex:0 0 auto}\n    .sal{font-size:14px;font-weight:700;color:#16a34a}.mod{font-size:11px;font-weight:700;padding:3px 9px;border-radius:6px;margin-top:6px;display:inline-block}\n  `,\n  render(d2){\n    var ds=d2.data(); var recs=ds?ds.records():[];\n    var f=d2.state.f||'all';\n    var list=recs.filter(function(j){return f==='all'||j.modality===f;});\n    var chips=['all','Remoto','Híbrido','Presencial'].map(function(k){return '<span class=\"chip'+(f===k?' on':'')+'\" data-f=\"'+k+'\">'+(k==='all'?'Todas':k)+'</span>';}).join('');\n    var jobs=list.map(function(j){var m=MOD[j.modality]||['#f1f5f9','#475569'];var tags=String(j.tags||'').split(',').filter(Boolean).map(function(t){return '<span class=\"tag\">'+esc(t)+'</span>';}).join('');return '<div class=\"job\"><div class=\"logo\">'+esc(j.logo||'🏢')+'</div><div class=\"ji\"><div class=\"jt\">'+esc(j.title)+'</div><div class=\"jc\">'+esc(j.company)+' · '+esc(j.location)+'</div><div class=\"tags\">'+tags+'</div></div><div class=\"jr\"><div class=\"sal\">'+esc(j.salary)+'</div><span class=\"mod\" style=\"background:'+m[0]+';color:'+m[1]+'\">'+esc(j.modality)+'</span></div></div>';}).join('');\n    return '<div class=\"jb\"><div class=\"hd\"><h1>💼 Vagas</h1><div class=\"filt\">'+chips+'</div></div><div class=\"list\">'+jobs+'</div></div>';\n  },\n  mounted(d2){ d2.on('[data-f]','click',function(e,el){d2.state.f=el.getAttribute('data-f');}); }\n}"}},"dataset":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"dataset"}}}}}}}}}},{"_id":"6a2d8e1cbaacaeb326294174","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kRealEstate","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>\"]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c];});}\nfunction brl(n){n=Number(n)||0;return n>=1000000?'R$ '+(n/1000000).toFixed(2).replace('.',',')+'M':'R$ '+(n/1000).toFixed(0)+'k';}\nexport default {\n  css: `\n    .re{height:100%;box-sizing:border-box;background:#f9fafb;padding:24px 28px;display:flex;flex-direction:column;gap:16px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;color:#111827;overflow:hidden}\n    .hd h1{margin:0;font-size:22px;font-weight:800}.hd p{margin:3px 0 0;font-size:13px;color:#6b7280}\n    .grid{flex:1;overflow:auto;display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));grid-auto-rows:300px;gap:18px;align-content:start}\n    .card{background:#fff;border:1px solid #e5e7eb;border-radius:16px;overflow:hidden;display:flex;flex-direction:column;box-shadow:0 1px 3px rgba(0,0,0,.05);transition:.15s}\n    .card:hover{transform:translateY(-4px);box-shadow:0 12px 28px rgba(0,0,0,.12)}\n    .photo{height:150px;display:flex;align-items:flex-start;justify-content:space-between;padding:12px}\n    .kind{background:rgba(255,255,255,.9);color:#374151;font-size:11px;font-weight:700;padding:3px 9px;border-radius:6px}\n    .fav{font-size:18px}\n    .body{padding:14px 16px;flex:1;display:flex;flex-direction:column}\n    .price{font-size:21px;font-weight:800;color:#111827}\n    .ttl{font-size:14px;font-weight:600;margin:4px 0 2px}.loc{font-size:12px;color:#6b7280}\n    .specs{display:flex;gap:14px;margin-top:auto;padding-top:12px;border-top:1px solid #f3f4f6;font-size:12px;color:#4b5563}\n  `,\n  render(d2){\n    var ds=d2.data(); var recs=ds?ds.records():[];\n    var cards=recs.map(function(p){return '<div class=\"card\"><div class=\"photo\" style=\"background:linear-gradient(135deg,'+esc(p.color||'#6366f1')+',#1e293b)\"><span class=\"kind\">'+esc(p.kind)+'</span><span class=\"fav\">🤍</span></div><div class=\"body\"><div class=\"price\">'+brl(p.price)+'</div><div class=\"ttl\">'+esc(p.title)+'</div><div class=\"loc\">📍 '+esc(p.city)+'</div><div class=\"specs\"><span>🛏️ '+p.beds+'</span><span>🛁 '+p.baths+'</span><span>📏 '+p.area+'m²</span></div></div></div>';}).join('');\n    return '<div class=\"re\"><div class=\"hd\"><h1>🏠 Imóveis à venda</h1><p>'+recs.length+' propriedades disponíveis</p></div><div class=\"grid\">'+cards+'</div></div>';\n  }\n}"}},"dataset":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"dataset"}}}}}}}}}},{"_id":"6a2d8e1c58bb101c90947afc","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kFitness","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;'}[c];});}\nexport default {\n  css: `\n    .fit{height:100%;box-sizing:border-box;background:#0c0a1d;color:#ece9ff;padding:24px 28px;display:flex;flex-direction:column;gap:18px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;overflow:auto}\n    .hd h1{margin:0;font-size:22px;font-weight:800}.hd p{margin:3px 0 0;font-size:13px;color:#9d96c9}\n    .kpis{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}\n    .kpi{background:linear-gradient(135deg,#1a1535,#12102a);border:1px solid #2a2350;border-radius:16px;padding:18px}\n    .kl{font-size:12px;color:#9d96c9}.kv{font-size:28px;font-weight:800;margin-top:4px}\n    .chart{display:flex;align-items:flex-end;gap:10px;height:120px;padding:6px 0}\n    .bar{flex:1;display:flex;flex-direction:column;align-items:center;gap:6px;height:100%;justify-content:flex-end}\n    .bf{width:100%;border-radius:6px 6px 0 0;background:linear-gradient(180deg,#a855f7,#6366f1);min-height:4px}\n    .bl{font-size:11px;color:#9d96c9}\n    .list{display:flex;flex-direction:column;gap:9px}\n    .w{display:flex;align-items:center;gap:13px;background:#15122e;border:1px solid #251f48;border-radius:12px;padding:13px 16px}\n    .we{font-size:24px}.wn{font-size:14px;font-weight:600}.wt{font-size:12px;color:#9d96c9}\n    .wr{margin-left:auto;text-align:right;font-size:12px;color:#c4bdf0}\n  `,\n  render(d2){\n    var ds=d2.data(); var recs=ds?ds.records():[];\n    var totMin=recs.reduce(function(s,w){return s+(Number(w.duration)||0);},0);\n    var totCal=recs.reduce(function(s,w){return s+(Number(w.calories)||0);},0);\n    var mx=Math.max.apply(null,recs.map(function(w){return Number(w.calories)||0;}))||1;\n    var bars=recs.map(function(w){return '<div class=\"bar\"><div class=\"bf\" style=\"height:'+((Number(w.calories)||0)/mx*100).toFixed(0)+'%\"></div><span class=\"bl\">'+esc(w.day)+'</span></div>';}).join('');\n    var rows=recs.map(function(w){return '<div class=\"w\"><span class=\"we\">'+esc(w.emoji||'💪')+'</span><div><div class=\"wn\">'+esc(w.name)+'</div><div class=\"wt\">'+esc(w.type)+' · '+esc(w.day)+'</div></div><div class=\"wr\">'+w.duration+' min<br>'+w.calories+' kcal</div></div>';}).join('');\n    return '<div class=\"fit\"><div class=\"hd\"><h1>💪 Meus Treinos</h1><p>Semana atual · '+recs.length+' sessões</p></div><div class=\"kpis\"><div class=\"kpi\"><div class=\"kl\">Tempo total</div><div class=\"kv\">'+Math.floor(totMin/60)+'h '+(totMin%60)+'m</div></div><div class=\"kpi\"><div class=\"kl\">Calorias</div><div class=\"kv\">'+totCal.toLocaleString('pt-BR')+'</div></div><div class=\"kpi\"><div class=\"kl\">Sessões</div><div class=\"kv\">'+recs.length+'</div></div></div><div class=\"chart\">'+bars+'</div><div class=\"list\">'+rows+'</div></div>';\n  }\n}"}},"dataset":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"dataset"}}}}}}}}}},{"_id":"6a2d8e1c5284d6e4f90a155a","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kWeather","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"var CITIES=[{n:'São Paulo',lat:-23.55,lon:-46.63},{n:'Rio de Janeiro',lat:-22.91,lon:-43.17},{n:'Belo Horizonte',lat:-19.92,lon:-43.94},{n:'Brasília',lat:-15.78,lon:-47.93},{n:'Porto Alegre',lat:-30.03,lon:-51.23},{n:'Recife',lat:-8.05,lon:-34.88}];\nfunction icon(c){if(c==null)return '❓';if(c===0)return '☀️';if(c<=3)return '⛅';if(c<=48)return '🌫️';if(c<=67)return '🌧️';if(c<=77)return '❄️';if(c<=82)return '🌦️';return '⛈️';}\nexport default {\n  css: `\n    .we{height:100%;box-sizing:border-box;background:linear-gradient(160deg,#1e3a8a,#0c1a3d);color:#fff;padding:26px 30px;display:flex;flex-direction:column;gap:18px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;overflow:auto}\n    .hd{display:flex;align-items:center}.hd h1{margin:0;font-size:23px;font-weight:800}.hd .rf{margin-left:auto;font-size:12px;color:#bcd;cursor:pointer;background:rgba(255,255,255,.12);padding:7px 13px;border-radius:8px}\n    .grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:16px}\n    .card{background:rgba(255,255,255,.1);border:1px solid rgba(255,255,255,.15);border-radius:18px;padding:20px;backdrop-filter:blur(6px)}\n    .cn{font-size:15px;font-weight:600;opacity:.9}\n    .row{display:flex;align-items:center;justify-content:space-between;margin-top:8px}\n    .temp{font-size:42px;font-weight:800}.ico{font-size:46px}\n    .mm{font-size:13px;opacity:.8;margin-top:6px}.wind{font-size:12px;opacity:.7;margin-top:3px}\n    .load{opacity:.6;font-size:13px}\n  `,\n  render(d2){\n    var w=d2.state.w||{};\n    var cards=CITIES.map(function(c){var d=w[c.n];if(!d)return '<div class=\"card\"><div class=\"cn\">'+c.n+'</div><div class=\"load\">carregando…</div></div>';return '<div class=\"card\"><div class=\"cn\">'+c.n+'</div><div class=\"row\"><span class=\"temp\">'+Math.round(d.t)+'°</span><span class=\"ico\">'+icon(d.code)+'</span></div><div class=\"mm\">↑ '+Math.round(d.max)+'°  ↓ '+Math.round(d.min)+'°</div><div class=\"wind\">💨 '+Math.round(d.wind)+' km/h</div></div>';}).join('');\n    return '<div class=\"we\"><div class=\"hd\"><h1>⛅ Clima agora</h1><span class=\"rf\" data-refresh>↻ Atualizar</span></div><div class=\"grid\">'+cards+'</div></div>';\n  },\n  mounted(d2){\n    function load(){CITIES.forEach(function(c){fetch('https://api.open-meteo.com/v1/forecast?latitude='+c.lat+'&longitude='+c.lon+'&current=temperature_2m,weather_code,wind_speed_10m&daily=temperature_2m_max,temperature_2m_min&timezone=auto').then(function(r){return r.json();}).then(function(j){if(!j||!j.current)return;var nw=Object.assign({},d2.state.w||{});nw[c.n]={t:j.current.temperature_2m,code:j.current.weather_code,wind:j.current.wind_speed_10m,max:j.daily.temperature_2m_max[0],min:j.daily.temperature_2m_min[0]};d2.state.w=nw;}).catch(function(){});});}\n    load();\n    d2.on('[data-refresh]','click',load);\n  }\n}"}}}}}}}},{"_id":"6a2d902a58bb101c90947eab","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kNetflix","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>\"]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c];});}\nexport default {\n  css: `\n    .nf{height:100%;overflow:auto;background:#141414;color:#fff;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif}\n    .top{display:flex;align-items:center;gap:24px;padding:16px 40px;position:sticky;top:0;background:linear-gradient(180deg,#141414,rgba(20,20,20,.6));z-index:5}\n    .logo{color:#e50914;font-size:26px;font-weight:900;letter-spacing:-1px}\n    .nav{font-size:13px;color:#e5e5e5;display:flex;gap:18px}\n    .hero{height:420px;position:relative;display:flex;flex-direction:column;justify-content:flex-end;padding:40px;background-size:cover;background-position:center}\n    .hero::after{content:'';position:absolute;inset:0;background:linear-gradient(90deg,rgba(20,20,20,.9),rgba(20,20,20,.2)),linear-gradient(0deg,#141414,transparent 60%)}\n    .hc{position:relative;z-index:1;max-width:560px}\n    .ht{font-size:44px;font-weight:900;margin:0 0 12px}\n    .hmeta{display:flex;gap:12px;font-size:14px;color:#46d369;font-weight:700;margin-bottom:10px}\n    .hd{font-size:15px;line-height:1.5;color:#ddd}\n    .hbtns{display:flex;gap:12px;margin-top:18px}\n    .hbtns button{border:none;border-radius:5px;padding:11px 26px;font:inherit;font-size:15px;font-weight:700;cursor:pointer}\n    .play{background:#fff;color:#000}.info{background:rgba(109,109,110,.7);color:#fff}\n    .rows{padding:10px 40px 40px}\n    .row{margin-bottom:26px}.rt{font-size:18px;font-weight:700;margin-bottom:12px}\n    .strip{display:flex;gap:10px;overflow-x:auto;padding-bottom:6px}\n    .card{width:150px;height:220px;flex:0 0 auto;border-radius:6px;overflow:hidden;background-size:cover;background-position:center;cursor:pointer;transition:.2s;position:relative}\n    .card:hover{transform:scale(1.06)}\n    .badge{position:absolute;top:6px;left:6px;background:#e50914;font-size:9px;font-weight:800;padding:2px 5px;border-radius:3px}\n    .cap{position:absolute;bottom:0;left:0;right:0;padding:18px 8px 6px;background:linear-gradient(0deg,rgba(0,0,0,.85),transparent);font-size:12px;font-weight:600}\n  `,\n  render(d2){\n    var ds=d2.data(); var recs=ds?ds.records():[];\n    if(!recs.length) return '<div class=\"nf\"><div style=\"padding:60px;color:#888\">Carregando catálogo…</div></div>';\n    var hero=recs.filter(function(m){return m.trending;})[0]||recs[0];\n    var cats={};recs.forEach(function(m){var c=m.category||'Outros';(cats[c]=cats[c]||[]).push(m);});\n    var rows=Object.keys(cats).map(function(c){var strip=cats[c].map(function(m){return '<div class=\"card\" style=\"background-image:url('+esc(m.poster)+')\">'+(m.trending?'<span class=\"badge\">EM ALTA</span>':'')+'<div class=\"cap\">'+esc(m.title)+'</div></div>';}).join('');return '<div class=\"row\"><div class=\"rt\">'+esc(c)+'</div><div class=\"strip\">'+strip+'</div></div>';}).join('');\n    return '<div class=\"nf\"><div class=\"top\"><span class=\"logo\">DATAFLIX</span><div class=\"nav\"><span>Início</span><span>Séries</span><span>Filmes</span><span>Minha Lista</span></div></div><div class=\"hero\" style=\"background-image:url('+esc(hero.backdrop||hero.poster)+')\"><div class=\"hc\"><h1 class=\"ht\">'+esc(hero.title)+'</h1><div class=\"hmeta\"><span>'+Math.round((hero.rating||0)*10)+'% relevante</span><span style=\"color:#fff\">'+esc(hero.year)+'</span><span style=\"color:#fff\">'+(hero.duration||0)+' min</span></div><div class=\"hd\">'+esc(hero.description)+'</div><div class=\"hbtns\"><button class=\"play\">▶ Assistir</button><button class=\"info\">ⓘ Mais informações</button></div></div></div><div class=\"rows\">'+rows+'</div></div>';\n  }\n}"}},"dataset":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"dataset"}}}}}}}}}},{"_id":"6a2d902b1b7164341d2f038a","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kSurvey","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>\"]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c];});}\nexport default {\n  css: `\n    .sv{height:100%;box-sizing:border-box;display:flex;background:#f8fafc;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;color:#0f172a;overflow:hidden}\n    .left{width:380px;flex:0 0 auto;border-right:1px solid #e2e8f0;background:#fff;padding:26px;display:flex;flex-direction:column;gap:22px}\n    .h1{font-size:20px;font-weight:800;margin:0}\n    .big{text-align:center}.bv{font-size:50px;font-weight:900;color:#4f46e5}.bl{font-size:13px;color:#64748b}\n    .kpis{display:grid;grid-template-columns:1fr 1fr;gap:12px}\n    .kpi{background:#f8fafc;border:1px solid #e2e8f0;border-radius:12px;padding:14px;text-align:center}\n    .kv{font-size:24px;font-weight:800}.kl{font-size:11px;color:#64748b;margin-top:3px}\n    .dist{display:flex;flex-direction:column;gap:7px}\n    .dr{display:flex;align-items:center;gap:10px;font-size:13px}\n    .ds{width:34px;color:#475569}.dbar{flex:1;height:10px;background:#eef2f6;border-radius:5px;overflow:hidden}.dbf{height:100%;background:#f59e0b}\n    .dn{width:26px;text-align:right;color:#64748b;font-size:12px}\n    .right{flex:1;padding:26px;overflow:auto}\n    .rt{font-size:15px;font-weight:700;margin-bottom:14px}\n    .cm{background:#fff;border:1px solid #e2e8f0;border-radius:12px;padding:14px 16px;margin-bottom:10px}\n    .cmh{display:flex;align-items:center;gap:8px;margin-bottom:6px}\n    .cmn{font-size:13px;font-weight:700}.stars{color:#f59e0b;font-size:13px}\n    .cmt{font-size:13.5px;color:#475569;line-height:1.5}\n  `,\n  render(d2){\n    var ds=d2.data(); var recs=ds?ds.records():[];\n    var n=recs.length||1;\n    var avg=recs.reduce(function(s,r){return s+(Number(r.rating)||0);},0)/n;\n    var rec=recs.filter(function(r){return r.recommend;}).length;\n    var recPct=Math.round(rec/n*100);\n    var dist=[5,4,3,2,1].map(function(st){var c=recs.filter(function(r){return Number(r.rating)===st;}).length;return '<div class=\"dr\"><span class=\"ds\">'+st+'★</span><div class=\"dbar\"><div class=\"dbf\" style=\"width:'+(c/n*100).toFixed(0)+'%\"></div></div><span class=\"dn\">'+c+'</span></div>';}).join('');\n    var coms=recs.map(function(r){var st='';for(var i=0;i<5;i++)st+=(i<r.rating?'★':'☆');return '<div class=\"cm\"><div class=\"cmh\"><span class=\"cmn\">'+esc(r.name)+'</span><span class=\"stars\">'+st+'</span></div><div class=\"cmt\">'+esc(r.comment)+'</div></div>';}).join('');\n    return '<div class=\"sv\"><div class=\"left\"><h1 class=\"h1\">📊 Pesquisa de Satisfação</h1><div class=\"big\"><div class=\"bv\">'+avg.toFixed(1)+'</div><div class=\"bl\">nota média · '+recs.length+' respostas</div></div><div class=\"kpis\"><div class=\"kpi\"><div class=\"kv\" style=\"color:#16a34a\">'+recPct+'%</div><div class=\"kl\">recomendam</div></div><div class=\"kpi\"><div class=\"kv\">'+recs.length+'</div><div class=\"kl\">respostas</div></div></div><div class=\"dist\">'+dist+'</div></div><div class=\"right\"><div class=\"rt\">Comentários</div>'+coms+'</div></div>';\n  }\n}"}},"dataset":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"dataset"}}}}}}}}}},{"_id":"6a2d902b1b7164341d2f038f","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kHotel","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>\"]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c];});}\nexport default {\n  css: `\n    .ho{height:100%;box-sizing:border-box;background:#f7f7f5;padding:24px 28px;display:flex;flex-direction:column;gap:16px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;color:#1a1a1a;overflow:hidden}\n    .hd h1{margin:0;font-size:22px;font-weight:800}.hd p{margin:3px 0 0;font-size:13px;color:#717171}\n    .grid{flex:1;overflow:auto;display:grid;grid-template-columns:repeat(auto-fill,minmax(290px,1fr));grid-auto-rows:280px;gap:18px;align-content:start}\n    .room{background:#fff;border:1px solid #ebebeb;border-radius:16px;overflow:hidden;display:flex;flex-direction:column;box-shadow:0 1px 3px rgba(0,0,0,.05)}\n    .ph{height:120px;display:flex;align-items:flex-start;justify-content:space-between;padding:12px}\n    .kind{background:rgba(255,255,255,.92);font-size:11px;font-weight:700;padding:3px 9px;border-radius:20px}\n    .body{padding:14px 16px;flex:1;display:flex;flex-direction:column}\n    .rn{font-size:15px;font-weight:700}.cap{font-size:12px;color:#717171;margin:3px 0 8px}\n    .am{display:flex;flex-wrap:wrap;gap:5px;margin-bottom:auto}.amt{font-size:10px;color:#555;background:#f2f2f2;padding:2px 7px;border-radius:5px}\n    .foot{display:flex;align-items:center;justify-content:space-between;margin-top:10px}\n    .price b{font-size:19px}.price span{font-size:12px;color:#717171}\n    .bk{border:none;border-radius:9px;padding:9px 16px;font:inherit;font-size:13px;font-weight:700;cursor:pointer}\n    .bk.ok{background:#e11d48;color:#fff}.bk.no{background:#f2f2f2;color:#999;cursor:default}\n  `,\n  render(d2){\n    var ds=d2.data(); var recs=ds?ds.records():[];\n    var av=recs.filter(function(r){return r.available;}).length;\n    var cards=recs.map(function(r){var am=String(r.amenities||'').split(',').filter(Boolean).slice(0,3).map(function(a){return '<span class=\"amt\">'+esc(a)+'</span>';}).join('');return '<div class=\"room\"><div class=\"ph\" style=\"background:linear-gradient(135deg,'+esc(r.color||'#888')+',#1f2937)\"><span class=\"kind\">'+esc(r.kind)+'</span></div><div class=\"body\"><div class=\"rn\">'+esc(r.name)+'</div><div class=\"cap\">👤 até '+r.capacity+' hóspedes</div><div class=\"am\">'+am+'</div><div class=\"foot\"><div class=\"price\"><b>R$ '+r.price+'</b><span>/noite</span></div><button class=\"bk '+(r.available?'ok':'no')+'\" data-id=\"'+(r.available?r._id:'')+'\">'+(r.available?'Reservar':'Indisponível')+'</button></div></div></div>';}).join('');\n    return '<div class=\"ho\"><div class=\"hd\"><h1>🏨 Hotel Vista Mar</h1><p>'+av+' de '+recs.length+' quartos disponíveis</p></div><div class=\"grid\">'+cards+'</div></div>';\n  },\n  mounted(d2){\n    d2.on('[data-id]','click',function(e,el){var id=el.getAttribute('data-id');if(!id)return;d2.data().update({_id:id,available:false});d2.dialog&&d2.dialog.alert?d2.dialog.alert('Reserva confirmada! 🎉'):0;});\n  }\n}"}},"dataset":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"dataset"}}}}}}}}}},{"_id":"6a2d902b7938117e38f32801","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kRestaurant","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>\"]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c];});}\nfunction brl(n){return 'R$ '+(Number(n)||0).toFixed(2).replace('.',',');}\nexport default {\n  css: `\n    .rs{height:100%;box-sizing:border-box;display:flex;background:#fbfaf8;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;color:#1c1917;overflow:hidden}\n    .menu{flex:1;padding:22px 26px;overflow:auto}\n    .h1{font-size:22px;font-weight:800;margin:0 0 16px}\n    .cat{font-size:13px;font-weight:700;color:#a8a29e;text-transform:uppercase;letter-spacing:.05em;margin:18px 0 10px}\n    .items{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:12px}\n    .it{display:flex;gap:12px;background:#fff;border:1px solid #efece8;border-radius:13px;padding:12px;cursor:pointer;transition:.12s}\n    .it:hover{border-color:#e11d48;box-shadow:0 3px 10px rgba(0,0,0,.06)}\n    .em{font-size:30px}.ii{flex:1;min-width:0}.inm{font-size:14px;font-weight:700}.idesc{font-size:11px;color:#78716c;margin:2px 0 5px;line-height:1.3}.ip{font-size:14px;font-weight:700;color:#e11d48}\n    .cart{width:340px;flex:0 0 auto;background:#fff;border-left:1px solid #efece8;display:flex;flex-direction:column}\n    .ch{padding:18px 20px;font-size:16px;font-weight:800;border-bottom:1px solid #f5f5f4}\n    .clist{flex:1;overflow:auto;padding:8px 0}\n    .cr{display:flex;align-items:center;gap:10px;padding:10px 20px}\n    .cn{flex:1;font-size:13px}.cn b{display:block;font-weight:600}.cn span{font-size:11px;color:#a8a29e}\n    .qty{display:flex;align-items:center;gap:8px}.qty button{width:24px;height:24px;border-radius:6px;border:1px solid #e7e5e4;background:#fff;cursor:pointer;font-weight:700}\n    .cempty{padding:50px 20px;text-align:center;color:#a8a29e;font-size:13px}\n    .cfoot{border-top:1px solid #f5f5f4;padding:18px 20px}\n    .tot{display:flex;justify-content:space-between;font-size:20px;font-weight:800;margin-bottom:12px}\n    .pay{width:100%;background:#e11d48;color:#fff;border:none;border-radius:11px;padding:13px;font:inherit;font-size:15px;font-weight:700;cursor:pointer}\n  `,\n  render(d2){\n    var ds=d2.data(); var recs=ds?ds.records():[];\n    var cart=d2.state.cart||{};\n    var cats={};recs.forEach(function(m){(cats[m.category]=cats[m.category]||[]).push(m);});\n    var menu=Object.keys(cats).map(function(c){var its=cats[c].map(function(m){return '<div class=\"it\" data-add=\"'+m._id+'\"><span class=\"em\">'+esc(m.emoji||'🍽️')+'</span><div class=\"ii\"><div class=\"inm\">'+esc(m.name)+'</div><div class=\"idesc\">'+esc(m.description||'')+'</div><div class=\"ip\">'+brl(m.price)+'</div></div></div>';}).join('');return '<div class=\"cat\">'+esc(c)+'</div><div class=\"items\">'+its+'</div>';}).join('');\n    var ids=Object.keys(cart).filter(function(k){return cart[k]>0;});\n    var total=0;var crows=ids.map(function(id){var m=recs.filter(function(x){return x._id===id;})[0];if(!m)return '';total+=m.price*cart[id];return '<div class=\"cr\"><div class=\"cn\"><b>'+esc(m.name)+'</b><span>'+brl(m.price)+'</span></div><div class=\"qty\"><button data-dec=\"'+id+'\">−</button>'+cart[id]+'<button data-inc=\"'+id+'\">+</button></div></div>';}).join('');\n    var cartHtml=ids.length?crows:'<div class=\"cempty\">Carrinho vazio<br>toque nos itens do menu</div>';\n    return '<div class=\"rs\"><div class=\"menu\"><h1 class=\"h1\">🍴 Cantina Bella</h1>'+menu+'</div><div class=\"cart\"><div class=\"ch\">🛒 Pedido</div><div class=\"clist\">'+cartHtml+'</div><div class=\"cfoot\"><div class=\"tot\"><span>Total</span><span>'+brl(total)+'</span></div><button class=\"pay\">Finalizar pedido</button></div></div></div>';\n  },\n  mounted(d2){\n    function upd(id,delta){var c=Object.assign({},d2.state.cart||{});c[id]=Math.max(0,(c[id]||0)+delta);d2.state.cart=c;}\n    d2.on('[data-add]','click',function(e,el){upd(el.getAttribute('data-add'),1);});\n    d2.on('[data-inc]','click',function(e,el){e.stopPropagation();upd(el.getAttribute('data-inc'),1);});\n    d2.on('[data-dec]','click',function(e,el){e.stopPropagation();upd(el.getAttribute('data-dec'),-1);});\n  }\n}"}},"dataset":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"dataset"}}}}}}}}}},{"_id":"6a2d902ce303c67716fa278a","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kTranslate","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>\"]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c];});}\nvar LANGS=[['Inglês','🇺🇸'],['Espanhol','🇪🇸'],['Francês','🇫🇷'],['Alemão','🇩🇪'],['Italiano','🇮🇹'],['Japonês','🇯🇵']];\nexport default {\n  css: `\n    .tr{height:100%;box-sizing:border-box;background:#f0f4ff;padding:28px 32px;display:flex;flex-direction:column;gap:16px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;color:#1e293b}\n    .h1{font-size:22px;font-weight:800;margin:0}\n    .langs{display:flex;gap:8px;flex-wrap:wrap}\n    .lc{font-size:13px;font-weight:600;padding:7px 13px;border-radius:20px;border:1px solid #c7d2fe;background:#fff;color:#4338ca;cursor:pointer}.lc.on{background:#4f46e5;color:#fff;border-color:#4f46e5}\n    .panes{flex:1;display:grid;grid-template-columns:1fr 1fr;gap:16px;min-height:0}\n    .pane{background:#fff;border:1px solid #e0e7ff;border-radius:16px;display:flex;flex-direction:column;overflow:hidden}\n    .pt{padding:11px 16px;font-size:12px;font-weight:700;color:#64748b;border-bottom:1px solid #eef2ff;text-transform:uppercase;letter-spacing:.04em}\n    .pane textarea{flex:1;border:none;outline:none;resize:none;padding:16px;font:inherit;font-size:16px;line-height:1.5;color:#1e293b}\n    .out{flex:1;padding:16px;font-size:16px;line-height:1.5;color:#1e293b;overflow:auto;white-space:pre-wrap}\n    .out.ph{color:#94a3b8}\n    .go{align-self:flex-start;background:#4f46e5;color:#fff;border:none;border-radius:11px;padding:12px 28px;font:inherit;font-size:15px;font-weight:700;cursor:pointer}.go:disabled{opacity:.5}\n  `,\n  render(d2){\n    var lang=d2.state.lang||'Inglês';\n    var langs=LANGS.map(function(l){return '<span class=\"lc'+(lang===l[0]?' on':'')+'\" data-lang=\"'+l[0]+'\">'+l[1]+' '+l[0]+'</span>';}).join('');\n    var out=d2.state.out;\n    return '<div class=\"tr\"><h1 class=\"h1\">🌐 Tradutor IA</h1><div class=\"langs\">'+langs+'</div><div class=\"panes\"><div class=\"pane\"><div class=\"pt\">Português</div><textarea data-src placeholder=\"Digite o texto para traduzir…\">'+esc(d2.state.src||'')+'</textarea></div><div class=\"pane\"><div class=\"pt\">'+esc(lang)+'</div><div class=\"out'+(out?'':' ph')+'\">'+(out?esc(out):(d2.state.busy?'Traduzindo…':'A tradução aparece aqui'))+'</div></div></div><button class=\"go\" data-go '+(d2.state.busy?'disabled':'')+'>'+(d2.state.busy?'…':'Traduzir')+'</button></div>';\n  },\n  mounted(d2){\n    d2.on('[data-src]','input',function(e,el){d2.state.src=el.value;});\n    d2.on('[data-lang]','click',function(e,el){d2.state.lang=el.getAttribute('data-lang');});\n    d2.on('[data-go]','click',function(){var s=(d2.state.src||'').trim();if(!s||d2.state.busy)return;d2.state.busy=true;var lang=d2.state.lang||'Inglês';Promise.resolve(d2.assistant(d2.params.translator).ask('Traduza para '+lang+':\\n'+s)).then(function(a){d2.state.out=String(a==null?'':a);d2.state.busy=false;}).catch(function(){d2.state.busy=false;});});\n  }\n}"}},"translator":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"translator"}}}}}}}}}},{"_id":"6a2d912761efae759d5d139e","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kInventory","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>\"]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c];});}\nfunction brl(n){return 'R$ '+(Number(n)||0).toLocaleString('pt-BR',{minimumFractionDigits:2,maximumFractionDigits:2});}\nexport default {\n  css: `\n    .iv{height:100%;box-sizing:border-box;background:#f8fafc;padding:22px 26px;display:flex;flex-direction:column;gap:16px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;color:#0f172a;overflow:hidden}\n    .hd h1{margin:0;font-size:21px;font-weight:800}\n    .kpis{display:grid;grid-template-columns:repeat(4,1fr);gap:14px}\n    .kpi{background:#fff;border:1px solid #e2e8f0;border-radius:12px;padding:15px 17px}\n    .kl{font-size:12px;color:#64748b}.kv{font-size:23px;font-weight:800;margin-top:4px;font-variant-numeric:tabular-nums}\n    .tbl{flex:1;background:#fff;border:1px solid #e2e8f0;border-radius:13px;overflow:auto}\n    .tr{display:grid;grid-template-columns:2.5fr 1fr 1fr 1.2fr 1fr;align-items:center;gap:10px;padding:11px 18px;border-bottom:1px solid #f1f5f9;font-size:13px}\n    .th{font-size:11px;font-weight:700;color:#94a3b8;text-transform:uppercase;letter-spacing:.04em;position:sticky;top:0;background:#fff}\n    .pn{display:flex;align-items:center;gap:10px;font-weight:600}.em{font-size:20px}\n    .sku{color:#94a3b8;font-size:12px}\n    .stk{font-weight:700;font-variant-numeric:tabular-nums}\n    .pill{font-size:10px;font-weight:700;padding:2px 8px;border-radius:10px;display:inline-block}\n    .ok{background:#dcfce7;color:#15803d}.low{background:#fef3c7;color:#b45309}.crit{background:#fee2e2;color:#b91c1c}\n  `,\n  render(d2){\n    var ds=d2.data(); var recs=ds?ds.records():[];\n    var totVal=recs.reduce(function(s,p){return s+(Number(p.stock)||0)*(Number(p.price)||0);},0);\n    var totUnits=recs.reduce(function(s,p){return s+(Number(p.stock)||0);},0);\n    var low=recs.filter(function(p){return (p.stock||0)<(p.minStock||0);}).length;\n    var kpis='<div class=\"kpi\"><div class=\"kl\">SKUs</div><div class=\"kv\">'+recs.length+'</div></div><div class=\"kpi\"><div class=\"kl\">Unidades</div><div class=\"kv\">'+totUnits.toLocaleString('pt-BR')+'</div></div><div class=\"kpi\"><div class=\"kl\">Valor em estoque</div><div class=\"kv\">'+brl(totVal)+'</div></div><div class=\"kpi\"><div class=\"kl\">Alertas</div><div class=\"kv\" style=\"color:'+(low?'#dc2626':'#16a34a')+'\">'+low+'</div></div>';\n    var head='<div class=\"tr th\"><span>Produto</span><span>Categoria</span><span>Estoque</span><span>Situação</span><span>Preço</span></div>';\n    var rows=recs.map(function(p){var st=p.stock||0,mn=p.minStock||0;var cls=st<mn?'crit':(st<mn*1.5?'low':'ok');var lbl=st<mn?'Repor':(st<mn*1.5?'Baixo':'OK');return '<div class=\"tr\"><span class=\"pn\"><span class=\"em\">'+esc(p.emoji||'📦')+'</span><span>'+esc(p.name)+'<br><span class=\"sku\">'+esc(p.sku)+'</span></span></span><span>'+esc(p.category)+'</span><span class=\"stk\">'+st+'</span><span><span class=\"pill '+cls+'\">'+lbl+'</span></span><span>'+brl(p.price)+'</span></div>';}).join('');\n    return '<div class=\"iv\"><div class=\"hd\"><h1>📦 Controle de Estoque</h1></div><div class=\"kpis\">'+kpis+'</div><div class=\"tbl\">'+head+rows+'</div></div>';\n  }\n}"}},"dataset":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"dataset"}}}}}}}}}},{"_id":"6a2d9127dbf815e74e992021","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kPRDash","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>\"]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c];});}\nvar ST={open:['#dafbe1','#1a7f37','● Aberto'],review:['#fff8c5','#9a6700','◐ Em revisão'],merged:['#faf2ff','#8250df','✓ Merged'],closed:['#ffebe9','#cf222e','✕ Fechado']};\nexport default {\n  css: `\n    .pr{height:100%;box-sizing:border-box;background:#0d1117;color:#e6edf3;padding:22px 26px;display:flex;flex-direction:column;gap:16px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;overflow:hidden}\n    .hd{display:flex;align-items:center;gap:14px}.hd h1{margin:0;font-size:20px;font-weight:800}\n    .tabs{display:flex;gap:6px;margin-left:auto}\n    .tab{font-size:12px;font-weight:600;padding:6px 12px;border-radius:7px;border:1px solid #30363d;background:#161b22;color:#7d8590;cursor:pointer}.tab.on{color:#e6edf3;border-color:#1f6feb}\n    .list{flex:1;overflow:auto;border:1px solid #30363d;border-radius:12px;background:#0d1117}\n    .row{display:flex;gap:12px;padding:14px 18px;border-bottom:1px solid #21262d;align-items:flex-start}\n    .ic{font-size:16px;flex:0 0 auto;margin-top:1px}\n    .pi{flex:1;min-width:0}\n    .pt{font-size:15px;font-weight:600;color:#e6edf3}\n    .pm{font-size:12px;color:#7d8590;margin-top:3px;display:flex;align-items:center;gap:8px}\n    .repo{color:#58a6ff}\n    .diff{font-size:12px;font-family:ui-monospace,Menlo,monospace;margin-top:5px}\n    .add{color:#3fb950}.del{color:#f85149}\n    .right{text-align:right;flex:0 0 auto}\n    .st{font-size:11px;font-weight:700;padding:3px 9px;border-radius:20px}\n    .cm{font-size:12px;color:#7d8590;margin-top:6px}\n  `,\n  render(d2){\n    var ds=d2.data(); var recs=ds?ds.records():[];\n    var f=d2.state.f||'all';\n    var list=recs.filter(function(p){return f==='all'||p.status===f;});\n    var counts={all:recs.length};['open','review','merged','closed'].forEach(function(k){counts[k]=recs.filter(function(p){return p.status===k;}).length;});\n    var tabs=[['all','Todos'],['open','Abertos'],['review','Revisão'],['merged','Merged']].map(function(t){return '<span class=\"tab'+(f===t[0]?' on':'')+'\" data-f=\"'+t[0]+'\">'+t[1]+' '+(counts[t[0]]||0)+'</span>';}).join('');\n    var rows=list.map(function(p){var s=ST[p.status]||ST.open;return '<div class=\"row\"><span class=\"ic\">🔀</span><div class=\"pi\"><div class=\"pt\">'+esc(p.title)+'</div><div class=\"pm\">'+esc(p.avatar||'')+' '+esc(p.author)+' · <span class=\"repo\">'+esc(p.repo)+'</span></div><div class=\"diff\"><span class=\"add\">+'+(p.additions||0)+'</span> <span class=\"del\">-'+(p.deletions||0)+'</span></div></div><div class=\"right\"><span class=\"st\" style=\"background:'+s[0]+';color:'+s[1]+'\">'+s[2]+'</span><div class=\"cm\">💬 '+(p.comments||0)+'</div></div></div>';}).join('');\n    return '<div class=\"pr\"><div class=\"hd\"><h1>🔀 Pull Requests</h1><div class=\"tabs\">'+tabs+'</div></div><div class=\"list\">'+rows+'</div></div>';\n  },\n  mounted(d2){ d2.on('[data-f]','click',function(e,el){d2.state.f=el.getAttribute('data-f');}); }\n}"}},"dataset":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"dataset"}}}}}}}}}},{"_id":"6a2d9127e303c67716fa2952","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kAnalytics","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;'}[c];});}\nexport default {\n  css: `\n    .an{height:100%;box-sizing:border-box;background:#fff;padding:24px 28px;display:flex;flex-direction:column;gap:20px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;color:#0f172a;overflow:hidden}\n    .hd h1{margin:0;font-size:21px;font-weight:800}.hd p{margin:3px 0 0;font-size:13px;color:#64748b}\n    .kpis{display:grid;grid-template-columns:repeat(4,1fr);gap:16px}\n    .kpi{border:1px solid #e2e8f0;border-radius:14px;padding:16px 18px}\n    .kl{font-size:12px;color:#64748b}.kv{font-size:26px;font-weight:800;margin-top:5px;font-variant-numeric:tabular-nums}\n    .kd{font-size:12px;font-weight:700;margin-top:4px}.up{color:#16a34a}\n    .chart{flex:1;border:1px solid #e2e8f0;border-radius:14px;padding:18px;display:flex;flex-direction:column;min-height:0}\n    .ct{font-size:14px;font-weight:700;margin-bottom:14px}\n    .bars{flex:1;display:flex;align-items:flex-end;gap:8px;min-height:0}\n    .col{flex:1;display:flex;flex-direction:column;align-items:center;gap:6px;height:100%;justify-content:flex-end}\n    .bar{width:100%;border-radius:6px 6px 0 0;background:linear-gradient(180deg,#818cf8,#4f46e5);position:relative;transition:.2s}\n    .col:hover .bar{filter:brightness(1.12)}\n    .bv{position:absolute;top:-17px;left:50%;transform:translateX(-50%);font-size:10px;color:#64748b;white-space:nowrap;opacity:0}\n    .col:hover .bv{opacity:1}\n    .bl{font-size:10px;color:#94a3b8}\n  `,\n  render(d2){\n    var ds=d2.data(); var recs=ds?ds.records():[];\n    var tv=recs.reduce(function(s,r){return s+(Number(r.visitors)||0);},0);\n    var ts=recs.reduce(function(s,r){return s+(Number(r.signups)||0);},0);\n    var tr=recs.reduce(function(s,r){return s+(Number(r.revenue)||0);},0);\n    var conv=tv?(ts/tv*100).toFixed(1):'0';\n    var mx=Math.max.apply(null,recs.map(function(r){return Number(r.revenue)||0;}))||1;\n    var bars=recs.map(function(r){var h=(Number(r.revenue)||0)/mx*100;return '<div class=\"col\"><div class=\"bar\" style=\"height:'+h.toFixed(0)+'%\"><span class=\"bv\">R$ '+(r.revenue||0).toLocaleString('pt-BR')+'</span></div><span class=\"bl\">'+esc(r.day)+'</span></div>';}).join('');\n    return '<div class=\"an\"><div class=\"hd\"><h1>📈 Analytics</h1><p>Últimos '+recs.length+' dias</p></div><div class=\"kpis\"><div class=\"kpi\"><div class=\"kl\">Visitantes</div><div class=\"kv\">'+tv.toLocaleString('pt-BR')+'</div><div class=\"kd up\">↑ 18%</div></div><div class=\"kpi\"><div class=\"kl\">Cadastros</div><div class=\"kv\">'+ts.toLocaleString('pt-BR')+'</div><div class=\"kd up\">↑ 24%</div></div><div class=\"kpi\"><div class=\"kl\">Receita</div><div class=\"kv\">R$ '+(tr/1000).toFixed(0)+'k</div><div class=\"kd up\">↑ 31%</div></div><div class=\"kpi\"><div class=\"kl\">Conversão</div><div class=\"kv\">'+conv+'%</div><div class=\"kd up\">↑ 6%</div></div></div><div class=\"chart\"><div class=\"ct\">Receita diária</div><div class=\"bars\">'+bars+'</div></div></div>';\n  }\n}"}},"dataset":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"dataset"}}}}}}}}}},{"_id":"6a2d9127911a2eb6b816c02b","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kCrypto","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>\"]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c];});}\nfunction spark(arr,col){if(!arr||!arr.length)return '';var W=100,H=30,mn=Math.min.apply(null,arr),mx=Math.max.apply(null,arr),rg=(mx-mn)||1;var d='';arr.forEach(function(v,i){d+=(i?'L':'M')+(i/(arr.length-1)*W).toFixed(1)+' '+(H-((v-mn)/rg)*H).toFixed(1)+' ';});return '<svg viewBox=\"0 0 '+W+' '+H+'\" preserveAspectRatio=\"none\" style=\"width:110px;height:30px\"><path d=\"'+d+'\" fill=\"none\" stroke=\"'+col+'\" stroke-width=\"1.5\"/></svg>';}\nfunction usd(n){return '$'+(Number(n)||0).toLocaleString('en-US',{minimumFractionDigits:2,maximumFractionDigits:2});}\nexport default {\n  css: `\n    .cr{height:100%;box-sizing:border-box;background:#0b0e16;color:#e8eaf0;padding:22px 26px;display:flex;flex-direction:column;gap:16px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;overflow:hidden}\n    .hd{display:flex;align-items:center}.hd h1{margin:0;font-size:21px;font-weight:800}.hd .rf{margin-left:auto;font-size:12px;background:#1a1f2e;padding:7px 13px;border-radius:8px;cursor:pointer;color:#9aa4bf}\n    .tbl{flex:1;overflow:auto;border:1px solid #1c2233;border-radius:13px}\n    .tr{display:grid;grid-template-columns:30px 2fr 1.2fr 1fr 1.3fr 110px;align-items:center;gap:12px;padding:12px 18px;border-bottom:1px solid #161b28;font-size:13.5px}\n    .th{font-size:11px;color:#6b7693;text-transform:uppercase;letter-spacing:.04em;position:sticky;top:0;background:#0b0e16}\n    .coin{display:flex;align-items:center;gap:10px;font-weight:600}.coin img{width:26px;height:26px}\n    .sym{color:#6b7693;text-transform:uppercase;font-size:11px}\n    .px{font-variant-numeric:tabular-nums;font-weight:600}\n    .chg{font-weight:700;font-variant-numeric:tabular-nums}\n    .pos{color:#16c784}.neg{color:#ea3943}\n    .mc{color:#9aa4bf;font-variant-numeric:tabular-nums}\n    .load{padding:50px;text-align:center;color:#6b7693}\n  `,\n  render(d2){\n    var coins=d2.state.coins;\n    if(!coins) return '<div class=\"cr\"><div class=\"hd\"><h1>₿ Crypto Tracker</h1></div><div class=\"load\">Carregando da CoinGecko…</div></div>';\n    if(coins.error) return '<div class=\"cr\"><div class=\"hd\"><h1>₿ Crypto Tracker</h1><span class=\"rf\" data-refresh>↻</span></div><div class=\"load\">Erro ao carregar. Toque em atualizar.</div></div>';\n    var head='<div class=\"tr th\"><span>#</span><span>Moeda</span><span>Preço</span><span>24h</span><span>Market Cap</span><span>7d</span></div>';\n    var rows=coins.map(function(c,i){var up=(c.price_change_percentage_24h||0)>=0;return '<div class=\"tr\"><span style=\"color:#6b7693\">'+(i+1)+'</span><span class=\"coin\"><img src=\"'+esc(c.image)+'\"/><span>'+esc(c.name)+' <span class=\"sym\">'+esc(c.symbol)+'</span></span></span><span class=\"px\">'+usd(c.current_price)+'</span><span class=\"chg '+(up?'pos':'neg')+'\">'+(up?'▲':'▼')+' '+Math.abs(c.price_change_percentage_24h||0).toFixed(2)+'%</span><span class=\"mc\">$'+((c.market_cap||0)/1e9).toFixed(1)+'B</span>'+spark(c.sparkline_in_7d&&c.sparkline_in_7d.price,up?'#16c784':'#ea3943')+'</div>';}).join('');\n    return '<div class=\"cr\"><div class=\"hd\"><h1>₿ Crypto Tracker</h1><span class=\"rf\" data-refresh>↻ Atualizar</span></div><div class=\"tbl\">'+head+rows+'</div></div>';\n  },\n  mounted(d2){\n    function load(){fetch('https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&order=market_cap_desc&per_page=20&page=1&sparkline=true&price_change_percentage=24h').then(function(r){return r.json();}).then(function(j){if(Array.isArray(j))d2.state.coins=j;else d2.state.coins={error:true};}).catch(function(){d2.state.coins={error:true};});}\n    load();\n    d2.on('[data-refresh]','click',function(){d2.state.coins=null;load();});\n  }\n}"}}}}}}}},{"_id":"6a2d9231e303c67716fa2bc8","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kPodcast","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>\"]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c];});}\nexport default {\n  css: `\n    .pd{height:100%;box-sizing:border-box;display:flex;background:#faf5ff;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;color:#1e1b2e;overflow:hidden}\n    .list{flex:1;overflow:auto;padding:24px 28px}\n    .h1{font-size:24px;font-weight:800;margin:0 0 18px}\n    .grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:16px}\n    .pc{background:#fff;border:1px solid #efe6fb;border-radius:16px;padding:16px;cursor:pointer;transition:.15s;box-shadow:0 1px 3px rgba(80,40,120,.06)}\n    .pc:hover{transform:translateY(-3px);box-shadow:0 10px 24px rgba(80,40,120,.14)}.pc.on{outline:2px solid #8b5cf6}\n    .cov{height:90px;border-radius:11px;display:flex;align-items:center;justify-content:center;font-size:40px;margin-bottom:11px}\n    .pt{font-size:15px;font-weight:700}.pcat{font-size:11px;color:#8b7fa8;margin-top:2px}.pe{font-size:12px;color:#5b5170;margin-top:7px;line-height:1.3}\n    .now{width:330px;flex:0 0 auto;background:#fff;border-left:1px solid #efe6fb;padding:26px;display:flex;flex-direction:column;align-items:center;gap:16px}\n    .bigcov{width:200px;height:200px;border-radius:18px;display:flex;align-items:center;justify-content:center;font-size:80px;box-shadow:0 14px 36px rgba(80,40,120,.3)}\n    .nt{font-size:19px;font-weight:800;text-align:center}.nh{font-size:13px;color:#8b7fa8}.ne{font-size:13px;color:#5b5170;text-align:center}\n    .bar{width:100%;height:5px;background:#eee;border-radius:3px;overflow:hidden}.bf{height:100%;width:28%;background:#8b5cf6}\n    .ctr{display:flex;align-items:center;gap:22px;font-size:20px}\n    .pl{width:56px;height:56px;border-radius:50%;background:#8b5cf6;color:#fff;border:none;font-size:22px;cursor:pointer}\n    .ph{margin:auto;color:#a99fc0;font-size:14px;text-align:center}\n  `,\n  render(d2){\n    var ds=d2.data(); var recs=ds?ds.records():[];\n    var cur=d2.state.cur,playing=d2.state.playing;\n    var cards=recs.map(function(p){return '<div class=\"pc'+(cur===p._id?' on':'')+'\" data-id=\"'+p._id+'\"><div class=\"cov\" style=\"background:linear-gradient(135deg,'+esc(p.color||'#8b5cf6')+',#1e1b2e)\">'+esc(p.emoji||'🎧')+'</div><div class=\"pt\">'+esc(p.title)+'</div><div class=\"pcat\">'+esc(p.host)+' · '+esc(p.category)+'</div><div class=\"pe\">'+esc(p.episode)+'</div></div>';}).join('');\n    var c=recs.filter(function(x){return x._id===cur;})[0];\n    var now=c?'<div class=\"bigcov\" style=\"background:linear-gradient(135deg,'+esc(c.color||'#8b5cf6')+',#1e1b2e)\">'+esc(c.emoji||'🎧')+'</div><div class=\"nt\">'+esc(c.title)+'</div><div class=\"nh\">'+esc(c.host)+'</div><div class=\"ne\">'+esc(c.episode)+'</div><div class=\"bar\"><div class=\"bf\"></div></div><div class=\"ctr\">⏮<button class=\"pl\" data-play>'+(playing?'❚❚':'▶')+'</button>⏭</div>':'<div class=\"ph\">Escolha um podcast<br>para ouvir</div>';\n    return '<div class=\"pd\"><div class=\"list\"><h1 class=\"h1\">🎧 Podcasts</h1><div class=\"grid\">'+cards+'</div></div><div class=\"now\">'+now+'</div></div>';\n  },\n  mounted(d2){\n    d2.on('[data-id]','click',function(e,el){d2.state.cur=el.getAttribute('data-id');d2.state.playing=true;});\n    d2.on('[data-play]','click',function(){d2.state.playing=!d2.state.playing;});\n  }\n}"}},"dataset":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"dataset"}}}}}}}}}},{"_id":"6a2d9231baacaeb326294966","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kFoodDelivery","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>\"]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c];});}\nfunction brl(n){return 'R$ '+(Number(n)||0).toFixed(2).replace('.',',');}\nexport default {\n  css: `\n    .fd{height:100%;box-sizing:border-box;display:flex;background:#fff8f3;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;color:#3d2817;overflow:hidden}\n    .menu{flex:1;padding:24px 28px;overflow:auto}\n    .h1{font-size:24px;font-weight:800;margin:0 0 4px}.sub{font-size:13px;color:#a8866a;margin-bottom:18px}\n    .grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:16px}\n    .rc{background:#fff;border:1px solid #f1e4d6;border-radius:16px;overflow:hidden;box-shadow:0 1px 3px rgba(0,0,0,.05)}\n    .rh{height:80px;display:flex;align-items:center;justify-content:center;font-size:40px}\n    .rb{padding:14px 16px}\n    .rn{font-size:16px;font-weight:700}.rmeta{font-size:12px;color:#a8866a;margin:3px 0 10px;display:flex;gap:10px}\n    .dish{display:flex;align-items:center;justify-content:space-between;border-top:1px solid #f5ece2;padding-top:10px}\n    .dn{font-size:13px}.dn b{display:block}.dp{font-size:13px;color:#e8590c;font-weight:700}\n    .add{background:#e8590c;color:#fff;border:none;border-radius:8px;padding:7px 13px;font:inherit;font-size:12px;font-weight:700;cursor:pointer;margin-top:8px}\n    .cart{width:330px;flex:0 0 auto;background:#fff;border-left:1px solid #f1e4d6;display:flex;flex-direction:column}\n    .ch{padding:18px 20px;font-size:17px;font-weight:800;border-bottom:1px solid #f5ece2}\n    .clist{flex:1;overflow:auto;padding:10px 0}\n    .ci{display:flex;justify-content:space-between;padding:10px 20px;font-size:13px}\n    .cempty{padding:50px 20px;text-align:center;color:#c4a98e;font-size:13px}\n    .cf{border-top:1px solid #f5ece2;padding:18px 20px}\n    .tot{display:flex;justify-content:space-between;font-size:20px;font-weight:800;margin-bottom:12px}\n    .go{width:100%;background:#e8590c;color:#fff;border:none;border-radius:11px;padding:13px;font:inherit;font-size:15px;font-weight:700;cursor:pointer}.go:disabled{opacity:.6}\n    .conf{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:14px;text-align:center;padding:30px}\n    .cbig{font-size:64px}.ct2{font-size:20px;font-weight:800}.ceta{font-size:14px;color:#a8866a}\n    .cnew{background:#e8590c;color:#fff;border:none;border-radius:10px;padding:11px 20px;font:inherit;font-weight:700;cursor:pointer}\n  `,\n  render(d2){\n    var ds=d2.data('restaurants'); var recs=ds?ds.records():[];\n    var cart=d2.state.cart||[];\n    if(d2.state.order){var o=d2.state.order;return '<div class=\"fd\"><div class=\"conf\"><div class=\"cbig\">✅</div><div class=\"ct2\">Pedido confirmado!</div><div class=\"ceta\">Pedido #'+esc(String(o.orderId).slice(-6))+' · chega em ~'+o.eta+' min 🛵</div><button class=\"cnew\" data-new>Fazer novo pedido</button></div></div>';}\n    var cards=recs.map(function(r){return '<div class=\"rc\"><div class=\"rh\" style=\"background:linear-gradient(135deg,'+esc(r.color||'#e8590c')+'33,'+esc(r.color||'#e8590c')+'11)\">'+esc(r.emoji||'🍽️')+'</div><div class=\"rb\"><div class=\"rn\">'+esc(r.name)+'</div><div class=\"rmeta\"><span>⭐ '+r.rating+'</span><span>🕝 '+r.deliveryTime+'min</span><span>🛵 '+brl(r.fee)+'</span></div><div class=\"dish\"><div class=\"dn\"><b>'+esc(r.dish)+'</b><span class=\"dp\">'+brl(r.price)+'</span></div></div><button class=\"add\" data-add=\"'+r._id+'\">+ Adicionar</button></div></div>';}).join('');\n    var total=cart.reduce(function(s,c){return s+(Number(c.price)||0);},0);\n    var ci=cart.length?cart.map(function(c,i){return '<div class=\"ci\"><span>'+esc(c.name)+'</span><span>'+brl(c.price)+'</span></div>';}).join(''):'<div class=\"cempty\">Carrinho vazio<br>adicione pratos 🍔</div>';\n    return '<div class=\"fd\"><div class=\"menu\"><h1 class=\"h1\">🍔 Delivery</h1><div class=\"sub\">'+recs.length+' restaurantes perto de você</div><div class=\"grid\">'+cards+'</div></div><div class=\"cart\"><div class=\"ch\">🛒 Seu pedido</div><div class=\"clist\">'+ci+'</div><div class=\"cf\"><div class=\"tot\"><span>Total</span><span>'+brl(total)+'</span></div><button class=\"go\" data-go '+(cart.length&&!d2.state.placing?'':'disabled')+'>'+(d2.state.placing?'Enviando…':'Finalizar pedido')+'</button></div></div></div>';\n  },\n  mounted(d2){\n    d2.on('[data-add]','click',function(e,el){var id=el.getAttribute('data-add');var r=d2.data('restaurants').records().filter(function(x){return x._id===id;})[0];if(!r)return;var cart=(d2.state.cart||[]).slice();cart.push({name:r.dish,price:r.price,rest:r.name});d2.state.cart=cart;});\n    d2.on('[data-new]','click',function(){d2.state.order=null;d2.state.cart=[];});\n    d2.on('[data-go]','click',function(){var cart=d2.state.cart||[];if(!cart.length||d2.state.placing)return;var total=cart.reduce(function(s,c){return s+(Number(c.price)||0);},0);var items=cart.map(function(c){return c.name;}).join(', ');var rest=cart[0].rest;d2.state.placing=true;Promise.resolve(d2.rush('fdPlaceOrder').invoke({restaurant:rest,items:items,total:total})).then(function(r){var dt=(r&&r.data)?r.data:r;d2.state.order={orderId:(dt&&dt.orderId)||'OK'+Date.now(),eta:(dt&&dt.eta)||28};d2.state.placing=false;d2.state.cart=[];}).catch(function(){d2.state.order={orderId:'LOCAL'+Date.now(),eta:28};d2.state.placing=false;d2.state.cart=[];});});\n  }\n}"}},"restaurants":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"restaurants"}}}}}}}}}},{"_id":"6a2d92321b7164341d2f07e7","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kAIStudio","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>\"]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c];});}\nfunction imgUrl(s){if(!s)return null;s=String(s);var m=s.match(/!\\[[^\\]]*\\]\\(([^)]+)\\)/);if(m)return m[1];m=s.match(/data:image\\/[a-zA-Z0-9+;=,_\\/-]+/);if(m)return m[0];m=s.match(/https?:\\/\\/[^\\s)\"'<>]+/);if(m)return m[0];return null;}\nexport default {\n  css: `\n    .ai{height:100%;box-sizing:border-box;display:flex;flex-direction:column;background:#0a0a14;color:#e8e8f5;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;overflow:hidden}\n    .hd{padding:18px 24px;display:flex;align-items:center;gap:16px;border-bottom:1px solid #1e1e30}\n    .hd h1{margin:0;font-size:19px;font-weight:800;background:linear-gradient(90deg,#a78bfa,#f0abfc);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}\n    .tabs{display:flex;gap:6px;margin-left:auto}\n    .tab{font-size:13px;font-weight:600;padding:7px 15px;border-radius:9px;background:#16162a;color:#8b8ba7;cursor:pointer;border:1px solid #24243a}.tab.on{background:#6d28d9;color:#fff;border-color:#6d28d9}\n    .body{flex:1;display:flex;flex-direction:column;min-height:0}\n    .log{flex:1;overflow:auto;padding:20px 24px;display:flex;flex-direction:column;gap:12px}\n    .b{max-width:75%;padding:11px 15px;border-radius:14px;font-size:14px;line-height:1.5;white-space:pre-wrap}\n    .me{align-self:flex-end;background:#6d28d9;color:#fff}\n    .bot{align-self:flex-start;background:#1a1a2e;color:#e8e8f5}\n    .empty{margin:auto;color:#5a5a78;font-size:14px;text-align:center}\n    .imgwrap{flex:1;display:flex;align-items:center;justify-content:center;padding:20px}\n    .imgwrap img{max-width:100%;max-height:100%;border-radius:14px;box-shadow:0 12px 40px rgba(109,40,217,.4)}\n    .ph2{color:#5a5a78;font-size:14px;text-align:center}\n    .inrow{display:flex;gap:10px;padding:16px 24px;border-top:1px solid #1e1e30}\n    .inrow input{flex:1;background:#16162a;border:1px solid #24243a;border-radius:12px;padding:12px 16px;color:#e8e8f5;font:inherit;font-size:14px;outline:none}\n    .inrow input:focus{border-color:#6d28d9}\n    .inrow button{background:linear-gradient(135deg,#7c3aed,#a855f7);color:#fff;border:none;border-radius:12px;padding:12px 22px;font:inherit;font-weight:700;cursor:pointer}.inrow button:disabled{opacity:.5}\n  `,\n  render(d2){\n    var tab=d2.state.tab||'chat';\n    var tabs='<span class=\"tab'+(tab==='chat'?' on':'')+'\" data-tab=\"chat\">💬 Chat</span><span class=\"tab'+(tab==='img'?' on':'')+'\" data-tab=\"img\">🎨 Imagem</span>';\n    var body;\n    if(tab==='chat'){\n      var msgs=d2.state.msgs||[];\n      var bub=msgs.map(function(m){return '<div class=\"b '+(m.role==='user'?'me':'bot')+'\">'+esc(m.text)+'</div>';}).join('');\n      if(d2.state.thinking){var a=d2.assistant(d2.params.chat);bub+='<div class=\"b bot\">'+esc(a.answer||'…')+'</div>';}\n      if(!msgs.length&&!d2.state.thinking)bub='<div class=\"empty\">Converse com a IA 👋<br>pergunte qualquer coisa</div>';\n      body='<div class=\"log\" data-log>'+bub+'</div><div class=\"inrow\"><input data-q placeholder=\"Pergunte algo…\" value=\"'+esc(d2.state.q||'')+'\" '+(d2.state.thinking?'disabled':'')+'/><button data-send '+(d2.state.thinking?'disabled':'')+'>Enviar</button></div>';\n    } else {\n      var url=imgUrl(d2.state.img);\n      var inner=url?'<img src=\"'+esc(url)+'\"/>':'<div class=\"ph2\">'+(d2.state.drawing?'🎨 Gerando imagem…':'Descreva uma imagem para gerar')+'</div>';\n      body='<div class=\"imgwrap\">'+inner+'</div><div class=\"inrow\"><input data-iq placeholder=\"ex: um robô pintando um quadro, neon\" value=\"'+esc(d2.state.iq||'')+'\" '+(d2.state.drawing?'disabled':'')+'/><button data-draw '+(d2.state.drawing?'disabled':'')+'>Gerar</button></div>';\n    }\n    return '<div class=\"ai\"><div class=\"hd\"><h1>✨ AI Studio</h1><div class=\"tabs\">'+tabs+'</div></div><div class=\"body\">'+body+'</div></div>';\n  },\n  mounted(d2){\n    d2.on('[data-tab]','click',function(e,el){d2.state.tab=el.getAttribute('data-tab');});\n    d2.on('[data-q]','input',function(e,el){d2.state.q=el.value;});\n    function send(){var t=(d2.state.q||'').trim();if(!t||d2.state.thinking)return;var msgs=(d2.state.msgs||[]).concat([{role:'user',text:t}]);d2.state.msgs=msgs;d2.state.q='';d2.state.thinking=true;var hist=msgs.map(function(m){return {role:(m.role==='user'?'user':'assistant'),content:m.text};});Promise.resolve(d2.assistant(d2.params.chat).reply(hist)).then(function(ans){d2.state.msgs=(d2.state.msgs||[]).concat([{role:'assistant',text:String(ans==null?'':ans)}]);d2.state.thinking=false;}).catch(function(){d2.state.thinking=false;});}\n    d2.on('[data-send]','click',send);\n    d2.on('[data-q]','keydown',function(e){if(e.key==='Enter')send();});\n    d2.on('[data-iq]','input',function(e,el){d2.state.iq=el.value;});\n    function draw(){var t=(d2.state.iq||'').trim();if(!t||d2.state.drawing)return;d2.state.drawing=true;d2.state.img=null;Promise.resolve(d2.assistant(d2.params.painter).draw(t)).then(function(r){d2.state.img=(typeof r==='string')?r:(d2.assistant(d2.params.painter).answer||(r&&(r.url||r.image))||'');d2.state.drawing=false;}).catch(function(){d2.state.drawing=false;});}\n    d2.on('[data-draw]','click',draw);\n    d2.on('[data-iq]','keydown',function(e){if(e.key==='Enter')draw();});\n  },\n  updated(d2){var l=d2.$('[data-log]');if(l)l.scrollTop=l.scrollHeight;}\n}"}},"chat":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"chat"}}}},"painter":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"painter"}}}}}}}}}},{"_id":"6a2e0f71dbf815e74e99bd8a","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kVivCatalog","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>\"]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c];});}\nfunction brl(n){return 'R$ '+(Number(n)||0).toLocaleString('pt-BR',{minimumFractionDigits:2,maximumFractionDigits:2});}\nfunction norm(p){var it=(p.items&&p.items[0])||{};var img=(it.images&&it.images[0]&&it.images[0].imageUrl)||'';var co=(it.sellers&&it.sellers[0]&&it.sellers[0].commertialOffer)||{};var pr=p.priceRange||{};var price=(pr.sellingPrice&&pr.sellingPrice.lowPrice)||co.Price||0;var list=(pr.listPrice&&pr.listPrice.lowPrice)||co.ListPrice||price;return {id:p.productId,name:p.productName,brand:p.brand,image:img,price:price,list:list,cat:(p.categories&&p.categories[0])||''};}\nexport default {\n  css: `@import url('https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@500;600&family=Jost:wght@300;400;500&display=swap');\n    .cat{height:100%;box-sizing:border-box;background:#FAF8F5;color:#1A1A1A;font-family:'Jost',-apple-system,sans-serif;display:flex;flex-direction:column;overflow:hidden}\n    .hd{padding:22px 30px 16px;display:flex;align-items:flex-end;gap:20px;border-bottom:1px solid #E8E2D9}\n    .hd h2{font-family:'Cormorant Garamond',Georgia,serif;font-size:26px;font-weight:600;margin:0;letter-spacing:.01em}\n    .hd .ct{font-size:12px;color:#9B8E7E;letter-spacing:.08em;text-transform:uppercase;margin-bottom:4px}\n    .search{margin-left:auto;position:relative}\n    .search input{width:240px;padding:9px 14px;border:1px solid #DDD5C8;border-radius:0;background:#fff;font:inherit;font-size:13px;outline:none}\n    .search input:focus{border-color:#B08D57}\n    .grid{flex:1;overflow:auto;padding:24px 30px;display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:26px;align-content:start}\n    .card{background:#fff;border:1px solid #EDE7DD;display:flex;flex-direction:column;transition:.2s;cursor:pointer}\n    .card:hover{box-shadow:0 10px 30px rgba(120,100,60,.12);border-color:#D9CDB8}\n    .ph{aspect-ratio:1;background:#fff;display:flex;align-items:center;justify-content:center;overflow:hidden;border-bottom:1px solid #F0EBE2}\n    .ph img{width:100%;height:100%;object-fit:contain;mix-blend-mode:multiply}\n    .info{padding:14px 16px 18px}\n    .brand{font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:#B08D57}\n    .name{font-family:'Cormorant Garamond',Georgia,serif;font-size:16px;font-weight:600;line-height:1.3;margin:5px 0 9px;color:#1A1A1A;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;min-height:42px}\n    .price{font-size:15px}.price s{color:#B6AB99;font-size:12px;margin-right:6px}.price b{font-weight:600;color:#1A1A1A}\n    .empty{grid-column:1/-1;text-align:center;color:#9B8E7E;padding:60px}\n  `,\n  render(d2){\n    var ds=d2.data(); var recs=ds?ds.records():[];\n    var q=(d2.state.q||'').toLowerCase();\n    var items=recs.map(norm).filter(function(p){return p.image&&(!q||(p.name||'').toLowerCase().indexOf(q)>=0);});\n    var joias=items.filter(function(p){return p.cat.indexOf('/Joias/')>=0;});\n    var list=joias.length>4?joias:items;\n    var cards=list.length?list.map(function(p){var off=p.list>p.price;return '<div class=\"card\"><div class=\"ph\"><img loading=\"lazy\" src=\"'+esc(p.image)+'\"/></div><div class=\"info\"><div class=\"brand\">'+esc(p.brand||'Vivara')+'</div><div class=\"name\">'+esc(p.name)+'</div><div class=\"price\">'+(off?'<s>'+brl(p.list)+'</s>':'')+'<b>'+brl(p.price)+'</b></div></div></div>';}).join(''):'<div class=\"empty\">'+(recs.length?'Nenhuma peça encontrada':'Carregando catálogo da Vivara…')+'</div>';\n    return '<div class=\"cat\"><div class=\"hd\"><div><div class=\"ct\">Catálogo VTEX</div><h2>Joias Vivara</h2></div><span style=\"font-size:12px;color:#9B8E7E\">'+list.length+' peças</span><div class=\"search\"><input data-q placeholder=\"Buscar joia…\" value=\"'+esc(d2.state.q||'')+'\"/></div></div><div class=\"grid\">'+cards+'</div></div>';\n  },\n  mounted(d2){ d2.on('[data-q]','input',function(e,el){d2.state.q=el.value;}); }\n}"}},"dataset":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"dataset"}}}}}}}}}},{"_id":"6a2e0f72911a2eb6b8174ef2","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kVivDashboard","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;'}[c];});}\nfunction k(n){n=Number(n)||0;return n>=1000?'R$ '+(n/1000).toFixed(0)+'k':'R$ '+n;}\nfunction brl(n){return 'R$ '+(Number(n)||0).toLocaleString('pt-BR');}\nexport default {\n  css: `@import url('https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@500;600&family=Jost:wght@300;400;500;600&display=swap');\n    .dash{height:100%;box-sizing:border-box;background:#FAF8F5;color:#1A1A1A;font-family:'Jost',-apple-system,sans-serif;padding:26px 32px;display:flex;flex-direction:column;gap:22px;overflow:auto}\n    .hd .ct{font-size:12px;color:#9B8E7E;letter-spacing:.08em;text-transform:uppercase}\n    .hd h2{font-family:'Cormorant Garamond',Georgia,serif;font-size:28px;font-weight:600;margin:3px 0 0}\n    .kpis{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:#E8E2D9;border:1px solid #E8E2D9}\n    .kpi{background:#fff;padding:20px 22px}\n    .kl{font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:#9B8E7E}\n    .kv{font-family:'Cormorant Garamond',Georgia,serif;font-size:30px;font-weight:600;margin-top:6px}\n    .kd{font-size:12px;color:#7A9B6E;margin-top:2px}\n    .cols{flex:1;display:grid;grid-template-columns:1.6fr 1fr;gap:24px;min-height:300px}\n    .panel{background:#fff;border:1px solid #EDE7DD;padding:22px 24px;display:flex;flex-direction:column}\n    .pt{font-family:'Cormorant Garamond',Georgia,serif;font-size:19px;font-weight:600;margin-bottom:18px}\n    .bars{flex:1;display:flex;align-items:flex-end;gap:7px;min-height:160px}\n    .bcol{flex:1;display:flex;flex-direction:column;align-items:center;gap:7px;height:100%;justify-content:flex-end}\n    .bar{width:100%;background:linear-gradient(180deg,#C9A24B,#B08D57);transition:.2s}\n    .bcol:hover .bar{filter:brightness(1.08)}\n    .bl{font-size:9px;color:#B6AB99}\n    .top{display:flex;flex-direction:column;gap:14px;overflow:auto}\n    .trow{display:flex;align-items:center;gap:13px}\n    .tn{width:40px;height:40px;object-fit:contain;mix-blend-mode:multiply;background:#FAF8F5;flex:0 0 auto}\n    .ti{flex:1;min-width:0}.tnm{font-size:13px;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tc{font-size:11px;color:#9B8E7E}\n    .tr2{text-align:right;flex:0 0 auto}.tsold{font-size:13px;font-weight:600;color:#B08D57}.trev{font-size:11px;color:#9B8E7E}\n  `,\n  render(d2){\n    var sales=(d2.data('sales')&&d2.data('sales').records())||[];\n    var top=(d2.data('top')&&d2.data('top').records())||[];\n    var rev=sales.reduce(function(s,r){return s+(Number(r.revenue)||0);},0);\n    var ord=sales.reduce(function(s,r){return s+(Number(r.orders)||0);},0);\n    var ticket=ord?Math.round(rev/ord):0;\n    var growth=sales.length>1?Math.round((((sales[sales.length-1].revenue||0)/(sales[0].revenue||1))-1)*100):0;\n    var mx=Math.max.apply(null,sales.map(function(r){return Number(r.revenue)||0;}))||1;\n    var bars=sales.map(function(r){return '<div class=\"bcol\"><div class=\"bar\" style=\"height:'+((Number(r.revenue)||0)/mx*100).toFixed(0)+'%\"></div><span class=\"bl\">'+esc(r.day)+'</span></div>';}).join('');\n    var trows=top.slice().sort(function(a,b){return (b.revenue||0)-(a.revenue||0);}).map(function(t){return '<div class=\"trow\"><img class=\"tn\" src=\"'+esc(t.image)+'\"/><div class=\"ti\"><div class=\"tnm\">'+esc(t.name)+'</div><div class=\"tc\">'+esc(t.category)+'</div></div><div class=\"tr2\"><div class=\"tsold\">'+t.sold+' un.</div><div class=\"trev\">'+brl(t.revenue)+'</div></div></div>';}).join('');\n    return '<div class=\"dash\"><div class=\"hd\"><div class=\"ct\">Visão geral</div><h2>Performance da Boutique</h2></div><div class=\"kpis\"><div class=\"kpi\"><div class=\"kl\">Receita (13d)</div><div class=\"kv\">'+k(rev)+'</div><div class=\"kd\">↗ '+growth+'% no período</div></div><div class=\"kpi\"><div class=\"kl\">Pedidos</div><div class=\"kv\">'+ord.toLocaleString('pt-BR')+'</div><div class=\"kd\">↗ saudável</div></div><div class=\"kpi\"><div class=\"kl\">Ticket médio</div><div class=\"kv\">'+k(ticket)+'</div><div class=\"kd\">premium</div></div><div class=\"kpi\"><div class=\"kl\">Conversão</div><div class=\"kv\">3,2%</div><div class=\"kd\">↗ 0,4pp</div></div></div><div class=\"cols\"><div class=\"panel\"><div class=\"pt\">Receita diária</div><div class=\"bars\">'+bars+'</div></div><div class=\"panel\"><div class=\"pt\">Mais vendidos</div><div class=\"top\">'+trows+'</div></div></div></div>';\n  }\n}"}},"sales":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"sales"}}}},"top":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"top"}}}}}}}}}},{"_id":"6a2e0f7361efae759d5da624","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kVivModels","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>\"]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c];});}\nfunction digUrl(o,d){if(o==null||d>6)return '';if(typeof o==='string'){if(o.indexOf('data:image')===0||/^https?:\\/\\//.test(o))return o;return '';}if(typeof o==='object'){if(typeof o.url==='string'){var u0=digUrl(o.url,d+1);if(u0)return u0;}if(o.length!=null&&typeof o!=='string'){for(var i=0;i<o.length;i++){var u=digUrl(o[i],d+1);if(u)return u;}}for(var k in o){try{if(!Object.prototype.hasOwnProperty.call(o,k))continue;}catch(e){continue;}var u2=digUrl(o[k],d+1);if(u2)return u2;}return '';}return '';}\nvar RUSH='https://ai-playground.data2apis.com/rush/vivDraw';\nvar PART=[['Mão','an elegant hand, graceful fingers, manicured','hand'],['Rosto','a beautiful face portrait, serene expression','face'],['Colo','the neckline, collarbones and décolletage','neck'],['Perfil','a refined profile view of the face and ear','profile'],['Pulso','a slender wrist and forearm','wrist']];\nvar SKIN=[['Clara','fair porcelain skin'],['Média','light beige skin'],['Oliva','warm olive skin'],['Morena','golden-brown skin'],['Retinta','deep rich ebony skin']];\nvar AGE=[['Jovem','in her early 20s'],['Adulta','in her 30s, poised'],['Madura','in her 50s, graceful and distinguished']];\nvar LOOK=[['Feminina','feminine elegant model'],['Masculina','masculine refined model'],['Andrógina','androgynous striking model']];\nvar LIGHT=[['Suave','soft diffused beauty light'],['Editorial','crisp editorial lighting'],['Golden','warm golden glow'],['Dramática','dramatic chiaroscuro']];\nvar MOOD=[['Editorial','high-fashion editorial mood'],['Natural','natural authentic beauty'],['Glamour','glamorous luxe styling'],['Minimal','clean minimal aesthetic']];\nfunction frag(a,v){var f=a.filter(function(o){return o[0]===v;})[0];return f?f[1]:a[0][1];}\nfunction ex(a,v){var f=a.filter(function(o){return o[0]===v;})[0];return f?f[2]:a[0][2];}\nfunction sec(t,a,k,sel){return '<div class=\"sec\"><div class=\"sl\">'+t+'</div><div class=\"chips\">'+a.map(function(o){return '<span class=\"chip'+(sel===o[0]?' on':'')+'\" data-k=\"'+k+'\" data-v=\"'+esc(o[0])+'\">'+esc(o[0])+'</span>';}).join('')+'</div></div>';}\nvar STEPS=['Definindo traços','Esculpindo a luz','Refinando a pele','Renderizando'];\nexport default {\n  css:`@import url('https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@500;600&family=Jost:wght@300;400;500;600&display=swap');\n    .mo{height:100%;box-sizing:border-box;background:#FAF8F5;color:#1A1A1A;font-family:'Jost',sans-serif;display:flex;overflow:hidden}\n    .cfg{width:360px;flex:0 0 auto;background:#fff;border-right:1px solid #E8E2D9;display:flex;flex-direction:column;overflow:hidden}\n    .scr{flex:1;overflow:auto}.grp{padding:18px 22px;border-bottom:1px solid #F0EBE2}\n    .gh{font-family:'Cormorant Garamond',serif;font-size:16px;font-weight:600;margin-bottom:12px}\n    .sec{margin-bottom:14px}.sec:last-child{margin-bottom:0}.sl{font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:#9B8E7E;margin-bottom:7px}\n    .chips{display:flex;flex-wrap:wrap;gap:6px}.chip{font-size:11.5px;padding:6px 11px;border:1px solid #E0D6C4;background:#fff;cursor:pointer;transition:.15s;color:#5A5045;border-radius:2px}\n    .chip:hover{border-color:#B08D57;transform:translateY(-2px);box-shadow:0 6px 14px rgba(176,141,87,.18)}.chip.on{background:#1A1A1A;color:#fff;border-color:#1A1A1A}\n    .nm{width:100%;box-sizing:border-box;border:1px solid #E0D6C4;padding:10px;font:inherit;font-size:13px;background:#FAF8F5;border-radius:2px}\n    .go{flex:0 0 auto;margin:16px 22px;background:#1A1A1A;color:#fff;border:none;padding:15px;font:inherit;font-size:13px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;cursor:pointer;transition:.2s;border-radius:3px;position:relative;overflow:hidden}\n    .go:hover:not(:disabled){background:#B08D57;letter-spacing:.14em}.go:disabled{opacity:.35;cursor:default}\n    .go .sheen{position:absolute;inset:0;background:linear-gradient(110deg,transparent 35%,rgba(201,162,75,.5) 50%,transparent 65%);transform:translateX(-120%);animation:sheen 3.6s ease-in-out infinite;pointer-events:none}@keyframes sheen{0%{transform:translateX(-120%)}55%,100%{transform:translateX(120%)}}\n    .main{flex:1;display:flex;flex-direction:column;overflow:hidden;position:relative;background:radial-gradient(circle at 50% 30%,#FFFDFA,#F2ECE2)}\n    .hd{padding:22px 30px 0;font-family:'Cormorant Garamond',serif;font-size:26px;font-weight:600}\n    .hsub{padding:2px 30px 0;font-size:12px;color:#9B8E7E}\n    .gal{flex:1;overflow:auto;padding:22px 30px;display:grid;gap:16px;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));align-content:start}\n    .card{position:relative;background:#fff;box-shadow:0 12px 30px rgba(120,95,50,.16);animation:fade .5s ease;border-radius:3px;overflow:hidden}\n    .card .im{width:100%;aspect-ratio:3/4;background:#F3EEE5 center/cover}\n    .card .meta{padding:9px 11px}.card .nme{font-size:13px;font-weight:500}.card .knd{font-size:10px;letter-spacing:.08em;text-transform:uppercase;color:#B08D57}\n    .card .del{position:absolute;top:8px;right:8px;width:24px;height:24px;border-radius:50%;background:rgba(255,255,255,.92);border:1px solid #E0D6C4;cursor:pointer;font-size:12px;display:flex;align-items:center;justify-content:center;opacity:0;transition:.15s}.card:hover .del{opacity:1}\n    .empty{grid-column:1/-1;text-align:center;color:#9B8E7E;padding:60px 0;font-family:'Cormorant Garamond',serif;font-size:20px}\n    @keyframes fade{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}\n    .load{position:absolute;inset:0;background:rgba(250,248,245,.94);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:16px;z-index:5}\n    .load canvas{position:absolute;inset:0;width:100%;height:100%}\n    .ring{width:68px;height:68px;z-index:1}.ring svg{width:100%;height:100%;animation:rot 1.4s linear infinite}@keyframes rot{to{transform:rotate(360deg)}}\n    .step{z-index:1;font-family:'Cormorant Garamond',serif;font-size:21px;font-weight:600}.ssub{z-index:1;font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:#B08D57}\n  `,\n  render(d2){\n    var models=(d2.data('dataset')&&d2.data('dataset').records())||[];\n    var s=d2.state;\n    var part=s.part||'Mão',skin=s.skin||'Média',age=s.age||'Adulta',look=s.look||'Feminina',light=s.light||'Suave',mood=s.mood||'Editorial';\n    var dir=sec('Enquadramento',PART,'part',part)+sec('Tom de pele',SKIN,'skin',skin)+sec('Idade',AGE,'age',age)+sec('Look',LOOK,'look',look)+sec('Iluminação',LIGHT,'light',light)+sec('Mood',MOOD,'mood',mood);\n    var cards=models.map(function(m){var has=m.imageUrl&&m.imageUrl.length>10;return '<div class=\"card\" data-id=\"'+m._id+'\"><div class=\"del\" data-del=\"'+m._id+'\">×</div><div class=\"im\" style=\"'+(has?'background-image:url('+esc(m.imageUrl)+')':'')+'\"></div><div class=\"meta\"><div class=\"nme\">'+esc(m.name||'Modelo')+'</div><div class=\"knd\">'+esc(m.kind||'')+'</div></div></div>';}).join('');\n    if(!models.length)cards='<div class=\"empty\">Nenhuma modelo ainda — defina e gere a primeira.</div>';\n    var load='';\n    if(s.busy){var st=Math.min(3,s.loadStep||0);load='<div class=\"load\"><canvas data-spark></canvas><div class=\"ring\"><svg viewBox=\"0 0 50 50\"><circle cx=\"25\" cy=\"25\" r=\"20\" fill=\"none\" stroke=\"#E8E2D9\" stroke-width=\"3\"/><circle cx=\"25\" cy=\"25\" r=\"20\" fill=\"none\" stroke=\"#B08D57\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-dasharray=\"90 126\"/></svg></div><div class=\"step\">'+esc(STEPS[st])+'…</div><div class=\"ssub\">criando personagem · ~25s</div></div>';}\n    return '<div class=\"mo\"><div class=\"cfg\"><div class=\"scr\"><div class=\"grp\"><div class=\"gh\">Nova modelo</div><input class=\"nm\" data-name placeholder=\"Nome (ex: Helena)\" value=\"'+esc(s.nameVal||'')+'\"/></div><div class=\"grp\"><div class=\"gh\">Direção</div>'+dir+'</div></div><button class=\"go\" data-go '+(s.busy?'disabled':'')+'><span class=\"sheen\"></span>Gerar Modelo</button></div><div class=\"main\"><div class=\"hd\">Modelos Virtuais</div><div class=\"hsub\">Personagens fotorrealistas para o seu try-on</div><div class=\"gal\">'+cards+'</div>'+load+'</div></div>';\n  },\n  mounted(d2){\n    var parts=[],loadStart=null,lastStep=-1;\n    d2.on('[data-k]','click',function(e,el){var st={};st[el.getAttribute('data-k')]=el.getAttribute('data-v');d2.setState(st);});\n    d2.on('[data-name]','input',function(e,el){d2.state.nameVal=el.value;});\n    d2.on('[data-del]','click',function(e,el){var id=el.getAttribute('data-del');var rec=((d2.data('dataset')&&d2.data('dataset').records())||[]).filter(function(r){return r._id===id;})[0];if(rec)d2.data('dataset').remove(rec);});\n    d2.raf(function(t){\n      if(d2.state.busy){if(loadStart==null){loadStart=t;parts=[];}var stp=Math.min(3,Math.floor((t-loadStart)/6000));if(stp!==lastStep){lastStep=stp;d2.setState({loadStep:stp});}}\n      else{loadStart=null;lastStep=-1;}\n      var cv=d2.$('[data-spark]');if(!cv)return;var ctx=cv.getContext('2d');var dpr=Math.min(window.devicePixelRatio||1,2);var w=cv.clientWidth,h=cv.clientHeight;if(cv.width!==Math.round(w*dpr)){cv.width=Math.round(w*dpr);cv.height=Math.round(h*dpr);ctx.setTransform(dpr,0,0,dpr,0,0);}\n      if(parts.length<40&&Math.random()<0.45)parts.push({x:Math.random()*w,y:h+10,vy:-(Math.random()*0.7+0.3),r:Math.random()*2+0.6,a:0,life:Math.random()*0.5+0.5});\n      ctx.clearRect(0,0,w,h);\n      for(var i=parts.length-1;i>=0;i--){var p=parts[i];p.y+=p.vy;p.a=Math.min(p.life,p.a+0.01);p.life-=0.004;if(p.life<=0||p.y<-10){parts.splice(i,1);continue;}var tw=0.6+0.4*Math.sin(t/300+p.x);ctx.fillStyle='rgba(201,162,75,'+(p.a*tw).toFixed(2)+')';ctx.beginPath();ctx.arc(p.x,p.y,p.r,0,6.28);ctx.fill();}\n    });\n    d2.on('[data-go]','click',function(){\n      if(d2.state.busy)return;\n      var s=d2.state;\n      var nm=(s.nameVal||'').trim()||('Modelo '+(((d2.data('dataset')&&d2.data('dataset').count)||0)+1));\n      var prompt='Ultra-realistic photograph of '+frag(LOOK,s.look||'Feminina')+', '+frag(AGE,s.age||'Adulta')+', with '+frag(SKIN,s.skin||'Média')+'. Show '+frag(PART,s.part||'Mão')+', completely bare with NO jewelry, ready for jewelry placement. Lighting: '+frag(LIGHT,s.light||'Suave')+'. Mood: '+frag(MOOD,s.mood||'Editorial')+'. Clean seamless studio background, hyperrealistic 8k beauty photography, flawless skin, Vivara premium aesthetic.';\n      d2.setState({busy:true,loadStep:0});\n      fetch(RUSH,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({prompt:prompt,options:{size:'896x1152'}})}).then(function(res){return res.json();}).then(function(j){var url=digUrl(j,0);if(url){try{d2.data('dataset').create({name:nm,kind:ex(PART,s.part||'Mão'),prompt:prompt,imageUrl:url,createdAt:new Date().toISOString()});}catch(_){}}d2.setState({busy:false,nameVal:''});}).catch(function(){d2.setState({busy:false});});\n    });\n  }\n}"}},"dataset":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"dataset"}}}}}}}}}},{"_id":"6a2e0fe058bb101c90951597","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kVivTryon","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>\"]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c];});}\nfunction norm(p){var it=(p.items&&p.items[0])||{};var img=(it.images&&it.images[0]&&it.images[0].imageUrl)||'';var pr=p.priceRange||{};return {id:String(p.productId),name:p.productName,image:img,price:(pr.sellingPrice&&pr.sellingPrice.lowPrice)||0,cat:(p.categories&&p.categories[0])||''};}\nfunction digUrl(o,d){if(o==null||d>6)return '';if(typeof o==='string'){if(o.indexOf('data:image')===0||/^https?:\\/\\//.test(o))return o;return '';}if(typeof o==='object'){if(typeof o.url==='string'){var u0=digUrl(o.url,d+1);if(u0)return u0;}if(o.length!=null&&typeof o!=='string'){for(var i=0;i<o.length;i++){var u=digUrl(o[i],d+1);if(u)return u;}}for(var k in o){try{if(!Object.prototype.hasOwnProperty.call(o,k))continue;}catch(e){continue;}var u2=digUrl(o[k],d+1);if(u2)return u2;}return '';}return '';}\nvar RUSH='https://ai-playground.data2apis.com/rush/vivDraw';\nvar LIGHT=[['Estúdio Suave','soft diffused studio softbox light, even flattering glow'],['Dramática','dramatic chiaroscuro, single key light, deep shadows'],['Golden Hour','warm golden-hour backlight, soft rim glow'],['High-Key','bright high-key, airy, minimal shadows'],['Cinematográfica','cinematic moody lighting, volumetric haze'],['Spotlight','tight spotlight on the jewel, brilliant gemstone sparkle']];\nvar SKIN=[['Clara','fair porcelain skin'],['Média','light beige skin'],['Oliva','warm olive skin'],['Morena','golden-brown skin'],['Retinta','deep rich ebony skin']];\nvar SCENE=[['Mármore','polished white marble with subtle gold veining'],['Veludo','deep black velvet backdrop'],['Seda','flowing champagne silk folds'],['Concreto','minimalist micro-cement surface'],['Natureza','softly blurred green foliage, dappled light'],['Infinito','seamless pure white infinity background']];\nvar FRAME=[['Macro','extreme macro close-up, shallow depth of field'],['Natural','elegant natural framing of hand/neck'],['Editorial','wide fashion-editorial framing']];\nvar FINISH=[['Hiper-real','hyperrealistic, ultra sharp, 8k, true materials'],['Editorial','high-fashion editorial retouch, magazine grade'],['E-commerce','clean catalog e-commerce finish']];\nvar RATIO=[['Retrato','896x1152'],['Quadrado','1024x1024'],['Story','768x1344']];\nvar STEPS=['Analisando a peça','Posicionando na modelo','Ajustando a iluminação','Refinando texturas e brilho','Renderizando em alta resolução'];\nfunction frag(a,v){var f=a.filter(function(o){return o[0]===v;})[0];return f?f[1]:a[0][1];}\nfunction sec(t,a,k,sel){return '<div class=\"sec\"><div class=\"sl\">'+t+'</div><div class=\"chips\">'+a.map(function(o){return '<span class=\"chip'+(sel===o[0]?' on':'')+'\" data-k=\"'+k+'\" data-v=\"'+esc(o[0])+'\">'+esc(o[0])+'</span>';}).join('')+'</div></div>';}\nexport default {\n  css:`@import url('https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@500;600&family=Jost:wght@300;400;500;600&display=swap');\n    *{-webkit-tap-highlight-color:transparent}\n    .ty{height:100%;box-sizing:border-box;background:#FAF8F5;color:#1A1A1A;font-family:'Jost',sans-serif;display:flex;overflow:hidden}\n    .cfg{width:380px;flex:0 0 auto;background:#fff;border-right:1px solid #E8E2D9;display:flex;flex-direction:column;overflow:hidden;position:relative;z-index:2}\n    .scr{flex:1;overflow:auto}.grp{padding:18px 22px;border-bottom:1px solid #F0EBE2}\n    .gh{font-family:'Cormorant Garamond',serif;font-size:16px;font-weight:600;margin-bottom:12px;display:flex;align-items:center;gap:8px}\n    .gh .n{width:19px;height:19px;border-radius:50%;background:#1A1A1A;color:#fff;font-size:10px;display:flex;align-items:center;justify-content:center}\n    .row{display:flex;gap:9px;overflow-x:auto;padding-bottom:3px}\n    .thumb{width:66px;flex:0 0 auto;cursor:pointer;text-align:center}\n    .thumb .im{width:66px;height:82px;background:#F3EEE5 center/cover;border:2px solid transparent;transition:.2s;border-radius:3px}\n    .thumb.on .im{border-color:#B08D57;box-shadow:0 0 0 3px rgba(176,141,87,.18)}.thumb .lb{font-size:9px;color:#9B8E7E;margin-top:3px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n    .up{width:66px;height:82px;flex:0 0 auto;border:1px dashed #C9BBA3;border-radius:3px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;cursor:pointer;color:#9B8E7E;font-size:9px;text-align:center}.up.on{border-style:solid;border-color:#B08D57}\n    .pg{display:grid;grid-template-columns:repeat(4,1fr);gap:6px;max-height:180px;overflow:auto}\n    .pc{cursor:pointer;border:2px solid transparent;padding:3px;background:#fff;border-radius:4px;transition:.2s}.pc:hover{transform:translateY(-2px)}.pc.on{border-color:#B08D57;animation:pulse 1.8s ease-in-out infinite}.pc img{width:100%;aspect-ratio:1;object-fit:contain;mix-blend-mode:multiply}\n    @keyframes pulse{0%,100%{box-shadow:0 0 0 0 rgba(176,141,87,.4)}50%{box-shadow:0 0 0 5px rgba(176,141,87,0)}}\n    .sec{margin-bottom:14px}.sec:last-child{margin-bottom:0}.sl{font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:#9B8E7E;margin-bottom:7px}\n    .chips{display:flex;flex-wrap:wrap;gap:6px}.chip{font-size:11.5px;padding:6px 11px;border:1px solid #E0D6C4;background:#fff;cursor:pointer;transition:.18s cubic-bezier(.2,.8,.2,1);color:#5A5045;border-radius:2px}\n    .chip:hover{border-color:#B08D57;transform:translateY(-2px);box-shadow:0 6px 14px rgba(176,141,87,.18)}.chip.on{background:#1A1A1A;color:#fff;border-color:#1A1A1A}\n    .go{flex:0 0 auto;margin:16px 22px;background:#1A1A1A;color:#fff;border:none;padding:15px;font:inherit;font-size:13px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;cursor:pointer;transition:.2s;position:relative;overflow:hidden;border-radius:3px}\n    .go:hover{letter-spacing:.14em;box-shadow:0 10px 26px rgba(26,26,26,.28)}.go.dim{opacity:.5}\n    .go .sheen{position:absolute;inset:0;background:linear-gradient(110deg,transparent 35%,rgba(201,162,75,.55) 50%,transparent 65%);transform:translateX(-120%);animation:sheen 3.6s ease-in-out infinite;pointer-events:none}\n    @keyframes sheen{0%{transform:translateX(-120%)}55%,100%{transform:translateX(120%)}}\n    .rip{position:absolute;border-radius:50%;background:rgba(201,162,75,.5);transform:translate(-50%,-50%) scale(0);width:280px;height:280px;animation:rip .6s ease-out;pointer-events:none}\n    @keyframes rip{to{transform:translate(-50%,-50%) scale(1);opacity:0}}\n    .stage{flex:1;position:relative;overflow:hidden;background:radial-gradient(circle at 50% 35%,#FFFDFA,#EFE7DA);perspective:1200px}\n    .bgfx{position:absolute;inset:0;width:100%;height:100%;z-index:0}\n    .depth{position:absolute;inset:0;z-index:1;display:flex;align-items:center;justify-content:center;padding:46px;transform-style:preserve-3d;transition:transform .18s ease-out}\n    .hint{text-align:center;color:#9B8E7E;transform:translateZ(40px)}.hint .mk{font-family:'Cormorant Garamond',serif;font-size:44px;color:#1A1A1A;font-weight:600;letter-spacing:.01em}\n    .hint .ru{width:60px;height:1px;background:linear-gradient(90deg,transparent,#B08D57,transparent);margin:14px auto}\n    .hint .sub{font-size:13px;letter-spacing:.05em}.hint .star{font-size:16px;color:#C9A24B;display:block;margin-bottom:8px;animation:tw 2.4s ease-in-out infinite}@keyframes tw{0%,100%{opacity:.4;transform:scale(.9)}50%{opacity:1;transform:scale(1.15)}}\n    .frame{position:relative;padding:12px;background:#fff;box-shadow:0 40px 90px rgba(120,95,50,.34);transform:translateZ(60px);animation:reveal .7s cubic-bezier(.2,.8,.2,1)}\n    .frame::after{content:'';position:absolute;inset:5px;border:1px solid #D9C9A8;pointer-events:none}\n    .res{display:block;max-width:46vw;max-height:64vh;object-fit:contain}\n    .glare{position:absolute;inset:0;pointer-events:none;mix-blend-mode:screen;background:radial-gradient(circle at calc(var(--px,.5)*100%) calc(var(--py,.5)*100%),rgba(255,255,255,.5),rgba(255,255,255,0) 42%)}\n    @keyframes reveal{from{opacity:0;transform:translateZ(60px) scale(.94);filter:blur(14px)}to{opacity:1;transform:translateZ(60px) scale(1);filter:blur(0)}}\n    .summ{position:absolute;left:0;right:0;bottom:24px;display:flex;flex-wrap:wrap;gap:6px;justify-content:center;z-index:3}\n    .tag{font-size:10px;letter-spacing:.06em;color:#8A6A38;border:1px solid rgba(176,141,87,.4);background:rgba(255,255,255,.65);padding:3px 9px;backdrop-filter:blur(6px);border-radius:20px}\n    .acts{position:absolute;top:24px;right:30px;display:flex;gap:8px;z-index:4}\n    .act{font-size:12px;font-weight:600;padding:8px 14px;border:1px solid #1A1A1A;background:rgba(255,255,255,.85);backdrop-filter:blur(6px);color:#1A1A1A;cursor:pointer;text-decoration:none;border-radius:3px;transition:.15s}.act:hover{background:#1A1A1A;color:#fff}\n    .load{position:absolute;inset:0;z-index:5;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:18px}\n    .load canvas{position:absolute;inset:0;width:100%;height:100%}\n    .ring{width:78px;height:78px;position:relative;z-index:1}.ring svg{width:100%;height:100%;animation:rot 1.4s linear infinite}@keyframes rot{to{transform:rotate(360deg)}}\n    .step{z-index:1;font-family:'Cormorant Garamond',serif;font-size:24px;color:#1A1A1A;font-weight:600;text-shadow:0 2px 20px rgba(255,253,248,.9)}\n    .ssub{z-index:1;font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:#B08D57}\n    .pbar{z-index:1;width:240px;height:2px;background:rgba(176,141,87,.22);overflow:hidden;border-radius:2px}.pfill{height:100%;background:linear-gradient(90deg,#C9A24B,#B08D57);transition:width .6s cubic-bezier(.3,1,.4,1)}\n  `,\n  render(d2){\n    var prods=((d2.data('products')&&d2.data('products').records())||[]).map(norm).filter(function(p){return p.image&&p.cat.indexOf('/Joias/')>=0;});\n    var models=(d2.data('models')&&d2.data('models').records())||[];\n    var s=d2.state;\n    var selM=s.selModelId,up=s.uploadedImg,selP=s.selProductId;\n    var light=s.light||'Estúdio Suave',skin=s.skin||'Média',scene=s.scene||'Mármore',frame=s.frame||'Natural',finish=s.finish||'Hiper-real',ratio=s.ratio||'Retrato';\n    var mrow=models.map(function(m){var has=m.imageUrl&&m.imageUrl.length>10;return '<div class=\"thumb'+(selM===m._id?' on':'')+'\" data-model=\"'+m._id+'\"><div class=\"im\" style=\"'+(has?'background-image:url('+esc(m.imageUrl)+')':'')+'\"></div><div class=\"lb\">'+esc(m.name)+'</div></div>';}).join('');\n    var upc='<div class=\"up'+(selM==='upload'?' on':'')+'\" data-upwrap><span style=\"font-size:18px\">↑</span>sua foto<input data-upload type=\"file\" accept=\"image/*\" style=\"display:none\"/></div>';\n    var pg=prods.map(function(p){return '<div class=\"pc'+(selP===p.id?' on':'')+'\" data-prod=\"'+p.id+'\"><img loading=\"lazy\" src=\"'+esc(p.image)+'\"/></div>';}).join('');\n    var dir=sec('Iluminação',LIGHT,'light',light)+sec('Tom de pele',SKIN,'skin',skin)+sec('Cenário',SCENE,'scene',scene)+sec('Enquadramento',FRAME,'frame',frame)+sec('Acabamento',FINISH,'finish',finish)+sec('Proporção',RATIO,'ratio',ratio);\n    var inner;\n    if(s.busy){var st=Math.min(4,s.loadStep||0);inner='<div class=\"load\"><canvas data-spark></canvas><div class=\"ring\"><svg viewBox=\"0 0 50 50\"><circle cx=\"25\" cy=\"25\" r=\"20\" fill=\"none\" stroke=\"rgba(176,141,87,.18)\" stroke-width=\"3\"/><circle cx=\"25\" cy=\"25\" r=\"20\" fill=\"none\" stroke=\"#B08D57\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-dasharray=\"90 126\"/></svg></div><div class=\"step\">'+esc(STEPS[st])+'…</div><div class=\"pbar\"><div class=\"pfill\" style=\"width:'+((st+1)/5*100)+'%\"></div></div><div class=\"ssub\">a IA está compondo · ~30s</div></div>';}\n    else if(s.result){inner='<div class=\"frame\"><img class=\"res\" src=\"'+esc(s.result)+'\"/><div class=\"glare\"></div></div>';}\n    else if(s.error){inner='<div class=\"hint\"><span class=\"star\">⚠</span><div class=\"mk\" style=\"font-size:32px\">Ops</div><div class=\"ru\"></div><div class=\"sub\">'+esc(s.error)+'</div></div>';}\n    else{inner='<div class=\"hint\"><span class=\"star\">✦</span><div class=\"mk\">Atelier Virtual</div><div class=\"ru\"></div><div class=\"sub\">Escolha a modelo, a joia e dirija a cena.</div></div>';}\n    var actbar=s.result?'<div class=\"acts\"><a class=\"act\" href=\"'+esc(s.result)+'\" download=\"vivara-tryon.png\">↓ Baixar</a><span class=\"act\" data-reset>↻ Nova</span></div>':'';\n    var summ=s.result?'<div class=\"summ\">'+[light,skin,scene,frame,finish].map(function(x){return '<span class=\"tag\">'+esc(x)+'</span>';}).join('')+'</div>':'';\n    var canGo=(selM&&(selM!=='upload'||up))&&selP&&!s.busy;\n    return '<div class=\"ty\"><div class=\"cfg\"><div class=\"scr\"><div class=\"grp\"><div class=\"gh\"><span class=\"n\">1</span>Modelo</div><div class=\"row\">'+upc+mrow+'</div></div><div class=\"grp\"><div class=\"gh\"><span class=\"n\">2</span>Joia</div><div class=\"pg\">'+pg+'</div></div><div class=\"grp\"><div class=\"gh\"><span class=\"n\">3</span>Direção de arte</div>'+dir+'</div></div><button class=\"go'+(canGo?'':' dim')+'\" data-go><span class=\"sheen\"></span>Renderizar Try-on</button></div><div class=\"stage\" data-stage><canvas class=\"bgfx\" data-bg></canvas><div class=\"depth\" data-depth>'+inner+'</div>'+actbar+summ+'</div></div>';\n  },\n  mounted(d2){\n    var parts=[],loadStart=null,lastStep=-1;\n    d2.on('[data-k]','click',function(e,el){var st={};st[el.getAttribute('data-k')]=el.getAttribute('data-v');d2.setState(st);});\n    d2.on('[data-model]','click',function(e,el){d2.setState({selModelId:el.getAttribute('data-model'),error:null});});\n    d2.on('[data-prod]','click',function(e,el){d2.setState({selProductId:el.getAttribute('data-prod'),error:null});});\n    d2.on('[data-reset]','click',function(){d2.setState({result:null,error:null});});\n    d2.on('[data-upwrap]','click',function(){var i=d2.$('[data-upload]');if(i)i.click();});\n    d2.on('[data-upload]','change',function(e,el){var f=el.files&&el.files[0];if(!f)return;var rd=new FileReader();rd.onload=function(){d2.setState({uploadedImg:rd.result,selModelId:'upload',error:null});};rd.readAsDataURL(f);});\n    var st=d2.$('[data-stage]');\n    if(st){d2.on(st,'pointermove',function(e){var r=st.getBoundingClientRect();var px=(e.clientX-r.left)/r.width,py=(e.clientY-r.top)/r.height;st.style.setProperty('--px',px.toFixed(3));st.style.setProperty('--py',py.toFixed(3));var dp=st.querySelector('[data-depth]');if(dp)dp.style.transform='rotateY('+((px-0.5)*9).toFixed(2)+'deg) rotateX('+((0.5-py)*7).toFixed(2)+'deg)';});\n      d2.on(st,'pointerleave',function(){st.style.setProperty('--px','.5');st.style.setProperty('--py','.5');var dp=st.querySelector('[data-depth]');if(dp)dp.style.transform='rotateY(0deg) rotateX(0deg)';});}\n    d2.raf(function(t){\n      if(d2.state.busy){if(loadStart==null){loadStart=t;parts=[];}var stp=Math.min(4,Math.floor((t-loadStart)/5200));if(stp!==lastStep){lastStep=stp;d2.setState({loadStep:stp});}}\n      else{loadStart=null;lastStep=-1;}\n      var bg=d2.$('[data-bg]');\n      if(bg){var bc=bg.getContext('2d');var dpr=Math.min(window.devicePixelRatio||1,2);var w=bg.clientWidth,h=bg.clientHeight;if(bg.width!==Math.round(w*dpr)){bg.width=Math.round(w*dpr);bg.height=Math.round(h*dpr);bc.setTransform(dpr,0,0,dpr,0,0);}\n        bc.clearRect(0,0,w,h);bc.globalCompositeOperation='lighter';var bl=[['201,162,75',0],['233,213,178',2.1],['176,141,87',4.2],['251,246,236',1.3]];\n        for(var b=0;b<bl.length;b++){var ph=bl[b][1];var cx=w*(0.5+0.34*Math.sin(t/3800+ph));var cy=h*(0.5+0.34*Math.cos(t/4300+ph*1.6));var rr=Math.max(w,h)*0.62;var g=bc.createRadialGradient(cx,cy,0,cx,cy,rr);g.addColorStop(0,'rgba('+bl[b][0]+',0.20)');g.addColorStop(1,'rgba('+bl[b][0]+',0)');bc.fillStyle=g;bc.beginPath();bc.arc(cx,cy,rr,0,6.28);bc.fill();}\n        bc.globalCompositeOperation='source-over';}\n      if(d2.state.busy){var cv=d2.$('[data-spark]');if(cv){var ctx=cv.getContext('2d');var dpr2=Math.min(window.devicePixelRatio||1,2);var w2=cv.clientWidth,h2=cv.clientHeight;if(cv.width!==Math.round(w2*dpr2)){cv.width=Math.round(w2*dpr2);cv.height=Math.round(h2*dpr2);ctx.setTransform(dpr2,0,0,dpr2,0,0);}\n        if(parts.length<54&&Math.random()<0.6)parts.push({x:Math.random()*w2,y:h2+10,vy:-(Math.random()*0.8+0.3),r:Math.random()*2.2+0.6,a:0,life:Math.random()*0.5+0.5});\n        ctx.clearRect(0,0,w2,h2);\n        for(var i=parts.length-1;i>=0;i--){var p=parts[i];p.y+=p.vy;p.a=Math.min(p.life,p.a+0.01);p.life-=0.004;if(p.life<=0||p.y<-10){parts.splice(i,1);continue;}var tw=0.6+0.4*Math.sin(t/300+p.x);ctx.fillStyle='rgba(201,162,75,'+(p.a*tw).toFixed(2)+')';ctx.beginPath();ctx.arc(p.x,p.y,p.r,0,6.28);ctx.fill();}}}\n    });\n    function fail(msg){d2.setState({busy:false,error:msg||'Falha ao gerar. Tente novamente.'});}\n    function finish(d2ref,modName,prod,r){\n      var url=digUrl(r,0);\n      if(url){d2ref.setState({result:url,busy:false,error:null});try{d2ref.data('tryons').create({modelName:modName,productName:prod.name,productImage:prod.image,resultUrl:url,ts:new Date().toISOString()});}catch(_){}}\n      else{fail('Não recebi a imagem da IA. Tente novamente.');}\n    }\n    d2.on('[data-go]','click',function(e,el){\n      if(d2.state.busy)return;\n      if(el){var r0=el.getBoundingClientRect();var rp=document.createElement('span');rp.className='rip';rp.style.left=(e.clientX-r0.left)+'px';rp.style.top=(e.clientY-r0.top)+'px';el.appendChild(rp);setTimeout(function(){if(rp.parentNode)rp.parentNode.removeChild(rp);},600);}\n      var prods=((d2.data('products')&&d2.data('products').records())||[]).map(norm);\n      var prod=prods.filter(function(p){return p.id===d2.state.selProductId;})[0];\n      var models=(d2.data('models')&&d2.data('models').records())||[];\n      var selM=d2.state.selModelId,modImg,modName,modDesc;\n      if(selM==='upload'){modImg=d2.state.uploadedImg;modName='Foto enviada';modDesc='the person from the provided photo';}\n      else{var m=models.filter(function(x){return x._id===selM;})[0];if(m){modImg=m.imageUrl;modName=m.name;modDesc='an elegant model ('+(m.kind||'hand')+')';}}\n      if(!selM||(selM==='upload'&&!modImg)){d2.setState({error:'Selecione uma modelo (ou envie sua foto).'});return;}\n      if(!prod){d2.setState({error:'Selecione uma joia.'});return;}\n      var s=d2.state;\n      var prompt='Ultra-realistic luxury jewelry editorial photograph. '+modDesc+' with '+frag(SKIN,s.skin||'Média')+', wearing this EXACT jewel from the reference image — keep the jewel perfectly identical in shape, gemstones and finish, positioned naturally. Lighting: '+frag(LIGHT,s.light||'Estúdio Suave')+'. Background: '+frag(SCENE,s.scene||'Mármore')+'. Framing: '+frag(FRAME,s.frame||'Natural')+'. Style: '+frag(FINISH,s.finish||'Hiper-real')+'. Vivara high-end premium aesthetic, flawless professional jewelry photography. Hero jewel: '+prod.name+'.';\n      var imgs=[];if(modImg&&modImg.length>10)imgs.push(modImg);imgs.push(prod.image);\n      d2.setState({busy:true,result:null,error:null,loadStep:0});\n      fetch(RUSH,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({prompt:prompt,images:imgs,options:{size:frag(RATIO,s.ratio||'Retrato')}})}).then(function(res){return res.json();}).then(function(j){finish(d2,modName,prod,j);}).catch(function(){fail();});\n    });\n  }\n}"}},"models":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"models"}}}},"products":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"products"}}}},"tryons":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"tryons"}}}}}}}}}},{"_id":"6a2e0fe1e303c67716fac878","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kVivCatalogGen","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>\"]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c];});}\nfunction norm(p){var it=(p.items&&p.items[0])||{};var img=(it.images&&it.images[0]&&it.images[0].imageUrl)||'';var pr=p.priceRange||{};return {id:String(p.productId),name:p.productName,image:img,price:(pr.sellingPrice&&pr.sellingPrice.lowPrice)||0,cat:(p.categories&&p.categories[0])||''};}\nfunction digUrl(o,d){if(o==null||d>6)return '';if(typeof o==='string'){if(o.indexOf('data:image')===0||/^https?:\\/\\//.test(o))return o;return '';}if(typeof o==='object'){if(typeof o.url==='string'){var u0=digUrl(o.url,d+1);if(u0)return u0;}if(o.length!=null&&typeof o!=='string'){for(var i=0;i<o.length;i++){var u=digUrl(o[i],d+1);if(u)return u;}}for(var k in o){try{if(!Object.prototype.hasOwnProperty.call(o,k))continue;}catch(e){continue;}var u2=digUrl(o[k],d+1);if(u2)return u2;}return '';}return '';}\nvar RUSH='https://ai-playground.data2apis.com/rush/vivDraw';\nvar SURF=[['Mármore','floating on polished white marble with gold veining'],['Veludo','on deep black velvet, soft reflection'],['Seda','nestled in champagne silk folds'],['Acrílico','on a glossy acrylic riser, clean reflection'],['Pedra','on raw natural stone, organic texture'],['Água','on a still water surface, subtle ripple reflection']];\nvar BG=[['Infinito Creme','seamless warm cream infinity background'],['Preto','pure dramatic black background'],['Gradiente','soft beige-to-gold gradient backdrop'],['Boudoir','blurred luxe boudoir interior bokeh'],['Botânico','out-of-focus botanical greenery'],['Sunset','warm sunset gradient glow']];\nvar LIGHT=[['Suave','soft diffused studio light, gentle gradients'],['Joalheria','crisp jewelry lighting, maximum gemstone sparkle and fire'],['Dramática','dramatic single-source light, deep luxury shadows'],['Golden','warm golden glow, premium mood'],['High-Key','bright clean high-key, e-commerce ready']];\nvar STYLE=[['Hero','hero macro shot, extreme detail, shallow depth of field'],['Editorial','high-fashion editorial composition, magazine grade'],['Lifestyle','aspirational lifestyle styling with elegant props'],['Minimal','ultra-minimal clean catalog, centered'],['Pack-shot','crisp e-commerce pack-shot, full sharp focus']];\nvar RATIO=[['Quadrado','1024x1024'],['Retrato','896x1152'],['Paisagem','1152x896']];\nvar STEPS=['Estudando a peça','Montando o set','Posicionando luzes','Capturando reflexos','Renderizando em alta'];\nfunction frag(a,v){var f=a.filter(function(o){return o[0]===v;})[0];return f?f[1]:a[0][1];}\nfunction sec(t,a,k,sel){return '<div class=\"sec\"><div class=\"sl\">'+t+'</div><div class=\"chips\">'+a.map(function(o){return '<span class=\"chip'+(sel===o[0]?' on':'')+'\" data-k=\"'+k+'\" data-v=\"'+esc(o[0])+'\">'+esc(o[0])+'</span>';}).join('')+'</div></div>';}\nexport default {\n  css:`@import url('https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@500;600&family=Jost:wght@300;400;500;600&display=swap');\n    .cg{height:100%;box-sizing:border-box;background:#FAF8F5;color:#1A1A1A;font-family:'Jost',sans-serif;display:flex;overflow:hidden}\n    .cfg{width:380px;flex:0 0 auto;background:#fff;border-right:1px solid #E8E2D9;display:flex;flex-direction:column;overflow:hidden}\n    .scr{flex:1;overflow:auto}.grp{padding:18px 22px;border-bottom:1px solid #F0EBE2}\n    .gh{font-family:'Cormorant Garamond',serif;font-size:16px;font-weight:600;margin-bottom:12px;display:flex;align-items:center;gap:8px}\n    .gh .n{width:19px;height:19px;border-radius:50%;background:#1A1A1A;color:#fff;font-size:10px;display:flex;align-items:center;justify-content:center}\n    .pg{display:grid;grid-template-columns:repeat(4,1fr);gap:6px;max-height:200px;overflow:auto}\n    .pc{cursor:pointer;border:2px solid transparent;padding:3px;border-radius:4px;transition:.2s}.pc:hover{transform:translateY(-2px)}.pc.on{border-color:#B08D57}.pc img{width:100%;aspect-ratio:1;object-fit:contain;mix-blend-mode:multiply}\n    .sec{margin-bottom:14px}.sec:last-child{margin-bottom:0}.sl{font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:#9B8E7E;margin-bottom:7px}\n    .chips{display:flex;flex-wrap:wrap;gap:6px}.chip{font-size:11.5px;padding:6px 11px;border:1px solid #E0D6C4;background:#fff;cursor:pointer;transition:.15s;color:#5A5045;border-radius:2px}\n    .chip:hover{border-color:#B08D57;transform:translateY(-2px);box-shadow:0 6px 14px rgba(176,141,87,.18)}.chip.on{background:#1A1A1A;color:#fff;border-color:#1A1A1A}\n    .qty{display:flex;gap:6px}.qb{flex:1;text-align:center;font-size:12px;padding:7px;border:1px solid #E0D6C4;cursor:pointer;border-radius:2px}.qb.on{background:#1A1A1A;color:#fff;border-color:#1A1A1A}\n    .go{flex:0 0 auto;margin:16px 22px;background:#1A1A1A;color:#fff;border:none;padding:15px;font:inherit;font-size:13px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;cursor:pointer;transition:.2s;border-radius:3px;position:relative;overflow:hidden}\n    .go:hover:not(:disabled){background:#B08D57;letter-spacing:.14em}.go:disabled{opacity:.35;cursor:default}\n    .go .sheen{position:absolute;inset:0;background:linear-gradient(110deg,transparent 35%,rgba(201,162,75,.5) 50%,transparent 65%);transform:translateX(-120%);animation:sheen 3.6s ease-in-out infinite;pointer-events:none}@keyframes sheen{0%{transform:translateX(-120%)}55%,100%{transform:translateX(120%)}}\n    .stage{flex:1;display:flex;align-items:center;justify-content:center;padding:36px;position:relative;background:radial-gradient(circle at 50% 35%,#FFFDFA,#EFE7DA);overflow:auto}\n    .hint{text-align:center;color:#9B8E7E}.hint .big{font-family:'Cormorant Garamond',serif;font-size:34px;color:#1A1A1A;margin-bottom:10px;font-weight:600}\n    .gallery{display:grid;gap:16px;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));width:100%;align-content:start}\n    .shot{position:relative;padding:10px;background:#fff;box-shadow:0 18px 44px rgba(120,95,50,.22);animation:fade .6s ease;border-radius:2px}\n    .shot::after{content:'';position:absolute;inset:4px;border:1px solid #D9C9A8;pointer-events:none}\n    .shot img{display:block;width:100%;object-fit:contain}\n    .shot .dl{position:absolute;top:14px;right:14px;font-size:11px;font-weight:600;padding:5px 10px;background:rgba(255,255,255,.92);border:1px solid #1A1A1A;text-decoration:none;color:#1A1A1A;opacity:0;transition:.15s;border-radius:2px}.shot:hover .dl{opacity:1}\n    @keyframes fade{from{opacity:0;transform:scale(.97)}to{opacity:1;transform:none}}\n    .load{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:18px}\n    .load canvas{position:absolute;inset:0;width:100%;height:100%}\n    .ring{width:74px;height:74px;z-index:1}.ring svg{width:100%;height:100%;animation:rot 1.4s linear infinite}@keyframes rot{to{transform:rotate(360deg)}}\n    .step{z-index:1;font-family:'Cormorant Garamond',serif;font-size:23px;font-weight:600}.ssub{z-index:1;font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:#B08D57}\n    .pbar{z-index:1;width:240px;height:2px;background:#E8E2D9;overflow:hidden;border-radius:2px}.pfill{height:100%;background:linear-gradient(90deg,#C9A24B,#B08D57);transition:width .5s}\n  `,\n  render(d2){\n    var prods=((d2.data('products')&&d2.data('products').records())||[]).map(norm).filter(function(p){return p.image&&p.cat.indexOf('/Joias/')>=0;});\n    var s=d2.state;var selP=s.selProductId;\n    var surf=s.surf||'Mármore',bg=s.bg||'Infinito Creme',light=s.light||'Joalheria',style=s.style||'Hero',ratio=s.ratio||'Quadrado',qty=s.qty||1;\n    var pg=prods.map(function(p){return '<div class=\"pc'+(selP===p.id?' on':'')+'\" data-prod=\"'+p.id+'\"><img loading=\"lazy\" src=\"'+esc(p.image)+'\"/></div>';}).join('');\n    var dir=sec('Superfície',SURF,'surf',surf)+sec('Fundo',BG,'bg',bg)+sec('Iluminação',LIGHT,'light',light)+sec('Estilo',STYLE,'style',style)+sec('Proporção',RATIO,'ratio',ratio);\n    var qb=[1,2,3].map(function(n){return '<div class=\"qb'+(qty===n?' on':'')+'\" data-qty=\"'+n+'\">'+n+' var.</div>';}).join('');\n    var stage;\n    if(s.busy){var st=Math.min(4,s.loadStep||0);stage='<div class=\"load\"><canvas data-spark></canvas><div class=\"ring\"><svg viewBox=\"0 0 50 50\"><circle cx=\"25\" cy=\"25\" r=\"20\" fill=\"none\" stroke=\"#E8E2D9\" stroke-width=\"3\"/><circle cx=\"25\" cy=\"25\" r=\"20\" fill=\"none\" stroke=\"#B08D57\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-dasharray=\"90 126\"/></svg></div><div class=\"step\">'+esc(STEPS[st])+'…</div><div class=\"pbar\"><div class=\"pfill\" style=\"width:'+((st+1)/5*100)+'%\"></div></div><div class=\"ssub\">estúdio IA · ~30s</div></div>';}\n    else if(s.shots&&s.shots.length){stage='<div class=\"gallery\">'+s.shots.map(function(u){return '<div class=\"shot\"><a class=\"dl\" href=\"'+esc(u)+'\" download=\"vivara-catalogo.png\">↓</a><img src=\"'+esc(u)+'\"/></div>';}).join('')+'</div>';}\n    else if(s.error){stage='<div class=\"hint\"><div class=\"big\">Ops</div><div class=\"sub\">'+esc(s.error)+'</div></div>';}\n    else{stage='<div class=\"hint\"><div class=\"big\">Estúdio de Catálogo</div><div class=\"sub\">Selecione a peça e componha o set perfeito.</div></div>';}\n    var canGo=selP&&!s.busy;\n    return '<div class=\"cg\"><div class=\"cfg\"><div class=\"scr\"><div class=\"grp\"><div class=\"gh\"><span class=\"n\">1</span>Peça</div><div class=\"pg\">'+pg+'</div></div><div class=\"grp\"><div class=\"gh\"><span class=\"n\">2</span>Set &amp; Direção</div>'+dir+'</div><div class=\"grp\"><div class=\"gh\"><span class=\"n\">3</span>Variações</div><div class=\"qty\">'+qb+'</div></div></div><button class=\"go\" data-go '+(canGo?'':'disabled')+'><span class=\"sheen\"></span>Gerar Fotos</button></div><div class=\"stage\">'+stage+'</div></div>';\n  },\n  mounted(d2){\n    var parts=[],loadStart=null,lastStep=-1;\n    d2.on('[data-k]','click',function(e,el){var st={};st[el.getAttribute('data-k')]=el.getAttribute('data-v');d2.setState(st);});\n    d2.on('[data-prod]','click',function(e,el){d2.setState({selProductId:el.getAttribute('data-prod'),error:null});});\n    d2.on('[data-qty]','click',function(e,el){d2.state.qty=parseInt(el.getAttribute('data-qty'),10);});\n    d2.raf(function(t){\n      if(d2.state.busy){if(loadStart==null){loadStart=t;parts=[];}var stp=Math.min(4,Math.floor((t-loadStart)/5200));if(stp!==lastStep){lastStep=stp;d2.setState({loadStep:stp});}}\n      else{loadStart=null;lastStep=-1;}\n      var cv=d2.$('[data-spark]');if(!cv)return;var ctx=cv.getContext('2d');var dpr=Math.min(window.devicePixelRatio||1,2);var w=cv.clientWidth,h=cv.clientHeight;if(cv.width!==Math.round(w*dpr)){cv.width=Math.round(w*dpr);cv.height=Math.round(h*dpr);ctx.setTransform(dpr,0,0,dpr,0,0);}\n      if(parts.length<46&&Math.random()<0.5)parts.push({x:Math.random()*w,y:h+10,vy:-(Math.random()*0.7+0.3),r:Math.random()*2+0.6,a:0,life:Math.random()*0.5+0.5});\n      ctx.clearRect(0,0,w,h);\n      for(var i=parts.length-1;i>=0;i--){var p=parts[i];p.y+=p.vy;p.a=Math.min(p.life,p.a+0.01);p.life-=0.004;if(p.life<=0||p.y<-10){parts.splice(i,1);continue;}var tw=0.6+0.4*Math.sin(t/300+p.x);ctx.fillStyle='rgba(201,162,75,'+(p.a*tw).toFixed(2)+')';ctx.beginPath();ctx.arc(p.x,p.y,p.r,0,6.28);ctx.fill();}\n    });\n    d2.on('[data-go]','click',function(){\n      if(d2.state.busy)return;\n      var prods=((d2.data('products')&&d2.data('products').records())||[]).map(norm);\n      var prod=prods.filter(function(p){return p.id===d2.state.selProductId;})[0];if(!prod){d2.setState({error:'Selecione uma peça.'});return;}\n      var s=d2.state;\n      var prompt='Professional luxury jewelry product photograph for Vivara catalog. The EXACT jewel from the reference image — keep shape, gemstones, metal and finish perfectly identical. Presentation: '+frag(SURF,s.surf||'Mármore')+'. Background: '+frag(BG,s.bg||'Infinito Creme')+'. Lighting: '+frag(LIGHT,s.light||'Joalheria')+'. Style: '+frag(STYLE,s.style||'Hero')+'. Premium high-end aesthetic, flawless commercial product photography, no text, no watermark. Product: '+prod.name+'.';\n      var n=s.qty||1;var sz=frag(RATIO,s.ratio||'Quadrado');\n      d2.setState({busy:true,shots:null,error:null,loadStep:0});\n      var calls=[];for(var q=0;q<n;q++){calls.push(fetch(RUSH,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({prompt:prompt,images:[prod.image],options:{size:sz}})}).then(function(res){return res.json();}).then(function(j){return digUrl(j,0);}).catch(function(){return '';}));}\n      Promise.all(calls).then(function(urls){urls=urls.filter(function(u){return u;});if(urls.length){d2.setState({shots:urls,busy:false});urls.forEach(function(u){try{d2.data('shots').create({productName:prod.name,style:(s.style||'Hero'),resultUrl:u,ts:new Date().toISOString()});}catch(_){}});}else{d2.setState({busy:false,error:'Não recebi as imagens da IA. Tente novamente.'});}}).catch(function(){d2.setState({busy:false,error:'Falha ao gerar. Tente novamente.'});});\n    });\n  }\n}"}},"products":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"products"}}}},"shots":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"shots"}}}}}}}}}},{"_id":"6a2e1016911a2eb6b8174f98","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kVivAdmin","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"var NAV=[['dashboard','Visão Geral','◷'],['catalog','Catálogo','◇'],['models','Modelos','☺'],['tryon','Try-on','✦'],['gen','Gerador','❖']];\nvar MODT={dashboard:'ai-playground@kVivDashboard',catalog:'ai-playground@kVivCatalog',models:'ai-playground@kVivModels',tryon:'ai-playground@kVivTryon',gen:'ai-playground@kVivCatalogGen'};\nvar MODTITLE={dashboard:'Visão Geral',catalog:'Catálogo de Joias',models:'Modelos Virtuais',tryon:'Virtual Try-on',gen:'Gerador de Catálogo'};\nexport default {\n  css: `@import url('https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@500;600;700&family=Jost:wght@300;400;500;600&display=swap');\n    .shell{height:100%;display:flex;font-family:'Jost',-apple-system,sans-serif;background:#FAF8F5;overflow:hidden}\n    .side{width:236px;flex:0 0 auto;background:#1A1A1A;color:#E8E2D9;display:flex;flex-direction:column;padding:0}\n    .logo{padding:30px 28px 26px;border-bottom:1px solid #2E2A24}\n    .logo .b{font-family:'Cormorant Garamond',Georgia,serif;font-size:28px;font-weight:600;letter-spacing:.22em;color:#fff}\n    .logo .s{font-size:9px;letter-spacing:.34em;text-transform:uppercase;color:#B08D57;margin-top:3px}\n    .nav{flex:1;padding:18px 0}\n    .item{display:flex;align-items:center;gap:14px;padding:13px 28px;cursor:pointer;color:#A89E8E;font-size:14px;border-left:2px solid transparent;transition:.15s}\n    .item:hover{color:#fff;background:rgba(255,255,255,.03)}\n    .item.on{color:#fff;border-left-color:#B08D57;background:rgba(176,141,87,.1)}\n    .item .ic{font-size:16px;width:18px;text-align:center;color:#B08D57}\n    .ft{padding:20px 28px;border-top:1px solid #2E2A24;font-size:10px;color:#6B6357;letter-spacing:.04em}\n    .main{flex:1;display:flex;flex-direction:column;min-width:0}\n    .top{height:62px;flex:0 0 auto;background:#fff;border-bottom:1px solid #E8E2D9;display:flex;align-items:center;padding:0 32px;gap:16px}\n    .top h1{font-family:'Cormorant Garamond',Georgia,serif;font-size:22px;font-weight:600;margin:0}\n    .top .badge{font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:#B08D57;border:1px solid #E0D6C4;padding:4px 10px}\n    .top .user{margin-left:auto;display:flex;align-items:center;gap:10px;font-size:13px;color:#6B6357}\n    .top .av{width:32px;height:32px;border-radius:50%;background:linear-gradient(135deg,#C9A24B,#B08D57);color:#fff;display:flex;align-items:center;justify-content:center;font-size:13px;font-weight:600}\n    .content{flex:1;min-height:0;position:relative}\n  `,\n  render(d2){\n    var mod=d2.state.module||'dashboard';\n    var nav=NAV.map(function(n){return '<div class=\"item'+(mod===n[0]?' on':'')+'\" data-mod=\"'+n[0]+'\"><span class=\"ic\">'+n[2]+'</span>'+n[1]+'</div>';}).join('');\n    var params;\n    if(mod==='dashboard')params={sales:d2.params.sales,top:d2.params.top};\n    else if(mod==='catalog')params={dataset:d2.params.products};\n    else if(mod==='models')params={dataset:d2.params.models};\n    else if(mod==='tryon')params={models:d2.params.models,products:d2.params.products,tryons:d2.params.tryons};\n    else params={products:d2.params.products,shots:d2.params.shots};\n    var child=d2.render(MODT[mod],params,{key:mod});\n    return '<div class=\"shell\"><div class=\"side\"><div class=\"logo\"><div class=\"b\">VIVARA</div><div class=\"s\">Studio</div></div><div class=\"nav\">'+nav+'</div><div class=\"ft\">Admin · IA Generativa<br>Catálogo VTEX ao vivo</div></div><div class=\"main\"><div class=\"top\"><h1>'+(MODTITLE[mod]||'')+'</h1><span class=\"badge\">Live</span><div class=\"user\">Boutique Iguatemi<div class=\"av\">V</div></div></div><div class=\"content\">'+child+'</div></div></div>';\n  },\n  mounted(d2){\n    d2.on('[data-mod]','click',function(e,el){d2.state.module=el.getAttribute('data-mod');});\n  }\n}"}},"products":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"products"}}}},"models":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"models"}}}},"tryons":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"tryons"}}}},"shots":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"shots"}}}},"sales":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"sales"}}}},"top":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"top"}}}}}}}}}},{"_id":"6a2e16c3911a2eb6b81755e0","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kVivMobile","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>\"]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c];});}\nfunction norm(p){var it=(p.items&&p.items[0])||{};var img=(it.images&&it.images[0]&&it.images[0].imageUrl)||'';var pr=p.priceRange||{};return {id:String(p.productId),name:p.productName,image:img,price:(pr.sellingPrice&&pr.sellingPrice.lowPrice)||0,cat:(p.categories&&p.categories[0])||''};}\nfunction digUrl(o,d){if(o==null||d>6)return '';if(typeof o==='string'){if(o.indexOf('data:image')===0||/^https?:\\/\\//.test(o))return o;return '';}if(typeof o==='object'){if(typeof o.url==='string'){var u0=digUrl(o.url,d+1);if(u0)return u0;}if(o.length!=null&&typeof o!=='string'){for(var i=0;i<o.length;i++){var u=digUrl(o[i],d+1);if(u)return u;}}for(var k in o){try{if(!Object.prototype.hasOwnProperty.call(o,k))continue;}catch(e){continue;}var u2=digUrl(o[k],d+1);if(u2)return u2;}return '';}return '';}\nvar RUSH='https://ai-playground.data2apis.com/rush/vivDraw';\nfunction brl(n){return 'R$ '+(Number(n)||0).toLocaleString('pt-BR',{minimumFractionDigits:2,maximumFractionDigits:2});}\nvar LIGHT=[['Suave','soft diffused studio light'],['Dramática','dramatic chiaroscuro lighting'],['Golden','warm golden-hour glow'],['Spotlight','tight spotlight, gem sparkle']];\nvar SKIN=[['Clara','fair porcelain skin'],['Média','light beige skin'],['Oliva','warm olive skin'],['Morena','golden-brown skin'],['Retinta','deep ebony skin']];\nvar SCENE=[['Mármore','white marble, gold veining'],['Veludo','black velvet'],['Seda','champagne silk'],['Natureza','blurred foliage'],['Infinito','white infinity']];\nvar STEPS=['Analisando','Posicionando','Iluminando','Renderizando'];\nfunction frag(a,v){var f=a.filter(function(o){return o[0]===v;})[0];return f?f[1]:a[0][1];}\nfunction chips(a,k,sel){return a.map(function(o){return '<span class=\"ch'+(sel===o[0]?' on':'')+'\" data-k=\"'+k+'\" data-v=\"'+esc(o[0])+'\">'+esc(o[0])+'</span>';}).join('');}\nexport default {\n  css:`@import url('https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@600&family=Jost:wght@300;400;500;600&display=swap');\n    *{-webkit-tap-highlight-color:transparent}\n    .ap{height:100%;width:100%;box-sizing:border-box;background:#FAF8F5;color:#1A1A1A;font-family:'Jost',sans-serif;display:flex;flex-direction:column;overflow:hidden;position:relative}\n    .sb{height:30px;flex:0 0 auto;display:flex;align-items:center;justify-content:space-between;padding:0 22px;font-size:12px;font-weight:600}\n    .bar{flex:0 0 auto;padding:6px 20px 12px;display:flex;align-items:center;justify-content:space-between}\n    .brand{font-family:'Cormorant Garamond',serif;font-size:21px;font-weight:600;letter-spacing:.02em}.brand b{color:#B08D57;font-weight:600}\n    .bag{width:34px;height:34px;border:1px solid #E0D6C4;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:14px}\n    .stage{flex:1;margin:0 16px;border-radius:22px;background:linear-gradient(160deg,#FFFDFA,#EFE7DA);position:relative;overflow:hidden;display:flex;align-items:center;justify-content:center;box-shadow:inset 0 0 0 1px rgba(176,141,87,.18)}\n    .empty{text-align:center;color:#A89A87;padding:24px}.empty .ic{font-size:40px;margin-bottom:10px}.empty .t{font-family:'Cormorant Garamond',serif;font-size:24px;color:#1A1A1A}.empty .s{font-size:12px;margin-top:4px}\n    .resimg{width:100%;height:100%;object-fit:cover;animation:fade .6s ease}\n    @keyframes fade{from{opacity:0;transform:scale(1.04)}to{opacity:1;transform:none}}\n    .badge{position:absolute;left:14px;bottom:14px;right:14px;display:flex;gap:6px;flex-wrap:wrap}\n    .tag{font-size:10px;color:#fff;background:rgba(26,26,26,.55);backdrop-filter:blur(6px);padding:4px 9px;border-radius:20px}\n    .retry{position:absolute;top:14px;right:14px;background:rgba(255,255,255,.9);border:none;border-radius:20px;padding:7px 13px;font:inherit;font-size:12px;font-weight:600}\n    .pick{flex:0 0 auto;padding:14px 0 4px}\n    .lbl{font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:#9B8E7E;padding:0 20px;margin-bottom:8px}\n    .strip{display:flex;gap:10px;overflow-x:auto;padding:0 20px 6px;scrollbar-width:none}.strip::-webkit-scrollbar{display:none}\n    .mod{flex:0 0 auto;width:52px;text-align:center}.mod .av{width:52px;height:52px;border-radius:50%;background:#EDE5D8 center/cover;border:2px solid transparent;transition:.15s}.mod.on .av{border-color:#B08D57}.mod .mn{font-size:9px;color:#9B8E7E;margin-top:3px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n    .jw{flex:0 0 auto;width:78px;cursor:pointer}.jw .ji{width:78px;height:78px;border-radius:16px;background:#fff center/contain no-repeat;border:2px solid transparent;transition:.15s;box-shadow:0 4px 14px rgba(120,95,50,.12)}.jw.on .ji{border-color:#B08D57}.jw .jn{font-size:9px;color:#5A5045;margin-top:4px;height:22px;overflow:hidden;line-height:1.1}.jw .jp{font-size:10px;color:#B08D57;font-weight:600}\n    .foot{flex:0 0 auto;padding:10px 16px calc(16px + env(safe-area-inset-bottom));background:#fff;border-top:1px solid #F0EBE2}\n    .dirbar{display:flex;gap:7px;overflow-x:auto;padding-bottom:9px;scrollbar-width:none}.dirbar::-webkit-scrollbar{display:none}\n    .pill{flex:0 0 auto;font-size:11px;padding:6px 12px;border:1px solid #E0D6C4;border-radius:20px;color:#5A5045;display:flex;gap:5px;align-items:center}.pill b{color:#1A1A1A;font-weight:600}\n    .cta{width:100%;border:none;border-radius:16px;background:#1A1A1A;color:#fff;padding:16px;font:inherit;font-size:14px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;transition:.2s}.cta:disabled{opacity:.35}.cta:active:not(:disabled){transform:scale(.98);background:#B08D57}\n    .sheet{position:absolute;left:0;right:0;bottom:0;background:#fff;border-radius:22px 22px 0 0;box-shadow:0 -16px 40px rgba(0,0,0,.18);transform:translateY(110%);transition:transform .32s cubic-bezier(.2,.8,.2,1);z-index:20;padding:8px 20px calc(22px + env(safe-area-inset-bottom));max-height:78%;overflow:auto}\n    .sheet.open{transform:none}\n    .grab{width:40px;height:4px;border-radius:4px;background:#E0D6C4;margin:6px auto 14px}\n    .sh{font-family:'Cormorant Garamond',serif;font-size:20px;font-weight:600;margin-bottom:12px}\n    .grp2{margin-bottom:16px}.gl2{font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:#9B8E7E;margin-bottom:8px}\n    .chrow{display:flex;flex-wrap:wrap;gap:7px}.ch{font-size:12px;padding:8px 13px;border:1px solid #E0D6C4;border-radius:20px;color:#5A5045}.ch.on{background:#1A1A1A;color:#fff;border-color:#1A1A1A}\n    .apply{width:100%;border:none;border-radius:14px;background:#B08D57;color:#fff;padding:14px;font:inherit;font-size:13px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;margin-top:4px}\n    .scrim{position:absolute;inset:0;background:rgba(26,20,12,.32);opacity:0;pointer-events:none;transition:.3s;z-index:15}.scrim.on{opacity:1;pointer-events:auto}\n    .load{position:absolute;inset:0;background:rgba(250,248,245,.96);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:14px;z-index:30}\n    .load canvas{position:absolute;inset:0;width:100%;height:100%}\n    .ring{width:62px;height:62px;z-index:1}.ring svg{width:100%;height:100%;animation:rot 1.4s linear infinite}@keyframes rot{to{transform:rotate(360deg)}}\n    .stp{z-index:1;font-family:'Cormorant Garamond',serif;font-size:20px;font-weight:600}.ssb{z-index:1;font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:#B08D57}\n  `,\n  render(d2){\n    var prods=((d2.data('products')&&d2.data('products').records())||[]).map(norm).filter(function(p){return p.image&&p.cat.indexOf('/Joias/')>=0;});\n    var models=(d2.data('models')&&d2.data('models').records())||[];\n    var s=d2.state;\n    var selM=s.selModelId,selP=s.selProductId;\n    var light=s.light||'Suave',skin=s.skin||'Média',scene=s.scene||'Mármore';\n    var mstrip=models.map(function(m){var has=m.imageUrl&&m.imageUrl.length>10;return '<div class=\"mod'+(selM===m._id?' on':'')+'\" data-model=\"'+m._id+'\"><div class=\"av\" style=\"'+(has?'background-image:url('+esc(m.imageUrl)+')':'')+'\"></div><div class=\"mn\">'+esc(m.name)+'</div></div>';}).join('');\n    var jstrip=prods.map(function(p){return '<div class=\"jw'+(selP===p.id?' on':'')+'\" data-prod=\"'+p.id+'\"><div class=\"ji\" style=\"background-image:url('+esc(p.image)+')\"></div><div class=\"jn\">'+esc(p.name)+'</div><div class=\"jp\">'+brl(p.price)+'</div></div>';}).join('');\n    var stage;\n    if(s.busy){var st=Math.min(3,s.loadStep||0);stage='<div class=\"load\"><canvas data-spark></canvas><div class=\"ring\"><svg viewBox=\"0 0 50 50\"><circle cx=\"25\" cy=\"25\" r=\"20\" fill=\"none\" stroke=\"#E8E2D9\" stroke-width=\"3\"/><circle cx=\"25\" cy=\"25\" r=\"20\" fill=\"none\" stroke=\"#B08D57\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-dasharray=\"90 126\"/></svg></div><div class=\"stp\">'+esc(STEPS[st])+'…</div><div class=\"ssb\">o atelier está compondo</div></div>';}\n    else if(s.result){var tags=[light,skin,scene].map(function(x){return '<span class=\"tag\">'+esc(x)+'</span>';}).join('');stage='<button class=\"retry\" data-reset>↻ Refazer</button><img class=\"resimg\" src=\"'+esc(s.result)+'\"/><div class=\"badge\">'+tags+'</div>';}\n    else if(s.error){stage='<div class=\"empty\"><div class=\"ic\">⚠</div><div class=\"t\">Ops</div><div class=\"s\">'+esc(s.error)+'</div></div>';}\n    else{stage='<div class=\"empty\"><div class=\"ic\">💎</div><div class=\"t\">Atelier Virtual</div><div class=\"s\">Escolha modelo e joia, depois prove.</div></div>';}\n    var canGo=selM&&selP&&!s.busy;\n    var dirbar='<div class=\"pill\">Luz <b>'+esc(light)+'</b></div><div class=\"pill\">Pele <b>'+esc(skin)+'</b></div><div class=\"pill\">Cena <b>'+esc(scene)+'</b></div>';\n    var sheet='<div class=\"grab\"></div><div class=\"sh\">Direção de arte</div><div class=\"grp2\"><div class=\"gl2\">Iluminação</div><div class=\"chrow\">'+chips(LIGHT,'light',light)+'</div></div><div class=\"grp2\"><div class=\"gl2\">Tom de pele</div><div class=\"chrow\">'+chips(SKIN,'skin',skin)+'</div></div><div class=\"grp2\"><div class=\"gl2\">Cenário</div><div class=\"chrow\">'+chips(SCENE,'scene',scene)+'</div></div><button class=\"apply\" data-close>Aplicar</button>';\n    return '<div class=\"ap\"><div class=\"sb\"><span>9:41</span><span class=\"dots\">●●● ▾ 100%</span></div><div class=\"bar\"><div class=\"brand\">VIVARA <b>·</b> Atelier</div><div class=\"bag\">♡</div></div><div class=\"stage\">'+stage+'</div><div class=\"pick\"><div class=\"lbl\">Modelo</div><div class=\"strip\">'+mstrip+'</div></div><div class=\"pick\"><div class=\"lbl\">Joias</div><div class=\"strip\">'+jstrip+'</div></div><div class=\"foot\"><div class=\"dirbar\" data-open>'+dirbar+'</div><button class=\"cta\" data-go '+(canGo?'':'disabled')+'>Provar Look</button></div><div class=\"scrim'+(s.sheet?' on':'')+'\" data-close></div><div class=\"sheet'+(s.sheet?' open':'')+'\">'+sheet+'</div></div>';\n  },\n  mounted(d2){\n    var parts=[],loadStart=null,lastStep=-1;\n    d2.on('[data-k]','click',function(e,el){var st={};st[el.getAttribute('data-k')]=el.getAttribute('data-v');d2.setState(st);});\n    d2.on('[data-model]','click',function(e,el){d2.setState({selModelId:el.getAttribute('data-model'),error:null});});\n    d2.on('[data-prod]','click',function(e,el){d2.setState({selProductId:el.getAttribute('data-prod'),error:null});});\n    d2.on('[data-open]','click',function(){d2.state.sheet=true;});\n    d2.on('[data-close]','click',function(){d2.state.sheet=false;});\n    d2.on('[data-reset]','click',function(){d2.setState({result:null,error:null});});\n    d2.raf(function(t){\n      if(d2.state.busy){if(loadStart==null){loadStart=t;parts=[];}var stp=Math.min(3,Math.floor((t-loadStart)/6500));if(stp!==lastStep){lastStep=stp;d2.setState({loadStep:stp});}}\n      else{loadStart=null;lastStep=-1;}\n      var cv=d2.$('[data-spark]');if(!cv)return;var ctx=cv.getContext('2d');var dpr=Math.min(window.devicePixelRatio||1,2);var w=cv.clientWidth,h=cv.clientHeight;if(cv.width!==Math.round(w*dpr)){cv.width=Math.round(w*dpr);cv.height=Math.round(h*dpr);ctx.setTransform(dpr,0,0,dpr,0,0);}\n      if(parts.length<34&&Math.random()<0.5)parts.push({x:Math.random()*w,y:h+10,vy:-(Math.random()*0.7+0.3),r:Math.random()*2+0.6,a:0,life:Math.random()*0.5+0.5});\n      ctx.clearRect(0,0,w,h);\n      for(var i=parts.length-1;i>=0;i--){var p=parts[i];p.y+=p.vy;p.a=Math.min(p.life,p.a+0.01);p.life-=0.004;if(p.life<=0||p.y<-10){parts.splice(i,1);continue;}var tw=0.6+0.4*Math.sin(t/300+p.x);ctx.fillStyle='rgba(201,162,75,'+(p.a*tw).toFixed(2)+')';ctx.beginPath();ctx.arc(p.x,p.y,p.r,0,6.28);ctx.fill();}\n    });\n    d2.on('[data-go]','click',function(){\n      if(d2.state.busy)return;\n      var prods=((d2.data('products')&&d2.data('products').records())||[]).map(norm);\n      var prod=prods.filter(function(p){return p.id===d2.state.selProductId;})[0];\n      var models=(d2.data('models')&&d2.data('models').records())||[];\n      var m=models.filter(function(x){return x._id===d2.state.selModelId;})[0];\n      if(!m){d2.setState({error:'Escolha uma modelo.'});return;}\n      if(!prod){d2.setState({error:'Escolha uma joia.'});return;}\n      var s=d2.state;\n      var prompt='Ultra-realistic luxury jewelry photo. An elegant model ('+(m.kind||'hand')+') with '+frag(SKIN,s.skin||'Média')+', wearing this EXACT jewel from the reference — keep it perfectly identical. Lighting: '+frag(LIGHT,s.light||'Suave')+'. Background: '+frag(SCENE,s.scene||'Mármore')+'. Natural framing, hyperrealistic, Vivara premium. Jewel: '+prod.name+'.';\n      var imgs=[];if(m.imageUrl&&m.imageUrl.length>10)imgs.push(m.imageUrl);imgs.push(prod.image);\n      d2.setState({busy:true,result:null,error:null,loadStep:0,sheet:false});\n      fetch(RUSH,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({prompt:prompt,images:imgs,options:{size:'896x1152'}})}).then(function(res){return res.json();}).then(function(j){var url=digUrl(j,0);if(url){d2.setState({result:url,busy:false});try{d2.data('tryons').create({modelName:m.name,productName:prod.name,productImage:prod.image,resultUrl:url,ts:new Date().toISOString()});}catch(_){}}else{d2.setState({busy:false,error:'Não recebi a imagem. Tente de novo.'});}}).catch(function(){d2.setState({busy:false,error:'Falha ao gerar. Tente de novo.'});});\n    });\n  }\n}"}},"models":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"models"}}}},"products":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"products"}}}},"tryons":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"tryons"}}}}}}}}}},{"_id":"6a2eb9e8ed769e0c582562d8","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kGhostcard","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"var LAND='https://ai-playground.data2.media/file/obX7Fco-aYb1DwCwM4FHX';\nvar FOG='https://ai-playground.data2.media/file/m3wvvc2omHFlq_HZeamT8';\nvar PH='ai-playground@kGcPhone';\nexport default {\n  css:`@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,500;0,600;0,700;1,500;1,600&family=Inter:wght@300;400;500;600&display=swap');\n  *{-webkit-tap-highlight-color:transparent;box-sizing:border-box}\n  .gc{position:relative;height:100%;overflow:hidden;background:#F4F3EE;color:#1A1A17;font-family:'Inter',sans-serif}\n  .cardlayer{position:absolute;inset:0;z-index:4;pointer-events:none;perspective:1700px}\n  .card{position:absolute;left:52%;top:47%;width:232px;height:366px;transform-style:preserve-3d;will-change:transform}\n  .face{position:absolute;inset:0;border-radius:20px;overflow:hidden;backface-visibility:hidden;box-shadow:0 60px 100px rgba(45,55,20,.45)}\n  .front{background:url(${LAND}) center/cover}\n  .front::before{content:'';position:absolute;inset:0;background:linear-gradient(145deg,rgba(255,255,255,.5),rgba(255,255,255,.08) 50%,rgba(255,255,255,.22))}\n  .front::after{content:'';position:absolute;inset:0;border-radius:20px;box-shadow:inset 0 1px 2px rgba(255,255,255,.7)}\n  .chip{position:absolute;top:28px;left:26px;width:40px;height:30px;border-radius:7px;background:linear-gradient(135deg,#e3d4a6,#b59a5c);z-index:2}\n  .chip::after{content:'';position:absolute;inset:6px 9px;border:1px solid rgba(120,100,50,.45);border-radius:2px}\n  .gcw{position:absolute;top:28px;right:24px;font-family:'Playfair Display',serif;font-style:italic;font-size:14px;color:rgba(30,30,25,.9);z-index:2}\n  .mc{position:absolute;bottom:28px;right:28px;width:56px;height:36px;z-index:2}\n  .mc i{position:absolute;top:0;width:36px;height:36px;border-radius:50%}.mc .r{left:0;background:#EB001B}.mc .y{right:0;background:#F79E1B;mix-blend-mode:hard-light}\n  .back{transform:rotateY(180deg);background:linear-gradient(135deg,#edece2,#d6d5c6)}.back .stripe{position:absolute;top:34px;left:0;right:0;height:40px;background:rgba(40,40,30,.8)}\n  .scr{position:absolute;inset:0;z-index:3;overflow-y:auto;overflow-x:hidden;scroll-behavior:smooth}\n  .scr::-webkit-scrollbar{width:0}\n  .sec{position:relative;width:100%;padding:0 6vw;overflow:hidden}\n  .hbg{position:absolute;inset:0;z-index:0;background:url(${LAND}) center 58%/cover;will-change:transform}\n  .cbg{position:absolute;inset:0;z-index:0;background:url(${FOG}) center 55%/cover}\n  .nav{position:absolute;top:24px;left:0;right:0;z-index:6;display:flex;align-items:center;justify-content:space-between;padding:14px 6vw 18px;font-size:14px;font-weight:500;border-bottom:1px solid rgba(40,40,30,.08)}\n  .nav .wm{font-family:'Playfair Display',serif;font-style:italic;font-size:22px;font-weight:600}\n  .nav .lks{display:flex;gap:34px;color:#33332b}\n  .nav .rt{display:flex;gap:10px;align-items:center}\n  .pill{border:1px solid #2a2a24;border-radius:30px;padding:9px 18px;background:transparent}\n  .pill.g{background:#8a9a3f;border-color:#8a9a3f;color:#fff;font-weight:600}\n  .tagline{position:absolute;top:120px;right:6vw;z-index:5;text-align:right;font-size:18px;line-height:1.3;color:#222;max-width:320px}\n  .hbot{position:absolute;left:6vw;bottom:9vh;z-index:5}\n  .badge{display:inline-flex;align-items:center;border:1px solid rgba(40,40,30,.25);border-radius:30px;padding:8px 16px;font-size:13px;background:rgba(255,255,255,.55);backdrop-filter:blur(6px);width:fit-content}\n  .badge.it{font-family:'Playfair Display',serif;font-style:italic}\n  h1{font-family:'Playfair Display',serif;font-weight:600;font-size:clamp(40px,6vw,92px);line-height:.97;letter-spacing:-.01em;margin:16px 0 0}\n  .start{position:absolute;right:6vw;bottom:9vh;z-index:5;border:none;background:rgba(247,246,240,.92);color:#1A1A17;border-radius:30px;padding:14px 24px;font:inherit;font-size:13px;font-weight:600;cursor:pointer;box-shadow:0 8px 24px rgba(60,60,40,.12)}\n  .center{position:relative;z-index:1;display:flex;flex-direction:column;justify-content:center;height:100%}\n  .sheet{margin:0 auto;width:100%;max-width:1200px}\n  .topr{position:absolute;top:8vh;right:6vw;z-index:2;font-size:13px;text-align:right;color:#33332b;line-height:1.3}\n  .ttl{font-family:'Playfair Display',serif;font-weight:600;font-size:clamp(30px,3.8vw,56px);line-height:1.0;margin:14px 0 26px;letter-spacing:-.01em}\n  .bento{display:grid;grid-template-columns:1fr 1.05fr 1fr;gap:16px;height:62vh;max-height:520px}\n  .cellq{border-radius:20px;padding:28px;background:linear-gradient(150deg,#f3f1df 8%,#c4cf82);color:#33371c;display:flex;flex-direction:column;justify-content:space-between}\n  .cellq .q{font-family:'Playfair Display',serif;font-style:italic;font-size:21px;line-height:1.38}\n  .cellq .role{font-style:italic;font-size:13px;color:#4a4e2a}\n  .cellr{border-radius:20px;overflow:hidden;position:relative;background:#eef0e6;display:flex;flex-direction:column;align-items:center;justify-content:flex-start;padding:26px 20px}\n  .cellr .cland{position:absolute;left:0;right:0;bottom:0;height:62%;background:url(${LAND}) center 75%/cover;opacity:.85}\n  .cellr .veil{position:absolute;inset:0;background:linear-gradient(180deg,#eef0e6 30%,rgba(238,240,230,.2))}\n  .cellr .lr{position:relative;z-index:2;font-size:12px;border:1px solid rgba(40,40,30,.2);border-radius:20px;padding:5px 14px;background:rgba(255,255,255,.7)}\n  .ringbox{position:relative;z-index:2;margin-top:26px;width:230px;height:230px;display:flex;align-items:center;justify-content:center}\n  .ringbox svg{position:absolute;inset:0;width:100%;height:100%}\n  .rc{text-align:center}.rc .cap{font-size:13px;color:#5b5b4e}.rc .big{font-family:'Playfair Display',serif;font-size:78px;line-height:1;font-weight:600}.rc .dy{font-size:11px;letter-spacing:.25em;color:#5b5b4e}\n  .colr{display:flex;flex-direction:column;gap:14px}\n  .cellt{border-radius:20px;background:rgba(255,255,255,.72);padding:24px;flex:1}\n  .cellt h4{font-family:'Playfair Display',serif;font-weight:600;font-size:26px;margin:0 0 8px}.cellt p{font-size:14px;color:#55554a;line-height:1.5;margin:0}\n  .calmbtn{border:none;border-radius:18px;background:#8a9a3f;color:#fff;padding:20px;font:inherit;font-size:15px;font-weight:600;cursor:pointer}\n  .phwrap{position:relative;height:100%}\n  .phrow{display:flex;gap:64px;justify-content:center;align-items:center;height:100%;transform:translateX(9vw)}\n  .phslot{flex:0 0 280px;height:600px}\n  .phead{position:absolute;left:6vw;top:13vh;z-index:4}\n  .co{position:absolute;font-size:14px;color:#33332b;max-width:160px;line-height:1.3;z-index:3}\n  .co::after{content:'';position:absolute;width:50px;height:1px;background:rgba(40,40,30,.4)}\n  .co.l1{left:6vw;top:50%}.co.l1::after{right:-56px;top:10px}\n  .co.l2{left:6vw;top:66%}.co.l2::after{right:-56px;top:10px}\n  .co.r1{right:6vw;top:42%;text-align:right}.co.r1::after{left:-56px;top:10px}\n  .statement{font-family:'Playfair Display',serif;font-weight:600;font-size:clamp(34px,5vw,80px);line-height:1.02;letter-spacing:-.01em;text-align:center}\n  .ctaveil{position:absolute;inset:0;z-index:1;background:linear-gradient(180deg,rgba(244,243,238,.5),rgba(244,243,238,.2))}\n  .ctin{position:relative;z-index:2;text-align:center;max-width:760px;margin:0 auto}\n  .ctsub{font-size:16px;color:#44443a;margin:18px 0 24px}\n  .form{display:flex;gap:8px;max-width:440px;margin:0 auto;background:#fff;border-radius:30px;padding:6px;box-shadow:0 12px 30px rgba(60,60,40,.12)}\n  .form input{flex:1;border:none;background:transparent;padding:12px 18px;font:inherit;font-size:14px;outline:none}\n  .form button{border:none;background:#8a9a3f;color:#fff;border-radius:24px;padding:12px 22px;font:inherit;font-size:13px;font-weight:600;cursor:pointer}\n  .ctatop{position:absolute;top:6vh;left:6vw;right:6vw;z-index:2;display:flex;justify-content:space-between;align-items:center;font-size:14px}\n  .foot{position:absolute;left:6vw;right:6vw;bottom:4vh;z-index:2;display:flex;justify-content:space-between;align-items:center;font-size:13px;color:#44443a}\n  .foot .lks{display:flex;gap:30px}.foot .soc{display:flex;gap:12px;font-size:15px}\n  .reveal{opacity:0;transform:translateY(80px)}\n  `,\n  render(d2){\n    var ph1=d2.render(PH,{screen:'home'},{key:'ph1',class:'phslot'});\n    var ph2=d2.render(PH,{screen:'tx'},{key:'ph2',class:'phslot'});\n    var cardlayer='<div class=\"cardlayer\"><div class=\"card\" data-card><div class=\"face front\"><div class=\"chip\"></div><div class=\"gcw\">Ghostcard</div><div class=\"mc\"><i class=\"r\"></i><i class=\"y\"></i></div></div><div class=\"face back\"><div class=\"stripe\"></div></div></div></div>';\n    var hero='<section class=\"sec\" data-sec><div class=\"hbg\" data-hbg></div><div class=\"nav\"><div class=\"wm\">Ghostcard</div><div class=\"lks\"><span>About</span><span>FAQ</span><span>Functions</span><span>Blog</span></div><div class=\"rt\"><span class=\"pill\">Contact us</span><span class=\"pill g\">Download app</span></div></div><div class=\"tagline\">Private banking designed for calm minds and modern lifestyles.</div><div class=\"hbot\"><div class=\"badge\">The future of quiet banking</div><h1>Money should<br/>feel invisible.</h1></div><button class=\"start\">Start Invisibly</button></section>';\n    var bento='<div class=\"bento\"><div class=\"cellq\"><div class=\"q\">“For the first time, my banking app feels quiet. No pressure. No noise. Just clarity about how long I can live, build, and move freely.”</div><div class=\"role\">Founder &amp; Remote Creative</div></div><div class=\"cellr\"><div class=\"cland\"></div><div class=\"veil\"></div><div class=\"lr\">Life Runway</div><div class=\"ringbox\"><svg viewBox=\"0 0 200 200\"><circle cx=\"100\" cy=\"100\" r=\"86\" fill=\"none\" stroke=\"rgba(40,40,30,.12)\" stroke-width=\"2\"/><circle data-ring cx=\"100\" cy=\"100\" r=\"86\" fill=\"none\" stroke=\"#8a9a3f\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-dasharray=\"540\" stroke-dashoffset=\"540\" transform=\"rotate(-90 100 100)\"/></svg><div class=\"rc\"><div class=\"cap\">You can live calmly for</div><div class=\"big\"><span data-num>0</span></div><div class=\"dy\">DAYS</div></div></div></div><div class=\"colr\"><div class=\"cellt\"><h4>Your calm days</h4><p>Estimated personal runway based on your current lifestyle and spending rhythm.</p></div><div class=\"cellt\"><h4>Zero stress</h4><p>No aggressive alerts, market panic, or dashboard overload. Only meaningful moments that actually matter.</p></div><button class=\"calmbtn\">You’re calm life</button></div></div>';\n    var feat='<section class=\"sec\" data-sec data-feat><div class=\"center\"><div class=\"topr\">The future of quiet<br/>banking</div><div class=\"sheet reveal\" data-reveal><div class=\"badge it\">Features</div><div class=\"ttl\">What it’s like banking<br/>with Ghostcard</div>'+bento+'</div></div></section>';\n    var phones='<section class=\"sec\" data-sec><div class=\"phead reveal\" data-reveal><div class=\"badge it\">About</div><div class=\"ttl\">Calm finance<br/>for modern life</div></div><div class=\"phwrap\"><div class=\"phrow\">'+ph1+ph2+'</div><div class=\"co l1\">Designed for founders and creators</div><div class=\"co l2\">Freedom over financial performance</div><div class=\"co r1\">Emotional clarity</div></div></section>';\n    var cta='<section class=\"sec\" data-sec><div class=\"cbg\" data-cbg></div><div class=\"ctaveil\"></div><div class=\"ctatop\"><div class=\"badge it\">Ghostcard</div><div>Designed for calm minds</div></div><div class=\"center\"><div class=\"ctin reveal\" data-reveal><div class=\"statement\">Built for people who value clarity over noise.</div><div class=\"ctsub\">Get early access to a calmer, privacy-first way to experience banking.</div><div class=\"form\"><input placeholder=\"Enter your email\"/><button>Start Invisibly</button></div></div></div><div class=\"foot\"><div class=\"soc\"><span>in</span><span>◎</span><span>✕</span></div><div class=\"lks\"><span>Contact us</span><span>Careers</span><span>Privacy</span><span>Terms</span></div><div>© 2026 Axis, Inc.</div></div></section>';\n    return '<div class=\"gc\">'+cardlayer+'<div class=\"scr\" data-scr><div class=\"track\">'+hero+feat+phones+cta+'</div></div></div>';\n  },\n  mounted(d2){\n    var scr=d2.$('[data-scr]'),card=d2.$('[data-card]'),hbg=d2.$('[data-hbg]'),feat=d2.$('[data-feat]'),ring=d2.$('[data-ring]'),num=d2.$('[data-num]');\n    function clamp(v,a,b){return v<a?a:(v>b?b:v);}\n    function sz(){var h=scr?scr.clientHeight:700;d2.$$('[data-sec]').forEach(function(s){s.style.height=h+'px';});}\n    sz(); if(typeof window!=='undefined'){d2.on(window,'resize',sz);}\n    var t0=null;\n    d2.raf(function(t){\n      if(t0==null)t0=t;\n      var e=1-Math.pow(1-clamp((t-t0)/1600,0,1),3);\n      var st=scr?scr.scrollTop:0, vh=scr?scr.clientHeight:1;\n      var sp=st/vh;\n      if(hbg){var hp=clamp(sp,0,1);hbg.style.transform='scale('+(1+hp*0.28).toFixed(3)+') translateY('+(hp*-24).toFixed(1)+'px)';}\n      if(card){\n        var ry=-(1-e)*400 - 6 - sp*210;\n        var rx=(1-e)*34 + sp*12;\n        var rz=-9*e - sp*4;\n        var cy=(1-e)*-150 + sp*vh*0.84;\n        var sc=(0.6+0.4*e)*(1-Math.min(sp,1.3)*0.16);\n        var op=clamp(1.18-sp,0,1)*clamp(e*2,0,1);\n        card.style.transform='translate(-50%,-50%) translateY('+cy.toFixed(1)+'px) rotateX('+rx.toFixed(1)+'deg) rotateY('+ry.toFixed(1)+'deg) rotateZ('+rz.toFixed(1)+'deg) scale('+sc.toFixed(3)+')';\n        card.style.opacity=op.toFixed(2);\n      }\n      if(feat&&num&&ring){\n        var r=feat.getBoundingClientRect(),s2=scr.getBoundingClientRect();\n        var p=clamp((vh-(r.top-s2.top))/(vh*0.7),0,1);\n        var val=Math.round(p*94);\n        if(num.textContent!=String(val))num.textContent=val;\n        ring.style.strokeDashoffset=(540*(1-val/100)).toFixed(1);\n      }\n      d2.$$('[data-reveal]').forEach(function(el){\n        var rr=el.getBoundingClientRect(),s3=scr.getBoundingClientRect();\n        var pp=clamp((vh-(rr.top-s3.top))/(vh*0.5),0,1);\n        var ease=1-Math.pow(1-pp,3);\n        el.style.opacity=ease.toFixed(2);\n        el.style.transform='translateY('+((1-ease)*80).toFixed(1)+'px)';\n      });\n    });\n  }\n}"}}}}}}}},{"_id":"6a2ebcabd73289eb8a0b7a2e","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kGcPhone","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"var LAND='https://ai-playground.data2.media/file/obX7Fco-aYb1DwCwM4FHX';\nexport default {\n  css:`@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,500;0,600;1,500&family=Inter:wght@300;400;500;600;700&display=swap');\n  *{box-sizing:border-box}\n  .ph{width:100%;height:100%;display:flex;align-items:center;justify-content:center;font-family:'Inter',sans-serif}\n  .body{position:relative;width:266px;height:560px;background:#1c1c22;border-radius:46px;padding:11px;box-shadow:0 50px 90px rgba(40,50,20,.28),inset 0 0 2px 1px rgba(255,255,255,.2);flex:0 0 auto}\n  .scrn{position:relative;width:100%;height:100%;border-radius:36px;overflow:hidden;background:#F4F3EE}\n  .di{position:absolute;top:11px;left:50%;transform:translateX(-50%);width:88px;height:26px;background:#0a0a0c;border-radius:16px;z-index:6}\n  .sbar{position:absolute;top:0;left:0;right:0;height:46px;display:flex;align-items:center;justify-content:space-between;padding:16px 22px 0;font-size:12px;font-weight:600;z-index:5}\n  .home{position:absolute;inset:0;display:flex;flex-direction:column}\n  .htop{display:flex;align-items:center;justify-content:space-between;padding:50px 20px 0;font-family:'Playfair Display',serif;font-style:italic;font-size:15px}\n  .htop .dots{font-style:normal;letter-spacing:2px;color:#999}\n  .hbig{padding:26px 20px 0;font-family:'Playfair Display',serif;font-size:40px;line-height:.96;font-weight:600}\n  .hbig .mut{color:#b9bcae}\n  .hsub{padding:8px 20px 0;font-size:12px;color:#55554a}\n  .hland{position:absolute;left:0;right:0;bottom:0;height:54%;background:url(${LAND}) center 70%/cover}\n  .hbtn{position:absolute;left:16px;right:16px;bottom:18px;background:rgba(255,255,255,.9);backdrop-filter:blur(6px);border-radius:16px;text-align:center;padding:14px;font-size:13px;font-weight:600;z-index:3}\n  .tx{position:absolute;inset:0;background:linear-gradient(180deg,#cfd2c0,#9fa97f)}\n  .txland{position:absolute;left:0;right:0;bottom:0;height:40%;background:url(${LAND}) center 80%/cover;opacity:.9}\n  .lr{position:absolute;top:52px;left:50%;transform:translateX(-50%);font-size:10px;background:rgba(255,255,255,.7);border-radius:20px;padding:3px 10px;z-index:4}\n  .av{position:absolute;top:48px;left:18px;width:30px;height:30px;border-radius:50%;background:#cbb89a center/cover;z-index:4}\n  .bell{position:absolute;top:48px;right:18px;width:30px;height:30px;border-radius:50%;background:rgba(255,255,255,.7);display:flex;align-items:center;justify-content:center;font-size:13px;z-index:4}\n  .sheet{position:absolute;left:0;right:0;bottom:0;height:74%;background:#F6F5F0;border-radius:24px 24px 0 0;padding:18px 16px;z-index:3;box-shadow:0 -10px 30px rgba(0,0,0,.12)}\n  .sheet h3{font-family:'Playfair Display',serif;font-weight:600;font-size:17px;text-align:center;margin:2px 0 14px}\n  .tabs{display:flex;background:#ECEBE2;border-radius:12px;padding:3px;margin-bottom:14px}\n  .tabs span{flex:1;text-align:center;font-size:11px;padding:7px;border-radius:9px;color:#7a7a6c}.tabs span.on{background:#fff;color:#1a1a17;font-weight:600}\n  .stat{display:flex;gap:10px;margin-bottom:16px}\n  .stat .c{flex:1;background:#fff;border-radius:14px;padding:11px 12px;display:flex;align-items:center;gap:8px}\n  .stat .ic{width:26px;height:26px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:12px;color:#fff}\n  .stat .ic.g{background:#8a9a3f}.stat .ic.n{background:#ECEBE2;color:#1a1a17}\n  .stat .lbl{font-size:9px;color:#888}.stat .val{font-size:14px;font-weight:700}\n  .dt{font-size:10px;color:#999;margin:10px 2px 8px}\n  .rowt{display:flex;align-items:center;gap:10px;margin-bottom:12px}\n  .rowt .ri{width:30px;height:30px;border-radius:9px;background:#ECEBE2;display:flex;align-items:center;justify-content:center;font-size:12px}\n  .rowt .ri.g{background:#8a9a3f;color:#fff}\n  .rowt .nm{flex:1}.rowt .nm b{font-size:12px;font-weight:600;display:block}.rowt .nm s{font-size:10px;color:#999;text-decoration:none}\n  .rowt .am{text-align:right}.rowt .am b{font-size:12px;font-weight:600;display:block}.rowt .am s{font-size:10px;color:#999;text-decoration:none}\n  `,\n  render(d2){\n    var screen=d2.param('screen','home');\n    var sbar='<div class=\"sbar\"><span>9:41</span><span>&#9679;&#9679;&#9679; &#128246; &#128267;</span></div>';\n    if(screen==='tx'){\n      var inner='<div class=\"tx\"><div class=\"txland\"></div></div><div class=\"av\"></div><div class=\"bell\">&#128276;</div><div class=\"lr\">Life Runway</div><div class=\"sheet\"><h3>All Transactions</h3><div class=\"tabs\"><span class=\"on\">History</span><span>Pending</span><span>Scheduled</span></div><div class=\"stat\"><div class=\"c\"><div class=\"ic g\">&#8595;</div><div><div class=\"lbl\">Income</div><div class=\"val\">&#8364;1,932</div></div></div><div class=\"c\"><div class=\"ic n\">&#8593;</div><div><div class=\"lbl\">Spending</div><div class=\"val\">&#8364;456</div></div></div></div><div class=\"dt\">May 26, 2026</div><div class=\"rowt\"><div class=\"ri\">&#8593;</div><div class=\"nm\"><b>Zara online</b><s>Shopping</s></div><div class=\"am\"><b>&#8364;19,99</b><s>12:45</s></div></div><div class=\"rowt\"><div class=\"ri\">&#8593;</div><div class=\"nm\"><b>Cafe</b><s>Shopping</s></div><div class=\"am\"><b>&#8364;2,50</b><s>16:02</s></div></div><div class=\"dt\">May 25, 2026</div><div class=\"rowt\"><div class=\"ri g\">&#8595;</div><div class=\"nm\"><b>Data group</b><s>Salary</s></div><div class=\"am\"><b>&#8364;2,500</b><s>16:02</s></div></div></div>';\n      return '<div class=\"ph\"><div class=\"body\"><div class=\"di\"></div><div class=\"scrn\">'+sbar+inner+'</div></div></div>';\n    }\n    var home='<div class=\"home\"><div class=\"htop\">Ghostcard<span class=\"dots\">&#8943;</span></div><div class=\"hbig\">Ultra-<br/>minimal<br/><span class=\"mut\">banking</span></div><div class=\"hsub\">Privacy is the new luxury</div><div class=\"hland\"></div><div class=\"hbtn\">Start Invisibly</div></div>';\n    return '<div class=\"ph\"><div class=\"body\"><div class=\"di\"></div><div class=\"scrn\">'+sbar+home+'</div></div></div>';\n  }\n}"}},"screen":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"screen"}}}}}}}}}},{"_id":"6a2f02cee6cc9d55d3ddef8b","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kVivFlash","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>\"]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c];});}\nfunction norm(p){var it=(p.items&&p.items[0])||{};var img=(it.images&&it.images[0]&&it.images[0].imageUrl)||'';return {id:String(p.productId),name:p.productName,image:img,cat:(p.categories&&p.categories[0])||''};}\nfunction digUrl(o,d){if(o==null||d>6)return '';if(typeof o==='string'){if(o.indexOf('data:image')===0||/^https?:\\/\\//.test(o))return o;return '';}if(typeof o==='object'){if(typeof o.url==='string'){var u0=digUrl(o.url,d+1);if(u0)return u0;}if(o.length!=null&&typeof o!=='string'){for(var i=0;i<o.length;i++){var u=digUrl(o[i],d+1);if(u)return u;}}for(var k in o){try{if(!Object.prototype.hasOwnProperty.call(o,k))continue;}catch(e){continue;}var u2=digUrl(o[k],d+1);if(u2)return u2;}return '';}return '';}\nvar RUSH='https://ai-playground.data2apis.com/rush/vivDraw';\nvar LIGHT=[['Suave','soft diffused studio light'],['Dramática','dramatic chiaroscuro'],['Golden','warm golden glow'],['Spotlight','tight spotlight gem sparkle']];\nvar SKIN=[['Clara','fair porcelain skin'],['Média','light beige skin'],['Morena','golden-brown skin'],['Retinta','deep ebony skin']];\nvar SCENE=[['Mármore','white marble'],['Veludo','black velvet'],['Seda','champagne silk'],['Infinito','white infinity']];\nvar STEPS=['Início','Modelo','Joia','Direção','Resultado'];\nfunction frag(a,v){var f=a.filter(function(o){return o[0]===v;})[0];return f?f[1]:a[0][1];}\nfunction chips(a,k,sel){return a.map(function(o){return '<span class=\"ch'+(sel===o[0]?' on':'')+'\" data-k=\"'+k+'\" data-v=\"'+esc(o[0])+'\">'+esc(o[0])+'</span>';}).join('');}\nexport default {\n  css:`@import url('https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@500;600;700&family=Jost:wght@300;400;500;600&display=swap');\n  *{box-sizing:border-box;-webkit-tap-highlight-color:transparent}\n  .fl{position:relative;height:100%;overflow:hidden;background:radial-gradient(135% 105% at 50% -12%,#FCE7DA 0%,#FBF5F0 42%,#F6F0EA 100%);color:#1A1A1A;font-family:'Jost',sans-serif}\n  .fx{position:absolute;inset:0;width:100%;height:100%;z-index:0;pointer-events:none;display:block}\n  .vign{position:absolute;inset:0;z-index:1;pointer-events:none;background:radial-gradient(115% 95% at 50% 38%,transparent 62%,rgba(150,118,92,.07))}\n  .stage{position:absolute;inset:0;z-index:2;perspective:1600px}\n  .screen{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:74px 8vw 64px;transition:transform .8s cubic-bezier(.2,1.15,.3,1),opacity .5s ease;backface-visibility:hidden;transform-style:preserve-3d;will-change:transform,opacity}\n  .disp{font-family:'Cormorant Garamond',serif;font-weight:600;letter-spacing:.01em}\n  .kick{font-size:11px;letter-spacing:.44em;text-transform:uppercase;color:#CC8E6C;margin-bottom:14px}\n  h1.t{font-family:'Cormorant Garamond',serif;font-weight:600;font-size:clamp(48px,8vw,120px);line-height:.92;margin:0;color:#1A1A1A;letter-spacing:.01em}\n  .sub{color:#857A6F;margin-top:16px;font-size:15px;letter-spacing:.04em;text-align:center}\n  .glass{position:relative;border-radius:18px;background:rgba(255,255,255,.82);border:1px solid #EADFD3;box-shadow:0 26px 60px rgba(180,150,120,.18)}\n  .gbtn{position:relative;overflow:hidden;border:none;cursor:pointer;border-radius:40px;padding:17px 40px;font:inherit;font-size:13px;font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:#fff;text-decoration:none;display:inline-flex;align-items:center;background:#1A1A1A;box-shadow:0 14px 30px rgba(0,0,0,.18);transition:transform .25s cubic-bezier(.34,1.7,.5,1),box-shadow .25s,background .3s}\n  .gbtn:hover{transform:translateY(-3px) scale(1.02);box-shadow:0 20px 40px rgba(0,0,0,.26)}\n  .gbtn:active{transform:translateY(0) scale(.97)}\n  .gbtn .shine{position:absolute;top:0;left:0;height:100%;width:55%;background:linear-gradient(105deg,transparent,rgba(255,255,255,.32),transparent);transform:translateX(-180%) skewX(-18deg);animation:shine 3.6s ease-in-out infinite}\n  @keyframes shine{0%{transform:translateX(-180%) skewX(-18deg)}55%,100%{transform:translateX(340%) skewX(-18deg)}}\n  .ghost{background:transparent;color:#1A1A1A;border:1px solid #1A1A1A;box-shadow:none}\n  .ghost:hover{background:rgba(26,26,26,.05);box-shadow:none}\n  .peach{background:linear-gradient(180deg,#EFAE8C,#E2885F);box-shadow:0 14px 30px rgba(213,130,90,.32)}\n  .rail{position:absolute;top:30px;left:0;right:0;z-index:5;display:flex;justify-content:center;gap:34px;font-size:11px;letter-spacing:.18em;text-transform:uppercase}\n  .rail .s{color:#B7A99B;transition:.4s;position:relative}.rail .s.on{color:#1A1A1A}.rail .s.done{color:#CC8E6C}\n  .rail .s::before{content:'';position:absolute;left:-18px;top:50%;width:6px;height:6px;border-radius:50%;background:#DBCDBF;transform:translateY(-50%);transition:.4s}.rail .s.on::before{background:#E2885F;box-shadow:0 0 10px rgba(226,136,95,.7)}\n  .back{position:absolute;top:26px;left:30px;z-index:6;width:42px;height:42px;border-radius:50%;cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:20px;color:#1A1A1A;border:1px solid #D9CCBE;background:rgba(255,255,255,.6);transition:.25s}.back:hover{background:#fff;transform:translateX(-3px);box-shadow:0 8px 20px rgba(170,140,110,.2)}\n  .grid{display:flex;gap:18px;flex-wrap:wrap;justify-content:center;max-width:820px}\n  .pick{position:relative;width:120px;cursor:pointer;transition:transform .35s cubic-bezier(.34,1.6,.5,1)}\n  .pick:hover{transform:translateY(-8px) scale(1.04)}\n  .pick .ph{width:120px;height:150px;border-radius:14px;background:#F1E9E0 center/cover;border:1px solid #E8DCCD;box-shadow:0 14px 30px rgba(170,140,110,.2);transition:.3s}\n  .pick.on .ph{border-color:#E2885F;box-shadow:0 0 0 2px #E2885F,0 18px 40px rgba(213,130,90,.3)}\n  .pick.jew .ph{background:#fff;padding:10px}\n  .pick.jew .ph img{width:100%;height:100%;object-fit:contain;mix-blend-mode:multiply}\n  .pick .nm{text-align:center;font-size:11px;color:#8A7E72;margin-top:8px}\n  .arts{display:flex;flex-direction:column;gap:22px;width:540px;max-width:90%}\n  .arts .lab{font-size:11px;letter-spacing:.2em;text-transform:uppercase;color:#A99580;margin-bottom:9px}\n  .chrow{display:flex;flex-wrap:wrap;gap:9px}\n  .ch{cursor:pointer;font-size:12px;padding:9px 16px;border-radius:30px;border:1px solid #E2D5C6;color:#6E635A;background:rgba(255,255,255,.5);transition:.25s cubic-bezier(.34,1.6,.5,1)}\n  .ch:hover{transform:translateY(-2px);border-color:#E2885F}.ch.on{background:#1A1A1A;color:#fff;border-color:#1A1A1A;font-weight:600}\n  .acts{display:flex;gap:14px;margin-top:30px;align-items:center}\n  .gen{position:absolute;inset:0;z-index:8;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:24px;background:rgba(251,247,242,.84)}\n  .orb{position:relative;width:90px;height:90px}\n  .orb i{position:absolute;top:50%;left:50%;width:10px;height:10px;margin:-5px;border-radius:50%;background:#E2885F;box-shadow:0 0 14px rgba(226,136,95,.6)}\n  .gtxt{font-family:'Cormorant Garamond',serif;font-size:27px;color:#1A1A1A;letter-spacing:.02em}\n  .frame{position:relative;border-radius:14px;overflow:hidden;background:#fff;padding:10px;box-shadow:0 40px 80px rgba(150,110,80,.28),0 0 0 1px #EADFD3;animation:pop .8s cubic-bezier(.2,1.3,.3,1) both}\n  @keyframes pop{from{transform:rotateY(35deg) scale(.7);opacity:0}to{transform:none;opacity:1}}\n  .frame img{display:block;max-width:42vw;max-height:58vh;object-fit:contain;border-radius:6px}\n  .frame .sweep{position:absolute;inset:0;pointer-events:none;background:linear-gradient(115deg,transparent 35%,rgba(255,255,255,.65) 50%,transparent 65%);transform:translateX(-130%);animation:swp 1.3s ease .35s both}\n  @keyframes swp{to{transform:translateX(130%)}}\n  .pre{position:absolute;inset:0;z-index:20;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:26px;background:radial-gradient(circle at 50% 42%,#FDEEE4,#F6EEE6);transition:opacity .7s ease,transform .9s cubic-bezier(.7,0,.3,1)}\n  .pre.gone{opacity:0;transform:scale(1.4);pointer-events:none}\n  .preword{font-family:'Cormorant Garamond',serif;font-weight:600;font-size:62px;letter-spacing:.36em;padding-left:.36em;color:#1A1A1A}\n  .bar{width:260px;height:3px;background:rgba(26,26,26,.1);border-radius:3px;overflow:hidden}\n  .bar i{display:block;height:100%;width:0;background:linear-gradient(90deg,#E2885F,#EFAE8C)}\n  .pct{font-size:12px;letter-spacing:.3em;color:#B79A86}\n  `,\n  render(d2){\n    var s=d2.state;var step=s.step||0;\n    var prods=((d2.data('products')&&d2.data('products').records())||[]).map(norm).filter(function(p){return p.image&&p.cat.indexOf('/Joias/')>=0;}).slice(0,8);\n    var models=(d2.data('models')&&d2.data('models').records())||[];\n    var light=s.light||'Suave',skin=s.skin||'Média',scene=s.scene||'Mármore';\n    function place(i){var rel=i-step;var tr;if(rel===0)tr='translateX(0) rotateY(0deg) scale(1)';else if(rel<0)tr='translateX(-70%) rotateY(38deg) scale(.82)';else tr='translateX(70%) rotateY(-38deg) scale(.82)';return 'style=\"transform:'+tr+';opacity:'+(rel===0?1:0)+';z-index:'+(rel===0?3:1)+';pointer-events:'+(rel===0?'auto':'none')+'\"';}\n    var home='<section class=\"screen\" '+place(0)+'><div class=\"kick\">Maison Vivara</div><h1 class=\"t\">Atelier<br/>Virtual</h1><div class=\"sub\">Prove as joias mais desejadas em uma experiência imersiva.</div><div class=\"acts\"><button class=\"gbtn\" data-go=\"1\"><span class=\"shine\"></span>Iniciar Experiência</button></div></section>';\n    var mhtml=models.map(function(m){var has=m.imageUrl&&m.imageUrl.length>10;return '<div class=\"pick'+(s.selModelId===m._id?' on':'')+'\" data-model=\"'+m._id+'\"><div class=\"ph\" style=\"'+(has?'background-image:url('+esc(m.imageUrl)+')':'')+'\"></div><div class=\"nm\">'+esc(m.name)+'</div></div>';}).join('');\n    var model='<section class=\"screen\" '+place(1)+'><div class=\"kick\">Passo 01 · A Modelo</div><div class=\"disp\" style=\"font-size:30px;margin-bottom:26px\">Escolha sua musa</div><div class=\"grid\">'+mhtml+'</div><div class=\"acts\"><button class=\"gbtn'+(s.selModelId?'':' ghost')+'\" data-go=\"2\">Continuar</button></div></section>';\n    var jhtml=prods.map(function(p){return '<div class=\"pick jew'+(s.selProductId===p.id?' on':'')+'\" data-prod=\"'+p.id+'\"><div class=\"ph\"><img src=\"'+esc(p.image)+'\"/></div></div>';}).join('');\n    var jewel='<section class=\"screen\" '+place(2)+'><div class=\"kick\">Passo 02 · A Joia</div><div class=\"disp\" style=\"font-size:30px;margin-bottom:26px\">Selecione a peça</div><div class=\"grid\">'+jhtml+'</div><div class=\"acts\"><button class=\"gbtn'+(s.selProductId?'':' ghost')+'\" data-go=\"3\">Continuar</button></div></section>';\n    var art='<section class=\"screen\" '+place(3)+'><div class=\"kick\">Passo 03 · A Direção</div><div class=\"disp\" style=\"font-size:30px;margin-bottom:26px\">Componha a cena</div><div class=\"arts glass\" style=\"padding:30px\"><div><div class=\"lab\">Iluminação</div><div class=\"chrow\">'+chips(LIGHT,'light',light)+'</div></div><div><div class=\"lab\">Tom de pele</div><div class=\"chrow\">'+chips(SKIN,'skin',skin)+'</div></div><div><div class=\"lab\">Cenário</div><div class=\"chrow\">'+chips(SCENE,'scene',scene)+'</div></div></div><div class=\"acts\"><button class=\"gbtn peach\" data-render><span class=\"shine\"></span>Renderizar</button></div></section>';\n    var resInner=s.result?'<div class=\"frame\"><img src=\"'+esc(s.result)+'\"/><div class=\"sweep\"></div></div>':'<div class=\"sub\">—</div>';\n    var result='<section class=\"screen\" '+place(4)+'><div class=\"kick\">A Revelação</div>'+resInner+'<div class=\"acts\"><button class=\"gbtn ghost\" data-go=\"3\">Refazer</button><a class=\"gbtn peach\" '+(s.result?'href=\"'+esc(s.result)+'\" download=\"vivara.png\"':'')+'><span class=\"shine\"></span>Baixar</a></div></section>';\n    var rail='<div class=\"rail\">'+STEPS.map(function(n,i){return '<span class=\"s'+(i===step?' on':(i<step?' done':''))+'\">'+esc(n)+'</span>';}).join('')+'</div>';\n    var back=step>0&&step<4?'<div class=\"back\" data-back>‹</div>':'';\n    var gen=s.busy?'<div class=\"gen\"><div class=\"orb\" data-orb><i></i><i></i><i></i><i></i><i></i></div><div class=\"gtxt\" data-gtxt>Compondo a joia…</div></div>':'';\n    var pre='<div class=\"pre'+(s.loading===false?' gone':'')+'\"><div class=\"preword\">VIVARA</div><div class=\"bar\"><i data-prebar></i></div><div class=\"pct\" data-pct>0%</div></div>';\n    return '<div class=\"fl\"><canvas class=\"fx\" data-fx></canvas><div class=\"vign\"></div><div class=\"stage\">'+home+model+jewel+art+result+'</div>'+rail+back+gen+pre+'</div>';\n  },\n  mounted(d2){\n    var parts=[],t0=null,preDone=false,lastTxt=-1;\n    var TXT=['Compondo a joia…','Posicionando na modelo…','Ajustando a luz…','Revelando…'];\n    d2.on('[data-go]','click',function(e,el){d2.setState({step:parseInt(el.getAttribute('data-go'),10)});});\n    d2.on('[data-back]','click',function(){d2.setState({step:Math.max(0,(d2.state.step||0)-1)});});\n    d2.on('[data-model]','click',function(e,el){d2.setState({selModelId:el.getAttribute('data-model')});});\n    d2.on('[data-prod]','click',function(e,el){d2.setState({selProductId:el.getAttribute('data-prod')});});\n    d2.on('[data-k]','click',function(e,el){var st={};st[el.getAttribute('data-k')]=el.getAttribute('data-v');d2.setState(st);});\n    d2.on('[data-render]','click',function(){\n      if(d2.state.busy)return;\n      var prods=((d2.data('products')&&d2.data('products').records())||[]).map(norm);\n      var prod=prods.filter(function(p){return p.id===d2.state.selProductId;})[0];\n      var models=(d2.data('models')&&d2.data('models').records())||[];\n      var m=models.filter(function(x){return x._id===d2.state.selModelId;})[0];\n      if(!m){d2.setState({step:1});return;} if(!prod){d2.setState({step:2});return;}\n      var s=d2.state;\n      var prompt='Ultra-realistic luxury jewelry photo. An elegant model ('+(m.kind||'hand')+') with '+frag(SKIN,s.skin||'Média')+', wearing this EXACT jewel from the reference — keep it identical. Lighting: '+frag(LIGHT,s.light||'Suave')+'. Background: '+frag(SCENE,s.scene||'Mármore')+'. Hyperrealistic, Vivara premium. Jewel: '+prod.name+'.';\n      var imgs=[];if(m.imageUrl&&m.imageUrl.length>10)imgs.push(m.imageUrl);imgs.push(prod.image);\n      d2.setState({busy:true,result:null});\n      fetch(RUSH,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({prompt:prompt,images:imgs,options:{size:'896x1152'}})}).then(function(r){return r.json();}).then(function(j){var url=digUrl(j,0);d2.setState({busy:false,result:url,step:url?4:3});try{if(url)d2.data('tryons').create({modelName:m.name,productName:prod.name,productImage:prod.image,resultUrl:url,ts:new Date().toISOString()});}catch(_){}}).catch(function(){d2.setState({busy:false});});\n    });\n    d2.raf(function(t){\n      if(t0==null)t0=t;\n      if(d2.state.loading!==false){\n        var pct=Math.min(100,(t-t0)/2000*100);\n        var bar=d2.$('[data-prebar]');if(bar)bar.style.width=pct.toFixed(0)+'%';\n        var pc=d2.$('[data-pct]');if(pc)pc.textContent=Math.floor(pct)+'%';\n        if(pct>=100&&!preDone){preDone=true;setTimeout(function(){d2.setState({loading:false});},350);}\n      }\n      if(d2.state.busy){\n        var gi=Math.floor(t/1400)%TXT.length;if(gi!==lastTxt){lastTxt=gi;var gt=d2.$('[data-gtxt]');if(gt)gt.textContent=TXT[gi];}\n        var orb=d2.$('[data-orb]');if(orb){var dts=orb.children;for(var o=0;o<dts.length;o++){var a=t/350+o*(6.283/dts.length);dts[o].style.transform='translate('+(Math.cos(a)*34).toFixed(1)+'px,'+(Math.sin(a)*34).toFixed(1)+'px) scale('+(0.6+0.6*(0.5+0.5*Math.sin(t/250+o))).toFixed(2)+')';}}\n      }\n      var cv=d2.$('[data-fx]');if(!cv)return;var ctx=cv.getContext('2d');var dpr=Math.min(window.devicePixelRatio||1,2);var w=cv.clientWidth,h=cv.clientHeight;if(w>0&&cv.width!==Math.round(w*dpr)){cv.width=Math.round(w*dpr);cv.height=Math.round(h*dpr);ctx.setTransform(dpr,0,0,dpr,0,0);}\n      if(parts.length<42&&Math.random()<0.55)parts.push({x:Math.random()*w,y:h+10,vy:-(Math.random()*0.45+0.12),vx:(Math.random()-0.5)*0.18,r:Math.random()*2.2+0.5,a:0,life:Math.random()*0.6+0.4});\n      ctx.clearRect(0,0,w,h);\n      for(var i=parts.length-1;i>=0;i--){var p=parts[i];p.y+=p.vy;p.x+=p.vx;p.a=Math.min(p.life,p.a+0.008);p.life-=0.0025;if(p.life<=0||p.y<-10){parts.splice(i,1);continue;}var tw=0.5+0.5*Math.sin(t/300+p.x);ctx.fillStyle='rgba(218,160,124,'+(p.a*tw*0.5).toFixed(3)+')';ctx.beginPath();ctx.arc(p.x,p.y,p.r,0,6.28);ctx.fill();}\n    });\n  }\n}"}},"models":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"models"}}}},"products":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"products"}}}},"tryons":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"tryons"}}}}}}}}}},{"_id":"6a2f1632d73289eb8a0bcfc5","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kSpark","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function pts(s){return String(s||'').split(',').map(function(x){return parseFloat(x);}).filter(function(n){return !isNaN(n);});}\nexport default {\n  css:`.sk{width:100%;height:100%;display:block}`,\n  render(d2){\n    var p=pts(d2.param('points',''));var up=d2.param('up',true);\n    if(p.length<2)return '<svg class=\"sk\" viewBox=\"0 0 100 30\" preserveAspectRatio=\"none\"></svg>';\n    var mn=Math.min.apply(null,p),mx=Math.max.apply(null,p),rng=(mx-mn)||1,n=p.length;\n    var coords=p.map(function(v,i){var x=(i/(n-1))*100;var y=28-((v-mn)/rng)*26;return x.toFixed(2)+','+y.toFixed(2);});\n    var line=coords.join(' ');var area='0,30 '+line+' 100,30';\n    var col=up?'#16c784':'#ea3943';var id=up?'gu':'gd';\n    return '<svg class=\"sk\" viewBox=\"0 0 100 30\" preserveAspectRatio=\"none\"><defs><linearGradient id=\"'+id+'\" x1=\"0\" x2=\"0\" y1=\"0\" y2=\"1\"><stop offset=\"0\" stop-color=\"'+col+'\" stop-opacity=\"0.35\"/><stop offset=\"1\" stop-color=\"'+col+'\" stop-opacity=\"0\"/></linearGradient></defs><polygon points=\"'+area+'\" fill=\"url(#'+id+')\"/><polyline points=\"'+line+'\" fill=\"none\" stroke=\"'+col+'\" stroke-width=\"1.4\" stroke-linejoin=\"round\" vector-effect=\"non-scaling-stroke\"/></svg>';\n  }\n}"}},"points":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"points"}}}},"up":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"up"}}}}}}}}}},{"_id":"6a2f1633d73289eb8a0bcfca","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kKpi","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>\"]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c];});}\nexport default {\n  css:`.kp{height:100%;display:flex;flex-direction:column;justify-content:center;padding:16px 20px;border-radius:14px;background:linear-gradient(160deg,#15181f,#0e1014);border:1px solid #21262f;box-shadow:0 12px 30px rgba(0,0,0,.4);font-family:'Inter',sans-serif;overflow:hidden}\n  .kp .lbl{font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:#6b7280}\n  .kp .val{font-size:26px;font-weight:700;color:#f1f5f9;margin-top:6px;font-variant-numeric:tabular-nums}\n  .kp .dl{font-size:12px;font-weight:600;margin-top:4px}`,\n  render(d2){\n    var label=d2.param('label','—'),value=d2.param('value','—'),delta=d2.param('delta','');\n    var dl=String(delta||'');var pos=dl.indexOf('-')!==0;\n    return '<div class=\"kp\"><div class=\"lbl\">'+esc(label)+'</div><div class=\"val\">'+esc(value)+'</div>'+(dl?'<div class=\"dl\" style=\"color:'+(pos?'#16c784':'#ea3943')+'\">'+esc(delta)+'</div>':'')+'</div>';\n  }\n}"}},"label":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"label"}}}},"value":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"value"}}}},"delta":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"delta"}}}}}}}}}},{"_id":"6a2f16ca75a8dfffb1d26d78","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kLiveDesk","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>\"]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c];});}\nfunction compact(n){n=Number(n)||0;if(n>=1e12)return '$'+(n/1e12).toFixed(2)+'T';if(n>=1e9)return '$'+(n/1e9).toFixed(2)+'B';if(n>=1e6)return '$'+(n/1e6).toFixed(2)+'M';return '$'+Math.round(n).toLocaleString('en-US');}\nfunction px(n){n=Number(n)||0;return n>=1?'$'+n.toLocaleString('en-US',{maximumFractionDigits:2}):'$'+n.toFixed(4);}\nfunction rel(ts){var d=new Date(ts).getTime();var s=Math.floor((Date.now()-d)/1000);if(s<5)return 'agora';if(s<60)return s+'s';if(s<3600)return Math.floor(s/60)+'min';return Math.floor(s/3600)+'h';}\nvar SPARK='ai-playground@kSpark',KPI='ai-playground@kKpi';\nvar EMIT='https://ai-playground.data2apis.com/rush/tapeEmit';\nfunction norm(c){var sp=(c.sparkline_in_7d&&c.sparkline_in_7d.price)||[];sp=sp.slice(-40);return {id:c.id,sym:(c.symbol||'').toUpperCase(),name:c.name,price:c.current_price,ch:c.price_change_percentage_24h||0,mcap:c.market_cap||0,vol:c.total_volume||0,img:c.image,spark:sp.map(function(v){return Number(v).toFixed(4);}).join(',')};}\nexport default {\n  css:`@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');\n  *{box-sizing:border-box}\n  .desk{height:100%;background:#0a0c10;color:#e5e9f0;font-family:'Inter',sans-serif;display:grid;grid-template-columns:1fr 340px;gap:18px;padding:22px 24px;overflow:hidden}\n  .main{display:flex;flex-direction:column;min-width:0;overflow:hidden}\n  .hdr{display:flex;align-items:center;gap:14px;margin-bottom:16px}\n  .brand{font-size:20px;font-weight:700;letter-spacing:.02em}.brand span{color:#16c784}\n  .live{display:flex;align-items:center;gap:7px;font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:#16c784}\n  .live .dot{width:8px;height:8px;border-radius:50%;background:#16c784;animation:pulse 1.6s infinite}\n  @keyframes pulse{0%{box-shadow:0 0 0 0 rgba(22,199,132,.5)}70%{box-shadow:0 0 0 8px rgba(22,199,132,0)}100%{box-shadow:0 0 0 0 rgba(22,199,132,0)}}\n  .upd{margin-left:auto;font-size:11px;color:#6b7280}\n  .kpiRow{display:flex;gap:14px;margin-bottom:18px}.kpiC{flex:1;height:92px}\n  .tbl{flex:1;overflow-y:auto;border:1px solid #1b2029;border-radius:14px;background:#0e1014}\n  .trow{display:grid;grid-template-columns:1.6fr .9fr .7fr 130px auto;align-items:center;gap:12px;padding:12px 16px;border-bottom:1px solid #161b23}\n  .trow.head{position:sticky;top:0;background:#10141b;color:#6b7280;font-size:11px;letter-spacing:.1em;text-transform:uppercase;z-index:2}\n  .coin{display:flex;align-items:center;gap:10px;min-width:0}.coin img{width:26px;height:26px;border-radius:50%}\n  .coin .sym{font-weight:700}.coin .nm{font-size:11px;color:#6b7280}\n  .price{font-variant-numeric:tabular-nums;font-weight:600;text-align:right}\n  .ch{font-weight:600;text-align:right;font-variant-numeric:tabular-nums}\n  .skC{width:120px;height:38px}\n  .tact{display:flex;gap:6px;justify-content:flex-end}\n  .tbtn{width:30px;height:30px;border-radius:8px;border:1px solid #232a35;background:#151a22;cursor:pointer;font-weight:700;font-size:12px;transition:.15s}\n  .tbtn.b{color:#16c784}.tbtn.b:hover{background:rgba(22,199,132,.13);border-color:#16c784}\n  .tbtn.s{color:#ea3943}.tbtn.s:hover{background:rgba(234,57,67,.13);border-color:#ea3943}\n  .tape{display:flex;flex-direction:column;border:1px solid #1b2029;border-radius:14px;background:#0e1014;overflow:hidden}\n  .tapeH{padding:14px 16px;border-bottom:1px solid #161b23;display:flex;align-items:center;gap:8px;font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:#9aa4b2}\n  .tapeB{flex:1;overflow-y:auto}\n  .tItem{padding:11px 16px;border-bottom:1px solid #12161d;display:flex;align-items:center;gap:10px;animation:slideIn .45s cubic-bezier(.2,1,.3,1)}\n  @keyframes slideIn{from{opacity:0;transform:translateX(16px)}to{opacity:1;transform:none}}\n  .tBadge{font-size:10px;font-weight:700;padding:3px 7px;border-radius:6px;flex:0 0 auto}\n  .tBadge.buy{background:rgba(22,199,132,.15);color:#16c784}.tBadge.sell{background:rgba(234,57,67,.15);color:#ea3943}\n  .tTxt{flex:1;font-size:12.5px;min-width:0}.tTxt b{font-weight:700}.tTxt .mut{color:#6b7280}\n  .tTime{font-size:10px;color:#5b6472}\n  .skel{padding:50px;text-align:center;color:#6b7280;font-size:13px}`,\n  render(d2){\n    var s=d2.state;var coins=(s.markets||[]).map(norm);\n    var kpis='';\n    if(coins.length){\n      var mcap=coins.reduce(function(a,c){return a+c.mcap;},0);\n      var vol=coins.reduce(function(a,c){return a+c.vol;},0);\n      var top=coins.slice().sort(function(a,b){return b.ch-a.ch;})[0];\n      var ups=coins.filter(function(c){return c.ch>=0;}).length;\n      var k=[['Market Cap',compact(mcap),''],['Volume 24h',compact(vol),''],['Top Gainer',top.sym,(top.ch>=0?'+':'')+top.ch.toFixed(2)+'%'],['Em Alta',ups+'/'+coins.length,'']];\n      kpis=k.map(function(o,i){return '<div class=\"kpiC\">'+d2.render(KPI,{label:o[0],value:o[1],delta:o[2]},{key:'k'+i})+'</div>';}).join('');\n    }\n    var rows='';\n    if(!coins.length){rows='<div class=\"skel\">Conectando ao mercado ao vivo…</div>';}\n    else{\n      rows='<div class=\"trow head\"><div>Ativo</div><div style=\"text-align:right\">Preço</div><div style=\"text-align:right\">24h</div><div>7 dias</div><div style=\"text-align:right\">Trade</div></div>';\n      rows+=coins.map(function(c){var up=c.ch>=0;var chc=up?'#16c784':'#ea3943';\n        return '<div class=\"trow\"><div class=\"coin\"><img src=\"'+esc(c.img)+'\"/><div><div class=\"sym\">'+esc(c.sym)+'</div><div class=\"nm\">'+esc(c.name)+'</div></div></div><div class=\"price\">'+px(c.price)+'</div><div class=\"ch\" style=\"color:'+chc+'\">'+(up?'+':'')+c.ch.toFixed(2)+'%</div><div class=\"skC\">'+d2.render(SPARK,{points:c.spark,up:up},{key:'sp'+c.id})+'</div><div class=\"tact\"><span class=\"tbtn b\" data-side=\"buy\" data-coin=\"'+esc(c.name)+'\" data-sym=\"'+esc(c.sym)+'\" data-price=\"'+c.price+'\">B</span><span class=\"tbtn s\" data-side=\"sell\" data-coin=\"'+esc(c.name)+'\" data-sym=\"'+esc(c.sym)+'\" data-price=\"'+c.price+'\">S</span></div></div>';\n      }).join('');\n    }\n    var feed=((d2.data('feed')&&d2.data('feed').records())||[]).slice().sort(function(a,b){return new Date(b.ts).getTime()-new Date(a.ts).getTime();}).slice(0,25);\n    var tape=feed.map(function(r){var buy=r.side==='buy';return '<div class=\"tItem\" data-key=\"'+esc(r._id)+'\"><span class=\"tBadge '+(buy?'buy':'sell')+'\">'+(buy?'COMPRA':'VENDA')+'</span><div class=\"tTxt\"><b>'+esc(r.actor)+'</b> <span class=\"mut\">'+(buy?'comprou':'vendeu')+'</span> '+esc(r.sym)+' <span class=\"mut\">@</span> '+px(r.price)+'</div><span class=\"tTime\">'+rel(r.ts)+'</span></div>';}).join('');\n    return '<div class=\"desk\"><div class=\"main\"><div class=\"hdr\"><div class=\"brand\">LIVE <span>DESK</span></div><div class=\"live\"><span class=\"dot\"></span>Ao vivo</div><div class=\"upd\">'+(s.updated?'atualizado '+rel(s.updated):'conectando…')+'</div></div><div class=\"kpiRow\">'+kpis+'</div><div class=\"tbl\">'+rows+'</div></div><div class=\"tape\"><div class=\"tapeH\"><span class=\"live\"><span class=\"dot\"></span></span>Fita ao vivo</div><div class=\"tapeB\">'+tape+'</div></div></div>';\n  },\n  mounted(d2){\n    var last=-1e9,lastF=-1e9;\n    function poll(){fetch('https://ai-playground.data2apis.com/rush/liveMarkets',{method:'POST',headers:{'Content-Type':'application/json'},body:'{}'}).then(function(r){return r.json();}).then(function(j){var arr=(j&&j.data)?j.data:j;if(Array.isArray(arr))d2.setState({markets:arr,updated:Date.now()});}).catch(function(){});}\n    var sock=d2.socket&&d2.socket('liveTape');\n    if(sock){try{sock.connect&&sock.connect();}catch(_){}try{sock.subscribe&&sock.subscribe('desk');}catch(_){}try{sock.onMessage&&sock.onMessage(function(){var f=d2.data('feed');if(f&&f.refresh)f.refresh();});}catch(_){}}\n    d2.on('[data-side]','click',function(e,el){\n      var body={actor:'Você',side:el.getAttribute('data-side'),coin:el.getAttribute('data-coin'),sym:el.getAttribute('data-sym'),price:parseFloat(el.getAttribute('data-price')),ts:new Date().toISOString()};\n      fetch(EMIT,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(body)}).then(function(){var f=d2.data('feed');if(f&&f.refresh)f.refresh();}).catch(function(){});\n    });\n    d2.raf(function(t){if(t-last>4000){last=t;poll();}if(t-lastF>20000){lastF=t;var ff=d2.data('feed');if(ff&&ff.refresh)ff.refresh();}});\n  }\n}"}},"feed":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"feed"}}}}}}}}}},{"_id":"6a342372b5a1f156bea57a56","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"cmp-cacapava-taubate","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n    *{box-sizing:border-box}\n    .root{height:100%;overflow:auto;background:#0f1117;color:#e8eaf0;font-family:'Inter',system-ui,sans-serif;padding:32px 40px 48px}\n    .head{display:flex;flex-direction:column;gap:6px;margin-bottom:8px}\n    .head h1{margin:0;font-size:26px;font-weight:800;letter-spacing:-.02em}\n    .head p{margin:0;font-size:13px;color:#8b90a3}\n    .cities{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin:24px 0}\n    .city{border-radius:18px;padding:20px;border:1px solid rgba(255,255,255,.06)}\n    .city.a{background:linear-gradient(160deg,#1b2a4a,#141b2e)}\n    .city.b{background:linear-gradient(160deg,#3a1f2e,#1f1620)}\n    .city h2{margin:0 0 2px;font-size:20px;font-weight:800}\n    .city .sub{font-size:12px;color:#9aa0b4;margin-bottom:14px}\n    .chips{display:flex;flex-wrap:wrap;gap:8px}\n    .chip{background:rgba(255,255,255,.06);border-radius:10px;padding:8px 10px;flex:1;min-width:90px}\n    .chip .k{font-size:10px;color:#8b90a3;text-transform:uppercase;letter-spacing:.05em}\n    .chip .v{font-size:16px;font-weight:700;margin-top:2px}\n    .toggle{display:inline-flex;background:rgba(255,255,255,.06);border-radius:12px;padding:4px;gap:4px;margin:8px 0 20px}\n    .toggle button{border:0;background:transparent;color:#9aa0b4;font-size:13px;font-weight:600;padding:8px 16px;border-radius:9px;cursor:pointer;transition:.15s}\n    .toggle button[data-on]{background:#5b8aff;color:#fff}\n    .bars{display:flex;flex-direction:column;gap:16px}\n    .barrow .top{display:flex;justify-content:space-between;font-size:13px;margin-bottom:6px}\n    .barrow .top .lbl{color:#c7cad6;font-weight:600}\n    .track{position:relative;height:34px;border-radius:9px;background:rgba(255,255,255,.04);overflow:hidden}\n    .fill{position:absolute;top:0;height:50%;display:flex;align-items:center;padding-left:10px;font-size:12px;font-weight:700;color:#fff;border-radius:8px;white-space:nowrap;transition:width .5s ease}\n    .fill.a{top:2px;background:#5b8aff}\n    .fill.b{bottom:2px;top:auto;background:#ff7a9c}\n    .legend{display:flex;gap:18px;font-size:12px;color:#9aa0b4;margin-top:18px}\n    .legend span{display:inline-flex;align-items:center;gap:6px}\n    .dot{width:10px;height:10px;border-radius:3px;display:inline-block}\n    .foot{margin-top:24px;font-size:11px;color:#666b80}\n  `,\n  render(d2){\n    const tab = d2.state.tab || 'viver'\n    const C = {\n      name:'Caçapava', sub:'SP · ~100 mil hab · 369 km²',\n      pibcap:67735, idhm:0.788, viver:65, investir:67, saude:7.88, saneamento:95.4, violencia:4.0\n    }\n    const T = {\n      name:'Taubaté', sub:'SP · ~317 mil hab · 626 km²',\n      pibcap:72755, idhm:0.800, viver:72, investir:65, saude:8.32, saneamento:98.0, violencia:1.9\n    }\n    const metrics = tab === 'viver'\n      ? [\n          {lbl:'Nota para VIVER (0–100)', a:C.viver, b:T.viver, max:100, fmt:v=>v},\n          {lbl:'Saneamento adequado (%)', a:C.saneamento, b:T.saneamento, max:100, fmt:v=>v+'%'},\n          {lbl:'Profissionais de saúde /mil hab', a:C.saude, b:T.saude, max:10, fmt:v=>d2.fmt.number(v)},\n          {lbl:'Violência letal /100 mil (menor=melhor)', a:C.violencia, b:T.violencia, max:8, fmt:v=>d2.fmt.number(v)},\n          {lbl:'IDHM', a:C.idhm, b:T.idhm, max:1, fmt:v=>d2.fmt.number(v)},\n        ]\n      : [\n          {lbl:'Nota para INVESTIR (0–100)', a:C.investir, b:T.investir, max:100, fmt:v=>v},\n          {lbl:'PIB per capita (R$)', a:C.pibcap, b:T.pibcap, max:80000, fmt:v=>d2.fmt.compact(v)},\n          {lbl:'IDHM', a:C.idhm, b:T.idhm, max:1, fmt:v=>d2.fmt.number(v)},\n        ]\n    const bar = m => `\n      <div class=\"barrow\">\n        <div class=\"top\"><span class=\"lbl\">${m.lbl}</span></div>\n        <div class=\"track\">\n          <div class=\"fill a\" style=\"width:${Math.min(100,(m.a/m.max)*100)}%\">${m.fmt(m.a)}</div>\n          <div class=\"fill b\" style=\"width:${Math.min(100,(m.b/m.max)*100)}%\">${m.fmt(m.b)}</div>\n        </div>\n      </div>`\n    const chip = (k,v) => `<div class=\"chip\"><div class=\"k\">${k}</div><div class=\"v\">${v}</div></div>`\n    return `<div class=\"root\">\n      <div class=\"head\">\n        <h1>Caçapava × Taubaté</h1>\n        <p>Comparação de indicadores municipais — fonte Painel das Cidades / IBGE (dados até 2025)</p>\n      </div>\n      <div class=\"cities\">\n        <div class=\"city a\">\n          <h2>${C.name}</h2><div class=\"sub\">${C.sub}</div>\n          <div class=\"chips\">\n            ${chip('IDHM', d2.fmt.number(C.idhm))}\n            ${chip('PIB/cap', 'R$ '+d2.fmt.compact(C.pibcap))}\n            ${chip('Saneamento', C.saneamento+'%')}\n          </div>\n        </div>\n        <div class=\"city b\">\n          <h2>${T.name}</h2><div class=\"sub\">${T.sub}</div>\n          <div class=\"chips\">\n            ${chip('IDHM', d2.fmt.number(T.idhm))}\n            ${chip('PIB/cap', 'R$ '+d2.fmt.compact(T.pibcap))}\n            ${chip('Saneamento', T.saneamento+'%')}\n          </div>\n        </div>\n      </div>\n      <div class=\"toggle\">\n        <button class=\"tab\" data-tab=\"viver\" ${tab==='viver'?'data-on':''}>🏡 Para viver</button>\n        <button class=\"tab\" data-tab=\"investir\" ${tab==='investir'?'data-on':''}>💼 Para investir</button>\n      </div>\n      <div class=\"bars\">${metrics.map(bar).join('')}</div>\n      <div class=\"legend\">\n        <span><i class=\"dot\" style=\"background:#5b8aff\"></i> Caçapava</span>\n        <span><i class=\"dot\" style=\"background:#ff7a9c\"></i> Taubaté</span>\n      </div>\n      <div class=\"foot\">Barras normalizadas por métrica. Em \"violência letal\", menor é melhor.</div>\n    </div>`\n  },\n  mounted(d2){\n    d2.on('.tab','click',(e,el)=>{ d2.state.tab = el.dataset.tab })\n  }\n}"}}}}}}}},{"_id":"6a3448a6cc914ec4c5f41f8b","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"tictactoe","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n    .wrap{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:20px;width:100%;height:100%;box-sizing:border-box;padding:24px;font-family:system-ui,-apple-system,sans-serif;background:radial-gradient(circle at 30% 20%,#2a2150,#15101f)}\n    .title{font-size:26px;font-weight:800;color:#fff;letter-spacing:.5px;margin:0}\n    .status{font-size:16px;font-weight:600;color:#c9c2ff;min-height:22px}\n    .board{display:grid;grid-template-columns:repeat(3,1fr);grid-template-rows:repeat(3,1fr);gap:10px;width:min(340px,80vmin);aspect-ratio:1/1}\n    .cell{display:flex;align-items:center;justify-content:center;background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.1);border-radius:16px;font-size:clamp(32px,12vmin,64px);font-weight:900;cursor:pointer;transition:transform .12s,background .2s;user-select:none}\n    .cell:hover{background:rgba(255,255,255,.1);transform:translateY(-2px)}\n    .cell[data-v=\"X\"]{color:#5ee0c4}\n    .cell[data-v=\"O\"]{color:#ff8fab}\n    .cell[data-win]{background:rgba(124,77,255,.35);border-color:#7c4dff}\n    .reset{padding:11px 26px;border:0;border-radius:12px;background:#7c4dff;color:#fff;font-size:15px;font-weight:700;cursor:pointer;transition:opacity .2s}\n    .reset:hover{opacity:.85}\n  `,\n  render(d2){\n    const b = d2.state.board || ['','','','','','','','','']\n    const turn = d2.state.turn || 'X'\n    const winner = d2.state.winner || null\n    const line = d2.state.line || []\n    let status\n    if (winner === 'draw') status = 'Deu velha! Empate 🤝'\n    else if (winner) status = `Jogador ${winner} venceu! 🎉`\n    else status = `Vez do jogador ${turn}`\n    const cells = b.map((v,i)=>{\n      const win = line.includes(i) ? 'data-win' : ''\n      return `<div class=\"cell\" data-key=\"${i}\" data-i=\"${i}\" data-v=\"${v}\" ${win}>${v}</div>`\n    }).join('')\n    return `<div class=\"wrap\">\n      <h1 class=\"title\">Jogo da Velha</h1>\n      <div class=\"status\">${status}</div>\n      <div class=\"board\">${cells}</div>\n      <button class=\"reset\">Reiniciar</button>\n    </div>`\n  },\n  mounted(d2){\n    const LINES=[[0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[2,5,8],[0,4,8],[2,4,6]]\n    const check=(b)=>{\n      for(const l of LINES){const [a,c,d]=l; if(b[a]&&b[a]===b[c]&&b[a]===b[d]) return {w:b[a],line:l}}\n      if(b.every(x=>x)) return {w:'draw',line:[]}\n      return null\n    }\n    d2.on('.cell','click',(e,el)=>{\n      if(d2.state.winner) return\n      const i=+el.dataset.i\n      const b=[...(d2.state.board||['','','','','','','','',''])]\n      if(b[i]) return\n      const turn=d2.state.turn||'X'\n      b[i]=turn\n      const res=check(b)\n      d2.setState({board:b, turn: turn==='X'?'O':'X', winner: res?res.w:null, line: res?res.line:[]})\n    })\n    d2.on('.reset','click',()=>{\n      d2.setState({board:['','','','','','','','',''], turn:'X', winner:null, line:[]})\n    })\n  },\n}"}}}}}}}},{"_id":"6a34af10dbb7889ef4ccaaab","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"pepper-ranking","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n  *{box-sizing:border-box}\n  .root{width:100%;height:100%;overflow:auto;background:radial-gradient(1200px 600px at 80% -10%,#3a0a0a,#160404 60%);font-family:'Segoe UI',system-ui,sans-serif;color:#fff;padding:28px 24px}\n  .head{display:flex;align-items:flex-end;justify-content:space-between;flex-wrap:wrap;gap:16px;margin-bottom:6px}\n  .title{font-size:30px;font-weight:900;letter-spacing:-.5px;line-height:1.05}\n  .title small{display:block;font-size:13px;font-weight:600;color:#ff9b7a;letter-spacing:.5px;margin-top:6px;text-transform:uppercase}\n  .ctrls{display:flex;gap:8px;flex-wrap:wrap}\n  .btn{border:1px solid rgba(255,255,255,.18);background:rgba(255,255,255,.06);color:#fff;font-size:12px;font-weight:700;padding:8px 13px;border-radius:999px;cursor:pointer;transition:.15s}\n  .btn:hover{background:rgba(255,255,255,.13)}\n  .btn[data-on]{background:#ff5a36;border-color:#ff5a36;color:#fff;box-shadow:0 4px 16px rgba(255,90,54,.4)}\n  .list{display:flex;flex-direction:column;gap:12px;margin-top:22px}\n  .card{display:flex;align-items:center;gap:16px;background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.09);border-radius:16px;padding:14px 18px;cursor:pointer;transition:.18s;backdrop-filter:blur(6px)}\n  .card:hover{transform:translateX(4px);background:rgba(255,255,255,.09);border-color:rgba(255,120,80,.4)}\n  .rank{font-size:26px;font-weight:900;width:46px;text-align:center;color:#ff7a55;flex:none}\n  .rank.top{color:#ffd23f;text-shadow:0 0 18px rgba(255,210,63,.5)}\n  .body{flex:1;min-width:0}\n  .name{font-size:17px;font-weight:800;display:flex;align-items:center;gap:8px;flex-wrap:wrap}\n  .origin{font-size:11px;font-weight:600;color:#ffb59c;background:rgba(255,90,54,.15);padding:2px 8px;border-radius:6px}\n  .barwrap{height:9px;background:rgba(255,255,255,.08);border-radius:999px;margin-top:9px;overflow:hidden}\n  .bar{height:100%;border-radius:999px;background:linear-gradient(90deg,#ffd23f,#ff8a00,#ff3b1d,#b00000);transition:width .6s cubic-bezier(.2,.8,.2,1)}\n  .shu{font-size:13px;font-weight:800;text-align:right;flex:none;width:130px}\n  .shu small{display:block;font-size:10px;font-weight:600;color:#ffb59c;margin-top:2px}\n  .detail{font-size:12px;color:#e7c7bd;margin-top:8px;line-height:1.45;display:none}\n  .card[data-open] .detail{display:block}\n  .foot{margin-top:24px;font-size:11px;color:#a88;text-align:center}\n  `,\n  render(d2){\n    const peppers = [\n      {n:'Pepper X',o:'EUA',shu:2693000,d:'Recordista mundial (Guinness 2023), criada por Ed Currie. Ardência tão extrema que provadores relataram cãibras de horas.'},\n      {n:'Carolina Reaper',o:'EUA',shu:2200000,d:'Recordista anterior. Sabor frutado seguido de uma onda de fogo brutal. A pimenta \"celebridade\" dos desafios de YouTube.'},\n      {n:'Trinidad Moruga Scorpion',o:'Trinidad',shu:2000000,d:'A ardência cresce em ondas e demora a chegar — depois não te larga.'},\n      {n:'7 Pot Douglah',o:'Trinidad',shu:1850000,d:'Casca marrom-chocolate, sabor rico. Uma das mais saborosas entre as super-hots.'},\n      {n:'7 Pot Primo',o:'EUA/Trinidad',shu:1470000,d:'Tem uma \"caudinha\" característica. Híbrida criada por Troy Primeaux.'},\n      {n:'Naga Viper',o:'Reino Unido',shu:1382000,d:'Híbrida instável de três pimentas. Já foi recordista em 2011.'},\n      {n:'Trinidad Scorpion Butch T',o:'Trinidad',shu:1463000,d:'Recordista em 2011. Recomenda-se luvas e máscara para manusear.'},\n      {n:'Naga Morich',o:'Bangladesh',shu:1500000,d:'\"Pimenta-cobra\". Prima da Bhut Jolokia, intensamente aromática.'},\n      {n:'Bhut Jolokia (Ghost Pepper)',o:'Índia',shu:1041427,d:'A lendária \"pimenta-fantasma\". Primeira a passar de 1 milhão de SHU em 2007.'},\n      {n:'7 Pot Barrackpore',o:'Trinidad',shu:1000000,d:'Diz a lenda que uma só tempera 7 panelas de ensopado.'},\n    ]\n    const sortBy = d2.state.sort || 'shu'\n    const rows = [...peppers].map((p,i)=>({...p,_i:i}))\n    if(sortBy==='shu') rows.sort((a,b)=>b.shu-a.shu)\n    else if(sortBy==='name') rows.sort((a,b)=>a.n.localeCompare(b.n))\n    else if(sortBy==='origin') rows.sort((a,b)=>a.o.localeCompare(b.o)||b.shu-a.shu)\n    const max = Math.max(...peppers.map(p=>p.shu))\n    const open = d2.state.open||{}\n    const cards = rows.map((p,idx)=>{\n      const rank = sortBy==='shu'? idx+1 : peppers.slice().sort((a,b)=>b.shu-a.shu).findIndex(x=>x.n===p.n)+1\n      const w = (p.shu/max*100).toFixed(1)\n      return `<div class=\"card\" data-id=\"${p.n}\" ${open[p.n]?'data-open':''}>\n        <div class=\"rank ${rank<=3?'top':''}\">${rank<=3?['🥇','🥈','🥉'][rank-1]:'#'+rank}</div>\n        <div class=\"body\">\n          <div class=\"name\">${p.n} <span class=\"origin\">${p.o}</span></div>\n          <div class=\"barwrap\"><div class=\"bar\" style=\"width:${w}%\"></div></div>\n          <div class=\"detail\">${p.d}</div>\n        </div>\n        <div class=\"shu\">${d2.fmt.number(p.shu)}<small>SHU</small></div>\n      </div>`\n    }).join('')\n    return `<div class=\"root\">\n      <div class=\"head\">\n        <div class=\"title\">🌶️ As 10 pimentas mais fortes do mundo<small>Ranking por Scoville (SHU) · clique num card pra detalhes</small></div>\n        <div class=\"ctrls\">\n          <button class=\"btn\" data-sort=\"shu\" ${sortBy==='shu'?'data-on':''}>🔥 Ardência</button>\n          <button class=\"btn\" data-sort=\"name\" ${sortBy==='name'?'data-on':''}>🔤 Nome</button>\n          <button class=\"btn\" data-sort=\"origin\" ${sortBy==='origin'?'data-on':''}>🌍 Origem</button>\n        </div>\n      </div>\n      <div class=\"list\">${cards}</div>\n      <div class=\"foot\">Para comparar: um jalapeño tem ~5.000 SHU. A Pepper X é mais de 500× mais forte.</div>\n    </div>`\n  },\n  mounted(d2){\n    d2.on('.btn','click',(e,el)=>{ d2.state.sort = el.dataset.sort })\n    d2.on('.card','click',(e,el)=>{\n      const id = el.dataset.id, open = {...(d2.state.open||{})}\n      open[id] = !open[id]; d2.state.open = open\n    })\n  },\n}"}}}}}}}},{"_id":"6a34bf05e3dcf78ce1334ae8","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"checkin","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n    *{box-sizing:border-box}\n    .app{width:100%;height:100%;display:flex;flex-direction:column;font-family:system-ui,-apple-system,sans-serif;background:#0f1117;color:#e8eaed;overflow:hidden}\n    .head{padding:20px 24px 16px;flex:0 0 auto}\n    .title{font-size:22px;font-weight:800;letter-spacing:-.01em}\n    .sub{font-size:13px;color:#8a909c;margin-top:2px}\n    .stats{display:flex;gap:10px;margin-top:16px}\n    .stat{flex:1;background:#181b24;border:1px solid #232734;border-radius:12px;padding:12px 14px}\n    .stat .n{font-size:24px;font-weight:800}\n    .stat .l{font-size:11px;color:#8a909c;text-transform:uppercase;letter-spacing:.05em;margin-top:2px}\n    .stat.in .n{color:#3ed47e}\n    .search{margin:14px 24px 0;flex:0 0 auto}\n    .search input{width:100%;padding:12px 14px;border-radius:10px;border:1px solid #232734;background:#181b24;color:#e8eaed;font-size:15px;outline:none}\n    .search input:focus{border-color:#3b82f6}\n    .list{flex:1;overflow:auto;padding:12px 24px 24px;display:flex;flex-direction:column;gap:8px}\n    .row{display:flex;align-items:center;gap:12px;padding:12px 14px;background:#181b24;border:1px solid #232734;border-radius:12px;transition:border-color .15s}\n    .row.done{background:#13251a;border-color:#1f7a47}\n    .avatar{width:40px;height:40px;border-radius:50%;background:#2a2f3d;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:15px;color:#aeb4c0;flex:0 0 auto}\n    .row.done .avatar{background:#1f7a47;color:#fff}\n    .info{flex:1;min-width:0}\n    .nm{font-size:15px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n    .em{font-size:12px;color:#8a909c;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n    .when{font-size:11px;color:#3ed47e;margin-top:2px}\n    .btn{flex:0 0 auto;padding:9px 16px;border-radius:9px;border:0;font-size:13px;font-weight:700;cursor:pointer;transition:transform .1s}\n    .btn:active{transform:scale(.95)}\n    .btn.go{background:#3b82f6;color:#fff}\n    .btn.undo{background:transparent;color:#8a909c;border:1px solid #2a2f3d}\n    .empty{text-align:center;color:#8a909c;padding:40px;font-size:14px}\n  `,\n  render(d2){\n    const ds = d2.data('guests')\n    if (ds.loading) return `<div class=\"app\"><div class=\"empty\">Carregando…</div></div>`\n    const all = ds.records()\n    const q = (d2.state.q || '').toLowerCase().trim()\n    const rows = q ? all.filter(r => (r.name||'').toLowerCase().includes(q) || (r.email||'').toLowerCase().includes(q)) : all\n    const total = all.length\n    const inCount = all.filter(r => r.checkedIn).length\n    const fmt = (d) => d ? d2.fmt.time(d) : ''\n    const list = rows.length ? rows.map(r => `\n      <div class=\"row ${r.checkedIn?'done':''}\" data-key=\"${r._id}\">\n        <div class=\"avatar\">${d2.fmt.initials(r.name||'?',2)}</div>\n        <div class=\"info\">\n          <div class=\"nm\">${(r.name||'').replace(/</g,'&lt;')}</div>\n          <div class=\"em\">${(r.email||'').replace(/</g,'&lt;')}</div>\n          ${r.checkedIn?`<div class=\"when\">✓ Check-in ${fmt(r.checkedInAt)}</div>`:''}\n        </div>\n        ${r.checkedIn\n          ? `<button class=\"btn undo\" data-undo=\"${r._id}\">Desfazer</button>`\n          : `<button class=\"btn go\" data-go=\"${r._id}\">Check-in</button>`}\n      </div>`).join('') : `<div class=\"empty\">Nenhum convidado encontrado</div>`\n    return `<div class=\"app\">\n      <div class=\"head\">\n        <div class=\"title\">Controle de Entrada</div>\n        <div class=\"sub\">Marque a presença dos convidados</div>\n        <div class=\"stats\">\n          <div class=\"stat in\"><div class=\"n\">${inCount}</div><div class=\"l\">Presentes</div></div>\n          <div class=\"stat\"><div class=\"n\">${total-inCount}</div><div class=\"l\">Faltam</div></div>\n          <div class=\"stat\"><div class=\"n\">${total}</div><div class=\"l\">Total</div></div>\n        </div>\n      </div>\n      <div class=\"search\"><input class=\"q\" placeholder=\"Buscar por nome ou e-mail…\" value=\"${(d2.state.q||'').replace(/\"/g,'&quot;')}\"/></div>\n      <div class=\"list\">${list}</div>\n    </div>`\n  },\n  mounted(d2){\n    d2.on('.q','input',(e,el)=>{ d2.state.q = el.value })\n    d2.on('.go','click',async(e,el)=>{\n      const ds = d2.data('guests'), rec = ds.records().find(r=>r._id===el.dataset.go)\n      if(rec) await ds.update({...rec, checkedIn:true, checkedInAt:new Date().toISOString()})\n    })\n    d2.on('.undo','click',async(e,el)=>{\n      const ds = d2.data('guests'), rec = ds.records().find(r=>r._id===el.dataset.undo)\n      if(rec) await ds.update({...rec, checkedIn:false, checkedInAt:null})\n    })\n  },\n}"}},"guests":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"guests"}}}}}}}}}},{"_id":"6a34bf6cef1674768dcd4ad5","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"hg0OaFlRtH6ie-oJApRHS","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n    .root{display:flex;flex-direction:column;height:100%;box-sizing:border-box;font:15px -apple-system,system-ui,sans-serif;background:#0f1115;color:#e8eaed}\n    .head{padding:16px 18px 12px;border-bottom:1px solid #232733}\n    .title{font-size:20px;font-weight:800;letter-spacing:-.01em}\n    .counts{display:flex;gap:8px;margin-top:12px}\n    .pill{flex:1;background:#171a21;border:1px solid #232733;border-radius:12px;padding:10px 12px}\n    .pill .n{font-size:24px;font-weight:800;line-height:1}\n    .pill .l{font-size:11px;color:#8b93a7;text-transform:uppercase;letter-spacing:.05em;margin-top:4px}\n    .pill.on .n{color:#3ed47e}\n    .form{display:flex;gap:8px;padding:14px 18px;border-bottom:1px solid #232733;flex-wrap:wrap}\n    .in{flex:1;min-width:120px;padding:13px 14px;border:1px solid #2c313d;border-radius:10px;background:#171a21;color:#fff;font-size:16px;outline:0}\n    .in:focus{border-color:#5b8cff}\n    .add{padding:13px 20px;border:0;border-radius:10px;background:#5b8cff;color:#fff;font-size:16px;font-weight:700;cursor:pointer;white-space:nowrap}\n    .add:disabled{opacity:.5;cursor:default}\n    .search{padding:10px 18px}\n    .search input{width:100%;box-sizing:border-box;padding:11px 14px;border:1px solid #2c313d;border-radius:10px;background:#13151b;color:#fff;font-size:15px;outline:0}\n    .list{flex:1;overflow:auto;padding:0 12px 12px}\n    .row{display:flex;align-items:center;gap:12px;padding:12px 10px;border-radius:12px}\n    .row+.row{border-top:1px solid #1c2029}\n    .ava{width:40px;height:40px;border-radius:50%;flex:none;display:flex;align-items:center;justify-content:center;font-weight:800;font-size:15px;background:#2a2f3c;color:#cdd3e0}\n    .row.in .ava{background:#143a25;color:#3ed47e}\n    .info{flex:1;min-width:0}\n    .nm{font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n    .sub{font-size:12px;color:#8b93a7;margin-top:2px}\n    .btn{padding:9px 16px;border-radius:9px;font-size:14px;font-weight:700;cursor:pointer;white-space:nowrap;border:1px solid transparent}\n    .btn.ci{background:#3ed47e;color:#06241a}\n    .btn.undo{background:transparent;border-color:#2c313d;color:#8b93a7}\n    .empty{text-align:center;color:#6b7280;padding:40px 20px;font-size:14px}\n  `,\n  render(d2){\n    const ds = d2.data('dataset')\n    if (ds.loading) return `<div class=\"root\"><div class=\"empty\">Carregando…</div></div>`\n    const q = (d2.state.q || '').toLowerCase()\n    let rows = ds.records()\n    const total = rows.length\n    const present = rows.filter(r => r.checkedIn).length\n    if (q) rows = rows.filter(r => (r.name||'').toLowerCase().includes(q) || (r.email||'').toLowerCase().includes(q))\n    rows = [...rows].sort((a,b)=> (b._createdAt||'').localeCompare?.(a._createdAt||'') || 0)\n    const esc = s => (s==null?'':String(s)).replace(/[<>&\"]/g, c=>({'<':'&lt;','>':'&gt;','&':'&amp;','\"':'&quot;'}[c]))\n    const list = rows.length ? rows.map(r => {\n      const initial = d2.fmt.initials(r.name || '?', 1)\n      const hora = r.checkedInAt ? d2.fmt.time(r.checkedInAt) : ''\n      return `<div class=\"row ${r.checkedIn?'in':''}\" data-key=\"${r._id}\">\n        <div class=\"ava\">${esc(initial)}</div>\n        <div class=\"info\">\n          <div class=\"nm\">${esc(r.name)||'(sem nome)'}</div>\n          <div class=\"sub\">${r.checkedIn ? '✓ presente · '+esc(hora) : (esc(r.email)||'aguardando')}</div>\n        </div>\n        ${r.checkedIn\n          ? `<button class=\"btn undo\" data-undo=\"${r._id}\">Desfazer</button>`\n          : `<button class=\"btn ci\" data-ci=\"${r._id}\">Check-in</button>`}\n      </div>`\n    }).join('') : `<div class=\"empty\">${q?'Ninguém encontrado':'Cadastre a primeira pessoa acima'}</div>`\n    return `<div class=\"root\">\n      <div class=\"head\">\n        <div class=\"title\">Check-in do Evento</div>\n        <div class=\"counts\">\n          <div class=\"pill on\"><div class=\"n\">${present}</div><div class=\"l\">Presentes</div></div>\n          <div class=\"pill\"><div class=\"n\">${total-present}</div><div class=\"l\">Faltam</div></div>\n          <div class=\"pill\"><div class=\"n\">${total}</div><div class=\"l\">Total</div></div>\n        </div>\n      </div>\n      <div class=\"form\">\n        <input class=\"in\" id=\"nm\" placeholder=\"Nome\" value=\"${esc(d2.state.nm)}\" autocomplete=\"off\"/>\n        <input class=\"in\" id=\"em\" placeholder=\"E-mail (opcional)\" value=\"${esc(d2.state.em)}\" autocomplete=\"off\"/>\n        <button class=\"add\" id=\"add\" ${ds.mutating?'disabled':''}>${ds.mutating?'…':'Cadastrar + check-in'}</button>\n      </div>\n      <div class=\"search\"><input id=\"q\" placeholder=\"Buscar nome ou e-mail…\" value=\"${esc(d2.state.q)}\"/></div>\n      <div class=\"list\">${list}</div>\n    </div>`\n  },\n  mounted(d2){\n    const ds = d2.data('dataset')\n    const add = async () => {\n      const nm = (d2.$('#nm').value||'').trim()\n      if (!nm) { d2.$('#nm').focus(); return }\n      const em = (d2.$('#em').value||'').trim()\n      d2.state.nm = ''; d2.state.em = ''\n      await ds.create({ name: nm, email: em, checkedIn: true, checkedInAt: new Date().toISOString() })\n      const f = d2.$('#nm'); if (f) f.focus()\n    }\n    d2.on('#add', 'click', add)\n    d2.on('#nm', 'keydown', e => { if (e.key==='Enter') add() })\n    d2.on('#em', 'keydown', e => { if (e.key==='Enter') add() })\n    d2.on('#nm', 'input', (e,el)=> d2.state.nm = el.value)\n    d2.on('#em', 'input', (e,el)=> d2.state.em = el.value)\n    d2.on('#q', 'input', (e,el)=> d2.state.q = el.value)\n    d2.on('[data-ci]', 'click', async (e,el)=>{\n      const r = ds.records().find(x=>x._id===el.dataset.ci)\n      if (r) await ds.update({ ...r, checkedIn:true, checkedInAt:new Date().toISOString() })\n    })\n    d2.on('[data-undo]', 'click', async (e,el)=>{\n      const r = ds.records().find(x=>x._id===el.dataset.undo)\n      if (r) await ds.update({ ...r, checkedIn:false, checkedInAt:null })\n    })\n  },\n}"}},"dataset":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"dataset"}}}}}}}}}},{"_id":"6a34c02491e2b9586702a429","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"guests-grid","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n    :host, .root { width:100%; height:100%; }\n    .root { display:flex; flex-direction:column; height:100%; font:13px -apple-system,Segoe UI,Roboto,sans-serif; background:#fff; color:#1a1a1a; box-sizing:border-box; }\n    .toolbar { display:flex; align-items:center; gap:10px; padding:10px 14px; border-bottom:1px solid #ececf1; flex:0 0 auto; }\n    .toolbar .title { font-weight:700; font-size:14px; }\n    .toolbar .count { color:#888; font-size:12px; }\n    .toolbar .spacer { flex:1; }\n    .search { padding:7px 10px; border:1px solid #ddd; border-radius:8px; font-size:13px; width:220px; outline:none; }\n    .search:focus { border-color:#7c4dff; }\n    .btn { padding:7px 13px; border:0; border-radius:8px; background:#7c4dff; color:#fff; font-size:13px; font-weight:600; cursor:pointer; }\n    .btn.ghost { background:#f1f1f4; color:#333; }\n    .scroll { flex:1; overflow:auto; }\n    table { border-collapse:separate; border-spacing:0; width:100%; min-width:760px; }\n    th { position:sticky; top:0; z-index:2; background:#fafafc; text-align:left; font-size:11px; text-transform:uppercase; letter-spacing:.04em; color:#999; padding:8px 10px; border-bottom:1px solid #ececf1; white-space:nowrap; }\n    td { padding:0; border-bottom:1px solid #f3f3f6; vertical-align:middle; }\n    td.cell input, td.cell select { width:100%; box-sizing:border-box; border:0; padding:9px 10px; font:13px inherit; background:transparent; outline:none; }\n    td.cell input:focus, td.cell select:focus { background:#f6f2ff; box-shadow:inset 0 0 0 2px #7c4dff; }\n    td.checkin { padding:6px 10px; white-space:nowrap; }\n    .pill { display:inline-flex; align-items:center; gap:5px; font-size:11px; font-weight:700; padding:3px 9px; border-radius:99px; }\n    .pill.in { background:#e7f8ee; color:#1a8a4f; }\n    .pill.out { background:#fdecec; color:#c0392b; }\n    .row:hover td { background:#fcfcfe; }\n    .saving { font-size:11px; color:#7c4dff; padding:0 14px 6px; flex:0 0 auto; min-height:14px; }\n    .empty { padding:30px; text-align:center; color:#999; }\n    .num { max-width:90px; }\n  `,\n  render(d2){\n    const ds = d2.data();\n    if (!ds || ds.loading) return `<div class=\"root\"><div class=\"empty\">Carregando…</div></div>`;\n    const q = (d2.state.q || '').toLowerCase();\n    let rows = ds.records();\n    if (q) rows = rows.filter(r =>\n      (r.name||'').toLowerCase().includes(q) ||\n      (r.email||'').toLowerCase().includes(q) ||\n      (r.company||'').toLowerCase().includes(q));\n    const cols = [\n      { k:'name', t:'Nome', w:'160px' },\n      { k:'email', t:'E-mail', w:'190px' },\n      { k:'phone', t:'Telefone', w:'130px' },\n      { k:'company', t:'Empresa', w:'150px' },\n      { k:'table', t:'Mesa', w:'80px' },\n      { k:'ticket', t:'Ingresso', w:'120px' },\n      { k:'plusOnes', t:'Acomp.', w:'70px', num:true },\n      { k:'notes', t:'Obs.', w:'200px' },\n    ];\n    const head = cols.map(c => `<th style=\"min-width:${c.w}\">${c.t}</th>`).join('') + `<th style=\"min-width:120px\">Presença</th>`;\n    const esc = s => (s==null?'':String(s)).replace(/\"/g,'&quot;');\n    const body = rows.length ? rows.map(r => {\n      const tds = cols.map(c => {\n        const v = esc(r[c.k]);\n        return `<td class=\"cell ${c.num?'num':''}\"><input data-id=\"${r._id}\" data-field=\"${c.k}\" ${c.num?'type=\"number\" min=\"0\"':''} value=\"${v}\" placeholder=\"—\"/></td>`;\n      }).join('');\n      const pill = r.checkedIn\n        ? `<span class=\"pill in\">● Presente</span>`\n        : `<span class=\"pill out\">○ Aguardando</span>`;\n      return `<tr class=\"row\" data-key=\"${r._id}\">${tds}<td class=\"checkin\">${pill}</td></tr>`;\n    }).join('') : `<tr><td colspan=\"${cols.length+1}\"><div class=\"empty\">Nenhum convidado${q?' encontrado':''}.</div></td></tr>`;\n    return `<div class=\"root\">\n      <div class=\"toolbar\">\n        <span class=\"title\">Planilha de Convidados</span>\n        <span class=\"count\">${rows.length} ${rows.length===1?'linha':'linhas'}</span>\n        <span class=\"spacer\"></span>\n        <input class=\"search\" placeholder=\"Buscar nome, e-mail, empresa…\" value=\"${esc(d2.state.q)}\"/>\n        <button class=\"btn add\">+ Nova linha</button>\n      </div>\n      <div class=\"scroll\"><table><thead><tr>${head}</tr></thead><tbody>${body}</tbody></table></div>\n      <div class=\"saving\">${d2.state.savingMsg || ''}</div>\n    </div>`;\n  },\n  mounted(d2){\n    const ds = d2.data();\n    d2.on('.search', 'input', (e, el) => { d2.state.q = el.value; });\n    // Save a single cell on blur (commit) — stages by id, then persists.\n    const commit = async (el) => {\n      const id = el.dataset.id, field = el.dataset.field;\n      const rec = ds.records().find(r => r._id === id);\n      if (!rec) return;\n      let val = el.value;\n      if (el.type === 'number') val = val === '' ? null : Number(val);\n      if ((rec[field] ?? '') === (val ?? '')) return; // no change\n      d2.state.savingMsg = 'Salvando…';\n      try {\n        await ds.update({ ...rec, [field]: val });\n        d2.state.savingMsg = 'Salvo ✓';\n        setTimeout(() => { if (d2.state.savingMsg === 'Salvo ✓') d2.state.savingMsg = ''; }, 1200);\n      } catch (err) {\n        d2.state.savingMsg = 'Erro ao salvar';\n      }\n    };\n    d2.on('td.cell input', 'blur', (e, el) => commit(el));\n    d2.on('td.cell input', 'keydown', (e, el) => { if (e.key === 'Enter') el.blur(); });\n    d2.on('.add', 'click', async () => {\n      d2.state.savingMsg = 'Criando linha…';\n      try {\n        await ds.create({ name:'', checkedIn:false });\n        d2.state.savingMsg = '';\n      } catch (err) { d2.state.savingMsg = 'Erro ao criar'; }\n    });\n  },\n}"}},"dataset":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"dataset"}}}}}}}}}},{"_id":"6a34c04f1e657fd727b17810","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"CHnn8zfu0KwfX0q9AmoDD","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n    .ss{display:flex;flex-direction:column;height:100%;width:100%;box-sizing:border-box;background:#fff;font:13px -apple-system,Segoe UI,Roboto,sans-serif;color:#1a1a1a;overflow:hidden}\n    .hd{display:flex;align-items:center;gap:10px;padding:12px 16px;border-bottom:1px solid #e8e8ec;flex:0 0 auto}\n    .hd h1{font-size:15px;font-weight:700;margin:0}\n    .cnt{font-size:12px;color:#888}\n    .spacer{flex:1}\n    .add{padding:7px 14px;border:0;border-radius:8px;background:#16a34a;color:#fff;font-weight:600;cursor:pointer;font-size:13px}\n    .add:hover{background:#15803d}\n    .scroll{flex:1;overflow:auto}\n    table{border-collapse:collapse;width:100%;min-width:760px}\n    th{position:sticky;top:0;z-index:2;background:#f7f7f9;text-align:left;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:#666;padding:9px 10px;border-bottom:2px solid #e3e3e8;border-right:1px solid #eee;white-space:nowrap}\n    td{padding:0;border-bottom:1px solid #f0f0f3;border-right:1px solid #f3f3f6;vertical-align:middle}\n    td:last-child,th:last-child{border-right:0}\n    tr:hover td{background:#fafafe}\n    .cell{width:100%;box-sizing:border-box;border:0;background:transparent;padding:9px 10px;font:13px inherit;color:inherit;outline:0}\n    .cell:focus{background:#eef4ff;box-shadow:inset 0 0 0 2px #2563eb}\n    .num{text-align:right}\n    .chk{display:flex;align-items:center;justify-content:center;gap:6px;padding:6px}\n    .chk input{width:17px;height:17px;cursor:pointer;accent-color:#16a34a}\n    .pill{display:inline-block;padding:2px 8px;border-radius:99px;font-size:11px;font-weight:600}\n    .pin{background:#dcfce7;color:#15803d}\n    .pout{background:#f1f1f4;color:#999}\n    .rownum{width:34px;text-align:center;color:#bbb;font-size:11px;user-select:none}\n    .empty{padding:40px;text-align:center;color:#999}\n    .saving{font-size:11px;color:#2563eb}\n  `,\n  render(d2){\n    const ds = d2.data('sheet')\n    if (ds.loading) return `<div class=\"ss\"><div class=\"empty\">Carregando…</div></div>`\n    const rows = ds.records()\n    const cols = [\n      {k:'name',  t:'Nome',          ty:'text'},\n      {k:'email', t:'E-mail',        ty:'text'},\n      {k:'phone', t:'Telefone',      ty:'text'},\n      {k:'table', t:'Mesa',          ty:'text'},\n      {k:'ticket',t:'Ingresso',      ty:'text'},\n      {k:'companions',t:'Acomp.',    ty:'num'},\n      {k:'notes', t:'Observações',   ty:'text'},\n    ]\n    const esc = s => (s==null?'':String(s)).replace(/\"/g,'&quot;').replace(/</g,'&lt;')\n    const present = rows.filter(r=>r.checkedIn).length\n    const body = rows.length ? rows.map((r,i)=>`\n      <tr data-key=\"${r._id}\" data-id=\"${r._id}\">\n        <td class=\"rownum\">${i+1}</td>\n        ${cols.map(c=>`\n          <td>\n            <input class=\"cell ${c.ty==='num'?'num':''}\" data-id=\"${r._id}\" data-field=\"${c.k}\"\n              ${c.ty==='num'?'type=\"number\" min=\"0\"':''}\n              value=\"${esc(r[c.k])}\" placeholder=\"—\"/>\n          </td>`).join('')}\n        <td>\n          <label class=\"chk\">\n            <input type=\"checkbox\" data-id=\"${r._id}\" data-check ${r.checkedIn?'checked':''}/>\n            <span class=\"pill ${r.checkedIn?'pin':'pout'}\">${r.checkedIn?'Presente':'Aguardando'}</span>\n          </label>\n        </td>\n      </tr>`).join('') : `<tr><td colspan=\"${cols.length+2}\" class=\"empty\">Nenhum convidado ainda. Clique em “+ Linha”.</td></tr>`\n    return `<div class=\"ss\">\n      <div class=\"hd\">\n        <h1>Convidados</h1>\n        <span class=\"cnt\">${rows.length} no total · ${present} presentes</span>\n        ${ds.mutating?'<span class=\"saving\">salvando…</span>':''}\n        <span class=\"spacer\"></span>\n        <button class=\"add\">+ Linha</button>\n      </div>\n      <div class=\"scroll\">\n        <table>\n          <thead><tr><th class=\"rownum\">#</th>${cols.map(c=>`<th>${c.t}</th>`).join('')}<th>Check-in</th></tr></thead>\n          <tbody>${body}</tbody>\n        </table>\n      </div>\n    </div>`\n  },\n  mounted(d2){\n    const ds = d2.data('sheet')\n    // Persist a single cell edit straight to the table (check-in reads the same table → auto-sync)\n    const saveCell = async (id, field, value, isNum) => {\n      const rec = ds.records().find(r => r._id === id)\n      if (!rec) return\n      const v = isNum ? (value === '' ? null : Number(value)) : value\n      await ds.update({ ...rec, [field]: v })\n    }\n    d2.on('.cell', 'change', (e, el) => {\n      saveCell(el.dataset.id, el.dataset.field, el.value, el.type === 'number')\n    })\n    d2.on('[data-check]', 'change', async (e, el) => {\n      const rec = ds.records().find(r => r._id === el.dataset.id)\n      if (!rec) return\n      const on = el.checked\n      await ds.update({ ...rec, checkedIn: on, checkedInAt: on ? new Date().toISOString() : null })\n    })\n    d2.on('.add', 'click', async () => {\n      await ds.create({ name: '', checkedIn: false })\n    })\n    // Live sync: pull rows the door check-in adds/changes\n    const iv = setInterval(() => { if (!ds.mutating) ds.refresh() }, 4000)\n    d2.onUnmount(() => clearInterval(iv))\n  },\n}"}},"sheet":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"sheet"}}}}}}}}}},{"_id":"6a34c05591e2b9586702a454","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"pKkUoh5m0iMbjvdg58YUb","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n    *{box-sizing:border-box}\n    .app{width:100%;height:100%;display:flex;flex-direction:column;font-family:system-ui,-apple-system,sans-serif;background:#0f1117;color:#e8eaed;overflow:hidden}\n    .head{padding:18px 22px 12px;flex:0 0 auto;display:flex;align-items:center;gap:16px;flex-wrap:wrap}\n    .title{font-size:20px;font-weight:800;letter-spacing:-.01em}\n    .sub{font-size:12px;color:#8a909c;margin-top:2px}\n    .spacer{flex:1}\n    .search input{width:240px;max-width:46vw;padding:9px 12px;border-radius:9px;border:1px solid #232734;background:#181b24;color:#e8eaed;font-size:14px;outline:none}\n    .search input:focus{border-color:#3b82f6}\n    .add{padding:9px 16px;border-radius:9px;border:0;background:#3b82f6;color:#fff;font-size:13px;font-weight:700;cursor:pointer}\n    .add:active{transform:scale(.96)}\n    .wrap{flex:1;overflow:auto;padding:0 22px 22px}\n    table{border-collapse:separate;border-spacing:0;width:100%;font-size:13px;min-width:760px}\n    th{position:sticky;top:0;z-index:2;background:#13161f;color:#8a909c;text-transform:uppercase;letter-spacing:.04em;font-size:10px;font-weight:700;text-align:left;padding:10px 10px;border-bottom:1px solid #232734}\n    td{padding:0;border-bottom:1px solid #1c2029;background:#181b24}\n    tr:hover td{background:#1c212c}\n    td input,td select{width:100%;padding:9px 10px;border:0;background:transparent;color:#e8eaed;font-size:13px;outline:none;font-family:inherit}\n    td input:focus,td select:focus{background:#0f1117;box-shadow:inset 0 0 0 1.5px #3b82f6}\n    td.center{text-align:center}\n    .chk{width:46px;text-align:center}\n    .chk input{width:18px;height:18px;accent-color:#3ed47e;cursor:pointer}\n    .del{width:40px;text-align:center}\n    .del button{background:transparent;border:0;color:#5a6172;cursor:pointer;font-size:15px;padding:8px}\n    .del button:hover{color:#ef4444}\n    .save{width:42px;text-align:center}\n    .dot{width:8px;height:8px;border-radius:50%;background:#3b82f6;display:inline-block;opacity:0;transition:opacity .2s}\n    tr.dirty .dot{opacity:1}\n    .empty{padding:40px;text-align:center;color:#8a909c}\n    .foot{flex:0 0 auto;padding:8px 22px;font-size:12px;color:#8a909c;border-top:1px solid #1c2029}\n  `,\n  render(d2){\n    const ds = d2.data('guests')\n    if (ds.loading) return `<div class=\"app\"><div class=\"empty\">Carregando…</div></div>`\n    const all = ds.records()\n    const q = (d2.state.q||'').toLowerCase().trim()\n    const rows = q ? all.filter(r => Object.values(r).some(v => (v==null?'':String(v)).toLowerCase().includes(q))) : all\n    const esc = s => (s==null?'':String(s)).replace(/\"/g,'&quot;').replace(/</g,'&lt;')\n    const body = rows.length ? rows.map(r => `\n      <tr data-key=\"${r._id}\" data-id=\"${r._id}\">\n        <td class=\"chk\"><input type=\"checkbox\" data-f=\"checkedIn\" ${r.checkedIn?'checked':''}/></td>\n        <td><input data-f=\"name\" value=\"${esc(r.name)}\" placeholder=\"Nome\"/></td>\n        <td><input data-f=\"email\" value=\"${esc(r.email)}\" placeholder=\"email@…\"/></td>\n        <td><input data-f=\"phone\" value=\"${esc(r.phone)}\" placeholder=\"(11) …\"/></td>\n        <td><input data-f=\"table\" value=\"${esc(r.table)}\" placeholder=\"—\"/></td>\n        <td><input data-f=\"ticket\" value=\"${esc(r.ticket)}\" placeholder=\"—\"/></td>\n        <td class=\"center\"><input data-f=\"companions\" type=\"number\" min=\"0\" value=\"${r.companions==null?'':r.companions}\" style=\"text-align:center\" placeholder=\"0\"/></td>\n        <td><input data-f=\"notes\" value=\"${esc(r.notes)}\" placeholder=\"—\"/></td>\n        <td class=\"save\"><span class=\"dot\"></span></td>\n        <td class=\"del\"><button data-del=\"${r._id}\" title=\"Remover\">✕</button></td>\n      </tr>`).join('') : `<tr><td colspan=\"10\"><div class=\"empty\">${q?'Nenhum resultado':'Sem convidados ainda — clique em “+ Adicionar linha”.'}</div></td></tr>`\n    return `<div class=\"app\">\n      <div class=\"head\">\n        <div><div class=\"title\">Planilha de Convidados</div><div class=\"sub\">Edite qualquer célula — salva sozinho</div></div>\n        <div class=\"spacer\"></div>\n        <div class=\"search\"><input class=\"q\" placeholder=\"Buscar em tudo…\" value=\"${(d2.state.q||'').replace(/\"/g,'&quot;')}\"/></div>\n        <button class=\"add\">+ Adicionar linha</button>\n      </div>\n      <div class=\"wrap\">\n        <table>\n          <thead><tr>\n            <th class=\"chk\">✓</th><th>Nome</th><th>E-mail</th><th>Telefone</th><th>Mesa</th><th>Ingresso</th><th class=\"center\">Acomp.</th><th>Observações</th><th></th><th></th>\n          </tr></thead>\n          <tbody>${body}</tbody>\n        </table>\n      </div>\n      <div class=\"foot\">${all.length} convidado(s) • ${all.filter(r=>r.checkedIn).length} presente(s)</div>\n    </div>`\n  },\n  mounted(d2){\n    const ds = () => d2.data('guests')\n    const markDirty = (tr) => tr && tr.classList.add('dirty')\n    const persist = async (id, patch) => {\n      const rec = ds().records().find(r=>r._id===id); if(!rec) return\n      const tr = d2.$(`tr[data-id=\"${id}\"]`)\n      await ds().update({...rec, ...patch})\n      if(tr) tr.classList.remove('dirty')\n    }\n    // text/number fields: mark dirty on input, persist on blur or Enter\n    d2.on('td input[data-f]','input',(e,el)=>{ if(el.type!=='checkbox') markDirty(el.closest('tr')) })\n    d2.on('td input[data-f]','blur',(e,el)=>{\n      if(el.type==='checkbox') return\n      const tr=el.closest('tr'), id=tr.dataset.id, f=el.dataset.f\n      let v = el.type==='number' ? (el.value===''?null:Number(el.value)) : el.value\n      persist(id,{[f]:v})\n    })\n    d2.on('td input[data-f]','keydown',(e,el)=>{ if(e.key==='Enter' && el.type!=='checkbox') el.blur() })\n    // checkbox: persist immediately + set time\n    d2.on('td input[data-f=\"checkedIn\"]','change',(e,el)=>{\n      const id=el.closest('tr').dataset.id, on=el.checked\n      persist(id,{checkedIn:on, checkedInAt: on?new Date().toISOString():null})\n    })\n    // search\n    d2.on('.q','input',(e,el)=>{ d2.state.q=el.value })\n    // add row\n    d2.on('.add','click',async()=>{ await ds().create({name:'', email:'', checkedIn:false}) })\n    // delete\n    d2.on('.del button','click',async(e,el)=>{\n      const rec = ds().records().find(r=>r._id===el.dataset.del); if(!rec) return\n      const ok = await d2.dialog.confirm(`Remover \"${rec.name||'esta linha'}\"?`)\n      if(ok) await ds().remove(rec)\n    })\n  },\n}"}},"guests":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"guests"}}}}}}}}}},{"_id":"6a353c891034b63f9a52ec08","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"nfsCdDAv1cVaM2HNENPpi","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `.frame-wrap{position:relative;width:100%;height:100%;background:#0b0b12;font:14px -apple-system,sans-serif;overflow:hidden}\n        iframe{width:100%;height:100%;border:0;display:block}\n        .fallback{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:14px;color:#e8e8f0;text-align:center;padding:40px;box-sizing:border-box;background:radial-gradient(circle at 50% 30%,#1a1430,#0b0b12)}\n        .fallback h2{margin:0;font-size:22px;font-weight:800}\n        .fallback p{margin:0;max-width:420px;color:#a9a9c0;line-height:1.5}\n        .fallback a{color:#fff;background:#7c4dff;padding:10px 18px;border-radius:10px;text-decoration:none;font-weight:600;margin-top:6px}\n        .bar{position:absolute;top:0;left:0;right:0;height:34px;background:#15151f;display:flex;align-items:center;gap:8px;padding:0 12px;z-index:2;border-bottom:1px solid #26263a}\n        .dot{width:10px;height:10px;border-radius:50%}\n        .url{flex:1;background:#0b0b12;color:#9a9ab0;font-size:12px;padding:4px 10px;border-radius:6px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n        .frame-area{position:absolute;top:34px;left:0;right:0;bottom:0}`,\n  render(d2){\n    const url = d2.param('url', 'https://hera.build')\n    return `<div class=\"frame-wrap\">\n      <div class=\"bar\">\n        <span class=\"dot\" style=\"background:#ff5f57\"></span>\n        <span class=\"dot\" style=\"background:#febc2e\"></span>\n        <span class=\"dot\" style=\"background:#28c840\"></span>\n        <span class=\"url\">${url}</span>\n      </div>\n      <div class=\"frame-area\">\n        <div class=\"fallback\" id=\"fb\">\n          <h2>O site bloqueia ser embutido</h2>\n          <p>O hera.build usa proteção anti-iframe (X-Frame-Options / CSP). Se você está vendo isto, é esse o motivo — não é erro meu.</p>\n          <a href=\"${url}\" target=\"_blank\" rel=\"noopener\">Abrir hera.build em nova aba</a>\n        </div>\n        <iframe id=\"ifr\" src=\"${url}\" referrerpolicy=\"no-referrer\"></iframe>\n      </div>\n    </div>`\n  },\n  mounted(d2){\n    const ifr = d2.$('#ifr'), fb = d2.$('#fb')\n    if (!ifr) return\n    ifr.addEventListener('load', () => { if (fb) fb.style.display = 'none' })\n  },\n}"}},"url":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"url"}}}}}}}}}},{"_id":"6a35402f19b6b46652cca33e","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"timer-widget","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n    .wrap{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:22px;height:100%;box-sizing:border-box;padding:28px;font-family:'SF Pro Display',-apple-system,system-ui,sans-serif;background:radial-gradient(120% 120% at 50% 0%,#1a1530 0%,#0e0b1c 60%,#080611 100%);color:#fff}\n    .ring-wrap{position:relative;width:260px;height:260px}\n    .ring-wrap svg{width:100%;height:100%;transform:rotate(-90deg)}\n    .track{fill:none;stroke:rgba(255,255,255,.08);stroke-width:12}\n    .prog{fill:none;stroke:url(#grad);stroke-width:12;stroke-linecap:round;transition:stroke-dashoffset .25s linear}\n    .center{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px}\n    .time{font-size:54px;font-weight:700;letter-spacing:.02em;font-variant-numeric:tabular-nums;color:#fff}\n    .time.done{color:#7cf0a8}\n    .sub{font-size:12px;text-transform:uppercase;letter-spacing:.18em;color:#9b91c4}\n    .presets{display:flex;gap:8px}\n    .preset{padding:7px 14px;border-radius:999px;border:1px solid rgba(255,255,255,.14);background:rgba(255,255,255,.04);color:#cfc7ec;font-size:13px;cursor:pointer;transition:all .15s}\n    .preset:hover{background:rgba(255,255,255,.1)}\n    .preset[data-on]{background:linear-gradient(135deg,#7c4dff,#b14dff);border-color:transparent;color:#fff}\n    .controls{display:flex;gap:14px;align-items:center}\n    .btn{width:58px;height:58px;border-radius:50%;border:0;display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:20px;transition:transform .12s,box-shadow .15s}\n    .btn:active{transform:scale(.92)}\n    .btn.main{width:74px;height:74px;background:linear-gradient(135deg,#7c4dff,#b14dff);color:#fff;box-shadow:0 10px 30px rgba(124,77,255,.45);font-size:26px}\n    .btn.ghost{background:rgba(255,255,255,.06);color:#cfc7ec;border:1px solid rgba(255,255,255,.12)}\n    .btn.ghost:hover{background:rgba(255,255,255,.12)}\n  `,\n  render(d2){\n    const total = d2.state.total ?? 300\n    const left = d2.state.left ?? total\n    const running = !!d2.state.running\n    const done = left <= 0\n    const mm = String(Math.floor(left/60)).padStart(2,'0')\n    const ss = String(left%60).padStart(2,'0')\n    const R = 116, C = 2*Math.PI*R\n    const frac = total>0 ? Math.max(0,Math.min(1,left/total)) : 0\n    const offset = C*(1-frac)\n    const presets = [\n      {label:'1m',v:60},{label:'3m',v:180},{label:'5m',v:300},{label:'10m',v:600},{label:'25m',v:1500}\n    ]\n    return `<div class=\"wrap\">\n      <div class=\"presets\">\n        ${presets.map(p=>`<button class=\"preset\" data-preset=\"${p.v}\" ${p.v===total?'data-on':''}>${p.label}</button>`).join('')}\n      </div>\n      <div class=\"ring-wrap\">\n        <svg viewBox=\"0 0 260 260\">\n          <defs><linearGradient id=\"grad\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\">\n            <stop offset=\"0%\" stop-color=\"#7c4dff\"/><stop offset=\"100%\" stop-color=\"#b14dff\"/>\n          </linearGradient></defs>\n          <circle class=\"track\" cx=\"130\" cy=\"130\" r=\"${R}\"/>\n          <circle class=\"prog\" cx=\"130\" cy=\"130\" r=\"${R}\" stroke-dasharray=\"${C}\" stroke-dashoffset=\"${offset}\"/>\n        </svg>\n        <div class=\"center\">\n          <div class=\"time ${done?'done':''}\">${done?'00:00':mm+':'+ss}</div>\n          <div class=\"sub\">${done?'tempo esgotado':(running?'rodando':'pausado')}</div>\n        </div>\n      </div>\n      <div class=\"controls\">\n        <button class=\"btn ghost reset\" title=\"Reiniciar\">↺</button>\n        <button class=\"btn main toggle\" title=\"${running?'Pausar':'Iniciar'}\">${running?'❚❚':'▶'}</button>\n        <button class=\"btn ghost minus\" title=\"-1 min\">−</button>\n      </div>\n    </div>`\n  },\n  mounted(d2){\n    if (d2.state.total == null){ d2.state.total = 300; d2.state.left = 300; d2.state.running = false }\n    const tick = () => {\n      if (!d2.state.running) return\n      if ((d2.state.left ?? 0) <= 0){ d2.state.running = false; return }\n      d2.state.left = (d2.state.left ?? 0) - 1\n      if (d2.state.left <= 0){ d2.state.running = false; try{ if(navigator.vibrate) navigator.vibrate([200,100,200]) }catch(e){} }\n    }\n    const iv = setInterval(tick, 1000)\n    d2.onUnmount(() => clearInterval(iv))\n\n    d2.on('.toggle','click',()=>{\n      if ((d2.state.left ?? 0) <= 0){ d2.state.left = d2.state.total; }\n      d2.state.running = !d2.state.running\n    })\n    d2.on('.reset','click',()=>{ d2.state.running=false; d2.state.left=d2.state.total })\n    d2.on('.minus','click',()=>{ d2.state.left = Math.max(0,(d2.state.left ?? 0) - 60) })\n    d2.on('.preset','click',(e,el)=>{\n      const v = Number(el.dataset.preset)\n      d2.state.total = v; d2.state.left = v; d2.state.running = false\n    })\n  },\n}"}}}}}}}},{"_id":"6a354063a4566d121f7a3cd7","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"Tdj19iZX3CobVkkEUm1ZN","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n    .wrap{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:28px;height:100%;width:100%;\n      box-sizing:border-box;padding:32px;font-family:-apple-system,Segoe UI,Roboto,sans-serif;\n      background:radial-gradient(circle at 50% 0%,#1b1640,#0c0a1f 70%);color:#fff}\n    .dial{position:relative;width:min(62vmin,300px);height:min(62vmin,300px)}\n    .dial svg{width:100%;height:100%;transform:rotate(-90deg)}\n    .track{fill:none;stroke:rgba(255,255,255,.08);stroke-width:10}\n    .prog{fill:none;stroke:url(#g);stroke-width:10;stroke-linecap:round;transition:stroke-dashoffset .25s linear}\n    .time{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px}\n    .big{font-size:clamp(40px,12vmin,68px);font-weight:800;letter-spacing:1px;font-variant-numeric:tabular-nums}\n    .lbl{font-size:12px;letter-spacing:.18em;text-transform:uppercase;color:#9b93c9}\n    .lbl[data-done]{color:#5ee6a8}\n    .chips{display:flex;gap:8px;flex-wrap:wrap;justify-content:center}\n    .chip{padding:7px 14px;border-radius:999px;border:1px solid rgba(255,255,255,.14);background:rgba(255,255,255,.04);\n      color:#cfc8f0;font-size:13px;cursor:pointer;transition:.15s}\n    .chip:hover{background:rgba(255,255,255,.1)}\n    .row{display:flex;gap:14px;align-items:center}\n    .btn{width:62px;height:62px;border-radius:50%;border:0;cursor:pointer;font-size:24px;display:flex;\n      align-items:center;justify-content:center;color:#fff;transition:transform .12s,filter .15s}\n    .btn:active{transform:scale(.92)}\n    .play{background:linear-gradient(135deg,#7c4dff,#b06bff);box-shadow:0 8px 24px rgba(124,77,255,.45)}\n    .ghost{background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.14);font-size:18px;width:52px;height:52px}\n    .ghost:hover{background:rgba(255,255,255,.13)}\n  `,\n  render(d2){\n    const total = Math.max(1, d2.state.total ?? (Number(d2.param('seconds', 300)) || 300))\n    const left = d2.state.left ?? total\n    const running = !!d2.state.running\n    const done = left <= 0\n    const mm = String(Math.floor(left / 60)).padStart(2,'0')\n    const ss = String(Math.floor(left % 60)).padStart(2,'0')\n    const R = 90, C = 2 * Math.PI * R\n    const frac = done ? 0 : left / total\n    const off = C * (1 - frac)\n    const presets = [1,5,10,25].map(m =>\n      `<div class=\"chip\" data-min=\"${m}\">${m} min</div>`).join('')\n    return `<div class=\"wrap\">\n      <div class=\"dial\">\n        <svg viewBox=\"0 0 200 200\">\n          <defs><linearGradient id=\"g\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\">\n            <stop offset=\"0\" stop-color=\"#7c4dff\"/><stop offset=\"1\" stop-color=\"#5ee6a8\"/>\n          </linearGradient></defs>\n          <circle class=\"track\" cx=\"100\" cy=\"100\" r=\"${R}\"/>\n          <circle class=\"prog\" cx=\"100\" cy=\"100\" r=\"${R}\"\n            stroke-dasharray=\"${C}\" stroke-dashoffset=\"${off}\"/>\n        </svg>\n        <div class=\"time\">\n          <div class=\"big\">${mm}:${ss}</div>\n          <div class=\"lbl\" ${done?'data-done':''}>${done?'finished':(running?'running':'paused')}</div>\n        </div>\n      </div>\n      <div class=\"chips\">${presets}</div>\n      <div class=\"row\">\n        <button class=\"btn ghost reset\" title=\"reset\">↺</button>\n        <button class=\"btn play toggle\">${running?'⏸':'▶'}</button>\n        <button class=\"btn ghost add\" title=\"+1 min\">+1</button>\n      </div>\n    </div>`\n  },\n  mounted(d2){\n    const init = Number(d2.param('seconds', 300)) || 300\n    if (d2.state.total == null){ d2.state.total = init; d2.state.left = init; d2.state.running = false }\n    let last = 0\n    d2.raf((t)=>{\n      if (!d2.state.running) { last = t; return }\n      if (!last) last = t\n      const dt = (t - last) / 1000\n      if (dt >= 0.25){\n        last = t\n        const nl = Math.max(0, (d2.state.left ?? d2.state.total) - dt)\n        d2.state.left = nl\n        if (nl <= 0) d2.state.running = false\n      }\n    })\n    d2.on('.toggle','click',()=>{\n      if ((d2.state.left ?? 0) <= 0) d2.state.left = d2.state.total\n      d2.state.running = !d2.state.running\n    })\n    d2.on('.reset','click',()=>{ d2.state.left = d2.state.total; d2.state.running = false })\n    d2.on('.add','click',()=>{ d2.state.left = (d2.state.left ?? d2.state.total) + 60; d2.state.total = Math.max(d2.state.total, d2.state.left) })\n    d2.on('.chip','click',(e,el)=>{\n      const s = Number(el.dataset.min) * 60\n      d2.state.total = s; d2.state.left = s; d2.state.running = false\n    })\n  },\n}"}},"seconds":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"seconds"}}}}}}}}}},{"_id":"6a354c97dbb7889ef4cd8440","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"alT0RyyiOeUTCr7QuHFB_","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n    .wrap{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:28px;\n          height:100%;box-sizing:border-box;padding:32px;\n          background:radial-gradient(circle at 50% 30%, #1c1c2e, #0d0d16);\n          font-family:ui-sans-serif,system-ui,sans-serif;user-select:none}\n    .ring{position:relative;width:min(64vmin,340px);height:min(64vmin,340px);display:flex;align-items:center;justify-content:center}\n    .ring svg{position:absolute;inset:0;width:100%;height:100%;transform:rotate(-90deg)}\n    .track{fill:none;stroke:rgba(255,255,255,.07);stroke-width:8}\n    .prog{fill:none;stroke:var(--accent,#7c5cff);stroke-width:8;stroke-linecap:round;\n          transition:stroke-dashoffset .2s linear;filter:drop-shadow(0 0 8px var(--accent,#7c5cff))}\n    .time{font-size:clamp(40px,12vmin,72px);font-weight:800;color:#fff;letter-spacing:1px;font-variant-numeric:tabular-nums}\n    .dot{color:var(--accent,#7c5cff);font-size:13px;letter-spacing:.18em;text-transform:uppercase;margin-top:6px}\n    .presets{display:flex;gap:8px}\n    .custom{display:flex;gap:8px;align-items:center}\n    .custom input{width:96px;padding:8px 12px;border-radius:999px;border:1px solid rgba(255,255,255,.14);\n          background:rgba(255,255,255,.04);color:#fff;font-size:14px;text-align:center;outline:none;\n          font-variant-numeric:tabular-nums}\n    .custom input:focus{border-color:var(--accent,#7c5cff)}\n    .custom button{padding:8px 16px;border-radius:999px;border:none;cursor:pointer;\n          background:var(--accent,#7c5cff);color:#fff;font-size:13px;font-weight:600;transition:.15s}\n    .custom button:hover{filter:brightness(1.1)}\n    .chip{padding:7px 14px;border-radius:999px;border:1px solid rgba(255,255,255,.14);background:transparent;\n          color:#cfcfe6;font-size:13px;cursor:pointer;transition:.15s}\n    .chip:hover{border-color:var(--accent,#7c5cff);color:#fff}\n    .chip[data-on]{background:var(--accent,#7c5cff);border-color:var(--accent,#7c5cff);color:#fff}\n    .ctrls{display:flex;gap:14px}\n    .btn{width:58px;height:58px;border-radius:50%;border:none;cursor:pointer;font-size:22px;\n         display:flex;align-items:center;justify-content:center;transition:.15s;color:#fff}\n    .btn:hover{transform:scale(1.06)}\n    .play{background:var(--accent,#7c5cff);box-shadow:0 6px 20px rgba(124,92,255,.4)}\n    .reset{background:rgba(255,255,255,.08)}\n    .done .time{color:var(--accent,#7c5cff);animation:pulse 1s infinite}\n    @keyframes pulse{50%{opacity:.4}}\n  `,\n  render(d2){\n    const total = d2.state.total ?? 300\n    const rem = d2.state.remaining ?? total\n    const running = !!d2.state.running\n    const done = rem <= 0\n    const m = Math.floor(rem/60), s = Math.floor(rem%60)\n    const label = `${String(m).padStart(2,'0')}:${String(s).padStart(2,'0')}`\n    const R=120, C=2*Math.PI*R\n    const frac = total>0 ? rem/total : 0\n    const off = C*(1-frac)\n    const presets = [1,5,10,25]\n    const chips = presets.map(p=>`<button class=\"chip\" data-min=\"${p}\" ${total===p*60?'data-on':''}>${p}m</button>`).join('')\n    return `<div class=\"wrap ${done?'done':''}\">\n      <div class=\"presets\">${chips}</div>\n      <div class=\"custom\">\n        <input class=\"cinput\" type=\"text\" inputmode=\"numeric\" placeholder=\"min:seg\" value=\"${d2.state.draft ?? ''}\"/>\n        <button class=\"capply\">aplicar</button>\n      </div>\n      <div class=\"ring\">\n        <svg viewBox=\"0 0 256 256\">\n          <circle class=\"track\" cx=\"128\" cy=\"128\" r=\"${R}\"/>\n          <circle class=\"prog\" cx=\"128\" cy=\"128\" r=\"${R}\" stroke-dasharray=\"${C}\" stroke-dashoffset=\"${off}\"/>\n        </svg>\n        <div style=\"display:flex;flex-direction:column;align-items:center\">\n          <div class=\"time\">${label}</div>\n          <div class=\"dot\">${done?'tempo!':(running?'rodando':'pausado')}</div>\n        </div>\n      </div>\n      <div class=\"ctrls\">\n        <button class=\"btn play\">${running?'⏸':'▶'}</button>\n        <button class=\"btn reset\">↺</button>\n      </div>\n    </div>`\n  },\n  mounted(d2){\n    if (d2.state.total == null){ d2.state.total = 300; d2.state.remaining = 300; d2.state.running = false }\n    let last = null\n    const tick = (t) => {\n      if (d2.state.running && d2.state.remaining > 0){\n        if (last != null){ d2.state.remaining = Math.max(0, d2.state.remaining - (t-last)/1000) }\n        if (d2.state.remaining <= 0){ d2.state.running = false }\n      }\n      last = t\n    }\n    d2.raf(tick)\n    d2.on('.play','click', () => {\n      if (d2.state.remaining <= 0){ d2.state.remaining = d2.state.total }\n      d2.state.running = !d2.state.running\n    })\n    d2.on('.reset','click', () => { d2.state.running = false; d2.state.remaining = d2.state.total })\n    d2.on('.chip','click', (e, el) => {\n      const min = Number(el.dataset.min)\n      d2.state.total = min*60; d2.state.remaining = min*60; d2.state.running = false; d2.state.draft = ''\n    })\n    const parse = (raw) => {\n      const txt = String(raw||'').trim()\n      if (!txt) return null\n      if (txt.includes(':')){\n        const p = txt.split(':').map(n=>Number(n)||0)\n        let secs = 0\n        if (p.length === 2) secs = p[0]*60 + p[1]\n        else if (p.length === 3) secs = p[0]*3600 + p[1]*60 + p[2]\n        else secs = p[0]*60\n        return secs\n      }\n      return Number(txt)*60 // bare number = minutes\n    }\n    const apply = () => {\n      const inp = d2.root.querySelector('.cinput')\n      const secs = parse(inp && inp.value)\n      if (secs && secs > 0){\n        const capped = Math.min(secs, 24*3600)\n        d2.state.total = capped; d2.state.remaining = capped; d2.state.running = false; d2.state.draft = ''\n      }\n    }\n    d2.on('.cinput','input', (e, el) => { d2.state.draft = el.value })\n    d2.on('.cinput','keydown', (e) => { if (e.key === 'Enter') apply() })\n    d2.on('.capply','click', apply)\n  },\n}"}},"accent":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"accent"}}}}}}}}}},{"_id":"6a356a1854b2fea545c0df35","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"nE9a4lB6AG50YCiZSCT9j","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n    .wrap{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:22px;height:100%;\n      box-sizing:border-box;padding:28px;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;\n      background:radial-gradient(120% 120% at 50% 0%, #1b1b24 0%, #0e0e14 100%);color:#fff;user-select:none}\n    .dial{position:relative;width:236px;height:236px}\n    .dial svg{width:100%;height:100%;transform:rotate(-90deg)}\n    .track{fill:none;stroke:rgba(255,255,255,.08);stroke-width:14}\n    .prog{fill:none;stroke-width:14;stroke-linecap:round;transition:stroke-dashoffset .35s linear}\n    .center{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px}\n    .time{font-size:48px;font-weight:800;font-variant-numeric:tabular-nums;letter-spacing:1px}\n    .time.done{animation:blink 1s steps(2,start) infinite}\n    @keyframes blink{50%{opacity:.25}}\n    .sub{font-size:12px;text-transform:uppercase;letter-spacing:.14em;color:#8a8a99}\n    .presets{display:flex;gap:8px}\n    .pre{padding:7px 13px;border-radius:999px;border:1px solid rgba(255,255,255,.14);background:rgba(255,255,255,.04);\n      color:#cfcfda;font-size:13px;cursor:pointer;transition:.15s}\n    .pre:hover{background:rgba(255,255,255,.1)}\n    .pre[data-active]{background:var(--accent);border-color:var(--accent);color:#0e0e14;font-weight:700}\n    .custom{display:flex;align-items:center;gap:8px}\n    .in{width:62px;padding:9px 8px;border-radius:10px;border:1px solid rgba(255,255,255,.16);background:rgba(255,255,255,.05);\n      color:#fff;font-size:15px;text-align:center;outline:0;font-variant-numeric:tabular-nums}\n    .in:focus{border-color:var(--accent)}\n    .clbl{font-size:12px;color:#8a8a99}\n    .ctrls{display:flex;gap:12px}\n    .btn{width:54px;height:54px;border-radius:50%;border:0;cursor:pointer;font-size:20px;display:flex;\n      align-items:center;justify-content:center;transition:.15s;color:#fff;background:rgba(255,255,255,.08)}\n    .btn:hover{transform:scale(1.06)}\n    .btn.play{width:64px;height:64px;background:var(--accent);color:#0e0e14;font-size:24px}\n  `,\n  render(d2){\n    const accent = d2.param('accent') || '#7c4dff'\n    const total = d2.state.total ?? 300\n    const left  = d2.state.left ?? total\n    const running = !!d2.state.running\n    const done = left <= 0\n    const R = 105, C = 2 * Math.PI * R\n    const frac = total > 0 ? Math.max(0, left / total) : 0\n    const offset = C * (1 - frac)\n    const mm = String(Math.floor(left / 60)).padStart(2,'0')\n    const ss = String(left % 60).padStart(2,'0')\n    const presets = [1,5,10,25]\n    const activeMin = total / 60\n    return `<div class=\"wrap\" style=\"--accent:${accent}\">\n      <div class=\"dial\">\n        <svg viewBox=\"0 0 236 236\">\n          <circle class=\"track\" cx=\"118\" cy=\"118\" r=\"${R}\"/>\n          <circle class=\"prog\" cx=\"118\" cy=\"118\" r=\"${R}\" stroke=\"${accent}\"\n            stroke-dasharray=\"${C.toFixed(1)}\" stroke-dashoffset=\"${offset.toFixed(1)}\"/>\n        </svg>\n        <div class=\"center\">\n          <div class=\"time ${done ? 'done' : ''}\">${done ? '00:00' : mm + ':' + ss}</div>\n          <div class=\"sub\">${done ? 'tempo!' : (running ? 'rodando' : 'pausado')}</div>\n        </div>\n      </div>\n      <div class=\"presets\">\n        ${presets.map(m => `<button class=\"pre\" data-min=\"${m}\" ${activeMin===m ? 'data-active':''}>${m} min</button>`).join('')}\n      </div>\n      <div class=\"custom\">\n        <input class=\"in\" data-role=\"mins\" type=\"number\" min=\"0\" max=\"599\" placeholder=\"min\"\n          value=\"${d2.state.editing ? (d2.state.draftMin ?? '') : Math.floor(activeMin)}\"/>\n        <span class=\"clbl\">min :</span>\n        <input class=\"in\" data-role=\"secs\" type=\"number\" min=\"0\" max=\"59\" placeholder=\"seg\"\n          value=\"${d2.state.editing ? (d2.state.draftSec ?? '') : String(total%60).padStart(2,'0')}\"/>\n        <span class=\"clbl\">seg</span>\n      </div>\n      <div class=\"ctrls\">\n        <button class=\"btn play\" data-act=\"toggle\">${running ? '⏸' : '▶'}</button>\n        <button class=\"btn\" data-act=\"reset\">↺</button>\n      </div>\n    </div>`\n  },\n  mounted(d2){\n    const tick = () => {\n      if (!d2.state.running) return\n      const l = (d2.state.left ?? d2.state.total ?? 300) - 1\n      if (l <= 0){ d2.state.left = 0; d2.state.running = false }\n      else d2.state.left = l\n    }\n    const setTotal = (secs) => {\n      secs = Math.max(0, Math.min(35940, Math.round(secs)))\n      d2.state.total = secs; d2.state.left = secs\n      d2.state.running = false; d2.state.editing = false\n    }\n    d2.on('.pre', 'click', (e, el) => setTotal(Number(el.dataset.min) * 60))\n    d2.on('.in', 'input', (e, el) => {\n      d2.state.editing = true\n      const m = Number(d2.$('.in[data-role=mins]').value) || 0\n      const s = Number(d2.$('.in[data-role=secs]').value) || 0\n      d2.state.draftMin = d2.$('.in[data-role=mins]').value\n      d2.state.draftSec = d2.$('.in[data-role=secs]').value\n      const secs = Math.max(0, Math.min(35940, m * 60 + s))\n      d2.state.total = secs; d2.state.left = secs; d2.state.running = false\n    })\n    d2.on('.in', 'blur', () => { d2.state.editing = false })\n    d2.on('[data-act=toggle]', 'click', () => {\n      if ((d2.state.left ?? d2.state.total ?? 300) <= 0) return\n      d2.state.editing = false\n      d2.state.running = !d2.state.running\n    })\n    d2.on('[data-act=reset]', 'click', () => {\n      d2.state.running = false\n      d2.state.left = d2.state.total ?? 300\n    })\n    let last = null\n    d2.raf((t) => {\n      if (last == null) last = t\n      if (t - last >= 1000){ last = t; tick() }\n    })\n  },\n}"}},"accent":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"accent"}}}}}}}}}},{"_id":"6a356d0e4fe6d93b7d1a9805","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"pomodoro-timer","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n  .pom{height:100%;width:100%;box-sizing:border-box;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:18px;\n       font-family:-apple-system,Segoe UI,Roboto,sans-serif;background:#fff;color:var(--ink,#1f1147);transition:background .5s;padding:24px}\n  .phase{display:flex;gap:8px}\n  .tab{padding:6px 14px;border-radius:999px;font-size:13px;font-weight:600;cursor:pointer;border:1px solid rgba(0,0,0,.12);\n        background:transparent;color:rgba(0,0,0,.55);transition:.2s}\n  .tab[data-on]{background:var(--ink,#1f1147);color:#fff}\n  .ringwrap{position:relative;width:240px;height:240px}\n  .ringwrap svg{transform:rotate(-90deg)}\n  .time{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px}\n  .clock{font-size:52px;font-weight:800;font-variant-numeric:tabular-nums;letter-spacing:1px}\n  .sub{font-size:12px;letter-spacing:.12em;text-transform:uppercase;color:rgba(0,0,0,.45)}\n  .ctrls{display:flex;gap:12px}\n  .btn{width:54px;height:54px;border-radius:50%;border:0;cursor:pointer;font-size:20px;display:flex;align-items:center;justify-content:center;\n       background:rgba(0,0,0,.06);color:var(--ink,#1f1147);transition:.15s}\n  .btn:hover{background:rgba(0,0,0,.12)}\n  .btn.go{width:64px;height:64px;font-size:24px;background:var(--ink,#1f1147);color:#fff}\n  .dots{display:flex;gap:7px;align-items:center}\n  .dot{width:10px;height:10px;border-radius:50%;background:rgba(0,0,0,.12)}\n  .dot[data-done]{background:var(--ink,#1f1147)}\n  .meta{font-size:12px;color:rgba(0,0,0,.45)}\n  .done .clock{animation:blink 1s steps(2,start) infinite}\n  @keyframes blink{50%{opacity:.25}}\n  `,\n  render(d2){\n    const focus = Number(d2.state.focusMin ?? 25)\n    const shortB = Number(d2.state.shortMin ?? 5)\n    const longB  = Number(d2.state.longMin ?? 15)\n    const mode = d2.state.mode || 'focus' // focus | short | long\n    const total = (mode==='focus'?focus:mode==='short'?shortB:longB)*60\n    if (d2.state.left == null) d2.state.left = total\n    const left = d2.state.left\n    const running = !!d2.state.running\n    const isDone = left<=0\n\n    const theme = mode==='focus'\n      ? {bg:'#1f1147', ink:'#1f1147', ring:'#ff5c7a'}\n      : mode==='short'\n        ? {bg:'#0d3b3b', ink:'#0d3b3b', ring:'#3ee7b5'}\n        : {bg:'#1a2a52', ink:'#1a2a52', ring:'#62a0ff'}\n\n    const r=104, C=2*Math.PI*r\n    const frac = Math.max(0, Math.min(1, left/total))\n    const off = C*(1-frac)\n    const mm = String(Math.floor(Math.max(0,left)/60)).padStart(2,'0')\n    const ss = String(Math.floor(Math.max(0,left)%60)).padStart(2,'0')\n    const cycles = Number(d2.state.cycles||0)\n    const dots = [0,1,2,3].map(i=>`<span class=\"dot\" ${i<(cycles%4||(cycles>0&&cycles%4===0?4:0))?'data-done':''}></span>`).join('')\n\n    return `<div class=\"pom ${isDone?'done':''}\" style=\"--bg:${theme.bg};--ink:${theme.ink}\">\n      <div class=\"phase\">\n        <span class=\"tab\" data-mode=\"focus\" ${mode==='focus'?'data-on':''}>Foco</span>\n        <span class=\"tab\" data-mode=\"short\" ${mode==='short'?'data-on':''}>Pausa</span>\n        <span class=\"tab\" data-mode=\"long\"  ${mode==='long' ?'data-on':''}>Descanso</span>\n      </div>\n      <div class=\"ringwrap\">\n        <svg width=\"240\" height=\"240\" viewBox=\"0 0 240 240\">\n          <circle cx=\"120\" cy=\"120\" r=\"${r}\" fill=\"none\" stroke=\"rgba(0,0,0,.08)\" stroke-width=\"14\"/>\n          <circle cx=\"120\" cy=\"120\" r=\"${r}\" fill=\"none\" stroke=\"${theme.ring}\" stroke-width=\"14\" stroke-linecap=\"round\"\n                  stroke-dasharray=\"${C}\" stroke-dashoffset=\"${off}\" style=\"transition:stroke-dashoffset .9s linear\"/>\n        </svg>\n        <div class=\"time\">\n          <div class=\"clock\">${isDone?'00:00':`${mm}:${ss}`}</div>\n          <div class=\"sub\">${isDone?'tempo!':(mode==='focus'?'foco':mode==='short'?'pausa curta':'descanso')}</div>\n        </div>\n      </div>\n      <div class=\"ctrls\">\n        <button class=\"btn\" data-act=\"reset\" title=\"Zerar\">↺</button>\n        <button class=\"btn go\" data-act=\"toggle\" title=\"${running?'Pausar':'Tocar'}\">${running?'⏸':'▶'}</button>\n        <button class=\"btn\" data-act=\"skip\" title=\"Pular fase\">⏭</button>\n      </div>\n      <div class=\"dots\">${dots}</div>\n      <div class=\"meta\">${cycles} pomodoro${cycles===1?'':'s'} concluído${cycles===1?'':'s'} • ${focus}/${shortB}/${longB} min</div>\n    </div>`\n  },\n  mounted(d2){\n    const totalFor = (m)=> (m==='focus'? Number(d2.state.focusMin??25) : m==='short'? Number(d2.state.shortMin??5) : Number(d2.state.longMin??15))*60\n    const advance = ()=>{\n      const m = d2.state.mode||'focus'\n      if (m==='focus'){\n        const c = Number(d2.state.cycles||0)+1\n        d2.state.cycles = c\n        d2.state.mode = (c%4===0) ? 'long' : 'short'\n      } else {\n        d2.state.mode = 'focus'\n      }\n      d2.state.left = totalFor(d2.state.mode)\n      d2.state.running = false\n    }\n    d2.on('.tab','click',(e,el)=>{\n      d2.state.mode = el.dataset.mode\n      d2.state.left = totalFor(el.dataset.mode)\n      d2.state.running = false\n    })\n    d2.on('.btn','click',(e,el)=>{\n      const a = el.dataset.act\n      if (a==='toggle'){\n        if ((d2.state.left??0)<=0) d2.state.left = totalFor(d2.state.mode||'focus')\n        d2.state.running = !d2.state.running\n      } else if (a==='reset'){\n        d2.state.running=false; d2.state.left = totalFor(d2.state.mode||'focus')\n      } else if (a==='skip'){\n        advance()\n      }\n    })\n    d2.raf((t)=>{\n      if (!d2.state.running) { d2.state._last = t; return }\n      if (d2.state._last==null) d2.state._last = t\n      const dt = t - d2.state._last\n      if (dt >= 1000){\n        d2.state._last = t\n        const nl = (d2.state.left??0) - Math.round(dt/1000)\n        if (nl <= 0){\n          d2.state.left = 0\n          d2.state.running = false\n          setTimeout(advance, 1400)\n        } else {\n          d2.state.left = nl\n        }\n      }\n    })\n  },\n}"}}}}}}}},{"_id":"6a39809ae5a95378ceed5d54","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"vans-tryon-ui","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n    *{box-sizing:border-box}\n    .wrap{font-family:'Helvetica Neue',Arial,sans-serif;color:#111;background:#fff;height:100%;overflow-y:auto;display:flex;flex-direction:column}\n    .top{background:#111;color:#fff;display:flex;align-items:center;gap:14px;padding:16px 24px}\n    .logo{font-weight:900;font-style:italic;font-size:24px;letter-spacing:-1px;background:#fff;color:#111;padding:2px 10px;transform:skew(-9deg)}\n    .ttl{font-weight:800;text-transform:uppercase;letter-spacing:1px;font-size:14px;line-height:1.2}\n    .ttl small{display:block;font-weight:400;text-transform:none;letter-spacing:0;opacity:.55;font-size:12px}\n    .body{display:grid;grid-template-columns:330px 1fr;align-items:start}\n    @media(max-width:780px){.body{grid-template-columns:1fr}}\n    .col{padding:22px}\n    .left{border-right:1px solid #eee;background:#fafafa}\n    .sec{font-size:11px;font-weight:800;text-transform:uppercase;letter-spacing:1.5px;color:#9a9a9a;margin:0 0 12px}\n    .tabs{display:flex;gap:6px;margin-bottom:14px;background:#eee;padding:4px;border-radius:10px}\n    .tab{flex:1;border:0;background:transparent;padding:9px;border-radius:8px;font-size:13px;font-weight:700;cursor:pointer;color:#777}\n    .tab.on{background:#111;color:#fff}\n    .drop{border:2px dashed #ccc;border-radius:14px;aspect-ratio:3/4;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;cursor:pointer;text-align:center;padding:16px;background:#fff;transition:.15s}\n    .drop:hover{border-color:#ED1C24;background:#fff6f6}\n    .drop .ic{font-size:34px}\n    .drop p{margin:0;font-size:13px;color:#666}\n    .drop b{color:#ED1C24}\n    .photo{position:relative;border-radius:14px;overflow:hidden;aspect-ratio:3/4;background:#eee}\n    .photo img{width:100%;height:100%;object-fit:cover;display:block}\n    .chg{position:absolute;bottom:10px;left:10px;background:rgba(0,0,0,.72);color:#fff;border:0;border-radius:8px;padding:7px 12px;font-size:12px;cursor:pointer}\n    .file{display:none}\n    .gen .gg{margin-bottom:14px}\n    .gen .gl{font-size:12px;font-weight:700;color:#555;margin-bottom:7px}\n    .chips{display:flex;flex-wrap:wrap;gap:7px}\n    .chip{border:1px solid #ddd;background:#fff;border-radius:20px;padding:7px 13px;font-size:12px;font-weight:600;cursor:pointer;color:#444;transition:.12s}\n    .chip:hover{border-color:#999}\n    .chip.on{background:#111;color:#fff;border-color:#111}\n    .field{display:flex;gap:8px;margin-bottom:18px}\n    .field input{flex:1;padding:11px 14px;border:1px solid #ddd;border-radius:10px;font-size:14px;outline:none}\n    .field input:focus{border-color:#111}\n    .btn{background:#111;color:#fff;border:0;border-radius:10px;padding:11px 16px;font-weight:700;cursor:pointer;font-size:14px}\n    .btn:disabled{opacity:.45;cursor:default}\n    .grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:12px}\n    .card{border:2px solid #ededed;border-radius:12px;overflow:hidden;cursor:pointer;background:#fff;transition:.15s;display:flex;flex-direction:column}\n    .card:hover{border-color:#c4c4c4;transform:translateY(-2px)}\n    .card[data-sel]{border-color:#ED1C24;box-shadow:0 0 0 3px rgba(237,28,36,.16)}\n    .card .ph{aspect-ratio:1;background:#f4f4f4}\n    .card img{width:100%;height:100%;object-fit:contain;display:block}\n    .card .meta{padding:8px 10px}\n    .card .nm{font-size:12px;font-weight:600;line-height:1.25;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;min-height:30px}\n    .card .pr{font-size:13px;font-weight:800;margin-top:4px}\n    .muted{color:#9a9a9a;font-size:13px;padding:36px 0;text-align:center}\n    .cta-wrap{padding:16px 22px;border-top:1px solid #eee;background:#fff;position:sticky;bottom:0;z-index:5}\n    .cta{width:100%;max-width:100%;background:#ED1C24;color:#fff;border:0;border-radius:12px;padding:15px;font-weight:800;text-transform:uppercase;letter-spacing:1px;font-size:15px;cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n    .cta:disabled{opacity:.35;cursor:default}\n    .result{padding:28px 22px;border-top:1px solid #222;background:#0d0d0d;color:#fff}\n    .out{display:flex;gap:28px;flex-wrap:wrap;align-items:center;justify-content:center;max-width:1080px;margin:0 auto}\n    .out a{flex:0 0 auto;display:block}\n    .out img{max-height:72vh;max-width:min(540px,92vw);width:auto;height:auto;border-radius:16px;display:block;background:#222;box-shadow:0 12px 44px rgba(0,0,0,.55);cursor:zoom-in}\n    .info{flex:1 1 240px;min-width:220px;max-width:380px}\n    .info h3{margin:0 0 4px;font-size:22px;font-weight:800}\n    .info .p2{opacity:.6;font-size:13px;margin:0 0 4px}\n    .info .pr{font-size:16px;font-weight:800;margin:6px 0}\n    .buy{display:inline-block;margin-top:10px;background:#fff;color:#111;text-decoration:none;padding:12px 20px;border-radius:10px;font-weight:800;text-transform:uppercase;font-size:13px;letter-spacing:1px}\n    .ghost{background:transparent;color:#fff;border:1px solid #555;margin-left:8px}\n    .spin{width:36px;height:36px;border:3px solid #333;border-top-color:#ED1C24;border-radius:50%;animation:sp 1s linear infinite}\n    @keyframes sp{to{transform:rotate(360deg)}}\n    .center{display:flex;flex-direction:column;align-items:center;gap:14px;justify-content:center;padding:30px 0}\n    .err{color:#ED1C24;font-size:13px;margin-top:10px;font-weight:600}\n    .custbox{margin-top:4px}\n    .chead{display:flex;justify-content:space-between;align-items:center;margin-bottom:12px;font-size:12px;font-weight:800;text-transform:uppercase;letter-spacing:1px;color:#777}\n    .clearc{background:none;border:0;color:#ED1C24;font-size:12px;font-weight:700;cursor:pointer}\n    .crow{display:flex;align-items:center;gap:12px;padding:9px 0;border-bottom:1px solid #f0f0f0}\n    .crow .cl{width:108px;flex:0 0 108px;font-size:13px;font-weight:600;color:#333}\n    .sw{display:flex;flex-wrap:wrap;gap:8px}\n    .swatch{width:26px;height:26px;border-radius:50%;border:1px solid rgba(0,0,0,.22);cursor:pointer;padding:0;transition:.12s}\n    .swatch:hover{transform:scale(1.14)}\n    .swatch.on{box-shadow:0 0 0 2px #fff,0 0 0 4px #111}\n  `,\n  render(d2){\n    const s = d2.state\n    const photo = s.userPhotoUrl\n    const results = s.results || []\n    const sel = s.selected\n    const mode = s.mode || 'gen'\n    const gen = s.gen || {gender:'homem', style:'streetwear', framing:'corpo'}\n    const canTry = !!photo && !!sel && !s.tryingOn\n\n    const grp = (label,key,opts)=>`<div class=\"gg\"><div class=\"gl\">${label}</div><div class=\"chips\">${opts.map(o=>`<button class=\"chip ${gen[key]===o[0]?'on':''}\" data-gk=\"${key}\" data-gv=\"${o[0]}\">${esc(o[1])}</button>`).join('')}</div></div>`\n    const genPanel = `<div class=\"gen\">\n      ${grp('Gênero','gender',[['homem','Homem'],['mulher','Mulher']])}\n      ${grp('Estilo','style',[['streetwear','Streetwear'],['casual','Casual'],['skatista','Skatista']])}\n      ${grp('Enquadramento','framing',[['corpo','Corpo inteiro'],['pes','Só os pés']])}\n      <button class=\"btn gen-btn\" style=\"width:100%;margin-top:4px\">✨ Gerar modelo</button></div>`\n\n    let leftInner\n    if (s.generating) leftInner = `<div class=\"drop\"><div class=\"spin\"></div><p>Gerando seu modelo…</p></div>`\n    else if (s.uploading) leftInner = `<div class=\"drop\"><div class=\"spin\"></div><p>Enviando foto…</p></div>`\n    else if (photo) leftInner = `<div class=\"photo\"><img src=\"${photo}\"/><button class=\"chg\">Trocar</button></div>`\n    else leftInner = `<div class=\"tabs\">\n        <button class=\"tab ${mode==='upload'?'on':''}\" data-mode=\"upload\">Enviar foto</button>\n        <button class=\"tab ${mode==='gen'?'on':''}\" data-mode=\"gen\">Gerar modelo</button></div>`\n      + (mode==='upload'\n          ? `<div class=\"drop\"><div class=\"ic\">📷</div><p>Toque para enviar uma <b>foto sua</b><br/>(corpo, pernas ou pés)</p></div>`\n          : genPanel)\n\n    let shoes\n    if (s.searching) shoes = `<div class=\"center\"><div class=\"spin\"></div></div>`\n    else if (!results.length) shoes = `<p class=\"muted\">${s.searched ? 'Nada encontrado. Tente outro termo.' : 'Busque um modelo: old skool, authentic, sk8-hi…'}</p>`\n    else shoes = `<div class=\"grid\">${results.map((r,i)=>`\n      <div class=\"card\" data-key=\"${esc(r.code||i)}\" data-idx=\"${i}\" ${sel&&sel.code===r.code?'data-sel':''}>\n        <div class=\"ph\"><img src=\"${esc(r.image||r.thumb||'')}\" loading=\"lazy\"/></div>\n        <div class=\"meta\"><div class=\"nm\">${esc(r.name||'')}</div><div class=\"pr\">${esc(r.price||'')}</div></div>\n      </div>`).join('')}</div>`\n\n    let resultPanel = ''\n    if (s.tryingOn) resultPanel = `<div class=\"result\"><div class=\"center\"><div class=\"spin\"></div><p>Provando o ${esc(sel?sel.name:'tênis')}… isso leva uns segundos.</p></div></div>`\n    else if (s.tryonUrl) resultPanel = `<div class=\"result\"><div class=\"out\">\n        <a href=\"${esc(s.tryonUrl)}\" target=\"_blank\" rel=\"noopener\"><img src=\"${esc(s.tryonUrl)}\" title=\"Abrir em tamanho real\"/></a>\n        <div class=\"info\"><div class=\"p2\">Resultado do provador</div><h3>${esc(sel?sel.name:'')}</h3>\n          <div class=\"pr\">${esc(sel?sel.price:'')}</div>\n          ${sel&&sel.link?`<a class=\"buy\" href=\"${esc(sel.link)}\" target=\"_blank\" rel=\"noopener\">Comprar na Vans →</a>`:''}\n          <button class=\"btn ghost chg2\">Provar outro</button>\n        </div></div></div>`\n\n    return `<div class=\"wrap\">\n      <div class=\"top\"><span class=\"logo\">VANS</span>\n        <div class=\"ttl\">Provador Virtual<small>Gere um modelo ou envie sua foto e prove os tênis com IA</small></div></div>\n      <input type=\"file\" class=\"file\" accept=\"image/*\"/>\n      <div class=\"body\">\n        <div class=\"col left\"><p class=\"sec\">1 · Quem vai provar</p>${leftInner}${s.error?`<div class=\"err\">${esc(s.error)}</div>`:''}</div>\n        <div class=\"col\"><p class=\"sec\">2 · Escolha um tênis Vans</p>\n          <div class=\"field\"><input class=\"search-in\" placeholder=\"Buscar tênis… ex: old skool\" value=\"${esc(s.term||'')}\"/><button class=\"btn search-btn\">Buscar</button></div>\n          ${shoes}\n          ${sel?`<p class=\"sec\" style=\"margin-top:26px\">3 · Personalize (opcional)</p>${custPanel(s,sel)}`:''}</div>\n      </div>\n      <div class=\"cta-wrap\"><button class=\"cta\" ${canTry?'':'disabled'}>${s.tryingOn?'Provando…':(photo? (sel?`Provar ${esc(d2.fmt.truncate(sel.name,24))}`:'Selecione um tênis'):'Gere ou envie uma imagem primeiro')}</button></div>\n      ${resultPanel}\n    </div>`\n  },\n  mounted(d2){\n    const unwrap = (r)=> (r && typeof r==='object' && 'data' in r) ? r.data : r\n    const readDataUrl = (file)=> new Promise((res,rej)=>{ const fr=new FileReader(); fr.onload=()=>res(fr.result); fr.onerror=()=>rej(new Error('read fail')); fr.readAsDataURL(file) })\n    const loadImg = (src)=> new Promise((res,rej)=>{ const im=new Image(); im.onload=()=>res(im); im.onerror=()=>rej(new Error('img fail')); im.src=src })\n    const downscale = async (file, max=1100)=>{\n      const raw = await readDataUrl(file)\n      try{\n        const img = await loadImg(raw)\n        const big = Math.max(img.width, img.height)\n        if(big <= max) return raw\n        const sc = max/big, w=Math.round(img.width*sc), h=Math.round(img.height*sc)\n        const c=document.createElement('canvas'); c.width=w; c.height=h\n        c.getContext('2d').drawImage(img,0,0,w,h)\n        return c.toDataURL('image/jpeg',0.86)\n      }catch(_){ return raw }\n    }\n    const modelPrompt = (g)=>{\n      const who = g.gender==='mulher' ? 'uma mulher jovem' : 'um homem jovem'\n      const sm = {streetwear:'com roupa streetwear urbana moderna', casual:'com roupa casual do dia a dia', skatista:'com visual skatista, camiseta larga e calça'}\n      const sty = sm[g.style] || ''\n      if(g.framing==='pes') return `Foto fotorrealista em close dos pés e canelas de ${who}, ${sty}, em pé sobre calçada urbana, calçando um tênis casual neutro de cor clara, jeans levemente dobrado, luz natural de dia, altíssima qualidade, foco nítido nos pés e no calçado.`\n      return `Foto fotorrealista de corpo inteiro de ${who} em pé, ${sty}, calçando um tênis casual neutro de cor clara, fundo de estúdio cinza-claro liso, iluminação de estúdio suave, pose natural e relaxada, corpo inteiro visível incluindo os pés bem enquadrados, altíssima qualidade, estilo lookbook de moda.`\n    }\n    const pick = ()=>{ const f=d2.$('.file'); if(f) f.click() }\n    d2.on('.drop','click',pick)\n    d2.on('.tab','click',(e,el)=>{ d2.state.mode = el.dataset.mode })\n    d2.on('.chip','click',(e,el)=>{\n      const base = {gender:'homem',style:'streetwear',framing:'corpo'}\n      d2.state.gen = Object.assign(base, d2.state.gen||{}, { [el.dataset.gk]: el.dataset.gv })\n    })\n    d2.on('.chg','click',()=>{ d2.state.userPhotoUrl=''; d2.state.tryonUrl='' })\n    d2.on('.gen-btn','click', async ()=>{\n      if(d2.state.generating) return\n      d2.state.generating=true; d2.state.error=''\n      try{\n        const prompt = modelPrompt(d2.state.gen || {gender:'homem',style:'streetwear',framing:'corpo'})\n        const r = await d2.rush('vans-pp-model').invoke({prompt})\n        const body = unwrap(r)\n        const url = body && (body.url || body.fileUrl)\n        if(!url) throw new Error('sem imagem')\n        d2.state.userPhotoUrl = url\n      }catch(err){ d2.state.error='Não consegui gerar o modelo. Tente de novo.'; d2.log(err) }\n      finally{ d2.state.generating=false }\n    })\n    d2.on('.file','change', async (e,el)=>{\n      const files = el.files; if(!files || !files.length) return\n      d2.state.uploading = true; d2.state.error=''\n      try{\n        const dataUrl = await downscale(files[0])\n        const r = await d2.rush('vans-pp-upload').invoke({dataUrl})\n        const body = unwrap(r)\n        const url = body && (body.url || body.fileUrl)\n        if(!url) throw new Error('upload sem URL')\n        d2.state.userPhotoUrl = url\n      }catch(err){ d2.state.error = 'Falha no upload da foto. Tente outra imagem.'; d2.log(err) }\n      finally{ d2.state.uploading=false; const f=d2.$('.file'); if(f) f.value='' }\n    })\n    const doSearch = async ()=>{\n      const term = ((d2.$('.search-in')||{}).value||'').trim()\n      d2.state.term = term\n      if(!term) return\n      d2.state.searching=true; d2.state.error=''; d2.state.searched=true\n      try{\n        const r = await d2.rush('vans-pp-search').invoke({term})\n        const list = unwrap(r)\n        d2.state.results = Array.isArray(list)? list : []\n      }catch(err){ d2.state.error='Busca falhou.'; d2.state.results=[]; d2.log(err) }\n      finally{ d2.state.searching=false }\n    }\n    d2.on('.search-btn','click',doSearch)\n    d2.on('.search-in','keydown',(e)=>{ if(e.key==='Enter') doSearch() })\n    d2.on('.card','click',(e,el)=>{\n      const i = Number(el.dataset.idx); const r = (d2.state.results||[])[i]\n      if(r){ d2.state.selected = r; d2.state.customParts=[]; d2.state.custom={}; d2.state.customFor=null }\n    })\n    d2.on('.cust-btn','click', async ()=>{\n      const sel=d2.state.selected; if(!sel || d2.state.analyzing) return\n      d2.state.analyzing=true; d2.state.error=''\n      try{\n        const r=await d2.rush('vans-pp-customize').invoke({shoeImageUrl: sel.image||sel.thumb, shoeName: sel.name})\n        const body=unwrap(r); const parts=(body&&body.parts)||[]\n        d2.state.customParts=Array.isArray(parts)?parts:[]; d2.state.customFor=sel.code; d2.state.custom={}\n      }catch(err){ d2.state.error='Não consegui gerar as opções de customização.'; d2.log(err) }\n      finally{ d2.state.analyzing=false }\n    })\n    d2.on('.swatch','click',(e,el)=>{\n      const pid=el.dataset.pid, oval=el.dataset.oval\n      const part=(d2.state.customParts||[]).find(p=>p.id===pid); if(!part) return\n      const opt=(part.options||[]).find(o=>o.value===oval); if(!opt) return\n      const cur=Object.assign({}, d2.state.custom||{})\n      if(cur[pid] && cur[pid].value===oval) delete cur[pid]\n      else cur[pid]={value:opt.value,label:opt.label,hex:opt.hex,part:part.label}\n      d2.state.custom=cur\n    })\n    d2.on('.clearc','click',()=>{ d2.state.custom={} })\n    d2.on('.cta','click', async ()=>{\n      const photo = d2.state.userPhotoUrl, sel = d2.state.selected\n      if(!photo || !sel || d2.state.tryingOn) return\n      d2.state.tryingOn=true; d2.state.error=''; d2.state.tryonUrl=''\n      try{\n        const shoeImg = sel.image || sel.thumb\n        let spec = ''\n        if(d2.state.customFor===sel.code){\n          const cps = d2.state.customParts||[], cm = d2.state.custom||{}\n          spec = cps.map(p=>{ const c=cm[p.id]; return c?`${p.label}: ${c.label}`:null }).filter(Boolean).join('; ')\n        }\n        const r = await d2.rush('vans-pp-tryon').invoke({userPhotoUrl:photo, shoeImageUrl:shoeImg, customization:spec})\n        const body = unwrap(r)\n        const url = body && body.image\n        if(!url) throw new Error('sem imagem')\n        d2.state.tryonUrl = url\n      }catch(err){ d2.state.error='O provador falhou. Tente outra imagem.'; d2.log(err) }\n      finally{ d2.state.tryingOn=false }\n    })\n    d2.on('.chg2','click',()=>{ d2.state.tryonUrl='' })\n  },\n  updated(d2){\n    if(d2.state.tryonUrl && d2.state._shownFor !== d2.state.tryonUrl){\n      d2.state._shownFor = d2.state.tryonUrl\n      const r = d2.$('.result'); if(r) r.scrollIntoView({behavior:'smooth', block:'start'})\n    }\n  },\n}\nfunction custPanel(s, sel){\n  if(s.analyzing) return `<div class=\"custbox\"><div class=\"center\"><div class=\"spin\"></div><p>Analisando o ${esc(sel.name)}…</p></div></div>`\n  const parts = (s.customFor===sel.code ? s.customParts : null) || []\n  if(!parts.length) return `<div class=\"custbox\"><button class=\"btn cust-btn\" style=\"width:100%\">🎨 Gerar opções de customização</button></div>`\n  const custom = s.custom || {}\n  const rows = parts.map(p=>`<div class=\"crow\"><div class=\"cl\">${esc(p.label)}</div><div class=\"sw\">${(p.options||[]).map(o=>`<button class=\"swatch ${custom[p.id]&&custom[p.id].value===o.value?'on':''}\" data-pid=\"${esc(p.id)}\" data-oval=\"${esc(o.value)}\" title=\"${esc(o.label)}\" style=\"background:${esc(o.hex||'#ccc')}\"></button>`).join('')}</div></div>`).join('')\n  return `<div class=\"custbox\"><div class=\"chead\"><span>Personalize seu par</span><button class=\"clearc\">Limpar</button></div>${rows}</div>`\n}\nfunction esc(s){ return String(s==null?'':s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/\"/g,'&quot;') }"}}}}}}}},{"_id":"6a39d74d2d136cb72d6c601a","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kClothChart","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n    .wrap{position:relative;width:100%;height:100%;overflow:hidden;border-radius:inherit}\n    .cv{display:block;width:100%;height:100%;touch-action:none;cursor:crosshair}\n  `,\n  render(d2){\n    const bg = d2.param('bg', '#0b0b14');\n    return `<div class=\"wrap\" style=\"background:${bg}\">\n      <canvas class=\"cv\" data-d2-static></canvas>\n    </div>`;\n  },\n  mounted(d2, root){\n    const cv = d2.$('.cv'); const ctx = cv.getContext('2d');\n    const clamp = (v,a,b) => Math.max(a, Math.min(b, v));\n    const clampInt = (v,a,b) => Math.max(a, Math.min(b, Math.round(Number(v) || a)));\n\n    function fieldKey(f){\n      if (f == null) return null;\n      if (typeof f === 'string') return f;\n      if (typeof f === 'object'){\n        if (f.key) return f.key;\n        if (f.params && f.params.key) return f.params.key;\n        if (f.value && typeof f.value === 'string') return f.value;\n      }\n      return null;\n    }\n    function scalarOf(v){\n      if (v == null) return v;\n      if (typeof v === 'object'){\n        if (v.params && 'content' in v.params) return v.params.content;\n        if ('content' in v) return v.content;\n        if ('value' in v && typeof v.value !== 'object') return v.value;\n        if ('_value' in v) return v._value;\n      }\n      return v;\n    }\n    function recVal(rec, key){\n      if (!rec || key == null) return undefined;\n      return scalarOf(rec[key]);\n    }\n    function colorOf(dc){\n      const p = (dc && dc.params) ? dc.params : dc;\n      if (!p) return null;\n      let rgba = null; const c = p.color;\n      if (c){\n        if (typeof c === 'string') rgba = c;\n        else if (c.params && c.params.rgba) rgba = c.params.rgba;\n        else if (c.rgba) rgba = c.rgba;\n      }\n      return { rgba, field: fieldKey(p.field), value: scalarOf(p.value) };\n    }\n\n    let W=0, H=0, dpr=1, baselineY=0, plotL=64, plotT=54, maxVal=1;\n    let bars=[], dcs=[], metricKey=null, dimKey=null, rawRecords=[], rawSample=null, sig='';\n\n    function size(){\n      dpr = window.devicePixelRatio || 1;\n      W = cv.clientWidth; H = cv.clientHeight;\n      cv.width = Math.max(1, Math.round(W*dpr));\n      cv.height = Math.max(1, Math.round(H*dpr));\n      ctx.setTransform(1,0,0,1,0,0); ctx.scale(dpr,dpr);\n    }\n\n    function colorForLabel(label, i){\n      for (const dc of dcs){\n        if (dc.value != null && String(dc.value) === String(label) && dc.rgba) return dc.rgba;\n      }\n      const pal = dcs.filter(dc => (dc.value == null || dc.value === '') && dc.rgba);\n      if (pal.length) return pal[i % pal.length].rgba;\n      const fb = ['#6d5dff','#ff5d8f','#22c1a6','#ffb020','#4d9bff','#e26cff'];\n      return fb[i % fb.length];\n    }\n\n    function build(){\n      size();\n      metricKey = fieldKey(d2.param('metric'));\n      dimKey = fieldKey(d2.param('dimension'));\n      let raw = d2.param('dataset', []);\n      if (raw && typeof raw.records === 'function') raw = raw.records();\n      rawRecords = Array.isArray(raw) ? raw : [];\n      rawSample = rawRecords[0] || null;\n      const dcRaw = d2.param('dataColors', []) || [];\n      dcs = (Array.isArray(dcRaw) ? dcRaw : []).map(colorOf).filter(Boolean);\n\n      const recs = rawRecords\n        .map(r => ({ label: recVal(r, dimKey), value: Number(recVal(r, metricKey)) }))\n        .filter(d => d.label != null && isFinite(d.value));\n\n      const padL=64, padR=28, padT=54, padB=66;\n      plotL = padL; plotT = padT;\n      baselineY = H - padB;\n      const chartW = Math.max(10, W - padL - padR);\n      const chartH = Math.max(10, baselineY - padT);\n      maxVal = Math.max(1, ...recs.map(d => d.value));\n\n      const n = recs.length;\n      const slot = n ? chartW / n : chartW;\n      bars = [];\n      for (let i=0;i<n;i++){\n        const d = recs[i];\n        const barH = Math.max(10, (d.value / maxVal) * chartH);\n        const bw = Math.min(slot * 0.62, 160);\n        const cx = padL + slot*i + slot/2;\n        const left = cx - bw/2;\n        const topY = baselineY - barH;\n        const cols = Math.max(3, Math.round(bw/15));\n        const rows = Math.max(4, Math.round(barH/15));\n        const sx = bw/cols, sy = barH/rows;\n        const pts = [];\n        for (let y=0;y<=rows;y++) for (let x=0;x<=cols;x++){\n          const px = left + x*sx, py = topY + y*sy;\n          pts.push({ x:px, y:py, ox:px, oy:py, ry:py, pinned:false });\n        }\n        const idx = (x,y) => y*(cols+1)+x;\n        for (let x=0;x<=cols;x++) pts[idx(x,rows)].pinned = true;\n        pts[idx(0,0)].pinned = true; pts[idx(cols,0)].pinned = true;\n        const st = [];\n        for (let y=0;y<=rows;y++) for (let x=0;x<=cols;x++){\n          if (x<cols) st.push([idx(x,y), idx(x+1,y), sx]);\n          if (y<rows) st.push([idx(x,y), idx(x,y+1), sy]);\n        }\n        bars.push({ pts, st, cols, rows, sx, sy, barH, cx, idx,\n                    color: colorForLabel(d.label, i), label: d.label, value: d.value });\n      }\n      sig = computeSig();\n    }\n\n    function computeSig(){\n      let raw = d2.param('dataset', []);\n      if (raw && typeof raw.records === 'function') raw = raw.records();\n      return JSON.stringify([\n        fieldKey(d2.param('metric')), fieldKey(d2.param('dimension')),\n        Array.isArray(raw) ? raw : [], d2.param('dataColors', []),\n        Math.round(cv.clientWidth), Math.round(cv.clientHeight)\n      ]);\n    }\n\n    function simulate(t){\n      const wind = Number(d2.param('wind', 0.6)) || 0;\n      const grav = Number(d2.param('gravity', 0.08)) || 0;\n      let damp = Number(d2.param('damping', 0.97)); if (!(damp>0)) damp = 0.97;\n      damp = clamp(damp, 0.8, 0.995);\n      const iter = clampInt(d2.param('stiffness', 6), 1, 12);\n      const amp = Number(d2.param('amplitude', 1)) || 1;\n      for (let bi=0; bi<bars.length; bi++){\n        const bar = bars[bi];\n        for (const p of bar.pts){\n          if (p.pinned) continue;\n          const hf = clamp((baselineY - p.y) / Math.max(1, bar.barH), 0, 1);\n          const w = wind * amp * hf * Math.sin(t/280 + p.ry*0.06 + bi*1.3) * (bar.sx*0.12);\n          const vx = (p.x-p.ox)*damp, vy = (p.y-p.oy)*damp;\n          p.ox = p.x; p.oy = p.y;\n          p.x += vx + w; p.y += vy + grav;\n        }\n        for (let k=0;k<iter;k++){\n          for (const s of bar.st){\n            const a = bar.pts[s[0]], b = bar.pts[s[1]];\n            const dx = b.x-a.x, dy = b.y-a.y;\n            const dd = Math.sqrt(dx*dx+dy*dy) || 0.0001;\n            const diff = ((s[2]-dd)/dd)*0.5;\n            const ox = dx*diff, oy = dy*diff;\n            if (!a.pinned){ a.x-=ox; a.y-=oy; }\n            if (!b.pinned){ b.x+=ox; b.y+=oy; }\n          }\n        }\n      }\n    }\n\n    function draw(){\n      ctx.clearRect(0,0,W,H);\n      ctx.strokeStyle='rgba(255,255,255,0.07)'; ctx.lineWidth=1;\n      ctx.fillStyle='rgba(255,255,255,0.35)';\n      ctx.font='11px ui-monospace,monospace'; ctx.textAlign='right'; ctx.textBaseline='middle';\n      const ticks=4;\n      for (let i=0;i<=ticks;i++){\n        const v = maxVal*i/ticks;\n        const y = baselineY - (baselineY - plotT)*(i/ticks);\n        ctx.beginPath(); ctx.moveTo(plotL, y); ctx.lineTo(W-28, y); ctx.stroke();\n        ctx.fillText(String(Math.round(v)), plotL-8, y);\n      }\n      ctx.strokeStyle='rgba(255,255,255,0.28)';\n      ctx.beginPath(); ctx.moveTo(plotL, baselineY); ctx.lineTo(W-28, baselineY); ctx.stroke();\n\n      const title = d2.param('title', '');\n      if (title){\n        ctx.fillStyle='rgba(255,255,255,0.92)'; ctx.font='600 16px ui-sans-serif,system-ui,sans-serif';\n        ctx.textAlign='left'; ctx.textBaseline='top'; ctx.fillText(String(title), plotL, 16);\n      }\n\n      if (!bars.length){\n        ctx.fillStyle='rgba(255,120,120,0.95)'; ctx.font='13px ui-monospace,monospace';\n        ctx.textAlign='left'; ctx.textBaseline='top';\n        ctx.fillText('cloth-chart: no bars parsed', 20, 40);\n        ctx.fillStyle='rgba(255,255,255,0.7)';\n        ctx.fillText('metricKey=' + metricKey + '  dimKey=' + dimKey, 20, 60);\n        ctx.fillText('records=' + (rawRecords ? rawRecords.length : '?'), 20, 78);\n        ctx.fillText('sample=' + JSON.stringify(rawSample).slice(0,140), 20, 96);\n        ctx.fillText('dataColors=' + JSON.stringify(dcs).slice(0,140), 20, 114);\n        return;\n      }\n\n      const showMesh = d2.param('showMesh', false);\n      for (const bar of bars){\n        for (let y=0;y<bar.rows;y++) for (let x=0;x<bar.cols;x++){\n          const p00=bar.pts[bar.idx(x,y)], p10=bar.pts[bar.idx(x+1,y)];\n          const p01=bar.pts[bar.idx(x,y+1)], p11=bar.pts[bar.idx(x+1,y+1)];\n          const curW = ((p10.x-p00.x)+(p11.x-p01.x))*0.5;\n          let sh = 1 - (curW / Math.max(0.001, bar.sx));\n          sh = clamp(sh*1.5, -0.42, 0.55);\n          ctx.fillStyle = bar.color;\n          ctx.beginPath();\n          ctx.moveTo(p00.x,p00.y); ctx.lineTo(p10.x,p10.y);\n          ctx.lineTo(p11.x,p11.y); ctx.lineTo(p01.x,p01.y); ctx.closePath();\n          ctx.fill();\n          ctx.fillStyle = sh>0 ? 'rgba(0,0,0,'+sh+')' : 'rgba(255,255,255,'+(-sh)+')';\n          ctx.fill();\n        }\n        if (showMesh){\n          ctx.strokeStyle='rgba(255,255,255,0.15)'; ctx.lineWidth=0.5; ctx.beginPath();\n          for (const s of bar.st){ const a=bar.pts[s[0]], b=bar.pts[s[1]]; ctx.moveTo(a.x,a.y); ctx.lineTo(b.x,b.y); }\n          ctx.stroke();\n        }\n        let tx=0, ty=0;\n        for (let x=0;x<=bar.cols;x++){ const p=bar.pts[bar.idx(x,0)]; tx+=p.x; ty+=p.y; }\n        tx/=(bar.cols+1); ty/=(bar.cols+1);\n        ctx.fillStyle='rgba(255,255,255,0.95)'; ctx.font='600 14px ui-sans-serif,system-ui,sans-serif';\n        ctx.textAlign='center'; ctx.textBaseline='bottom';\n        ctx.fillText(String(bar.value), tx, ty-8);\n        ctx.fillStyle='rgba(255,255,255,0.62)'; ctx.font='12px ui-sans-serif,system-ui,sans-serif';\n        ctx.textBaseline='top';\n        ctx.fillText(String(bar.label), bar.cx, baselineY+10);\n      }\n    }\n\n    build();\n\n    d2.on(cv, 'pointerdown', (e) => {\n      const r = cv.getBoundingClientRect();\n      const mx = e.clientX - r.left, my = e.clientY - r.top;\n      for (const bar of bars) for (const p of bar.pts){\n        if (p.pinned) continue;\n        const dx = p.x-mx, dy = p.y-my, d2d = dx*dx+dy*dy;\n        if (d2d < 7000){ const f = 10/Math.sqrt(d2d+1); p.ox -= dx*f; p.oy -= dy*f*0.3; }\n      }\n    });\n\n    d2.raf((t) => {\n      const s = computeSig();\n      if (s !== sig) build();\n      simulate(t);\n      draw();\n    });\n  },\n}"}},"metric":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"metric"}}}},"dimension":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"dimension"}}}},"dataset":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"dataset"}}}},"dataColors":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"dataColors"}}}},"type":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"type"}}}},"title":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"title"}}}},"wind":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"wind"}}}},"gravity":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"gravity"}}}},"stiffness":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"stiffness"}}}},"damping":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"damping"}}}},"amplitude":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"amplitude"}}}},"showMesh":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"showMesh"}}}},"bg":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"bg"}}}}}}}}}},{"_id":"6a39dc3b1ad3726794469905","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kStlViewer","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n    .wrap{position:relative;width:100%;height:100%;overflow:hidden;border-radius:inherit;font:13px ui-sans-serif,system-ui,sans-serif}\n    .cv{display:block;width:100%;height:100%;cursor:grab;touch-action:none}\n    .cv:active{cursor:grabbing}\n    .wrap.drag .cv{filter:brightness(1.15)}\n    .hud{position:absolute;left:0;right:0;bottom:0;display:flex;align-items:center;gap:12px;padding:10px 14px;\n         background:linear-gradient(transparent,rgba(0,0,0,.55));color:rgba(255,255,255,.75);pointer-events:none}\n    .hud b{color:#fff}\n    .hud .hint{color:rgba(255,255,255,.45);font:11px ui-monospace,monospace;letter-spacing:.03em}\n    .hud .err{color:#ff9a9a}\n    .browse{pointer-events:auto;margin-left:auto;border:1px solid rgba(255,255,255,.25);background:rgba(255,255,255,.08);\n            color:#fff;padding:6px 12px;border-radius:8px;cursor:pointer;font:12px ui-sans-serif,system-ui;white-space:nowrap}\n    .browse:hover{background:rgba(255,255,255,.16)}\n    .drophint{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;pointer-events:none;opacity:0;transition:opacity .15s}\n    .wrap.drag .drophint{opacity:1}\n    .drophint span{border:2px dashed rgba(255,255,255,.5);border-radius:16px;padding:24px 40px;color:#fff;background:rgba(0,0,0,.3)}\n  `,\n  render(d2){\n    const bg = d2.param('bg', '#0e0e16');\n    const has = d2.state.hasModel;\n    const name = (d2.state.fileName || '').replace(/</g,'&lt;');\n    const tris = d2.state.tris || 0;\n    const err = d2.state.err || '';\n    return `<div class=\"wrap\" style=\"background:${bg}\">\n      <canvas class=\"cv\" data-d2-static></canvas>\n      <div class=\"drophint\"><span>Solte o .STL</span></div>\n      <div class=\"hud\">\n        ${has ? `<b>${name}</b>` : `<b>demo</b>`}\n        <span class=\"hint\">${tris.toLocaleString()} tris · arraste p/ girar · scroll zoom · dbl-click reset</span>\n        ${err ? `<span class=\"err\">${err}</span>` : ''}\n        <button class=\"browse\">${has ? 'trocar STL' : 'escolher .STL'}</button>\n      </div>\n      <input class=\"file\" type=\"file\" accept=\".stl,model/stl,application/sla\" hidden />\n    </div>`;\n  },\n  mounted(d2, root){\n    const cv = d2.$('.cv'); const ctx = cv.getContext('2d');\n    const clamp = (v,a,b) => Math.max(a, Math.min(b, v));\n    const L = (() => { const x=0.4,y=0.7,z=0.6, m=Math.hypot(x,y,z); return [x/m,y/m,z/m]; })();\n    const AMB = 0.26, DIF = 0.82;\n\n    let W=0,H=0,dpr=1;\n    let model=null, SX=null, SY=null, RZ=null, ORD=null, DEP=null, INT=null;\n    let rotX=-0.45, rotY=0.6, zoom=1, dirty=true, dragging=false, drag={x:0,y:0};\n    let lastUrl=null;\n\n    function size(){\n      dpr = window.devicePixelRatio || 1;\n      W = cv.clientWidth; H = cv.clientHeight;\n      cv.width = Math.max(1, Math.round(W*dpr));\n      cv.height = Math.max(1, Math.round(H*dpr));\n      ctx.setTransform(1,0,0,1,0,0); ctx.scale(dpr,dpr);\n    }\n    function parseColor(s, fb){\n      s = (s==null?'':String(s)).trim(); if(!s) s=fb;\n      if (s[0]==='#'){ let h=s.slice(1); if(h.length===3) h=h.split('').map(c=>c+c).join('');\n        const n=parseInt(h,16); if(isFinite(n)) return [(n>>16)&255,(n>>8)&255,n&255]; return parseColor(fb,'#cccccc'); }\n      const m=s.match(/rgba?\\(([^)]+)\\)/i); if(m){ const p=m[1].split(',').map(parseFloat); return [p[0]||0,p[1]||0,p[2]||0]; }\n      return parseColor(fb,'#cccccc');\n    }\n    function colorStr(v, fb){ if(v==null) return fb; if(typeof v==='string') return v; if(v.params&&v.params.rgba) return v.params.rgba; if(v.rgba) return v.rgba; return fb; }\n    function cross(ax,ay,az,bx,by,bz){ return [ay*bz-az*by, az*bx-ax*bz, ax*by-ay*bx]; }\n\n    function parseSTL(buf){\n      const dv=new DataView(buf);\n      if (buf.byteLength>=84){ const nTri=dv.getUint32(80,true); if(84+nTri*50===buf.byteLength) return parseBinary(dv,nTri); }\n      const text=new TextDecoder().decode(new Uint8Array(buf));\n      if (/^\\s*solid/i.test(text) || text.indexOf('facet')!==-1) return parseAscii(text);\n      if (buf.byteLength>=84){ const nTri=dv.getUint32(80,true); if(nTri>0 && 84+nTri*50<=buf.byteLength) return parseBinary(dv,nTri); }\n      return null;\n    }\n    function parseBinary(dv,n){\n      const pos=new Float32Array(n*9), nor=new Float32Array(n*3); let o=84;\n      for(let i=0;i<n;i++){ nor[i*3]=dv.getFloat32(o,true); nor[i*3+1]=dv.getFloat32(o+4,true); nor[i*3+2]=dv.getFloat32(o+8,true);\n        for(let k=0;k<9;k++) pos[i*9+k]=dv.getFloat32(o+12+k*4,true); o+=50; }\n      return { pos, nor, tris:n };\n    }\n    function parseAscii(text){\n      const blocks=text.split(/facet/i).slice(1); const posA=[], norA=[];\n      for(const b of blocks){ const nums=b.match(/[-+]?\\d*\\.?\\d+(?:[eE][-+]?\\d+)?/g); if(!nums||nums.length<12) continue;\n        const f=nums.map(Number); norA.push(f[0],f[1],f[2]); for(let k=0;k<9;k++) posA.push(f[3+k]); }\n      return { pos:new Float32Array(posA), nor:new Float32Array(norA), tris:(posA.length/9)|0 };\n    }\n\n    function setModel(geo, name, isReal){\n      const pos=geo.pos, nor=geo.nor, n=geo.tris;\n      let minx=1e30,miny=1e30,minz=1e30,maxx=-1e30,maxy=-1e30,maxz=-1e30;\n      for(let v=0;v<n*3;v++){ const x=pos[v*3],y=pos[v*3+1],z=pos[v*3+2];\n        if(x<minx)minx=x; if(y<miny)miny=y; if(z<minz)minz=z; if(x>maxx)maxx=x; if(y>maxy)maxy=y; if(z>maxz)maxz=z; }\n      const ccx=(minx+maxx)/2, ccy=(miny+maxy)/2, ccz=(minz+maxz)/2;\n      const dim=Math.max(maxx-minx, maxy-miny, maxz-minz)||1; const sc=2/dim;\n      for(let v=0;v<n*3;v++){ pos[v*3]=(pos[v*3]-ccx)*sc; pos[v*3+1]=(pos[v*3+1]-ccy)*sc; pos[v*3+2]=(pos[v*3+2]-ccz)*sc; }\n      for(let i=0;i<n;i++){ let nx=nor[i*3],ny=nor[i*3+1],nz=nor[i*3+2]; let m=Math.hypot(nx,ny,nz);\n        if(m<1e-6){ const a=i*9; const e1x=pos[a+3]-pos[a],e1y=pos[a+4]-pos[a+1],e1z=pos[a+5]-pos[a+2];\n          const e2x=pos[a+6]-pos[a],e2y=pos[a+7]-pos[a+1],e2z=pos[a+8]-pos[a+2];\n          const c=cross(e1x,e1y,e1z,e2x,e2y,e2z); nx=c[0];ny=c[1];nz=c[2]; m=Math.hypot(nx,ny,nz)||1; }\n        nor[i*3]=nx/m; nor[i*3+1]=ny/m; nor[i*3+2]=nz/m; }\n      model={pos,nor,tris:n};\n      SX=new Float32Array(n*3); SY=new Float32Array(n*3); RZ=new Float32Array(n*3);\n      ORD=new Int32Array(n); DEP=new Float32Array(n); INT=new Float32Array(n);\n      rotX=-0.45; rotY=0.6; zoom=1; dirty=true;\n      d2.setState({ hasModel:!!isReal, fileName:name||'', tris:n, err:'' });\n    }\n\n    function makeSphere(seg){\n      const u=seg, vS=Math.max(4, Math.round(seg/2)); const posA=[], norA=[];\n      const P=(i,j)=>{ const th=i/u*Math.PI*2, ph=j/vS*Math.PI; return [Math.sin(ph)*Math.cos(th), Math.cos(ph), Math.sin(ph)*Math.sin(th)]; };\n      const tri=(a,b,c)=>{ posA.push(a[0],a[1],a[2],b[0],b[1],b[2],c[0],c[1],c[2]);\n        const cN=cross(b[0]-a[0],b[1]-a[1],b[2]-a[2], c[0]-a[0],c[1]-a[1],c[2]-a[2]); const m=Math.hypot(cN[0],cN[1],cN[2])||1;\n        norA.push(cN[0]/m,cN[1]/m,cN[2]/m); };\n      for(let j=0;j<vS;j++) for(let i=0;i<u;i++){ const a=P(i,j),b=P(i+1,j),c=P(i+1,j+1),d=P(i,j+1); tri(a,b,c); tri(a,c,d); }\n      return { pos:new Float32Array(posA), nor:new Float32Array(norA), tris:(posA.length/9)|0 };\n    }\n\n    function loadFile(file){ if(!file) return; const r=new FileReader();\n      r.onload=()=>{ try{ const geo=parseSTL(r.result); if(geo&&geo.tris) setModel(geo,file.name,true); else d2.setState({err:'Não consegui ler esse STL'});\n        }catch(e){ d2.setState({err:'Erro ao parsear: '+(e&&e.message||'')}); } };\n      r.onerror=()=>d2.setState({err:'Falha ao ler o arquivo'}); r.readAsArrayBuffer(file); }\n\n    function loadUrl(){\n      const url=(d2.param('fileUrl','')||'').trim();\n      if(url===lastUrl) return; lastUrl=url;\n      if(!url) return;\n      d2.setState({ err:'carregando…' });\n      fetch(url).then(res=>{ if(!res.ok) throw new Error('HTTP '+res.status); return res.arrayBuffer(); })\n        .then(buf=>{ const geo=parseSTL(buf); if(geo&&geo.tris) setModel(geo, url.split('/').pop().split('?')[0], true);\n          else d2.setState({err:'STL inválido na URL'}); })\n        .catch(e=>d2.setState({ err:'URL: '+(e&&e.message||'erro')+' (CORS?)' }));\n    }\n\n    function draw(){\n      ctx.clearRect(0,0,W,H);\n      if (!model) return;\n      const n=model.tris, pos=model.pos, nor=model.nor;\n      const cx=W/2, cyT=(H-44)/2, s=Math.min(W,H)*0.36*zoom, dist=3.0, f=2.4;\n      const cY=Math.cos(rotY),sY=Math.sin(rotY),cX=Math.cos(rotX),sX=Math.sin(rotX);\n      const wire=d2.param('wireframe', false);\n      const doCull=d2.param('cull', true) && !wire;\n      const base=parseColor(colorStr(d2.param('modelColor'),'#b9c2d0'),'#b9c2d0');\n\n      let mnx=1e30,mny=1e30,mxx=-1e30,mxy=-1e30;\n      for(let v=0;v<n*3;v++){\n        const o=v*3; const x=pos[o],y=pos[o+1],z=pos[o+2];\n        const x1=x*cY+z*sY, z1=-x*sY+z*cY;\n        const y2=y*cX - z1*sX, z2=y*sX + z1*cX;\n        const persp=f/(dist - z2);\n        const sx=W/2 + x1*persp*s, sy=H/2 - y2*persp*s;\n        SX[v]=sx; SY[v]=sy; RZ[v]=z2;\n        if(sx<mnx)mnx=sx; if(sx>mxx)mxx=sx; if(sy<mny)mny=sy; if(sy>mxy)mxy=sy;\n      }\n      // recenter projected silhouette (perspective can shift it off-center)\n      const offx=cx-(mnx+mxx)/2, offy=cyT-(mny+mxy)/2;\n      if(offx||offy){ for(let v=0;v<n*3;v++){ SX[v]+=offx; SY[v]+=offy; } }\n\n      let count=0;\n      for(let i=0;i<n;i++){\n        const no=i*3; const nx=nor[no],ny=nor[no+1],nz=nor[no+2];\n        const nx1=nx*cY+nz*sY, nz1=-nx*sY+nz*cY;\n        const ny2=ny*cX - nz1*sX, nz2=ny*sX + nz1*cX;\n        if(doCull && nz2<=0) continue;\n        ORD[count]=i; DEP[count]=RZ[i*3]+RZ[i*3+1]+RZ[i*3+2];\n        INT[count]=AMB + DIF*Math.max(0, nx1*L[0] + ny2*L[1] + nz2*L[2]); count++;\n      }\n      const idx=[]; for(let k=0;k<count;k++) idx.push(k); idx.sort((a,b)=>DEP[a]-DEP[b]);\n      for(let k=0;k<count;k++){ const p=idx[k], i=ORD[p], a=i*3;\n        ctx.beginPath(); ctx.moveTo(SX[a],SY[a]); ctx.lineTo(SX[a+1],SY[a+1]); ctx.lineTo(SX[a+2],SY[a+2]); ctx.closePath();\n        if(wire){ ctx.strokeStyle='rgba(180,210,255,0.5)'; ctx.lineWidth=0.6; ctx.stroke(); }\n        else { const it=INT[p]; ctx.fillStyle='rgb('+Math.round(base[0]*it)+','+Math.round(base[1]*it)+','+Math.round(base[2]*it)+')';\n          ctx.fill(); ctx.strokeStyle=ctx.fillStyle; ctx.lineWidth=0.5; ctx.stroke(); } }\n    }\n\n    size();\n    setModel(makeSphere(26), '', false);\n    loadUrl();\n\n    if(typeof ResizeObserver!=='undefined'){ const ro=new ResizeObserver(()=>{ size(); dirty=true; }); ro.observe(root); d2.onUnmount(()=>ro.disconnect()); }\n    d2.on('.wrap','dragover',(e)=>{ e.preventDefault(); root.querySelector('.wrap')&&root.querySelector('.wrap').classList.add('drag'); });\n    d2.on('.wrap','dragleave',()=>{ root.querySelector('.wrap')&&root.querySelector('.wrap').classList.remove('drag'); });\n    d2.on('.wrap','drop',(e)=>{ e.preventDefault(); root.querySelector('.wrap')&&root.querySelector('.wrap').classList.remove('drag');\n      loadFile(e.dataTransfer&&e.dataTransfer.files&&e.dataTransfer.files[0]); });\n    d2.on('.browse','click',()=>{ const fIn=d2.$('.file'); if(fIn) fIn.click(); });\n    d2.on('.file','change',(e,el)=>{ loadFile(el.files&&el.files[0]); el.value=''; });\n    d2.on(cv,'pointerdown',(e)=>{ dragging=true; drag.x=e.clientX; drag.y=e.clientY; cv.setPointerCapture&&cv.setPointerCapture(e.pointerId); });\n    d2.on(window,'pointermove',(e)=>{ if(!dragging) return; rotY += (e.clientX-drag.x)*0.01; rotX += (e.clientY-drag.y)*0.01;\n      rotX=clamp(rotX,-1.55,1.55); drag.x=e.clientX; drag.y=e.clientY; dirty=true; });\n    d2.on(window,'pointerup',()=>{ dragging=false; });\n    d2.on(cv,'wheel',(e)=>{ e.preventDefault(); zoom=clamp(zoom*(1-e.deltaY*0.0012),0.25,8); dirty=true; });\n    d2.on(cv,'dblclick',()=>{ rotX=-0.45; rotY=0.6; zoom=1; dirty=true; });\n\n    d2.raf(()=>{\n      loadUrl();\n      if (!model) return;\n      if (d2.param('autoRotate', true) && !dragging){ rotY += 0.005; dirty=true; }\n      if (dirty){ draw(); dirty=false; }\n    });\n  },\n}"}},"fileUrl":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"fileUrl"}}}},"modelColor":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"modelColor"}}}},"bg":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"bg"}}}},"autoRotate":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"autoRotate"}}}},"wireframe":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"wireframe"}}}},"cull":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"cull"}}}}}}}}}},{"_id":"6a39dd73abae7186c29fcb70","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kNormalBlock","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `\n    .wrap{position:relative;width:100%;height:100%;overflow:hidden;border-radius:inherit;font:12px ui-sans-serif,system-ui,sans-serif}\n    .cv{position:absolute;inset:0;display:block;width:100%;height:100%;cursor:crosshair;touch-action:none}\n    .wrap.drag .cv{filter:brightness(1.1)}\n    .hud{position:absolute;left:0;right:0;bottom:0;display:flex;align-items:center;gap:10px;padding:8px 12px;\n         background:linear-gradient(transparent,rgba(0,0,0,.35));color:rgba(255,255,255,.7);pointer-events:none}\n    .hud b{color:#fff}\n    .browse{pointer-events:auto;margin-left:auto;border:1px solid rgba(255,255,255,.3);background:rgba(0,0,0,.25);\n            color:#fff;padding:5px 10px;border-radius:7px;cursor:pointer;font:11px ui-sans-serif}\n    .browse:hover{background:rgba(0,0,0,.45)}\n  `,\n  render(d2){\n    const bg = d2.param('bg', 'transparent');\n    const frost = Math.max(0, Number(d2.param('frost', 0)) || 0);\n    const bf = frost > 0 ? `backdrop-filter:blur(${frost}px);-webkit-backdrop-filter:blur(${frost}px);` : '';\n    return `<div class=\"wrap\" style=\"background:${bg};${bf}\">\n      <canvas class=\"cv\" data-d2-static></canvas>\n      <div class=\"hud\"><b>normal block</b> · luz = mouse · aplica no que está atrás\n        <button class=\"browse\">${d2.state.srcName || 'normal map…'}</button></div>\n      <input class=\"file\" type=\"file\" accept=\"image/*\" hidden />\n    </div>`;\n  },\n  mounted(d2, root){\n    const cv = d2.$('.cv'); const ctx = cv.getContext('2d');\n    const work = document.createElement('canvas'); const wctx = work.getContext('2d', { willReadFrequently:true });\n    const clamp = (v,a,b)=>Math.max(a,Math.min(b,v));\n    const num=(v,fb)=>{ const n=Number(v); return isFinite(n)?n:fb; };\n    const TARGET = 240;\n\n    let W=0,H=0,dpr=1, src=null, outData=null, wW=0,wH=0, dirty=true, lastTex=null;\n    const light={x:120,y:90,z:120,have:false};\n\n    function colorStr(v,fb){ if(v==null)return fb; if(typeof v==='string')return v; if(v.params&&v.params.rgba)return v.params.rgba; if(v.rgba)return v.rgba; return fb; }\n    function parseColor(s,fb){ s=(s==null?'':String(s)).trim(); if(!s)s=fb;\n      if(s[0]==='#'){ let h=s.slice(1); if(h.length===3)h=h.split('').map(c=>c+c).join(''); const n=parseInt(h,16); if(isFinite(n))return [(n>>16)&255,(n>>8)&255,n&255]; return parseColor(fb,'#fff'); }\n      const m=s.match(/rgba?\\(([^)]+)\\)/i); if(m){ const p=m[1].split(',').map(parseFloat); return [p[0]||0,p[1]||0,p[2]||0]; }\n      return parseColor(fb,'#fff'); }\n\n    function size(){ dpr=window.devicePixelRatio||1; W=cv.clientWidth; H=cv.clientHeight;\n      cv.width=Math.max(1,Math.round(W*dpr)); cv.height=Math.max(1,Math.round(H*dpr));\n      ctx.setTransform(1,0,0,1,0,0); ctx.scale(dpr,dpr); ctx.imageSmoothingEnabled=true; }\n\n    function alloc(imgData,w,h){ src=imgData.data; wW=w; wH=h; outData=ctx.createImageData(w,h); work.width=w; work.height=h;\n      light.x=w*0.6; light.y=h*0.32; light.z=Math.max(w,h)*0.5; dirty=true; }\n\n    function genDefault(){\n      const w=220,h=220; const id=new ImageData(w,h); const d=id.data; const cell=44;\n      const Hf=(x,y)=>{ const fx=(((x%cell)+cell)%cell)/cell-0.5, fy=(((y%cell)+cell)%cell)/cell-0.5; const r2=fx*fx+fy*fy; return r2<0.18?Math.sqrt(0.18-r2):0; };\n      for(let y=0;y<h;y++) for(let x=0;x<w;x++){ const hl=Hf(x-1,y),hr=Hf(x+1,y),hu=Hf(x,y-1),hd=Hf(x,y+1);\n        let nx=(hl-hr)*3, ny=(hu-hd)*3, nz=1; const m=Math.hypot(nx,ny,nz)||1; nx/=m;ny/=m;nz/=m;\n        const i=(y*w+x)*4; d[i]=(nx*0.5+0.5)*255; d[i+1]=(ny*0.5+0.5)*255; d[i+2]=(nz*0.5+0.5)*255; d[i+3]=255; }\n      alloc(id,w,h); d2.setState({ srcName:'procedural' });\n    }\n    function setFromImg(img,name){\n      const sc=Math.min(1,TARGET/Math.max(img.width,img.height)); const w=Math.max(2,Math.round(img.width*sc)), h=Math.max(2,Math.round(img.height*sc));\n      work.width=w; work.height=h; wctx.clearRect(0,0,w,h); wctx.drawImage(img,0,0,w,h);\n      let id; try{ id=wctx.getImageData(0,0,w,h); }catch(e){ d2.setState({ srcName:'(CORS) use upload' }); return; }\n      alloc(id,w,h); d2.setState({ srcName:name||'imagem' });\n    }\n    function loadTex(){ const url=(d2.param('normalMap','')||'').trim(); if(url===lastTex) return; lastTex=url;\n      if(!url){ genDefault(); return; } const im=new Image(); im.crossOrigin='anonymous';\n      im.onload=()=>setFromImg(im,url.split('/').pop().split('?')[0]); im.onerror=()=>{ genDefault(); }; im.src=url; }\n    function loadFile(file){ if(!file)return; const r=new FileReader(); r.onload=()=>{ const im=new Image(); im.onload=()=>setFromImg(im,file.name); im.src=r.result; }; r.readAsDataURL(file); }\n\n    function relight(){\n      if(!src) return; const w=wW,h=wH, out=outData.data;\n      const inv=d2.param('invertGreen',true)?-1:1;\n      const diffuse=clamp(num(d2.param('diffuse',1.6),1.6),0,6);\n      const specS=clamp(num(d2.param('specStrength',1.1),1.1),0,6);\n      const shin=clamp(num(d2.param('shininess',26),26),1,200);\n      const shadowS=clamp(num(d2.param('shadowStrength',1.2),1.2),0,6);\n      const lc=parseColor(colorStr(d2.param('lightColor'),'#fff0cf'),'#fff0cf');\n      const lx=light.x, ly=light.y, lz=light.z;\n      for(let p=0,i=0;p<w*h;p++,i+=4){\n        let nx=src[i]/127.5-1, ny=(src[i+1]/127.5-1)*inv, nz=src[i+2]/127.5-1;\n        const nm=Math.hypot(nx,ny,nz)||1; nx/=nm;ny/=nm;nz/=nm;\n        const px=p%w, py=(p/w)|0;\n        let Lx=lx-px, Ly=ly-py, Lz=lz; const ld=Math.hypot(Lx,Ly,Lz)||1; Lx/=ld;Ly/=ld;Lz/=ld;\n        const ndl=nx*Lx+ny*Ly+nz*Lz;\n        const delta=ndl-Lz; // relative to a flat surface → flat areas stay transparent\n        let Hx=Lx,Hy=Ly,Hz=Lz+1; const hd=Math.hypot(Hx,Hy,Hz)||1; Hx/=hd;Hy/=hd;Hz/=hd;\n        const ndh=nx*Hx+ny*Hy+nz*Hz;\n        const spec=Math.max(0, Math.pow(Math.max(0,ndh),shin) - Math.pow(Math.max(0,Hz),shin));\n        let r,g,b,a;\n        if(delta>=0){ a=delta*diffuse + spec*specS; r=lc[0];g=lc[1];b=lc[2]; }\n        else { a=-delta*shadowS; r=0;g=0;b=0; }\n        a=clamp(a,0,1)*255;\n        out[i]=r; out[i+1]=g; out[i+2]=b; out[i+3]=a;\n      }\n      wctx.putImageData(outData,0,0);\n    }\n    function blit(){ ctx.clearRect(0,0,W,H); if(!src)return; ctx.drawImage(work,0,0,wW,wH, 0,0,W,H); }\n\n    function mapLight(e){ const r=cv.getBoundingClientRect(); const mx=e.clientX-r.left, my=e.clientY-r.top;\n      light.x=clamp(mx/W,0,1)*wW; light.y=clamp(my/H,0,1)*wH; light.have=true; dirty=true; }\n\n    size(); loadTex();\n    if(typeof ResizeObserver!=='undefined'){ const ro=new ResizeObserver(()=>{ size(); dirty=true; }); ro.observe(root); d2.onUnmount(()=>ro.disconnect()); }\n    d2.on('.wrap','dragover',(e)=>{ e.preventDefault(); root.querySelector('.wrap')&&root.querySelector('.wrap').classList.add('drag'); });\n    d2.on('.wrap','dragleave',()=>{ root.querySelector('.wrap')&&root.querySelector('.wrap').classList.remove('drag'); });\n    d2.on('.wrap','drop',(e)=>{ e.preventDefault(); root.querySelector('.wrap')&&root.querySelector('.wrap').classList.remove('drag'); loadFile(e.dataTransfer&&e.dataTransfer.files&&e.dataTransfer.files[0]); });\n    d2.on('.browse','click',()=>{ const f=d2.$('.file'); if(f)f.click(); });\n    d2.on('.file','change',(e,el)=>{ loadFile(el.files&&el.files[0]); el.value=''; });\n    d2.on(cv,'pointermove',mapLight);\n    d2.on(cv,'pointerleave',()=>{ light.have=false; });\n\n    d2.raf((t)=>{\n      loadTex();\n      if(!light.have && d2.param('autoOrbit',true) && src){ const a=t/1500; light.x=wW*0.5+Math.cos(a)*wW*0.34; light.y=wH*0.5+Math.sin(a)*wH*0.34; dirty=true; }\n      light.z=clamp(num(d2.param('lightZ',0.5),0.5),0.05,3)*Math.max(wW,wH);\n      if(dirty){ relight(); blit(); dirty=false; }\n    });\n  },\n}"}},"normalMap":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"normalMap"}}}},"lightColor":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"lightColor"}}}},"frost":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"frost"}}}},"diffuse":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"diffuse"}}}},"specStrength":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"specStrength"}}}},"shininess":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"shininess"}}}},"shadowStrength":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"shadowStrength"}}}},"lightZ":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"lightZ"}}}},"invertGreen":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"invertGreen"}}}},"autoOrbit":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"autoOrbit"}}}},"bg":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"bg"}}}}}}}}}},{"_id":"6a455ead209db9c366369b7a","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kVivProduct","package":"ai-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"function esc(s){return String(s==null?'':s).replace(/[&<>\"]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c];});}\nfunction digUrl(o,d){if(o==null||d>6)return '';if(typeof o==='string'){if(o.indexOf('data:image')===0||/^https?:\\/\\//.test(o))return o;return '';}if(typeof o==='object'){if(typeof o.url==='string'){var u0=digUrl(o.url,d+1);if(u0)return u0;}if(typeof o.imageUrl==='string'){var u1=digUrl(o.imageUrl,d+1);if(u1)return u1;}if(o.length!=null){for(var i=0;i<o.length;i++){var u=digUrl(o[i],d+1);if(u)return u;}}for(var k in o){try{if(!Object.prototype.hasOwnProperty.call(o,k))continue;}catch(e){continue;}var u2=digUrl(o[k],d+1);if(u2)return u2;}return '';}return '';}\nfunction imgs(p){var out=[];var its=p.items||[];for(var i=0;i<its.length;i++){var im=its[i].images||[];for(var j=0;j<im.length;j++){var u=im[j]&&im[j].imageUrl;if(u&&out.indexOf(u)<0)out.push(u);}}return out;}\nfunction norm(p){var pr=p.priceRange||{};var all=imgs(p);return {id:String(p.productId),name:p.productName||'Sem nome',image:all[0]||'',images:all,price:(pr.sellingPrice&&pr.sellingPrice.lowPrice)||(pr.listPrice&&pr.listPrice.lowPrice)||0,cat:(p.categories&&p.categories[0])||'',brand:p.brand||'Vivara'};}\nfunction H(s){s=String(s);var n=2166136261;for(var i=0;i<s.length;i++){n^=s.charCodeAt(i);n=Math.imul(n,16777619);}return (n>>>0);}\nfunction R(seed){var x=Math.sin(seed)*10000;return x-Math.floor(x);}\nfunction money(v){v=Math.round(v);var s=v.toString();var o='';var c=0;for(var i=s.length-1;i>=0;i--){o=s[i]+o;if(++c%3===0&&i>0)o='.'+o;}return 'R$ '+o;}\nfunction kfmt(v){v=Math.round(v);if(v>=1000000)return (v/1000000).toFixed(1).replace('.',',')+'M';if(v>=1000)return (v/1000).toFixed(v>=10000?0:1).replace('.',',')+'k';return String(v);}\nfunction pctf(v){return v.toFixed(2).replace('.',',')+'%';}\nfunction sim(key,price){var im=3200+Math.floor(R(H(key))*15800);var ctr=2.4+R(H(key+'|ctr'))*7.2;var cvr=1.1+R(H(key+'|cvr'))*4.9;var clicks=Math.round(im*ctr/100);var cart=Math.round(clicks*(0.34+R(H(key+'|ca'))*0.26));var orders=Math.round(clicks*cvr/100);var revenue=orders*(price||1200);return {impressions:im,ctr:ctr,cvr:cvr,clicks:clicks,cart:cart,orders:orders,revenue:revenue};}\nfunction series(key,n,base,vol,drift){var a=[],v=base;for(var i=0;i<n;i++){v+=(R(H(key+'|'+i))-0.5)*vol+drift;if(v<base*0.35)v=base*0.35;a.push(v);}return a;}\nfunction areaPath(a,w,h,pad){var mn=Math.min.apply(null,a),mx=Math.max.apply(null,a);var rg=(mx-mn)||1;var n=a.length;var pts=a.map(function(v,i){var x=pad+i/(n-1)*(w-pad*2);var y=pad+(1-(v-mn)/rg)*(h-pad*2);return [x,y];});var ln='M'+pts.map(function(p){return p[0].toFixed(1)+' '+p[1].toFixed(1);}).join(' L ');var ar=ln+' L '+(w-pad).toFixed(1)+' '+(h-pad).toFixed(1)+' L '+pad.toFixed(1)+' '+(h-pad).toFixed(1)+' Z';return {line:ln,area:ar,last:pts[pts.length-1]};}\nvar LOGO='https://upload.wikimedia.org/wikipedia/commons/4/45/Vivara.png';\nvar SCENE=[['Mármore','floating on polished white marble with subtle gold veining'],['Preto','on a dramatic pure black background'],['Creme','seamless warm cream infinity backdrop'],['Sunset','warm golden sunset gradient glow'],['Boudoir','blurred luxe interior bokeh'],['Botânico','out-of-focus botanical greenery'],['Seda','nestled in champagne silk folds'],['Veludo','on deep black velvet with soft sheen'],['Água','on a still water surface with subtle ripple reflection'],['Pedra','on raw natural stone with organic texture'],['Espelho','on a mirrored surface with elegant reflection']];\nvar LIGHT=[['Joalheria','crisp jewelry lighting, maximum gemstone sparkle and fire'],['Suave','soft diffused studio light, gentle gradients'],['Dramática','dramatic single-source light, deep luxury shadows'],['Golden','warm golden glow, premium mood'],['High-Key','bright clean high-key e-commerce lighting'],['Contraluz','elegant backlight with a soft rim glow'],['Natural','soft natural window light']];\nvar STYLE=[['Hero','hero macro shot, extreme detail, shallow depth of field'],['Editorial','high-fashion editorial composition, magazine grade'],['Lifestyle','aspirational lifestyle styling with elegant props'],['Minimal','ultra-minimal clean catalog, centered'],['Pack-shot','crisp e-commerce pack-shot, full sharp focus'],['Macro','extreme macro detail of the gemstones and finish'],['Campanha','bold advertising campaign composition']];\nvar RATIO=[['Quadrado','1024x1024'],['Retrato','896x1152'],['Paisagem','1152x896']];\nvar MTYPE=[['Mão','mao',\"a woman's elegant hand and wrist\"],['Colo','colo',\"a woman's neckline and collarbone, elegantly clothed\"],['Orelha','orelha',\"a woman's ear and the side of her face, hair elegantly styled\"],['Pescoço','pescoco',\"a woman's elegant neck and throat\"],['Pulso','pulso',\"a woman's wrist and forearm\"],['Rosto','rosto',\"a woman's face and shoulders, a refined beauty portrait\"]];\nvar SKIN=[['Clara','fair porcelain'],['Média','light beige'],['Morena','warm golden-brown'],['Negra','deep rich ebony']];\nvar MOOD=[['Suave','soft diffused daylight, natural elegant mood'],['Glamour','warm golden glow, glamorous luxe styling'],['Editorial','refined editorial lighting, high-fashion mood']];\nvar STEPS=['Estudando a peça','Montando o set','Posicionando as luzes','Capturando reflexos','Renderizando em alta'];\nvar MSTEPS=['Definindo o casting','Ajustando pose e clima','Iluminando o set','Renderizando o modelo'];\nvar RUSH='https://ai-playground.data2apis.com/rush/vivDraw';\nfunction wait(ms){return new Promise(function(res){setTimeout(res,ms);});}\nfunction drawRetry(prompts,images,size,i){i=i||0;var p=prompts[Math.min(i,prompts.length-1)];return fetch(RUSH,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({prompt:p,images:images||[],options:{size:size}})}).then(function(r){return r.json();}).then(function(j){var u=digUrl(j,0);if(u)return u;if(i<2)return wait(700).then(function(){return drawRetry(prompts,images,size,i+1);});return '';}).catch(function(){if(i<2)return wait(700).then(function(){return drawRetry(prompts,images,size,i+1);});return '';});}\nfunction mdesc(v){for(var i=0;i<MTYPE.length;i++){if(MTYPE[i][0]===v)return MTYPE[i][2];}return MTYPE[0][2];}\nfunction mkind(v){for(var i=0;i<MTYPE.length;i++){if(MTYPE[i][0]===v)return MTYPE[i][1];}return 'mao';}\nfunction modelPrompts(typ,sk,mo){return [\n  'Elegant fashion beauty photograph for a luxury jewelry brand. A tightly cropped studio close-up of '+typ+', '+sk+' complexion, '+mo+'. Only '+typ+' fills the frame, macro editorial framing. Professional high-end fashion photography, photorealistic, natural realistic skin texture with fine detail, physically accurate light, tasteful and refined, clean seamless studio background, ready to showcase fine jewelry. Never CGI or 3D-render look. No jewelry in frame, no text, no watermark.',\n  'Refined commercial macro close-up of '+typ+' for a fine jewelry catalog, '+sk+' complexion, elegant styling, soft premium studio lighting, tightly cropped composition, clean background, tasteful. No jewelry, no text.',\n  'Luxury jewelry catalog close-up crop showing '+typ+', '+sk+' complexion, graceful pose, clean studio backdrop, premium fashion editorial framing, tasteful. No text, no watermark.'\n];}\nfunction frag(a,v){for(var i=0;i<a.length;i++){if(a[i][0]===v)return a[i][1];}return a[0][1];}\nfunction chips(t,a,k,sel){return '<div class=\"sec\"><div class=\"sl\">'+t+'</div><div class=\"chips\">'+a.map(function(o){return '<span class=\"chip'+(sel===o[0]?' on':'')+'\" data-sk=\"'+k+'\" data-sv=\"'+esc(o[0])+'\">'+esc(o[0])+'</span>';}).join('')+'</div></div>';}\nfunction initials(s){s=String(s||'?').trim();var p=s.split(/\\s+/);return ((p[0]&&p[0][0])||'')+((p[1]&&p[1][0])||'');}\nfunction jtype(cat){var c=(cat||'').toLowerCase();\n  if(c.indexOf('alian')>=0)return {t:'wedding ring',p:'worn on a single finger',l:'Aliança'};\n  if(c.indexOf('anel')>=0||c.indexOf('anéis')>=0||c.indexOf('aneis')>=0)return {t:'ring',p:'worn on a single finger, sitting at the base of one finger',l:'Anel'};\n  if(c.indexOf('pulseira')>=0||c.indexOf('bracelete')>=0)return {t:'bracelet',p:'worn around the wrist',l:'Pulseira'};\n  if(c.indexOf('brinco')>=0||c.indexOf('argola')>=0)return {t:'pair of earrings',p:'worn on the ear',l:'Brinco'};\n  if(c.indexOf('colar')>=0||c.indexOf('gargantilha')>=0||c.indexOf('corrente')>=0)return {t:'necklace',p:'worn around the neck, resting on the neckline',l:'Colar'};\n  if(c.indexOf('pingente')>=0||c.indexOf('berloque')>=0)return {t:'pendant',p:'on a chain around the neck',l:'Pingente'};\n  if(c.indexOf('rel')>=0)return {t:'watch',p:'worn around the wrist',l:'Relógio'};\n  return {t:'jewelry piece',p:'worn correctly at realistic scale',l:((cat||'').split('/').filter(Boolean).pop())||'Joia'};}\n\nvar MOD={\n  css: `@import url('https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@500;600;700&family=Jost:wght@300;400;500;600&display=swap');\n    *{box-sizing:border-box}\n    .vp{height:100%;display:flex;font-family:'Jost',-apple-system,sans-serif;background:#FAF8F5;color:#1A1A1A;overflow:hidden}\n    .col{width:300px;flex:0 0 auto;background:#fff;border-right:1px solid #E8E2D9;display:flex;flex-direction:column;min-height:0}\n    .colh{padding:22px 22px 14px;border-bottom:1px solid #F0EBE2}\n    .colh .vlogo{height:22px;width:auto;display:block;margin-bottom:4px}\n    .colh .s{font-size:9px;letter-spacing:.3em;text-transform:uppercase;color:#B08D57}\n    .srch{margin:12px 22px;padding:9px 12px;border:1px solid #E0D6C4;border-radius:3px;font:inherit;font-size:12.5px;color:#1A1A1A;outline:none}\n    .srch:focus{border-color:#B08D57}\n    .plist{flex:1;overflow:auto;padding:4px 12px 12px}\n    .prow{display:flex;gap:11px;align-items:center;padding:9px 10px;border-radius:5px;cursor:pointer;transition:.14s;border:1px solid transparent}\n    .prow:hover{background:#FAF8F5}.prow.on{background:#1A1A1A;border-color:#1A1A1A}.prow.on .pn{color:#fff}.prow.on .pp{color:#C9A24B}\n    .prow img{width:44px;height:44px;object-fit:contain;mix-blend-mode:multiply;flex:0 0 auto}\n    .pn{font-size:12.5px;line-height:1.25;max-height:32px;overflow:hidden}.pp{font-size:11px;color:#9B8E7E;margin-top:2px}\n    .main{flex:1;display:flex;flex-direction:column;min-width:0;overflow:auto}\n    .empty{margin:auto;text-align:center;color:#9B8E7E}.empty .big{font-family:'Cormorant Garamond',serif;font-size:32px;color:#1A1A1A;margin-bottom:8px}\n    .hero{display:flex;gap:26px;padding:28px 34px 22px;border-bottom:1px solid #E8E2D9;align-items:center}\n    .hero .fig{width:132px;height:132px;flex:0 0 auto;background:#fff;border:1px solid #eee;display:flex;align-items:center;justify-content:center;border-radius:4px;overflow:hidden}\n    .hero .fig img{width:100%;height:100%;object-fit:contain;mix-blend-mode:multiply}\n    .hero .meta{flex:1;min-width:0}\n    .hero .cat{font-size:10px;letter-spacing:.16em;text-transform:uppercase;color:#B08D57}\n    .hero h1{font-family:'Cormorant Garamond',serif;font-size:28px;font-weight:600;margin:5px 0 8px;line-height:1.08}\n    .hero .price{font-size:19px;font-weight:500}.hero .sku{font-size:11px;color:#9B8E7E;margin-top:6px}\n    .cta{margin-left:auto;flex:0 0 auto;background:#1A1A1A;color:#fff;border:none;padding:14px 22px;font:inherit;font-size:12.5px;font-weight:600;letter-spacing:.09em;text-transform:uppercase;cursor:pointer;border-radius:3px;transition:.18s;align-self:center}\n    .cta:hover{background:#B08D57;letter-spacing:.13em}\n    .kpis{display:grid;grid-template-columns:repeat(5,1fr);gap:1px;background:#E8E2D9;border-bottom:1px solid #E8E2D9}\n    .kpi{background:#fff;padding:16px 20px}\n    .kpi .kl{font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:#9B8E7E}\n    .kpi .kv{font-family:'Cormorant Garamond',serif;font-size:26px;font-weight:600;margin-top:5px;line-height:1}\n    .kpi .kd{font-size:11px;margin-top:5px;color:#5A5045}.kpi .kd.up{color:#2E7D5B}.kpi .kd.dn{color:#B0857A}\n    .row2{display:grid;grid-template-columns:1.5fr 1fr;gap:20px;padding:22px 34px 4px}\n    .panel{background:#fff;border:1px solid #EFE7DA;border-radius:6px;padding:18px 20px}\n    .ph3{display:flex;align-items:baseline;justify-content:space-between;margin-bottom:14px}\n    .ph3 .t{font-family:'Cormorant Garamond',serif;font-size:18px;font-weight:600}\n    .ph3 .v{font-size:12px;color:#9B8E7E}\n    .chart{width:100%;height:120px;display:block}\n    .fun{display:flex;flex-direction:column;gap:9px}\n    .fstop{display:flex;justify-content:space-between;font-size:12px;margin-bottom:4px}\n    .fstop .fn{color:#5A5045}.fstop .fv{font-weight:600}\n    .ftrack{height:12px;background:#F0EBE2;border-radius:3px;overflow:hidden}\n    .ffill{height:100%;background:linear-gradient(90deg,#C9A24B,#B08D57);border-radius:3px}\n    .frate{font-size:10px;color:#9B8E7E;margin-top:2px;text-align:right}\n    .ins{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;padding:16px 34px 4px}\n    .icard{background:#fff;border:1px solid #EFE7DA;border-left:3px solid #C9A24B;border-radius:5px;padding:15px 17px}\n    .icard .ik{font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:#B08D57;margin-bottom:6px}\n    .icard .iv{font-size:13.5px;line-height:1.4;color:#3A342C}.icard .iv b{color:#1A1A1A}\n    .sect{padding:22px 34px 30px}\n    .sh{display:flex;align-items:baseline;gap:12px;margin-bottom:16px}\n    .sh h2{font-family:'Cormorant Garamond',serif;font-size:21px;font-weight:600;margin:0}\n    .sh .sub{font-size:12px;color:#9B8E7E}\n    .grid{display:grid;gap:16px;grid-template-columns:repeat(auto-fill,minmax(196px,1fr))}\n    .card{background:#fff;border:1px solid #EFE7DA;border-radius:5px;overflow:hidden;transition:.18s;position:relative}\n    .card:hover{transform:translateY(-3px);box-shadow:0 16px 34px rgba(120,95,50,.16)}\n    .card.win{border-color:#C9A24B;box-shadow:0 0 0 1px #C9A24B}\n    .card .ph{aspect-ratio:1;background:#FAF8F5;display:flex;align-items:center;justify-content:center;overflow:hidden}\n    .card .ph img{width:100%;height:100%;object-fit:contain;mix-blend-mode:multiply}\n    .crown{position:absolute;top:10px;left:10px;background:#C9A24B;color:#fff;font-size:9px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;padding:4px 8px;border-radius:2px}\n    .tag{position:absolute;top:10px;right:10px;background:rgba(26,26,26,.86);color:#fff;font-size:9px;letter-spacing:.08em;text-transform:uppercase;padding:4px 8px;border-radius:2px}\n    .cbody{padding:12px 13px 14px}\n    .clabel{font-size:12.5px;font-weight:500}\n    .cvrrow{display:flex;align-items:flex-end;justify-content:space-between;margin-top:9px}\n    .cvr{font-family:'Cormorant Garamond',serif;font-size:25px;font-weight:600;line-height:1}\n    .cvr.hi{color:#2E7D5B}.cvr.lo{color:#B0857A}\n    .cvrl{font-size:9px;letter-spacing:.08em;text-transform:uppercase;color:#9B8E7E}\n    .imp{font-size:10.5px;color:#9B8E7E;text-align:right;line-height:1.5}\n    .bar{height:4px;background:#F0EBE2;border-radius:3px;margin-top:10px;overflow:hidden}\n    .bfill{height:100%;background:linear-gradient(90deg,#C9A24B,#B08D57)}\n    .mrow{display:flex;gap:10px;font-size:10.5px;color:#7A7060;margin-top:8px;border-top:1px solid #F4EFE6;padding-top:8px}\n    .mrow div{flex:1}.mrow b{color:#1A1A1A;font-weight:600;display:block;font-size:12px}\n    .newc{border:1.5px dashed #D9C9A8;background:transparent;border-radius:5px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;cursor:pointer;color:#9B8E7E;min-height:196px;transition:.18s}\n    .newc:hover{border-color:#B08D57;color:#B08D57;background:#fff}\n    .newc .pl{font-size:34px;font-weight:200;line-height:.7}.newc .nt{font-size:12px;letter-spacing:.04em}\n    .ov{position:absolute;inset:0;background:rgba(26,22,18,.42);backdrop-filter:blur(3px);display:flex;align-items:center;justify-content:center;z-index:20;animation:fin .2s ease}\n    @keyframes fin{from{opacity:0}to{opacity:1}}\n    .studio{width:min(960px,95%);height:min(640px,94%);background:#FAF8F5;border-radius:8px;box-shadow:0 40px 100px rgba(0,0,0,.4);display:flex;overflow:hidden;animation:pop .25s cubic-bezier(.2,.8,.3,1)}\n    @keyframes pop{from{transform:scale(.96);opacity:0}to{transform:none;opacity:1}}\n    .scfg{width:340px;flex:0 0 auto;background:#fff;border-right:1px solid #E8E2D9;display:flex;flex-direction:column;min-height:0}\n    .sch{padding:17px 22px;border-bottom:1px solid #F0EBE2;display:flex;align-items:center;gap:10px}\n    .sbk{font-size:18px;color:#8A7E6E;cursor:pointer;line-height:1}.sbk:hover{color:#1A1A1A}\n    .sch .st{font-family:'Cormorant Garamond',serif;font-size:19px;font-weight:600}\n    .sch .ss{font-size:11px;color:#9B8E7E;margin-top:2px}\n    .sbody{flex:1;overflow:auto;padding:16px 22px}\n    .seg{display:flex;gap:6px;margin-bottom:16px;background:#F0EBE2;padding:4px;border-radius:5px}\n    .segb{flex:1;text-align:center;font-size:12px;padding:9px;border-radius:3px;cursor:pointer;transition:.15s;color:#5A5045;font-weight:500}\n    .segb.on{background:#1A1A1A;color:#fff}\n    .sec{margin-bottom:16px}.sl{font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:#9B8E7E;margin-bottom:8px;display:flex;justify-content:space-between;align-items:center}\n    .sl .add{color:#B08D57;cursor:pointer;font-size:10px;letter-spacing:.04em;text-transform:none}.sl .add:hover{text-decoration:underline}\n    .chips{display:flex;flex-wrap:wrap;gap:6px}\n    .chip{font-size:11.5px;padding:6px 11px;border:1px solid #E0D6C4;background:#fff;cursor:pointer;transition:.14s;color:#5A5045;border-radius:2px}\n    .chip:hover{border-color:#B08D57}.chip.on{background:#1A1A1A;color:#fff;border-color:#1A1A1A}\n    .models{display:grid;grid-template-columns:repeat(4,1fr);gap:7px}\n    .mc{cursor:pointer;border:2px solid transparent;border-radius:5px;overflow:hidden;transition:.15s;background:#FAF8F5;position:relative}\n    .mc .mi{width:100%;aspect-ratio:1;object-fit:cover;display:block}\n    .mc.noimg{display:flex;align-items:center;justify-content:center;aspect-ratio:1;min-height:58px}\n    .mc.noimg::before{content:attr(data-ini);font-family:'Cormorant Garamond',serif;font-size:20px;color:#B08D57;text-transform:uppercase}\n    .mc.on{border-color:#B08D57}.mc .mn{font-size:9px;text-align:center;padding:3px 2px;color:#5A5045;background:#fff}\n    .mc.newm{border:1.5px dashed #D9C9A8;display:flex;flex-direction:column;align-items:center;justify-content:center;color:#9B8E7E;min-height:82px;gap:2px}\n    .mc.newm:hover{border-color:#B08D57;color:#B08D57}.mc.newm .p{font-size:22px;font-weight:200;line-height:.8}.mc.newm .l{font-size:8.5px}\n    .mc .mdel{position:absolute;top:2px;right:2px;width:17px;height:17px;border-radius:50%;background:rgba(26,26,26,.72);color:#fff;font-size:12px;line-height:17px;text-align:center;cursor:pointer;opacity:0;transition:.14s;z-index:3}\n    .mc:hover .mdel{opacity:1}.mc .mdel:hover{background:#B0857A}\n    .sgo{flex:0 0 auto;margin:14px 22px 18px;background:#1A1A1A;color:#fff;border:none;padding:14px;font:inherit;font-size:12.5px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;cursor:pointer;border-radius:3px;transition:.18s;position:relative;overflow:hidden}\n    .sgo:hover:not(:disabled){background:#B08D57;letter-spacing:.14em}.sgo:disabled{opacity:.4;cursor:default}\n    .sgo .sheen{position:absolute;inset:0;background:linear-gradient(110deg,transparent 35%,rgba(201,162,75,.5) 50%,transparent 65%);transform:translateX(-120%);animation:shn 3.4s ease-in-out infinite;pointer-events:none}@keyframes shn{0%{transform:translateX(-120%)}55%,100%{transform:translateX(120%)}}\n    .sstage{flex:1;display:flex;align-items:center;justify-content:center;padding:26px;background:radial-gradient(circle at 50% 34%,#FFFDFA,#EFE7DA);position:relative;min-width:0}\n    .sx{position:absolute;top:14px;right:16px;font-size:22px;line-height:1;color:#8A7E6E;cursor:pointer;z-index:2;font-weight:300}.sx:hover{color:#1A1A1A}\n    .shint{text-align:center;color:#9B8E7E;max-width:300px}.shint .bg{font-family:'Cormorant Garamond',serif;font-size:25px;color:#1A1A1A;margin-bottom:8px;line-height:1.1}\n    .res{padding:12px;background:#fff;box-shadow:0 18px 44px rgba(120,95,50,.24);border-radius:2px;position:relative;max-height:100%;animation:fd .5s ease;text-align:center}\n    .res::after{content:'';position:absolute;inset:4px;border:1px solid #D9C9A8;pointer-events:none}\n    .res img{display:block;max-width:100%;max-height:300px;object-fit:contain;margin:0 auto}\n    .mgname{display:block;width:100%;margin-top:11px;padding:10px 12px;border:1px solid #E0D6C4;border-radius:3px;font:inherit;font-size:13px;text-align:center;color:#1A1A1A;outline:none}\n    .mgname:focus{border-color:#B08D57}\n    .addlib{margin-top:10px;background:#1A1A1A;color:#fff;border:none;padding:11px 18px;font:inherit;font-size:11.5px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;cursor:pointer;border-radius:3px;transition:.15s}\n    .addlib:hover{background:#B08D57}.addlib.done{background:#2E7D5B;pointer-events:none}\n    .qa{width:100%;max-width:560px;display:flex;flex-direction:column;gap:12px;animation:fd .5s ease}\n    .qah{font-family:'Cormorant Garamond',serif;font-size:22px;font-weight:600;text-align:center}\n    .qatag{font-size:9px;letter-spacing:.16em;text-transform:uppercase;color:#B08D57;text-align:center}\n    .qasub{font-size:12px;color:#7A7060;text-align:center;max-width:420px;margin:0 auto}\n    .qacmp{display:flex;gap:16px;justify-content:center;align-items:stretch;margin-top:4px}\n    .qacol{flex:1;min-width:0;display:flex;flex-direction:column}\n    .qacap{font-size:9px;letter-spacing:.12em;text-transform:uppercase;color:#9B8E7E;text-align:center;margin-bottom:6px}\n    .qafig{flex:1;background:#fff;padding:8px;box-shadow:0 12px 30px rgba(120,95,50,.18);border-radius:2px;display:flex;align-items:center;justify-content:center}\n    .qafig.new{box-shadow:0 0 0 2px #C9A24B,0 12px 30px rgba(120,95,50,.2)}\n    .qafig img{display:block;max-width:100%;max-height:250px;object-fit:contain}\n    .qaref{display:grid;grid-template-columns:1fr 1fr;gap:6px;align-content:start}\n    .qaref .rimg{background:#fff;border:1px solid #EFE7DA;border-radius:2px;aspect-ratio:1;display:flex;align-items:center;justify-content:center;overflow:hidden}\n    .qaref .rimg img{width:100%;height:100%;object-fit:contain;mix-blend-mode:multiply}\n    .refine{width:100%;min-height:50px;resize:none;margin-top:2px;padding:10px 12px;border:1px solid #E0D6C4;border-radius:4px;font:inherit;font-size:12px;color:#1A1A1A;outline:none;background:#fff}\n    .refine:focus{border-color:#B08D57}\n    .qacta{display:flex;gap:10px;justify-content:center;margin-top:6px}\n    .qbtn{border:none;padding:12px 20px;font:inherit;font-size:11.5px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;cursor:pointer;border-radius:3px;transition:.15s}\n    .qbtn.ok{background:#1A1A1A;color:#fff}.qbtn.ok:hover{background:#2E7D5B}.qbtn.ok.done{background:#2E7D5B;pointer-events:none}\n    .qbtn.ghost{background:transparent;border:1px solid #D9C9A8;color:#5A5045}.qbtn.ghost:hover{border-color:#B08D57;color:#B08D57}\n    @keyframes fd{from{opacity:0;transform:scale(.97)}to{opacity:1;transform:none}}\n    .load{display:flex;flex-direction:column;align-items:center;gap:16px}\n    .ring{width:66px;height:66px}.ring svg{width:100%;height:100%;animation:rot 1.4s linear infinite}@keyframes rot{to{transform:rotate(360deg)}}\n    .step{font-family:'Cormorant Garamond',serif;font-size:21px;font-weight:600}\n    .pbar{width:220px;height:2px;background:#E8E2D9;overflow:hidden;border-radius:2px}.pfill{height:100%;background:linear-gradient(90deg,#C9A24B,#B08D57);transition:width .5s}\n    .ssub{font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:#B08D57}\n    .gate{position:absolute;inset:0;background:radial-gradient(circle at 50% 30%,#242019,#141210);display:flex;align-items:center;justify-content:center;z-index:50}\n    .gbox{display:flex;flex-direction:column;align-items:center;gap:14px;padding:52px 60px;border:1px solid #2E2A24;background:rgba(255,255,255,.02);border-radius:6px}\n    .glogo{height:30px;width:auto;filter:brightness(0) invert(1)}\n    .gsub{font-size:10px;letter-spacing:.3em;text-transform:uppercase;color:#B08D57}\n    .gin{width:240px;padding:12px 14px;background:transparent;border:1px solid #4A443A;border-radius:3px;color:#E8E2D9;font:inherit;font-size:14px;text-align:center;letter-spacing:.2em;outline:none}\n    .gin:focus{border-color:#B08D57}\n    .gbtn{width:240px;padding:12px;background:#B08D57;border:none;color:#fff;font:inherit;font-size:12px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;cursor:pointer;border-radius:3px;transition:.18s}\n    .gbtn:hover{background:#C9A24B}\n    .gerr{font-size:11px;color:#C96A5A;min-height:14px}\n  `,\n  render(d2){\n    var s=d2.state;\n    var unlocked=s.unlocked===true;if(!unlocked){try{unlocked=localStorage.getItem('vivGate2020')==='1';}catch(_){}}\n    if(!unlocked){return '<div class=\"gate\"><div class=\"gbox\"><img class=\"glogo\" src=\"'+LOGO+'\"/><div class=\"gsub\">Acesso restrito</div><input class=\"gin\" data-gpw type=\"password\" placeholder=\"Senha\"/><button class=\"gbtn\" data-gunlock>Entrar</button><div class=\"gerr\">'+(s.gateErr?'Senha incorreta':'')+'</div></div></div>';}\n    var raw=(d2.data('products')&&d2.data('products').records())||[];\n    var prods=raw.map(norm).filter(function(p){return p.image&&p.cat.indexOf('/Joias/')>=0;});\n    if(!prods.length)prods=raw.map(norm).filter(function(p){return p.image;});\n    var q=(s.q||'').toLowerCase();\n    var shown=q?prods.filter(function(p){return p.name.toLowerCase().indexOf(q)>=0;}):prods;\n    var selP=s.selProductId||(prods[0]&&prods[0].id);\n    var prod=prods.filter(function(p){return p.id===selP;})[0]||prods[0];\n\n    var plist=shown.map(function(p){return '<div class=\"prow'+(prod&&p.id===prod.id?' on':'')+'\" data-prod=\"'+esc(p.id)+'\"><img loading=\"lazy\" src=\"'+esc(p.image)+'\"/><div><div class=\"pn\">'+esc(p.name)+'</div><div class=\"pp\">'+money(p.price)+'</div></div></div>';}).join('');\n    var left='<div class=\"col\"><div class=\"colh\"><img class=\"vlogo\" src=\"'+LOGO+'\"/><div class=\"s\">Performance de Produto</div></div><input class=\"srch\" data-q placeholder=\"Buscar peça...\" value=\"'+esc(s.q||'')+'\"/><div class=\"plist\">'+plist+'</div></div>';\n\n    if(!prod){return '<div class=\"vp\">'+left+'<div class=\"main\"><div class=\"empty\"><div class=\"big\">Catálogo VTEX</div><div>Carregando peças ao vivo...</div></div></div></div>';}\n\n    var lib=((d2.data('library')&&d2.data('library').records())||[]).filter(function(r){return String(r.productId)===String(prod.id);});\n    var vars=[];\n    var vlabels=['Foto oficial','Ângulo lateral','Detalhe macro','Ambientada','Editorial','Look completo'];\n    prod.images.slice(0,6).forEach(function(u,i){var m=sim(prod.id+'|'+i,prod.price);vars.push({url:u,label:vlabels[i]||('Variante '+(i+1)),m:m,ai:false,withModel:false,status:'live'});});\n    lib.forEach(function(r){var m=sim((r._id||r.imageUrl)+'|ai',prod.price);vars.push({url:r.imageUrl,label:r.label||(r.withModel?'IA · com modelo':'IA · catálogo'),m:{impressions:r.impressions||m.impressions,cvr:r.cvr||m.cvr,ctr:m.ctr,clicks:r.clicks||m.clicks,cart:m.cart,orders:r.orders||m.orders,revenue:r.revenue||m.revenue},ai:true,withModel:!!r.withModel,status:r.status||'testing'});});\n\n    var tImp=0,tOrd=0,tRev=0,tClick=0,tCart=0,best=null,worst=null;\n    vars.forEach(function(v){tImp+=v.m.impressions;tOrd+=v.m.orders;tRev+=v.m.revenue;tClick+=v.m.clicks;tCart+=v.m.cart;if(!best||v.m.cvr>best.m.cvr)best=v;if(!worst||v.m.cvr<worst.m.cvr)worst=v;});\n    var aggCvr=tImp?(tOrd/tImp*100):0;var aov=tOrd?(tRev/tOrd):0;\n    var maxCvr=best?best.m.cvr:1;\n    var deltaSku=(R(H(prod.id+'|d'))*36-6);\n\n    var kpis='<div class=\"kpis\">'+\n      '<div class=\"kpi\"><div class=\"kl\">Impressões · 30d</div><div class=\"kv\">'+kfmt(tImp)+'</div><div class=\"kd up\">▲ '+(8+Math.floor(R(H(prod.id+'|i'))*22))+'%</div></div>'+\n      '<div class=\"kpi\"><div class=\"kl\">Conversão média</div><div class=\"kv\">'+pctf(aggCvr)+'</div><div class=\"kd '+(deltaSku>=0?'up':'dn')+'\">'+(deltaSku>=0?'▲ ':'▼ ')+Math.abs(deltaSku).toFixed(1).replace('.',',')+'% vs categoria</div></div>'+\n      '<div class=\"kpi\"><div class=\"kl\">Pedidos · 30d</div><div class=\"kv\">'+kfmt(tOrd)+'</div><div class=\"kd\">'+vars.length+' imagens no teste</div></div>'+\n      '<div class=\"kpi\"><div class=\"kl\">Receita atribuída</div><div class=\"kv\">'+kfmt(tRev)+'</div><div class=\"kd up\">▲ '+(5+Math.floor(R(H(prod.id+'|r'))*18))+'%</div></div>'+\n      '<div class=\"kpi\"><div class=\"kl\">Ticket médio</div><div class=\"kv\">'+kfmt(aov)+'</div><div class=\"kd\">por pedido</div></div>'+\n      '</div>';\n\n    var ser=series(prod.id+'|cvr30',30,aggCvr,0.5,0.012);\n    var ap=areaPath(ser,420,120,10);\n    var trend='<div class=\"panel\"><div class=\"ph3\"><div class=\"t\">Conversão · 30 dias</div><div class=\"v\">agora '+pctf(ser[ser.length-1])+'</div></div>'+\n      '<svg class=\"chart\" viewBox=\"0 0 420 120\" preserveAspectRatio=\"none\"><defs><linearGradient id=\"g'+esc(prod.id)+'\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\"><stop offset=\"0\" stop-color=\"#C9A24B\" stop-opacity=\"0.28\"/><stop offset=\"1\" stop-color=\"#C9A24B\" stop-opacity=\"0\"/></linearGradient></defs>'+\n      '<path d=\"'+ap.area+'\" fill=\"url(#g'+esc(prod.id)+')\"/><path d=\"'+ap.line+'\" fill=\"none\" stroke=\"#B08D57\" stroke-width=\"2\" stroke-linejoin=\"round\"/>'+\n      '<circle cx=\"'+ap.last[0].toFixed(1)+'\" cy=\"'+ap.last[1].toFixed(1)+'\" r=\"3.5\" fill=\"#1A1A1A\"/></svg></div>';\n\n    var fstages=[['Impressões',tImp,1],['Cliques',tClick,tImp?tClick/tImp:0],['Adições ao carrinho',tCart,tClick?tCart/tClick:0],['Pedidos',tOrd,tCart?tOrd/tCart:0]];\n    var funnel='<div class=\"panel\"><div class=\"ph3\"><div class=\"t\">Funil de conversão</div><div class=\"v\">30 dias</div></div><div class=\"fun\">'+\n      fstages.map(function(f,i){var w=Math.max(6,Math.round(f[1]/(tImp||1)*100));return '<div><div class=\"fstop\"><span class=\"fn\">'+f[0]+'</span><span class=\"fv\">'+kfmt(f[1])+'</span></div><div class=\"ftrack\"><div class=\"ffill\" style=\"width:'+w+'%\"></div></div>'+(i>0?'<div class=\"frate\">'+(f[2]*100).toFixed(1).replace('.',',')+'% da etapa anterior</div>':'')+'</div>';}).join('')+\n      '</div></div>';\n    var row2='<div class=\"row2\">'+trend+funnel+'</div>';\n\n    var lift=worst&&worst.m.cvr>0?((best.m.cvr/worst.m.cvr-1)*100):0;\n    var withM=vars.filter(function(v){return v.withModel;});var noM=vars.filter(function(v){return !v.withModel;});\n    var avgWM=withM.length?withM.reduce(function(a,v){return a+v.m.cvr;},0)/withM.length:0;\n    var avgNM=noM.length?noM.reduce(function(a,v){return a+v.m.cvr;},0)/noM.length:0;\n    var modelIns=withM.length?('Imagens <b>com modelo</b> convertem <b>'+pctf(avgWM)+'</b> vs <b>'+pctf(avgNM)+'</b> sem modelo — '+(avgWM>=avgNM?'+':'')+((avgNM?(avgWM/avgNM-1)*100:0)).toFixed(0)+'% de diferença.'):'Nenhuma imagem <b>com modelo</b> ainda. Gere uma no estúdio para comparar o efeito do try-on na conversão.';\n    var trendDir=ser[ser.length-1]>=ser[0];\n    var ins='<div class=\"ins\">'+\n      '<div class=\"icard\"><div class=\"ik\">♛ Imagem campeã</div><div class=\"iv\"><b>'+esc(best.label)+'</b> lidera com <b>'+pctf(best.m.cvr)+'</b> de conversão — <b>+'+lift.toFixed(0)+'%</b> acima da pior variante. Vale promover como imagem principal.</div></div>'+\n      '<div class=\"icard\"><div class=\"ik\">✦ Efeito do modelo</div><div class=\"iv\">'+modelIns+'</div></div>'+\n      '<div class=\"icard\"><div class=\"ik\">'+(trendDir?'▲ Tendência':'▼ Tendência')+'</div><div class=\"iv\">Conversão '+(trendDir?'<b>subindo</b>':'<b>caindo</b>')+' nos últimos 30 dias ('+pctf(ser[0])+' → <b>'+pctf(ser[ser.length-1])+'</b>). '+(trendDir?'Momento bom para escalar mídia.':'Teste uma nova imagem para reagir.')+'</div></div>'+\n      '</div>';\n\n    var cards=vars.map(function(v){\n      var win=v===best;var pct=Math.max(8,Math.round(v.m.cvr/maxCvr*100));\n      var hilo=v.m.cvr>=aggCvr?'hi':'lo';\n      return '<div class=\"card'+(win?' win':'')+'\">'+\n        (win?'<div class=\"crown\">♛ Campeã</div>':'')+\n        (v.ai?'<div class=\"tag\">'+(v.withModel?'IA · modelo':(v.status==='testing'?'IA · testando':'IA'))+'</div>':'')+\n        '<div class=\"ph\"><img loading=\"lazy\" src=\"'+esc(v.url)+'\"/></div>'+\n        '<div class=\"cbody\"><div class=\"clabel\">'+esc(v.label)+'</div>'+\n        '<div class=\"cvrrow\"><div><div class=\"cvr '+hilo+'\">'+pctf(v.m.cvr)+'</div><div class=\"cvrl\">conversão</div></div>'+\n        '<div class=\"imp\">'+kfmt(v.m.impressions)+' impr.<br>'+kfmt(v.m.orders)+' pedidos</div></div>'+\n        '<div class=\"bar\"><div class=\"bfill\" style=\"width:'+pct+'%\"></div></div>'+\n        '<div class=\"mrow\"><div><b>'+v.m.ctr.toFixed(1).replace('.',',')+'%</b>CTR</div><div><b>'+kfmt(v.m.cart)+'</b>carrinho</div><div><b>'+kfmt(v.m.revenue)+'</b>receita</div></div>'+\n        '</div></div>';\n    }).join('');\n    var newcard='<div class=\"newc\" data-open><div class=\"pl\">+</div><div class=\"nt\">Criar nova imagem</div></div>';\n\n    var hero='<div class=\"hero\"><div class=\"fig\"><img src=\"'+esc(prod.image)+'\"/></div><div class=\"meta\"><div class=\"cat\">'+esc((prod.cat.split('/').filter(Boolean).pop())||'Joias')+'</div><h1>'+esc(prod.name)+'</h1><div class=\"price\">'+money(prod.price)+'</div><div class=\"sku\">SKU '+esc(prod.id)+' · '+esc(prod.brand)+'</div></div><button class=\"cta\" data-open>+ Criar nova imagem</button></div>';\n    var gallery='<div class=\"sect\"><div class=\"sh\"><h2>Imagens em teste</h2><div class=\"sub\">comparando conversão foto a foto · '+vars.length+' variantes</div></div><div class=\"grid\">'+cards+newcard+'</div></div>';\n\n    var modal='';\n    if(s.studioOpen)modal=MOD.studio(d2,prod,s);\n\n    return '<div class=\"vp\">'+left+'<div class=\"main\">'+hero+kpis+row2+ins+gallery+'</div>'+modal+'</div>';\n  },\n  studio:function(d2,prod,s){\n    if(s.modelGen)return MOD.modelStudio(d2,s);\n    var withModel=!!s.withModel;\n    var models=((d2.data('models')&&d2.data('models').records())||[]).concat(s.newModels||[]);\n    var scene=s.scene||'Mármore',light=s.light||'Joalheria',style=s.style||'Hero',ratio=s.ratio||'Quadrado';\n    var stage;\n    if(s.busy){var st=Math.min(4,s.loadStep||0);stage='<div class=\"load\"><div class=\"ring\"><svg viewBox=\"0 0 50 50\"><circle cx=\"25\" cy=\"25\" r=\"20\" fill=\"none\" stroke=\"#E8E2D9\" stroke-width=\"3\"/><circle cx=\"25\" cy=\"25\" r=\"20\" fill=\"none\" stroke=\"#B08D57\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-dasharray=\"90 126\"/></svg></div><div class=\"step\">'+esc(STEPS[st])+'…</div><div class=\"pbar\"><div class=\"pfill\" style=\"width:'+((st+1)/5*100)+'%\"></div></div><div class=\"ssub\">estúdio IA · ~30s</div></div>';}\n    else if(s.genUrl){\n      var refThumbs=prod.images.slice(0,4).map(function(u){return '<div class=\"rimg\"><img src=\"'+esc(u)+'\"/></div>';}).join('');\n      stage='<div class=\"qa\"><div class=\"qatag\">Aprovação de qualidade</div><div class=\"qah\">A peça continua fiel?</div><div class=\"qasub\">Avalie lado a lado com as fotos oficiais. Só entra na biblioteca se não descaracterizar o produto.</div>'+\n        '<div class=\"qacmp\"><div class=\"qacol\"><div class=\"qacap\">Gerada · IA</div><div class=\"qafig new\"><img src=\"'+esc(s.genUrl)+'\"/></div></div>'+\n        '<div class=\"qacol\"><div class=\"qacap\">Fotos oficiais</div><div class=\"qaref\">'+refThumbs+'</div></div></div>'+\n        '<textarea class=\"refine\" data-refine placeholder=\"Orientação livre (opcional): ex. menos reflexo, aproxime da pulseira, fundo mais claro…\">'+esc(s.refineNote||'')+'</textarea>'+\n        '<div class=\"qacta\"><button class=\"qbtn ghost\" data-regen>↺ Gerar outra</button><button class=\"qbtn ok'+(s.added?' done':'')+'\" data-add>'+(s.added?'✓ Aprovada · na biblioteca':'✓ Aprovar e adicionar')+'</button></div></div>';\n    }\n    else if(s.error){stage='<div class=\"shint\"><div class=\"bg\">Ops</div><div>'+esc(s.error)+'</div></div>';}\n    else{stage='<div class=\"shint\"><div class=\"bg\">'+esc(prod.name)+'</div><div>Peça já selecionada. Escolha com ou sem modelo, componha o set e gere.</div></div>';}\n\n    var modelPick=withModel?'<div class=\"sec\"><div class=\"sl\"><span>Modelo</span><span class=\"add\" data-newmodel>＋ Novo modelo</span></div><div class=\"models\"><div class=\"mc newm\" data-newmodel><div class=\"p\">+</div><div class=\"l\">Criar</div></div>'+models.map(function(m){var mid=m._id||m.imageUrl;var u=m.imageUrl||'';var on=String(s.selModelId)===String(mid);return '<div class=\"mc'+(on?' on':'')+(u?'':' noimg')+'\" data-model=\"'+esc(mid)+'\" data-ini=\"'+esc(initials(m.name||m.kind))+'\"><span class=\"mdel\" data-delmodel=\"'+esc(mid)+'\" data-delid=\"'+esc(m._id||'')+'\">×</span>'+(u?'<img class=\"mi\" src=\"'+esc(u)+'\" onerror=\"this.parentNode.classList.add(\\'noimg\\');this.remove();\"/>':'')+'<div class=\"mn\">'+esc(m.name||m.kind||'Modelo')+'</div></div>';}).join('')+'</div></div>':'';\n\n    var canGo=!s.busy&&(!withModel||s.selModelId);\n    return '<div class=\"ov\" data-ovcancel><div class=\"studio\" data-stop>'+\n      '<div class=\"scfg\"><div class=\"sch\"><div><div class=\"st\">Novo ensaio</div><div class=\"ss\">'+esc(jtype(prod.cat).l)+' · '+esc(prod.name)+'</div></div></div>'+\n      '<div class=\"sbody\">'+\n      '<div class=\"seg\"><div class=\"segb'+(!withModel?' on':'')+'\" data-mode=\"0\">Sem modelo</div><div class=\"segb'+(withModel?' on':'')+'\" data-mode=\"1\">Com modelo</div></div>'+\n      modelPick+\n      chips('Cenário',SCENE,'scene',scene)+chips('Iluminação',LIGHT,'light',light)+chips('Estilo',STYLE,'style',style)+chips('Proporção',RATIO,'ratio',ratio)+\n      '</div>'+\n      '<button class=\"sgo\" data-gen '+(canGo?'':'disabled')+'><span class=\"sheen\"></span>'+(withModel?'Gerar com modelo':'Gerar imagem')+'</button>'+\n      '</div>'+\n      '<div class=\"sstage\"><span class=\"sx\" data-close>×</span>'+stage+'</div>'+\n      '</div></div>';\n  },\n  modelStudio:function(d2,s){\n    var mtype=s.mgType||'Mão',skin=s.mgSkin||'Média',mood=s.mgMood||'Suave';\n    var stage;\n    if(s.mgBusy){var st=Math.min(3,s.mgStep||0);stage='<div class=\"load\"><div class=\"ring\"><svg viewBox=\"0 0 50 50\"><circle cx=\"25\" cy=\"25\" r=\"20\" fill=\"none\" stroke=\"#E8E2D9\" stroke-width=\"3\"/><circle cx=\"25\" cy=\"25\" r=\"20\" fill=\"none\" stroke=\"#B08D57\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-dasharray=\"90 126\"/></svg></div><div class=\"step\">'+esc(MSTEPS[st])+'…</div><div class=\"pbar\"><div class=\"pfill\" style=\"width:'+((st+1)/4*100)+'%\"></div></div><div class=\"ssub\">casting IA · ~25s</div></div>';}\n    else if(s.mgUrl){var sugg=((s.mgType||'Modelo')+' '+(s.mgSkin||'')).trim();stage='<div class=\"res\"><img src=\"'+esc(s.mgUrl)+'\"/><input class=\"mgname\" data-mgname placeholder=\"Nome do modelo\" value=\"'+esc(sugg)+'\"/><button class=\"addlib'+(s.mgAdded?' done':'')+'\" data-usemodel>'+(s.mgAdded?'✓ Modelo salvo':'Salvar modelo')+'</button></div>';}\n    else if(s.mgError){stage='<div class=\"shint\"><div class=\"bg\">Ops</div><div>'+esc(s.mgError)+'</div></div>';}\n    else{stage='<div class=\"shint\"><div class=\"bg\">Casting de modelo</div><div>Gera um close-up cropped da parte do corpo (mão, colo, orelha, pescoço, pulso) ou um retrato (rosto). Ele entra na sua biblioteca de modelos.</div></div>';}\n    var canGo=!s.mgBusy;\n    return '<div class=\"ov\" data-ovcancel><div class=\"studio\" data-stop>'+\n      '<div class=\"scfg\"><div class=\"sch\"><span class=\"sbk\" data-backmodel>‹</span><div><div class=\"st\">Novo modelo</div><div class=\"ss\">gerar pessoa / parte do corpo</div></div></div>'+\n      '<div class=\"sbody\">'+\n      chips('Tipo',MTYPE,'mgType',mtype)+chips('Tom de pele',SKIN,'mgSkin',skin)+chips('Clima',MOOD,'mgMood',mood)+\n      '</div>'+\n      '<button class=\"sgo\" data-genmodel '+(canGo?'':'disabled')+'><span class=\"sheen\"></span>Gerar modelo</button>'+\n      '</div>'+\n      '<div class=\"sstage\"><span class=\"sx\" data-close>×</span>'+stage+'</div>'+\n      '</div></div>';\n  },\n  mounted(d2){\n    function tryUnlock(){var el=d2.$('[data-gpw]');var v=el?el.value:'';if(v==='VivaraData22020'){try{localStorage.setItem('vivGate2020','1');}catch(_){}d2.setState({unlocked:true,gateErr:false});}else{d2.setState({gateErr:true});}}\n    d2.on('[data-gunlock]','click',tryUnlock);\n    d2.on('[data-gpw]','keydown',function(e){if(e.key==='Enter')tryUnlock();});\n    var loadStart=null,lastStep=-1,mLoadStart=null,mLastStep=-1;\n    d2.on('[data-prod]','click',function(e,el){d2.setState({selProductId:el.getAttribute('data-prod')});});\n    d2.on('[data-q]','input',function(e,el){d2.state.q=el.value;});\n    d2.on('[data-open]','click',function(){d2.setState({studioOpen:true,modelGen:false,genUrl:null,error:null,added:false,busy:false});});\n    d2.on('[data-close]','click',function(){d2.setState({studioOpen:false,modelGen:false});});\n    d2.on('[data-ovcancel]','click',function(e,el){if(e.target===el)d2.setState({studioOpen:false,modelGen:false});});\n    d2.on('[data-stop]','click',function(e){e.stopPropagation();});\n    d2.on('[data-mode]','click',function(e,el){d2.setState({withModel:el.getAttribute('data-mode')==='1'});});\n    d2.on('[data-model]','click',function(e,el){if(e.target&&e.target.getAttribute&&e.target.getAttribute('data-delmodel')!=null)return;d2.setState({selModelId:el.getAttribute('data-model'),error:null});});\n    d2.on('[data-delmodel]','click',function(e,el){e.stopPropagation();var mid=el.getAttribute('data-delmodel');var delid=el.getAttribute('data-delid');d2.dialog.confirm('Apagar este modelo da biblioteca?').then(function(ok){if(!ok)return;if(delid){try{d2.data('models').remove(delid);}catch(_){}}var nm=(d2.state.newModels||[]).filter(function(x){return String(x.imageUrl)!==String(mid);});var st={newModels:nm};if(String(d2.state.selModelId)===String(mid))st.selModelId=null;d2.setState(st);});});\n    d2.on('[data-newmodel]','click',function(){d2.setState({modelGen:true,mgUrl:null,mgError:null,mgAdded:false,mgBusy:false});});\n    d2.on('[data-backmodel]','click',function(){d2.setState({modelGen:false});});\n    d2.on('[data-sk]','click',function(e,el){var o={};o[el.getAttribute('data-sk')]=el.getAttribute('data-sv');d2.setState(o);});\n    d2.raf(function(t){\n      if(d2.state.busy){if(loadStart==null){loadStart=t;}var stp=Math.min(4,Math.floor((t-loadStart)/5200));if(stp!==lastStep){lastStep=stp;d2.setState({loadStep:stp});}}else{loadStart=null;lastStep=-1;}\n      if(d2.state.mgBusy){if(mLoadStart==null){mLoadStart=t;}var ms=Math.min(3,Math.floor((t-mLoadStart)/6000));if(ms!==mLastStep){mLastStep=ms;d2.setState({mgStep:ms});}}else{mLoadStart=null;mLastStep=-1;}\n    });\n    function runGen(note){\n      var s=d2.state;if(s.busy)return;\n      var raw=(d2.data('products')&&d2.data('products').records())||[];\n      var prod=raw.map(norm).filter(function(p){return p.id===s.selProductId;})[0];\n      if(!prod){var pl=raw.map(norm).filter(function(p){return p.image;});prod=pl[0];}\n      if(!prod){d2.setState({error:'Selecione uma peça.'});return;}\n      var withModel=!!s.withModel;var refs=prod.images.slice(0,2);if(!refs.length&&prod.image)refs=[prod.image];var modelDesc='';\n      if(withModel){var models=((d2.data('models')&&d2.data('models').records())||[]).concat(s.newModels||[]);var mm=models.filter(function(m){return String(m._id||m.imageUrl)===String(s.selModelId);})[0];if(mm){refs=refs.concat([mm.imageUrl]);modelDesc=' The elegant model from the FINAL reference image naturally showcases the jewel — tasteful pose, realistic anatomy and proportions, keep the model consistent with that reference. This is a model shot — do NOT add any surface reflection, mirrored tabletop, or reflected duplicate of the subject.';}}\n      var extra=(note&&note.trim())?(' Additional guidance from the art director, follow it precisely: '+note.trim()+'.'):'';\n      var jt=jtype(prod.cat);\n      var typeClause=' This product is a '+jt.t+' and MUST be rendered as a '+jt.t+', '+jt.p+', at true-to-life scale and correct anatomical proportion — never distort its form, size or placement.';\n      var refClause=withModel?'The product reference images all show the SAME jewel from different angles; the final reference image is the model.':'The reference images all show the SAME jewel from different angles.';\n      var noModelClause=withModel?'':' This is a PRODUCT-ONLY still life: absolutely no person, no model and no body part (hand, fingers, wrist, arm, neck, ear) may appear in the frame — even if a reference image shows the jewel being worn, render the jewel ALONE.';\n      var frameClause=' Full-bleed composition: the new scene fills the ENTIRE frame edge to edge — never render a smaller picture floating inside white margins or a border, and do NOT copy the plain white catalog background from the references; build a completely new scene as directed.';\n      var prompt='Professional luxury jewelry photograph for Vivara catalog. '+refClause+' Reproduce the jewel EXACTLY as in the references — identical shape, gemstones, metal color and finish, faithful from every angle.'+typeClause+noModelClause+modelDesc+frameClause+' Scene: '+frag(SCENE,s.scene||'Mármore')+'. Lighting: '+frag(LIGHT,s.light||'Joalheria')+'. Style: '+frag(STYLE,s.style||'Hero')+'.'+extra+' Photorealistic professional photography: full-frame camera with macro lens, natural realistic skin texture, physically accurate light, reflections and shadows, true-to-life color. Never an illustration, CGI or 3D-render look. Premium high-end commercial aesthetic, no text, no watermark. Product: '+prod.name+' ('+jt.t+').';\n      d2.setState({busy:true,genUrl:null,error:null,added:false,loadStep:0,refineNote:(note||'')});\n      drawRetry([prompt],refs,frag(RATIO,s.ratio||'Quadrado'),0).then(function(u){if(u){d2.setState({busy:false,genUrl:u});}else{d2.setState({busy:false,error:'Não recebi a imagem da IA (tentei algumas vezes). Ajuste o set e tente de novo.'});}}).catch(function(){d2.setState({busy:false,error:'Falha ao gerar. Tente de novo.'});});\n    }\n    d2.on('[data-gen]','click',function(){runGen('');});\n    d2.on('[data-regen]','click',function(){var el=d2.$('[data-refine]');runGen(el?el.value:'');});\n    d2.on('[data-add]','click',function(){\n      var s=d2.state;if(!s.genUrl||s.added)return;\n      var raw=(d2.data('products')&&d2.data('products').records())||[];\n      var prod=raw.map(norm).filter(function(p){return p.id===s.selProductId;})[0];if(!prod)prod=raw.map(norm)[0];\n      var withModel=!!s.withModel;var models=((d2.data('models')&&d2.data('models').records())||[]).concat(s.newModels||[]);var mm=models.filter(function(m){return String(m._id||m.imageUrl)===String(s.selModelId);})[0];\n      var m=sim(s.genUrl,prod?prod.price:1200);\n      try{d2.data('library').create({productId:prod?prod.id:'',productName:prod?prod.name:'',imageUrl:s.genUrl,label:(withModel?'IA · '+((mm&&mm.name)||'com modelo'):'IA · '+(s.style||'Hero')),withModel:withModel,modelName:(mm&&mm.name)||'',source:'ai',status:'testing',impressions:m.impressions,clicks:m.clicks,orders:m.orders,revenue:m.revenue,cvr:m.cvr,createdAt:new Date().toISOString()});}catch(_){}\n      d2.setState({added:true});\n    });\n    d2.on('[data-genmodel]','click',function(){\n      var s=d2.state;if(s.mgBusy)return;\n      var typ=mdesc(s.mgType||'Mão'),sk=frag(SKIN,s.mgSkin||'Média'),mo=frag(MOOD,s.mgMood||'Suave');\n      var prompts=modelPrompts(typ,sk,mo);\n      d2.setState({mgBusy:true,mgUrl:null,mgError:null,mgAdded:false,mgStep:0});\n      drawRetry(prompts,[],'896x1152',0).then(function(u){if(u){d2.setState({mgBusy:false,mgUrl:u});}else{d2.setState({mgBusy:false,mgError:'A IA recusou o pedido mesmo após novas tentativas. Troque o tipo ou o clima e tente novamente.'});}}).catch(function(){d2.setState({mgBusy:false,mgError:'Falha ao gerar o modelo. Tente de novo.'});});\n    });\n    d2.on('[data-usemodel]','click',function(){\n      var s=d2.state;if(!s.mgUrl||s.mgAdded)return;\n      var nel=d2.$('[data-mgname]');var name=(nel&&nel.value&&nel.value.trim())||((s.mgType||'Modelo')+' '+(s.mgSkin||'')).trim();\n      var typ=mdesc(s.mgType||'Mão'),sk=frag(SKIN,s.mgSkin||'Média'),mo=frag(MOOD,s.mgMood||'Suave');\n      var prompt='Tightly cropped close-up of '+typ+', '+sk+' complexion, '+mo+', tasteful and refined, ready to showcase fine jewelry.';\n      var rec={name:name,kind:mkind(s.mgType||'Mão'),prompt:prompt,imageUrl:s.mgUrl,createdAt:new Date().toISOString()};\n      try{d2.data('models').create(rec);}catch(_){}\n      var nm=(d2.state.newModels||[]).slice();nm.push(rec);\n      d2.setState({newModels:nm,selModelId:s.mgUrl,mgAdded:true,modelGen:false,withModel:true});\n    });\n  }\n};\nexport default MOD;"}},"products":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"products"}}}},"models":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"models"}}}},"library":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"library"}}}}}}}}}},{"_id":"6a45654f9f0bd53b14d5f500","component":"data2-core-types@Component","system":"6a11aec3b70f2dc40823369a","params":{"extends":"data2-core-primitives@Block","component":"kVivDeck","package":"ai-playground","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 SLIDES = [\n  { id: 0, theme: 'light', kind: 'abertura' },\n  { id: 1, theme: 'dark',  kind: 'magritte' },\n  { id: 2, theme: 'dark',  kind: 'joia' },\n  { id: 3, theme: 'dark',  kind: 'tese' },\n  { id: 4, theme: 'light', kind: 'representacao' },\n  { id: 5, theme: 'light', kind: 'teste' },\n  { id: 6, theme: 'dark',  kind: 'risco' },\n  { id: 7, theme: 'dark',  kind: 'virada' },\n  { id: 8, theme: 'light', kind: 'proposta' },\n  { id: 9, theme: 'dark',  kind: 'handoff' },\n];\n\nconst VIVARA_LOGO = 'https://upload.wikimedia.org/wikipedia/commons/4/45/Vivara.png';\n\nconst IMG_PIPE = 'https://midias.jb.com.br/_midias/jpg/2022/09/08/isto_nao_e_um_cachimbo-693982.jpeg';\nconst IMG_JOIA = 'https://lojavivarafsv3.vtexassets.com/arquivos/ids/2497625/Anel-Palace-em-Prata-925-e-Ouro-Amarelo-18k-com-Safira-Incolor-Negra-e-Laranja-113699_1_set.jpg';\n\nfunction pad(n){ return (n < 10 ? '0' : '') + n; }\n\nfunction slideHTML(kind){\n  switch(kind){\n    case 'abertura':\n      return `\n        <div class=\"stage stage-center\">\n          <div class=\"eyebrow eyebrow-logo\"><img class=\"viv-logo\" src=\"${VIVARA_LOGO}\" alt=\"Vivara\" /><span class=\"eyebrow-sep\">&middot;</span>INTELIG&Ecirc;NCIA GENERATIVA</div>\n          <h1 class=\"display display-xl\">O que podemos operar<br/>em um e-commerce de joias de luxo?</h1>\n          <div class=\"hairline-sm\"></div>\n          <p class=\"sub sub-serif\">Abstraia a opera&ccedil;&atilde;o inteira. No fim, sobra uma coisa.</p>\n        </div>`;\n    case 'tese':\n      return `\n        <div class=\"stage stage-center\">\n          <div class=\"eyebrow eyebrow-gold\">A TESE</div>\n          <h1 class=\"display display-huge\">A imagem<br/><span class=\"ital\">&Eacute;</span> o produto.</h1>\n          <p class=\"sub sub-serif\">Antes de tudo, &eacute; a imagem que opera a venda.</p>\n        </div>`;\n    case 'magritte':\n      return `\n        <div class=\"stage stage-center\">\n          <div class=\"frame frame-art fade-item\" style=\"--d:.1s\">\n            <img src=\"${IMG_PIPE}\" alt=\"Ceci n'est pas une pipe\" />\n          </div>\n          <p class=\"caption caption-ital fade-item\" style=\"--d:.5s\">&ldquo;Ceci n&rsquo;est pas une pipe.&rdquo;</p>\n          <p class=\"credit fade-item\" style=\"--d:.7s\">Ren&eacute; Magritte, 1929</p>\n          <div class=\"reveal reveal-line fade-item\" style=\"--d:1.1s\">Isto n&atilde;o &eacute; um cachimbo.</div>\n        </div>`;\n    case 'joia':\n      return `\n        <div class=\"stage stage-center\">\n          <div class=\"frame frame-jewel fade-item\" style=\"--d:.1s\">\n            <img src=\"${IMG_JOIA}\" alt=\"Anel Palace Vivara\" />\n          </div>\n          <div class=\"reveal reveal-line fade-item\" style=\"--d:.7s\">Isto n&atilde;o &eacute; uma joia.</div>\n          <p class=\"sub sub-serif fade-item\" style=\"--d:1.05s\">&Eacute; uma representa&ccedil;&atilde;o dela.</p>\n        </div>`;\n    case 'representacao':\n      return `\n        <div class=\"stage stage-left\">\n          <div class=\"eyebrow\">REPRESENTA&Ccedil;&Atilde;O</div>\n          <h1 class=\"display display-lg\">O que vendemos s&atilde;o representa&ccedil;&otilde;es<br/>dos nossos produtos.</h1>\n          <div class=\"hairline-sm hairline-left\"></div>\n          <p class=\"body body-wide\">No varejo de luxo, essa &eacute; a nossa &uacute;nica alavanca de diferencia&ccedil;&atilde;o &mdash; antes da propaganda, antes do desconto. &Eacute; como representamos o produto.</p>\n        </div>`;\n    case 'teste':\n      return `\n        <div class=\"stage stage-left\">\n          <div class=\"eyebrow\">O TESTE</div>\n          <div class=\"escalation\">\n            <div class=\"esc-line fade-item\" style=\"--d:.2s\"><span class=\"esc-q\">Produto sem nome?</span><span class=\"esc-dash\">&mdash;</span><span class=\"esc-a\">Vende.</span></div>\n            <div class=\"esc-line fade-item\" style=\"--d:.55s\"><span class=\"esc-q\">Sem descri&ccedil;&atilde;o?</span><span class=\"esc-dash\">&mdash;</span><span class=\"esc-a\">Vende.</span></div>\n            <div class=\"esc-line fade-item\" style=\"--d:.9s\"><span class=\"esc-q\">Sem foto?</span><span class=\"esc-dash\">&mdash;</span><span class=\"esc-a esc-a-strong\">Imposs&iacute;vel.</span></div>\n          </div>\n          <div class=\"hairline-sm hairline-left fade-item\" style=\"--d:1.2s\"></div>\n          <p class=\"closing-gold fade-item\" style=\"--d:1.4s\">A imagem &eacute; pe&ccedil;a fundamental da taxa de convers&atilde;o de um SKU.</p>\n        </div>`;\n    case 'risco':\n      return `\n        <div class=\"stage stage-left\">\n          <div class=\"eyebrow eyebrow-gold\">O RISCO</div>\n          <h1 class=\"display display-lg\">Conhecemos os riscos<br/>da IA com joias.</h1>\n          <div class=\"hairline-sm hairline-left\"></div>\n          <p class=\"body body-wide\">Um try-on virtual pode distorcer a pe&ccedil;a. Errar a propor&ccedil;&atilde;o. Inventar uma pedra.</p>\n        </div>`;\n    case 'virada':\n      return `\n        <div class=\"stage stage-center\">\n          <div class=\"eyebrow eyebrow-gold\">A VIRADA</div>\n          <h2 class=\"display display-md\">E se colocássemos a IA para trabalhar<br/>em um contexto seguro?</h2>\n          <div class=\"hairline-sm\"></div>\n          <h1 class=\"display display-lg\">Operando no cerne dos resultados:<br/><span class=\"gold-word\">a taxa de convers&atilde;o.</span></h1>\n        </div>`;\n    case 'proposta':\n      return `\n        <div class=\"stage stage-left\">\n          <div class=\"eyebrow\">O QUE PASSA A SER POSS&Iacute;VEL</div>\n          <div class=\"points\">\n            ${[\n              '100% das imagens curadas por profissionais do time Vivara.',\n              'Testes A/B de imagem operacionalizados &mdash; a convers&atilde;o decide.',\n              'E-commerce hiperpersonalizado por cliente.',\n              'Com hist&oacute;rico de vendas, sabemos exatamente qual foto gera o impulso de compra para cada cliente.'\n            ].map(function(t,i){\n              return '<div class=\"point fade-item\" style=\"--d:'+(0.2+i*0.28)+'s\">'\n                + '<div class=\"point-num\">'+pad(i+1)+'</div>'\n                + '<div class=\"point-text\">'+t+'</div>'\n                + '</div>';\n            }).join('')}\n          </div>\n        </div>`;\n    case 'handoff':\n      return `\n        <div class=\"stage stage-center\">\n          <img class=\"viv-logo viv-logo-lg\" src=\"${VIVARA_LOGO}\" alt=\"Vivara\" />\n          <div class=\"eyebrow eyebrow-gold\">FINALMENTE</div>\n          <h1 class=\"display display-demo\">[ DEMO ]</h1>\n          <div class=\"demo-hint\">\n            <span class=\"demo-arrow\">&rarr;</span>\n            <span class=\"demo-label\">Abrir o painel de produto</span>\n          </div>\n        </div>`;\n    default:\n      return '<div class=\"stage\"></div>';\n  }\n}\n\nexport default {\n  css: `\n    @import url('https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,500;0,600;0,700;1,500;1,600&family=Jost:wght@300;400;500;600&display=swap');\n\n    :host, .deck { width:100%; height:100%; }\n    .deck {\n      position:absolute; inset:0; overflow:hidden;\n      font-family:'Jost',sans-serif; -webkit-font-smoothing:antialiased;\n      background:#1A1A1A;\n    }\n    .deck * { box-sizing:border-box; }\n\n    .slide {\n      position:absolute; inset:0;\n      display:flex; align-items:center; justify-content:center;\n      opacity:0; visibility:hidden; pointer-events:none;\n      transition:opacity .9s cubic-bezier(.22,.61,.36,1), transform 1.1s cubic-bezier(.22,.61,.36,1), visibility 0s linear .9s;\n      transform:translateY(14px) scale(.994);\n    }\n    .slide.active {\n      opacity:1; visibility:visible; pointer-events:auto;\n      transform:translateY(0) scale(1);\n      transition:opacity .9s cubic-bezier(.22,.61,.36,1), transform 1.1s cubic-bezier(.22,.61,.36,1), visibility 0s;\n    }\n    .slide.light { background:#FAF8F5; color:#1A1A1A; }\n    .slide.dark  { background:#1A1A1A; color:#E8E2D9; }\n\n    .stage {\n      position:relative; z-index:2;\n      width:100%; max-width:1080px; padding:0 96px;\n      display:flex; flex-direction:column;\n    }\n    .stage-center { align-items:center; text-align:center; }\n    .stage-left { align-items:flex-start; text-align:left; }\n\n    .eyebrow {\n      font-family:'Jost',sans-serif; font-weight:500;\n      font-size:13px; letter-spacing:.32em; text-transform:uppercase;\n      color:#9B8E7E; margin-bottom:38px;\n    }\n    .slide.dark .eyebrow { color:#9B8E7E; }\n    .eyebrow-gold { color:#B08D57 !important; }\n\n    .viv-logo { height:30px; width:auto; display:inline-block; vertical-align:middle; }\n    .slide.dark .viv-logo { filter:brightness(0) invert(1); }\n    .eyebrow-logo { display:inline-flex; align-items:center; gap:14px; }\n    .eyebrow-sep { color:#B08D57; }\n    .viv-logo-lg { height:34px; margin-bottom:30px; }\n\n    .display {\n      font-family:'Cormorant Garamond',serif; font-weight:600;\n      line-height:1.04; letter-spacing:-.005em; margin:0;\n    }\n    .display-xl { font-size:58px; }\n    .display-lg { font-size:52px; }\n    .display-md { font-size:34px; font-weight:500; color:#9B8E7E; margin-bottom:6px; }\n    .display-huge { font-size:96px; font-weight:700; line-height:.98; }\n    .display-demo { font-size:104px; font-weight:600; letter-spacing:.06em; color:#E8E2D9; }\n    .ital { font-style:italic; font-weight:700; color:#C9A24B; }\n    .gold-word { color:#C9A24B; font-style:italic; }\n\n    .hairline-sm {\n      width:64px; height:1px; background:#B08D57; margin:34px auto; opacity:.8;\n    }\n    .hairline-left { margin:34px 0; }\n\n    .sub, .body { font-weight:300; color:#6B6357; }\n    .slide.dark .sub, .slide.dark .body { color:#9B8E7E; }\n    .sub-serif {\n      font-family:'Cormorant Garamond',serif; font-style:italic;\n      font-size:24px; font-weight:500; margin:0;\n    }\n    .body-wide { font-family:'Jost',sans-serif; font-size:19px; font-weight:300; line-height:1.7; max-width:620px; }\n\n    .frame { padding:18px; background:transparent; }\n    .frame-art {\n      border:1px solid #2E2A24; box-shadow:0 30px 80px rgba(0,0,0,.5);\n      background:#0f0f0f;\n    }\n    .frame-art img { display:block; max-height:340px; max-width:520px; width:auto; height:auto; }\n    .frame-jewel {\n      border:1px solid #2E2A24; box-shadow:0 30px 90px rgba(0,0,0,.6);\n      background:#111;\n    }\n    .frame-jewel img { display:block; max-height:380px; max-width:380px; width:auto; height:auto; border-radius:2px; }\n\n    .caption { margin:28px 0 4px; }\n    .caption-ital {\n      font-family:'Cormorant Garamond',serif; font-style:italic; font-weight:500;\n      font-size:26px; color:#E8E2D9;\n    }\n    .credit { font-family:'Jost',sans-serif; font-weight:300; font-size:12px; letter-spacing:.14em; color:#6B6357; text-transform:uppercase; }\n\n    .reveal-line {\n      margin-top:30px; font-family:'Cormorant Garamond',serif; font-weight:600;\n      font-size:40px; color:#C9A24B; letter-spacing:.01em;\n    }\n\n    .escalation { margin-top:12px; display:flex; flex-direction:column; gap:20px; }\n    .esc-line { display:flex; align-items:baseline; gap:20px; font-family:'Cormorant Garamond',serif; }\n    .esc-q { font-size:38px; font-weight:500; color:#1A1A1A; }\n    .esc-dash { color:#B08D57; font-size:30px; }\n    .esc-a { font-size:38px; font-weight:600; color:#6B6357; font-style:italic; }\n    .esc-a-strong { color:#B08D57; }\n    .closing-gold {\n      font-family:'Cormorant Garamond',serif; font-style:italic; font-weight:600;\n      font-size:28px; color:#B08D57; max-width:640px; line-height:1.35;\n    }\n\n    .points { display:flex; flex-direction:column; margin-top:6px; width:100%; max-width:760px; }\n    .point { display:flex; align-items:flex-start; gap:28px; padding:26px 0; border-top:1px solid #E8E2D9; }\n    .point:last-child { border-bottom:1px solid #E8E2D9; }\n    .point-num { font-family:'Cormorant Garamond',serif; font-weight:600; font-size:26px; color:#B08D57; min-width:44px; line-height:1.1; }\n    .point-text { font-family:'Jost',sans-serif; font-weight:300; font-size:20px; line-height:1.5; color:#1A1A1A; }\n\n    .demo-hint {\n      margin-top:40px; display:inline-flex; align-items:center; gap:14px;\n      padding:16px 34px; border:1px solid #2E2A24; border-radius:2px;\n      animation:pulse 2.4s ease-in-out infinite;\n    }\n    .demo-arrow { color:#C9A24B; font-size:22px; }\n    .demo-label { font-family:'Jost',sans-serif; font-weight:400; font-size:15px; letter-spacing:.14em; text-transform:uppercase; color:#E8E2D9; }\n    @keyframes pulse {\n      0%,100% { border-color:#2E2A24; box-shadow:0 0 0 0 rgba(201,162,75,0); }\n      50% { border-color:#B08D57; box-shadow:0 0 34px 0 rgba(201,162,75,.16); }\n    }\n\n    /* stagger reveal on active slide */\n    .fade-item { opacity:0; transform:translateY(12px); }\n    .slide.active .fade-item {\n      animation:fadeUp .9s cubic-bezier(.22,.61,.36,1) forwards;\n      animation-delay:var(--d, .1s);\n    }\n    @keyframes fadeUp { to { opacity:1; transform:translateY(0); } }\n\n    /* top progress hairline */\n    .progress { position:absolute; top:0; left:0; height:2px; background:#B08D57; z-index:20; transition:width .9s cubic-bezier(.22,.61,.36,1); }\n    .slide.dark ~ .progress { }\n\n    /* nav bar */\n    .navbar {\n      position:absolute; left:0; right:0; bottom:0; z-index:20;\n      height:64px; display:flex; align-items:center; justify-content:space-between;\n      padding:0 44px; pointer-events:none;\n    }\n    .navbar > * { pointer-events:auto; }\n    .nav-counter {\n      font-family:'Jost',sans-serif; font-weight:400; font-size:12px; letter-spacing:.24em;\n      color:#9B8E7E;\n    }\n    .nav-counter .cur { color:#B08D57; }\n    .dots { display:flex; align-items:center; gap:11px; }\n    .dot {\n      width:6px; height:6px; border-radius:999px; background:#9B8E7E; opacity:.35;\n      cursor:pointer; transition:opacity .3s, transform .3s, background .3s;\n    }\n    .dot:hover { opacity:.7; }\n    .dot.on { opacity:1; background:#B08D57; transform:scale(1.5); }\n    .arrows { display:flex; align-items:center; gap:8px; }\n    .arrow {\n      width:38px; height:38px; display:flex; align-items:center; justify-content:center;\n      border:1px solid #9B8E7E; border-radius:999px; color:#9B8E7E; cursor:pointer;\n      font-size:15px; user-select:none; transition:border-color .3s, color .3s, background .3s;\n    }\n    .arrow:hover { border-color:#B08D57; color:#B08D57; }\n    .arrow.disabled { opacity:.25; pointer-events:none; }\n\n    /* nav color tuned per theme via slide class on host */\n    .deck.on-light .nav-counter, .deck.on-light .dot { }\n    .deck.on-dark .arrow { border-color:#6B6357; }\n\n    /* invisible click zones */\n    .clickzone { position:absolute; top:0; bottom:64px; width:33.333%; z-index:10; cursor:pointer; }\n    .clickzone.left { left:0; }\n    .clickzone.right { right:0; }\n    .clickzone.mid { left:33.333%; pointer-events:none; }\n    .gate{position:absolute;inset:0;background:radial-gradient(circle at 50% 30%,#242019,#141210);display:flex;align-items:center;justify-content:center;z-index:50;font-family:'Jost',sans-serif}\n    .gbox{display:flex;flex-direction:column;align-items:center;gap:14px;padding:52px 60px;border:1px solid #2E2A24;background:rgba(255,255,255,.02);border-radius:6px}\n    .glogo{height:30px;width:auto;filter:brightness(0) invert(1)}\n    .gsub{font-size:10px;letter-spacing:.3em;text-transform:uppercase;color:#B08D57}\n    .gin{width:240px;padding:12px 14px;background:transparent;border:1px solid #4A443A;border-radius:3px;color:#E8E2D9;font:inherit;font-size:14px;text-align:center;letter-spacing:.2em;outline:none}\n    .gin:focus{border-color:#B08D57}\n    .gbtn{width:240px;padding:12px;background:#B08D57;border:none;color:#fff;font:inherit;font-size:12px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;cursor:pointer;border-radius:3px;transition:.18s}\n    .gbtn:hover{background:#C9A24B}\n    .gerr{font-size:11px;color:#C96A5A;min-height:14px}\n  `,\n  render(d2){\n    var unlocked=d2.state.unlocked===true;if(!unlocked){try{unlocked=localStorage.getItem('vivGate2020')==='1';}catch(_){}}\n    if(!unlocked){return '<div class=\"gate\"><div class=\"gbox\"><img class=\"glogo\" src=\"'+VIVARA_LOGO+'\"/><div class=\"gsub\">Acesso restrito</div><input class=\"gin\" data-gpw type=\"password\" placeholder=\"Senha\"/><button class=\"gbtn\" data-gunlock>Entrar</button><div class=\"gerr\">'+(d2.state.gateErr?'Senha incorreta':'')+'</div></div></div>';}\n    const cur = d2.state.i || 0;\n    const total = SLIDES.length;\n    const slidesMarkup = SLIDES.map(function(s){\n      const active = s.id === cur ? ' active' : '';\n      return '<section class=\"slide '+s.theme+active+'\" data-slide=\"'+s.id+'\">'+slideHTML(s.kind)+'</section>';\n    }).join('');\n\n    const dots = SLIDES.map(function(s){\n      return '<span class=\"dot'+(s.id===cur?' on':'')+'\" data-goto=\"'+s.id+'\"></span>';\n    }).join('');\n\n    const progressPct = ((cur+1)/total*100).toFixed(3);\n    const onTheme = SLIDES[cur].theme === 'dark' ? 'on-dark' : 'on-light';\n\n    return `\n      <div class=\"deck ${onTheme}\">\n        ${slidesMarkup}\n        <div class=\"progress\" style=\"width:${progressPct}%\"></div>\n        <div class=\"clickzone left\" data-nav=\"prev\"></div>\n        <div class=\"clickzone mid\"></div>\n        <div class=\"clickzone right\" data-nav=\"next\"></div>\n        <div class=\"navbar\">\n          <div class=\"nav-counter\"><span class=\"cur\">${pad(cur+1)}</span> / ${pad(total)}</div>\n          <div class=\"dots\">${dots}</div>\n          <div class=\"arrows\">\n            <div class=\"arrow ${cur===0?'disabled':''}\" data-nav=\"prev\">&larr;</div>\n            <div class=\"arrow ${cur===total-1?'disabled':''}\" data-nav=\"next\">&rarr;</div>\n          </div>\n        </div>\n      </div>`;\n  },\n  mounted(d2){\n    function tryUnlock(){var el=d2.$('[data-gpw]');var v=el?el.value:'';if(v==='VivaraData22020'){try{localStorage.setItem('vivGate2020','1');}catch(_){}d2.setState({unlocked:true,gateErr:false});}else{d2.setState({gateErr:true});}}\n    d2.on('[data-gunlock]','click',tryUnlock);\n    d2.on('[data-gpw]','keydown',function(e){if(e.key==='Enter'){e.stopPropagation();tryUnlock();}});\n    if (d2.state.i == null) d2.setState({ i: 0 });\n    const total = SLIDES.length;\n    const go = function(n){\n      const clamped = Math.max(0, Math.min(total-1, n));\n      if (clamped !== (d2.state.i||0)) d2.setState({ i: clamped });\n    };\n    const next = function(){ go((d2.state.i||0) + 1); };\n    const prev = function(){ go((d2.state.i||0) - 1); };\n\n    d2.on('[data-nav=\"next\"]','click', function(){ next(); });\n    d2.on('[data-nav=\"prev\"]','click', function(){ prev(); });\n    d2.on('[data-goto]','click', function(e, el){\n      const idx = parseInt(el.getAttribute('data-goto'), 10);\n      if (!isNaN(idx)) go(idx);\n    });\n\n    d2.on(document, 'keydown', function(e){\n      if (e.key === 'ArrowRight' || e.key === 'PageDown' || e.key === ' ') { e.preventDefault(); next(); }\n      else if (e.key === 'ArrowLeft' || e.key === 'PageUp') { e.preventDefault(); prev(); }\n      else if (e.key === 'Home') { go(0); }\n      else if (e.key === 'End') { go(total-1); }\n    });\n  }\n}"}}}}}}}},{"_id":"5ed9bed7b9e0891ce913e884","component":"data2-core-types@Component","params":{"package":"data2-core","component":"DataSource","renderable":{"dimensions":{"disabled":false,"component":"data2-core-types@Dimensions","params":{"width":1366,"exactWidth":false,"exactHeight":false,"height":768}}}}},{"_id":"5f472ae463c680de4ff296e9","component":"data2-core-types@Component","params":{"package":"data2-core","component":"Data2TableDataSource","extends":"data2-core@DataSource","renderable":{"dimensions":{"disabled":false,"component":"data2-core-types@Dimensions","params":{"width":1366,"exactWidth":false,"exactHeight":false,"height":768}}}}},{"_id":"614df5ca33fad3ebebb9879b","component":"data2-core-types@Component","params":{"package":"http","component":"CustomHTTPDataSource","extends":"data2-core@DataSource","definition":{"params":{},"component":"data2-core-types@Definition"},"renderable":{"dimensions":{"disabled":false,"component":"data2-core-types@Dimensions","params":{"width":1366,"exactWidth":false,"exactHeight":false,"height":768}}}}}]}},{"reference":"ExternalComponentInstancesTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"_id":"5f060d9b1ca96def42f3c40a","displayName":"Builder AuthStrategy","component":"data2-core@AuthenticationStrategy","system":"5e3b796d6228227ca637d0f4","params":{"credentials":[{"component":"data2-core-types@DataSetColumnReference","params":{"column":"email"}},{"component":"data2-core-types@DataSetColumnReference","params":{"column":"password"}},{"component":"data2-core-types@DataSetColumnReference","params":{"column":"status"}}],"verifier":{"component":"data2-core-types@DataSetReference","params":{"reference":"UsersDataSet"}},"sessionShared":{"component":"data2-core-primitives@Boolean","params":{"content":false}},"password":{"disabled":false,"component":"data2-core-types@DataSetColumnReference","params":{"column":"password"}},"email":{"disabled":false,"component":"data2-core-types@DataSetColumnReference","params":{"column":"email"}},"resetPassword":{"resetEmail":{"artboard":{"params":{"preventEvaluation":true,"reference":"nR6Q9d7qdaPtZhJ28Q8Dy"},"component":"data2-core-types@ArtboardReference"}},"resetSuccessEmail":{"artboard":{"params":{"preventEvaluation":true,"reference":"yPCJBTKo8q1Mw0B_3Kpwl"},"component":"data2-core-types@ArtboardReference"}}},"session":[{"component":"data2-core-types@DataSetColumnReference","params":{"column":"name"}},{"component":"data2-core-types@DataSetColumnReference","params":{"column":"email"}},{"component":"data2-core-types@DataSetColumnReference","params":{"column":"password"}},{"component":"data2-core-types@DataSetColumnReference","params":{"column":"status"}}],"sessionMetadata":{"params":{"actions":[{"params":{"compare":{"params":{"subject":{"params":{"components":[{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$user._id"}}}},{"params":{"comparisonSubject":{"component":"data2-core-primitives@String","params":{"content":"active"}},"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$user.status"}}}}},"component":"data2-core-comparison-operators@Equal","displayName":"is active user"}]},"component":"data2-core-logical-operators@And","displayName":"is active and has _id"}},"component":"data2-core-logical-operators@Not"},"then":{"params":{"message":{"component":"data2-core-primitives@String","params":{"content":"Invalid Credentials"}},"code":{"component":"data2-core-primitives@String","params":{"content":"401"}}},"component":"data2-core-types@Error"}},"component":"data2-core-flow@If","displayName":"check $user"},{"params":{"action":{"params":{"pattern":{"component":"data2-core-primitives@String","params":{"content":"@data2.app"}},"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$user.email"}}}}},"component":"data2-core-functions@Includes","displayName":"isData2User"},"resultName":{"component":"data2-core-primitives@String","params":{"content":"is_data2_user"}}},"component":"data2-core-flow@Step"},{"params":{"action":{"params":{"pattern":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$metadata.d2_app"}}}},"subject":[{"component":"data2-core-primitives@String","params":{"content":"management"}}]},"component":"data2-core-functions@Includes","displayName":"isData2App Exception"},"resultName":{"component":"data2-core-primitives@String","params":{"content":"is_data2_app_exception"}}},"component":"data2-core-flow@Step"},{"params":{"resultName":{"component":"data2-core-primitives@String","params":{"content":"has_access"}},"action":{"params":{"compare":{"params":{"components":[{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"is_data2_user"}}}},{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"is_data2_app_exception"}}}}]},"component":"data2-core-logical-operators@Or"},"else":{"params":{"actions":[{"params":{"actions":[{"params":{"compare":{"params":{"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$metadata.system"}}}}},"component":"data2-core-logical-operators@Not"},"then":{"params":{"message":{"component":"data2-core-primitives@String","params":{"content":"Invalid Credentials"}},"code":{"component":"data2-core-primitives@String","params":{"content":"401"}}},"component":"data2-core-types@Error"}},"component":"data2-core-flow@If","displayName":"check $metadata.system"},{"params":{"module":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"WuUa-VKHhW9uYU0E3-mJ8"}},"prop":"filter","args":[{"_id":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$metadata.system"}}}}}]},"component":"data2-core-types@Interaction"},{"params":{"compare":{"params":{"subject":{"component":"data2-core-types@Getter","params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"WuUa-VKHhW9uYU0E3-mJ8"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"data.records.length"}}}}},"component":"data2-core-logical-operators@Not","displayName":"systems not found"},"then":{"params":{"message":{"component":"data2-core-primitives@String","params":{"content":"Invalid Credentials"}},"code":{"component":"data2-core-primitives@String","params":{"content":"401"}}},"component":"data2-core-types@Error"}},"component":"data2-core-flow@If","displayName":"check system found"},{"params":{"actions":[{"params":{"module":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"Ok6Tsu5XkS7r8PyW_7TyW"}},"prop":"filter","args":[{"user":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$user._id"}}}},"organization":{"component":"data2-core-types@Getter","params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"WuUa-VKHhW9uYU0E3-mJ8"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"cursor.current.organization._id"}}}}}]},"component":"data2-core-types@Interaction"},{"params":{"module":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"NqKAY34n2ffFL64zamp7t"}},"prop":"filter","args":[{"user":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$user._id"}}}},"system":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$metadata.system"}}}}}]},"component":"data2-core-types@Interaction"}]},"component":"data2-core-flow@Parallel"}]},"component":"data2-core-flow@Series","displayName":"common setup"},{"params":{"then":{"params":{"content":true},"component":"data2-core-primitives@Boolean"},"else":{"params":{"content":false},"component":"data2-core-primitives@Boolean"},"compare":{"params":{"components":{"params":{"array":{"params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"WuUa-VKHhW9uYU0E3-mJ8"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"data.records"}}},"component":"data2-core-types@Getter"},"mapper":{"disabled":false,"component":"data2-core-functions@Function","params":{"parameters":[{"component":"data2-core-primitives@String","params":{"content":"system"}}],"body":{"params":{"expression":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"system.visibility"}}}},"defaultCase":{"params":{"content":false},"component":"data2-core-primitives@Boolean"},"cases":[{"component":"data2-core-flow@Case","params":{"expression":{"component":"data2-core-primitives@String","params":{"content":"public"}},"value":{"params":{"components":[{"params":{"array":{"params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"Ok6Tsu5XkS7r8PyW_7TyW"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"data.records"}}},"component":"data2-core-types@Getter"},"filter":{"disabled":false,"component":"data2-core-functions@Function","params":{"parameters":[{"component":"data2-core-primitives@String","params":{"content":"member"}}],"body":{"params":{"components":[{"params":{"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"member.organization._id"}}}},"comparisonSubject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"system.organization._id"}}}}},"component":"data2-core-comparison-operators@Equal","displayName":"is org member"},{"params":{"pattern":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"member.role"}}}},"subject":[{"component":"data2-core-primitives@String","params":{"content":"owner"}},{"component":"data2-core-primitives@String","params":{"content":"billing-owner"}},{"component":"data2-core-primitives@String","params":{"content":"admin"}},{"component":"data2-core-primitives@String","params":{"content":"member"}}]},"component":"data2-core-functions@Includes","displayName":"has role with access"}]},"component":"data2-core-logical-operators@And","displayName":"has org member role with access"}}}},"component":"data2-core-functions@ArrayFind","displayName":"is org member"},{"params":{"components":[{"params":{"array":{"params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"Ok6Tsu5XkS7r8PyW_7TyW"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"data.records"}}},"component":"data2-core-types@Getter"},"filter":{"disabled":false,"component":"data2-core-functions@Function","params":{"parameters":[{"component":"data2-core-primitives@String","params":{"content":"member"}}],"body":{"params":{"components":[{"params":{"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"member.organization._id"}}}},"comparisonSubject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"system.organization._id"}}}}},"component":"data2-core-comparison-operators@Equal","displayName":"is org member"},{"params":{"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"member.role"}}}},"comparisonSubject":{"component":"data2-core-primitives@String","params":{"content":"collaborator"}}},"component":"data2-core-comparison-operators@Equal","displayName":"is collaborator"}]},"component":"data2-core-logical-operators@And","displayName":"is org member and collaborator"}}}},"component":"data2-core-functions@ArrayFind","displayName":"is collaborator"},{"params":{"array":{"params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"NqKAY34n2ffFL64zamp7t"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"data.records"}}},"component":"data2-core-types@Getter"},"filter":{"disabled":false,"component":"data2-core-functions@Function","params":{"parameters":[{"component":"data2-core-primitives@String","params":{"content":"access"}}],"body":{"params":{"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"access.system._id"}}}},"comparisonSubject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"system._id"}}}}},"component":"data2-core-comparison-operators@Equal"}}}},"component":"data2-core-functions@ArrayFind","displayName":"has system access"}]},"component":"data2-core-logical-operators@And","displayName":"is collaborator and has system access"}]},"component":"data2-core-logical-operators@Or"}}},{"component":"data2-core-flow@Case","params":{"expression":{"component":"data2-core-primitives@String","params":{"content":"private"}},"value":{"params":{"components":[{"params":{"array":{"params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"Ok6Tsu5XkS7r8PyW_7TyW"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"data.records"}}},"component":"data2-core-types@Getter"},"filter":{"disabled":false,"component":"data2-core-functions@Function","params":{"parameters":[{"component":"data2-core-primitives@String","params":{"content":"member"}}],"body":{"params":{"components":[{"params":{"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"member.organization._id"}}}},"comparisonSubject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"system.organization._id"}}}}},"component":"data2-core-comparison-operators@Equal","displayName":"is org member"},{"params":{"pattern":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"member.role"}}}},"subject":[{"component":"data2-core-primitives@String","params":{"content":"owner"}},{"component":"data2-core-primitives@String","params":{"content":"admin"}}]},"component":"data2-core-functions@Includes","displayName":"is owner/admin"}]},"component":"data2-core-logical-operators@And","displayName":"has org member role with access"}}}},"component":"data2-core-functions@ArrayFind","displayName":"is owner/admin"},{"params":{"components":[{"params":{"array":{"params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"Ok6Tsu5XkS7r8PyW_7TyW"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"data.records"}}},"component":"data2-core-types@Getter"},"filter":{"disabled":false,"component":"data2-core-functions@Function","params":{"parameters":[{"component":"data2-core-primitives@String","params":{"content":"member"}}],"body":{"params":{"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"member.organization._id"}}}},"comparisonSubject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"system.organization._id"}}}}},"component":"data2-core-comparison-operators@Equal"}}}},"component":"data2-core-functions@ArrayFind","displayName":"is org member"},{"params":{"array":{"params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"NqKAY34n2ffFL64zamp7t"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"data.records"}}},"component":"data2-core-types@Getter"},"filter":{"disabled":false,"component":"data2-core-functions@Function","params":{"parameters":[{"component":"data2-core-primitives@String","params":{"content":"access"}}],"body":{"params":{"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"access.system._id"}}}},"comparisonSubject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"system._id"}}}}},"component":"data2-core-comparison-operators@Equal"}}}},"component":"data2-core-functions@ArrayFind","displayName":"has system access"}]},"component":"data2-core-logical-operators@And","displayName":"is member and has system access"}]},"component":"data2-core-logical-operators@Or","displayName":"is owner/admin or has system access"}}}]},"component":"data2-core-flow@Switch"}}}},"component":"data2-core-functions@ArrayMap"}},"component":"data2-core-logical-operators@And","displayName":"has org member for all systems in request"}},"component":"data2-core-flow@If"}]},"component":"data2-core-flow@Series"},"then":{"params":{"content":true},"component":"data2-core-primitives@Boolean"}},"component":"data2-core-flow@If"}},"component":"data2-core-flow@Step"},{"params":{"then":{"system":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$metadata.system"}}}}},"else":{"params":{"message":{"component":"data2-core-primitives@String","params":{"content":"Invalid Credentials"}},"code":{"component":"data2-core-primitives@String","params":{"content":"401"}}},"component":"data2-core-types@Error"},"compare":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"has_access"}}}}},"component":"data2-core-flow@If"}]},"component":"data2-core-flow@Series"},"sessionExpiresIn":{"component":"data2-core-primitives@Number","params":{"content":604800}},"sessionRenewal":{"component":"data2-core-primitives@Boolean","params":{"content":true}}},"reference":"Data2BuilderAuthentication","updatedAt":"2025-10-28T02:48:49.233Z"},{"_id":"5f060ee51ca96def42f3fbd1","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"UsersTableDataSource"}},"pagination":{"size":{"component":"data2-core-primitives@Number","params":{"content":1}}}},"reference":"UsersDataSet","updatedAt":"2026-03-04T21:16:40.291Z"},{"_id":"68f938cf5fb002e33752a43d","displayName":"InternalApplicationsAuthenticationStrategy","component":"data2-core@AuthenticationStrategy","system":"5e3b796d6228227ca637d0f4","params":{"resetPassword":{"resetEmail":{"artboard":{"params":{"preventEvaluation":true},"component":"data2-core-types@ArtboardReference"}},"resetSuccessEmail":{"artboard":{"params":{"preventEvaluation":true},"component":"data2-core-types@ArtboardReference"}}},"verifier":{"disabled":false,"component":"data2-core-types@DataSetReference","params":{"reference":"InternalApplicationsVerifierDataSet"}},"password":{"disabled":false,"component":"data2-core-types@DataSetColumnReference","params":{"column":"secret"}},"credentials":[{"component":"data2-core-types@FieldReference","params":{"key":"application"}},{"component":"data2-core-types@FieldReference","params":{"key":"secret"}},{"component":"data2-core-types@FieldReference","params":{"key":"status"}}],"session":[{"component":"data2-core-types@FieldReference","params":{"key":"application"}},{"component":"data2-core-types@FieldReference","params":{"key":"secret"}},{"component":"data2-core-types@FieldReference","params":{"key":"status"}}]},"reference":"InternalApplicationsAuthenticationStrategy","updatedAt":"2025-10-22T20:08:54.442Z","createdAt":"2025-10-22T20:04:31.198Z"},{"component":"data2-core@DataSet","reference":"SessionsDataSet","params":{"requiresConfirmation":false,"pk":"key","datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"data2sessionsdatasource"}}}},{"reference":"UsersTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"component":"data2-core@ServerSessionsDataSource","reference":"data2sessionsdatasource","params":{}},{"_id":"5f1600b70528b92601890f75","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"ServiceComponentInstancesTableDataSource"}},"pk":"_id","autoEdit":true,"master":{"params":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"_id"}}},"component":"data2-core-types@DataSetMaster"},"autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}},"policies":{"params":{"allowGet":{"component":"data2-core-primitives@Boolean","params":{"content":true}}},"component":"data2@hkXy-UhMjhyfptdE6_fpW"}},"reference":"ServiceComponentInstancesDataSet","updatedAt":"2025-11-06T21:07:20.208Z","createdAt":"2020-07-20T20:38:15.436Z"},{"_id":"5f1602190528b92601890f7d","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"pagination":{"size":40000},"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"ComponentInstancesTableDataSource"}},"sort":{"_id":1},"pk":"_id","autoEdit":true,"master":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"_id"}}},"autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}},"policies":{"params":{"allowGet":{"component":"data2-core-primitives@Boolean","params":{"content":true}}},"component":"data2@hkXy-UhMjhyfptdE6_fpW"}},"reference":"ComponentInstancesDataSet","updatedAt":"2025-11-06T21:07:07.089Z","createdAt":"2020-07-20T20:44:09.350Z"},{"_id":"5f16017f0528b92601890f7a","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"FileComponentInstancesTableDataSource"}},"pk":"_id","autoEdit":true,"filter":{"domain":{"component":"data2-core-types@Reference","params":{"reference":"clientApplicationDomain"}}},"master":{"params":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"_id"}}},"component":"data2-core-types@DataSetMaster"},"autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}}},"reference":"FileComponentInstancesDataSet","updatedAt":"2023-08-03T16:08:18.193Z","createdAt":"2020-07-20T20:41:35.797Z"},{"_id":"5f1601990528b92601890f7b","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"ApplicationsTableDataSource"}},"pk":"_id","autoEdit":{"component":"data2-core-primitives@Boolean","params":{"content":true}},"master":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"params":{"column":"_id"},"component":"data2-core-types@DataSetColumnReference"}},"autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}}},"reference":"ApplicationsDataSet","updatedAt":"2022-12-13T21:51:13.995Z","createdAt":"2020-07-20T20:42:01.657Z"},{"_id":"5f16172a0528b92601890f85","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"pagination":{"size":{"component":"data2-core-primitives@Number","params":{"content":10000}}},"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"DataComponentInstancesTableDataSource"}},"pk":"_id","autoEdit":true,"master":{"params":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"_id"}}},"component":"data2-core-types@DataSetMaster"},"autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}},"policies":{"params":{"allowGet":{"component":"data2-core-primitives@Boolean","params":{"content":true}}},"component":"data2@hkXy-UhMjhyfptdE6_fpW"}},"reference":"DataComponentInstancesDataSet","updatedAt":"2025-11-06T21:07:12.831Z","createdAt":"2020-07-20T22:14:02.097Z"},{"_id":"60ddc1bbda3861ca65407c5a","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"FileComponentInstancesTableDataSource"}},"pk":"_id","autoEdit":true,"filter":{"domain":{"component":"data2-core-types@Reference","params":{"reference":"clientApplicationDomain"}}},"pagination":{"size":1},"master":{"params":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"_id"}}},"component":"data2-core-types@DataSetMaster"}},"reference":"OneFileComponentInstancesDataSet","updatedAt":"2022-02-09T19:44:38.036Z","createdAt":"2020-07-20T20:41:35.797Z"},{"_id":"63ee3d38b8c9838c62fb05fb","displayName":"DriveFileComponentInstancesDataSet","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"FileComponentInstancesTableDataSource"}},"pk":"_id","autoEdit":true,"filter":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core@Drive"}}},"master":{"params":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"_id"}}},"component":"data2-core-types@DataSetMaster"},"autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}}},"reference":"DriveFileComponentInstancesDataSet","updatedAt":"2025-12-04T21:58:32.367Z","createdAt":"2023-02-16T14:27:07.797Z"},{"reference":"ServiceComponentInstancesTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[{"_id":"6a16ed543e1cd42ae6b1ee4f","component":"data2-core-ai@Assistant","reference":"l1-plain","system":"6a11aec3b70f2dc40823369a","params":{"model":"cerebras","_context":"You are a concise assistant. Answer in 1-2 short sentences max.","creativity":30}},{"_id":"6a16ee1e171b7dc03e10253e","component":"data2-core-ai@Assistant","reference":"l7-image","system":"6a11aec3b70f2dc40823369a","params":{"model":"cerebras","_context":"You generate images. Style: editorial illustration, soft gradient lighting, isometric composition, 1:1 ratio.","creativity":70}},{"_id":"6a16ee1b88626343794bd227","component":"data2-core-ai@Assistant","reference":"l6-colors","system":"6a11aec3b70f2dc40823369a","params":{"model":"cerebras","_context":"You are a designer who generates color palettes for moods. Given a mood description, return EXACTLY this JSON shape: { \"primary\": \"#RRGGBB\", \"accent\": \"#RRGGBB\", \"neutralDark\": \"#RRGGBB\", \"neutralLight\": \"#RRGGBB\", \"rationale\": string }. All four colors MUST be valid 6-digit hex. The rationale is one sentence (max 18 words) explaining the choice.","creativity":85}},{"_id":"6a2d91d2dbf815e74e992184","component":"data2-rush@HTTPListener","reference":"fdPlaceOrder","system":"6a11aec3b70f2dc40823369a","params":{}},{"_id":"6a398b114d21de73ecd289fb","component":"data2-rush@HTTPListener","reference":"vans-pp-model","system":"6a11aec3b70f2dc40823369a","params":{}},{"_id":"6a398983c726c3c1b9e2bb2a","component":"data2-rush@HTTPListener","reference":"vans-pp-upload","system":"6a11aec3b70f2dc40823369a","params":{}},{"_id":"6a398623e5a95378ceed6579","component":"data2-rush@HTTPListener","reference":"vans-pp-search","system":"6a11aec3b70f2dc40823369a","params":{}},{"_id":"6a399f8b38143640ca88d4b1","component":"data2-rush@HTTPListener","reference":"vans-pp-customize","system":"6a11aec3b70f2dc40823369a","params":{}},{"_id":"6a39869b253db03eb29bd591","component":"data2-rush@HTTPListener","reference":"vans-pp-tryon","system":"6a11aec3b70f2dc40823369a","params":{}},{"_id":"6a2e0d2561efae759d5da3f6","component":"data2-core-connect@HttpRequest","reference":"vivaraSearchReq","system":"6a11aec3b70f2dc40823369a","params":{"parent":{"component":"data2-core-types@InstanceReference","params":{"component":"data2-core-connect@HttpClient","reference":"vivara"}},"method":{"component":"data2-core-primitives@String","params":{"content":"GET"}},"requestParameters":[],"useProxy":true}},{"_id":"6a2e0ce51b1e52cefa12aac6","component":"data2-core-connect@HttpClient","reference":"vivara","system":"6a11aec3b70f2dc40823369a","params":{}}]}},{"reference":"ComponentInstancesTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[{"_id":"6a455ecdb95d9a763fc49b91","component":"data2-core-primitives@Artboard","system":"6a11aec3b70f2dc40823369a","displayName":"💎 Vivara · Produto","params":{"title":{"component":"data2-core-primitives@String","params":{"content":"💎 Vivara · Produto"}},"dimensions":{"component":"data2-core-types@Dimensions","params":{"width":1440,"height":900}},"position":{"component":"data2-core-types@Position","params":{"x":-957,"y":2266,"exactX":-957.49,"exactY":2265.79}}},"reference":"OBA2NRRzHDlhFsnRF4tBk"},{"_id":"24c7e367ac70f54762233fd1","parent":"6a455ecdb95d9a763fc49b91","component":"ai-playground@kVivProduct","system":"6a11aec3b70f2dc40823369a","displayName":"Viv Product Panel","params":{"products":{"component":"data2-core-types@DataSetReference","params":{"reference":"vivaraProductsDataSet"}},"models":{"component":"data2-core-types@DataSetReference","params":{"reference":"9_7GWgCZIZHlKnHFteBFHDataSet"}},"library":{"component":"data2-core-types@DataSetReference","params":{"reference":"32qFMbWLUAzD_QOgxXlCDDataSet"}},"super":{"position":{"component":"data2-core-types@Position","params":{"x":0,"y":0,"freeTransform":true,"left":true,"right":false,"top":true,"bottom":false,"growH":true,"growV":true}},"dimensions":{"component":"data2-core-types@Dimensions","params":{"width":1440,"height":900}}}},"reference":"LNbvHEwVBp844f3JotKmc"}]}},{"_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":"6a467b9c20611373d1fb4622","displayName":"Vivara · Performance de Produto","reference":"M7DfcbVFrtCrbYfKKzHpA","params":{"domain":{"component":"data2-core-primitives@String","params":{"content":"vivara"}},"entryPoint":{"component":"data2-core-types@ComponentInstanceReference","params":{"component":"data2-core-primitives@Artboard","reference":"OBA2NRRzHDlhFsnRF4tBk"}}},"system":"6a11aec3b70f2dc40823369a","component":"data2-core-primitives@Application"}]}},{"reference":"DataComponentInstancesTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[{"_id":"6a2f15806202ef3347df3508","component":"data2-core-connect@PowerCordSocket","system":"6a11aec3b70f2dc40823369a","params":{"autoConnect":true,"onMessage":{"component":"data2-core-types@Getter","params":{"prop":{"component":"data2-core-primitives@String","params":{"content":"fn"}},"module":{"fn":{"component":"data2-core-functions@Function","params":{"parameters":[{"component":"data2-core-primitives@String","params":{"content":"event"}}],"body":{"component":"data2-core-flow@Series","params":{"actions":[]}}}}}}}},"reference":"liveTape"},{"_id":"6a34bee860df893593c1abd3","component":"data2-core@Data2TableDataSource","system":"6a11aec3b70f2dc40823369a","params":{"table":"guests","schema":[{"component":"data2-core-types@Field","params":{"key":"name","title":"Nome","component":"data2-core-primitives@String","required":true}},{"component":"data2-core-types@Field","params":{"key":"email","title":"E-mail","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"checkedIn","title":"Presente","component":"data2-core-primitives@Boolean"}},{"component":"data2-core-types@Field","params":{"key":"checkedInAt","title":"Hora do check-in","component":"data2-core-primitives@Date"}},{"component":"data2-core-types@Field","params":{"key":"phone","title":"Telefone","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"company","title":"Empresa","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"table","title":"Mesa","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"ticket","title":"Ingresso","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"plusOnes","title":"Acompanhantes","component":"data2-core-primitives@Number"}},{"component":"data2-core-types@Field","params":{"key":"notes","title":"Observações","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"companions","title":"Acompanhantes","component":"data2-core-primitives@Number"}}]},"reference":"guests"},{"_id":"6a455e2be03c48ad27d0452b","component":"data2-core@DataSet","system":"6a11aec3b70f2dc40823369a","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"32qFMbWLUAzD_QOgxXlCD"}}},"reference":"32qFMbWLUAzD_QOgxXlCDDataSet"},{"_id":"6a2e0e6458bb101c9095144e","component":"data2-core@DataSet","system":"6a11aec3b70f2dc40823369a","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"9_7GWgCZIZHlKnHFteBFH"}}},"reference":"9_7GWgCZIZHlKnHFteBFHDataSet"},{"_id":"6a2e0d30baacaeb32629dc6c","component":"data2-core@DataSet","system":"6a11aec3b70f2dc40823369a","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"vivaraProducts"}},"autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":true}},"pagination":{"size":40}},"reference":"vivaraProductsDataSet"},{"_id":"6a455e2ab996a38498ae1c6a","component":"data2-core@Data2TableDataSource","system":"6a11aec3b70f2dc40823369a","params":{"table":"32qFMbWLUAzD_QOgxXlCD","schema":[{"component":"data2-core-types@Field","params":{"key":"productId","title":"SKU","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"productName","title":"Produto","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"imageUrl","title":"Imagem","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"label","title":"Variante","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"withModel","title":"Com modelo","component":"data2-core-primitives@Boolean"}},{"component":"data2-core-types@Field","params":{"key":"modelName","title":"Modelo","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"source","title":"Origem","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"status","title":"Status","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"impressions","title":"Impressões","component":"data2-core-primitives@Number"}},{"component":"data2-core-types@Field","params":{"key":"clicks","title":"Cliques","component":"data2-core-primitives@Number"}},{"component":"data2-core-types@Field","params":{"key":"orders","title":"Pedidos","component":"data2-core-primitives@Number"}},{"component":"data2-core-types@Field","params":{"key":"revenue","title":"Receita","component":"data2-core-primitives@Number"}},{"component":"data2-core-types@Field","params":{"key":"cvr","title":"Conversão %","component":"data2-core-primitives@Number"}},{"component":"data2-core-types@Field","params":{"key":"createdAt","title":"Criado em","component":"data2-core-primitives@Date"}}]},"reference":"32qFMbWLUAzD_QOgxXlCD"},{"_id":"6a2e0e649b58f90d1c23aea7","component":"data2-core@Data2TableDataSource","system":"6a11aec3b70f2dc40823369a","params":{"table":"9_7GWgCZIZHlKnHFteBFH","schema":[{"component":"data2-core-types@Field","params":{"key":"name","title":"Modelo","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"kind","title":"Tipo","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"prompt","title":"Prompt","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"imageUrl","title":"Imagem","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"createdAt","title":"Criado","component":"data2-core-primitives@Date"}}]},"reference":"9_7GWgCZIZHlKnHFteBFH"},{"_id":"6a2e0d30baacaeb32629dc67","component":"http@CustomHTTPDataSource","system":"6a11aec3b70f2dc40823369a","params":{"super":{},"find":{"component":"data2-core-flow@Series","params":{"actions":[{"component":"data2-core-types@Interaction","params":{"module":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"vivara"}},"prop":"sendRequest","args":[{"request":{"disabled":false,"component":"data2-core-types@InstanceReference","params":{"component":"data2-core-connect@HttpRequest","reference":"vivaraSearchReq"}}}]}}]}},"countKey":{"component":"data2-core-primitives@String","params":{"content":"count"}},"recordsKey":{"component":"data2-core-primitives@String","params":{"content":"products"}}},"reference":"vivaraProducts"}]}},{"reference":"BundlesTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}}],"processesParams":{}}}}