{"context":{"domain":"katia-party"},"layers":{"ApplicationLayer":{"reference":"ApplicationLayer","availableInstances":[{"reference":"ComponentsDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"component":"data2-core@DataSet","reference":"SystemsDataSet","params":{"filter":{"domain":"data2"},"pagination":{"size":1},"datasource":{"component":"data2-core-types@ProcessReference","params":{"reference":"SystemsDataSource"}}}},{"reference":"ExternalComponentInstancesDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"reference":"SystemsDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[{"_id":"5e3b796d6228227ca637d0f4","name":"data2","domain":"data2","organization":"62292184611f480b3191c37c","visibility":"public","updatedAt":"2026-07-27T14:19:36.810Z"}]}},{"reference":"OrganizationsDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"reference":"DataComponentInstancesDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"component":"data2-core@DataSet","reference":"OneFileComponentInstancesDataSet","params":{"pagination":{"size":1},"master":{"dataset":{"component":"data2-core-types@ProcessReference","params":{"reference":"SystemsDataSet"}},"localField":"system","masterField":"_id"},"datasource":{"component":"data2-core-types@ProcessReference","params":{"reference":"FileComponentInstancesDataSource"}}}},{"reference":"ApplicationsDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"reference":"ComponentInstancesDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"reference":"ServiceComponentInstancesDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"component":"data2-core@Data2TableDataSource","reference":"FileComponentInstancesDataSource","params":{"table":"fileComponentInstances","schema":[{"component":"data2-core-types@Field","params":{"key":"component","title":"Component","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"system","title":"System","component":"data2-core-primitives@ObjectId"}},{"component":"data2-core-types@Field","params":{"key":"displayName","title":"Display Name","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"params","title":"Params","component":"data2-core-primitives@Object"}},{"component":"data2-core-types@Field","params":{"key":"reference","title":"Reference","component":"data2-core-primitives@String"}}]}},{"component":"data2-core@MemoryDataSource","reference":"EmptyDataSource","params":{"initialData":[]}},{"reference":"ComponentsDataSet","component":"data2-core@DataSet","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"EmptyDataSource"}}}},{"reference":"UserComponentsDataSet","component":"data2-core@DataSet","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"EmptyDataSource"}}}},{"reference":"DataComponentInstancesDataSet","component":"data2-core@DataSet","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"EmptyDataSource"}}}},{"reference":"ServiceComponentInstancesDataSet","component":"data2-core@DataSet","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"EmptyDataSource"}}}},{"reference":"ComponentInstancesDataSet","component":"data2-core@DataSet","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"EmptyDataSource"}}}},{"reference":"ExternalComponentInstancesDataSet","component":"data2-core@DataSet","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"EmptyDataSource"}}}},{"reference":"ApplicationsDataSet","component":"data2-core@DataSet","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"EmptyDataSource"}}}}],"processesParams":{}},"HostApplicationLayer":{"reference":"HostApplicationLayer","availableInstances":[{"_id":"5f15ff190528b92601890f71","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"SystemsTableDataSource"}},"filter":{"domain":{"component":"data2-core-types@Reference","params":{"reference":"domain"}}},"pk":"_id","fields":[{"component":"data2-core-types@FieldReference","params":{"key":"_id"}},{"component":"data2-core-types@FieldReference","params":{"key":"name"}},{"component":"data2-core-types@FieldReference","params":{"key":"domain"}},{"component":"data2-core-types@FieldReference","params":{"key":"visibility"}},{"component":"data2-core-types@FieldReference","params":{"key":{"component":"data2-core-primitives@String","params":{"content":"customDomains"}}},"break":true},{"component":"data2-core-types@FieldReference","params":{"key":{"component":"data2-core-primitives@String","params":{"content":"organization._id"}}},"break":true},{"component":"data2-core-types@FieldReference","params":{"key":{"component":"data2-core-primitives@String","params":{"content":"organization.name"}}},"break":true},{"component":"data2-core-types@FieldReference","params":{"key":{"component":"data2-core-primitives@String","params":{"content":"organization.billingStatus"}}},"break":true},{"component":"data2-core-types@FieldReference","params":{"key":{"component":"data2-core-primitives@String","params":{"content":"organization.publicTrial.active"}}},"break":true},{"component":"data2-core-types@FieldReference","params":{"key":{"component":"data2-core-primitives@String","params":{"content":"settings.defaultAccessPolicy"}}},"break":true}],"pagination":{"size":{"component":"data2-core-primitives@Number","params":{"content":1}}},"staticPagination":{"size":{"component":"data2-core-primitives@Number","params":{"content":1}}},"policies":[{"component":"data2-core-auth@Policy","params":{"allow":{"params":{"actions":[{"params":{"components":[{"params":{"query":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$params.query"}}}},"field":{"component":"data2-core-primitives@String","params":{"content":"_id"}},"fieldType":"string"},"component":"data2@7KkQq0vK4a7D2gg6IVJT7"},{"params":{"query":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$params.query"}}}},"field":{"component":"data2-core-primitives@String","params":{"content":"domain"}},"fieldType":"string"},"component":"data2@7KkQq0vK4a7D2gg6IVJT7"},{"params":{"query":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$params.query"}}}},"field":{"component":"data2-core-primitives@String","params":{"content":"customDomains"}},"fieldType":"string"},"component":"data2@7KkQq0vK4a7D2gg6IVJT7"}]},"component":"data2-core-logical-operators@Or"}]},"component":"data2-core-flow@Series"}}}]},"reference":"SystemsDataSet","updatedAt":"2026-08-07T21:51:24.037Z","createdAt":"2020-07-20T20:31:21.838Z"},{"_id":"5f1601ce0528b92601890f7c","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"pagination":{"size":1000},"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"ComponentsTableDataSource"}},"sort":{"params.package":1,"params.component":1},"pk":"_id","autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}},"staticFilter":{"system":{"exists":{"params":{"content":false},"component":"data2-core-primitives@Boolean"}}},"filter":{"system":{"exists":{"params":{"content":false},"component":"data2-core-primitives@Boolean"}}}},"reference":"ComponentsDataSet","updatedAt":"2025-11-05T19:37:01.935Z","createdAt":"2020-07-20T20:42:54.898Z"},{"_id":"5f9041dbc8da12be8b94aea4","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"pagination":{"size":2000},"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"ComponentsTableDataSource"}},"pk":"_id","autoEdit":true,"master":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"_id"}}},"autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}},"policies":{"params":{"allowGet":{"component":"data2-core-primitives@Boolean","params":{"content":true}}},"component":"data2@hkXy-UhMjhyfptdE6_fpW"}},"reference":"UserComponentsDataSet","updatedAt":"2025-11-06T21:06:58.095Z","createdAt":"2020-07-20T20:44:09.350Z"},{"_id":"65d8c4fabc9dbb8f94de8d53","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"ExternalComponentInstancesTableDataSource"}},"pk":"_id","autoEdit":true,"master":{"params":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"_id"}}},"component":"data2-core-types@DataSetMaster"},"autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}},"policies":{"params":{"allowGet":{"component":"data2-core-primitives@Boolean","params":{"content":true}}},"component":"data2@hkXy-UhMjhyfptdE6_fpW"}},"reference":"ExternalComponentInstancesDataSet","updatedAt":"2025-11-06T21:07:23.742Z","createdAt":"2024-02-23T16:17:01.816Z"},{"reference":"SystemsTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[{"_id":"6abed5371a6b03943b9618d7","name":"Party","domain":"katia-party","visibility":"public","updatedAt":"2026-10-01T21:48:39.250Z","createdAt":"2026-10-01T21:48:39.250Z"}]}},{"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":"6abef9f4e9fa96de8a9fbe05","component":"data2-core-types@Component","system":"6abed5371a6b03943b9618d7","params":{"extends":"data2-core-primitives@Block","component":"kp-login","package":"katia-party","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"// kp-login — tela de login + esqueci senha + redefinir senha (?reset=TOKEN)\n// params: auth (service → @partyAuth), requestReset (rush → @request-reset), doReset (rush → @do-reset)\nfunction esc(s){return String(s??'').replace(/[&<>\"]/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c]))}\nfunction fonts(){try{if(document.getElementById('kp-fonts'))return;const l=document.createElement('link');l.id='kp-fonts';l.rel='stylesheet';l.href='https://fonts.googleapis.com/css2?family=Fredoka:wght@400;500;600;700&family=Nunito:wght@400;600;700;800&display=swap';document.head.appendChild(l)}catch(e){}}\nfunction pwa(){try{if(window.__kpPwa)return;window.__kpPwa=1\n  const svg=`<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><defs><linearGradient id=\"g\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\"><stop offset=\"0\" stop-color=\"#FBD3DB\"/><stop offset=\".6\" stop-color=\"#FDE3D3\"/><stop offset=\"1\" stop-color=\"#FFF2C9\"/></linearGradient></defs><rect width=\"512\" height=\"512\" fill=\"url(#g)\"/><circle cx=\"420\" cy=\"92\" r=\"40\" fill=\"#fff\" opacity=\".55\"/><circle cx=\"86\" cy=\"430\" r=\"26\" fill=\"#F9CDD4\" opacity=\".8\"/><g transform=\"translate(112 140) scale(2.4)\"><path d=\"M22 50 L30 8 L56 32 Z\" fill=\"#E59A55\"/><path d=\"M29 41 L33 18 L48 33 Z\" fill=\"#F8D7B5\"/><path d=\"M98 50 L90 8 L64 32 Z\" fill=\"#E59A55\"/><path d=\"M91 41 L87 18 L72 33 Z\" fill=\"#F8D7B5\"/><ellipse cx=\"60\" cy=\"62\" rx=\"44\" ry=\"40\" fill=\"#E59A55\"/><path d=\"M24 70 Q30 99 60 103 Q90 99 96 70 Q84 58 72 66 Q60 74 48 66 Q36 58 24 70Z\" fill=\"#FFF4E8\"/><ellipse cx=\"44\" cy=\"45\" rx=\"6\" ry=\"4\" fill=\"#FFF4E8\"/><ellipse cx=\"76\" cy=\"45\" rx=\"6\" ry=\"4\" fill=\"#FFF4E8\"/><ellipse cx=\"44\" cy=\"58\" rx=\"4.5\" ry=\"5.5\" fill=\"#3B2A2E\"/><ellipse cx=\"76\" cy=\"58\" rx=\"4.5\" ry=\"5.5\" fill=\"#3B2A2E\"/><circle cx=\"45.5\" cy=\"56\" r=\"1.5\" fill=\"#fff\"/><circle cx=\"77.5\" cy=\"56\" r=\"1.5\" fill=\"#fff\"/><path d=\"M54 72 Q60 68 66 72 Q63 78 60 78 Q57 78 54 72Z\" fill=\"#3B2A2E\"/><path d=\"M52 83 Q56 88 60 83 Q64 88 68 83\" stroke=\"#3B2A2E\" stroke-width=\"2.4\" fill=\"none\" stroke-linecap=\"round\"/><ellipse cx=\"32\" cy=\"74\" rx=\"7\" ry=\"4.5\" fill=\"#F4A7B5\" opacity=\".75\"/><ellipse cx=\"88\" cy=\"74\" rx=\"7\" ry=\"4.5\" fill=\"#F4A7B5\" opacity=\".75\"/><path d=\"M36 10 L60 -22 L84 10 Z\" fill=\"#E79AAB\"/><circle cx=\"60\" cy=\"-24\" r=\"6\" fill=\"#fff\"/><circle cx=\"50\" cy=\"0\" r=\"3\" fill=\"#fff\"/><circle cx=\"66\" cy=\"-8\" r=\"3\" fill=\"#FFF2C9\"/></g></svg>`\n  const mk=(size)=>new Promise(res=>{const img=new Image();img.onload=()=>{const c=document.createElement('canvas');c.width=c.height=size;c.getContext('2d').drawImage(img,0,0,size,size);res(c.toDataURL('image/png'))};img.onerror=()=>res('');img.src='data:image/svg+xml;charset=utf-8,'+encodeURIComponent(svg)})\n  Promise.all([mk(192),mk(512),mk(180)]).then(([i192,i512,i180])=>{\n    const o=location.origin+'/'\n    const m={name:'Festa da Katia · Backoffice',short_name:'Festa Katia',description:'Orçamento, convidados e o Milo 🐕',id:o,start_url:o,scope:o,display:'standalone',orientation:'portrait',background_color:'#FFF7F5',theme_color:'#FBD3DB',lang:'pt-BR',\n      icons:[{src:i192,sizes:'192x192',type:'image/png',purpose:'any'},{src:i512,sizes:'512x512',type:'image/png',purpose:'any'},{src:i512,sizes:'512x512',type:'image/png',purpose:'maskable'}]}\n    const put=(tag,match,attrs)=>{let el=[...document.head.querySelectorAll(tag)].find(match);if(!el){el=document.createElement(tag);document.head.appendChild(el)}for(const k in attrs)el.setAttribute(k,attrs[k]);return el}\n    put('link',e=>e.rel==='manifest',{rel:'manifest',href:'data:application/manifest+json;charset=utf-8,'+encodeURIComponent(JSON.stringify(m))})\n    put('link',e=>e.rel==='apple-touch-icon',{rel:'apple-touch-icon',href:i180})\n    put('link',e=>e.rel==='icon',{rel:'icon',type:'image/png',href:i192})\n    put('meta',e=>e.name==='theme-color',{name:'theme-color',content:'#FBD3DB'})\n    put('meta',e=>e.name==='apple-mobile-web-app-title',{name:'apple-mobile-web-app-title',content:'Festa Katia'})\n    put('meta',e=>e.name==='apple-mobile-web-app-status-bar-style',{name:'apple-mobile-web-app-status-bar-style',content:'default'})\n    put('meta',e=>e.name==='description',{name:'description',content:m.description})\n  })}catch(e){}}\nfunction shiba(cls){return `<svg class=\"${cls||''}\" viewBox=\"0 0 120 110\" aria-hidden=\"true\"><path d=\"M22 50 L30 8 L56 32 Z\" fill=\"#E59A55\"/><path d=\"M29 41 L33 18 L48 33 Z\" fill=\"#F8D7B5\"/><path d=\"M98 50 L90 8 L64 32 Z\" fill=\"#E59A55\"/><path d=\"M91 41 L87 18 L72 33 Z\" fill=\"#F8D7B5\"/><ellipse cx=\"60\" cy=\"62\" rx=\"44\" ry=\"40\" fill=\"#E59A55\"/><path d=\"M24 70 Q30 99 60 103 Q90 99 96 70 Q84 58 72 66 Q60 74 48 66 Q36 58 24 70Z\" fill=\"#FFF4E8\"/><ellipse cx=\"44\" cy=\"45\" rx=\"6\" ry=\"4\" fill=\"#FFF4E8\"/><ellipse cx=\"76\" cy=\"45\" rx=\"6\" ry=\"4\" fill=\"#FFF4E8\"/><g class=\"eyes\"><ellipse cx=\"44\" cy=\"58\" rx=\"4.5\" ry=\"5.5\" fill=\"#3B2A2E\"/><ellipse cx=\"76\" cy=\"58\" rx=\"4.5\" ry=\"5.5\" fill=\"#3B2A2E\"/><circle cx=\"45.5\" cy=\"56\" r=\"1.5\" fill=\"#fff\"/><circle cx=\"77.5\" cy=\"56\" r=\"1.5\" fill=\"#fff\"/></g><path d=\"M54 72 Q60 68 66 72 Q63 78 60 78 Q57 78 54 72Z\" fill=\"#3B2A2E\"/><path d=\"M52 83 Q56 88 60 83 Q64 88 68 83\" stroke=\"#3B2A2E\" stroke-width=\"2.4\" fill=\"none\" stroke-linecap=\"round\"/><ellipse cx=\"32\" cy=\"74\" rx=\"7\" ry=\"4.5\" fill=\"#F4A7B5\" opacity=\".75\"/><ellipse cx=\"88\" cy=\"74\" rx=\"7\" ry=\"4.5\" fill=\"#F4A7B5\" opacity=\".75\"/></svg>`}\nfunction isErr(r){return r&&typeof r==='object'&&(r.isData2Error||r.error||r.name==='Data2Error'||r.status>=400)}\n\nexport default {\n  css:`\n:host{--bg:#FFF7F5;--card:#FFFFFF;--blush-50:#FFF1F2;--blush-100:#FDE4E7;--blush-200:#F9CDD4;--blush-300:#F2AEBA;--rose:#D9879A;--rose-deep:#B8647A;--ink:#4A3439;--muted:#94797E;--line:#F3DDE0;--peach:#FDE3D3;--sage:#DCEBDD;--sage-ink:#4F7A57;--shadow:0 6px 24px rgba(184,100,122,.12)}\n*{box-sizing:border-box}\n.page{position:relative;height:100%;min-height:100%;overflow:auto;display:flex;align-items:center;justify-content:center;padding:24px 16px;font-family:'Nunito',system-ui,sans-serif;color:var(--ink);\n  background:radial-gradient(1200px 600px at 10% -10%,#FDE4E7 0,transparent 60%),radial-gradient(900px 500px at 110% 110%,#FDE3D3 0,transparent 55%),var(--bg)}\n.balloon{position:absolute;width:56px;height:68px;border-radius:50% 50% 48% 48%;opacity:.55;animation:float 9s ease-in-out infinite}\n.balloon:after{content:'';position:absolute;left:50%;top:100%;width:1px;height:60px;background:rgba(184,100,122,.35)}\n.b1{left:7%;top:14%;background:#F9CDD4}.b2{left:84%;top:10%;background:#FDE3D3;animation-delay:-3s;width:44px;height:54px}\n.b3{left:78%;top:70%;background:#ECE3F6;animation-delay:-5s}.b4{left:12%;top:72%;background:#FFF2C9;animation-delay:-7s;width:40px;height:50px}\n@keyframes float{0%,100%{transform:translateY(0) rotate(-3deg)}50%{transform:translateY(-22px) rotate(3deg)}}\n.wrap{position:relative;width:100%;max-width:400px;z-index:1}\n.dog{display:block;width:96px;height:88px;margin:0 auto -18px;position:relative;z-index:2;cursor:pointer;filter:drop-shadow(0 6px 10px rgba(184,100,122,.18));transition:transform .2s}\n.dog:hover{transform:translateY(-3px) rotate(-3deg)}\n.dog.wink .eyes{transform-origin:76px 58px;animation:wink .4s}\n@keyframes wink{50%{transform:scaleY(.1)}}\n.bark{position:absolute;left:calc(50% + 40px);top:-6px;background:#fff;border:1px solid var(--line);border-radius:14px 14px 14px 4px;padding:4px 10px;font:600 13px 'Fredoka',sans-serif;color:var(--rose-deep);box-shadow:var(--shadow);opacity:0;transform:translateY(6px);transition:all .25s;pointer-events:none;z-index:3}\n.bark.on{opacity:1;transform:none}\n.card{background:var(--card);border:1px solid var(--line);border-radius:28px;box-shadow:0 20px 60px rgba(184,100,122,.16);padding:36px 28px 26px}\nh1{font:600 34px/1.05 'Fredoka',sans-serif;text-align:center;margin:6px 0 4px;color:var(--rose-deep);letter-spacing:-.5px}\nh1 span{color:var(--ink)}\n.sub{text-align:center;color:var(--muted);font-size:14px;margin:0 0 22px}\nlabel{display:block;font-weight:700;font-size:13px;margin:12px 0 6px;color:var(--ink)}\ninput{width:100%;border:1.5px solid var(--line);background:var(--blush-50);border-radius:14px;padding:12px 14px;font:600 15px 'Nunito',sans-serif;color:var(--ink);outline:none;transition:border .15s,background .15s}\ninput:focus{border-color:var(--blush-300);background:#fff}\n.btn{width:100%;margin-top:18px;border:0;border-radius:14px;padding:13px 16px;font:600 16px 'Fredoka',sans-serif;cursor:pointer;color:#fff;background:linear-gradient(135deg,#E79AAB,#D9879A);box-shadow:0 8px 20px rgba(217,135,154,.35);transition:transform .1s,filter .15s}\n.btn:hover{filter:brightness(1.04)}.btn:active{transform:scale(.98)}.btn[disabled]{opacity:.6;cursor:default}\n.link{display:block;text-align:center;margin-top:14px;color:var(--rose-deep);font-weight:700;font-size:13px;cursor:pointer;background:none;border:0;width:100%}\n.msg{margin-top:14px;padding:10px 12px;border-radius:12px;font-size:13px;font-weight:600}\n.err{background:#FDE4E7;color:#A2475E}.ok{background:var(--sage);color:var(--sage-ink)}\n.foot{text-align:center;color:var(--muted);font-size:12px;margin-top:16px}\n.heart{position:fixed;top:-30px;font-size:22px;pointer-events:none;animation:fall linear forwards;z-index:9}\n@keyframes fall{to{transform:translateY(110vh) rotate(360deg)}}\n`,\n  render(d2){\n    const s=d2.state, mode=s.mode||'login'\n    const msg=s.err?`<div class=\"msg err\">${esc(s.err)}</div>`:s.ok?`<div class=\"msg ok\">${esc(s.ok)}</div>`:''\n    let body=''\n    if(mode==='login') body=`\n      <form class=\"f-login\" autocomplete=\"on\">\n        <label>Email</label><input name=\"email\" type=\"email\" autocomplete=\"username\" placeholder=\"voce@email.com\" value=\"${esc(s.email||'')}\" required/>\n        <label>Senha</label><input name=\"password\" type=\"password\" autocomplete=\"current-password\" placeholder=\"••••••••\" required/>\n        <button class=\"btn\" type=\"submit\" ${s.busy?'disabled':''}>${s.busy?'Entrando…':'Entrar 🎈'}</button>\n      </form>${msg}<button class=\"link go-forgot\" type=\"button\">Esqueci minha senha</button>`\n    else if(mode==='forgot') body=`\n      <form class=\"f-forgot\"><p class=\"sub\" style=\"margin:0 0 4px\">Mandamos um link pro seu email pra você escolher uma senha nova.</p>\n        <label>Email</label><input name=\"email\" type=\"email\" placeholder=\"voce@email.com\" value=\"${esc(s.email||'')}\" required/>\n        <button class=\"btn\" type=\"submit\" ${s.busy?'disabled':''}>${s.busy?'Enviando…':'Enviar link ✉️'}</button>\n      </form>${msg}<button class=\"link go-login\" type=\"button\">← Voltar pro login</button>`\n    else if(mode==='reset') body=`\n      <form class=\"f-reset\"><p class=\"sub\" style=\"margin:0 0 4px\">Escolha sua nova senha (mínimo 6 caracteres).</p>\n        <label>Nova senha</label><input name=\"p1\" type=\"password\" autocomplete=\"new-password\" minlength=\"6\" required/>\n        <label>Repita a senha</label><input name=\"p2\" type=\"password\" autocomplete=\"new-password\" minlength=\"6\" required/>\n        <button class=\"btn\" type=\"submit\" ${s.busy?'disabled':''}>${s.busy?'Salvando…':'Salvar nova senha'}</button>\n      </form>${msg}<button class=\"link go-login\" type=\"button\">← Voltar pro login</button>`\n    return `<div class=\"page\">\n      <div class=\"balloon b1\"></div><div class=\"balloon b2\"></div><div class=\"balloon b3\"></div><div class=\"balloon b4\"></div>\n      <div class=\"wrap\">\n        <div class=\"bark ${s.bark?'on':''}\">${esc(s.bark||'au!')}</div>\n        <div class=\"dog-wrap\">${shiba('dog'+(s.wink?' wink':''))}</div>\n        <div class=\"card\">\n          <h1><span>Festa da</span> Katia</h1>\n          <p class=\"sub\">backoffice da festa · 15.11.2026</p>\n          ${body}\n        </div>\n        <div class=\"foot\">feito com 💗 e supervisão canina</div>\n      </div></div>`\n  },\n  mounted(d2){\n    fonts();pwa()\n    const s=d2.state\n    try{const t=new URLSearchParams(window.location.search).get('reset');if(t){s.token=t;s.mode='reset'}}catch(e){}\n    const set=(o)=>d2.setState(o)\n    d2.on('.go-forgot','click',()=>set({mode:'forgot',err:'',ok:''}))\n    d2.on('.go-login','click',()=>{set({mode:'login',err:'',ok:''});try{if(s.token)history.replaceState(null,'',window.location.pathname)}catch(e){}})\n    d2.on('form','submit',async(e,form)=>{\n      e.preventDefault()\n      const f=Object.fromEntries(new FormData(form).entries())\n      set({busy:true,err:'',ok:''})\n      try{\n        if(form.classList.contains('f-login')){\n          const email=String(f.email||'').trim().toLowerCase()\n          s.email=email\n          const auth=d2.auth(d2.param('auth'))\n          const r=await auth.login({credentials:{email,password:f.password}})\n          if(isErr(r)) throw r\n          set({ok:'Bem-vindo(a)! 🎉'})\n          setTimeout(()=>{window.location.replace(window.location.pathname)},350)\n          return\n        }\n        if(form.classList.contains('f-forgot')){\n          const email=String(f.email||'').trim().toLowerCase()\n          await d2.rush(d2.param('requestReset')).invoke({email})\n          set({ok:'Se esse email estiver cadastrado, o link chega em instantes. Olha o spam também 😉'})\n        }\n        if(form.classList.contains('f-reset')){\n          if(String(f.p1).length<6) throw new Error('A senha precisa ter pelo menos 6 caracteres.')\n          if(f.p1!==f.p2) throw new Error('As senhas não batem.')\n          const r=await d2.rush(d2.param('doReset')).invoke({token:s.token,password:f.p1})\n          const out=r&&r.data?r.data:r\n          if(!out||!out.ok) throw new Error((out&&out.error)||'Link inválido ou expirado.')\n          try{history.replaceState(null,'',window.location.pathname)}catch(e){}\n          set({mode:'login',email:out.email||'',token:'',ok:'Senha nova salva! Agora é só entrar 🐾'})\n        }\n      }catch(err){\n        const m=err&&err.message&&!/credential|unauthor|401|invalid/i.test(err.message)?err.message:'Email ou senha incorretos.'\n        set({err: form.classList.contains('f-login')?'Email ou senha incorretos.':m})\n      }finally{set({busy:false})}\n    })\n    let clicks=0,tm\n    d2.on('.dog','click',()=>{\n      clicks++; clearTimeout(tm); tm=setTimeout(()=>{clicks=0},1500)\n      const barks=['au!','au au! 🐾','*abana o rabo*','a festa vai ser linda 💗','auuu! 🎂']\n      set({wink:true,bark:barks[Math.min(clicks-1,barks.length-1)]})\n      setTimeout(()=>set({wink:false}),400); setTimeout(()=>set({bark:''}),1600)\n      if(clicks===5){\n        for(let i=0;i<26;i++){const h=document.createElement('div');h.className='heart';h.textContent=['💗','🎈','🐾','🌸','🎂'][i%5];h.style.left=Math.random()*100+'vw';h.style.animationDuration=(2.5+Math.random()*2.5)+'s';h.style.animationDelay=(Math.random()*1.2)+'s';d2.root.appendChild(h);setTimeout(()=>h.remove(),6500)}\n      }\n    })\n  },\n}\n"}},"auth":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"auth"}}}},"requestReset":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"requestReset"}}}},"doReset":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"doReset"}}}}}}}}}},{"_id":"6abefc2d0484650e9b1b43db","component":"data2-core-types@Component","system":"6abed5371a6b03943b9618d7","params":{"extends":"data2-core-primitives@Block","component":"kp-summary","package":"katia-party","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"// kp-summary — painel inicial: contagem regressiva, orçamento, convidados, próximos passos + shiba espiando\n// params: items quotes guests tasks settings (dataset), me (string)\nfunction esc(s){return String(s??'').replace(/[&<>\"]/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c]))}\nfunction shiba(cls){return `<svg class=\"${cls||''}\" viewBox=\"0 0 120 110\" aria-hidden=\"true\"><path d=\"M22 50 L30 8 L56 32 Z\" fill=\"#E59A55\"/><path d=\"M29 41 L33 18 L48 33 Z\" fill=\"#F8D7B5\"/><path d=\"M98 50 L90 8 L64 32 Z\" fill=\"#E59A55\"/><path d=\"M91 41 L87 18 L72 33 Z\" fill=\"#F8D7B5\"/><ellipse cx=\"60\" cy=\"62\" rx=\"44\" ry=\"40\" fill=\"#E59A55\"/><path d=\"M24 70 Q30 99 60 103 Q90 99 96 70 Q84 58 72 66 Q60 74 48 66 Q36 58 24 70Z\" fill=\"#FFF4E8\"/><ellipse cx=\"44\" cy=\"45\" rx=\"6\" ry=\"4\" fill=\"#FFF4E8\"/><ellipse cx=\"76\" cy=\"45\" rx=\"6\" ry=\"4\" fill=\"#FFF4E8\"/><ellipse cx=\"44\" cy=\"58\" rx=\"4.5\" ry=\"5.5\" fill=\"#3B2A2E\"/><ellipse cx=\"76\" cy=\"58\" rx=\"4.5\" ry=\"5.5\" fill=\"#3B2A2E\"/><circle cx=\"45.5\" cy=\"56\" r=\"1.5\" fill=\"#fff\"/><circle cx=\"77.5\" cy=\"56\" r=\"1.5\" fill=\"#fff\"/><path d=\"M54 72 Q60 68 66 72 Q63 78 60 78 Q57 78 54 72Z\" fill=\"#3B2A2E\"/><path d=\"M52 83 Q56 88 60 83 Q64 88 68 83\" stroke=\"#3B2A2E\" stroke-width=\"2.4\" fill=\"none\" stroke-linecap=\"round\"/><ellipse cx=\"32\" cy=\"74\" rx=\"7\" ry=\"4.5\" fill=\"#F4A7B5\" opacity=\".75\"/><ellipse cx=\"88\" cy=\"74\" rx=\"7\" ry=\"4.5\" fill=\"#F4A7B5\" opacity=\".75\"/></svg>`}\nconst BRL=(n)=>new Intl.NumberFormat('pt-BR',{style:'currency',currency:'BRL',maximumFractionDigits:(Number(n)||0)%1?2:0}).format(Number(n)||0)\nconst PARTY=new Date('2026-11-15T12:00:00-03:00')\nconst MAPS='https://maps.app.goo.gl/wVNFaGGmY8bLGoJt9'\nconst recs=(d2,k)=>{const h=d2.data(k);return h?h.records()||[]:[]}\n\nexport default {\n  css:`\n:host{--bg:var(--k-bg,#FFF7F5);--card:var(--k-card,#FFFFFF);--blush-50:var(--k-blush-50,#FFF1F2);--blush-100:var(--k-blush-100,#FDE4E7);--blush-200:var(--k-blush-200,#F9CDD4);--blush-300:var(--k-blush-300,#F2AEBA);--rose:var(--k-rose,#D9879A);--rose-deep:var(--k-rose-deep,#B8647A);--ink:var(--k-ink,#4A3439);--muted:var(--k-muted,#94797E);--line:var(--k-line,#F3DDE0);--peach:var(--k-peach,#FDE3D3);--sage:var(--k-sage,#DCEBDD);--sage-ink:var(--k-sage-ink,#4F7A57);--butter:var(--k-butter,#FFF2C9);--butter-ink:var(--k-butter-ink,#8A6D1F);--lilac:var(--k-lilac,#ECE3F6);--lilac-ink:var(--k-lilac-ink,#6B5390);--shadow:var(--k-shadow,0 6px 24px rgba(184,100,122,.12))}\n*{box-sizing:border-box}\n.wrap{height:100%;overflow:auto;padding:28px clamp(16px,3vw,40px) 90px;font-family:'Nunito',system-ui,sans-serif;color:var(--ink);position:relative}\n.inner{max-width:1120px;margin:0 auto;display:grid;gap:18px}\n.hello{font:600 15px 'Fredoka';color:var(--muted);margin:0}\n.remind{margin:14px 0 0;display:flex;gap:12px;align-items:center;justify-content:space-between;flex-wrap:wrap;background:var(--butter);border:1.5px dashed #E8C66A;border-radius:20px;padding:14px 16px}.remind b{display:block;font:600 18px 'Fredoka',sans-serif;color:var(--butter-ink);margin-bottom:4px}.remind span{font-size:14px;color:var(--ink)}.bf-ok{border:0;background:var(--card);color:var(--butter-ink);border-radius:12px;padding:9px 14px;font:800 13px 'Nunito',sans-serif;cursor:pointer}\n.hero{position:relative;overflow:hidden;border-radius:28px;padding:28px clamp(20px,3vw,36px);background:var(--k-hero,linear-gradient(120deg,#FBD3DB 0%,#FDE3D3 55%,#FFF2C9 120%));box-shadow:0 18px 50px rgba(217,135,154,.22);display:grid;grid-template-columns:1fr auto;gap:18px;align-items:center}\n.hero h1{font:600 clamp(30px,4.4vw,48px)/1.02 'Fredoka',sans-serif;margin:0 0 8px;color:var(--k-plum,#8E4258);letter-spacing:-.5px}\n.hero p{margin:0;font-weight:700;color:var(--k-plum2,#7A5560);font-size:15px}\n.hero .where{display:inline-flex;align-items:center;gap:8px;margin-top:14px;background:var(--k-glass,rgba(255,255,255,.7));border-radius:999px;padding:8px 14px;font-weight:800;font-size:13px;color:var(--rose-deep);text-decoration:none}\n.big{text-align:center;background:var(--k-glass,rgba(255,255,255,.75));border-radius:24px;padding:16px 22px;min-width:150px}\n.big b{display:block;font:600 64px/1 'Fredoka';color:var(--rose-deep)}\n.big span{font-weight:800;font-size:13px;color:var(--k-plum2,#7A5560)}\n.conf{position:absolute;border-radius:50%;opacity:.5}\n.grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:14px}\n.card{background:var(--card);border:1px solid var(--line);border-radius:22px;padding:18px;box-shadow:var(--shadow);cursor:pointer;transition:transform .15s,box-shadow .15s;min-width:0}\n.card:hover{transform:translateY(-2px);box-shadow:0 12px 30px rgba(184,100,122,.18)}\n.card .k{font-weight:800;font-size:12px;letter-spacing:.4px;text-transform:uppercase;color:var(--muted);display:flex;align-items:center;gap:6px}\n.card .v{font:600 28px/1.1 'Fredoka';margin:8px 0 4px;color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n.card .h{font-size:13px;color:var(--muted);font-weight:700}\n.bar{height:10px;border-radius:999px;background:var(--blush-50);overflow:hidden;margin-top:10px}\n.bar i{display:block;height:100%;border-radius:999px;background:linear-gradient(90deg,#F2AEBA,#D9879A)}\n.bar i.warn{background:linear-gradient(90deg,#F7C59F,#E8956B)}.bar i.over{background:linear-gradient(90deg,#EE9AA5,#C9506B)}\n.two{display:grid;grid-template-columns:1.3fr 1fr;gap:14px}\n.panel{background:var(--card);border:1px solid var(--line);border-radius:22px;padding:20px;box-shadow:var(--shadow);min-width:0}\n.panel h3{font:600 18px 'Fredoka';margin:0 0 12px;display:flex;align-items:center;gap:8px}\n.row{display:flex;align-items:center;gap:12px;padding:10px 4px;border-top:1px dashed var(--line);cursor:pointer}\n.row:first-of-type{border-top:0}\n.em{width:36px;height:36px;border-radius:12px;background:var(--blush-50);display:grid;place-items:center;font-size:18px;flex:none}\n.row .t{font-weight:800;font-size:14px;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.chip{font-weight:800;font-size:11px;border-radius:999px;padding:3px 9px;white-space:nowrap}\n.c-pend{background:var(--blush-100);color:var(--rose-deep)}.c-cot{background:var(--butter);color:var(--butter-ink)}.c-ok{background:var(--sage);color:var(--sage-ink)}.c-lil{background:var(--lilac);color:var(--lilac-ink)}\n.empty{color:var(--muted);font-weight:700;font-size:14px;padding:8px 4px}\n.peek{position:fixed;right:22px;bottom:-14px;width:92px;height:84px;cursor:pointer;transition:transform .35s cubic-bezier(.3,1.6,.5,1);z-index:5;filter:drop-shadow(0 -4px 10px rgba(184,100,122,.15))}\n.peek:hover{transform:translateY(-16px) rotate(-6deg)}\n.bubble{position:fixed;right:110px;bottom:56px;background:var(--card);border:1px solid var(--line);border-radius:16px 16px 4px 16px;padding:10px 14px;font:600 14px 'Fredoka';color:var(--rose-deep);box-shadow:var(--shadow);z-index:5;max-width:240px}\n@media (max-width:1020px){.grid{grid-template-columns:repeat(2,minmax(0,1fr))}.two{grid-template-columns:1fr}}\n@media (max-width:560px){.hero{grid-template-columns:1fr}.big{display:flex;align-items:baseline;gap:10px;justify-content:center}.big b{font-size:44px}.card .v{font-size:22px}.peek{display:none}.wrap{padding-top:18px}}\n`,\n  render(d2){\n    const items=recs(d2,'items'),quotes=recs(d2,'quotes'),guests=recs(d2,'guests'),tasks=recs(d2,'tasks'),settings=recs(d2,'settings')\n    const party=(settings.find(r=>r.key==='party')||{}).value||{}\n    const cap=Number(party.budgetCap)||15000\n    const byItem={};for(const q of quotes){(byItem[q.itemId]=byItem[q.itemId]||[]).push(q)}\n    let chosen=0,closed=0,proj=0;const est=items.filter(it=>it.estimate).length\n    const next=[]\n    for(const it of items){const qs=byItem[it._id]||[];const c=qs.find(q=>q.chosen)\n      if(c){chosen+=Number(c.price)||0;proj+=Number(c.price)||0;closed++}else if(it.free){closed++}\n      else{const min=qs.length?Math.min(...qs.map(q=>Number(q.price)||0)):0;proj+=min;next.push({it,n:qs.length,min})}}\n    const pct=Math.min(100,Math.round(chosen/cap*100))\n    const cls=chosen>cap?'over':pct>=85?'warn':''\n    const people=()=>1 // convite individual\n    const totalP=guests.reduce((a,g)=>a+people(g),0)\n    const confP=guests.filter(g=>g.status==='confirmado').reduce((a,g)=>a+people(g),0)\n    const provP=guests.filter(g=>g.status==='provável').reduce((a,g)=>a+people(g),0) // não confirmou, mas deve ir: conta pro buffet\n    // 🍢 lembrete do buffet: a partir de buffetCheckFrom (20/10) até alguém marcar \"Já conferi\"\n    const pax=Number(party.buffetPax)||90,noAns=guests.filter(g=>['convidado','a convidar','em dúvida'].includes(g.status||'a convidar')).length\n    const bf=!party.buffetChecked&&Date.now()>=new Date((party.buffetCheckFrom||'2026-10-20')+'T00:00:00-03:00').getTime()&&Date.now()<PARTY.getTime()\n    const pendT=tasks.filter(t=>['pendente','em andamento'].includes(t.status||'pendente'))\n    const days=Math.max(0,Math.ceil((PARTY.getTime()-Date.now())/86400000))\n    const me=d2.param('me')||''\n    const h=new Date().getHours(),greet=h<12?'Bom dia':h<18?'Boa tarde':'Boa noite'\n    const mood=chosen>cap?'Ih… estourou o teto 😬 bora rever?':pct>=85?'Tá chegando no teto, atenção! 🐾':closed===items.length&&items.length?'Tudo fechado! Melhores organizadores 🏆':'Tô de olho no orçamento pra vocês 🐕'\n    return `<div class=\"wrap\"><div class=\"inner\">\n      <p class=\"hello\">${greet}${me?', '+esc(me):''}! 💗</p>\n      <section class=\"hero\">\n        <div class=\"conf\" style=\"width:120px;height:120px;right:-30px;top:-40px;background:#fff\"></div>\n        <div class=\"conf\" style=\"width:60px;height:60px;left:40%;bottom:-24px;background:#F9CDD4\"></div>\n        <div><h1>Festa da Katia 🎂</h1><p>Domingo, 15 de novembro de 2026</p>\n          <a class=\"where\" href=\"${MAPS}\" target=\"_blank\" rel=\"noopener\">📍 Sítio Recanto dos Lagos · Mogi das Cruzes</a></div>\n        <div class=\"big\"><b>${days}</b><span>${days===1?'dia':'dias'} pra festa</span></div>\n      </section>\n      ${bf?`<section class=\"remind\"><div><b>🍢 Hora de conferir o buffet!</b><span>${confP} confirmados${provP?` + ${provP} prováveis`:''}${noAns?` + ${noAns} sem resposta`:''} × ${pax} pessoas no orçamento do buffet. ${confP+provP>pax?'Já passou: precisa aumentar o pedido.':confP+provP+noAns>pax?'Se quem não respondeu vier, passa do combinado.':'Por enquanto cabe direitinho.'} O orçamento vale até 21/10.</span></div><button class=\"bf-ok\">Já conferi ✓</button></section>`:''}\n      <div class=\"grid\">\n        <div class=\"card go\" data-go=\"budget\"><div class=\"k\">💸 Escolhido</div><div class=\"v\">${BRL(chosen)}</div><div class=\"h\">de ${BRL(cap)} · ${pct}%${est?` · ${est} estimado${est>1?'s':''}`:''}</div><div class=\"bar\"><i class=\"${cls}\" style=\"width:${pct}%\"></i></div></div>\n        <div class=\"card go\" data-go=\"budget\"><div class=\"k\">✅ Itens fechados</div><div class=\"v\">${closed}/${items.length}</div><div class=\"h\">projeção ${BRL(proj)}</div><div class=\"bar\"><i style=\"width:${items.length?Math.round(closed/items.length*100):0}%\"></i></div></div>\n        <div class=\"card go\" data-go=\"guests\"><div class=\"k\">💌 Convidados</div><div class=\"v\">${totalP} ${totalP===1?'pessoa':'pessoas'}</div><div class=\"h\">${confP} confirmados${provP?` · ${provP} prováveis`:''} · ${totalP-confP-provP} a confirmar</div><div class=\"bar\"><i style=\"width:${totalP?Math.round(confP/totalP*100):0}%\"></i></div></div>\n        <div class=\"card go\" data-go=\"chat\"><div class=\"k\">🐕 Tasks do Milo</div><div class=\"v\">${pendT.length}</div><div class=\"h\">${pendT.length?'esperando o Claude':'nada pendente ✨'}</div></div>\n      </div>\n      <div class=\"two\">\n        <div class=\"panel\"><h3>📝 Falta cotar / decidir</h3>\n          ${next.length?next.slice(0,8).map(x=>`<div class=\"row go\" data-go=\"budget\" data-item=\"${esc(x.it._id)}\"><div class=\"em\">${esc(x.it.glyph||'✨')}</div><div class=\"t\">${esc(x.it.name)}</div>${x.n?`<span class=\"chip c-cot\">${x.n} cotaç${x.n>1?'ões':'ão'} · a partir de ${BRL(x.min)}</span>`:'<span class=\"chip c-pend\">sem cotação</span>'}</div>`).join(''):'<div class=\"empty\">Tudo decidido por aqui 🎉</div>'}\n        </div>\n        <div class=\"panel\"><h3>🐾 Tasks pendentes</h3>\n          ${pendT.length?pendT.slice(0,6).map(t=>`<div class=\"row go\" data-go=\"chat\"><div class=\"em\">${t.status==='em andamento'?'⏳':'📌'}</div><div class=\"t\">${esc(t.title)}</div><span class=\"chip ${t.status==='em andamento'?'c-cot':'c-lil'}\">${esc(t.status||'pendente')}</span></div>`).join(''):'<div class=\"empty\">Nenhuma task. Fala com o Milo no chat! 🐕</div>'}\n        </div>\n      </div>\n    </div>\n    </div>`\n  },\n  mounted(d2){\n    d2.on('.bf-ok','click',async()=>{const S=d2.data('settings'),rec=S&&(S.records()||[]).find(r=>r.key==='party');if(!rec)return\n      await S.update({...rec,value:{...(rec.value||{}),buffetChecked:true}});d2.bus.emit('kp:toast','Buffet conferido ✓ Não lembro mais disso 🐾')})\n    d2.on('.go','click',(e,el)=>{if(el.dataset.item)d2.shared.set('kp-open-item',el.dataset.item,{global:true});d2.bus.emit('kp:nav',el.dataset.go)})\n    let tm\n    d2.on('.peek','click',()=>{const m=d2.$('.peek-wrap');d2.state.bubble=m?m.dataset.mood:'au!';clearTimeout(tm);tm=setTimeout(()=>{d2.state.bubble=''},3500)})\n  },\n}\n"}},"items":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"items"}}}},"quotes":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"quotes"}}}},"guests":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"guests"}}}},"tasks":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"tasks"}}}},"settings":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"settings"}}}},"me":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"me"}}}}}}}}}},{"_id":"6abefc5ee9fa96de8a9fd12d","component":"data2-core-types@Component","system":"6abed5371a6b03943b9618d7","params":{"extends":"data2-core-primitives@Block","component":"kp-app","package":"katia-party","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"// kp-app — casca do backoffice: sidebar (desktop) / bottom-nav (mobile), topo com contagem regressiva,\n// menu do usuário (trocar senha / sair) e a view ativa renderizada via d2.render.\n// params: auth(service) requestReset(rush) items quotes guests messages tasks settings artworks(dataset)\n//         scribe artist(assistant) drive(service)\n//         vSummary vBudget vGuests vChat vArt (component)\nfunction esc(s){return String(s??'').replace(/[&<>\"]/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c]))}\nfunction fonts(){try{if(document.getElementById('kp-fonts'))return;const l=document.createElement('link');l.id='kp-fonts';l.rel='stylesheet';l.href='https://fonts.googleapis.com/css2?family=Fredoka:wght@400;500;600;700&family=Nunito:wght@400;600;700;800&display=swap';document.head.appendChild(l)}catch(e){}}\nfunction pwa(){try{if(window.__kpPwa)return;window.__kpPwa=1\n  const svg=`<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><defs><linearGradient id=\"g\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\"><stop offset=\"0\" stop-color=\"#FBD3DB\"/><stop offset=\".6\" stop-color=\"#FDE3D3\"/><stop offset=\"1\" stop-color=\"#FFF2C9\"/></linearGradient></defs><rect width=\"512\" height=\"512\" fill=\"url(#g)\"/><circle cx=\"420\" cy=\"92\" r=\"40\" fill=\"#fff\" opacity=\".55\"/><circle cx=\"86\" cy=\"430\" r=\"26\" fill=\"#F9CDD4\" opacity=\".8\"/><g transform=\"translate(112 140) scale(2.4)\"><path d=\"M22 50 L30 8 L56 32 Z\" fill=\"#E59A55\"/><path d=\"M29 41 L33 18 L48 33 Z\" fill=\"#F8D7B5\"/><path d=\"M98 50 L90 8 L64 32 Z\" fill=\"#E59A55\"/><path d=\"M91 41 L87 18 L72 33 Z\" fill=\"#F8D7B5\"/><ellipse cx=\"60\" cy=\"62\" rx=\"44\" ry=\"40\" fill=\"#E59A55\"/><path d=\"M24 70 Q30 99 60 103 Q90 99 96 70 Q84 58 72 66 Q60 74 48 66 Q36 58 24 70Z\" fill=\"#FFF4E8\"/><ellipse cx=\"44\" cy=\"45\" rx=\"6\" ry=\"4\" fill=\"#FFF4E8\"/><ellipse cx=\"76\" cy=\"45\" rx=\"6\" ry=\"4\" fill=\"#FFF4E8\"/><ellipse cx=\"44\" cy=\"58\" rx=\"4.5\" ry=\"5.5\" fill=\"#3B2A2E\"/><ellipse cx=\"76\" cy=\"58\" rx=\"4.5\" ry=\"5.5\" fill=\"#3B2A2E\"/><circle cx=\"45.5\" cy=\"56\" r=\"1.5\" fill=\"#fff\"/><circle cx=\"77.5\" cy=\"56\" r=\"1.5\" fill=\"#fff\"/><path d=\"M54 72 Q60 68 66 72 Q63 78 60 78 Q57 78 54 72Z\" fill=\"#3B2A2E\"/><path d=\"M52 83 Q56 88 60 83 Q64 88 68 83\" stroke=\"#3B2A2E\" stroke-width=\"2.4\" fill=\"none\" stroke-linecap=\"round\"/><ellipse cx=\"32\" cy=\"74\" rx=\"7\" ry=\"4.5\" fill=\"#F4A7B5\" opacity=\".75\"/><ellipse cx=\"88\" cy=\"74\" rx=\"7\" ry=\"4.5\" fill=\"#F4A7B5\" opacity=\".75\"/><path d=\"M36 10 L60 -22 L84 10 Z\" fill=\"#E79AAB\"/><circle cx=\"60\" cy=\"-24\" r=\"6\" fill=\"#fff\"/><circle cx=\"50\" cy=\"0\" r=\"3\" fill=\"#fff\"/><circle cx=\"66\" cy=\"-8\" r=\"3\" fill=\"#FFF2C9\"/></g></svg>`\n  const mk=(size)=>new Promise(res=>{const img=new Image();img.onload=()=>{const c=document.createElement('canvas');c.width=c.height=size;c.getContext('2d').drawImage(img,0,0,size,size);res(c.toDataURL('image/png'))};img.onerror=()=>res('');img.src='data:image/svg+xml;charset=utf-8,'+encodeURIComponent(svg)})\n  Promise.all([mk(192),mk(512),mk(180)]).then(([i192,i512,i180])=>{\n    const o=location.origin+'/'\n    const m={name:'Festa da Katia · Backoffice',short_name:'Festa Katia',description:'Orçamento, convidados e o Milo 🐕',id:o,start_url:o,scope:o,display:'standalone',orientation:'portrait',background_color:'#FFF7F5',theme_color:'#FBD3DB',lang:'pt-BR',\n      icons:[{src:i192,sizes:'192x192',type:'image/png',purpose:'any'},{src:i512,sizes:'512x512',type:'image/png',purpose:'any'},{src:i512,sizes:'512x512',type:'image/png',purpose:'maskable'}]}\n    const put=(tag,match,attrs)=>{let el=[...document.head.querySelectorAll(tag)].find(match);if(!el){el=document.createElement(tag);document.head.appendChild(el)}for(const k in attrs)el.setAttribute(k,attrs[k]);return el}\n    put('link',e=>e.rel==='manifest',{rel:'manifest',href:'data:application/manifest+json;charset=utf-8,'+encodeURIComponent(JSON.stringify(m))})\n    put('link',e=>e.rel==='apple-touch-icon',{rel:'apple-touch-icon',href:i180})\n    put('link',e=>e.rel==='icon',{rel:'icon',type:'image/png',href:i192})\n    put('meta',e=>e.name==='theme-color',{name:'theme-color',content:'#FBD3DB'})\n    put('meta',e=>e.name==='apple-mobile-web-app-title',{name:'apple-mobile-web-app-title',content:'Festa Katia'})\n    put('meta',e=>e.name==='apple-mobile-web-app-status-bar-style',{name:'apple-mobile-web-app-status-bar-style',content:'default'})\n    put('meta',e=>e.name==='description',{name:'description',content:m.description})\n  })}catch(e){}}\nfunction shiba(cls){return `<svg class=\"${cls||''}\" viewBox=\"0 0 120 110\" aria-hidden=\"true\"><path d=\"M22 50 L30 8 L56 32 Z\" fill=\"#E59A55\"/><path d=\"M29 41 L33 18 L48 33 Z\" fill=\"#F8D7B5\"/><path d=\"M98 50 L90 8 L64 32 Z\" fill=\"#E59A55\"/><path d=\"M91 41 L87 18 L72 33 Z\" fill=\"#F8D7B5\"/><ellipse cx=\"60\" cy=\"62\" rx=\"44\" ry=\"40\" fill=\"#E59A55\"/><path d=\"M24 70 Q30 99 60 103 Q90 99 96 70 Q84 58 72 66 Q60 74 48 66 Q36 58 24 70Z\" fill=\"#FFF4E8\"/><ellipse cx=\"44\" cy=\"45\" rx=\"6\" ry=\"4\" fill=\"#FFF4E8\"/><ellipse cx=\"76\" cy=\"45\" rx=\"6\" ry=\"4\" fill=\"#FFF4E8\"/><ellipse cx=\"44\" cy=\"58\" rx=\"4.5\" ry=\"5.5\" fill=\"#3B2A2E\"/><ellipse cx=\"76\" cy=\"58\" rx=\"4.5\" ry=\"5.5\" fill=\"#3B2A2E\"/><circle cx=\"45.5\" cy=\"56\" r=\"1.5\" fill=\"#fff\"/><circle cx=\"77.5\" cy=\"56\" r=\"1.5\" fill=\"#fff\"/><path d=\"M54 72 Q60 68 66 72 Q63 78 60 78 Q57 78 54 72Z\" fill=\"#3B2A2E\"/><path d=\"M52 83 Q56 88 60 83 Q64 88 68 83\" stroke=\"#3B2A2E\" stroke-width=\"2.4\" fill=\"none\" stroke-linecap=\"round\"/><ellipse cx=\"32\" cy=\"74\" rx=\"7\" ry=\"4.5\" fill=\"#F4A7B5\" opacity=\".75\"/><ellipse cx=\"88\" cy=\"74\" rx=\"7\" ry=\"4.5\" fill=\"#F4A7B5\" opacity=\".75\"/></svg>`}\nfunction who(d2){const a=d2.auth(d2.param('auth'));const u=(a&&a.user)||{};let email=u.email||(a&&a.session&&a.session.credentials&&a.session.credentials.email)||'';if(!email){try{const t=localStorage.getItem('__data2-session-katia-party')||'';const p=JSON.parse(decodeURIComponent(escape(atob(t.split('.')[1].replace(/-/g,'+').replace(/_/g,'/')))));const s=(p.sessions||[]).find(x=>x.authStrategy==='partyAuth')||(p.sessions||[])[0];email=(s&&s.credentials&&s.credentials.email)||''}catch(e){}}return String(email).toLowerCase()}\nconst PARTY=new Date('2026-11-15T12:00:00-03:00')\n// 🐕 Milo com expressões (mesmo desenho do shiba(), ver assets/milo-atual.js)\n// feliz | piscadinha | radiante | apaixonado | surpreso | dormindo | pidao | festeiro\nfunction miloA(expr,cls){const ink='#3B2A2E',cr='#FFF4E8',hp='M0 6 C-2 -2 -13 -2 -13 6 C-13 13 -4 17 0 21 C4 17 13 13 13 6 C13 -2 2 -2 0 6Z'\n  const eo=(x,y,rx=4.5,ry=5.5)=>`<ellipse cx=\"${x}\" cy=\"${y}\" rx=\"${rx}\" ry=\"${ry}\" fill=\"${ink}\"/><circle cx=\"${x+1.5}\" cy=\"${y-2}\" r=\"${rx*.33}\" fill=\"#fff\"/>`\n  const ea=(x,y)=>`<path d=\"M${x-6} ${y+2} Q${x} ${y-6} ${x+6} ${y+2}\" stroke=\"${ink}\" stroke-width=\"3\" fill=\"none\" stroke-linecap=\"round\"/>`\n  const es=(x,y)=>`<path d=\"M${x-6} ${y} Q${x} ${y+5} ${x+6} ${y}\" stroke=\"${ink}\" stroke-width=\"2.6\" fill=\"none\" stroke-linecap=\"round\"/>`\n  const eb=(x,y)=>`<ellipse cx=\"${x}\" cy=\"${y}\" rx=\"7.5\" ry=\"8.5\" fill=\"${ink}\"/><circle cx=\"${x+2.5}\" cy=\"${y-3}\" r=\"3\" fill=\"#fff\"/><circle cx=\"${x-2.5}\" cy=\"${y+3}\" r=\"1.4\" fill=\"#fff\"/>`\n  const ht=(x,y,s)=>`<path transform=\"translate(${x} ${y}) scale(${s})\" d=\"${hp}\" fill=\"#E8547A\"/>`\n  const mW=`<path d=\"M52 83 Q56 88 60 83 Q64 88 68 83\" stroke=\"${ink}\" stroke-width=\"2.4\" fill=\"none\" stroke-linecap=\"round\"/>`,mOp=`<path d=\"M52 82 Q60 97 68 82 Z\" fill=\"#8E3B4E\"/><ellipse cx=\"60\" cy=\"90\" rx=\"4\" ry=\"2.6\" fill=\"#F48FA2\"/>`,mS=`<path d=\"M56 84 Q60 87 64 84\" stroke=\"${ink}\" stroke-width=\"2.2\" fill=\"none\" stroke-linecap=\"round\"/>`\n  let eyes=eo(44,58)+eo(76,58),m=mW,x='',top='',dots=`<ellipse cx=\"44\" cy=\"45\" rx=\"6\" ry=\"4\" fill=\"${cr}\"/><ellipse cx=\"76\" cy=\"45\" rx=\"6\" ry=\"4\" fill=\"${cr}\"/>`\n  if(expr==='piscadinha'){eyes=eo(44,58)+ea(76,59);m=mOp;x=`<path d=\"M100 42 l4 -4 M104 48 l6 -1 M102 54 l5 2\" stroke=\"#F6B678\" stroke-width=\"2.2\" stroke-linecap=\"round\"/>`}\n  if(expr==='radiante'){eyes=ea(44,59)+ea(76,59);m=mOp;x=`<path d=\"M8 30 l4 -6 M2 40 l-7 -2 M112 30 l-4 -6 M118 40 l7 -2\" stroke=\"#F6B678\" stroke-width=\"2.4\" stroke-linecap=\"round\"/>`}\n  if(expr==='apaixonado'){eyes=ht(44,52,.55)+ht(76,52,.55);x=ht(108,18,.45)+ht(10,26,.35)}\n  if(expr==='surpreso'){eyes=eo(44,58,3.6,4.4)+eo(76,58,3.6,4.4);m=`<ellipse cx=\"60\" cy=\"86\" rx=\"3.5\" ry=\"4.5\" fill=\"#8E3B4E\"/>`;dots=dots.replace(/cy=\"45\"/g,'cy=\"40\"');x=`<text x=\"104\" y=\"30\" font-size=\"20\" font-weight=\"900\" fill=\"#E8547A\" font-family=\"sans-serif\">!</text>`}\n  if(expr==='dormindo'){eyes=es(44,59)+es(76,59);m=mS;x=`<circle cx=\"70\" cy=\"80\" r=\"4.5\" fill=\"#BFE3F5\" opacity=\".85\" stroke=\"#9CCDE6\"/><text x=\"96\" y=\"22\" font-size=\"14\" font-weight=\"900\" fill=\"#9F86C9\" font-family=\"sans-serif\">z</text><text x=\"106\" y=\"8\" font-size=\"20\" font-weight=\"900\" fill=\"#9F86C9\" font-family=\"sans-serif\">Z</text>`}\n  if(expr==='pidao'){eyes=eb(44,58)+eb(76,58)+`<path d=\"M38 66 q-2.5 6 1.5 8 q4 -2 1.5 -8 z\" fill=\"#9CCDE6\"/>`;m=mS;dots=`<ellipse cx=\"44\" cy=\"45\" rx=\"6\" ry=\"3.6\" fill=\"${cr}\" transform=\"rotate(-22 44 45)\"/><ellipse cx=\"76\" cy=\"45\" rx=\"6\" ry=\"3.6\" fill=\"${cr}\" transform=\"rotate(22 76 45)\"/>`}\n  if(expr==='festeiro'){eyes=ea(44,59)+ea(76,59);m=mOp;top=`<path d=\"M42 30 L60 -8 L78 30 Z\" fill=\"#E79AAB\"/><circle cx=\"54\" cy=\"16\" r=\"2.6\" fill=\"#fff\"/><circle cx=\"64\" cy=\"8\" r=\"2.4\" fill=\"#FFF2C9\"/><circle cx=\"66\" cy=\"22\" r=\"2.4\" fill=\"#fff\"/><circle cx=\"60\" cy=\"-10\" r=\"5.5\" fill=\"#FFF2C9\" stroke=\"#E79AAB\" stroke-width=\"1.5\"/>`;x=`<rect x=\"6\" y=\"14\" width=\"5\" height=\"9\" rx=\"2\" fill=\"#CDB8EA\" transform=\"rotate(-20 8 18)\"/><rect x=\"108\" y=\"10\" width=\"5\" height=\"9\" rx=\"2\" fill=\"#F5D98B\" transform=\"rotate(25 110 14)\"/><circle cx=\"114\" cy=\"36\" r=\"3\" fill=\"#B9D8BF\"/><circle cx=\"4\" cy=\"40\" r=\"2.6\" fill=\"#F2AEBA\"/>`}\n  return `<svg class=\"${cls||''}\" viewBox=\"0 0 120 110\" style=\"overflow:visible\" aria-hidden=\"true\"><path d=\"M22 50 L30 8 L56 32 Z\" fill=\"#E59A55\"/><path d=\"M29 41 L33 18 L48 33 Z\" fill=\"#F8D7B5\"/><path d=\"M98 50 L90 8 L64 32 Z\" fill=\"#E59A55\"/><path d=\"M91 41 L87 18 L72 33 Z\" fill=\"#F8D7B5\"/><ellipse cx=\"60\" cy=\"62\" rx=\"44\" ry=\"40\" fill=\"#E59A55\"/>${top}<path d=\"M24 70 Q30 99 60 103 Q90 99 96 70 Q84 58 72 66 Q60 74 48 66 Q36 58 24 70Z\" fill=\"${cr}\"/>${dots}<ellipse cx=\"32\" cy=\"74\" rx=\"7\" ry=\"4.5\" fill=\"#F4A7B5\" opacity=\".75\"/><ellipse cx=\"88\" cy=\"74\" rx=\"7\" ry=\"4.5\" fill=\"#F4A7B5\" opacity=\".75\"/>${eyes}<path d=\"M54 72 Q60 68 66 72 Q63 78 60 78 Q57 78 54 72Z\" fill=\"${ink}\"/>${m}${x}</svg>`}\nconst quietNow=()=>{try{return localStorage.getItem('kp-milo-quiet')==='1'}catch(e){return false}}\n// humor de base: dormindo no modo quietinho ou de madrugada; feliz no resto\nconst baseMood=()=>{const h=new Date().getHours();return quietNow()||h>=23||h<6?'dormindo':'feliz'}\nfunction miloK(expr='feliz'){\n  const C={fur:'#EE9A57',furL:'#F6B678',cream:'#FFF6EC',inner:'#F9C3B5',ink:'#2E2226',blush:'#F6A5B4',heart:'#E8547A'}\n  const eyeOpen=(x,y,rx=11,ry=13)=>`<ellipse cx=\"${x}\" cy=\"${y}\" rx=\"${rx}\" ry=\"${ry}\" fill=\"${C.ink}\"/><ellipse cx=\"${x}\" cy=\"${y+4}\" rx=\"${rx-3}\" ry=\"${ry-6}\" fill=\"#5A3A30\" opacity=\".55\"/><circle cx=\"${x+4}\" cy=\"${y-5}\" r=\"${rx*.38}\" fill=\"#fff\"/><circle cx=\"${x-4}\" cy=\"${y+5}\" r=\"${rx*.18}\" fill=\"#fff\"/>`\n  const eyeArc=(x,y)=>`<path d=\"M${x-10} ${y+3} Q${x} ${y-9} ${x+10} ${y+3}\" stroke=\"${C.ink}\" stroke-width=\"4.2\" fill=\"none\" stroke-linecap=\"round\"/>`\n  const eyeShut=(x,y)=>`<path d=\"M${x-10} ${y} Q${x} ${y+7} ${x+10} ${y}\" stroke=\"${C.ink}\" stroke-width=\"3.6\" fill=\"none\" stroke-linecap=\"round\"/>`\n  const heart=(x,y,s=1)=>`<path transform=\"translate(${x} ${y}) scale(${s})\" d=\"M0 6 C-2 -2 -13 -2 -13 6 C-13 13 -4 17 0 21 C4 17 13 13 13 6 C13 -2 2 -2 0 6Z\" fill=\"${C.heart}\"/><circle cx=\"${x-5*s}\" cy=\"${y+3*s}\" r=\"${2.4*s}\" fill=\"#fff\" opacity=\".8\"/>`\n  const mouthW=`<path d=\"M71 115 Q75.5 120.5 80 115 Q84.5 120.5 89 115\" stroke=\"${C.ink}\" stroke-width=\"2.6\" fill=\"none\" stroke-linecap=\"round\"/>`\n  const mouthOpen=`<path d=\"M70 113 Q80 131 90 113 Z\" fill=\"#8E3B4E\"/><ellipse cx=\"80\" cy=\"122.5\" rx=\"5.5\" ry=\"3.5\" fill=\"#F48FA2\"/>`\n  const mouthO=`<ellipse cx=\"80\" cy=\"118\" rx=\"4.5\" ry=\"5.5\" fill=\"#8E3B4E\"/>`\n  const mouthSmall=`<path d=\"M76 116 Q80 119 84 116\" stroke=\"${C.ink}\" stroke-width=\"2.4\" fill=\"none\" stroke-linecap=\"round\"/>`\n  const blush=(x)=>`<ellipse cx=\"${x}\" cy=\"110\" rx=\"11\" ry=\"6.5\" fill=\"${C.blush}\" opacity=\".7\"/><path d=\"M${x-6} 112 l3 -5 M${x-1} 112 l3 -5 M${x+4} 112 l3 -5\" stroke=\"#E07D93\" stroke-width=\"1.4\" stroke-linecap=\"round\" opacity=\".7\"/>`\n  let eyes=eyeOpen(58,90)+eyeOpen(102,90),mouth=mouthW,extra='',top='',brows=''\n  if(expr==='piscadinha'){eyes=eyeOpen(58,90)+eyeArc(102,91);mouth=mouthOpen;extra=`<path d=\"M126 70 l5 -5 M131 76 l7 -2 M128 82 l6 2\" stroke=\"#F6B678\" stroke-width=\"2.4\" stroke-linecap=\"round\"/>`}\n  if(expr==='radiante'){eyes=eyeArc(58,91)+eyeArc(102,91);mouth=mouthOpen;extra=`<path d=\"M24 52 l4 -8 M18 60 l-8 -3 M136 52 l-4 -8 M142 60 l8 -3\" stroke=\"#F6B678\" stroke-width=\"2.6\" stroke-linecap=\"round\"/>`}\n  if(expr==='apaixonado'){eyes=heart(58,80,.95)+heart(102,80,.95);mouth=mouthW;extra=heart(132,40,.55)+heart(20,48,.42)}\n  if(expr==='surpreso'){eyes=eyeOpen(58,90,8,10)+eyeOpen(102,90,8,10);mouth=mouthO;brows=`<path d=\"M50 70 Q58 64 66 70 M94 70 Q102 64 110 70\" stroke=\"${C.furL}\" stroke-width=\"3\" fill=\"none\" stroke-linecap=\"round\"/>`;extra=`<text x=\"128\" y=\"50\" font-size=\"22\" font-weight=\"900\" fill=\"${C.heart}\" font-family=\"sans-serif\">!</text>`}\n  if(expr==='dormindo'){eyes=eyeShut(58,91)+eyeShut(102,91);mouth=mouthSmall;extra=`<circle cx=\"92\" cy=\"118\" r=\"5\" fill=\"#BFE3F5\" opacity=\".85\" stroke=\"#9CCDE6\"/><text x=\"118\" y=\"46\" font-size=\"16\" font-weight=\"900\" fill=\"#9F86C9\" font-family=\"sans-serif\">z</text><text x=\"130\" y=\"32\" font-size=\"22\" font-weight=\"900\" fill=\"#9F86C9\" font-family=\"sans-serif\">Z</text>`}\n  if(expr==='pidao'){eyes=eyeOpen(58,89,13,15)+eyeOpen(102,89,13,15)+`<circle cx=\"52\" cy=\"84\" r=\"2\" fill=\"#fff\"/><circle cx=\"96\" cy=\"84\" r=\"2\" fill=\"#fff\"/><path d=\"M50 104 q-2 6 2 8 q4 -2 2 -8 z\" fill=\"#BFE3F5\"/>`;mouth=mouthSmall;brows=`<path d=\"M48 68 Q56 64 64 70 M96 70 Q104 64 112 68\" stroke=\"#B9763E\" stroke-width=\"3\" fill=\"none\" stroke-linecap=\"round\"/>`}\n  if(expr==='festeiro'){eyes=eyeArc(58,91)+eyeArc(102,91);mouth=mouthOpen;top=`<path d=\"M62 40 L80 -2 L98 40 Z\" fill=\"#F2AEBA\" stroke=\"#E79AAB\" stroke-width=\"2\"/><path d=\"M70 24 L90 30 M66 34 L94 38\" stroke=\"#fff\" stroke-width=\"3\" opacity=\".8\"/><circle cx=\"80\" cy=\"-2\" r=\"6\" fill=\"#FFF2C9\"/>`;extra=`<rect x=\"18\" y=\"30\" width=\"6\" height=\"10\" rx=\"2\" fill=\"#CDB8EA\" transform=\"rotate(-20 21 35)\"/><rect x=\"134\" y=\"26\" width=\"6\" height=\"10\" rx=\"2\" fill=\"#F5D98B\" transform=\"rotate(25 137 31)\"/><circle cx=\"140\" cy=\"56\" r=\"3.5\" fill=\"#B9D8BF\"/><circle cx=\"16\" cy=\"58\" r=\"3\" fill=\"#F2AEBA\"/>`}\n  return `<svg viewBox=\"0 -10 160 160\" xmlns=\"http://www.w3.org/2000/svg\">\n    <g><path d=\"M28 66 C22 34 32 14 44 8 C58 16 68 34 72 48 Z\" fill=\"${C.fur}\"/><path d=\"M37 56 C35 36 40 24 46 20 C54 28 60 38 62 48 Z\" fill=\"${C.inner}\"/></g>\n    <g transform=\"translate(160 0) scale(-1 1)\"><path d=\"M28 66 C22 34 32 14 44 8 C58 16 68 34 72 48 Z\" fill=\"${C.fur}\"/><path d=\"M37 56 C35 36 40 24 46 20 C54 28 60 38 62 48 Z\" fill=\"${C.inner}\"/></g>\n    ${top}\n    <path d=\"M80 36 C122 36 148 60 148 94 C148 126 118 144 80 144 C42 144 12 126 12 94 C12 60 38 36 80 36 Z\" fill=\"${C.fur}\"/>\n    <path d=\"M12 98 C8 104 10 110 16 112 M148 98 C152 104 150 110 144 112\" stroke=\"${C.fur}\" stroke-width=\"6\" stroke-linecap=\"round\"/>\n    <path d=\"M20 102 C24 82 46 78 62 88 C70 93 75 97 80 97 C85 97 90 93 98 88 C114 78 136 82 140 102 C138 128 114 142 80 142 C46 142 22 128 20 102 Z\" fill=\"${C.cream}\"/>\n    <ellipse cx=\"58\" cy=\"66\" rx=\"7.5\" ry=\"4.5\" fill=\"${C.cream}\"/><ellipse cx=\"102\" cy=\"66\" rx=\"7.5\" ry=\"4.5\" fill=\"${C.cream}\"/>\n    ${brows}${blush(38)}${blush(122)}${eyes}\n    <path d=\"M73.5 104 Q80 100.5 86.5 104 Q84.5 111 80 111 Q75.5 111 73.5 104Z\" fill=\"${C.ink}\"/><ellipse cx=\"78\" cy=\"104\" rx=\"2.2\" ry=\"1.2\" fill=\"#fff\" opacity=\".7\"/>\n    ${mouth}${extra}</svg>`\n}\n// Chibi = adesivos gerados (Gemini) a partir dos shibinhas do convite polaroid. PNGs no Drive; originais em assets/milo-adesivo/\nconst MC={feliz:'FHzir7Okbf8i27LC0AdzM',piscadinha:'4b4IoOBUc6NO_Mzj8eLUL',radiante:'JR8AHTg-qFbF4bOzpphxE',apaixonado:'II0WrK9emVby-H4S4NUrV',surpreso:'vlSjz0N_0953n-DyWDgkq',dormindo:'WSZ6B5cfSIA9aH0fztInw',pidao:'mn3EEEIs4svWnuTZ4WuNi',festeiro:'fPCwftn3a-m_nbktmgUV4'}\nconst mcUrl=(e)=>'https://katia-party.data2.media/file/'+(MC[e]||MC.feliz)\nfunction miloC(expr){return `<img src=\"${mcUrl(expr)}\" alt=\"\" draggable=\"false\"/>`}\nfunction miloT(expr='feliz'){\n  const O='#5A3A28',F='#F4B860',CR='#FFF1D6',IN='#F7C9B0',BL='#F7A8A8',HR='#E8547A',W=2.6\n  const dot=(x,y,r=5)=>`<circle cx=\"${x}\" cy=\"${y}\" r=\"${r}\" fill=\"#2B1D16\"/><circle cx=\"${x+1.6}\" cy=\"${y-1.8}\" r=\"${r*.3}\" fill=\"#fff\"/>`\n  const arc=(x,y)=>`<path d=\"M${x-6} ${y+2} Q${x} ${y-5} ${x+6} ${y+2}\" stroke=\"#2B1D16\" stroke-width=\"3\" fill=\"none\" stroke-linecap=\"round\"/>`\n  const line=(x,y)=>`<path d=\"M${x-6} ${y} Q${x} ${y+4} ${x+6} ${y}\" stroke=\"#2B1D16\" stroke-width=\"2.8\" fill=\"none\" stroke-linecap=\"round\"/>`\n  const ht=(x,y,s)=>`<path transform=\"translate(${x} ${y}) scale(${s})\" d=\"M0 6 C-2 -2 -13 -2 -13 6 C-13 13 -4 17 0 21 C4 17 13 13 13 6 C13 -2 2 -2 0 6Z\" fill=\"${HR}\"/>`\n  const m3=`<path d=\"M73 102 Q76.5 106.5 80 102 Q83.5 106.5 87 102\" stroke=\"${O}\" stroke-width=\"2.6\" fill=\"none\" stroke-linecap=\"round\"/>`\n  const mOpen=`<path d=\"M72 101 Q80 113 88 101 Z\" fill=\"#7A2E3A\"/><path d=\"M76 107 Q80 104 84 107 Q80 111 76 107Z\" fill=\"#F48FA2\"/>`\n  const mO=`<ellipse cx=\"80\" cy=\"105\" rx=\"3.6\" ry=\"4.6\" fill=\"#7A2E3A\"/>`\n  const mFlat=`<path d=\"M75 104 L85 104\" stroke=\"${O}\" stroke-width=\"2.6\" stroke-linecap=\"round\"/>`\n  const mWob=`<path d=\"M73 105 Q76 101 79 105 Q82 109 85 105 Q86.5 103 88 104\" stroke=\"${O}\" stroke-width=\"2.4\" fill=\"none\" stroke-linecap=\"round\"/>`\n  let eyes=dot(58,84)+dot(102,84),m=m3,x='',top=''\n  if(expr==='piscadinha'){eyes=dot(58,84)+arc(102,86);m=mOpen;x=`<path d=\"M128 70 l4 -5 M132 77 l7 -1\" stroke=\"${O}\" stroke-width=\"2.4\" stroke-linecap=\"round\"/>`}\n  if(expr==='radiante'){eyes=arc(58,86)+arc(102,86);m=mOpen;x=`<path d=\"M16 46 l4 -7 M10 58 l-8 -2 M144 46 l-4 -7 M150 58 l8 -2\" stroke=\"${O}\" stroke-width=\"2.4\" stroke-linecap=\"round\"/>`}\n  if(expr==='apaixonado'){eyes=ht(58,77,.55)+ht(102,77,.55);x=ht(140,28,.45)+ht(18,36,.35)}\n  if(expr==='surpreso'){eyes=`<circle cx=\"58\" cy=\"84\" r=\"7\" fill=\"#fff\" stroke=\"#2B1D16\" stroke-width=\"2.6\"/><circle cx=\"58\" cy=\"84\" r=\"2.6\" fill=\"#2B1D16\"/><circle cx=\"102\" cy=\"84\" r=\"7\" fill=\"#fff\" stroke=\"#2B1D16\" stroke-width=\"2.6\"/><circle cx=\"102\" cy=\"84\" r=\"2.6\" fill=\"#2B1D16\"/>`;m=mO;x=`<text x=\"134\" y=\"40\" font-size=\"22\" font-weight=\"900\" fill=\"${O}\" font-family=\"sans-serif\">!</text>`}\n  if(expr==='dormindo'){eyes=line(58,85)+line(102,85);m=mFlat;x=`<text x=\"122\" y=\"36\" font-size=\"14\" font-weight=\"900\" fill=\"${O}\" font-family=\"sans-serif\">z</text><text x=\"132\" y=\"22\" font-size=\"20\" font-weight=\"900\" fill=\"${O}\" font-family=\"sans-serif\">Z</text>`}\n  if(expr==='pidao'){eyes=`<circle cx=\"58\" cy=\"84\" r=\"8\" fill=\"#2B1D16\"/><circle cx=\"61\" cy=\"80.5\" r=\"3.2\" fill=\"#fff\"/><circle cx=\"55\" cy=\"87.5\" r=\"1.5\" fill=\"#fff\"/><circle cx=\"102\" cy=\"84\" r=\"8\" fill=\"#2B1D16\"/><circle cx=\"105\" cy=\"80.5\" r=\"3.2\" fill=\"#fff\"/><circle cx=\"99\" cy=\"87.5\" r=\"1.5\" fill=\"#fff\"/><path d=\"M50 92 q-2.5 7 1.5 9 q4 -2 1.5 -9 z\" fill=\"#8CC4E2\"/>`;m=mWob;x=`<path d=\"M48 76 L64 71 M112 76 L96 71\" stroke=\"${O}\" stroke-width=\"2.6\" stroke-linecap=\"round\"/>`}\n  if(expr==='festeiro'){eyes=arc(58,86)+arc(102,86);m=mOpen;top=`<path d=\"M62 40 L80 -6 L98 40 Z\" fill=\"#9FD3C7\" stroke=\"${O}\" stroke-width=\"${W}\" stroke-linejoin=\"round\"/><path d=\"M71 18 L89 22 M67 30 L93 33\" stroke=\"#fff\" stroke-width=\"3\"/><circle cx=\"80\" cy=\"-8\" r=\"6\" fill=\"#F7A8A8\" stroke=\"${O}\" stroke-width=\"${W}\"/>`;x=`<path d=\"M14 26 l6 4 M146 22 l-6 5 M150 50 l-5 0 M10 54 l5 1\" stroke=\"${O}\" stroke-width=\"2.4\" stroke-linecap=\"round\"/><circle cx=\"24\" cy=\"16\" r=\"3\" fill=\"#F7A8A8\"/><circle cx=\"138\" cy=\"10\" r=\"3\" fill=\"#9FD3C7\"/>`}\n  return `<svg viewBox=\"-4 -18 168 166\" xmlns=\"http://www.w3.org/2000/svg\">\n    <path d=\"M30 60 L34 18 Q36 12 41 15 L70 40 Z\" fill=\"${F}\" stroke=\"${O}\" stroke-width=\"${W}\" stroke-linejoin=\"round\"/><path d=\"M38 50 L41 27 L58 42 Z\" fill=\"${IN}\"/>\n    <path d=\"M130 60 L126 18 Q124 12 119 15 L90 40 Z\" fill=\"${F}\" stroke=\"${O}\" stroke-width=\"${W}\" stroke-linejoin=\"round\"/><path d=\"M122 50 L119 27 L102 42 Z\" fill=\"${IN}\"/>\n    <path d=\"M24 70 Q24 36 80 36 Q136 36 136 70 L137 104 Q137 138 80 138 Q23 138 23 104 Z\" fill=\"${F}\" stroke=\"${O}\" stroke-width=\"${W}\" stroke-linejoin=\"round\"/>${top}\n    <path d=\"M25 96 Q42 84 62 92 Q80 100 98 92 Q118 84 135 96 L136 104 Q136 136 80 136 Q24 136 24 104 Z\" fill=\"${CR}\"/>\n    <ellipse cx=\"38\" cy=\"100\" rx=\"7\" ry=\"4\" fill=\"${BL}\" opacity=\".8\"/><ellipse cx=\"122\" cy=\"100\" rx=\"7\" ry=\"4\" fill=\"${BL}\" opacity=\".8\"/>\n    ${eyes}<ellipse cx=\"80\" cy=\"96\" rx=\"4\" ry=\"2.8\" fill=\"#2B1D16\"/>${m}${x}</svg>`\n}\n// 🎨 estilos do Milo (escolhido no menu do avatar; fica em settings key 'milo', vale pros dois)\nconst MSETS={atual:['Atual',miloA],kawaii:['Kawaii',miloK],chibi:['Chibi',miloC],at:['Desenho animado',miloT]}\n// 🎛️ preferências POR USUÁRIO: settings key 'prefs' → {[email com . trocado por _]: {milo, theme}}; localStorage = cache do aparelho\nconst pkey=(d2)=>who(d2).replace(/[.$]/g,'_')\nconst myPrefs=(d2)=>{const h=d2.data('settings');const r=h&&(h.records()||[]).find(x=>x.key==='prefs');const k=pkey(d2);return (r&&r.value&&k&&r.value[k])||{}}\nasync function savePref(d2,patch){const k=pkey(d2);if(!k)return;const S=d2.data('settings'),rec=(S.records()||[]).find(r=>r.key==='prefs');const v={...((rec&&rec.value)||{})};v[k]={...(v[k]||{}),...patch};if(rec)await S.update({...rec,value:v});else await S.create({key:'prefs',value:v})}\nconst miloSet=(d2)=>{let v=myPrefs(d2).milo;if(!v){try{v=localStorage.getItem('kp-milo-set')}catch(e){}}return MSETS[v]?v:'atual'}\nfunction miloSvg(d2,expr,cls,set){set=set||miloSet(d2);const f=MSETS[set][1];return set==='atual'?f(expr,(cls||'')+' s-atual'):f(expr).replace(/^<(svg|img) /,(m,t)=>`<${t} class=\"${cls||''} s-${set}\" `)}\n// 🌗 tema por usuário: auto (segue o sistema), claro, escuro. As telas filhas leem as cores via --k-* (definidas em .app.dark)\nconst THEMES={auto:'🌗 Tema: automático',claro:'☀️ Tema: claro',escuro:'🌙 Tema: escuro'}\nconst themeOf=(d2)=>{let t=myPrefs(d2).theme;if(!t){try{t=localStorage.getItem('kp-theme')}catch(e){}}return THEMES[t]?t:'auto'}\nconst isDark=(d2)=>{const t=themeOf(d2);return t==='escuro'||(t==='auto'&&!!(window.matchMedia&&matchMedia('(prefers-color-scheme: dark)').matches))}\nconst NAMES={'danilojun9@gmail.com':'Danilo','katia.s.honda@gmail.com':'Katia'}\nconst TABS=[\n  {id:'summary',label:'Resumo',glyph:'🏡',view:'vSummary'},\n  {id:'budget',label:'Orçamento',glyph:'💸',view:'vBudget'},\n  {id:'guests',label:'Convidados',glyph:'💌',view:'vGuests'},\n  {id:'chat',label:'Milo',glyph:'🐕',view:'vChat'},\n  {id:'art',label:'Artes',glyph:'🎨',view:'vArt'},\n]\nconst DS=['items','quotes','guests','messages','tasks','settings','artworks']\n// versão deste bundle: a cada publish suba APP_V aqui E o settings {key:'app', value:{version}} (ver AGENTS.md). Diferente → hint no 🔄\nconst APP_V='2026-10-03.6'\nconst SCAN=new WeakMap() // root → função que detecta mudança de status das tasks (chamada no updated)\n\nexport default {\n  css:`\n:host{--bg:#FFF7F5;--card:#FFFFFF;--blush-50:#FFF1F2;--blush-100:#FDE4E7;--blush-200:#F9CDD4;--blush-300:#F2AEBA;--rose:#D9879A;--rose-deep:#B8647A;--ink:#4A3439;--muted:#94797E;--line:#F3DDE0;--peach:#FDE3D3;--sage:#DCEBDD;--sage-ink:#4F7A57;--shadow:0 6px 24px rgba(184,100,122,.12)}\n*{box-sizing:border-box}\n.app{height:100%;display:grid;grid-template-columns:244px minmax(0,1fr);grid-template-rows:minmax(0,1fr);background:var(--bg);color:var(--ink);font-family:'Nunito',system-ui,sans-serif;overflow:hidden}\n.side{display:flex;flex-direction:column;gap:6px;padding:22px 16px 16px;background:var(--k-side,linear-gradient(180deg,#FFFFFF 0,#FFF3F4 100%));border-right:1px solid var(--line);min-height:0}\n.logo{display:flex;align-items:center;gap:10px;padding:4px 8px 18px;cursor:pointer;user-select:none}\n.logo svg{width:44px;height:40px;flex:none;transition:transform .3s}.logo:hover svg{transform:rotate(-8deg)}\n.logo b{font:600 22px/1 'Fredoka',sans-serif;color:var(--rose-deep);display:block}\n.logo small{font-size:12px;color:var(--muted);font-weight:700}\n.nav{display:flex;flex-direction:column;gap:4px}\n.tab{display:flex;align-items:center;gap:12px;padding:11px 14px;border-radius:14px;cursor:pointer;font:600 15px 'Fredoka',sans-serif;color:var(--ink);border:0;background:none;text-align:left;transition:background .15s}\n.tab .g{font-size:18px;width:26px;text-align:center}\n.tab:hover{background:var(--blush-50)}\n.tab[data-on]{background:var(--blush-100);color:var(--rose-deep);box-shadow:inset 0 0 0 1px var(--blush-200)}\n.tab .badge{margin-left:auto;background:var(--rose);color:#fff;border-radius:999px;font:700 11px 'Nunito';padding:2px 7px}\n.spacer{flex:1}\n.rf{border:1.5px solid var(--line);background:var(--card);color:var(--rose-deep);border-radius:999px;padding:6px 10px;font:600 13px 'Fredoka';cursor:pointer;white-space:nowrap}\n.side .rf{margin:0 4px;padding:9px 12px}\n.rf.new{background:linear-gradient(135deg,#E79AAB,#D9879A);color:#fff;border-color:transparent;animation:rfp 1.6s ease-in-out infinite}\n.rfw{position:relative;display:inline-flex}.rfhint{position:absolute;top:calc(100% + 8px);right:-6px;background:var(--ink);color:#fff;font:700 11px 'Nunito',sans-serif;padding:5px 9px;border-radius:9px;white-space:nowrap;z-index:30;pointer-events:none;animation:pop .3s ease-out}\n.rfhint:before{content:'';position:absolute;top:-4px;right:16px;width:8px;height:8px;background:var(--ink);transform:rotate(45deg)}\n@keyframes rfp{0%,100%{box-shadow:0 0 0 0 rgba(217,135,154,.55)}50%{box-shadow:0 0 0 7px rgba(217,135,154,0)}}\n.count{margin:10px 4px;padding:14px;border-radius:18px;background:var(--k-soft,linear-gradient(135deg,#FDE4E7,#FDE3D3));text-align:center}\n.count b{display:block;font:600 34px/1 'Fredoka',sans-serif;color:var(--rose-deep)}\n.count span{font-size:12px;font-weight:700;color:var(--muted)}\n.me{position:relative;display:flex;align-items:center;gap:10px;padding:10px;border-radius:14px;cursor:pointer;border:1px solid transparent}\n.me:hover{background:var(--card);border-color:var(--line)}\n.av{width:34px;height:34px;border-radius:50%;display:grid;place-items:center;font:600 14px 'Fredoka';color:#fff;background:linear-gradient(135deg,#E79AAB,#D9879A);flex:none}\n.me .n{font-weight:800;font-size:14px}.me .e{font-size:11px;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:140px}\n.menu{position:absolute;bottom:calc(100% + 6px);left:0;right:0;background:var(--card);border:1px solid var(--line);border-radius:14px;box-shadow:var(--shadow);padding:6px;z-index:20}\n.menu.top{bottom:auto;top:calc(100% + 6px);left:auto;right:0;width:220px}\n.menu button{display:block;width:100%;text-align:left;border:0;background:none;padding:10px 12px;border-radius:10px;font:700 14px 'Nunito';color:var(--ink);cursor:pointer}\n.menu button:hover{background:var(--blush-50)}\n.main{display:grid;grid-template-rows:auto minmax(0,1fr);min-width:0;min-height:0}\n.top{display:none}\n.view{min-height:0;position:relative;grid-row:2}\n.top{grid-row:1}.bottom{grid-row:3}\n.view>*{position:absolute!important;inset:0!important;width:auto!important;height:auto!important}\n.bottom{display:none}\n.toast{position:fixed;left:50%;bottom:26px;transform:translateX(-50%);background:var(--ink);color:#fff;padding:10px 16px;border-radius:14px;font-weight:700;font-size:14px;box-shadow:var(--shadow);z-index:50;max-width:calc(100vw - 32px);text-align:center}\n.rain{position:fixed;top:-70px;width:54px;height:50px;pointer-events:none;z-index:60;animation:fall linear forwards}\n.rain svg{width:100%;height:100%}\n@keyframes fall{to{transform:translateY(115vh) rotate(540deg)}}\n.milo{position:fixed;right:20px;bottom:-14px;width:88px;height:80px;cursor:pointer;z-index:40;transition:transform .35s cubic-bezier(.3,1.6,.5,1);filter:drop-shadow(0 -4px 10px rgba(184,100,122,.18))}\n.pick{position:fixed;inset:0;background:rgba(74,52,57,.35);z-index:60;display:grid;place-items:center;padding:16px}.pbox{background:var(--card);border-radius:24px;padding:18px;max-width:520px;width:100%;max-height:90vh;overflow:auto;box-shadow:0 20px 60px rgba(184,100,122,.25)}.pbox h3{margin:0 0 2px;font:600 22px 'Fredoka',sans-serif;color:var(--k-plum,#8E4258)}.pbox p{margin:0 0 12px;color:var(--muted);font-size:13px}.pgrid{display:grid;grid-template-columns:1fr 1fr;gap:10px}.pk{border:2px solid var(--line);background:var(--bg);border-radius:18px;padding:12px 8px;cursor:pointer;display:grid;gap:8px;justify-items:center;font:inherit;color:var(--ink)}.pk.on{border-color:#D9879A;background:var(--blush-100)}.pk .pf svg{width:86px;height:86px;display:block;overflow:visible}.pk .pe{display:flex;gap:2px}.pk .pe svg{width:28px;height:28px;overflow:visible}.pk b{font:800 14px 'Nunito',sans-serif}.pclose{margin-top:12px;width:100%;border:0;background:var(--blush-100);color:var(--k-plum,#8E4258);border-radius:14px;padding:11px;font:800 14px 'Nunito',sans-serif;cursor:pointer}\n.app.dark{color-scheme:dark;--bg:#1C1517;--k-bg:#1C1517;--card:#281F22;--k-card:#281F22;--blush-50:#31252A;--k-blush-50:#31252A;--blush-100:#3C2B31;--k-blush-100:#3C2B31;--blush-200:#4A3239;--k-blush-200:#4A3239;--blush-300:#7A4E5B;--k-blush-300:#7A4E5B;--rose:#E79AAB;--k-rose:#E79AAB;--rose-deep:#F2AEBA;--k-rose-deep:#F2AEBA;--ink:#F6E7EA;--k-ink:#F6E7EA;--muted:#B89EA4;--k-muted:#B89EA4;--line:#3E2F35;--k-line:#3E2F35;--peach:#3A2B26;--k-peach:#3A2B26;--sage:#1F3227;--k-sage:#1F3227;--sage-ink:#9DD3A8;--k-sage-ink:#9DD3A8;--butter:#3A3120;--k-butter:#3A3120;--butter-ink:#EBD07E;--k-butter-ink:#EBD07E;--lilac:#2F2839;--k-lilac:#2F2839;--lilac-ink:#C9B4EC;--k-lilac-ink:#C9B4EC;--shadow:0 6px 24px rgba(0,0,0,.35);--k-shadow:0 6px 24px rgba(0,0,0,.35);--k-glass:rgba(255,255,255,.08);--k-glass2:rgba(40,31,34,.92);--k-hero:linear-gradient(120deg,#3C2B31 0%,#3A2B26 55%,#3A3120 120%);--k-plum:#F2AEBA;--k-plum2:#D8B6BE;--k-cream:#33282A;--k-mine:linear-gradient(135deg,#4A3239,#3C2B31);--k-mute:#2E2629;--k-card2:linear-gradient(180deg,#30242A,#281F22);--k-side:linear-gradient(180deg,#281F22 0,#221A1D 100%);--k-soft:linear-gradient(135deg,#3C2B31,#3A2B26);--k-prov:#F0B48A}\n.milo.s-chibi,.rain img{object-fit:contain}.rain img{width:100%;height:100%}.pk .pf img{width:86px;height:86px;object-fit:contain;display:block}.pk .pe img{width:28px;height:28px;object-fit:contain}\n.milo:hover,.milo.up{transform:translateY(-18px) rotate(-6deg)}\n.mbub{position:fixed;right:106px;bottom:46px;max-width:min(320px,calc(100vw - 140px));background:var(--card);border:1px solid var(--line);border-radius:16px 16px 4px 16px;padding:10px 14px;font:600 14px/1.35 'Fredoka',sans-serif;color:var(--rose-deep);box-shadow:0 10px 30px rgba(184,100,122,.22);z-index:41;cursor:pointer;animation:pop .3s ease-out}\n.mbub small{display:block;margin-top:3px;font:700 12px/1.3 'Nunito',sans-serif;color:var(--muted)}\n@keyframes pop{from{opacity:0;transform:translateY(8px) scale(.96)}}\n.mbub.top{bottom:auto;top:84px;border-radius:16px 4px 16px 16px}\n@media (max-width:820px){.milo{right:10px;bottom:92px;width:58px;height:53px}.mbub{right:16px;bottom:148px;max-width:calc(100vw - 32px)}}\n@media (max-width:820px){\n  .app{grid-template-columns:minmax(0,1fr)}\n  .side{display:none}\n  .main{grid-template-rows:auto minmax(0,1fr) auto}\n  .top{display:flex;align-items:center;gap:10px;padding:10px 16px;background:var(--card);border-bottom:1px solid var(--line)}\n  .top .logo{padding:0;flex:1;min-width:0}.top .logo svg{width:34px;height:31px}.top .logo b{font-size:19px}\n  .pill{font:600 13px 'Fredoka';color:var(--rose-deep);background:var(--blush-100);border-radius:999px;padding:6px 10px;white-space:nowrap}\n  .top .me{padding:0}.top .me .txt{display:none}\n  .bottom{display:grid;grid-template-columns:repeat(5,1fr);background:var(--card);border-top:1px solid var(--line);padding:6px 4px calc(36px + env(safe-area-inset-bottom))} /* sobe o menu: o banner do data2 fica embaixo */\n  .toast{bottom:112px}\n  .bottom .tab{flex-direction:column;gap:2px;padding:6px 2px;font-size:11px;justify-content:center;align-items:center;border-radius:12px;position:relative}\n  .bottom .tab .g{font-size:20px;width:auto}\n  .bottom .tab .badge{position:absolute;top:2px;right:calc(50% - 22px);margin:0;padding:1px 5px;font-size:10px}\n}\n`,\n  render(d2){\n    const s=d2.state\n    const email=who(d2)\n    const me=NAMES[email]||(email?email.split('@')[0]:'Você')\n    const tab=TABS.find(t=>t.id===s.tab)||TABS[0]\n    const days=Math.max(0,Math.ceil((PARTY.getTime()-Date.now())/86400000))\n    const appRec=((d2.data('settings')&&d2.data('settings').records())||[]).find(r=>r.key==='app'),outdated=!!(appRec&&appRec.value&&appRec.value.version&&appRec.value.version!==APP_V)\n    const tasks=d2.data('tasks'), pend=tasks?tasks.records().filter(t=>['pendente','em andamento'].includes(t.status||'pendente')).length:0\n    const tabBtn=(t)=>`<button class=\"tab\" data-tab=\"${t.id}\" ${t.id===tab.id?'data-on':''}><span class=\"g\">${t.glyph}</span><span>${t.label}</span>${t.id==='chat'&&pend?`<span class=\"badge\">${pend}</span>`:''}</button>`\n    const menu=(cls)=>s.menu?`<div class=\"menu ${cls}\"><button class=\"m-milo\">🐕 Estilo do Milo</button><button class=\"m-theme\">${THEMES[themeOf(d2)]}</button><button class=\"m-pass\">🔑 Trocar senha</button><button class=\"m-out\">👋 Sair</button></div>`:''\n    const P=d2.params\n    const common={items:P.items,quotes:P.quotes,guests:P.guests,messages:P.messages,tasks:P.tasks,settings:P.settings,artworks:P.artworks,scribe:P.scribe,artist:P.artist,drive:P.drive,uploader:'upload-file',me}\n    const dark=isDark(d2);try{document.documentElement.style.background=dark?'#1C1517':''}catch(e){}\n    return `<div class=\"app ${dark?'dark':''}\">\n      <aside class=\"side\">\n        <div class=\"logo\">${shiba()}<div><b>Festa da Katia</b><small>15.11 · Sítio Recanto dos Lagos</small></div></div>\n        <nav class=\"nav\">${TABS.map(tabBtn).join('')}</nav>\n        <div class=\"spacer\"></div>\n        <button class=\"rf ${outdated?'new':''}\" title=\"Atualizar o app\">${outdated?'✨ Nova versão: atualizar':'🔄 Atualizar'}</button>\n        <div class=\"count\"><b>${days}</b><span>${days===0?'é hoje!!! 🎉':days===1?'dia pra festa 🎂':'dias pra festa 🎂'}</span></div>\n        <div class=\"me\"><div class=\"av\">${esc(me[0]||'?')}</div><div class=\"txt\"><div class=\"n\">${esc(me)}</div><div class=\"e\">${esc(email)}</div></div>${menu('')}</div>\n      </aside>\n      <section class=\"main\">\n        <header class=\"top\">\n          <div class=\"logo\">${shiba()}<div><b>Festa da Katia</b></div></div>\n          <span class=\"rfw\"><button class=\"rf ${outdated?'new':''}\" title=\"Atualizar o app\">🔄</button>${outdated?'<span class=\"rfhint\">nova versão ✨ toca aqui</span>':''}</span><span class=\"pill\">🎂 ${days}d</span>\n          <div class=\"me\"><div class=\"av\">${esc(me[0]||'?')}</div>${menu('top')}</div>\n        </header>\n        <div class=\"view\">${d2.render(d2.param(tab.view),common,{key:tab.id})}</div>\n        <nav class=\"bottom\">${TABS.map(tabBtn).join('')}</nav>\n      </section>\n      ${s.note?`<div class=\"mbub ${tab.id==='chat'?'top':''}\" data-go=\"${esc(s.note.go||'')}\">${esc(s.note.text)}${s.note.sub?`<small>${esc(s.note.sub)}</small>`:''}</div>`:''}\n      ${tab.id==='chat'?'':`<div class=\"milo-wrap\" title=\"Milo\">${miloSvg(d2,(s.note&&s.note.mood)||baseMood(),'milo'+(s.note?' up':''))}</div>`}\n      ${s.toast?`<div class=\"toast\">${esc(s.toast)}</div>`:''}\n      ${s.picker?`<div class=\"pick\"><div class=\"pbox\"><h3>Estilo do Milo</h3><p>Só pra você: cada um escolhe o seu. As expressões continuam as mesmas.</p><div class=\"pgrid\">${Object.keys(MSETS).map(k=>`<button class=\"pk ${k===miloSet(d2)?'on':''}\" data-set=\"${k}\"><div class=\"pf\">${miloSvg(d2,'feliz','',k)}</div><div class=\"pe\">${['piscadinha','apaixonado','festeiro','dormindo'].map(e=>miloSvg(d2,e,'',k)).join('')}</div><b>${MSETS[k][0]}</b></button>`).join('')}</div><button class=\"pclose\">Fechar</button></div></div>`:''}\n    </div>`\n  },\n  mounted(d2){\n    fonts();pwa()\n    try{const t=localStorage.getItem('kp-tab');if(t)d2.state.tab=t}catch(e){}\n    for(const k of DS){try{const h=d2.data(k);if(h)h.loadAll()}catch(e){}}\n    const go=(id)=>{d2.setState({tab:id,menu:false});try{localStorage.setItem('kp-tab',id)}catch(e){}\n      // trocou de aba → recarrega só os dados (não o app), pra ver sempre o mais recente\n      for(const k of DS){try{const h=d2.data(k);h&&h.loadAll()}catch(e){}}}\n    let tt;const toast=(m)=>{d2.state.toast=m;clearTimeout(tt);tt=setTimeout(()=>{d2.state.toast=''},3200)}\n    d2.on('.tab','click',(e,el)=>go(el.dataset.tab))\n    d2.bus.on('kp:nav',(id)=>go(id))\n    d2.bus.on('kp:toast',(m)=>toast(m))\n    // 🐕 Milo do canto: avisa quando o Claude pega/termina uma task. Tasks e mensagens são recarregadas a cada 30 s.\n    const seen=new Map(),gseen=new Map();let primed=false,gprimed=false,showing=false;const queue=[]\n    const show=()=>{if(showing||!queue.length)return;showing=true;d2.state.note=queue.shift();setTimeout(()=>{d2.state.note=null;showing=false;setTimeout(show,500)},8000)}\n    const notify=(n)=>{queue.push(n);show()}\n    // 🍢 lembrete do buffet (a partir de 20/10, uma vez por dia em cada aparelho, até alguém marcar \"Já conferi\" no Resumo)\n    const bfTick=()=>{const S=d2.data('settings'),G=d2.data('guests');if(!S||S.loading||!G||G.loading)return setTimeout(bfTick,3000)\n      const p=((S.records()||[]).find(r=>r.key==='party')||{}).value||{};if(p.buffetChecked)return\n      const from=new Date((p.buffetCheckFrom||'2026-10-20')+'T00:00:00-03:00').getTime();if(Date.now()<from||Date.now()>PARTY.getTime())return\n      const k='kp-buffet-'+new Date().toDateString();try{if(localStorage.getItem(k))return;localStorage.setItem(k,'1')}catch(e){}\n      const conf=(G.records()||[]).filter(g=>g.status==='confirmado').length,pax=Number(p.buffetPax)||90\n      notify({text:`🍢 Hora de conferir o buffet! ${conf} confirmados × ${pax} no orçamento`,sub:conf>pax?'Passou! Precisa aumentar o pedido (o orçamento vale até 21/10)':'Confere no Resumo e marca \"Já conferi\" 🐾',go:'summary',mood:conf>pax?'surpreso':'piscadinha'})}\n    const bfT=setTimeout(bfTick,4000);d2.onUnmount(()=>clearTimeout(bfT))\n    SCAN.set(d2.root,()=>{const T=d2.data('tasks');if(!T||T.loading)return\n      for(const t of (T.records()||[])){if(!t._id)continue;const st=t.status||'pendente',prev=seen.get(t._id);seen.set(t._id,st)\n        if(!primed||prev===st)continue\n        if(st==='feita')notify({text:`Au! O Claude terminou: ${t.title} ✨`,sub:t.result?String(t.result).slice(0,140):'toca aqui pra ver no chat',go:'chat',mood:'radiante'})\n        else if(st==='em andamento')notify({text:`O Claude pegou a task: ${t.title} 🐾`,sub:'tô de olho, já te aviso!',go:'chat',mood:'piscadinha'})}\n      primed=true\n      const Gd=d2.data('guests');if(Gd&&!Gd.loading){for(const g of (Gd.records()||[])){if(!g._id)continue;const k=g.rsvpAt||'',prev=gseen.get(g._id);gseen.set(g._id,k)\n        if(!gprimed||prev===undefined||!k||prev===k)continue;const nm=String(g.name||'').split(' (')[0]\n        if(g.status==='confirmado')notify({text:`🎉 ${nm} confirmou presença!`,sub:g.rsvpNote&&g.rsvpNote!=='undefined'?`“${String(g.rsvpNote).slice(0,120)}”`:'pelo convite 💌',go:'guests',mood:'festeiro'})\n        else if(g.status==='não vem')notify({text:`😢 ${nm} não vai conseguir ir`,sub:g.rsvpNote&&g.rsvpNote!=='undefined'?`“${String(g.rsvpNote).slice(0,120)}”`:'respondeu pelo convite',go:'guests',mood:'pidao'})}\n        gprimed=true}})\n    const poll=setInterval(()=>{for(const k of ['tasks','messages','guests','settings']){try{const h=d2.data(k);h&&h.loadAll()}catch(e){}}},30000)\n    d2.onUnmount(()=>clearInterval(poll))\n    d2.on('.mbub','click',(e,el)=>{const g=el.dataset.go;d2.state.note=null;if(g)go(g)})\n    let bk=0\n    d2.on('.milo','click',()=>{if(d2.state.note)return\n      const days=Math.max(0,Math.ceil((PARTY.getTime()-Date.now())/86400000))\n      const qs=(d2.data('quotes')&&d2.data('quotes').records())||[],chosen=qs.filter(q=>q.chosen).reduce((a,q)=>a+(Number(q.price)||0),0)\n      const set=((d2.data('settings')&&d2.data('settings').records())||[]).find(r=>r.key==='party'),cap=Number(set&&set.value&&set.value.budgetCap)||15000\n      const brl=(n)=>new Intl.NumberFormat('pt-BR',{style:'currency',currency:'BRL',maximumFractionDigits:0}).format(n)\n      const open=((d2.data('tasks')&&d2.data('tasks').records())||[]).filter(t=>['pendente','em andamento'].includes(t.status||'pendente')).length\n      const B=[['Au! 🐾','radiante'],[`Faltam ${days} dias pra festa 🎂`,'festeiro'],[`Já escolhemos ${brl(chosen)} de ${brl(cap)} 💸`,'surpreso'],[open?`Tem ${open} task${open>1?'s':''} na fila do Claude 📋`:'Fila de tasks zerada ✨','piscadinha'],['Cadê meu petisco? 🦴','pidao'],['*abana o rabo*','apaixonado']]\n      const [text,mood]=B[bk++%B.length];notify({text,mood})})\n    // 🐕💬 easter egg: o Milo tagarela sozinho de vez em quando (3–8 min). Dois toques nele = modo quietinho.\n    const QUIET='kp-milo-quiet',isQuiet=()=>{try{return localStorage.getItem(QUIET)==='1'}catch(e){return false}}\n    const pick=(a)=>a[Math.floor(Math.random()*a.length)]\n    const R=(k)=>{const h=d2.data(k);return (h&&h.records())||[]}\n    const chatter=()=>{\n      const now=new Date(),h=now.getHours(),dow=now.getDay(),days=Math.max(0,Math.ceil((PARTY.getTime()-Date.now())/86400000))\n      if(days===0)return pick(['É HOJE!!! 🎂🎉🐕','HOJE TEM FESTA!!! Já tô de gravatinha 🎀','Parabéns, Katia!!! mil lambeijos pra você 💗🐾'])\n      const me=NAMES[who(d2)]||'',tab=d2.state.tab||'summary'\n      const G=R('guests'),conf=G.filter(g=>g.status==='confirmado').length,duv=G.filter(g=>g.status==='em dúvida').length,inv=G.filter(g=>g.status==='convidado').length\n      const qs=R('quotes'),chosen=qs.filter(q=>q.chosen).reduce((a,q)=>a+(Number(q.price)||0),0)\n      const set=R('settings').find(r=>r.key==='party'),cap=Number(set&&set.value&&set.value.budgetCap)||15000,pct=Math.round(chosen/cap*100)\n      const open=R('tasks').filter(t=>['pendente','em andamento'].includes(t.status||'pendente')).length\n      const L=['Se sobrar espetinho, vocês sabem onde me encontrar 🍢👀','Lembrete importante: shibas também são convidados VIP 🐕✨','Será que rola um bolinho de patê pra mim? 🎂🐾',\n        'Eu cuido da portaria da festa. Só entra quem trouxer petisco 🦴','Tô treinando minha pose pro painel de fotos 📸','Balões: lindos. Balão estourando: meu pior pesadelo 🎈😱',\n        'Sabia que shiba sorri? Olha esse sorrisão 😁','*cheira o orçamento* hmm… cheirinho de festa boa 💸','Tô aqui no cantinho fingindo que não tô vendo vocês trabalharem 👀',\n        'Dica de shiba: bebe uma água aí 💧','Já pensaram na playlist? Eu voto em latido lo-fi 🎶','Se precisar de mim, é só chamar. Ou abrir um pacote de biscoito 🍪',\n        'Fato: festa com cachorro é 37% mais feliz. Fonte: eu 📊🐕',`Faltam ${days} dias e eu já tô abanando o rabo 🎂`,\n        `${G.length} convidados = ${G.length} pessoas pra me fazer carinho 🥹`,`Orçamento em ${pct}% do teto. Tô de olho, hein? 🧐`]\n      if(conf>2)L.push(`Já são ${conf} confirmados! Mais um e eu dou uma voltinha 🌀`)\n      if(duv)L.push(`Tem ${duv} convidados em dúvida… quer que eu decida no cara ou coroa? 🪙`)\n      if(!inv&&G.length)L.push('Psiu… ninguém foi convidado ainda. Bora mandar os convites? 💌')\n      const est=R('items').filter(i=>i.estimate).map(i=>i.name)\n      if(est.length)L.push(`Lembrete: ${est.join(' e ')} ainda ${est.length>1?'estão':'está'} com valor estimado. Quando souberem o real, me avisa! 🧾`)\n      if(open)L.push(`Tem ${open} task${open>1?'s':''} na fila do Claude. Ele é rápido, mas não mais que eu atrás de bolinha 🎾`)\n      if(me==='Katia')L.push('Katia, você vai arrasar na festa! 💗','Aniversariante não trabalha! Deixa que eu e o Danilo cuidamos 😌')\n      if(me==='Danilo')L.push('Danilo, já falou hoje que a Katia é incrível? Fala aí 💗','Organizador do ano: Danilo 🏆 (patrocínio: Milo)')\n      if(h>=23||h<6)L.push('Zzz… sonhando com espetinho de queijo coalho 💤','Ainda acordado? Até eu já tô de pijama 🌙','Psiu, tá tarde… amanhã a gente continua? 😴')\n      else if(h<11)L.push('Bom dia! Já tomei meu café (era água) ☀️','Bom dia! Já levei vocês pra passear… ah não, é o contrário 🦮')\n      else if(h<14)L.push('Hora do almoço? Divide comigo? 🍽️🥺')\n      else if(h>=18)L.push('Fim de tarde é hora de passeio, só dizendo 🌇🦮')\n      if(dow===5)L.push('Sextou! Bora organizar a festa ou… só curtir? 🎉')\n      if(dow===1)L.push('Segunda-feira… até eu fico com preguiça 🥱')\n      if(dow===0||dow===6)L.push('Fim de semana bom tem passeio no parque, hein? 🌳')\n      if(days<=7)L.push('Falta só UMA semana!!! 🙀','Contagem final! Já tô escovando o pelo 🪮')\n      else if(days<=30)L.push('Menos de um mês! Contagem regressiva ativada ⏳')\n      const T={budget:['Escolhe o que tiver mais bacon… digo, mais custo-benefício 🥓','Cadê a cotação de petiscos? Esqueceram de mim? 🦴'],\n        guests:['Pode pôr meu nome na lista? Milo, nº 118 🐕','Conferindo a lista… cadê o nome do carteiro? (brincadeira, odeio o carteiro) 📮'],\n        chat:['Pode falar que eu anoto tudinho 📝','Prometo não comer as tasks 🙊'],art:['Me desenha de chapéu de festa? Por favor? 🥺🎨','Eu posaria pra um quadro, só dizendo 🖼️'],\n        summary:['Tá tudo indo bem! Eu acho. Sou um cachorro 🐕']}[tab]\n      if(T)L.push(...T,...T)\n      if(Math.random()<.06)return pick(['Psiu… segredo: toca 5 vezes no logo lá em cima 😉','Dica secreta: na tela de login, toca 5 vezes em mim 💗','Easter egg desbloqueado: você leu isso. Parabéns 🏅'])\n      return pick(L)}\n    let ct;const schedule=(first)=>{ct=setTimeout(tick,(first?90+Math.random()*90:180+Math.random()*300)*1000)}\n    const moodOf=(t)=>/HOJE|Parabéns/.test(t)?'festeiro':/petisco|fome|carinho/i.test(t)?'pidao':/segredo|secreta|Easter/i.test(t)?'surpreso':/💗|amo|❤/.test(t)?'apaixonado':pick(['feliz','piscadinha','radiante'])\n    const tick=()=>{if(!document.hidden&&!d2.state.note&&!showing&&!isQuiet()){const text=chatter();notify({text,mood:moodOf(text)})}schedule()}\n    schedule(true);d2.onUnmount(()=>clearTimeout(ct))\n    d2.on('.milo','dblclick',()=>{const q=!isQuiet();try{localStorage.setItem(QUIET,q?'1':'0')}catch(e){}\n      queue.length=0;d2.state.note=null;showing=false;notify({text:q?'Tá bom, fico quietinho 🤐':'Voltei a tagarelar! 🐕💬',sub:q?'dois toques em mim pra eu voltar a falar (aviso de task continua aparecendo)':'',mood:q?'dormindo':'radiante'})})\n    d2.on('.m-milo','click',()=>{d2.setState({menu:false,picker:true})})\n    d2.on('.m-theme','click',async()=>{const order=['auto','claro','escuro'],nx=order[(order.indexOf(themeOf(d2))+1)%3]\n      try{localStorage.setItem('kp-theme',nx)}catch(err){};d2.state.themeTick=Date.now()\n      try{await savePref(d2,{theme:nx})}catch(err){toast('Salvei só neste aparelho 😕')}})\n    const mq=window.matchMedia&&matchMedia('(prefers-color-scheme: dark)'),onMq=()=>{d2.state.themeTick=Date.now()}\n    if(mq&&mq.addEventListener){mq.addEventListener('change',onMq);d2.onUnmount(()=>mq.removeEventListener('change',onMq))}\n    if(miloSet(d2)==='chibi')Object.keys(MC).forEach(k=>{const i=new Image();i.src=mcUrl(k)})\n    d2.on('.pclose','click',()=>{d2.state.picker=false})\n    d2.on('.pick','click',(e)=>{if(e.target.classList&&e.target.classList.contains('pick'))d2.state.picker=false})\n    d2.on('.pk','click',async(e,el)=>{const v=el.dataset.set;try{localStorage.setItem('kp-milo-set',v)}catch(err){}\n      d2.state.picker=false\n      try{await savePref(d2,{milo:v})}catch(err){toast('Salvei só neste aparelho 😕')}\n      queue.length=0;showing=false;notify({text:'Gostou do meu visual novo? 💅',mood:'radiante'})})\n    d2.on('.me','click',(e)=>{if(e.target.closest('.menu'))return;d2.state.menu=!d2.state.menu})\n    d2.on(document,'click',(e)=>{if(d2.state.menu&&!e.composedPath().some(n=>n.classList&&n.classList.contains('me')))d2.state.menu=false})\n    d2.on('.m-out','click',async()=>{const a=d2.auth(d2.param('auth'));try{await a.logout(a.session)}catch(e){}try{localStorage.removeItem('__data2-session-katia-party')}catch(e){}window.location.replace(window.location.pathname)})\n    // 🔄 atualizar: derruba o service worker (que pode servir o bundle antigo) e recarrega\n    d2.on('.rf','click',async()=>{try{const r=navigator.serviceWorker?await navigator.serviceWorker.getRegistrations():[];for(const x of r)await x.unregister()}catch(e){}window.location.reload()})\n    d2.on('.m-pass','click',async()=>{\n      d2.state.menu=false\n      const email=who(d2)\n      if(!email)return toast('Não achei seu email 😕')\n      try{await d2.rush(d2.param('requestReset')).invoke({email});toast(`Link pra trocar a senha enviado pra ${email} ✉️`)}catch(e){toast('Ops, não consegui enviar agora.')}\n    })\n    // easter egg: 5 toques no logo = chuva de shibas\n    let n=0,tm\n    d2.on('.logo','click',()=>{n++;clearTimeout(tm);tm=setTimeout(()=>{n=0},1600);if(n<5)return;n=0\n      toast('au au au! 🐕🐕🐕')\n      for(let i=0;i<22;i++){const w=document.createElement('div');w.className='rain';w.innerHTML=miloSvg(d2,pick(['festeiro','radiante','apaixonado','piscadinha']));w.style.left=(Math.random()*96)+'vw';w.style.animationDuration=(2.6+Math.random()*2.4)+'s';w.style.animationDelay=(Math.random()*1.4)+'s';d2.root.appendChild(w);setTimeout(()=>w.remove(),7000)}\n    })\n  },\n  updated(d2){const f=SCAN.get(d2.root);if(f)f()},\n}\n"}},"auth":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"auth"}}}},"requestReset":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"requestReset"}}}},"items":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"items"}}}},"quotes":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"quotes"}}}},"guests":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"guests"}}}},"messages":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"messages"}}}},"tasks":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"tasks"}}}},"settings":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"settings"}}}},"artworks":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"artworks"}}}},"scribe":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"scribe"}}}},"artist":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"artist"}}}},"drive":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"drive"}}}},"vSummary":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"vSummary"}}}},"vBudget":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"vBudget"}}}},"vGuests":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"vGuests"}}}},"vChat":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"vChat"}}}},"vArt":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"vArt"}}}}}}}}}},{"_id":"6abefd25492457561460c69b","component":"data2-core-types@Component","system":"6abed5371a6b03943b9618d7","params":{"extends":"data2-core-primitives@Block","component":"kp-budget","package":"katia-party","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"// kp-budget — itens do orçamento + cotações (comparar, escolher ⭐, total vs teto ajustável)\n// params: items quotes settings (dataset), drive (service), uploader (rush → @upload-file), me (string)\nfunction esc(s){return String(s??'').replace(/[&<>\"]/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c]))}\nconst BRL=(n)=>new Intl.NumberFormat('pt-BR',{style:'currency',currency:'BRL',maximumFractionDigits:(Number(n)||0)%1?2:0}).format(Number(n)||0)\nconst num=(v)=>{let s=String(v??'').replace(/[^\\d,.-]/g,'');if(s.includes(','))s=s.replace(/\\./g,'').replace(',','.');const n=parseFloat(s);return isNaN(n)?0:n}\nconst recs=(d2,k)=>{const h=d2.data(k);return h?h.records()||[]:[]}\nconst toast=(d2,m)=>d2.bus.emit('kp:toast',m)\n// upload via Rush `upload-file` (o Drive recusa upload direto de usuário final). Imagens são reduzidas antes.\nasync function toB64(file){if(/^image\\/(png|jpe?g|webp)$/i.test(file.type||'')){try{const bmp=await createImageBitmap(file);const k=Math.min(1,1920/Math.max(bmp.width,bmp.height));const c=document.createElement('canvas');c.width=Math.round(bmp.width*k);c.height=Math.round(bmp.height*k);const g=c.getContext('2d');g.fillStyle='#fff';g.fillRect(0,0,c.width,c.height);g.drawImage(bmp,0,0,c.width,c.height);const du=c.toDataURL('image/jpeg',0.85);return {base64:du.split(',')[1],contentType:'image/jpeg',fileName:String(file.name||'foto').replace(/\\.[^.]+$/,'')+'.jpg'}}catch(e){}}\n  const du=await new Promise((res,rej)=>{const r=new FileReader();r.onload=()=>res(r.result);r.onerror=rej;r.readAsDataURL(file)});return {base64:String(du).split(',')[1],contentType:file.type||'application/octet-stream',fileName:file.name||'arquivo'}}\nasync function shrink(file){if(!/^image\\/(png|jpe?g|webp)$/i.test(file.type||''))return file;const p=await toB64(file);if(p.contentType!=='image/jpeg')return file;const bin=atob(p.base64),u8=new Uint8Array(bin.length);for(let i=0;i<bin.length;i++)u8[i]=bin.charCodeAt(i);return new File([u8],p.fileName,{type:'image/jpeg'})}\n// 1º upload direto no Drive (presigned S3, sem limite prático; liberado pela DrivePolicy upload). 2º fallback: Rush (até ~1 MB, limite da Lambda).\nasync function uploadAll(d2,files){const out=[];for(const f0 of files){if(f0.size>25e6)throw new Error(`${f0.name}: muito grande (máx. 25 MB)`);const f=await shrink(f0);let url=''\n  try{const up=await d2.drive(d2.param('drive')).upload([f]);const u=up&&up[0];url=(u&&(u.fileUrl||u.url))||''}catch(e){}\n  if(!url&&f.size<9e5){const p=await toB64(f);const r=await d2.rush('upload-file').invoke(p);const d=r&&r.data?r.data:r;url=(d&&d.url)||''}\n  if(!url)throw new Error(`${f0.name}: não consegui enviar`)\n  out.push({url,name:f0.name||f.name,type:f.type})}return out}\nconst STATUS={pendente:['c-pend','sem cotação'],cotando:['c-cot','cotando'],fechado:['c-ok','fechado']}\nconst GLYPHS=['🍽️','⛺','🎂','🪑','🎈','🧁','📸','🧵','🎶','🌸','🍰','🥂','🍹','💡','🎁','🚐','🧑‍🍳','🪅','🕯️','🧊','🎤','👗','💐','✨']\n\nexport default {\n  css:`\n:host{--bg:var(--k-bg,#FFF7F5);--card:var(--k-card,#FFFFFF);--blush-50:var(--k-blush-50,#FFF1F2);--blush-100:var(--k-blush-100,#FDE4E7);--blush-200:var(--k-blush-200,#F9CDD4);--blush-300:var(--k-blush-300,#F2AEBA);--rose:var(--k-rose,#D9879A);--rose-deep:var(--k-rose-deep,#B8647A);--ink:var(--k-ink,#4A3439);--muted:var(--k-muted,#94797E);--line:var(--k-line,#F3DDE0);--peach:var(--k-peach,#FDE3D3);--sage:var(--k-sage,#DCEBDD);--sage-ink:var(--k-sage-ink,#4F7A57);--butter:var(--k-butter,#FFF2C9);--butter-ink:var(--k-butter-ink,#8A6D1F);--lilac:var(--k-lilac,#ECE3F6);--lilac-ink:var(--k-lilac-ink,#6B5390);--shadow:var(--k-shadow,0 6px 24px rgba(184,100,122,.12))}\n*{box-sizing:border-box}\n.wrap{height:100%;overflow:auto;padding:28px clamp(16px,3vw,40px) 90px;font-family:'Nunito',system-ui,sans-serif;color:var(--ink)}\n.inner{max-width:1120px;margin:0 auto;display:grid;gap:18px}\n.head{display:flex;align-items:flex-end;gap:12px;flex-wrap:wrap}\n.head h2{font:600 30px/1 'Fredoka';margin:0;flex:1;min-width:200px}\n.head p{margin:6px 0 0;color:var(--muted);font-weight:700;font-size:14px}\n.btn{border:0;border-radius:14px;padding:11px 16px;font:600 15px 'Fredoka';cursor:pointer;background:linear-gradient(135deg,#E79AAB,#D9879A);color:#fff;box-shadow:0 6px 16px rgba(217,135,154,.3);white-space:nowrap}\n.btn:active{transform:scale(.97)}.btn[disabled]{opacity:.55}\n.ghost{border:1.5px solid var(--line);background:var(--card);color:var(--ink);box-shadow:none}\n.ghost:hover{border-color:var(--blush-300)}\n.danger{background:var(--card);color:#B4475F;border:1.5px solid #F5C9D2;box-shadow:none}\n.sm{padding:7px 11px;font-size:13px;border-radius:11px}\n.sum{display:grid;grid-template-columns:1.4fr 1fr 1fr;gap:14px;background:var(--card);border:1px solid var(--line);border-radius:24px;padding:20px 22px;box-shadow:var(--shadow)}\n.sum .k{font-weight:800;font-size:12px;letter-spacing:.4px;text-transform:uppercase;color:var(--muted)}\n.sum .v{font:600 30px/1.1 'Fredoka';margin-top:6px}\n.sum .v small{font:700 15px 'Nunito';color:var(--muted)}\n.cap{cursor:pointer;border-bottom:1.5px dashed var(--blush-300)}\n.capin{width:140px;border:1.5px solid var(--blush-300);border-radius:10px;padding:4px 8px;font:700 15px 'Nunito';color:var(--ink)}\n.bar{height:12px;border-radius:999px;background:var(--blush-50);overflow:hidden;margin-top:12px;position:relative}\n.bar i{position:absolute;left:0;top:0;bottom:0;border-radius:999px;background:linear-gradient(90deg,#F2AEBA,#D9879A);transition:width .5s}\n.bar i.proj{background:repeating-linear-gradient(45deg,#FDE4E7 0 6px,#F9CDD4 6px 12px);transition:width .5s}\n.bar i.warn{background:linear-gradient(90deg,#F7C59F,#E8956B)}.bar i.over{background:linear-gradient(90deg,#EE9AA5,#C9506B)}\n.legend{display:flex;gap:14px;margin-top:8px;font-size:12px;font-weight:700;color:var(--muted);flex-wrap:wrap}\n.legend span:before{content:'';display:inline-block;width:10px;height:10px;border-radius:3px;margin-right:5px;vertical-align:-1px;background:#D9879A}\n.legend span.p:before{background:#F9CDD4}\n.filters{display:flex;gap:8px;flex-wrap:wrap}\n.f{border:1.5px solid var(--line);background:var(--card);border-radius:999px;padding:7px 13px;font:700 13px 'Nunito';color:var(--ink);cursor:pointer}\n.f[data-on]{background:var(--blush-100);border-color:var(--blush-300);color:var(--rose-deep)}\n.list{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:14px}\n.item{background:var(--card);border:1px solid var(--line);border-radius:22px;padding:16px;box-shadow:var(--shadow);cursor:pointer;display:grid;grid-template-columns:auto 1fr;gap:12px;align-items:center;transition:transform .15s,box-shadow .15s}\n.item:hover{transform:translateY(-2px);box-shadow:0 12px 30px rgba(184,100,122,.18)}\n.em{width:48px;height:48px;border-radius:16px;background:var(--blush-50);display:grid;place-items:center;font-size:24px}\n.item .n{font:600 17px/1.2 'Fredoka';margin-bottom:5px}\n.item .d{font-size:13px;color:var(--muted);font-weight:700}\n.item .d b{color:var(--ink)}\n.chip{display:inline-block;font-weight:800;font-size:11px;border-radius:999px;padding:3px 9px;white-space:nowrap;margin-bottom:6px}\n.c-pend{background:var(--blush-100);color:var(--rose-deep)}.c-cot{background:var(--butter);color:var(--butter-ink)}.c-ok{background:var(--sage);color:var(--sage-ink)}.c-free{background:var(--lilac);color:var(--lilac-ink)}.c-est{background:var(--card);color:var(--rose-deep);border:1.5px dashed var(--rose)}\n.card{background:var(--card);border:1px solid var(--line);border-radius:24px;padding:20px;box-shadow:var(--shadow)}\n.back{display:inline-flex;align-items:center;gap:6px;font:700 14px 'Nunito';color:var(--rose-deep);cursor:pointer;border:0;background:none;padding:0}\n.dh{display:grid;grid-template-columns:auto 1fr auto;gap:14px;align-items:center}\n.dh .em{width:64px;height:64px;font-size:32px;border-radius:20px;cursor:pointer}\n.dh h2{font:600 26px/1.15 'Fredoka';margin:0}\n.dh .meta{color:var(--muted);font-weight:700;font-size:13px;margin-top:4px}\n.glyphs{display:flex;flex-wrap:wrap;gap:6px;margin-top:12px}\n.glyphs button{width:40px;height:40px;border-radius:12px;border:1px solid var(--line);background:var(--card);font-size:20px;cursor:pointer}\n.quotes{display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:14px}\n.q{position:relative;background:var(--card);border:1.5px solid var(--line);border-radius:22px;padding:18px;display:flex;flex-direction:column;gap:6px;box-shadow:var(--shadow);min-width:0}\n.q[data-chosen]{border-color:#E7A2B1;background:var(--k-card2,linear-gradient(180deg,#FFF5F6,#fff));box-shadow:0 12px 34px rgba(217,135,154,.28)}\n.q .ven{font:600 18px 'Fredoka';padding-right:70px;word-break:break-word}\n.q .pr{font:600 28px 'Fredoka';color:var(--rose-deep)}\n.q .ln{font-size:13px;font-weight:700;color:var(--muted);word-break:break-word}\n.q .ln a{color:var(--rose-deep)}\n.q .tags{position:absolute;top:14px;right:14px;display:flex;flex-direction:column;align-items:flex-end;gap:4px}\n.q .tag{font-weight:800;font-size:11px;border-radius:999px;padding:3px 8px;background:var(--sage);color:var(--sage-ink)}\n.q .tag.star{background:var(--blush-100);color:var(--k-plum,#8E4258)}\n.q .cmp{height:8px;border-radius:999px;background:var(--blush-50);overflow:hidden;margin:4px 0}\n.q .cmp i{display:block;height:100%;background:var(--blush-300);border-radius:999px}\n.q .acts{display:flex;gap:6px;flex-wrap:wrap;margin-top:auto;padding-top:8px}\n.files{display:flex;gap:6px;flex-wrap:wrap}\n.files a{font-size:12px;font-weight:800;color:var(--lilac-ink);background:var(--lilac);border-radius:8px;padding:3px 8px;text-decoration:none;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\nform.qf{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}\nform.qf .full{grid-column:1/-1}\nlabel{display:block;font-weight:800;font-size:12px;color:var(--muted);margin-bottom:4px}\ninput,textarea,select{width:100%;border:1.5px solid var(--line);background:var(--blush-50);border-radius:12px;padding:10px 12px;font:600 14px 'Nunito';color:var(--ink);outline:none}\ninput:focus,textarea:focus,select:focus{border-color:var(--blush-300);background:var(--card)}\ntextarea{resize:vertical;min-height:70px}\n.row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}\n.sect{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap}\n.sect h3{font:600 20px 'Fredoka';margin:0}\n.empty{text-align:center;color:var(--muted);font-weight:700;padding:26px 10px;border:2px dashed var(--line);border-radius:22px;background:var(--card)}\n.empty .z{font-size:34px;display:block;margin-bottom:6px}\n.switch{display:flex;align-items:center;gap:8px;font-weight:800;font-size:13px;cursor:pointer;user-select:none}\n.switch input{width:auto}\n.notes{width:100%}\n@media (max-width:760px){.sum{grid-template-columns:1fr 1fr}.sum>div:first-child{grid-column:1/-1}form.qf{grid-template-columns:1fr}.dh{grid-template-columns:auto 1fr}.dh .acts{grid-column:1/-1}.wrap{padding-top:18px}.head h2{font-size:26px}}\n`,\n  render(d2){\n    const s=d2.state\n    const items=recs(d2,'items').slice().sort((a,b)=>(a.sort??999)-(b.sort??999))\n    const quotes=recs(d2,'quotes')\n    const settings=recs(d2,'settings'),setRec=settings.find(r=>r.key==='party')||{}\n    const cap=Number((setRec.value||{}).budgetCap)||15000\n    const byItem={};for(const q of quotes){(byItem[q.itemId]=byItem[q.itemId]||[]).push(q)}\n    const statusOf=(it)=>{const qs=byItem[it._id]||[];return it.free||qs.some(q=>q.chosen)?'fechado':qs.length?'cotando':'pendente'}\n    let chosen=0,proj=0,closed=0\n    for(const it of items){const qs=byItem[it._id]||[];const c=qs.find(q=>q.chosen)\n      if(c){chosen+=num(c.price);proj+=num(c.price);closed++}else if(it.free)closed++;else if(qs.length)proj+=Math.min(...qs.map(q=>num(q.price)))}\n    const pct=cap?Math.min(100,chosen/cap*100):0,ppct=cap?Math.min(100,proj/cap*100):0\n    const cls=chosen>cap?'over':pct>=85?'warn':''\n    const left=cap-chosen\n    const open=s.open&&items.find(i=>i._id===s.open)\n\n    if(open){\n      const it=open,qs=(byItem[it._id]||[]).slice().sort((a,b)=>num(a.price)-num(b.price))\n      const max=Math.max(1,...qs.map(q=>num(q.price))),min=qs.length?num(qs[0].price):0\n      const st=statusOf(it)\n      const form=(q)=>`<form class=\"qf card\" data-id=\"${esc(q?q._id:'')}\">\n          <div class=\"full sect\"><h3>${q?'Editar cotação':'Nova cotação'}</h3></div>\n          <div><label>Fornecedor</label><input name=\"vendor\" value=\"${esc(q?q.vendor:'')}\" placeholder=\"Ex.: Buffet da Dona Maria\" required/></div>\n          <div><label>Valor (R$)</label><input name=\"price\" inputmode=\"decimal\" value=\"${q?esc(String(q.price??'').replace('.',',')):''}\" placeholder=\"3.500,00\" required/></div>\n          <div><label>Contato</label><input name=\"contact\" value=\"${esc(q?q.contact:'')}\" placeholder=\"(11) 9…  /  @insta\"/></div>\n          <div><label>Link</label><input name=\"link\" value=\"${esc(q?q.link:'')}\" placeholder=\"https://…\"/></div>\n          <div class=\"full\"><label>Observações (o que inclui, prazos, condições…)</label><textarea name=\"notes\">${esc(q?q.notes:'')}</textarea></div>\n          <div class=\"full\"><label>Anexos (PDF, print, foto)</label><input name=\"files\" type=\"file\" multiple accept=\"image/*,application/pdf\"/></div>\n          <div class=\"full row\"><button class=\"btn\" type=\"submit\" ${s.busy?'disabled':''}>${s.busy?'Salvando…':'Salvar cotação'}</button><button class=\"btn ghost cancel-q\" type=\"button\">Cancelar</button></div>\n        </form>`\n      return `<div class=\"wrap\"><div class=\"inner\">\n        <button class=\"back\" type=\"button\">← Todos os itens</button>\n        <div class=\"card\"><div class=\"dh\">\n          <div class=\"em pick-glyph\" title=\"Trocar emoji\">${esc(it.glyph||'✨')}</div>\n          <div><h2>${esc(it.name)}</h2><div class=\"meta\"><span class=\"chip ${it.free?'c-free':STATUS[st][0]}\">${it.free?'grátis 💜':STATUS[st][1]}</span>${it.estimate?'<span class=\"chip c-est\">≈ estimativa</span>':''} ${qs.length} cotaç${qs.length===1?'ão':'ões'}${qs.length>1?` · de ${BRL(min)} a ${BRL(max)}`:''}</div></div>\n          <div class=\"row acts\"><button class=\"btn ghost sm rename\">✏️ Renomear</button><button class=\"btn danger sm del-item\">Excluir</button></div>\n        </div>\n        ${s.glyphs?`<div class=\"glyphs\">${GLYPHS.map(g=>`<button type=\"button\" class=\"g\" data-g=\"${g}\">${g}</button>`).join('')}</div>`:''}\n        <div style=\"margin-top:14px\" class=\"row\"><label class=\"switch\"><input type=\"checkbox\" class=\"free\" ${it.free?'checked':''}/> Item gratuito / já resolvido sem custo</label></div>\n        <div style=\"margin-top:8px\" class=\"row\"><label class=\"switch\"><input type=\"checkbox\" class=\"est\" ${it.estimate?'checked':''}/> Valor é estimativa (lembrar de colocar o real)</label></div>\n        <div style=\"margin-top:12px\"><label>Anotações do item</label><textarea class=\"notes\" data-id=\"${esc(it._id)}\" placeholder=\"Ideias, requisitos, quantidade de pessoas…\">${esc(it.notes||'')}</textarea></div>\n        </div>\n        <div class=\"sect\"><h3>Cotações</h3>${s.editing?'':'<button class=\"btn new-q\">+ Cotação</button>'}</div>\n        ${s.editing==='new'?form(null):''}\n        ${qs.length?`<div class=\"quotes\">${qs.map((q,i)=>s.editing===q._id?form(q):`\n          <div class=\"q\" data-key=\"${esc(q._id||'p'+i)}\" ${q.chosen?'data-chosen':''}>\n            <div class=\"tags\">${q.chosen?'<span class=\"tag star\">⭐ escolhida</span>':''}${qs.length>1&&num(q.price)===min?'<span class=\"tag\">mais barata</span>':''}</div>\n            <div class=\"ven\">${esc(q.vendor||'Sem nome')}</div>\n            <div class=\"pr\">${BRL(q.price)}</div>\n            ${qs.length>1?`<div class=\"cmp\"><i style=\"width:${Math.round(num(q.price)/max*100)}%\"></i></div>`:''}\n            ${q.contact?`<div class=\"ln\">📞 ${esc(q.contact)}</div>`:''}\n            ${q.link?`<div class=\"ln\">🔗 <a href=\"${esc(q.link)}\" target=\"_blank\" rel=\"noopener\">${esc(q.link.replace(/^https?:\\/\\//,'').slice(0,40))}</a></div>`:''}\n            ${q.notes?`<div class=\"ln\" style=\"white-space:pre-wrap\">${esc(q.notes)}</div>`:''}\n            ${(q.attachments||[]).length?`<div class=\"files\">${q.attachments.map(a=>`<a href=\"${esc(a.url)}\" target=\"_blank\" rel=\"noopener\">📎 ${esc(a.name||'arquivo')}</a>`).join('')}</div>`:''}\n            <div class=\"acts\">\n              <button class=\"btn sm ${q.chosen?'ghost':''} choose\" data-id=\"${esc(q._id)}\">${q.chosen?'Desmarcar':'⭐ Escolher'}</button>\n              <button class=\"btn ghost sm edit-q\" data-id=\"${esc(q._id)}\">Editar</button>\n              <button class=\"btn danger sm del-q\" data-id=\"${esc(q._id)}\">Excluir</button>\n            </div>\n          </div>`).join('')}</div>`:(s.editing?'':`<div class=\"empty\"><span class=\"z\">🐕💤</span>Nenhuma cotação ainda. Adicione aqui ou mande pro Milo no chat!</div>`)}\n      </div></div>`\n    }\n\n    const f=s.filter||'todos'\n    const shown=items.filter(it=>f==='todos'||statusOf(it)===f)\n    const counts={todos:items.length,pendente:0,cotando:0,fechado:0};for(const it of items)counts[statusOf(it)]++\n    return `<div class=\"wrap\"><div class=\"inner\">\n      <div class=\"head\"><div style=\"flex:1;min-width:200px\"><h2>Orçamento 💸</h2><p>Lance os itens, registre as cotações e marque a ⭐ escolhida.</p></div><button class=\"btn new-item\">+ Item</button></div>\n      <div class=\"sum\">\n        <div><div class=\"k\">Total escolhido</div>\n          <div class=\"v\">${BRL(chosen)} <small>de ${s.capEdit?`<input class=\"capin\" inputmode=\"decimal\" value=\"${esc(String(cap))}\"/>`:`<span class=\"cap\" title=\"Clique para ajustar o teto\">${BRL(cap)}</span>`}</small></div>\n          <div class=\"bar\"><i class=\"proj\" style=\"width:${ppct}%\"></i><i class=\"${cls}\" style=\"width:${pct}%\"></i></div>\n          <div class=\"legend\"><span>escolhido</span><span class=\"p\">projeção (escolhidas + mais baratas)</span></div></div>\n        <div><div class=\"k\">${left>=0?'Ainda cabe':'Estourou'}</div><div class=\"v\" style=\"color:${left>=0?'var(--sage-ink)':'#B4475F'}\">${BRL(Math.abs(left))}</div></div>\n        <div><div class=\"k\">Projeção</div><div class=\"v\">${BRL(proj)}</div><div class=\"legend\" style=\"margin-top:4px\">${closed}/${items.length} itens fechados</div></div>\n      </div>\n      ${s.newItem?`<form class=\"ni card row\"><input name=\"name\" placeholder=\"Nome do item (ex.: Fotógrafo)\" required style=\"flex:1;min-width:180px\"/><button class=\"btn\" type=\"submit\">Adicionar</button><button class=\"btn ghost cancel-ni\" type=\"button\">Cancelar</button></form>`:''}\n      <div class=\"filters\">${[['todos','Todos'],['pendente','Sem cotação'],['cotando','Cotando'],['fechado','Fechados']].map(([k,l])=>`<button class=\"f\" data-f=\"${k}\" ${f===k?'data-on':''}>${l} · ${counts[k]}</button>`).join('')}</div>\n      ${shown.length?`<div class=\"list\">${shown.map((it,i)=>{const qs=byItem[it._id]||[],c=qs.find(q=>q.chosen),st=statusOf(it)\n        const mn=qs.length?Math.min(...qs.map(q=>num(q.price))):0,mx=qs.length?Math.max(...qs.map(q=>num(q.price))):0\n        return `<div class=\"item\" data-key=\"${esc(it._id||'p'+i)}\" data-id=\"${esc(it._id)}\"><div class=\"em\">${esc(it.glyph||'✨')}</div><div style=\"min-width:0\">\n          <span class=\"chip ${it.free?'c-free':STATUS[st][0]}\">${it.free?'grátis 💜':STATUS[st][1]}</span>${it.estimate?'<span class=\"chip c-est\">≈ estimativa</span>':''}\n          <div class=\"n\">${esc(it.name)}</div>\n          <div class=\"d\">${c?`⭐ ${esc(c.vendor||'')} · <b>${BRL(c.price)}</b>`:it.free?'Sem custo 🎉':qs.length?`${qs.length} cotaç${qs.length>1?'ões':'ão'} · <b>${qs.length>1?BRL(mn)+' – '+BRL(mx):BRL(mn)}</b>`:'Nenhuma cotação ainda'}</div></div></div>`}).join('')}</div>`\n        :`<div class=\"empty\"><span class=\"z\">🐕💤</span>Nada por aqui nesse filtro.</div>`}\n    </div></div>`\n  },\n  mounted(d2){\n    const s=d2.state\n    const I=()=>d2.data('items'),Q=()=>d2.data('quotes'),S=()=>d2.data('settings')\n    const pend=d2.shared.get('kp-open-item',null,{global:true});if(pend){s.open=pend;d2.shared.set('kp-open-item',null,{global:true})}\n    const openRec=()=>I().records().find(i=>i._id===s.open)\n    const saveItem=async(patch)=>{const it=openRec();if(!it)return;await I().update({...it,...patch})}\n    d2.on('.item','click',(e,el)=>d2.setState({open:el.dataset.id,editing:null,glyphs:false}))\n    d2.on('.back','click',()=>d2.setState({open:null,editing:null,glyphs:false}))\n    d2.on('.f','click',(e,el)=>{s.filter=el.dataset.f})\n    d2.on('.new-item','click',()=>{s.newItem=true;setTimeout(()=>{const i=d2.$('form.ni input');i&&i.focus()},30)})\n    d2.on('.cancel-ni','click',()=>{s.newItem=false})\n    d2.on('.cap','click',()=>{s.capEdit=true;setTimeout(()=>{const i=d2.$('.capin');i&&(i.focus(),i.select())},30)})\n    const saveCap=async()=>{const el=d2.$('.capin');if(!el)return;const v=num(el.value);s.capEdit=false;if(!v)return\n      const rec=S().records().find(r=>r.key==='party');if(rec)await S().update({...rec,value:{...(rec.value||{}),budgetCap:v}});else await S().create({key:'party',value:{budgetCap:v}})\n      toast(d2,`Teto ajustado pra ${BRL(v)} 💗`)}\n    d2.on('.capin','keydown',(e)=>{if(e.key==='Enter')saveCap();if(e.key==='Escape')s.capEdit=false})\n    d2.on('.capin','blur',()=>saveCap())\n    d2.on('.pick-glyph','click',()=>{s.glyphs=!s.glyphs})\n    d2.on('.g','click',async(e,el)=>{s.glyphs=false;await saveItem({glyph:el.dataset.g})})\n    d2.on('.rename','click',async()=>{const it=openRec();if(!it)return;const n=await d2.dialog.prompt('Novo nome do item',it.name);if(n&&n.trim())await saveItem({name:n.trim()})})\n    d2.on('.free','change',async(e,el)=>{await saveItem({free:el.checked,status:el.checked?'fechado':'pendente'});if(el.checked)toast(d2,'Item marcado como gratuito 💜')})\n    d2.on('.est','change',async(e,el)=>{await saveItem({estimate:el.checked});toast(d2,el.checked?'Marcado como estimativa ≈ (o Milo vai lembrar)':'Valor real ✓')})\n    d2.on('.notes','change',async(e,el)=>{await saveItem({notes:el.value});toast(d2,'Anotação salva ✍️')})\n    d2.on('.del-item','click',async()=>{const it=openRec();if(!it)return\n      if(!await d2.dialog.confirm(`Excluir \"${it.name}\" e todas as cotações dele?`))return\n      for(const q of Q().records().filter(q=>q.itemId===it._id))await Q().remove(q)\n      await I().remove(it);d2.setState({open:null});toast(d2,'Item excluído')})\n    d2.on('.new-q','click',()=>{s.editing='new'})\n    d2.on('.edit-q','click',(e,el)=>{s.editing=el.dataset.id})\n    d2.on('.cancel-q','click',()=>{s.editing=null})\n    d2.on('.del-q','click',async(e,el)=>{const q=Q().records().find(r=>r._id===el.dataset.id);if(!q)return\n      if(!await d2.dialog.confirm(`Excluir a cotação de \"${q.vendor||'sem nome'}\"?`))return\n      await Q().remove(q);toast(d2,'Cotação excluída')})\n    d2.on('.choose','click',async(e,el)=>{const id=el.dataset.id;const all=Q().records().filter(q=>q.itemId===s.open)\n      const target=all.find(q=>q._id===id);if(!target)return\n      const on=!target.chosen\n      for(const q of all){const want=on&&q._id===id;if(!!q.chosen!==want)await Q().update({...q,chosen:want})}\n      await saveItem({status:on?'fechado':'cotando'})\n      toast(d2,on?`⭐ ${target.vendor||'Cotação'} escolhida! ${BRL(target.price)}`:'Escolha desfeita')})\n    d2.on('form','submit',async(e,form)=>{e.preventDefault()\n      if(form.classList.contains('ni')){const name=new FormData(form).get('name');if(!String(name).trim())return\n        const max=Math.max(0,...I().records().map(i=>Number(i.sort)||0))\n        s.newItem=false;await I().create({name:String(name).trim(),glyph:'✨',status:'pendente',sort:max+1});toast(d2,'Item criado ✨');return}\n      if(!form.classList.contains('qf'))return\n      const fd=new FormData(form);const id=form.dataset.id\n      s.busy=true\n      try{\n        let attachments=[]\n        const files=form.querySelector('input[type=file]').files\n        if(files&&files.length){try{attachments=await uploadAll(d2,[...files])}catch(e){attachments=[]}\n          if(!attachments.length)toast(d2,'Os anexos não subiram 😕 salvei a cotação sem eles')}\n        const data={itemId:s.open,vendor:String(fd.get('vendor')||'').trim(),price:num(fd.get('price')),contact:String(fd.get('contact')||'').trim(),link:String(fd.get('link')||'').trim(),notes:String(fd.get('notes')||'').trim()}\n        if(id){const q=Q().records().find(r=>r._id===id);await Q().update({...q,...data,attachments:[...((q&&q.attachments)||[]),...attachments]})}\n        else{await Q().create({...data,chosen:false,attachments});const it=openRec();if(it&&!it.free&&it.status==='pendente')await saveItem({status:'cotando'})}\n        d2.setState({editing:null});toast(d2,'Cotação salva 💸')\n      }catch(err){toast(d2,'Não consegui salvar 😕 tenta de novo?')}\n      finally{s.busy=false}\n    })\n  },\n}\n"}},"items":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"items"}}}},"quotes":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"quotes"}}}},"settings":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"settings"}}}},"drive":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"drive"}}}},"me":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"me"}}}}}}}}}},{"_id":"6abefd26ba309d7a9fad110b","component":"data2-core-types@Component","system":"6abed5371a6b03943b9618d7","params":{"extends":"data2-core-primitives@Block","component":"kp-guests","package":"katia-party","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"// kp-guests — lista de convidados: lista corrida ordenada pelo nº (ou A–Z), adultos/crianças,\n// status (toque pra alternar), busca, filtro \"incertos\" com edição rápida do nome, colar lista.\n// params: guests settings (dataset), me (string)\nfunction esc(s){return String(s??'').replace(/[&<>\"]/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c]))}\nconst recs=(d2,k)=>{const h=d2.data(k);return h?h.records()||[]:[]}\nconst toast=(d2,m)=>d2.bus.emit('kp:toast',m)\nconst ST=['em dúvida','a convidar','convidado','provável','confirmado','não vem']\nconst GROUPS=['Família','Amigos','Salão','Extra']\nconst GC={'Família':'#F7C59F','Amigos':'#B9D8BF','Salão':'#CDB8EA','Extra':'#F2AEBA'}\nconst STC={'em dúvida':'c-duv','a convidar':'c-pend','convidado':'c-lil','provável':'c-prov','confirmado':'c-ok','não vem':'c-no'}\nconst ppl=()=>1 // cada convidado = 1 pessoa (convite individual)\nconst UNC=/\\s*·?\\s*\\((sobrenome com )?leitura incerta\\)/i\nconst isUnc=(g)=>UNC.test(String(g.notes||''))\nconst numFromNotes=(g)=>{const m=String(g.notes||'').match(/Lista nº\\s*(\\d+)/i);return m?Number(m[1]):null}\nconst numOf=(g)=>Number(g.num)||numFromNotes(g)||null\nconst cleanNotes=(n)=>String(n||'').replace(UNC,'').trim()\n// convite individual: token aleatório por convidado → https://convite.katia-party.next.data2.app/?c=TOKEN\nconst INVITE='https://convite.katia-party.next.data2.app/?c='\nconst tok=()=>{const A='abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789',a=new Uint8Array(14);crypto.getRandomValues(a);return Array.from(a,b=>A[b%A.length]).join('')}\n// só o primeiro nome (o nome completo fica na lista); mantém tratamento (D., Dona…) e Maria/Ana compostos\nconst firstName=(n)=>{const w=String(n||'').split(' (')[0].trim().split(/\\s+/).filter(Boolean);if(w.length<2)return w[0]||'';const a=w[0].toLowerCase().replace(/\\.$/,'');return ['d','dona','dr','dra','sr','sra','seu','tia','tio','maria','ana'].includes(a)?w[0]+' '+w[1]:w[0]}\nfunction inviteMsg(g,p){p=p||{};return `Oi, ${firstName(g.name)}! 💗\n\nVou fazer aniversário e quero muito você lá pra comemorar comigo! 🎂\n\n📅 ${p.dateLabel||'Domingo, 15 de novembro'}\n🕛 ${p.time||'12h00'}\n📍 ${p.place||'Sítio Recanto dos Lagos'}, ${p.city||'Mogi das Cruzes - SP'}\n🗺️ ${p.maps||'https://maps.app.goo.gl/wVNFaGGmY8bLGoJt9'}\n\nÉ num sítio: vem de calçado confortável pra terra e pedra 👟, traz roupa de banho (tem piscina! 👙) e protetor solar/repelente 🧴\n\nConfirma sua presença até ${p.rsvpDeadlineLabel||'15/10'} pelo seu convite:\n${INVITE}${g.rsvpToken}\n\nBeijos, Katia 💗 (e o Milo 🐕)`}\n\nexport default {\n  css:`\n:host{--bg:var(--k-bg,#FFF7F5);--card:var(--k-card,#FFFFFF);--blush-50:var(--k-blush-50,#FFF1F2);--blush-100:var(--k-blush-100,#FDE4E7);--blush-200:var(--k-blush-200,#F9CDD4);--blush-300:var(--k-blush-300,#F2AEBA);--rose:var(--k-rose,#D9879A);--rose-deep:var(--k-rose-deep,#B8647A);--ink:var(--k-ink,#4A3439);--muted:var(--k-muted,#94797E);--line:var(--k-line,#F3DDE0);--peach:var(--k-peach,#FDE3D3);--sage:var(--k-sage,#DCEBDD);--sage-ink:var(--k-sage-ink,#4F7A57);--butter:var(--k-butter,#FFF2C9);--butter-ink:var(--k-butter-ink,#8A6D1F);--lilac:var(--k-lilac,#ECE3F6);--lilac-ink:var(--k-lilac-ink,#6B5390);--shadow:var(--k-shadow,0 6px 24px rgba(184,100,122,.12))}\n*{box-sizing:border-box}\n.wrap{height:100%;overflow:auto;padding:28px clamp(16px,3vw,40px) 90px;font-family:'Nunito',system-ui,sans-serif;color:var(--ink)}\n.inner{max-width:1120px;margin:0 auto;display:grid;gap:16px}\n.head{display:flex;align-items:flex-end;gap:10px;flex-wrap:wrap}\n.head h2{font:600 30px/1 'Fredoka';margin:0}\n.head p{margin:6px 0 0;color:var(--muted);font-weight:700;font-size:14px}\n.btn{border:0;border-radius:14px;padding:11px 16px;font:600 15px 'Fredoka';cursor:pointer;background:linear-gradient(135deg,#E79AAB,#D9879A);color:#fff;box-shadow:0 6px 16px rgba(217,135,154,.3);white-space:nowrap}\n.btn:active{transform:scale(.97)}.btn[disabled]{opacity:.55}\n.ghost{border:1.5px solid var(--line);background:var(--card);color:var(--ink);box-shadow:none}\n.danger{background:var(--card);color:#B4475F;border:1.5px solid #F5C9D2;box-shadow:none}\n.sm{padding:7px 11px;font-size:13px;border-radius:11px}\n.stats{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px}\n.st{background:var(--card);border:1px solid var(--line);border-radius:20px;padding:14px 16px;box-shadow:var(--shadow)}\n.st .k{font-weight:800;font-size:11px;letter-spacing:.4px;text-transform:uppercase;color:var(--muted)}\n.st .v{font:600 28px/1.1 'Fredoka';margin-top:4px}\n.st .h{font-size:12px;font-weight:700;color:var(--muted)}\n.tools{display:flex;gap:8px;flex-wrap:wrap;align-items:center}\n.search{flex:1;min-width:200px}\ninput,textarea,select{width:100%;border:1.5px solid var(--line);background:var(--card);border-radius:12px;padding:10px 12px;font:600 14px 'Nunito';color:var(--ink);outline:none}\ninput:focus,textarea:focus,select:focus{border-color:var(--blush-300)}\n.f{border:1.5px solid var(--line);background:var(--card);border-radius:999px;padding:7px 12px;font:700 13px 'Nunito';color:var(--ink);cursor:pointer;white-space:nowrap}\n.f[data-on]{background:var(--blush-100);border-color:var(--blush-300);color:var(--rose-deep)}\n.f.warn[data-on]{background:var(--butter);border-color:#EED48A;color:var(--butter-ink)}\n.seg{display:inline-flex;border:1.5px solid var(--line);border-radius:999px;overflow:hidden;background:var(--card)}\n.seg button{border:0;background:none;padding:7px 12px;font:700 13px 'Nunito';cursor:pointer;color:var(--ink)}\n.seg button[data-on]{background:var(--blush-100);color:var(--rose-deep)}\n.list{background:var(--card);border:1px solid var(--line);border-radius:22px;box-shadow:var(--shadow);overflow:hidden}\n.g{display:grid;grid-template-columns:auto minmax(0,1fr) auto auto;gap:12px;align-items:center;padding:11px 16px;border-top:1px solid var(--line)}\n.g:first-child{border-top:0}\n.num{min-width:40px;height:40px;padding:0 6px;border-radius:12px;display:grid;place-items:center;font:600 14px 'Fredoka';color:var(--rose-deep);background:var(--blush-50);border:1px solid var(--line)}\n.g.unc .num{background:var(--butter);color:var(--butter-ink);border-color:#EED48A}\n.g .n{font-weight:800;font-size:15px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.g .m{font-size:12px;font-weight:700;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.g .m a{color:var(--sage-ink);text-decoration:none}\n.g .m .w{color:var(--butter-ink)}\n.chip{border:0;font:800 12px 'Nunito';border-radius:999px;padding:6px 11px;white-space:nowrap;cursor:pointer}\n.c-pend{background:var(--blush-100);color:var(--rose-deep)}.c-lil{background:var(--lilac);color:var(--lilac-ink)}.c-ok{background:var(--sage);color:var(--sage-ink)}.c-no{background:var(--k-mute,#EFE7E8);color:#8C7377}.c-duv{background:var(--butter);color:var(--butter-ink)}.c-prov{background:var(--peach);color:var(--k-prov,#9A5A34)}.chips{display:flex;gap:6px;align-items:center}.gchip{border:1.5px solid var(--line);background:var(--card);font:800 12px 'Nunito';border-radius:999px;padding:5px 10px;cursor:pointer;color:var(--ink);white-space:nowrap}.gchip i{display:inline-block;width:8px;height:8px;border-radius:50%;margin-right:5px}.gchip.none{border-style:dashed;color:var(--muted)}.gtag{font-weight:800;color:var(--rose-deep)}\n.ed{border:0;background:none;cursor:pointer;font-size:16px;padding:6px;border-radius:10px}\n.ed:hover{background:var(--blush-50)}\n.acts{display:flex;gap:2px;align-items:center}.wa,.lk{border:0;background:none;cursor:pointer;font-size:16px;padding:6px;border-radius:10px}.wa:hover,.lk:hover{background:var(--blush-50)}\n.g .m .rs{color:var(--sage-ink)}\n.fix{display:flex;gap:6px;align-items:center;min-width:0}\n.fix input{padding:8px 10px;font-size:15px;font-weight:800;background:var(--butter);border-color:#EED48A}\n.fix .ok{border:0;border-radius:10px;padding:8px 12px;font:700 13px 'Nunito';cursor:pointer;background:var(--sage);color:var(--sage-ink);white-space:nowrap}\n.tip{font-size:12px;font-weight:700;color:var(--muted)}\n.banner{background:var(--butter);color:var(--butter-ink);border-radius:16px;padding:10px 14px;font-weight:700;font-size:13px}\nform.gf{display:grid;grid-template-columns:.6fr 2fr 1.4fr;gap:10px;background:var(--card);border:1px solid var(--line);border-radius:22px;padding:16px;box-shadow:var(--shadow)}\nform.gf .full{grid-column:1/-1}\nform.gf .half{grid-column:span 2}\nlabel{display:block;font-weight:800;font-size:12px;color:var(--muted);margin-bottom:4px}\n.row{display:flex;gap:8px;flex-wrap:wrap;align-items:center}\n.paste{background:var(--card);border:1px solid var(--line);border-radius:22px;padding:16px;box-shadow:var(--shadow);display:grid;gap:10px}\n.paste textarea{min-height:140px;font-family:ui-monospace,Menlo,monospace;font-size:13px}\n.empty{text-align:center;color:var(--muted);font-weight:700;padding:30px 10px;border:2px dashed var(--line);border-radius:22px;background:var(--card)}\n.empty .z{font-size:36px;display:block;margin-bottom:6px}\n@media (max-width:760px){.stats{grid-template-columns:1fr 1fr}form.gf{grid-template-columns:1fr 1fr}form.gf .wide{grid-column:1/-1}.g{grid-template-columns:auto minmax(0,1fr) auto}.g .acts{grid-column:3;grid-row:1}.g .chips{grid-column:2/4;justify-self:start}.g .fix{grid-column:2/4}.wrap{padding-top:18px}.head h2{font-size:26px}}\n`,\n  render(d2){\n    const s=d2.state\n    const all=recs(d2,'guests')\n    const q=(s.q||'').toLowerCase().trim(),f=s.filter||'todos',sort=s.sort||'num',gf=s.gf||'todos'\n    const opts=all.filter(x=>numOf(x)).sort((a,b)=>numOf(a)-numOf(b))\n    const uncN=all.filter(isUnc).length\n    const list=all.filter(g=>(gf==='todos'||(gf==='sem'?!GROUPS.includes(g.group):g.group===gf))&&(f==='todos'||(f==='incertos'?isUnc(g):(g.status||'a convidar')===f))&&(!q||`${numOf(g)||''} ${g.name} ${g.group} ${g.phone} ${g.notes}`.toLowerCase().includes(q)))\n      .sort(sort==='az'?(a,b)=>String(a.name).localeCompare(String(b.name),'pt-BR'):(a,b)=>(numOf(a)??1e9)-(numOf(b)??1e9)||String(a.name).localeCompare(String(b.name),'pt-BR'))\n    const totalP=all.length\n    const conf=all.filter(g=>g.status==='confirmado'),confP=conf.reduce((a,g)=>a+ppl(g),0)\n    const no=all.filter(g=>g.status==='não vem').reduce((a,g)=>a+ppl(g),0)\n    const nextNum=Math.max(0,...all.map(g=>numOf(g)||0))+1\n    const form=(g)=>`<form class=\"gf\" data-id=\"${esc(g?g._id:'')}\">\n      <div><label>Nº</label><input name=\"num\" type=\"number\" min=\"1\" value=\"${g?(numOf(g)||''):nextNum}\"/></div>\n      <div class=\"wide\"><label>Nome</label><input name=\"name\" required value=\"${esc(g?g.name:'')}\" placeholder=\"Ex.: Tia Lúcia\"/></div>\n      <div class=\"wide\"><label>Grupo</label><select name=\"group\"><option value=\"\">—</option>${GROUPS.map(x=>`<option ${g&&g.group===x?'selected':''}>${x}</option>`).join('')}</select></div>\n      <div class=\"half wide comp\" style=\"${g&&g.group==='Extra'?'':'display:none'}\"><label>Agregado de</label><select name=\"companionOf\"><option value=\"\">—</option>${opts.filter(x=>!g||x._id!==g._id).map(x=>`<option value=\"${numOf(x)}\" ${g&&Number(g.companionOf)===numOf(x)?'selected':''}>#${numOf(x)} ${esc(x.name)}</option>`).join('')}</select></div>\n      <div class=\"wide\"><label>Status</label><select name=\"status\">${ST.map(x=>`<option ${((g&&g.status)||'a convidar')===x?'selected':''}>${x}</option>`).join('')}</select></div>\n      <div class=\"half wide\"><label>Observações</label><input name=\"notes\" value=\"${esc(g?g.notes:'')}\" placeholder=\"Restrição alimentar, acompanhante…\"/></div>\n      <div class=\"full row\"><button class=\"btn\" type=\"submit\">${g?'Salvar':'Adicionar'}</button><button class=\"btn ghost cancel\" type=\"button\">Cancelar</button>${g?`<button class=\"btn danger del\" type=\"button\" data-id=\"${esc(g._id)}\" style=\"margin-left:auto\">Excluir</button>`:''}</div>\n    </form>`\n    const row=(g,i)=>{\n      if(s.editing===g._id)return form(g)\n      const n=numOf(g),unc=isUnc(g)\n      const meta=[]\n      if(g.group==='Extra'&&g.companionOf){const c=all.find(x=>numOf(x)===Number(g.companionOf));meta.push(`agregado de #${g.companionOf}${c?' '+esc(c.name):''}`)}\n      if(g.phone)meta.push(`<a href=\"https://wa.me/55${esc(String(g.phone).replace(/\\D/g,'').replace(/^55/,''))}\" target=\"_blank\" rel=\"noopener\">${esc(g.phone)}</a>`)\n      const extra=cleanNotes(String(g.notes||'').replace(/Lista nº\\s*\\d+\\s*·?\\s*/i,''))\n      if(extra)meta.push(esc(extra))\n      if(unc)meta.push('<span class=\"w\">⚠️ leitura incerta</span>')\n      if(g.rsvpNote&&g.rsvpNote!=='undefined')meta.push(`<span class=\"rs\">💬 “${esc(g.rsvpNote)}”</span>`)\n      else if(g.rsvpAt)meta.push('<span class=\"rs\">respondeu pelo convite</span>')\n      else if(g.invitedAt&&g.status==='convidado')meta.push('convite enviado 📲')\n      const fixing=f==='incertos'&&unc\n      return `<div class=\"g ${unc?'unc':''}\" data-key=\"${esc(g._id||'p'+i)}\">\n        <div class=\"num\">${n?esc(String(n)):'·'}</div>\n        ${fixing?`<div class=\"fix\"><input class=\"fixname\" data-id=\"${esc(g._id)}\" value=\"${esc(g.name)}\" aria-label=\"Nome correto\"/><button class=\"ok\" data-id=\"${esc(g._id)}\">✓ Confirmar</button></div>`\n          :`<div style=\"min-width:0\"><div class=\"n\">${esc(g.name)}</div>${meta.length?`<div class=\"m\">${meta.join(' · ')}</div>`:''}</div>`}\n        <div class=\"chips\">${GROUPS.includes(g.group)?`<button class=\"gchip\" data-id=\"${esc(g._id)}\" title=\"Toque pra trocar o grupo\"><i style=\"background:${GC[g.group]}\"></i>${esc(g.group)}</button>`:`<button class=\"gchip none\" data-id=\"${esc(g._id)}\" title=\"Toque pra escolher o grupo\">+ grupo</button>`}<button class=\"chip ${STC[g.status||'a convidar']||'c-pend'}\" data-id=\"${esc(g._id)}\">${esc(g.status||'a convidar')}</button></div>\n        <span class=\"acts\"><button class=\"wa\" data-id=\"${esc(g._id)}\" title=\"Enviar convite (WhatsApp)\">📲</button><button class=\"lk\" data-id=\"${esc(g._id)}\" title=\"Copiar link do convite\">🔗</button><button class=\"ed\" data-id=\"${esc(g._id)}\" title=\"Editar\">✏️</button></span></div>`}\n    return `<div class=\"wrap\"><div class=\"inner\">\n      <div class=\"head\"><div style=\"flex:1;min-width:200px\"><h2>Convidados 💌</h2><p>Toque no grupo ou no status pra trocar · status: em dúvida → a convidar → convidado → provável → confirmado → não vem.</p></div>\n        <button class=\"btn ghost paste-open\">📋 Colar lista</button><button class=\"btn add\">+ Convidado</button></div>\n      <div class=\"stats\">\n        <div class=\"st\"><div class=\"k\">Convidados</div><div class=\"v\">${totalP}</div><div class=\"h\">${all.filter(g=>g.status==='em dúvida').length} em dúvida</div></div>\n        <div class=\"st\"><div class=\"k\">Confirmados</div><div class=\"v\" style=\"color:var(--sage-ink)\">${confP}</div><div class=\"h\">${(()=>{const pv=all.filter(g=>g.status==='provável').length;return pv?`+ ${pv} prováveis = ${confP+pv} pro buffet`:`${totalP?Math.round(confP/totalP*100):0}% da lista`})()}</div></div>\n        <div class=\"st\"><div class=\"k\">A convidar</div><div class=\"v\">${all.filter(g=>(g.status||'a convidar')==='a convidar').length}</div><div class=\"h\">${all.filter(g=>g.status==='convidado').length} já convidados</div></div>\n        <div class=\"st\"><div class=\"k\">Não vêm</div><div class=\"v\">${no}</div><div class=\"h\">pessoas</div></div>\n      </div>\n      ${s.editing==='new'?form(null):''}\n      ${s.paste?`<div class=\"paste\"><b style=\"font:600 17px Fredoka\">Colar lista</b>\n        <div class=\"tip\">Um convidado por linha. Formato livre: <code>Nome; Grupo; telefone</code> (só o nome é obrigatório; grupo = Família, Amigos, Salão ou Extra). Cada linha = 1 convite individual. Os números continuam a partir do ${nextNum}. Listas bagunçadas ou em foto? Manda pro Milo no chat 🐕</div>\n        <textarea class=\"pastebox\" placeholder=\"Tia Lúcia; Família; 11999990000&#10;Ana Paula; Amigos&#10;Marcos\"></textarea>\n        <div class=\"row\"><button class=\"btn do-paste\">Importar</button><button class=\"btn ghost paste-close\">Cancelar</button></div></div>`:''}\n      <div class=\"tools\"><input class=\"search\" placeholder=\"🔎 Buscar por nº, nome, telefone…\" value=\"${esc(s.q||'')}\"/>\n        <span class=\"seg\"><button data-sort=\"num\" ${sort==='num'?'data-on':''}>Nº</button><button data-sort=\"az\" ${sort==='az'?'data-on':''}>A–Z</button></span></div>\n      <div class=\"tools\">${[['todos','Todos os grupos'],...GROUPS.map(x=>[x,x]),['sem','Sem grupo']].map(([k,l])=>`<button class=\"f\" data-gf=\"${k}\" ${gf===k?'data-on':''}>${l} · ${k==='todos'?all.length:all.filter(g=>k==='sem'?!GROUPS.includes(g.group):g.group===k).length}</button>`).join('')}</div>\n      <div class=\"tools\">${['todos',...ST].map(k=>`<button class=\"f\" data-f=\"${k}\" ${f===k?'data-on':''}>${k==='todos'?'Todos':k}</button>`).join('')}\n        ${uncN||f==='incertos'?`<button class=\"f warn\" data-f=\"incertos\" ${f==='incertos'?'data-on':''}>⚠️ Incertos · ${uncN}</button>`:''}</div>\n      ${f==='incertos'&&uncN?`<div class=\"banner\">Corrija o nome no campo e toque em ✓ Confirmar (ou Enter). A marca de \"leitura incerta\" sai sozinha 🐾</div>`:''}\n      ${list.length?`<div class=\"list\">${list.map(row).join('')}</div>`\n      :`<div class=\"empty\"><span class=\"z\">${f==='incertos'?'🎉':'🐕💤'}</span>${f==='incertos'?'Nenhum nome incerto, tudo conferido!':all.length?'Ninguém com esse filtro.':'Nenhum convidado ainda. Adicione, cole uma lista ou mande pro Milo no chat!'}</div>`}\n    </div></div>`\n  },\n  mounted(d2){\n    const s=d2.state,G=()=>d2.data('guests')\n    // backfill único: grava `num` a partir de \"Lista nº X\" nas observações\n    let tries=0\n    const backfill=async()=>{const rs=G().records()||[];if(!rs.length&&tries++<20){setTimeout(backfill,700);return}\n      for(const g of rs){const patch={};if(!Number(g.num)){const n=numFromNotes(g);if(n)patch.num=n}if(!g.rsvpToken)patch.rsvpToken=tok()\n        if(Object.keys(patch).length){try{await G().update({...g,...patch})}catch(e){}}}}\n    setTimeout(backfill,500)\n    const fix=async(id)=>{const el=d2.$(`.fixname[data-id=\"${id}\"]`);const g=G().records().find(r=>r._id===id);if(!g||!el)return\n      const name=el.value.trim();if(!name)return\n      await G().update({...g,name,notes:cleanNotes(g.notes)});toast(d2,`${name} conferido ✓`)}\n    d2.on('.ok','click',(e,el)=>fix(el.dataset.id))\n    d2.on('.fixname','keydown',(e,el)=>{if(e.key==='Enter'){e.preventDefault();fix(el.dataset.id)}})\n    d2.on('.add','click',()=>{d2.setState({editing:'new',paste:false});setTimeout(()=>{const i=d2.$('form.gf input[name=name]');i&&i.focus()},30)})\n    d2.on('.ed','click',(e,el)=>{s.editing=el.dataset.id})\n    d2.on('.cancel','click',()=>{s.editing=null})\n    d2.on('.paste-open','click',()=>d2.setState({paste:true,editing:null}))\n    d2.on('.paste-close','click',()=>{s.paste=false})\n    d2.on('.search','input',(e,el)=>{s.q=el.value})\n    d2.on('.f','click',(e,el)=>{if(el.dataset.gf)s.gf=el.dataset.gf;else s.filter=el.dataset.f})\n    d2.on('[data-sort]','click',(e,el)=>{s.sort=el.dataset.sort})\n    let partyCache={};(async()=>{try{const r=await d2.rush('rsvp-get').invoke({c:''});const d=r&&r.data?r.data:r;partyCache=(d&&d.party)||{}}catch(e){}})()\n    const party=()=>partyCache\n    const ensureTok=async(g)=>{if(g.rsvpToken)return g;const t=tok();await G().update({...g,rsvpToken:t});return {...g,rsvpToken:t}}\n    const markSent=async(g)=>{const cur=G().records().find(r=>r._id===g._id)||g;if(['a convidar','em dúvida'].includes(cur.status||'a convidar'))await G().update({...cur,status:'convidado',invitedAt:new Date().toISOString()})}\n    const pngOf=async(url)=>{const b=await (await fetch(url)).blob();if(b.type==='image/png')return b;const bm=await createImageBitmap(b),c=document.createElement('canvas');c.width=bm.width;c.height=bm.height;c.getContext('2d').drawImage(bm,0,0);return await new Promise(r=>c.toBlob(r,'image/png'))}\n    let imgFile=null,imgFor=''\n    const preload=()=>{const u=party().inviteImage;if(!u||imgFor===u)return;imgFor=u;fetch(u).then(r=>r.blob()).then(b=>{imgFile=new File([b],'convite-katia.'+(b.type==='image/png'?'png':'jpg'),{type:b.type||'image/jpeg'})}).catch(()=>{imgFor=''})}\n    let warmN=0;const warm=()=>{preload();if(!imgFor&&++warmN<20)setTimeout(warm,1500)};warm()\n    d2.on('.wa','click',async(e,el)=>{let g=G().records().find(r=>r._id===el.dataset.id);if(!g)return\n      const p=party(),mobile=matchMedia('(pointer:coarse)').matches;preload()\n      // celular: compartilha imagem + texto juntos (folha de compartilhar → WhatsApp)\n      if(mobile&&imgFile&&navigator.canShare&&navigator.canShare({files:[imgFile]})){g=await ensureTok(g)\n        try{await navigator.share({files:[imgFile],text:inviteMsg(g,p)});await markSent(g);toast(d2,`Convite enviado pra ${firstName(g.name)} 💌`);return}catch(err){if(err&&err.name==='AbortError')return}}\n      // computador: copia a imagem pro clipboard e abre o WhatsApp com o texto (api.whatsapp.com preserva emoji; wa.me quebra)\n      const copied=(p.inviteImage&&window.ClipboardItem&&navigator.clipboard&&navigator.clipboard.write)?navigator.clipboard.write([new ClipboardItem({'image/png':pngOf(p.inviteImage)})]).then(()=>true,()=>false):null\n      const w=window.open('about:blank','_blank')\n      g=await ensureTok(g)\n      const ph=String(g.phone||'').replace(/\\D/g,'').replace(/^55/,'')\n      const url=`https://api.whatsapp.com/send?${ph?`phone=55${ph}&`:''}text=${encodeURIComponent(inviteMsg(g,p))}`\n      if(w)w.location.href=url;else window.open(url,'_blank')\n      const ok=copied&&await copied\n      await markSent(g);toast(d2,ok?`Imagem do convite copiada: cola (Ctrl+V) na conversa com ${firstName(g.name)} 🖼️`:p.inviteImage?`Mensagem pronta pra ${firstName(g.name)}. Anexa a imagem do convite 🖼️`:`Mensagem pronta pra ${firstName(g.name)} 💌`)})\n    d2.on('.lk','click',async(e,el)=>{let g=G().records().find(r=>r._id===el.dataset.id);if(!g)return;g=await ensureTok(g)\n      const link=INVITE+g.rsvpToken;try{await navigator.clipboard.writeText(link);toast(d2,`Link de ${firstName(g.name)} copiado 🔗`)}catch(err){await d2.dialog.prompt('Link do convite (copie):',link)}})\n    d2.on('.gchip','click',async(e,el)=>{const g=G().records().find(r=>r._id===el.dataset.id);if(!g)return\n      const order=['',...GROUPS],nx=order[(order.indexOf(GROUPS.includes(g.group)?g.group:'')+1)%order.length]\n      await G().update({...g,group:nx,companionOf:nx==='Extra'?(g.companionOf||null):null})\n      if(nx==='Extra'&&!g.companionOf)toast(d2,`${g.name} agora é Extra. Toque no ✏️ pra dizer de quem é agregado 🐾`)})\n    d2.on('select[name=group]','change',(e,el)=>{const w=el.form&&el.form.querySelector('.comp');if(w)w.style.display=el.value==='Extra'?'':'none'})\n    d2.on('.chip','click',async(e,el)=>{const g=G().records().find(r=>r._id===el.dataset.id);if(!g)return\n      const nx=ST[(ST.indexOf(g.status||'a convidar')+1)%ST.length];await G().update({...g,status:nx})\n      if(nx==='confirmado')toast(d2,`${g.name} confirmado(a)! 🎉`)})\n    d2.on('.del','click',async(e,el)=>{const g=G().records().find(r=>r._id===el.dataset.id);if(!g)return\n      if(!await d2.dialog.confirm(`Remover ${g.name} da lista?`))return\n      await G().remove(g);s.editing=null;toast(d2,'Convidado removido')})\n    d2.on('.do-paste','click',async()=>{const t=(d2.$('.pastebox')||{}).value||''\n      let n=Math.max(0,...G().records().map(g=>numOf(g)||0))\n      const rows=t.split(/\\n+/).map(l=>l.trim()).filter(Boolean).map(l=>{const p=l.split(/[;\\t|]/).map(x=>x.trim())\n        return {name:p[0],group:GROUPS.find(x=>x.toLowerCase()===String(p[1]||'').toLowerCase())||'',adults:1,kids:0,phone:p[2]||'',status:'a convidar'}}).filter(r=>r.name)\n      if(!rows.length)return\n      s.paste=false;for(const r of rows)await G().create({...r,num:++n});toast(d2,`${rows.length} convidado${rows.length>1?'s':''} importado${rows.length>1?'s':''} 💌`)})\n    d2.on('form','submit',async(e,form)=>{e.preventDefault()\n      const fd=new FormData(form),id=form.dataset.id\n      const data={num:Number(fd.get('num'))||null,name:String(fd.get('name')||'').trim(),group:String(fd.get('group')||'').trim(),companionOf:String(fd.get('group')||'')==='Extra'?(Number(fd.get('companionOf'))||null):null,adults:1,kids:0,phone:String(fd.get('phone')||'').trim(),status:fd.get('status')||'a convidar',notes:String(fd.get('notes')||'').trim()}\n      if(!data.name)return\n      if(id){const g=G().records().find(r=>r._id===id);if(g&&data.name!==g.name)data.notes=cleanNotes(data.notes);await G().update({...g,...data});s.editing=null;toast(d2,'Salvo ✨')}\n      else{await G().create(data);toast(d2,`${data.name} adicionado(a) 💌`);form.reset();const i=form.querySelector('input[name=num]');if(i)i.value=String((data.num||0)+1);const nm=form.querySelector('input[name=name]');nm&&nm.focus()}\n    })\n  },\n}\n"}},"guests":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"guests"}}}},"me":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"me"}}}}}}}}}},{"_id":"6abefda70484650e9b1b46bb","component":"data2-core-types@Component","system":"6abed5371a6b03943b9618d7","params":{"extends":"data2-core-primitives@Block","component":"kp-chat","package":"katia-party","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"// kp-chat — conversa única com o Milo (assistente) que registra TASKS estruturadas pro Claude executar depois.\n// Aceita fotos/arquivos (Drive). Painel lateral de tasks (desktop) / aba (mobile).\n// params: messages tasks (dataset), scribe (assistant), drive (service), uploader (rush → @upload-file), me (string)\nfunction esc(s){return String(s??'').replace(/[&<>\"]/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c]))}\nfunction md(s){return esc(s).replace(/\\*\\*(.+?)\\*\\*/g,'<b>$1</b>').replace(/(https?:\\/\\/[^\\s<]+)/g,'<a href=\"$1\" target=\"_blank\" rel=\"noopener\">$1</a>').replace(/\\n/g,'<br>')}\nfunction shiba(cls){return `<svg class=\"${cls||''}\" viewBox=\"0 0 120 110\" aria-hidden=\"true\"><path d=\"M22 50 L30 8 L56 32 Z\" fill=\"#E59A55\"/><path d=\"M29 41 L33 18 L48 33 Z\" fill=\"#F8D7B5\"/><path d=\"M98 50 L90 8 L64 32 Z\" fill=\"#E59A55\"/><path d=\"M91 41 L87 18 L72 33 Z\" fill=\"#F8D7B5\"/><ellipse cx=\"60\" cy=\"62\" rx=\"44\" ry=\"40\" fill=\"#E59A55\"/><path d=\"M24 70 Q30 99 60 103 Q90 99 96 70 Q84 58 72 66 Q60 74 48 66 Q36 58 24 70Z\" fill=\"#FFF4E8\"/><ellipse cx=\"44\" cy=\"45\" rx=\"6\" ry=\"4\" fill=\"#FFF4E8\"/><ellipse cx=\"76\" cy=\"45\" rx=\"6\" ry=\"4\" fill=\"#FFF4E8\"/><ellipse cx=\"44\" cy=\"58\" rx=\"4.5\" ry=\"5.5\" fill=\"#3B2A2E\"/><ellipse cx=\"76\" cy=\"58\" rx=\"4.5\" ry=\"5.5\" fill=\"#3B2A2E\"/><circle cx=\"45.5\" cy=\"56\" r=\"1.5\" fill=\"#fff\"/><circle cx=\"77.5\" cy=\"56\" r=\"1.5\" fill=\"#fff\"/><path d=\"M54 72 Q60 68 66 72 Q63 78 60 78 Q57 78 54 72Z\" fill=\"#3B2A2E\"/><path d=\"M52 83 Q56 88 60 83 Q64 88 68 83\" stroke=\"#3B2A2E\" stroke-width=\"2.4\" fill=\"none\" stroke-linecap=\"round\"/><ellipse cx=\"32\" cy=\"74\" rx=\"7\" ry=\"4.5\" fill=\"#F4A7B5\" opacity=\".75\"/><ellipse cx=\"88\" cy=\"74\" rx=\"7\" ry=\"4.5\" fill=\"#F4A7B5\" opacity=\".75\"/></svg>`}\nconst recs=(d2,k)=>{const h=d2.data(k);return h?h.records()||[]:[]}\nconst toast=(d2,m)=>d2.bus.emit('kp:toast',m)\n// upload via Rush `upload-file` (o Drive recusa upload direto de usuário final). Imagens são reduzidas antes.\nasync function toB64(file){if(/^image\\/(png|jpe?g|webp)$/i.test(file.type||'')){try{const bmp=await createImageBitmap(file);const k=Math.min(1,1920/Math.max(bmp.width,bmp.height));const c=document.createElement('canvas');c.width=Math.round(bmp.width*k);c.height=Math.round(bmp.height*k);const g=c.getContext('2d');g.fillStyle='#fff';g.fillRect(0,0,c.width,c.height);g.drawImage(bmp,0,0,c.width,c.height);const du=c.toDataURL('image/jpeg',0.85);return {base64:du.split(',')[1],contentType:'image/jpeg',fileName:String(file.name||'foto').replace(/\\.[^.]+$/,'')+'.jpg'}}catch(e){}}\n  const du=await new Promise((res,rej)=>{const r=new FileReader();r.onload=()=>res(r.result);r.onerror=rej;r.readAsDataURL(file)});return {base64:String(du).split(',')[1],contentType:file.type||'application/octet-stream',fileName:file.name||'arquivo'}}\nasync function shrink(file){if(!/^image\\/(png|jpe?g|webp)$/i.test(file.type||''))return file;const p=await toB64(file);if(p.contentType!=='image/jpeg')return file;const bin=atob(p.base64),u8=new Uint8Array(bin.length);for(let i=0;i<bin.length;i++)u8[i]=bin.charCodeAt(i);return new File([u8],p.fileName,{type:'image/jpeg'})}\n// 1º upload direto no Drive (presigned S3, sem limite prático; liberado pela DrivePolicy upload). 2º fallback: Rush (até ~1 MB, limite da Lambda).\nasync function uploadAll(d2,files){const out=[];for(const f0 of files){if(f0.size>25e6)throw new Error(`${f0.name}: muito grande (máx. 25 MB)`);const f=await shrink(f0);let url=''\n  try{const up=await d2.drive(d2.param('drive')).upload([f]);const u=up&&up[0];url=(u&&(u.fileUrl||u.url))||''}catch(e){}\n  if(!url&&f.size<9e5){const p=await toB64(f);const r=await d2.rush('upload-file').invoke(p);const d=r&&r.data?r.data:r;url=(d&&d.url)||''}\n  if(!url)throw new Error(`${f0.name}: não consegui enviar`)\n  out.push({url,name:f0.name||f.name,type:f.type})}return out}\nconst stamp=(r)=>r.createdAt?new Date(r.createdAt).getTime():Number.MAX_SAFE_INTEGER\nconst isImg=(a)=>/^image\\//.test(a.type||'')||/\\.(png|jpe?g|gif|webp|heic)(\\?|$)/i.test(a.url||'')\nconst KIND={convidados:'💌',orcamento:'💸',cotacao:'🧾',design:'🎨',convite:'✉️',lembrete:'⏰',outro:'📌'}\nconst TST={pendente:'c-lil','em andamento':'c-cot',feita:'c-ok',cancelada:'c-no'}\nconst LBL={pendente:'na fila','em andamento':'fazendo',feita:'feita',cancelada:'cancelada'}\nconst OPEN=(t)=>['pendente','em andamento'].includes(t.status||'pendente')\nconst SEEN=new WeakMap()\nconst sid=(id)=>String(id||'').slice(-6)\n// conserta JSON do modelo: ignora fechamentos sobrando (fora de strings) e fecha o que ficou aberto\nfunction fixJson(t){let out='',st=[],q=false,esc=false\n  for(let i=0;i<t.length;i++){const ch=t[i];if(q){out+=ch;if(esc)esc=false;else if(ch==='\\\\')esc=true;else if(ch==='\"')q=false;continue}\n    if(ch==='\"'){q=true;out+=ch;continue}\n    if(ch==='{'||ch==='['){st.push(ch);out+=ch;continue}\n    if(ch==='}'||ch===']'){const want=ch==='}'?'{':'[';if(st[st.length-1]===want&&!(st.length===1&&t.slice(i+1).trim())){st.pop();out+=ch}continue}\n    out+=ch}\n  while(st.length)out+=st.pop()==='{'?'}':']';return out.replace(/,\\s*([}\\]])/g,'$1')}\nfunction parseAnswer(a){if(a&&typeof a==='object')return a;let t=String(a||'').trim().replace(/^```(json)?/i,'').replace(/```$/,'').trim()\n  const tries=[t];const m=t.match(/\\{[\\s\\S]*\\}/);if(m)tries.push(m[0]);tries.push(fixJson(m?m[0]:t))\n  for(const x of tries){try{const o=JSON.parse(x);if(o&&typeof o==='object')return o}catch(e){}}\n  // último recurso: pelo menos não mostrar JSON cru, só o texto do \"reply\"\n  const r=t.match(/\"reply\"\\s*:\\s*\"((?:[^\"\\\\]|\\\\.)*)\"/);if(r){try{return {reply:JSON.parse('\"'+r[1]+'\"'),task:null}}catch(e){return {reply:r[1],task:null}}}\n  return {reply:t||'Au? Não entendi direito, pode repetir? 🐕',task:null}}\n\nexport default {\n  css:`\n:host{--bg:var(--k-bg,#FFF7F5);--card:var(--k-card,#FFFFFF);--blush-50:var(--k-blush-50,#FFF1F2);--blush-100:var(--k-blush-100,#FDE4E7);--blush-200:var(--k-blush-200,#F9CDD4);--blush-300:var(--k-blush-300,#F2AEBA);--rose:var(--k-rose,#D9879A);--rose-deep:var(--k-rose-deep,#B8647A);--ink:var(--k-ink,#4A3439);--muted:var(--k-muted,#94797E);--line:var(--k-line,#F3DDE0);--peach:var(--k-peach,#FDE3D3);--sage:var(--k-sage,#DCEBDD);--sage-ink:var(--k-sage-ink,#4F7A57);--butter:var(--k-butter,#FFF2C9);--butter-ink:var(--k-butter-ink,#8A6D1F);--lilac:var(--k-lilac,#ECE3F6);--lilac-ink:var(--k-lilac-ink,#6B5390);--shadow:var(--k-shadow,0 6px 24px rgba(184,100,122,.12))}\n*{box-sizing:border-box}\n.wrap{height:100%;display:grid;grid-template-columns:minmax(0,1fr) 340px;font-family:'Nunito',system-ui,sans-serif;color:var(--ink);min-height:0}\n.chat{display:grid;grid-template-rows:auto minmax(0,1fr) auto;min-height:0;min-width:0}\n.ch{display:flex;align-items:center;gap:12px;padding:14px 20px;border-bottom:1px solid var(--line);background:var(--card)}\n.ch svg{width:44px;height:40px}\n.ch b{font:600 19px 'Fredoka';display:block}.ch small{font-size:12px;font-weight:700;color:var(--muted)}\n.ch .tg{margin-left:auto;display:none}\n.log{overflow:auto;padding:20px clamp(12px,3vw,32px);display:flex;flex-direction:column;gap:14px;background:radial-gradient(600px 300px at 100% 0,var(--blush-50),transparent),var(--bg)}\n.m{display:flex;gap:10px;align-items:flex-end;max-width:min(680px,92%)}\n.m.me{align-self:flex-end;flex-direction:row-reverse}\n.m .av{width:34px;height:34px;border-radius:50%;flex:none;display:grid;place-items:center;font:600 13px 'Fredoka';color:#fff;background:linear-gradient(135deg,#E79AAB,#D9879A)}\n.m .av.dog{background:var(--k-cream,#FFF4E8);border:1px solid var(--line)}.m .av.dog svg{width:28px;height:26px}\n.m .av.cl{background:linear-gradient(135deg,#CDB8EA,#9F86C9)}\n.bub{padding:11px 14px;border-radius:18px 18px 18px 6px;background:var(--card);border:1px solid var(--line);box-shadow:0 2px 10px rgba(184,100,122,.06);font-size:15px;line-height:1.45;word-break:break-word;min-width:0}\n.m.me .bub{border-radius:18px 18px 6px 18px;background:var(--k-mine,linear-gradient(135deg,#FBD3DB,#F9CDD4));border-color:var(--line)}\n.m.cl .bub{background:var(--lilac);border-color:var(--line)}\n.bub a{color:var(--rose-deep);word-break:break-all}\n.who{font-size:11px;font-weight:800;color:var(--muted);margin-bottom:3px}\n.m.me .who{text-align:right}\n.att{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}\n.att img{width:120px;height:120px;object-fit:cover;border-radius:12px;border:1px solid var(--line);cursor:zoom-in;background:var(--card)}\n.att a.file{font-size:12px;font-weight:800;color:var(--lilac-ink);background:var(--card);border:1px solid var(--line);border-radius:10px;padding:5px 9px;text-decoration:none}\n.tchip{display:inline-flex;align-items:center;gap:6px;margin-top:8px;font-size:12px;font-weight:800;border-radius:10px;padding:5px 9px;background:var(--blush-50);border:1px dashed var(--blush-300);cursor:pointer}\n.typing{display:inline-flex;gap:4px;padding:4px 2px}\n.typing i{width:7px;height:7px;border-radius:50%;background:var(--rose);animation:bop 1s infinite}\n.typing i:nth-child(2){animation-delay:.15s}.typing i:nth-child(3){animation-delay:.3s}\n@keyframes bop{0%,100%{transform:translateY(0);opacity:.5}50%{transform:translateY(-5px);opacity:1}}\n.compose{padding:12px clamp(12px,3vw,24px) 14px;background:var(--card);border-top:1px solid var(--line)}\n.pending{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:8px}\n.pending span{font-size:12px;font-weight:800;background:var(--lilac);color:var(--lilac-ink);border-radius:10px;padding:4px 8px;display:inline-flex;gap:6px;align-items:center}\n.pending button{border:0;background:none;cursor:pointer;color:inherit;font-weight:900}\n.bar{display:flex;gap:8px;align-items:flex-end}\n.clip{width:44px;height:44px;flex:none;border-radius:14px;border:1.5px solid var(--line);background:var(--card);display:grid;place-items:center;cursor:pointer;font-size:19px}\n.clip input{display:none}\ntextarea{flex:1;min-height:44px;max-height:160px;resize:none;border:1.5px solid var(--line);background:var(--blush-50);border-radius:14px;padding:11px 14px;font:600 15px 'Nunito';color:var(--ink);outline:none}\ntextarea:focus{border-color:var(--blush-300);background:var(--card)}\n.send{height:44px;border:0;border-radius:14px;padding:0 18px;font:600 15px 'Fredoka';cursor:pointer;background:linear-gradient(135deg,#E79AAB,#D9879A);color:#fff;box-shadow:0 6px 16px rgba(217,135,154,.3)}\n.send[disabled]{opacity:.5}\n.hint{font-size:11px;font-weight:700;color:var(--muted);margin-top:6px}\n.side{border-left:1px solid var(--line);background:var(--card);display:grid;grid-template-rows:auto auto minmax(0,1fr);min-height:0}\n.sh{padding:16px 16px 8px;font:600 18px 'Fredoka';display:flex;align-items:center;gap:8px}\n.sh small{margin-left:auto;font:700 12px 'Nunito';color:var(--muted)}\n.fs{display:flex;gap:6px;padding:0 16px 10px;flex-wrap:wrap}\n.f{border:1.5px solid var(--line);background:var(--card);border-radius:999px;padding:5px 10px;font:700 12px 'Nunito';color:var(--ink);cursor:pointer}\n.f[data-on]{background:var(--blush-100);border-color:var(--blush-300);color:var(--rose-deep)}\n.tl{overflow:auto;padding:0 12px 16px;display:flex;flex-direction:column;gap:8px}\n.t{border:1px solid var(--line);border-radius:16px;padding:11px 12px;background:var(--card);cursor:pointer}\n.t[data-open]{border-color:var(--blush-300);box-shadow:var(--shadow)}\n.t .tt{font-weight:800;font-size:14px;display:flex;gap:6px}\n.t .tm{font-size:11px;font-weight:700;color:var(--muted);margin-top:4px;display:flex;gap:6px;flex-wrap:wrap;align-items:center}\n.chip{font-weight:800;font-size:11px;border-radius:999px;padding:2px 8px}\n.c-lil{background:var(--lilac);color:var(--lilac-ink)}.c-cot{background:var(--butter);color:var(--butter-ink)}.c-ok{background:var(--sage);color:var(--sage-ink)}.c-no{background:var(--k-mute,#EFE7E8);color:#8C7377}\n.t .td{font-size:13px;line-height:1.45;margin-top:8px;white-space:pre-wrap;word-break:break-word}\n.t pre{font-size:11px;background:var(--blush-50);border-radius:10px;padding:8px;overflow:auto;max-height:200px;margin:8px 0 0}\n.t .res{margin-top:8px;font-size:13px;background:var(--sage);color:var(--sage-ink);border-radius:10px;padding:8px;font-weight:700}\n.t .acts{display:flex;gap:6px;margin-top:8px}\n.t .acts button{border:1.5px solid var(--line);background:var(--card);border-radius:10px;padding:5px 9px;font:700 12px 'Nunito';cursor:pointer;color:var(--ink)}\n.empty{color:var(--muted);font-weight:700;font-size:13px;text-align:center;padding:24px 8px}\n.welcome{align-self:center;text-align:center;max-width:440px;margin:auto;color:var(--muted);font-weight:700}\n.welcome svg{width:110px;height:100px}\n.welcome b{display:block;font:600 22px 'Fredoka';color:var(--rose-deep);margin:6px 0}\n.sugg{display:flex;flex-wrap:wrap;gap:6px;justify-content:center;margin-top:12px}\n.sugg button{border:1.5px solid var(--line);background:var(--card);border-radius:999px;padding:7px 12px;font:700 13px 'Nunito';cursor:pointer;color:var(--ink)}\n.zoom{position:fixed;inset:0;background:rgba(74,52,57,.75);display:grid;place-items:center;z-index:80;cursor:zoom-out;padding:16px}\n.zoom img{max-width:100%;max-height:100%;border-radius:16px}\n@media (max-width:980px){\n  .wrap{grid-template-columns:minmax(0,1fr)}\n  .side{display:none;border-left:0}\n  .wrap[data-pane=\"tasks\"] .chat{display:none}.wrap[data-pane=\"tasks\"] .side{display:grid}\n  .ch .tg{display:inline-flex}\n  .tgb{border:1.5px solid var(--line);background:var(--card);border-radius:999px;padding:6px 12px;font:700 13px 'Nunito';cursor:pointer;color:var(--rose-deep)}\n  .bub{font-size:14px}\n  .tgb{white-space:nowrap}\n  .hint{display:none}\n  .ch{padding:10px 14px}\n}\n`,\n  render(d2){\n    const s=d2.state\n    const msgs=recs(d2,'messages').slice().sort((a,b)=>stamp(a)-stamp(b))\n    const tasks=recs(d2,'tasks').slice().sort((a,b)=>stamp(b)-stamp(a))\n    const tById={};for(const t of tasks)tById[t._id]=t\n    const me=d2.param('me')||'Você'\n    const a=d2.assistant(d2.param('scribe'))\n    const thinking=s.thinking||(a&&a.busy)\n    const pendN=tasks.filter(t=>(t.status||'pendente')==='pendente'||t.status==='em andamento').length\n    const atts=(list)=>list&&list.length?`<div class=\"att\">${list.map(x=>isImg(x)?`<img src=\"${esc(x.url)}\" data-zoom=\"${esc(x.url)}\" alt=\"${esc(x.name||'')}\" loading=\"lazy\"/>`:`<a class=\"file\" href=\"${esc(x.url)}\" target=\"_blank\" rel=\"noopener\">📎 ${esc(x.name||'arquivo')}</a>`).join('')}</div>`:''\n    const bubble=(m,i)=>{\n      const role=m.role||'user', mine=role==='user'&&m.author===me\n      const t=m.taskId&&tById[m.taskId]\n      const av=role==='assistant'?`<div class=\"av dog\">${shiba()}</div>`:role==='claude'?`<div class=\"av cl\">✨</div>`:`<div class=\"av\">${esc((m.author||'?')[0])}</div>`\n      return `<div class=\"m ${mine?'me':''} ${role==='claude'?'cl':''}\" data-key=\"${esc(m._id||'pm'+i)}\">${av}<div style=\"min-width:0\">\n        <div class=\"who\">${esc(role==='assistant'?'Milo 🐕':role==='claude'?'Claude ✨':m.author||'')}${m.createdAt?' · '+esc(d2.fmt.relative(m.createdAt)):''}</div>\n        <div class=\"bub\">${md(m.text||'')}${atts(m.attachments)}${t?`<div class=\"tchip\" data-task=\"${esc(t._id)}\">${KIND[t.kind]||'📌'} Task #${sid(t._id)} · ${esc(t.title)} · <span class=\"chip ${TST[t.status||'pendente']}\">${esc(LBL[t.status||'pendente']||t.status)}</span></div>`:''}</div></div></div>`}\n    const f=s.tf||'abertas'\n    const shownT=tasks.filter(t=>{const st=t.status||'pendente';return f==='todas'||(f==='abertas'?(st==='pendente'||st==='em andamento'):st===f)})\n    return `<div class=\"wrap\" data-pane=\"${s.pane||'chat'}\">\n      <section class=\"chat\">\n        <div class=\"ch\">${shiba()}<div><b>Milo</b><small>registra tasks pro Claude fazer depois · ${pendN} em aberto</small></div><span class=\"tg\"><button class=\"tgb to-tasks\">📋 Tasks${pendN?` (${pendN})`:''}</button></span></div>\n        <div class=\"log\">\n          ${msgs.length?msgs.map(bubble).join(''):`<div class=\"welcome\">${shiba()}<b>Oi! Eu sou o Milo 🐾</b>Me conta o que precisa: eu entendo, organizo e registro uma task pro Claude fazer depois. Pode mandar lista de convidados, print de orçamento, foto de inspiração…\n            <div class=\"sugg\"><button data-s=\"Registra essa lista de convidados: \">💌 Lista de convidados</button><button data-s=\"Tenho uma cotação nova de buffet: \">🧾 Nova cotação</button><button data-s=\"Quero ideias de decoração com essa foto de referência\">🎨 Inspiração</button></div></div>`}\n          ${s.optimistic?bubble({...s.optimistic},'opt'):''}\n          ${thinking?`<div class=\"m\"><div class=\"av dog\">${shiba()}</div><div><div class=\"who\">Milo 🐕</div><div class=\"bub\"><span class=\"typing\"><i></i><i></i><i></i></span></div></div></div>`:''}\n        </div>\n        <div class=\"compose\">\n          ${(s.files||[]).length||s.uploading?`<div class=\"pending\">${(s.files||[]).map((x,i)=>`<span>${isImg(x)?'🖼️':'📎'} ${esc(x.name)}<button class=\"rm\" data-i=\"${i}\">×</button></span>`).join('')}${s.uploading?'<span>⏫ enviando…</span>':''}</div>`:''}\n          <div class=\"bar\">\n            <label class=\"clip\" title=\"Anexar fotos/arquivos\">📎<input type=\"file\" class=\"file\" multiple accept=\"image/*,application/pdf,.doc,.docx,.xls,.xlsx,.csv,.txt\"/></label>\n            <textarea class=\"in\" rows=\"1\" placeholder=\"Escreve pro Milo…\" ${thinking?'disabled':''}></textarea>\n            <button class=\"send\" ${thinking||s.uploading?'disabled':''}>Enviar</button>\n          </div>\n          <div class=\"hint\">O Milo não executa nada: ele registra a task. O Claude pega as tasks em aberto, faz e responde aqui ✨</div>\n        </div>\n      </section>\n      <aside class=\"side\">\n        <div class=\"sh\">📋 Tasks <small><button class=\"tgb to-chat\" style=\"display:${s.pane==='tasks'?'inline-flex':'none'}\">← chat</button> ${tasks.length} no total</small></div>\n        <div class=\"fs\">${[['abertas','Abertas'],['em andamento','Fazendo'],['feita','Feitas'],['todas','Todas']].map(([k,l])=>`<button class=\"f\" data-tf=\"${k}\" ${f===k?'data-on':''}>${l}${k==='em andamento'?` · ${tasks.filter(t=>t.status==='em andamento').length}`:''}</button>`).join('')}</div>\n        <div class=\"tl\">${shownT.length?shownT.map((t,i)=>{const o=s.openT===t._id;return `<div class=\"t\" data-key=\"${esc(t._id||'pt'+i)}\" data-id=\"${esc(t._id)}\" ${o?'data-open':''}>\n          <div class=\"tt\"><span>${KIND[t.kind]||'📌'}</span><span>${esc(t.title)}</span></div>\n          <div class=\"tm\"><span class=\"chip ${TST[t.status||'pendente']}\">${esc(LBL[t.status||'pendente']||t.status)}</span>#${sid(t._id)} · ${esc(t.createdBy||'')}${t.createdAt?' · '+esc(d2.fmt.relative(t.createdAt)):''}</div>\n          ${o?`<div class=\"td\">${esc(t.description||'')}</div>${t.payload&&Object.keys(t.payload).length?`<pre>${esc(JSON.stringify(t.payload,null,2))}</pre>`:''}${atts(t.attachments)}${t.result?`<div class=\"res\">✨ ${esc(t.result)}</div>`:''}\n            <div class=\"acts\">${(t.status||'pendente')==='feita'?`<button class=\"reopen\" data-id=\"${esc(t._id)}\">Reabrir</button>`:`<button class=\"done\" data-id=\"${esc(t._id)}\">Marcar feita</button>`}<button class=\"cancel\" data-id=\"${esc(t._id)}\">Cancelar</button></div>`:''}\n        </div>`}).join(''):'<div class=\"empty\">🐕💤 Nenhuma task aqui.</div>'}</div>\n      </aside>\n      ${s.zoom?`<div class=\"zoom\"><img src=\"${esc(s.zoom)}\"/></div>`:''}\n    </div>`\n  },\n  mounted(d2){\n    const s=d2.state,M=()=>d2.data('messages'),T=()=>d2.data('tasks')\n    const me=()=>d2.param('me')||'Você'\n    const grow=(el)=>{el.style.height='auto';el.style.height=Math.min(160,el.scrollHeight)+'px'}\n    d2.on('.in','input',(e,el)=>grow(el))\n    d2.on('.sugg button','click',(e,el)=>{const i=d2.$('.in');if(i){i.value=el.dataset.s;i.focus()}})\n    d2.on('.file','change',async(e,el)=>{const files=el.files;if(!files||!files.length)return\n      s.uploading=true\n      try{const add=await uploadAll(d2,[...files])\n        if(!add.length)throw new Error('upload sem url')\n        s.files=[...(s.files||[]),...add]}\n      catch(err){s.upErr=String(err&&err.message||err).slice(0,140);toast(d2,`Não consegui subir o arquivo 😕 (${s.upErr})`)}\n      finally{s.uploading=false;el.value=''}})\n    d2.on('.rm','click',(e,el)=>{const f=(s.files||[]).slice();f.splice(Number(el.dataset.i),1);s.files=f})\n    d2.on('[data-zoom]','click',(e,el)=>{s.zoom=el.dataset.zoom})\n    d2.on('.zoom','click',()=>{s.zoom=null})\n    d2.on('.to-tasks','click',()=>{s.pane='tasks'});d2.on('.to-chat','click',()=>{s.pane='chat'})\n    d2.on('.tchip','click',(e,el)=>d2.setState({openT:el.dataset.task,pane:'tasks',tf:'todas'}))\n    d2.on('.f','click',(e,el)=>{s.tf=el.dataset.tf})\n    d2.on('.t','click',(e,el)=>{if(e.target.closest('button,a,img'))return;s.openT=s.openT===el.dataset.id?null:el.dataset.id})\n    const setT=async(id,status)=>{const t=T().records().find(r=>r._id===id);if(t)await T().update({...t,status})}\n    d2.on('.done','click',(e,el)=>setT(el.dataset.id,'feita'))\n    d2.on('.reopen','click',(e,el)=>setT(el.dataset.id,'pendente'))\n    d2.on('.cancel','click',async(e,el)=>{if(await d2.dialog.confirm('Cancelar essa task?'))setT(el.dataset.id,'cancelada')})\n\n    const send=async()=>{\n      const el=d2.$('.in');const text=(el&&el.value||'').trim();const files=s.files||[]\n      if((!text&&!files.length)||s.thinking||s.uploading)return\n      el.value='';grow(el)\n      const author=me()\n      s.optimistic={role:'user',author,text,attachments:files}\n      s.files=[];s.thinking=true\n      try{\n        const userMsg=await M().create({role:'user',author,text,attachments:files})\n        s.optimistic=null\n        const hist=M().records().slice().sort((a,b)=>stamp(a)-stamp(b)).slice(-60)\n          .map(m=>`[${m.role==='assistant'?'Milo':m.role==='claude'?'Claude (agente)':m.author||'usuário'}] ${m.text||''}${(m.attachments||[]).length?` (anexos: ${m.attachments.map(x=>x.url).join(', ')})`:''}${m.taskId?` → task #${sid(m.taskId)}`:''}`).join('\\n')\n        const tl=T().records().slice(-60).map(t=>OPEN(t)?`#${sid(t._id)} [${LBL[t.status||'pendente']} · EDITÁVEL · tipo ${t.kind||'outro'}] título: ${t.title}\\n   descrição: ${String(t.description||'').slice(0,400)}${t.payload&&Object.keys(t.payload).length?`\\n   payload: ${JSON.stringify(t.payload).slice(0,600)}`:''}`:`#${sid(t._id)} [${LBL[t.status]||t.status} · FECHADA, não pode alterar] ${t.title}`).join('\\n')||'(nenhuma)'\n        const imgs=files.filter(isImg).map(x=>x.url)\n        const prompt=`Hoje é ${new Date().toLocaleDateString('pt-BR',{weekday:'long',day:'2-digit',month:'long',year:'numeric'})}.\\n\\nTASKS JÁ REGISTRADAS:\\n${tl}\\n\\nHISTÓRICO DA CONVERSA (mais antigo → mais novo):\\n${hist}\\n\\nNOVA MENSAGEM de ${author}:\\n${text||'(sem texto, só anexos)'}\\n${files.length?`Anexos desta mensagem: ${files.map(x=>`${x.name} <${x.url}>`).join(', ')}`:''}\\n\\nResponda no formato JSON combinado.`\n        const raw=await d2.assistant(d2.param('scribe')).ask(prompt,{json:true,images:imgs.length?imgs:undefined})\n        const out=parseAnswer(raw)\n        let taskId=''\n        const notes=[];let opTask=''\n        for(const op of (Array.isArray(out.ops)?out.ops:[])){const ref=String(op.id||'').replace('#','').trim();const t=ref&&T().records().find(x=>sid(x._id)===ref||x._id===ref);if(!t){notes.push(`não achei a task #${ref}`);continue}\n          if(!OPEN(t)){notes.push(`a task #${sid(t._id)} já está ${LBL[t.status]||t.status}, então não dá pra mexer nela`);continue}\n          if(op.op==='cancel'){await T().update({...t,status:'cancelada',result:`Cancelada por ${author}${op.reason?': '+op.reason:''}`});opTask=t._id;toast(d2,`🗑️ Task #${sid(t._id)} cancelada`)}\n          else if(op.op==='update'){const ch={};if(op.title)ch.title=String(op.title);if(op.description)ch.description=String(op.description);if(op.kind)ch.kind=op.kind;if(op.payload&&typeof op.payload==='object')ch.payload={...(t.payload||{}),...op.payload};if(files.length)ch.attachments=[...(t.attachments||[]),...files];await T().update({...t,...ch,updatedBy:author});opTask=t._id;toast(d2,`✏️ Task #${sid(t._id)} atualizada`)}}\n        if(out.task&&out.task.title){\n          const tr=await T().create({title:String(out.task.title),description:String(out.task.description||text),kind:out.task.kind||'outro',payload:out.task.payload||{},attachments:files,status:'pendente',createdBy:author,messageId:(userMsg&&userMsg._id)||''})\n          taskId=(tr&&(tr._id||(tr.data&&tr.data._id)))||''\n          if(!taskId){const f=T().records().find(t=>t.title===String(out.task.title)&&t._id);taskId=f?f._id:''}\n        }\n        await M().create({role:'assistant',author:'Milo',text:String(out.reply||'Anotado! 🐾')+(notes.length?`\\n\\n⚠️ ${notes.join('; ')}.`:''),taskId:taskId||opTask})\n        if(taskId)toast(d2,'📌 Task registrada!')\n      }catch(err){\n        s.optimistic=null\n        await M().create({role:'assistant',author:'Milo',text:'Ops, tropecei na coleira 🐕💫 Não consegui processar agora. Tenta mandar de novo?'}).catch(()=>{})\n      }finally{s.thinking=false}\n    }\n    d2.on('.send','click',send)\n    d2.on('.in','keydown',(e)=>{if(e.key==='Enter'&&!e.shiftKey&&!e.isComposing){e.preventDefault();send()}})\n  },\n  updated(d2){const log=d2.$('.log');if(!log)return;const n=log.children.length;if(SEEN.get(d2.root)!==n){SEEN.set(d2.root,n);log.scrollTop=log.scrollHeight}},\n}\n"}},"messages":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"messages"}}}},"tasks":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"tasks"}}}},"scribe":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"scribe"}}}},"drive":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"drive"}}}},"me":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"me"}}}}}}}}}},{"_id":"6abefda80484650e9b1b46c0","component":"data2-core-types@Component","system":"6abed5371a6b03943b9618d7","params":{"extends":"data2-core-primitives@Block","component":"kp-art","package":"katia-party","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"// kp-art — estúdio de artes: gera imagens (assistant draw) no estilo da festa e salva numa galeria (Drive + tabela)\n// params: artist (assistant), drive (service), artworks settings (dataset), me (string)\nfunction esc(s){return String(s??'').replace(/[&<>\"]/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c]))}\nfunction shiba(cls){return `<svg class=\"${cls||''}\" viewBox=\"0 0 120 110\" aria-hidden=\"true\"><path d=\"M22 50 L30 8 L56 32 Z\" fill=\"#E59A55\"/><path d=\"M29 41 L33 18 L48 33 Z\" fill=\"#F8D7B5\"/><path d=\"M98 50 L90 8 L64 32 Z\" fill=\"#E59A55\"/><path d=\"M91 41 L87 18 L72 33 Z\" fill=\"#F8D7B5\"/><ellipse cx=\"60\" cy=\"62\" rx=\"44\" ry=\"40\" fill=\"#E59A55\"/><path d=\"M24 70 Q30 99 60 103 Q90 99 96 70 Q84 58 72 66 Q60 74 48 66 Q36 58 24 70Z\" fill=\"#FFF4E8\"/><ellipse cx=\"44\" cy=\"45\" rx=\"6\" ry=\"4\" fill=\"#FFF4E8\"/><ellipse cx=\"76\" cy=\"45\" rx=\"6\" ry=\"4\" fill=\"#FFF4E8\"/><ellipse cx=\"44\" cy=\"58\" rx=\"4.5\" ry=\"5.5\" fill=\"#3B2A2E\"/><ellipse cx=\"76\" cy=\"58\" rx=\"4.5\" ry=\"5.5\" fill=\"#3B2A2E\"/><circle cx=\"45.5\" cy=\"56\" r=\"1.5\" fill=\"#fff\"/><circle cx=\"77.5\" cy=\"56\" r=\"1.5\" fill=\"#fff\"/><path d=\"M54 72 Q60 68 66 72 Q63 78 60 78 Q57 78 54 72Z\" fill=\"#3B2A2E\"/><path d=\"M52 83 Q56 88 60 83 Q64 88 68 83\" stroke=\"#3B2A2E\" stroke-width=\"2.4\" fill=\"none\" stroke-linecap=\"round\"/><ellipse cx=\"32\" cy=\"74\" rx=\"7\" ry=\"4.5\" fill=\"#F4A7B5\" opacity=\".75\"/><ellipse cx=\"88\" cy=\"74\" rx=\"7\" ry=\"4.5\" fill=\"#F4A7B5\" opacity=\".75\"/></svg>`}\nconst recs=(d2,k)=>{const h=d2.data(k);return h?h.records()||[]:[]}\nconst toast=(d2,m)=>d2.bus.emit('kp:toast',m)\nconst stamp=(r)=>r.createdAt?new Date(r.createdAt).getTime():Number.MAX_SAFE_INTEGER\nconst PRESETS=[\n  ['💌 Convite','Elegant birthday invitation background, pastel blush pink and cream watercolor flowers, soft balloons, delicate gold accents, lots of empty space in the center for text'],\n  ['🐕 Shiba festeira','A cute smiling Shiba Inu wearing a tiny pink party hat next to a pastel birthday cake with thin lit candles, soft watercolor, pastel pink background'],\n  ['📸 Painel de fotos','Photo booth backdrop design, pastel pink balloon garland arch, cream and peach tones, dreamy, elegant, outdoor farm party'],\n  ['🎂 Topo de bolo','Cake topper illustration of a heart in soft pastel pink with tiny flowers and a small Shiba Inu silhouette, flat pastel style, white background'],\n  ['🌸 Mesa posta','Inspiration board of a pastel pink birthday dessert table at a countryside farm, lace tablecloths, macarons, flowers, balloons'],\n  ['🏡 Sítio','Whimsical watercolor illustration of a countryside farm with a lake and a white party tent decorated with pastel pink balloons at golden hour'],\n]\n// 💌 compositor do convite: arte inteira em cima + título e infos embaixo → 1080×1600\nconst DRAWN=new WeakMap()\n// opções do convite: prontos com foto (já com texto) primeiro, depois artes onde o texto entra por cima\nconst INVT=(arts)=>[...arts.filter(a=>a.tag==='convite-foto'),...arts.filter(a=>a.tag==='convite')]\nfunction partyOf(d2){return {p:d2.state.party||{}}} // infos da festa vêm do Rush rsvp-get (leitura) e party-set (gravação)\nfunction rr(c,x,y,w,h,r){c.beginPath();c.moveTo(x+r,y);c.arcTo(x+w,y,x+w,y+h,r);c.arcTo(x+w,y+h,x,y+h,r);c.arcTo(x,y+h,x,y,r);c.arcTo(x,y,x+w,y,r);c.closePath()}\nfunction fit(c,t,max,size,weight,fam){let s=size;do{c.font=`${weight} ${s}px ${fam}`;if(c.measureText(t).width<=max)break;s-=2}while(s>18);return s}\nasync function drawInvite(cv,url,p){const c=cv.getContext('2d'),W=1080,H=1600,S=W-80\n  try{await Promise.all(['600 110px Fredoka','500 30px Fredoka','800 44px Nunito','700 30px Nunito'].map(f=>document.fonts.load(f)))}catch(e){}\n  const bg=c.createLinearGradient(0,0,0,H);bg.addColorStop(0,'#FDE4E7');bg.addColorStop(.6,'#FFF7F5');bg.addColorStop(1,'#FDE3D3');c.fillStyle=bg;c.fillRect(0,0,W,H)\n  if(url){const img=new Image();img.crossOrigin='anonymous';img.src=url;try{await img.decode();c.save();rr(c,40,40,S,S,48);c.clip();const k=Math.max(S/img.width,S/img.height),w=img.width*k,h=img.height*k;c.drawImage(img,40+(S-w)/2,40+(S-h)/2,w,h);c.restore()}catch(e){}}\n  c.strokeStyle='rgba(255,255,255,.9)';c.lineWidth=8;rr(c,40,40,S,S,48);c.stroke()\n  c.textAlign='center'\n  const ctr=(t,y,size,weight,fam,color)=>{c.fillStyle=color;fit(c,t,W-140,size,weight,fam);c.fillText(t,W/2,y)}\n  ctr('V E M   C O M E M O R A R   C O M I G O',1100,30,500,'Fredoka','#B8647A')\n  ctr('Aniversário da Katia',1210,84,600,'Fredoka','#8E4258')\n  ctr((p.dateLabel||'Domingo, 15 de novembro')+'  ·  '+(p.time||'12h00'),1290,40,800,'Nunito','#4A3439')\n  ctr((p.place||'Sítio Recanto dos Lagos')+'  ·  '+String(p.city||'Mogi das Cruzes').split(' - ')[0],1348,36,800,'Nunito','#4A3439')\n  ctr('calçado pra terra e pedra  ·  tem piscina, traga roupa de banho!  ·  protetor e repelente',1412,28,700,'Nunito','#7A5560')\n  const pill='Confirme até '+(p.rsvpDeadlineLabel||'15/10')+' pelo seu link';c.font='800 32px Nunito';const pw=c.measureText(pill).width+64\n  c.fillStyle='#D9879A';rr(c,(W-pw)/2,1462,pw,66,33);c.fill();c.fillStyle='#fff';c.fillText(pill,W/2,1506)\n  const sig='com carinho, Katia (e o Milo)';c.fillStyle='#B8647A';c.font='700 26px Nunito';c.fillText(sig,W/2,1572)\n  const hx=W/2+c.measureText(sig).width/2+22,hy=1560;c.fillStyle='#E79AAB';c.beginPath();c.moveTo(hx,hy+8);c.bezierCurveTo(hx-14,hy-2,hx-8,hy-14,hx,hy-6);c.bezierCurveTo(hx+8,hy-14,hx+14,hy-2,hx,hy+8);c.fill()}\nfunction urlFrom(r){try{if(r&&r.data&&r.data[0])return r.data[0].url||r.data[0].b64_json&&('data:image/png;base64,'+r.data[0].b64_json);if(typeof r==='string'){const j=JSON.parse(r);return j.data&&j.data[0]&&j.data[0].url}}catch(e){}return typeof r==='string'&&/^(https?:|data:image)/.test(r)?r:''}\n\nexport default {\n  css:`\n:host{--bg:var(--k-bg,#FFF7F5);--card:var(--k-card,#FFFFFF);--blush-50:var(--k-blush-50,#FFF1F2);--blush-100:var(--k-blush-100,#FDE4E7);--blush-200:var(--k-blush-200,#F9CDD4);--blush-300:var(--k-blush-300,#F2AEBA);--rose:var(--k-rose,#D9879A);--rose-deep:var(--k-rose-deep,#B8647A);--ink:var(--k-ink,#4A3439);--muted:var(--k-muted,#94797E);--line:var(--k-line,#F3DDE0);--peach:var(--k-peach,#FDE3D3);--lilac:var(--k-lilac,#ECE3F6);--lilac-ink:var(--k-lilac-ink,#6B5390);--shadow:var(--k-shadow,0 6px 24px rgba(184,100,122,.12))}\n*{box-sizing:border-box}\n.wrap{height:100%;overflow:auto;padding:28px clamp(16px,3vw,40px) 90px;font-family:'Nunito',system-ui,sans-serif;color:var(--ink)}\n.inner{max-width:1120px;margin:0 auto;display:grid;gap:18px}\nh2{font:600 30px/1 'Fredoka';margin:0}\n.sub{margin:6px 0 0;color:var(--muted);font-weight:700;font-size:14px}\n.studio{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:16px}\n.card{background:var(--card);border:1px solid var(--line);border-radius:24px;padding:18px;box-shadow:var(--shadow);min-width:0}\ntextarea{width:100%;min-height:130px;resize:vertical;border:1.5px solid var(--line);background:var(--blush-50);border-radius:14px;padding:12px 14px;font:600 15px 'Nunito';color:var(--ink);outline:none}\ntextarea:focus{border-color:var(--blush-300);background:var(--card)}\n.pre{display:flex;flex-wrap:wrap;gap:6px;margin:10px 0 14px}\n.pre button{border:1.5px solid var(--line);background:var(--card);border-radius:999px;padding:7px 12px;font:700 13px 'Nunito';cursor:pointer;color:var(--ink)}\n.pre button:hover{border-color:var(--blush-300)}\n.btn{border:0;border-radius:14px;padding:12px 18px;font:600 15px 'Fredoka';cursor:pointer;background:linear-gradient(135deg,#E79AAB,#D9879A);color:#fff;box-shadow:0 6px 16px rgba(217,135,154,.3)}\n.btn[disabled]{opacity:.55}.ghost{border:1.5px solid var(--line);background:var(--card);color:var(--ink);box-shadow:none}\n.row{display:flex;gap:8px;flex-wrap:wrap;align-items:center}\n.canvas{aspect-ratio:1;border-radius:20px;background:repeating-linear-gradient(45deg,var(--blush-50) 0 14px,var(--bg) 14px 28px);display:grid;place-items:center;overflow:hidden;position:relative;border:1px solid var(--line)}\n.canvas img{width:100%;height:100%;object-fit:cover}\n.canvas .ph{text-align:center;color:var(--muted);font-weight:700;padding:20px}\n.canvas .ph svg{width:90px;height:82px}\n.paint svg{width:96px;height:88px;animation:wig 1s ease-in-out infinite}\n@keyframes wig{0%,100%{transform:rotate(-8deg)}50%{transform:rotate(8deg)}}\n.gal{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:12px}\n.thw{position:relative}.thw i{position:absolute;top:4px;right:4px;background:#4F7A57;color:#fff;font:800 11px 'Nunito',sans-serif;font-style:normal;border-radius:999px;padding:2px 6px}.thw b{position:absolute;left:4px;bottom:4px;background:var(--k-glass2,rgba(255,255,255,.92));color:#B8647A;font:800 10px 'Nunito',sans-serif;border-radius:6px;padding:1px 5px}.fullinv{width:100%;height:auto;border-radius:18px;display:block;box-shadow:var(--shadow)}\n.art{position:relative;border-radius:18px;overflow:hidden;aspect-ratio:1;background:var(--blush-50);border:1px solid var(--line);cursor:zoom-in}\n.art img{width:100%;height:100%;object-fit:cover;display:block}\n.art .cap{position:absolute;left:0;right:0;bottom:0;padding:22px 10px 8px;background:linear-gradient(transparent,rgba(74,52,57,.7));color:#fff;font-size:11px;font-weight:700;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.zoom{position:fixed;inset:0;background:rgba(74,52,57,.8);display:grid;place-items:center;z-index:80;padding:16px}\n.zoom .box{max-width:min(900px,100%);max-height:100%;display:grid;gap:10px;justify-items:center}\n.zoom img{max-width:100%;max-height:75vh;border-radius:16px}\n.zoom p{color:#fff;font-weight:700;font-size:13px;margin:0;text-align:center;max-width:700px}\n.empty{text-align:center;color:var(--muted);font-weight:700;padding:26px 10px;border:2px dashed var(--line);border-radius:22px;background:var(--card)}\n.inv{display:grid;gap:12px}.invgrid{display:grid;grid-template-columns:minmax(0,1fr) 340px;gap:16px;align-items:start}.thumbs{display:grid;grid-template-columns:repeat(auto-fill,minmax(92px,1fr));gap:8px}.th{width:100%;aspect-ratio:1;object-fit:cover;border-radius:12px;cursor:pointer;border:3px solid transparent;display:block}.th.on{border-color:#D9879A}.prev canvas{width:100%;height:auto;border-radius:16px;box-shadow:0 10px 30px rgba(184,100,122,.2);display:block}.tm{flex:1;min-width:200px;border:1.5px solid var(--line);border-radius:12px;padding:10px 12px;font:600 14px 'Nunito';color:var(--ink)}.kw{display:grid;gap:8px}.kw p{margin:6px 0 0;font-weight:800}.kw img{width:100%;height:auto;display:block;border-radius:16px;border:1.5px solid var(--line)}.inuse{font-weight:800;font-size:13px;color:#4F7A57}\n@media (max-width:820px){.invgrid{grid-template-columns:1fr}.studio{grid-template-columns:1fr}.wrap{padding-top:18px}h2{font-size:26px}.gal{grid-template-columns:repeat(2,minmax(0,1fr))}}\n`,\n  render(d2){\n    const s=d2.state\n    const arts=recs(d2,'artworks').slice().sort((a,b)=>stamp(b)-stamp(a))\n    const z=s.zoom&&arts.find(a=>a._id===s.zoom)\n    return `<div class=\"wrap\"><div class=\"inner\">\n      <div><h2>Estúdio de artes 🎨</h2><p class=\"sub\">Gere artes no clima da festa (rosa pastel + shiba) pra convite, painel, topo de bolo… e salve na galeria.</p></div>\n      <div class=\"studio\">\n        <div class=\"card\">\n          <textarea class=\"prompt\" placeholder=\"Descreva a arte (pode ser em português)…\">${esc(s.prompt||'')}</textarea>\n          <div class=\"pre\">${PRESETS.map((p,i)=>`<button data-p=\"${i}\">${p[0]}</button>`).join('')}</div>\n          <div class=\"row\"><button class=\"btn draw\" ${s.busy?'disabled':''}>${s.busy?'Pintando…':'✨ Desenhar'}</button>${s.img&&!s.saved?`<button class=\"btn ghost save\" ${s.saving?'disabled':''}>${s.saving?'Salvando…':'💾 Salvar na galeria'}</button>`:''}${s.img?`<a class=\"btn ghost\" href=\"${esc(s.img)}\" download=\"katia33-arte.png\" target=\"_blank\" rel=\"noopener\" style=\"text-decoration:none\">⬇️ Baixar</a>`:''}</div>\n          ${s.err?`<p class=\"sub\" style=\"color:#B4475F\">${esc(s.err)}</p>`:''}\n        </div>\n        <div class=\"canvas\">${s.busy?`<div class=\"ph paint\">${shiba()}<div>o Milo tá pintando… 🖌️</div></div>`:s.img?`<img src=\"${esc(s.img)}\" alt=\"arte gerada\"/>`:`<div class=\"ph\">${shiba()}<div>Sua arte aparece aqui</div></div>`}</div>\n      </div>\n      ${(()=>{const inv=INVT(arts),{p}=partyOf(d2);if(!inv.length)return ''\n        const isCur=(a)=>p.inviteFull?a.url===p.inviteImage:(a.tag==='convite'&&a.url===p.inviteArt&&!!p.inviteImage)\n        const sel=inv.find(a=>a._id===s.invArt)||inv.find(isCur)||inv[0],foto=sel.tag==='convite-foto'\n        return `<div class=\"card inv\"><div class=\"row\" style=\"justify-content:space-between\"><h2 style=\"font-size:22px\">💌 Convite</h2>${inv.some(isCur)?'<span class=\"inuse\">✓ = convite em uso</span>':'<span class=\"sub\">escolha um convite pronto ou uma arte (o texto entra por cima)</span>'}</div>\n          <div class=\"invgrid\"><div style=\"display:grid;gap:12px;align-content:start\"><div class=\"thumbs\">${inv.map(a=>`<div class=\"thw\"><img class=\"th ${a._id===sel._id?'on':''}\" data-id=\"${esc(a._id)}\" src=\"${esc(a.url)}\" alt=\"\" title=\"${esc(a.prompt||'')}\"/>${isCur(a)?'<i>✓</i>':''}${a.tag==='convite-foto'?'<b>pronto</b>':''}</div>`).join('')}</div>\n            ${foto?'<p class=\"sub\" style=\"margin:0\">Convite pronto: vai do jeito que está, já com todas as infos.</p>':`<div class=\"row\"><input class=\"tm\" value=\"${esc(p.time||'')}\" placeholder=\"Horário (ex.: a partir das 12h)\"/><button class=\"btn ghost savetm\">Salvar horário</button></div>`}\n            <div class=\"row\"><button class=\"btn dlinv\">⬇️ Baixar imagem</button>${isCur(sel)?'<span class=\"inuse\">✓ em uso</span>':`<button class=\"btn ghost useinv\" ${s.saving?'disabled':''}>${s.saving?'Salvando…':'⭐ Usar no convite'}</button>`}</div>\n            <p class=\"sub\" style=\"margin:0\">\"Usar no convite\" coloca essa imagem na página de cada convidado e no envio pelo 📲 da lista.</p></div>\n          <div class=\"prev\">${foto?`<img class=\"fullinv\" src=\"${esc(sel.url)}\" alt=\"convite\"/>`:'<div data-d2-static><canvas class=\"invc\" width=\"1080\" height=\"1600\"></canvas></div>'}</div></div></div>`})()}\n      <div class=\"row\" style=\"justify-content:space-between\"><h2 style=\"font-size:22px\">Galeria</h2><span class=\"sub\">${arts.length} arte${arts.length===1?'':'s'}</span></div>\n      ${arts.length?`<div class=\"gal\">${arts.map((a,i)=>`<div class=\"art\" data-key=\"${esc(a._id||'pa'+i)}\" data-id=\"${esc(a._id)}\"><img src=\"${esc(a.url)}\" loading=\"lazy\" alt=\"\"/><div class=\"cap\">${esc(a.by||'')} · ${esc(a.prompt||'')}</div></div>`).join('')}</div>`:`<div class=\"empty\">🐕💤 Nenhuma arte salva ainda.</div>`}\n      <div class=\"row\" style=\"justify-content:space-between\"><h2 style=\"font-size:22px\">Expressões do Milo</h2><span class=\"sub\">troque o seu no menu do avatar → 🐕 Estilo do Milo</span></div>\n      <div class=\"kw\">${[['Atual','W66oaDHIYNaOFOe5Ij8Hl'],['Kawaii','t0GEPsHpGwtY7MWDPhSXw'],['Chibi','boZqXX1GtMA_epyXdYR9U'],['Desenho animado','KIgeMNjP6zHkoPb9CNXlb']].map(([n,f])=>`<p class=\"sub\">${n}</p><img src=\"https://katia-party.data2.media/file/${f}\" loading=\"lazy\" alt=\"Milo ${n}: feliz, piscadinha, radiante, apaixonado, surpreso, dormindo, pidão, festeiro\"/>`).join('')}</div>\n    </div>\n    ${z?`<div class=\"zoom\"><div class=\"box\"><img src=\"${esc(z.url)}\"/><p>${esc(z.prompt||'')}</p><div class=\"row\"><a class=\"btn\" href=\"${esc(z.url)}\" target=\"_blank\" rel=\"noopener\" style=\"text-decoration:none\">Abrir</a><button class=\"btn ghost del\" data-id=\"${esc(z._id)}\">Excluir</button><button class=\"btn ghost close\">Fechar</button></div></div></div>`:''}\n    </div>`\n  },\n  updated(d2){const cv=d2.$('.invc');if(!cv)return;const A=d2.data('artworks');const inv=((A&&A.records())||[]).filter(a=>a.tag==='convite');const {p}=partyOf(d2)\n    const on=d2.$('.th.on'),art=(on&&inv.find(a=>a._id===on.dataset.id))||inv[0];if(!art)return\n    const key=art.url+'|'+(p.time||'');if(DRAWN.get(d2.root)===key&&cv.dataset.drawn===key)return;DRAWN.set(d2.root,key);cv.dataset.drawn=key;drawInvite(cv,art.url,p)},\n  mounted(d2){\n    const s=d2.state,A=()=>d2.data('artworks')\n    d2.on('.pre button','click',(e,el)=>{const t=d2.$('.prompt');if(t)t.value=PRESETS[Number(el.dataset.p)][1]})\n    d2.on('.draw','click',async()=>{const t=d2.$('.prompt');const p=(t&&t.value||'').trim();if(!p)return\n      d2.setState({busy:true,err:'',img:'',saved:false,prompt:p})\n      try{const r=await d2.assistant(d2.param('artist')).draw(p);let u=urlFrom(r)\n        if(!u){const a=d2.assistant(d2.param('artist'));u=urlFrom(a.answer)}\n        if(!u)throw new Error('sem imagem');d2.setState({img:u})}\n      catch(err){d2.setState({err:'Não consegui desenhar agora 😕 tenta de novo ou muda a descrição.'})}\n      finally{d2.setState({busy:false})}})\n    d2.on('.save','click',async()=>{if(!s.img)return;s.saving=true\n      try{let url=s.img\n        if(url.startsWith('data:')){const [meta,b64]=url.split(',')\n          const r=await d2.rush('upload-file').invoke({base64:b64,contentType:(meta.match(/data:(.*?);/)||[])[1]||'image/png',fileName:`arte-${Date.now()}.png`})\n          const d=r&&r.data?r.data:r;url=(d&&d.url)||url}\n        else{try{const out=await d2.drive(d2.param('drive')).uploadFromUrls([url]);url=(out&&out[0]&&(out[0].fileUrl||out[0].url))||url}catch(e){}}\n        await A().create({prompt:s.prompt,url,by:d2.param('me')||'',tag:''});d2.setState({saved:true});toast(d2,'Arte salva na galeria 🎨')}\n      catch(err){toast(d2,'Não consegui salvar 😕')}finally{s.saving=false}})\n    d2.on('.art','click',(e,el)=>{s.zoom=el.dataset.id})\n    d2.on('.th','click',(e,el)=>{s.invArt=el.dataset.id})\n    const curArt=()=>{const inv=INVT(A().records()),on=d2.$('.th.on');return (on&&inv.find(a=>a._id===on.dataset.id))||inv[0]}\n    const saveParty=async(patch)=>{const r=await d2.rush('party-set').invoke({patch});const d=r&&r.data?r.data:r;if(d&&d.party)d2.state.party=d.party}\n    ;(async()=>{try{const r=await d2.rush('rsvp-get').invoke({c:''});const d=r&&r.data?r.data:r;d2.state.party=(d&&d.party)||{}}catch(e){}})()\n    d2.on('.savetm','click',async()=>{const v=(d2.$('.tm')||{}).value||'';await saveParty({time:v.trim()});DRAWN.delete(d2.root);d2.refresh();toast(d2,'Horário salvo 🕛')})\n    d2.on('.dlinv','click',()=>{const art=curArt();if(art&&art.tag==='convite-foto'){window.open(art.url,'_blank');return}const cv=d2.$('.invc');if(!cv)return;cv.toBlob(b=>{const a=document.createElement('a');a.href=URL.createObjectURL(b);a.download='convite-katia.jpg';a.click();setTimeout(()=>URL.revokeObjectURL(a.href),4000)},'image/jpeg',.92)})\n    d2.on('.useinv','click',async()=>{const cv=d2.$('.invc'),art=curArt();if(!art)return\n      // convite pronto (com foto e texto): vai como está → inviteFull mostra sem recorte na página do convite\n      if(art.tag==='convite-foto'){s.saving=true;try{await saveParty({inviteImage:art.url,inviteArt:art.url,inviteFull:true});toast(d2,'Convite definido ⭐ já aparece pros convidados 💌')}catch(e){toast(d2,'Não consegui salvar o convite 😕')}finally{s.saving=false}return}\n      if(!cv)return;s.saving=true\n      try{const b=await new Promise(r=>cv.toBlob(r,'image/jpeg',.9));const f=new File([b],'convite-katia.jpg',{type:'image/jpeg'})\n        let url='';try{const up=await d2.drive(d2.param('drive')).upload([f]);url=(up&&up[0]&&(up[0].fileUrl||up[0].url))||''}catch(e){}\n        if(!url)throw new Error('upload')\n        await saveParty({inviteImage:url,inviteArt:art.url,inviteFull:false});toast(d2,'Convite definido ⭐ já aparece pros convidados 💌')}\n      catch(e){toast(d2,'Não consegui salvar o convite 😕')}finally{s.saving=false}})\n    d2.on('.close','click',()=>{s.zoom=null})\n    d2.on('.zoom','click',(e)=>{if(e.target.classList.contains('zoom'))s.zoom=null})\n    d2.on('.del','click',async(e,el)=>{const a=A().records().find(r=>r._id===el.dataset.id);if(!a)return;if(!await d2.dialog.confirm('Excluir essa arte?'))return;await A().remove(a);s.zoom=null})\n  },\n}\n"}},"artist":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"artist"}}}},"drive":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"drive"}}}},"artworks":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"artworks"}}}},"me":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"me"}}}}}}}}}},{"_id":"6ac06ecdf716dbfbc7dde26a","component":"data2-core-types@Component","system":"6abed5371a6b03943b9618d7","params":{"extends":"data2-core-primitives@Block","component":"kp-invite","package":"katia-party","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"// kp-invite — página PÚBLICA do convite + RSVP individual (?c=TOKEN).\n// Fala só com os Rush públicos `rsvp-get` / `rsvp-answer` (token aleatório por convidado). Sem params.\nfunction esc(s){return String(s??'').replace(/[&<>\"]/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c]))}\nfunction fonts(){try{if(document.getElementById('kp-fonts'))return;const l=document.createElement('link');l.id='kp-fonts';l.rel='stylesheet';l.href='https://fonts.googleapis.com/css2?family=Fredoka:wght@400;500;600;700&family=Nunito:wght@400;600;700;800&display=swap';document.head.appendChild(l)}catch(e){}}\nfunction shiba(cls){return `<svg class=\"${cls||''}\" viewBox=\"0 0 120 110\" aria-hidden=\"true\"><path d=\"M22 50 L30 8 L56 32 Z\" fill=\"#E59A55\"/><path d=\"M29 41 L33 18 L48 33 Z\" fill=\"#F8D7B5\"/><path d=\"M98 50 L90 8 L64 32 Z\" fill=\"#E59A55\"/><path d=\"M91 41 L87 18 L72 33 Z\" fill=\"#F8D7B5\"/><ellipse cx=\"60\" cy=\"62\" rx=\"44\" ry=\"40\" fill=\"#E59A55\"/><path d=\"M24 70 Q30 99 60 103 Q90 99 96 70 Q84 58 72 66 Q60 74 48 66 Q36 58 24 70Z\" fill=\"#FFF4E8\"/><ellipse cx=\"44\" cy=\"45\" rx=\"6\" ry=\"4\" fill=\"#FFF4E8\"/><ellipse cx=\"76\" cy=\"45\" rx=\"6\" ry=\"4\" fill=\"#FFF4E8\"/><ellipse cx=\"44\" cy=\"58\" rx=\"4.5\" ry=\"5.5\" fill=\"#3B2A2E\"/><ellipse cx=\"76\" cy=\"58\" rx=\"4.5\" ry=\"5.5\" fill=\"#3B2A2E\"/><circle cx=\"45.5\" cy=\"56\" r=\"1.5\" fill=\"#fff\"/><circle cx=\"77.5\" cy=\"56\" r=\"1.5\" fill=\"#fff\"/><path d=\"M54 72 Q60 68 66 72 Q63 78 60 78 Q57 78 54 72Z\" fill=\"#3B2A2E\"/><path d=\"M52 83 Q56 88 60 83 Q64 88 68 83\" stroke=\"#3B2A2E\" stroke-width=\"2.4\" fill=\"none\" stroke-linecap=\"round\"/><ellipse cx=\"32\" cy=\"74\" rx=\"7\" ry=\"4.5\" fill=\"#F4A7B5\" opacity=\".75\"/><ellipse cx=\"88\" cy=\"74\" rx=\"7\" ry=\"4.5\" fill=\"#F4A7B5\" opacity=\".75\"/></svg>`}\n// só o primeiro nome (o nome completo fica na lista); mantém tratamento (D., Dona…) e Maria/Ana compostos\nconst first=(n)=>{const w=String(n||'').split(' (')[0].trim().split(/\\s+/).filter(Boolean);if(w.length<2)return w[0]||'';const a=w[0].toLowerCase().replace(/\\.$/,'');return ['d','dona','dr','dra','sr','sra','seu','tia','tio','maria','ana'].includes(a)?w[0]+' '+w[1]:w[0]}\nconst CAL='https://calendar.google.com/calendar/render?action=TEMPLATE&text='+encodeURIComponent('Aniversário da Katia 🎂')+'&dates=20261115T150000Z/20261115T230000Z&location='+encodeURIComponent('Sítio Recanto dos Lagos, Av. Joaquim Pereira de Carvalho, 985 - Volta Fria, Mogi das Cruzes - SP')+'&details='+encodeURIComponent('A partir das 12h00. Leve roupa de banho, protetor e repelente!')\n\n// favicon + título da aba (o shell do player não usa os campos da Application no tier next)\nfunction favicon(){try{if(window.__kpIco)return;window.__kpIco=1;document.title='Aniversário da Katia 💌'\n  const put=(tag,match,attrs)=>{let el=[...document.head.querySelectorAll(tag)].find(match);if(!el){el=document.createElement(tag);document.head.appendChild(el)}for(const k in attrs)el.setAttribute(k,attrs[k])}\n  put('link',e=>e.rel==='icon',{rel:'icon',type:'image/png',href:'https://katia-party.data2.media/file/NNSRc0zuoPi-b2Y7R0jtP'})\n  put('link',e=>e.rel==='apple-touch-icon',{rel:'apple-touch-icon',href:'https://katia-party.data2.media/file/CwaCSTz_cd4qiS6JYlkN-'})\n  put('meta',e=>e.name==='theme-color',{name:'theme-color',content:'#FBD3DB'})}catch(e){}}\nexport default {\n  css:`\n:host{--bg:#FFF7F5;--card:#FFFFFF;--blush-50:#FFF1F2;--blush-100:#FDE4E7;--blush-200:#F9CDD4;--blush-300:#F2AEBA;--rose:#D9879A;--rose-deep:#B8647A;--ink:#4A3439;--muted:#94797E;--line:#F3DDE0;--sage:#DCEBDD;--sage-ink:#4F7A57;--butter:#FFF2C9;--butter-ink:#8A6D1F;--shadow:0 6px 24px rgba(184,100,122,.12)}\n*{box-sizing:border-box}\n.page{height:100%;overflow:auto;font-family:'Nunito',system-ui,sans-serif;color:var(--ink);background:radial-gradient(900px 500px at 0 0,#FDE4E7,transparent 60%),radial-gradient(800px 500px at 100% 100%,#FDE3D3,transparent 55%),var(--bg);padding:22px 16px 120px}\n.card{max-width:480px;margin:0 auto;background:var(--card);border:1px solid var(--line);border-radius:28px;box-shadow:0 20px 60px rgba(184,100,122,.18);overflow:hidden}\n.art{position:relative;aspect-ratio:1;background:linear-gradient(135deg,#FBD3DB,#FDE3D3 60%,#FFF2C9)}\n.art img{width:100%;height:100%;object-fit:cover;display:block}\n.art.r45{aspect-ratio:4/5}\n.art.full{aspect-ratio:auto}.art.full img{height:auto}\n.art .ov{position:absolute;left:0;right:0;top:9%;text-align:center;color:#8E4258;text-shadow:0 1px 10px rgba(255,255,255,.95)}\n.ov small{font:500 13px 'Fredoka';letter-spacing:3px}\n.ov b{display:block;font:600 46px/1 'Fredoka';margin:6px 0}\n.ov span{font:800 13px 'Nunito'}\n.body{padding:22px 22px 26px;display:grid;gap:16px}\nh1{font:600 26px/1.15 'Fredoka';margin:0;color:var(--rose-deep)}\n.lead{margin:0;font-size:16px;font-weight:700;line-height:1.45}\n.solo{margin:0;font-size:14px;font-weight:700;line-height:1.45;color:var(--rose-deep);background:var(--blush-50);border:1px dashed var(--blush-300);border-radius:16px;padding:10px 14px}\n.info{display:grid;gap:10px;background:var(--blush-50);border-radius:20px;padding:14px 16px}\n.info div{display:flex;gap:10px;align-items:flex-start;font-weight:700;font-size:15px;line-height:1.35}\n.info div span:first-child{font-size:18px;width:24px;text-align:center;flex:none}\n.info small{display:block;font-weight:600;color:var(--muted);font-size:13px}\n.links{display:flex;gap:8px;flex-wrap:wrap}\n.lnk{flex:1;min-width:150px;text-align:center;border:1.5px solid var(--line);background:#fff;border-radius:14px;padding:10px 12px;font:700 14px 'Nunito';color:var(--rose-deep);text-decoration:none}\n.tips{display:grid;gap:8px}\n.tips h3,.rsvp h3{font:600 18px 'Fredoka';margin:0}\n.tip{background:#fff;border:1px dashed var(--blush-300);border-radius:14px;padding:10px 12px;font-weight:700;font-size:14px;line-height:1.4}\n.rsvp{display:grid;gap:10px;border-top:1px solid var(--line);padding-top:16px}\n.dl{font-size:13px;font-weight:800;color:var(--butter-ink);background:var(--butter);border-radius:10px;padding:6px 10px;justify-self:start}\n.btns{display:grid;grid-template-columns:1fr 1fr;gap:10px}\n.btn{border:0;border-radius:16px;padding:15px 10px;font:600 17px 'Fredoka';cursor:pointer;color:#fff;background:linear-gradient(135deg,#E79AAB,#D9879A);box-shadow:0 8px 20px rgba(217,135,154,.35)}\n.btn.no{background:#fff;color:var(--ink);border:1.5px solid var(--line);box-shadow:none}\n.btn[disabled]{opacity:.6}\ntextarea{width:100%;min-height:70px;resize:vertical;border:1.5px solid var(--line);background:var(--blush-50);border-radius:14px;padding:10px 12px;font:600 14px 'Nunito';color:var(--ink);outline:none}\ntextarea:focus{border-color:var(--blush-300);background:#fff}\n.done{border-radius:18px;padding:16px;text-align:center;font-weight:800;font-size:16px;line-height:1.4}\n.done.yes{background:var(--sage);color:var(--sage-ink)}.done.no{background:#EFE7E8;color:#7A6468}\n.done small{display:block;margin-top:6px;font-weight:700;font-size:13px;opacity:.85}\n.change{border:0;background:none;color:var(--rose-deep);font:800 13px 'Nunito';cursor:pointer;text-decoration:underline}\n.sign{text-align:center;color:var(--muted);font-weight:700;font-size:13px}\n.err{text-align:center;font-weight:700;color:var(--muted);padding:6px}\n.load{display:grid;place-items:center;height:60vh;color:var(--muted);font-weight:800}\n.load svg{width:90px;height:82px;animation:wig 1s ease-in-out infinite}\n@keyframes wig{0%,100%{transform:rotate(-8deg)}50%{transform:rotate(8deg)}}\n.milo{position:fixed;right:14px;bottom:-12px;width:80px;height:73px;cursor:pointer;z-index:5;transition:transform .35s cubic-bezier(.3,1.6,.5,1);filter:drop-shadow(0 -4px 10px rgba(184,100,122,.18))}\n.milo:hover,.milo.up{transform:translateY(-16px) rotate(-6deg)}\n.bub{position:fixed;right:96px;bottom:40px;max-width:min(260px,calc(100vw - 120px));background:#fff;border:1px solid var(--line);border-radius:16px 16px 4px 16px;padding:9px 13px;font:600 14px 'Fredoka';color:var(--rose-deep);box-shadow:var(--shadow);z-index:6}\n.conf{position:fixed;top:-30px;font-size:22px;pointer-events:none;animation:fall linear forwards;z-index:9}\n@keyframes fall{to{transform:translateY(110vh) rotate(360deg)}}\n`,\n  render(d2){\n    const s=d2.state\n    if(!s.loaded)return `<div class=\"page\"><div class=\"load\"><div>${shiba()}<div>abrindo seu convite… 💌</div></div></div></div>`\n    const p=s.party||{},ok=s.ok,name=first(s.name)\n    const img=p.inviteArt?`<img src=\"${esc(p.inviteArt)}\" alt=\"Convite da Katia\"/>`\n      :`<div class=\"ov\"><small>VEM COMEMORAR</small><b>Aniversário da Katia</b><span>domingo · 15.11.2026</span></div>`\n    const past=p.rsvpDeadline&&Date.now()>new Date(p.rsvpDeadline+'T23:59:59-03:00').getTime()\n    let rsvp=''\n    if(ok){\n      if(s.status==='confirmado'&&!s.editing)rsvp=`<div class=\"done yes\">Oba! Presença confirmada 🎉<small>Mal podemos esperar pra te ver!</small></div><button class=\"change\">mudar minha resposta</button>`\n      else if(s.status==='não vem'&&!s.editing)rsvp=`<div class=\"done no\">Poxa, que pena! 😢<small>Obrigado por avisar. Se os planos mudarem, é só responder de novo.</small></div><button class=\"change\">mudar minha resposta</button>`\n      else rsvp=`<span class=\"dl\">${past?'O prazo era até '+esc(p.rsvpDeadlineLabel||'')+', mas ainda dá pra avisar 💗':'Confirme até '+esc(p.rsvpDeadlineLabel||'15/10')}</span>\n        <div class=\"btns\"><button class=\"btn yes\" ${s.busy?'disabled':''}>Eu vou! 🎉</button><button class=\"btn no\" ${s.busy?'disabled':''}>Não vou conseguir 😢</button></div>`\n    }\n    return `<div class=\"page\"><div class=\"card\">\n      <div class=\"art${p.inviteFull?' full':''}\">${img}</div>\n      <div class=\"body\">\n        <h1>${ok&&name?`Oi, ${esc(name)}! 💗`:'Oi! 💗'}</h1>\n        <p class=\"lead\">Vou fazer aniversário e quero muito você lá pra comemorar comigo! 🎂</p>\n        ${ok?`<p class=\"solo\">💌 Este convite é individual, feito especialmente pra você. Por isso a confirmação vale só pro seu nome, tá? Qualquer dúvida, fala direto com a Katia 💗</p>`:''}\n        <div class=\"info\">\n          <div><span>📅</span><span>${esc(p.dateLabel||'Domingo, 15 de novembro')}</span></div>\n          <div><span>🕛</span><span>${esc(p.time||'12h00')}</span></div>\n          <div><span>📍</span><span>${esc(p.place||'Sítio Recanto dos Lagos')}<small>${esc(p.address||'')}</small></span></div>\n        </div>\n        <div class=\"links\">${p.maps?`<a class=\"lnk\" href=\"${esc(p.maps)}\" target=\"_blank\" rel=\"noopener\">🗺️ Abrir no mapa</a>`:''}<a class=\"lnk\" href=\"${CAL}\" target=\"_blank\" rel=\"noopener\">🗓️ Salvar na agenda</a></div>\n        ${(p.tips||[]).length?`<div class=\"tips\"><h3>Pra aproveitar bem ☀️</h3>${p.tips.map(t=>`<div class=\"tip\">${esc(t)}</div>`).join('')}</div>`:''}\n        ${ok?`<div class=\"rsvp\"><h3>Você vem? 💌</h3>${rsvp}</div>`:`<div class=\"err\">Esse convite é pessoal 💌 Use o link que a Katia te mandou pra confirmar presença.</div>`}\n        ${s.err?`<div class=\"err\">${esc(s.err)}</div>`:''}\n        <div class=\"sign\">Com carinho, Katia 💗 (e o Milo 🐕)</div>\n      </div></div>\n      ${s.bark?`<div class=\"bub\">${esc(s.bark)}</div>`:''}\n      ${shiba('milo'+(s.bark?' up':''))}\n    </div>`\n  },\n  mounted(d2){\n    fonts();favicon()\n    const s=d2.state\n    let c='';try{c=new URLSearchParams(window.location.search).get('c')||''}catch(e){}\n    s.c=c\n    ;(async()=>{try{const r=await d2.rush('rsvp-get').invoke({c});const d=r&&r.data?r.data:r\n      d2.setState({loaded:true,ok:!!(d&&d.ok),name:d&&d.name,status:d&&d.status,note:(d&&d.note&&d.note!=='undefined')?d.note:'',party:(d&&d.party)||{}})}\n    catch(e){d2.setState({loaded:true,ok:false,party:{},err:'Não consegui abrir o convite agora 😕 tenta de novo daqui a pouquinho.'})}})()\n    const party=()=>{for(let i=0;i<30;i++){const h=document.createElement('div');h.className='conf';h.textContent=['🎉','💗','🎈','🐾','🎂','✨'][i%6];h.style.left=Math.random()*100+'vw';h.style.animationDuration=(2.4+Math.random()*2.4)+'s';h.style.animationDelay=(Math.random()*1)+'s';d2.root.appendChild(h);setTimeout(()=>h.remove(),6000)}}\n    const answer=async(a)=>{const note=s.note||'' // sem campo de recado (conversa é pelo WhatsApp); preserva o que já existir\n      d2.setState({busy:true,err:''})\n      try{const r=await d2.rush('rsvp-answer').invoke({c:s.c,answer:a,note});const d=r&&r.data?r.data:r\n        if(!d||!d.ok)throw new Error('x')\n        d2.setState({status:d.status,note,editing:false});if(a==='sim')party()}\n      catch(e){d2.setState({err:'Ops, não consegui salvar sua resposta 😕 tenta de novo?'})}\n      finally{d2.setState({busy:false})}}\n    d2.on('.btn.yes','click',()=>answer('sim'))\n    d2.on('.btn.no','click',()=>answer('nao'))\n    d2.on('.change','click',()=>{s.editing=true})\n    const barks=['Au! Te espero lá! 🐾','Traz petisco? 🦴','Vai ter piscina! 💦','Eu vou estar de gravatinha 🎀','Confirma logo, vai! 🥺']\n    let n=0,tm\n    d2.on('.milo','click',()=>{d2.state.bark=barks[n++%barks.length];clearTimeout(tm);tm=setTimeout(()=>{d2.state.bark=''},2600)})\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}}}}}]}},{"reference":"ExternalComponentInstancesTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"_id":"5f060d9b1ca96def42f3c40a","displayName":"Builder AuthStrategy","component":"data2-core@AuthenticationStrategy","system":"5e3b796d6228227ca637d0f4","params":{"credentials":[{"component":"data2-core-types@DataSetColumnReference","params":{"column":"email"}},{"component":"data2-core-types@DataSetColumnReference","params":{"column":"password"}},{"component":"data2-core-types@DataSetColumnReference","params":{"column":"status"}}],"verifier":{"component":"data2-core-types@DataSetReference","params":{"reference":"UsersDataSet"}},"sessionShared":{"component":"data2-core-primitives@Boolean","params":{"content":false}},"password":{"disabled":false,"component":"data2-core-types@DataSetColumnReference","params":{"column":"password"}},"email":{"disabled":false,"component":"data2-core-types@DataSetColumnReference","params":{"column":"email"}},"resetPassword":{"resetEmail":{"artboard":{"params":{"preventEvaluation":true,"reference":"nR6Q9d7qdaPtZhJ28Q8Dy"},"component":"data2-core-types@ArtboardReference"}},"resetSuccessEmail":{"artboard":{"params":{"preventEvaluation":true,"reference":"yPCJBTKo8q1Mw0B_3Kpwl"},"component":"data2-core-types@ArtboardReference"}}},"session":[{"component":"data2-core-types@DataSetColumnReference","params":{"column":"name"}},{"component":"data2-core-types@DataSetColumnReference","params":{"column":"email"}},{"component":"data2-core-types@DataSetColumnReference","params":{"column":"password"}},{"component":"data2-core-types@DataSetColumnReference","params":{"column":"status"}}],"sessionMetadata":{"params":{"actions":[{"params":{"compare":{"params":{"subject":{"params":{"components":[{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$user._id"}}}},{"params":{"comparisonSubject":{"component":"data2-core-primitives@String","params":{"content":"active"}},"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$user.status"}}}}},"component":"data2-core-comparison-operators@Equal","displayName":"is active user"}]},"component":"data2-core-logical-operators@And","displayName":"is active and has _id"}},"component":"data2-core-logical-operators@Not"},"then":{"params":{"message":{"component":"data2-core-primitives@String","params":{"content":"Invalid Credentials"}},"code":{"component":"data2-core-primitives@String","params":{"content":"401"}}},"component":"data2-core-types@Error"}},"component":"data2-core-flow@If","displayName":"check $user"},{"params":{"action":{"params":{"pattern":{"component":"data2-core-primitives@String","params":{"content":"@data2.app"}},"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$user.email"}}}}},"component":"data2-core-functions@Includes","displayName":"isData2User"},"resultName":{"component":"data2-core-primitives@String","params":{"content":"is_data2_user"}}},"component":"data2-core-flow@Step"},{"params":{"action":{"params":{"pattern":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$metadata.d2_app"}}}},"subject":[{"component":"data2-core-primitives@String","params":{"content":"management"}}]},"component":"data2-core-functions@Includes","displayName":"isData2App Exception"},"resultName":{"component":"data2-core-primitives@String","params":{"content":"is_data2_app_exception"}}},"component":"data2-core-flow@Step"},{"params":{"resultName":{"component":"data2-core-primitives@String","params":{"content":"has_access"}},"action":{"params":{"compare":{"params":{"components":[{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"is_data2_user"}}}},{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"is_data2_app_exception"}}}}]},"component":"data2-core-logical-operators@Or"},"else":{"params":{"actions":[{"params":{"actions":[{"params":{"compare":{"params":{"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$metadata.system"}}}}},"component":"data2-core-logical-operators@Not"},"then":{"params":{"message":{"component":"data2-core-primitives@String","params":{"content":"Invalid Credentials"}},"code":{"component":"data2-core-primitives@String","params":{"content":"401"}}},"component":"data2-core-types@Error"}},"component":"data2-core-flow@If","displayName":"check $metadata.system"},{"params":{"module":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"WuUa-VKHhW9uYU0E3-mJ8"}},"prop":"filter","args":[{"_id":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$metadata.system"}}}}}]},"component":"data2-core-types@Interaction"},{"params":{"compare":{"params":{"subject":{"component":"data2-core-types@Getter","params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"WuUa-VKHhW9uYU0E3-mJ8"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"data.records.length"}}}}},"component":"data2-core-logical-operators@Not","displayName":"systems not found"},"then":{"params":{"message":{"component":"data2-core-primitives@String","params":{"content":"Invalid Credentials"}},"code":{"component":"data2-core-primitives@String","params":{"content":"401"}}},"component":"data2-core-types@Error"}},"component":"data2-core-flow@If","displayName":"check system found"},{"params":{"actions":[{"params":{"module":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"Ok6Tsu5XkS7r8PyW_7TyW"}},"prop":"filter","args":[{"user":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$user._id"}}}},"organization":{"component":"data2-core-types@Getter","params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"WuUa-VKHhW9uYU0E3-mJ8"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"cursor.current.organization._id"}}}}}]},"component":"data2-core-types@Interaction"},{"params":{"module":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"NqKAY34n2ffFL64zamp7t"}},"prop":"filter","args":[{"user":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$user._id"}}}},"system":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$metadata.system"}}}}}]},"component":"data2-core-types@Interaction"}]},"component":"data2-core-flow@Parallel"}]},"component":"data2-core-flow@Series","displayName":"common setup"},{"params":{"then":{"params":{"content":true},"component":"data2-core-primitives@Boolean"},"else":{"params":{"content":false},"component":"data2-core-primitives@Boolean"},"compare":{"params":{"components":{"params":{"array":{"params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"WuUa-VKHhW9uYU0E3-mJ8"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"data.records"}}},"component":"data2-core-types@Getter"},"mapper":{"disabled":false,"component":"data2-core-functions@Function","params":{"parameters":[{"component":"data2-core-primitives@String","params":{"content":"system"}}],"body":{"params":{"expression":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"system.visibility"}}}},"defaultCase":{"params":{"content":false},"component":"data2-core-primitives@Boolean"},"cases":[{"component":"data2-core-flow@Case","params":{"expression":{"component":"data2-core-primitives@String","params":{"content":"public"}},"value":{"params":{"components":[{"params":{"array":{"params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"Ok6Tsu5XkS7r8PyW_7TyW"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"data.records"}}},"component":"data2-core-types@Getter"},"filter":{"disabled":false,"component":"data2-core-functions@Function","params":{"parameters":[{"component":"data2-core-primitives@String","params":{"content":"member"}}],"body":{"params":{"components":[{"params":{"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"member.organization._id"}}}},"comparisonSubject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"system.organization._id"}}}}},"component":"data2-core-comparison-operators@Equal","displayName":"is org member"},{"params":{"pattern":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"member.role"}}}},"subject":[{"component":"data2-core-primitives@String","params":{"content":"owner"}},{"component":"data2-core-primitives@String","params":{"content":"billing-owner"}},{"component":"data2-core-primitives@String","params":{"content":"admin"}},{"component":"data2-core-primitives@String","params":{"content":"member"}}]},"component":"data2-core-functions@Includes","displayName":"has role with access"}]},"component":"data2-core-logical-operators@And","displayName":"has org member role with access"}}}},"component":"data2-core-functions@ArrayFind","displayName":"is org member"},{"params":{"components":[{"params":{"array":{"params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"Ok6Tsu5XkS7r8PyW_7TyW"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"data.records"}}},"component":"data2-core-types@Getter"},"filter":{"disabled":false,"component":"data2-core-functions@Function","params":{"parameters":[{"component":"data2-core-primitives@String","params":{"content":"member"}}],"body":{"params":{"components":[{"params":{"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"member.organization._id"}}}},"comparisonSubject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"system.organization._id"}}}}},"component":"data2-core-comparison-operators@Equal","displayName":"is org member"},{"params":{"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"member.role"}}}},"comparisonSubject":{"component":"data2-core-primitives@String","params":{"content":"collaborator"}}},"component":"data2-core-comparison-operators@Equal","displayName":"is collaborator"}]},"component":"data2-core-logical-operators@And","displayName":"is org member and collaborator"}}}},"component":"data2-core-functions@ArrayFind","displayName":"is collaborator"},{"params":{"array":{"params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"NqKAY34n2ffFL64zamp7t"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"data.records"}}},"component":"data2-core-types@Getter"},"filter":{"disabled":false,"component":"data2-core-functions@Function","params":{"parameters":[{"component":"data2-core-primitives@String","params":{"content":"access"}}],"body":{"params":{"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"access.system._id"}}}},"comparisonSubject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"system._id"}}}}},"component":"data2-core-comparison-operators@Equal"}}}},"component":"data2-core-functions@ArrayFind","displayName":"has system access"}]},"component":"data2-core-logical-operators@And","displayName":"is collaborator and has system access"}]},"component":"data2-core-logical-operators@Or"}}},{"component":"data2-core-flow@Case","params":{"expression":{"component":"data2-core-primitives@String","params":{"content":"private"}},"value":{"params":{"components":[{"params":{"array":{"params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"Ok6Tsu5XkS7r8PyW_7TyW"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"data.records"}}},"component":"data2-core-types@Getter"},"filter":{"disabled":false,"component":"data2-core-functions@Function","params":{"parameters":[{"component":"data2-core-primitives@String","params":{"content":"member"}}],"body":{"params":{"components":[{"params":{"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"member.organization._id"}}}},"comparisonSubject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"system.organization._id"}}}}},"component":"data2-core-comparison-operators@Equal","displayName":"is org member"},{"params":{"pattern":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"member.role"}}}},"subject":[{"component":"data2-core-primitives@String","params":{"content":"owner"}},{"component":"data2-core-primitives@String","params":{"content":"admin"}}]},"component":"data2-core-functions@Includes","displayName":"is owner/admin"}]},"component":"data2-core-logical-operators@And","displayName":"has org member role with access"}}}},"component":"data2-core-functions@ArrayFind","displayName":"is owner/admin"},{"params":{"components":[{"params":{"array":{"params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"Ok6Tsu5XkS7r8PyW_7TyW"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"data.records"}}},"component":"data2-core-types@Getter"},"filter":{"disabled":false,"component":"data2-core-functions@Function","params":{"parameters":[{"component":"data2-core-primitives@String","params":{"content":"member"}}],"body":{"params":{"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"member.organization._id"}}}},"comparisonSubject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"system.organization._id"}}}}},"component":"data2-core-comparison-operators@Equal"}}}},"component":"data2-core-functions@ArrayFind","displayName":"is org member"},{"params":{"array":{"params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"NqKAY34n2ffFL64zamp7t"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"data.records"}}},"component":"data2-core-types@Getter"},"filter":{"disabled":false,"component":"data2-core-functions@Function","params":{"parameters":[{"component":"data2-core-primitives@String","params":{"content":"access"}}],"body":{"params":{"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"access.system._id"}}}},"comparisonSubject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"system._id"}}}}},"component":"data2-core-comparison-operators@Equal"}}}},"component":"data2-core-functions@ArrayFind","displayName":"has system access"}]},"component":"data2-core-logical-operators@And","displayName":"is member and has system access"}]},"component":"data2-core-logical-operators@Or","displayName":"is owner/admin or has system access"}}}]},"component":"data2-core-flow@Switch"}}}},"component":"data2-core-functions@ArrayMap"}},"component":"data2-core-logical-operators@And","displayName":"has org member for all systems in request"}},"component":"data2-core-flow@If"}]},"component":"data2-core-flow@Series"},"then":{"params":{"content":true},"component":"data2-core-primitives@Boolean"}},"component":"data2-core-flow@If"}},"component":"data2-core-flow@Step"},{"params":{"then":{"system":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$metadata.system"}}}}},"else":{"params":{"message":{"component":"data2-core-primitives@String","params":{"content":"Invalid Credentials"}},"code":{"component":"data2-core-primitives@String","params":{"content":"401"}}},"component":"data2-core-types@Error"},"compare":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"has_access"}}}}},"component":"data2-core-flow@If"}]},"component":"data2-core-flow@Series"},"sessionExpiresIn":{"component":"data2-core-primitives@Number","params":{"content":604800}},"sessionRenewal":{"component":"data2-core-primitives@Boolean","params":{"content":true}},"identityProviders":[{"provider":{"component":"data2-core-primitives@String","params":{"content":"GOOGLE"}},"clientId":{"component":"data2-core-primitives@String","params":{"content":"55470861603-22pvfc1t49lp8cjnbfk71s5ct9hp1q1v.apps.googleusercontent.com"}}}]},"reference":"Data2BuilderAuthentication","updatedAt":"2026-08-06T19:31:23.557Z"},{"_id":"5f060ee51ca96def42f3fbd1","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"UsersTableDataSource"}},"pagination":{"size":{"component":"data2-core-primitives@Number","params":{"content":1}}}},"reference":"UsersDataSet","updatedAt":"2026-03-04T21:16:40.291Z"},{"_id":"68f938cf5fb002e33752a43d","displayName":"InternalApplicationsAuthenticationStrategy","component":"data2-core@AuthenticationStrategy","system":"5e3b796d6228227ca637d0f4","params":{"resetPassword":{"resetEmail":{"artboard":{"params":{"preventEvaluation":true},"component":"data2-core-types@ArtboardReference"}},"resetSuccessEmail":{"artboard":{"params":{"preventEvaluation":true},"component":"data2-core-types@ArtboardReference"}}},"verifier":{"disabled":false,"component":"data2-core-types@DataSetReference","params":{"reference":"InternalApplicationsVerifierDataSet"}},"password":{"disabled":false,"component":"data2-core-types@DataSetColumnReference","params":{"column":"secret"}},"credentials":[{"component":"data2-core-types@FieldReference","params":{"key":"application"}},{"component":"data2-core-types@FieldReference","params":{"key":"secret"}},{"component":"data2-core-types@FieldReference","params":{"key":"status"}}],"session":[{"component":"data2-core-types@FieldReference","params":{"key":"application"}},{"component":"data2-core-types@FieldReference","params":{"key":"secret"}},{"component":"data2-core-types@FieldReference","params":{"key":"status"}}]},"reference":"InternalApplicationsAuthenticationStrategy","updatedAt":"2025-10-22T20:08:54.442Z","createdAt":"2025-10-22T20:04:31.198Z"},{"component":"data2-core@DataSet","reference":"SessionsDataSet","params":{"requiresConfirmation":false,"pk":"key","datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"data2sessionsdatasource"}}}},{"reference":"UsersTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"component":"data2-core@ServerSessionsDataSource","reference":"data2sessionsdatasource","params":{}},{"_id":"5f1600b70528b92601890f75","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"ServiceComponentInstancesTableDataSource"}},"pk":"_id","autoEdit":true,"master":{"params":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"_id"}}},"component":"data2-core-types@DataSetMaster"},"autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}},"policies":{"params":{"allowGet":{"component":"data2-core-primitives@Boolean","params":{"content":true}}},"component":"data2@hkXy-UhMjhyfptdE6_fpW"}},"reference":"ServiceComponentInstancesDataSet","updatedAt":"2025-11-06T21:07:20.208Z","createdAt":"2020-07-20T20:38:15.436Z"},{"_id":"5f1602190528b92601890f7d","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"pagination":{"size":40000},"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"ComponentInstancesTableDataSource"}},"sort":{"_id":1},"pk":"_id","autoEdit":true,"master":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"_id"}}},"autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}},"policies":{"params":{"allowGet":{"component":"data2-core-primitives@Boolean","params":{"content":true}}},"component":"data2@hkXy-UhMjhyfptdE6_fpW"}},"reference":"ComponentInstancesDataSet","updatedAt":"2025-11-06T21:07:07.089Z","createdAt":"2020-07-20T20:44:09.350Z"},{"_id":"5f16017f0528b92601890f7a","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"FileComponentInstancesTableDataSource"}},"pk":"_id","autoEdit":true,"filter":{"domain":{"component":"data2-core-types@Reference","params":{"reference":"clientApplicationDomain"}}},"master":{"params":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"_id"}}},"component":"data2-core-types@DataSetMaster"},"autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}}},"reference":"FileComponentInstancesDataSet","updatedAt":"2023-08-03T16:08:18.193Z","createdAt":"2020-07-20T20:41:35.797Z"},{"_id":"5f1601990528b92601890f7b","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"ApplicationsTableDataSource"}},"pk":"_id","autoEdit":{"component":"data2-core-primitives@Boolean","params":{"content":true}},"master":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"params":{"column":"_id"},"component":"data2-core-types@DataSetColumnReference"}},"autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}}},"reference":"ApplicationsDataSet","updatedAt":"2022-12-13T21:51:13.995Z","createdAt":"2020-07-20T20:42:01.657Z"},{"_id":"5f16172a0528b92601890f85","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"pagination":{"size":{"component":"data2-core-primitives@Number","params":{"content":10000}}},"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"DataComponentInstancesTableDataSource"}},"pk":"_id","autoEdit":true,"master":{"params":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"_id"}}},"component":"data2-core-types@DataSetMaster"},"autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}},"policies":{"params":{"allowGet":{"component":"data2-core-primitives@Boolean","params":{"content":true}}},"component":"data2@hkXy-UhMjhyfptdE6_fpW"}},"reference":"DataComponentInstancesDataSet","updatedAt":"2025-11-06T21:07:12.831Z","createdAt":"2020-07-20T22:14:02.097Z"},{"_id":"60ddc1bbda3861ca65407c5a","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"FileComponentInstancesTableDataSource"}},"pk":"_id","autoEdit":true,"filter":{"domain":{"component":"data2-core-types@Reference","params":{"reference":"clientApplicationDomain"}}},"pagination":{"size":1},"master":{"params":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"_id"}}},"component":"data2-core-types@DataSetMaster"}},"reference":"OneFileComponentInstancesDataSet","updatedAt":"2022-02-09T19:44:38.036Z","createdAt":"2020-07-20T20:41:35.797Z"},{"_id":"63ee3d38b8c9838c62fb05fb","displayName":"DriveFileComponentInstancesDataSet","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"FileComponentInstancesTableDataSource"}},"pk":"_id","autoEdit":true,"filter":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core@Drive"}}},"master":{"params":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"_id"}}},"component":"data2-core-types@DataSetMaster"},"autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}}},"reference":"DriveFileComponentInstancesDataSet","updatedAt":"2025-12-04T21:58:32.367Z","createdAt":"2023-02-16T14:27:07.797Z"},{"reference":"ServiceComponentInstancesTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[{"_id":"6abf06d627cc7cea8f5b99c2","component":"data2-rush@HTTPListener","reference":"upload-file","system":"6abed5371a6b03943b9618d7","params":{}},{"_id":"6ac06e29c1d9b5fa79c9fe10","component":"data2-rush@HTTPListener","reference":"rsvp-get","system":"6abed5371a6b03943b9618d7","params":{}},{"_id":"6ac070821a6b03943b9936e0","component":"data2-rush@HTTPListener","reference":"party-set","system":"6abed5371a6b03943b9618d7","params":{}},{"_id":"6ac06e2a6ef68381dfeda8c2","component":"data2-rush@HTTPListener","reference":"rsvp-answer","system":"6abed5371a6b03943b9618d7","params":{}},{"_id":"6abef890ea8ac94fb0929594","component":"data2-rush@HTTPListener","reference":"do-reset","system":"6abed5371a6b03943b9618d7","params":{}},{"_id":"6abef88e6ef68381dfeaed1d","component":"data2-rush@HTTPListener","reference":"request-reset","system":"6abed5371a6b03943b9618d7","params":{}},{"_id":"6abef836ea8ac94fb09294f4","component":"data2-core-ai@Assistant","reference":"party-artist","system":"6abed5371a6b03943b9618d7","params":{"model":"cerebras","_context":"You create soft, charming illustrations for Katia's 33rd birthday party. Default art direction: pastel blush pink, cream and peach palette, gentle watercolor or flat-pastel style, cute and elegant. When it fits, include Milo, the couple's friendly red Shiba Inu dog. No text in the image unless explicitly requested.","creativity":80}},{"_id":"6abef835e9fa96de8a9fbaf0","component":"data2-core-ai@Assistant","reference":"party-scribe","system":"6abed5371a6b03943b9618d7","params":{"model":"cerebras","_context":"Você é o \"Milo\", o shiba inu de verdade do Danilo e da Katia, agora trabalhando como assistente do backoffice da festa de 33 anos da Katia (15/11/2026, Sítio Recanto dos Lagos, Mogi das Cruzes). Quem fala com você: Danilo e Katia, seus humanos e os organizadores. Você é um cachorrinho simpático, leal e animado (pode soltar um \"au!\" ou 🐾 de vez em quando, sem exagero). Fale de si no masculino.\n\nSEU TRABALHO: cuidar da FILA DE TASKS do Claude. Você NÃO executa nada e NÃO precisa resolver o pedido. Quem faz o trabalho é o Claude (um agente), que lê as tasks e os anexos e executa no sistema. Depois ele responde no chat com o papel \"Claude (agente)\". Você pode: CRIAR task, ALTERAR task aberta, CANCELAR task aberta.\n\nComo trabalhar:\n1. Leia o histórico da conversa e a lista de tasks (vem no contexto). Cada task tem um id curto (#xxxxxx) e um status: \"na fila\" e \"fazendo\" são ABERTAS (EDITÁVEIS); \"feita\" e \"cancelada\" são FECHADAS.\n2. CRIAR: assim que der pra entender O QUE fazer, crie a task. Coloque em `payload` o que você tirar do TEXTO (nomes, valores, fornecedores, datas) e liste os anexos em payload.attachments. Convidados são sempre convites individuais: 1 pessoa por item, sem adultos/crianças. Cada convidado pode ter grupo: Família, Amigos, Salão ou Extra (Extra = agregado/acompanhante; anote de quem ele é agregado, pelo nome ou nº da lista). Status possíveis: em dúvida, a convidar, convidado, confirmado, não vem.\n3. ANEXOS (fotos, prints, PDFs): você NÃO consegue ver o conteúdo, mas o Claude consegue. NUNCA peça pra pessoa digitar o que está no anexo e nunca diga que viu a imagem. Anexo + pedido = crie a task na hora, dizendo que o Claude deve ler os anexos.\n4. ALTERAR: se a pessoa quer mudar, corrigir ou complementar uma task ABERTA, use uma op \"update\" com o id dela (não crie task nova). Mande só os campos que mudam; description deve ser a descrição COMPLETA já atualizada.\n5. CANCELAR/DELETAR: se a pessoa quer apagar, cancelar ou desistir de uma task ABERTA, use uma op \"cancel\" com o id.\n6. Task FECHADA (feita/cancelada) não pode ser alterada nem cancelada: explique com carinho e PERGUNTE se a pessoa quer que você crie uma task nova (não crie sem ela confirmar).\n7. Se não ficar claro QUAL task a pessoa quer mexer, pergunte citando as opções (#id + título) e não faça nenhuma op.\n8. Pergunte só quando faltar algo essencial que NÃO está nem no texto nem nos anexos. Conversa ou agradecimento: responda simpático, sem task nem ops.\n\nTipos (kind): \"convidados\", \"orcamento\", \"cotacao\", \"design\", \"convite\", \"lembrete\", \"outro\".\n\nResponda SEMPRE em português do Brasil, com mensagens curtas e calorosas.","behaviour":"Responda APENAS com JSON válido, sem markdown, no formato:\n{\"reply\": \"texto curto para o usuário (pode usar emoji)\", \"task\": null | {\"title\": \"título curto e acionável\", \"kind\": \"convidados|orcamento|cotacao|design|convite|lembrete|outro\", \"description\": \"descrição completa e autossuficiente do que o Claude deve fazer, com o contexto da conversa\", \"payload\": { ...dados extraídos... }}, \"ops\": [ {\"op\": \"update\", \"id\": \"#xxxxxx\", \"title\"?: \"...\", \"description\"?: \"...\", \"kind\"?: \"...\", \"payload\"?: { ... }} | {\"op\": \"cancel\", \"id\": \"#xxxxxx\", \"reason\": \"...\"} ]}\nUse \"ops\": [] quando não for mexer em task existente. Ao criar task, o reply NUNCA diz que a coisa já foi feita: diga que ANOTOU pro Claude fazer e resuma o que entendeu. Ao alterar ou cancelar, confirme qual task (#id + título) e o que mudou.","creativity":40,"json":true}}]}},{"reference":"ComponentInstancesTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[{"_id":"6abefa0a492457561460b240","component":"data2-core-primitives@Router","system":"6abed5371a6b03943b9618d7","displayName":"Main Router","params":{"routerType":{"component":"data2-core-primitives@String","params":{"content":"browser"}},"routes":[{"component":"data2-core-primitives@Route","params":{"path":"","name":"Katia Party · Backoffice","content":{"component":"data2-core-types@ArtboardReference","params":{"reference":"JiKgVr-_3uwtI_BcMS_gb"}},"policies":[{"component":"data2-core-auth@Policy","params":{"authenticationStrategy":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"partyAuth"}}}}]}}],"login":{"component":"data2-core-types@ArtboardReference","params":{"reference":"WEHpVgWWJ6UsN0I4hUW-M"}}},"reference":"MainRouter"},{"_id":"6abefa0056470c270674bb6e","component":"data2-core-primitives@Artboard","system":"6abed5371a6b03943b9618d7","displayName":"Login","params":{"title":{"component":"data2-core-primitives@String","params":{"content":"Login"}},"dimensions":{"component":"data2-core-types@Dimensions","params":{"width":1440,"height":900}},"position":{"component":"data2-core-types@Position","params":{"x":0,"y":0}}},"reference":"WEHpVgWWJ6UsN0I4hUW-M"},{"_id":"6abefa01c1d9b5fa79c741b2","component":"data2-core-primitives@Artboard","system":"6abed5371a6b03943b9618d7","displayName":"Backoffice","params":{"title":{"component":"data2-core-primitives@String","params":{"content":"Backoffice"}},"dimensions":{"component":"data2-core-types@Dimensions","params":{"width":1440,"height":900}},"position":{"component":"data2-core-types@Position","params":{"x":0,"y":0}}},"reference":"JiKgVr-_3uwtI_BcMS_gb"},{"_id":"a5611d5576109431776d2460","parent":"6abefa0056470c270674bb6e","component":"katia-party@kp-login","system":"6abed5371a6b03943b9618d7","displayName":"Login","params":{"auth":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"partyAuth"}},"requestReset":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"request-reset"}},"doReset":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"do-reset"}},"super":{"position":{"component":"data2-core-types@Position","params":{"x":0,"y":0,"freeTransform":true,"left":true,"right":true,"top":true,"bottom":true}},"dimensions":{"component":"data2-core-types@Dimensions","params":{"width":1440,"height":900}}}},"reference":"A1V4W_XIkcP-r8Bg5WwCW"},{"_id":"86ce5f6442be86bee0393eb8","parent":"6abefa01c1d9b5fa79c741b2","component":"katia-party@kp-app","system":"6abed5371a6b03943b9618d7","displayName":"App Shell","params":{"auth":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"partyAuth"}},"requestReset":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"request-reset"}},"items":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"itemsDataSet"}},"quotes":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"quotesDataSet"}},"guests":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"guestsDataSet"}},"messages":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"messagesDataSet"}},"tasks":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"tasksDataSet"}},"settings":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"settingsDataSet"}},"artworks":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"artworksDataSet"}},"scribe":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"party-scribe"}},"artist":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"party-artist"}},"drive":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"party-files"}},"vSummary":"katia-party@kp-summary","super":{"position":{"component":"data2-core-types@Position","params":{"x":0,"y":0,"freeTransform":true,"left":true,"right":true,"top":true,"bottom":true}},"dimensions":{"component":"data2-core-types@Dimensions","params":{"width":1440,"height":900}}},"vBudget":"katia-party@kp-budget","vGuests":"katia-party@kp-guests","vChat":"katia-party@kp-chat","vArt":"katia-party@kp-art","uploader":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"upload-file"}}},"reference":"GNJq5QcYxce2-LFrk85PJ"}]}},{"_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":"6abefa0fce21b725b3149f27","displayName":"Katia Party · Backoffice","reference":"kWFnGg3rARV2jEDnURLpr","params":{"domain":{"component":"data2-core-primitives@String","params":{"content":"backoffice"}},"entryPoint":{"component":"data2-core-types@ComponentInstanceReference","params":{"component":"data2-core-primitives@Router","reference":"MainRouter"}}},"system":"6abed5371a6b03943b9618d7","component":"data2-core-primitives@Application"}]}},{"reference":"DataComponentInstancesTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[{"_id":"6abef7e1ea8ac94fb092942e","component":"data2-core@Data2TableDataSource","system":"6abed5371a6b03943b9618d7","params":{"table":"items","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":"glyph","title":"Emoji","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":"notes","title":"Observações","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"sort","title":"Ordem","component":"data2-core-primitives@Number"}},{"component":"data2-core-types@Field","params":{"key":"free","title":"Grátis","component":"data2-core-primitives@Boolean"}},{"component":"data2-core-types@Field","params":{"key":"estimate","title":"Estimativa","component":"data2-core-primitives@Boolean"}}]},"reference":"items"},{"_id":"6abef7e456470c270674b6f8","component":"data2-core@Data2TableDataSource","system":"6abed5371a6b03943b9618d7","params":{"table":"quotes","schema":[{"component":"data2-core-types@Field","params":{"key":"itemId","title":"Item","component":"data2-core-primitives@String","required":true}},{"component":"data2-core-types@Field","params":{"key":"vendor","title":"Fornecedor","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"price","title":"Valor","component":"data2-core-primitives@Number"}},{"component":"data2-core-types@Field","params":{"key":"contact","title":"Contato","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"link","title":"Link","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"notes","title":"Observações","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"chosen","title":"Escolhida","component":"data2-core-primitives@Boolean"}},{"component":"data2-core-types@Field","params":{"key":"attachments","title":"Anexos","component":"data2-core-primitives@Array"}}]},"reference":"quotes"},{"_id":"6abef7e6c5d15a59091ad1fa","component":"data2-core@Data2TableDataSource","system":"6abed5371a6b03943b9618d7","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":"group","title":"Grupo","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"adults","title":"Adultos","component":"data2-core-primitives@Number"}},{"component":"data2-core-types@Field","params":{"key":"kids","title":"Crianças","component":"data2-core-primitives@Number"}},{"component":"data2-core-types@Field","params":{"key":"phone","title":"Telefone","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":"notes","title":"Observações","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"num","title":"Nº","component":"data2-core-primitives@Number"}},{"component":"data2-core-types@Field","params":{"key":"companionOf","title":"Agregado de (nº)","component":"data2-core-primitives@Number"}},{"component":"data2-core-types@Field","params":{"key":"rsvpToken","title":"Token do convite","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"rsvpAt","title":"Respondeu em","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"rsvpNote","title":"Recado","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"invitedAt","title":"Convidado em","component":"data2-core-primitives@String"}}]},"reference":"guests"},{"_id":"6abef7e827cc7cea8f5b6a57","component":"data2-core@Data2TableDataSource","system":"6abed5371a6b03943b9618d7","params":{"table":"tasks","schema":[{"component":"data2-core-types@Field","params":{"key":"title","title":"Título","component":"data2-core-primitives@String","required":true}},{"component":"data2-core-types@Field","params":{"key":"description","title":"Descrição","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":"payload","title":"Dados extraídos","component":"data2-core-primitives@Object"}},{"component":"data2-core-types@Field","params":{"key":"attachments","title":"Anexos","component":"data2-core-primitives@Array"}},{"component":"data2-core-types@Field","params":{"key":"status","title":"Status","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"createdBy","title":"Criado por","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"messageId","title":"Mensagem","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"result","title":"Resultado","component":"data2-core-primitives@String"}}]},"reference":"tasks"},{"_id":"6abef7e956470c270674b707","component":"data2-core@Data2TableDataSource","system":"6abed5371a6b03943b9618d7","params":{"table":"settings","schema":[{"component":"data2-core-types@Field","params":{"key":"key","title":"Chave","component":"data2-core-primitives@String","required":true}},{"component":"data2-core-types@Field","params":{"key":"value","title":"Valor","component":"data2-core-primitives@Object"}}]},"reference":"settings"},{"_id":"6abef7e7ba309d7a9facfa3c","component":"data2-core@Data2TableDataSource","system":"6abed5371a6b03943b9618d7","params":{"table":"messages","schema":[{"component":"data2-core-types@Field","params":{"key":"role","title":"Papel","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"author","title":"Autor","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"text","title":"Texto","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"attachments","title":"Anexos","component":"data2-core-primitives@Array"}},{"component":"data2-core-types@Field","params":{"key":"taskId","title":"Task","component":"data2-core-primitives@String"}}]},"reference":"messages"},{"_id":"6abefa4d0484650e9b1b3371","component":"data2-core@Data2TableDataSource","system":"6abed5371a6b03943b9618d7","params":{"table":"artworks","schema":[{"component":"data2-core-types@Field","params":{"key":"prompt","title":"Prompt","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"url","title":"URL","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"by","title":"Autor","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"tag","title":"Uso","component":"data2-core-primitives@String"}}]},"reference":"artworks"},{"_id":"6abef7f3c1d9b5fa79c73dc1","component":"data2-core@AuthenticationStrategy","system":"6abed5371a6b03943b9618d7","params":{"credentials":[{"key":"email"},{"key":"password"}],"verifier":{"component":"data2-core-types@DataSetReference","params":{"reference":"usersDataSet"}},"email":"email","password":"password","role":"role","roleDefault":"admin"},"reference":"partyAuth"},{"_id":"6abef7e1c5d15a59091ad1df","component":"data2-core@DataSet","system":"6abed5371a6b03943b9618d7","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"users"}}},"reference":"usersDataSet"},{"_id":"6abef7e1ea8ac94fb0929427","component":"data2-core@Data2TableDataSource","system":"6abed5371a6b03943b9618d7","params":{"table":"users","schema":[{"component":"data2-core-types@Field","params":{"key":"email","title":"Email","component":"data2-core-primitives@String","required":true}},{"component":"data2-core-types@Field","params":{"key":"password","title":"Senha","component":"data2-core-types@Password"}},{"component":"data2-core-types@Field","params":{"key":"name","title":"Nome","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"role","title":"Papel","component":"data2-core-primitives@String"}}]},"reference":"users"},{"_id":"6abefa4ece21b725b3149f6e","component":"data2-core@DataSet","system":"6abed5371a6b03943b9618d7","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"artworks"}}},"reference":"artworksDataSet"},{"_id":"6abef7e9c1d9b5fa79c73dac","component":"data2-core@DataSet","system":"6abed5371a6b03943b9618d7","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"settings"}}},"reference":"settingsDataSet"},{"_id":"6abef7e8c5d15a59091ad205","component":"data2-core@DataSet","system":"6abed5371a6b03943b9618d7","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"tasks"}}},"reference":"tasksDataSet"},{"_id":"6abef7e70484650e9b1b2eb6","component":"data2-core@DataSet","system":"6abed5371a6b03943b9618d7","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"messages"}}},"reference":"messagesDataSet"},{"_id":"6abef7e6ce21b725b3149b14","component":"data2-core@DataSet","system":"6abed5371a6b03943b9618d7","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"guests"}}},"reference":"guestsDataSet"},{"_id":"6abef7e4ba309d7a9facfa33","component":"data2-core@DataSet","system":"6abed5371a6b03943b9618d7","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"quotes"}}},"reference":"quotesDataSet"},{"_id":"6abef7e16ef68381dfeaebe6","component":"data2-core@DataSet","system":"6abed5371a6b03943b9618d7","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"items"}}},"reference":"itemsDataSet"}]}},{"reference":"BundlesTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}}],"processesParams":{}}}}