{"context":{"domain":"fernando-playground"},"layers":{"ApplicationLayer":{"reference":"ApplicationLayer","availableInstances":[{"reference":"ComponentsDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"component":"data2-core@DataSet","reference":"SystemsDataSet","params":{"filter":{"domain":"data2"},"pagination":{"size":1},"datasource":{"component":"data2-core-types@ProcessReference","params":{"reference":"SystemsDataSource"}}}},{"reference":"ExternalComponentInstancesDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"reference":"SystemsDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[{"_id":"5e3b796d6228227ca637d0f4","name":"data2","domain":"data2","organization":"62292184611f480b3191c37c","visibility":"public","updatedAt":"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":"66f6c624d8a4a0c67041a910","name":"Fernando Moreira","domain":"fernando-playground","visibility":"public","settings":{"defaultAccessPolicy":"private"},"updatedAt":"2026-08-14T19:26:29.927Z","createdAt":"2024-09-27T12:56:41.025Z"}]}},{"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":"6af890c18b6a65dcd9daf60f","component":"data2-core-types@Component","system":"66f6c624d8a4a0c67041a910","params":{"extends":"data2-core-primitives@Block","component":"mgeo_Pagina_do_medico","package":"fernando-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"// mgeo · Página pública do médico (code component)\n// GEO no cliente: título, meta, canonical, Open Graph e JSON-LD (@graph) injetados no <head>.\n// Dados: rush `api` (mgeo-perfil) devolve só campos públicos. Formulários: rushes `contato` e `avaliar`.\n\nconst DEF = {\n  siteNome: 'Guia Saúde Perto',\n  siteDescricao: 'Diretório de médicos com perfis verificados, valores, convênios e avaliações de pacientes.',\n  baseUrl: 'https://medico-geo.fernando-playground.next.data2.app',\n  slugPadrao: 'dra-helena-duarte-cardiologista-sao-paulo',\n  aviso: 'Perfil fictício criado para testes de GEO no Data2. Não é uma médica real.'\n}\n\nconst ESPEC = {\n  'Cardiologia': 'Cardiovascular', 'Dermatologia': 'Dermatology', 'Pediatria': 'Pediatric',\n  'Ginecologia': 'Gynecologic', 'Obstetrícia': 'Obstetric', 'Ortopedia': 'Musculoskeletal',\n  'Psiquiatria': 'Psychiatric', 'Neurologia': 'Neurologic', 'Endocrinologia': 'Endocrine',\n  'Urologia': 'Urologic', 'Gastroenterologia': 'Gastroenterologic', 'Pneumologia': 'Pulmonary',\n  'Oncologia': 'Oncologic', 'Reumatologia': 'Rheumatologic', 'Otorrinolaringologia': 'Otolaryngologic',\n  'Clínica Médica': 'PrimaryCare'\n}\n\nconst PROF = {\n  'Cardiologia': 'cardiologista', 'Dermatologia': 'dermatologista', 'Pediatria': 'pediatra',\n  'Ginecologia': 'ginecologista', 'Obstetrícia': 'obstetra', 'Ortopedia': 'ortopedista',\n  'Psiquiatria': 'psiquiatra', 'Neurologia': 'neurologista', 'Endocrinologia': 'endocrinologista',\n  'Urologia': 'urologista', 'Gastroenterologia': 'gastroenterologista', 'Pneumologia': 'pneumologista',\n  'Oncologia': 'oncologista', 'Reumatologia': 'reumatologista', 'Otorrinolaringologia': 'otorrinolaringologista',\n  'Oftalmologia': 'oftalmologista', 'Clínica Médica': 'clínico geral'\n}\nconst profissao = (m) => PROF[m.especialidadePrincipal] || String(m.especialidadePrincipal || '').toLowerCase()\nconst cap = (s) => String(s || '').charAt(0).toUpperCase() + String(s || '').slice(1)\n\nconst ERROS = {\n  'consentimento-obrigatorio': 'Marque o consentimento para enviarmos seu pedido.',\n  'nome-invalido': 'Informe seu nome (de 2 a 80 caracteres).',\n  'telefone-invalido': 'Informe um telefone com DDD.',\n  'email-invalido': 'O e-mail parece inválido.',\n  'medico-nao-encontrado': 'Este perfil não está disponível no momento.',\n  'pedido-ja-registrado': 'Já recebemos pedidos deste telefone. A equipe vai retornar em breve.',\n  'nota-invalida': 'Escolha uma nota de 1 a 5.',\n  'texto-invalido': 'Escreva entre 20 e 1.500 caracteres.'\n}\n\nconst FA = {} // valores do formulário de agendamento (não reativo de propósito)\nconst FR = {} // valores do formulário de avaliação\n\nconst esc = (v) => String(v == null ? '' : v)\n  .replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')\n  .replace(/\"/g, '&quot;').replace(/'/g, '&#39;')\nconst arr = (v) => (Array.isArray(v) ? v : [])\nconst digits = (s) => String(s || '').replace(/\\D/g, '')\nconst brl = (n) => (typeof n === 'number'\n  ? n.toLocaleString('pt-BR', { style: 'currency', currency: 'BRL', minimumFractionDigits: 0, maximumFractionDigits: 0 })\n  : '')\nconst fmt1 = (n) => Number(n || 0).toLocaleString('pt-BR', { minimumFractionDigits: 1, maximumFractionDigits: 1 })\nconst dataBR = (iso) => {\n  if (!iso) return ''\n  const d = new Date(iso)\n  if (isNaN(d.getTime())) return ''\n  return d.toLocaleDateString('pt-BR', { day: '2-digit', month: 'long', year: 'numeric', timeZone: 'America/Sao_Paulo' })\n}\nconst isoDia = (iso) => (iso ? String(iso).slice(0, 10) : undefined)\nconst mapsUrl = (l) => 'https://www.google.com/maps/search/?api=1&query=' + encodeURIComponent(\n  (l.lat != null && l.lng != null) ? (l.lat + ',' + l.lng) : [l.logradouro, l.numero, l.bairro, l.cidade, l.uf].join(' '))\nconst waUrl = (n) => 'https://wa.me/' + digits(n)\nconst telUrl = (n) => 'tel:+' + digits(n)\nconst enderecoTxt = (l) => [\n  [l.logradouro, l.numero].filter(Boolean).join(', ') + (l.complemento ? ' - ' + l.complemento : ''),\n  l.bairro, [l.cidade, l.uf].filter(Boolean).join(' - '), l.cep ? 'CEP ' + l.cep : ''\n].filter(Boolean).join(', ')\nconst nomeExib = (m) => (m.tratamento ? m.tratamento + ' ' : '') + m.nome\nconst anosExp = (m) => (m.anoInicioCarreira ? (new Date().getFullYear() - Number(m.anoInicioCarreira)) : null)\nconst unwrap = (r) => (r && typeof r === 'object' && r.data && typeof r.data === 'object' && ('ok' in r.data)) ? r.data : r\nconst estrelas = (n, cls) => `<span class=\"stars ${cls || ''}\" style=\"--v:${Math.max(0, Math.min(100, (Number(n) || 0) / 5 * 100))}%\" aria-hidden=\"true\">★★★★★</span>`\n\nfunction cfg(d2) {\n  let st = null\n  try { st = d2.store('cfg') } catch (e) { st = null }\n  const g = (k) => {\n    try {\n      const v = st ? st.get(k) : undefined\n      return (v === undefined || v === null || v === '') ? DEF[k] : v\n    } catch (e) { return DEF[k] }\n  }\n  return {\n    siteNome: g('siteNome'), siteDescricao: g('siteDescricao'),\n    baseUrl: String(g('baseUrl')).replace(/\\/+$/, ''), slugPadrao: g('slugPadrao'), aviso: g('aviso')\n  }\n}\n\nfunction slugDaUrl() {\n  try {\n    const seg = String(location.pathname || '').split('/').filter(Boolean)[0] || ''\n    return /^[a-z0-9-]{3,120}$/.test(seg) ? seg : ''\n  } catch (e) { return '' }\n}\n\nfunction stats(av) {\n  const n = av.length\n  if (!n) return { n: 0, media: 0, pont: 0, aten: 0, estr: 0, dist: [] }\n  const med = (k) => av.reduce((s, a) => s + (Number(a[k]) || 0), 0) / n\n  const dist = [5, 4, 3, 2, 1].map((k) => ({ k, c: av.filter((a) => Math.round(Number(a.nota)) === k).length }))\n  return { n, media: med('nota'), pont: med('notaPontualidade'), aten: med('notaAtencao'), estr: med('notaEstrutura'), dist }\n}\n\nfunction principalDe(p) {\n  const ls = arr(p.locais)\n  return ls.find((l) => l.principal) || ls[0] || {}\n}\n\nfunction faixaPreco(p) {\n  const v = arr(p.servicos).map((s) => Number(s.preco)).filter((x) => x > 0)\n  if (!v.length) return undefined\n  return brl(Math.min.apply(null, v)) + ' - ' + brl(Math.max.apply(null, v))\n}\n\n// ---------- GEO: textos de head ----------\nfunction tituloPagina(p, c) {\n  const m = p.medico\n  const pr = principalDe(p)\n  return `${nomeExib(m)} - ${cap(profissao(m))} em ${pr.cidade || ''} | CRM-${m.crmUf} ${m.crm} | ${c.siteNome}`\n}\n\nfunction descricaoPagina(p) {\n  const m = p.medico\n  const st = stats(arr(p.avaliacoes))\n  const bairros = arr(p.locais).map((l) => l.bairro).filter(Boolean).join(' e ')\n  const pr = principalDe(p)\n  let d = `${nomeExib(m)}, ${profissao(m)} em ${pr.cidade || ''}${bairros ? ' (' + bairros + ')' : ''}.`\n  if (st.n) d += ` Nota ${fmt1(st.media)} de 5 em ${st.n} avaliações.`\n  if (m.valorConsulta) d += ` Consulta ${brl(m.valorConsulta)}${m.atendeTeleconsulta && m.valorTeleconsulta ? ', teleconsulta ' + brl(m.valorTeleconsulta) : ''}.`\n  if (arr(m.convenios).length) d += ` Convênios: ${arr(m.convenios).join(', ')}.`\n  return d.length > 300 ? d.slice(0, 297) + '...' : d\n}\n\nfunction grafo(p, c) {\n  const m = p.medico\n  const url = c.baseUrl + '/' + m.slug\n  const idMed = url + '#medico'\n  const idPessoa = url + '#pessoa'\n  const idPag = url + '#pagina'\n  const idSite = c.baseUrl + '/#site'\n  const idBread = url + '#breadcrumb'\n  const st = stats(arr(p.avaliacoes))\n  const pr = principalDe(p)\n  const esp = ESPEC[m.especialidadePrincipal]\n  const postal = (l) => ({\n    '@type': 'PostalAddress',\n    streetAddress: [l.logradouro, l.numero].filter(Boolean).join(', ') + (l.complemento ? ' - ' + l.complemento : ''),\n    addressLocality: l.cidade, addressRegion: l.uf, postalCode: l.cep, addressCountry: 'BR'\n  })\n  const geo = (l) => (l.lat != null && l.lng != null) ? { '@type': 'GeoCoordinates', latitude: l.lat, longitude: l.lng } : undefined\n  const horarios = (l) => arr(l.horarios).map((h) => ({\n    '@type': 'OpeningHoursSpecification', dayOfWeek: 'https://schema.org/' + h.dia, opens: h.abre, closes: h.fecha\n  }))\n\n  const locais = arr(p.locais).map((l) => ({\n    '@type': l.tipo === 'Clínica' ? 'MedicalClinic' : 'PhysiciansOffice',\n    '@id': url + '#local-' + l.id,\n    name: l.nome,\n    address: postal(l),\n    geo: geo(l),\n    hasMap: mapsUrl(l),\n    telephone: l.telefone,\n    openingHoursSpecification: horarios(l),\n    amenityFeature: arr(l.acessibilidade).map((a) => ({ '@type': 'LocationFeatureSpecification', name: a, value: true })),\n    medicalSpecialty: esp ? 'https://schema.org/' + esp : undefined,\n    isAccessibleForFree: false,\n    publicAccess: true,\n    description: [l.comoChegar, l.estacionamento].filter(Boolean).join(' ')\n  }))\n\n  const avaliacoes = arr(p.avaliacoes)\n  const reviews = avaliacoes.slice(0, 10).map((a) => ({\n    '@type': 'Review',\n    author: { '@type': 'Person', name: a.autorNome },\n    datePublished: isoDia(a.dataConsulta),\n    name: a.titulo,\n    reviewBody: a.texto,\n    reviewRating: { '@type': 'Rating', ratingValue: a.nota, bestRating: 5, worstRating: 1 }\n  }))\n\n  const ofertas = arr(p.servicos).map((s) => {\n    const item = { '@type': s.categoria === 'Exame' ? 'MedicalTest' : (s.categoria === 'Consulta' ? 'Service' : 'MedicalProcedure'), name: s.nome, description: s.descricao }\n    const o = { '@type': 'Offer', itemOffered: item, priceCurrency: 'BRL', availability: 'https://schema.org/InStock' }\n    if (s.precoAPartirDe) o.priceSpecification = { '@type': 'PriceSpecification', minPrice: s.preco, priceCurrency: 'BRL' }\n    else o.price = s.preco\n    return o\n  })\n\n  const identificadores = [{ '@type': 'PropertyValue', propertyID: 'CRM-' + m.crmUf, value: m.crm, name: 'Registro no Conselho Regional de Medicina' }]\n    .concat(arr(m.rqes).map((r) => ({ '@type': 'PropertyValue', propertyID: 'RQE', value: r.numero, name: 'Registro de Qualificação de Especialista - ' + r.especialidade })))\n\n  const sameAs = Object.values(m.redesSociais || {}).filter(Boolean).concat(m.siteProprio ? [m.siteProprio] : [])\n\n  const medico = {\n    '@type': 'IndividualPhysician',\n    '@id': idMed,\n    name: nomeExib(m),\n    alternateName: m.nome,\n    url,\n    image: m.fotoUrl || undefined,\n    description: m.bioCurta,\n    medicalSpecialty: esp ? 'https://schema.org/' + esp : m.especialidadePrincipal,\n    identifier: identificadores,\n    knowsAbout: arr(m.especialidades).concat(arr(m.areasAtuacao), arr(m.condicoesTratadas)),\n    knowsLanguage: arr(m.idiomas),\n    practicesAt: locais.map((l) => ({ '@id': l['@id'] })),\n    address: pr.cidade ? postal(pr) : undefined,\n    geo: geo(pr),\n    telephone: pr.telefone,\n    openingHoursSpecification: horarios(pr),\n    isAcceptingNewPatients: true,\n    priceRange: faixaPreco(p),\n    currenciesAccepted: 'BRL',\n    paymentAccepted: arr(m.formasPagamento).join(', '),\n    areaServed: [{ '@type': 'City', name: pr.cidade }, m.atendeTeleconsulta ? { '@type': 'Country', name: 'Brasil' } : undefined].filter(Boolean),\n    availableService: arr(p.servicos).map((s) => ({ '@type': s.categoria === 'Exame' ? 'MedicalTest' : 'MedicalProcedure', name: s.nome, description: s.descricao })),\n    hasOfferCatalog: { '@type': 'OfferCatalog', name: 'Consultas, exames e programas', itemListElement: ofertas },\n    aggregateRating: st.n ? { '@type': 'AggregateRating', ratingValue: Number(st.media.toFixed(2)), reviewCount: st.n, ratingCount: st.n, bestRating: 5, worstRating: 1 } : undefined,\n    review: reviews.length ? reviews : undefined,\n    founder: { '@id': idPessoa },\n    sameAs: sameAs.length ? sameAs : undefined\n  }\n\n  const formacao = arr(m.formacao)\n  const pessoa = {\n    '@type': 'Person',\n    '@id': idPessoa,\n    name: m.nome,\n    honorificPrefix: m.tratamento,\n    gender: m.genero === 'feminino' ? 'https://schema.org/Female' : (m.genero === 'masculino' ? 'https://schema.org/Male' : undefined),\n    image: m.fotoUrl || undefined,\n    jobTitle: (m.genero === 'feminino' ? 'Médica ' : 'Médico ') + profissao(m),\n    hasOccupation: {\n      '@type': 'Occupation',\n      name: (m.genero === 'feminino' ? 'Médica ' : 'Médico ') + profissao(m),\n      occupationLocation: { '@type': 'City', name: pr.cidade },\n      experienceRequirements: anosExp(m) ? anosExp(m) + ' anos de experiência' : undefined\n    },\n    worksFor: { '@id': idMed },\n    alumniOf: formacao.map((f) => ({ '@type': 'EducationalOrganization', name: f.instituicao })),\n    hasCredential: formacao.map((f) => ({\n      '@type': 'EducationalOccupationalCredential', name: f.tipo + ' em ' + f.curso,\n      credentialCategory: f.tipo, recognizedBy: { '@type': 'EducationalOrganization', name: f.instituicao }, dateCreated: f.anoConclusao ? String(f.anoConclusao) : undefined\n    })).concat(arr(m.certificacoes).map((t) => ({ '@type': 'EducationalOccupationalCredential', name: t, credentialCategory: 'Título/Certificação' }))),\n    memberOf: arr(m.sociedades).map((s) => ({ '@type': 'MedicalOrganization', name: s })),\n    award: arr(m.premios).map((a) => a.titulo + ' (' + a.entidade + ', ' + a.ano + ')'),\n    knowsLanguage: arr(m.idiomas),\n    sameAs: sameAs.length ? sameAs : undefined\n  }\n\n  const artigos = arr(p.conteudos).map((a) => ({\n    '@type': 'Article', '@id': url + '#artigo-' + a.slug, headline: a.titulo, abstract: a.resumo,\n    datePublished: isoDia(a.publicadoEm), dateModified: isoDia(a.revisadoEm || a.publicadoEm),\n    author: { '@id': idPessoa }, keywords: arr(a.tags).join(', '), inLanguage: 'pt-BR',\n    timeRequired: a.tempoLeituraMin ? 'PT' + a.tempoLeituraMin + 'M' : undefined, isPartOf: { '@id': idPag }\n  }))\n\n  const publicacoes = arr(m.publicacoes).map((x) => ({\n    '@type': 'ScholarlyArticle', headline: x.titulo, datePublished: String(x.ano), url: x.url,\n    isPartOf: { '@type': 'Periodical', name: x.veiculo }, author: { '@id': idPessoa }\n  }))\n\n  const faq = {\n    '@type': 'FAQPage', '@id': url + '#faq', isPartOf: { '@id': idPag },\n    mainEntity: arr(p.faq).map((q) => ({ '@type': 'Question', name: q.pergunta, acceptedAnswer: { '@type': 'Answer', text: q.resposta } }))\n  }\n\n  const breadcrumb = {\n    '@type': 'BreadcrumbList', '@id': idBread,\n    itemListElement: [\n      { '@type': 'ListItem', position: 1, name: c.siteNome, item: c.baseUrl + '/' },\n      { '@type': 'ListItem', position: 2, name: m.especialidadePrincipal, item: c.baseUrl + '/?especialidade=' + encodeURIComponent(profissao(m)) },\n      { '@type': 'ListItem', position: 3, name: m.especialidadePrincipal + ' em ' + (pr.cidade || ''), item: c.baseUrl + '/?especialidade=' + encodeURIComponent(profissao(m)) + '&cidade=' + encodeURIComponent(String(pr.cidade || '').toLowerCase()) },\n      { '@type': 'ListItem', position: 4, name: nomeExib(m), item: url }\n    ]\n  }\n\n  const pagina = {\n    '@type': ['ProfilePage', 'MedicalWebPage'], '@id': idPag, url, name: tituloPagina(p, c),\n    description: descricaoPagina(p), inLanguage: 'pt-BR', isPartOf: { '@id': idSite },\n    about: { '@id': idMed }, mainEntity: { '@id': idMed }, breadcrumb: { '@id': idBread },\n    primaryImageOfPage: m.fotoUrl ? { '@type': 'ImageObject', url: m.fotoUrl } : undefined,\n    dateModified: m.atualizadoEm, lastReviewed: m.dataVerificacao,\n    audience: { '@type': 'MedicalAudience', audienceType: 'Patient' },\n    hasPart: artigos.map((a) => ({ '@id': a['@id'] })).concat([{ '@id': url + '#faq' }])\n  }\n\n  const site = { '@type': 'WebSite', '@id': idSite, url: c.baseUrl + '/', name: c.siteNome, description: c.siteDescricao, inLanguage: 'pt-BR' }\n\n  return { '@context': 'https://schema.org', '@graph': [pagina, site, breadcrumb, medico, pessoa].concat(locais, [faq], artigos, publicacoes) }\n}\n\nfunction aplicarHead(d2, p, c) {\n  if (d2.context && d2.context.isBuilder) return // não sujar o head do builder\n  try {\n    const m = p.medico\n    const H = document.head\n    const url = c.baseUrl + '/' + m.slug\n    const titulo = tituloPagina(p, c)\n    const desc = descricaoPagina(p)\n    const pr = principalDe(p)\n    H.querySelectorAll('[data-mgeo]').forEach((n) => n.remove())\n    document.title = titulo\n    document.documentElement.setAttribute('lang', 'pt-BR')\n    const meta = (attr, key, content) => {\n      if (content == null || content === '') return\n      let el = H.querySelector('meta[' + attr + '=\"' + key + '\"]')\n      if (!el) { el = document.createElement('meta'); el.setAttribute(attr, key); el.setAttribute('data-mgeo', '1'); H.appendChild(el) }\n      el.setAttribute('content', String(content))\n    }\n    const link = (rel, href) => {\n      let el = H.querySelector('link[rel=\"' + rel + '\"]')\n      if (!el) { el = document.createElement('link'); el.setAttribute('rel', rel); el.setAttribute('data-mgeo', '1'); H.appendChild(el) }\n      el.setAttribute('href', href)\n    }\n    meta('name', 'description', desc)\n    meta('name', 'robots', 'index, follow, max-snippet:-1, max-image-preview:large')\n    meta('name', 'author', nomeExib(m))\n    meta('property', 'og:type', 'profile')\n    meta('property', 'og:site_name', c.siteNome)\n    meta('property', 'og:locale', 'pt_BR')\n    meta('property', 'og:title', titulo)\n    meta('property', 'og:description', desc)\n    meta('property', 'og:url', url)\n    meta('property', 'og:image', m.fotoUrl)\n    meta('property', 'profile:first_name', String(m.nome || '').split(' ')[0])\n    meta('property', 'profile:last_name', String(m.nome || '').split(' ').slice(1).join(' '))\n    meta('property', 'profile:gender', m.genero === 'feminino' ? 'female' : (m.genero === 'masculino' ? 'male' : ''))\n    meta('name', 'twitter:card', 'summary')\n    meta('name', 'twitter:title', titulo)\n    meta('name', 'twitter:description', desc)\n    meta('name', 'twitter:image', m.fotoUrl)\n    meta('name', 'geo.region', 'BR-' + (pr.uf || ''))\n    meta('name', 'geo.placename', pr.cidade)\n    if (pr.lat != null && pr.lng != null) {\n      meta('name', 'geo.position', pr.lat + ';' + pr.lng)\n      meta('name', 'ICBM', pr.lat + ', ' + pr.lng)\n    }\n    meta('name', 'mgeo-render-client', 'sim') // marcador para o teste: este head veio do JS (o do servidor é 'mgeo-render')\n    link('canonical', url)\n    const s = document.createElement('script')\n    s.type = 'application/ld+json'\n    s.setAttribute('data-mgeo', '1')\n    s.textContent = JSON.stringify(grafo(p, c))\n    H.appendChild(s)\n  } catch (e) {\n    d2.log('mgeo head erro', e && e.message)\n  }\n}\n\nasync function carregar(d2) {\n  const c = cfg(d2)\n  const slug = slugDaUrl() || c.slugPadrao\n  d2.setState({ status: 'loading', slug })\n  try {\n    const r = unwrap(await d2.rush('api').invoke({ slug }))\n    if (!r || !r.ok) { d2.setState({ status: (r && r.erro === 'nao-encontrado') ? 'notfound' : 'error' }); return }\n    d2.setState({ status: 'ready', p: r })\n    aplicarHead(d2, r, c)\n  } catch (e) {\n    d2.log('mgeo perfil erro', e && e.message)\n    d2.setState({ status: 'error' })\n  }\n}\n\nfunction lerForm(form, alvo) {\n  if (!form) return\n  form.querySelectorAll('input, select, textarea').forEach((el) => {\n    if (!el.name) return\n    if (el.type === 'checkbox') alvo[el.name] = !!el.checked\n    else if (el.type === 'radio') { if (el.checked) alvo[el.name] = el.value }\n    else alvo[el.name] = el.value\n  })\n}\n\n// ---------- seções ----------\nconst v = (o, k) => esc(o[k] == null ? '' : o[k])\nconst sel = (o, k, val) => (String(o[k] || '') === String(val) ? ' selected' : '')\nconst chk = (o, k, val) => (String(o[k] || '') === String(val) ? ' checked' : '')\n\nfunction secNav() {\n  const itens = [['resumo', 'Resumo'], ['sobre', 'Sobre'], ['locais', 'Onde atende'], ['servicos', 'Serviços e valores'],\n    ['convenios', 'Convênios'], ['formacao', 'Formação'], ['avaliacoes', 'Avaliações'], ['conteudos', 'Artigos'], ['faq', 'Perguntas'], ['agendar', 'Agendar']]\n  return `<nav class=\"secnav\" aria-label=\"Seções do perfil\"><div class=\"wrap secnav-in\">${itens.map(([id, t]) => `<a href=\"#${id}\" data-ir=\"${id}\">${t}</a>`).join('')}</div></nav>`\n}\n\nfunction secHero(p, c, st) {\n  const m = p.medico\n  const pr = principalDe(p)\n  const exp = anosExp(m)\n  const rqe = arr(m.rqes).map((r) => 'RQE ' + esc(r.numero)).join(' · ')\n  const chips = [m.atendePresencial ? 'Presencial' : '', m.atendeTeleconsulta ? 'Teleconsulta' : '', exp ? exp + ' anos de experiência' : '']\n    .concat(arr(m.idiomas).length ? ['Idiomas: ' + arr(m.idiomas).join(', ')] : []).filter(Boolean)\n  return `\n  <header class=\"hero\" id=\"topo\">\n    <div class=\"wrap\">\n      <nav class=\"bread\" aria-label=\"Você está em\">\n        <ol><li><a href=\"${esc(c.baseUrl)}/\">${esc(c.siteNome)}</a></li><li>${esc(m.especialidadePrincipal)}</li><li>${esc(pr.cidade)}</li><li aria-current=\"page\">${esc(nomeExib(m))}</li></ol>\n      </nav>\n      <div class=\"hero-grid\">\n        <img class=\"foto\" src=\"${esc(m.fotoUrl)}\" alt=\"Foto de ${esc(nomeExib(m))}, ${esc(profissao(m))}\" width=\"132\" height=\"132\" loading=\"eager\">\n        <div class=\"hero-txt\">\n          ${m.verificado ? `<p class=\"selo\">✓ Perfil verificado${m.dataVerificacao ? ' em ' + esc(dataBR(m.dataVerificacao)) : ''}</p>` : ''}\n          <h1>${esc(nomeExib(m))}</h1>\n          <p class=\"sub\">${esc(cap(profissao(m)))} em ${esc(pr.cidade)} - ${esc(pr.uf)} · CRM-${esc(m.crmUf)} ${esc(m.crm)}${rqe ? ' · ' + rqe : ''}</p>\n          ${st.n ? `<p class=\"nota-hero\"><a href=\"#avaliacoes\" data-ir=\"avaliacoes\">${estrelas(st.media)} <strong>${fmt1(st.media)}</strong> de 5 · ${st.n} ${st.n === 1 ? 'avaliação' : 'avaliações'}</a></p>` : ''}\n          <ul class=\"chips\">${chips.map((x) => `<li>${esc(x)}</li>`).join('')}</ul>\n        </div>\n      </div>\n    </div>\n  </header>`\n}\n\nfunction secResumo(p, st) {\n  const m = p.medico\n  const pr = principalDe(p)\n  const exp = anosExp(m)\n  const bairros = arr(p.locais).map((l) => l.bairro).filter(Boolean)\n  const frase = `${nomeExib(m)} é ${m.genero === 'feminino' ? 'médica' : 'médico'} ${profissao(m)} em ${pr.cidade || ''}${exp ? ', com ' + exp + ' anos de experiência' : ''}. ` +\n    `${bairros.length ? 'Atende ' + (m.genero === 'feminino' ? 'na' : 'na') + ' ' + bairros.join(' e no ') : ''}${m.atendeTeleconsulta ? (bairros.length ? ' e' : 'Atende') + ' por teleconsulta para todo o Brasil' : ''}. ` +\n    `${m.valorConsulta ? 'A consulta particular custa ' + brl(m.valorConsulta) + (m.atendeTeleconsulta && m.valorTeleconsulta ? ' (teleconsulta ' + brl(m.valorTeleconsulta) + ')' : '') + '. ' : ''}` +\n    `${arr(m.convenios).length ? 'Aceita ' + arr(m.convenios).join(', ') + '. ' : ''}` +\n    `${st.n ? 'Tem nota ' + fmt1(st.media) + ' de 5 em ' + st.n + ' avaliações de pacientes.' : ''}`\n  const fatos = [\n    ['Especialidade', m.especialidadePrincipal],\n    ['Registro', 'CRM-' + m.crmUf + ' ' + m.crm + (arr(m.rqes).length ? ' · ' + arr(m.rqes).map((r) => 'RQE ' + r.numero + ' (' + r.especialidade + ')').join(', ') : '')],\n    ['Experiência', exp ? exp + ' anos (desde ' + m.anoInicioCarreira + ')' : ''],\n    ['Consulta particular', m.valorConsulta ? brl(m.valorConsulta) + ' · ' + (m.duracaoConsultaMin || '') + ' min' : ''],\n    ['Teleconsulta', m.atendeTeleconsulta ? (m.valorTeleconsulta ? brl(m.valorTeleconsulta) : 'Sim') : 'Não'],\n    ['Retorno', m.retornoDias ? 'Incluso em até ' + m.retornoDias + ' dias' : ''],\n    ['Convênios', arr(m.convenios).join(', ')],\n    ['Idiomas', arr(m.idiomas).join(', ')],\n    ['Endereços', arr(p.locais).map((l) => l.nome + ' (' + l.bairro + ')').join(' · ')],\n    ['Avaliação', st.n ? fmt1(st.media) + ' de 5 (' + st.n + ' avaliações)' : '']\n  ].filter((f) => f[1])\n  return `\n  <section class=\"card\" id=\"resumo\" aria-labelledby=\"t-resumo\">\n    <h2 id=\"t-resumo\">Resumo rápido</h2>\n    <p class=\"lead\">${esc(frase.replace(/\\s+/g, ' ').trim())}</p>\n    <dl class=\"fatos\">${fatos.map(([k, val]) => `<div><dt>${esc(k)}</dt><dd>${esc(val)}</dd></div>`).join('')}</dl>\n  </section>`\n}\n\nfunction secSobre(p) {\n  const m = p.medico\n  return `\n  <section class=\"card\" id=\"sobre\" aria-labelledby=\"t-sobre\">\n    <h2 id=\"t-sobre\">Sobre ${m.genero === 'feminino' ? 'a' : 'o'} ${esc(nomeExib(m))}</h2>\n    <p>${esc(m.bio)}</p>\n    ${m.abordagem ? `<h3>Como é a consulta</h3><p>${esc(m.abordagem)}</p>` : ''}\n    <div class=\"cols3\">\n      <div><h3>Especialidades</h3><ul class=\"tags\">${arr(m.especialidades).map((x) => `<li>${esc(x)}</li>`).join('')}</ul></div>\n      <div><h3>Áreas de atuação</h3><ul class=\"tags\">${arr(m.areasAtuacao).map((x) => `<li>${esc(x)}</li>`).join('')}</ul></div>\n      <div><h3>Público atendido</h3><ul class=\"tags\">${arr(m.publicoAtendido).map((x) => `<li>${esc(x)}</li>`).join('')}</ul></div>\n    </div>\n    <h3>Condições que trata</h3>\n    <ul class=\"lista2\">${arr(m.condicoesTratadas).map((x) => `<li>${esc(x)}</li>`).join('')}</ul>\n  </section>`\n}\n\nfunction secLocais(p) {\n  const locais = arr(p.locais)\n  if (!locais.length) return ''\n  return `\n  <section class=\"card\" id=\"locais\" aria-labelledby=\"t-locais\">\n    <h2 id=\"t-locais\">Onde atende</h2>\n    <div class=\"locais\">\n      ${locais.map((l) => `\n      <article class=\"local\" data-key=\"${esc(l.id)}\">\n        <h3>${esc(l.nome)} ${l.principal ? '<span class=\"pill\">Principal</span>' : ''}</h3>\n        <address>${esc(enderecoTxt(l))}</address>\n        <table class=\"horas\"><caption>Horários</caption><tbody>\n          ${arr(l.horarios).map((h) => `<tr><th scope=\"row\">${esc(h.diaPt || h.dia)}</th><td><time>${esc(h.abre)}</time> às <time>${esc(h.fecha)}</time></td></tr>`).join('')}\n        </tbody></table>\n        ${arr(l.acessibilidade).length ? `<p><strong>Acessibilidade:</strong> ${esc(arr(l.acessibilidade).join(', '))}</p>` : ''}\n        ${l.estacionamento ? `<p><strong>Estacionamento:</strong> ${esc(l.estacionamento)}</p>` : ''}\n        ${l.comoChegar ? `<p><strong>Como chegar:</strong> ${esc(l.comoChegar)}</p>` : ''}\n        <p class=\"acoes\">\n          <a class=\"btn sec\" href=\"${esc(mapsUrl(l))}\" target=\"_blank\" rel=\"noopener\">Ver no mapa</a>\n          ${l.whatsapp ? `<a class=\"btn sec\" href=\"${esc(waUrl(l.whatsapp))}\" target=\"_blank\" rel=\"noopener\">WhatsApp</a>` : ''}\n          ${l.telefone ? `<a class=\"btn sec\" href=\"${esc(telUrl(l.telefone))}\">Ligar ${esc(l.telefone)}</a>` : ''}\n        </p>\n      </article>`).join('')}\n    </div>\n  </section>`\n}\n\nfunction secServicos(p) {\n  const sv = arr(p.servicos)\n  if (!sv.length) return ''\n  return `\n  <section class=\"card\" id=\"servicos\" aria-labelledby=\"t-serv\">\n    <h2 id=\"t-serv\">Serviços e valores</h2>\n    <div class=\"tabela-wrap\"><table class=\"serv\">\n      <thead><tr><th scope=\"col\">Serviço</th><th scope=\"col\">Duração</th><th scope=\"col\">Valor particular</th><th scope=\"col\">Convênio</th></tr></thead>\n      <tbody>\n        ${sv.map((s) => `<tr data-key=\"${esc(s.id)}\">\n          <td><strong>${esc(s.nome)}</strong> <span class=\"cat\">${esc(s.categoria)}</span><br><span class=\"mut\">${esc(s.descricao)}</span>\n            ${s.preparo ? `<details><summary>Preparo</summary><p>${esc(s.preparo)}</p></details>` : ''}</td>\n          <td>${s.duracaoMin ? esc(s.duracaoMin) + ' min' : '-'}</td>\n          <td>${s.precoAPartirDe ? 'a partir de ' : ''}<strong>${esc(brl(s.preco))}</strong></td>\n          <td>${s.cobertoConvenio ? 'Sim' : 'Não'}</td>\n        </tr>`).join('')}\n      </tbody>\n    </table></div>\n    <p class=\"mut peq\">Valores particulares informados pelo consultório. Cobertura por convênio depende do plano contratado.</p>\n  </section>`\n}\n\nfunction secConvenios(p) {\n  const m = p.medico\n  return `\n  <section class=\"card\" id=\"convenios\" aria-labelledby=\"t-conv\">\n    <h2 id=\"t-conv\">Convênios e formas de pagamento</h2>\n    <div class=\"cols2\">\n      <div><h3>Convênios aceitos</h3><ul class=\"lista2\">${arr(m.convenios).map((x) => `<li>${esc(x)}</li>`).join('') || '<li>Somente particular</li>'}</ul></div>\n      <div><h3>Pagamento</h3><ul class=\"lista2\">${arr(m.formasPagamento).map((x) => `<li>${esc(x)}</li>`).join('')}</ul>\n        ${m.retornoDias ? `<p>Retorno incluso em até <strong>${esc(m.retornoDias)} dias</strong>.</p>` : ''}</div>\n    </div>\n  </section>`\n}\n\nfunction secFormacao(p) {\n  const m = p.medico\n  const f = arr(m.formacao).slice().sort((a, b) => (a.anoConclusao || 0) - (b.anoConclusao || 0))\n  return `\n  <section class=\"card\" id=\"formacao\" aria-labelledby=\"t-form\">\n    <h2 id=\"t-form\">Formação e credenciais</h2>\n    <ol class=\"timeline\">${f.map((x) => `<li><span class=\"ano\">${esc(x.anoConclusao)}</span><div><strong>${esc(x.tipo)} em ${esc(x.curso)}</strong><br><span class=\"mut\">${esc(x.instituicao)}</span></div></li>`).join('')}</ol>\n    <div class=\"cols2\">\n      <div><h3>Títulos e certificações</h3><ul class=\"lista2\">${arr(m.certificacoes).map((x) => `<li>${esc(x)}</li>`).join('')}</ul></div>\n      <div><h3>Sociedades médicas</h3><ul class=\"lista2\">${arr(m.sociedades).map((x) => `<li>${esc(x)}</li>`).join('')}</ul></div>\n    </div>\n    ${arr(m.premios).length ? `<h3>Prêmios</h3><ul class=\"lista2\">${arr(m.premios).map((a) => `<li>${esc(a.titulo)} - ${esc(a.entidade)}, ${esc(a.ano)}</li>`).join('')}</ul>` : ''}\n    ${arr(m.publicacoes).length ? `<h3>Publicações</h3><ul class=\"pubs\">${arr(m.publicacoes).map((x) => `<li><cite>${esc(x.titulo)}</cite> - ${esc(x.veiculo)}, ${esc(x.ano)}${x.url ? ` · <a href=\"${esc(x.url)}\" target=\"_blank\" rel=\"noopener\">ver</a>` : ''}</li>`).join('')}</ul>` : ''}\n  </section>`\n}\n\nfunction formAvaliar(d2) {\n  const s = d2.state\n  if (s.avStatus === 'ok') return `<div class=\"ok-box\" role=\"status\">Obrigado! Sua avaliação foi recebida e aparece aqui depois da moderação.</div>`\n  return `\n  <form class=\"form av\" novalidate>\n    <div class=\"grid2\">\n      <label>Seu nome (como vai aparecer)<input name=\"autorNome\" maxlength=\"60\" autocomplete=\"name\" value=\"${v(FR, 'autorNome')}\" required></label>\n      <label>Nota geral\n        <select name=\"nota\" required><option value=\"\">Escolha</option>${[5, 4, 3, 2, 1].map((n) => `<option value=\"${n}\"${sel(FR, 'nota', n)}>${n} - ${['', 'Ruim', 'Regular', 'Boa', 'Muito boa', 'Excelente'][n]}</option>`).join('')}</select></label>\n      <label>Título<input name=\"titulo\" maxlength=\"80\" value=\"${v(FR, 'titulo')}\"></label>\n      <label>Atendimento\n        <select name=\"tipoAtendimento\"><option value=\"\">Escolha</option>${['Presencial', 'Teleconsulta'].map((t) => `<option${sel(FR, 'tipoAtendimento', t)}>${t}</option>`).join('')}</select></label>\n    </div>\n    <label>Conte como foi (mínimo 20 caracteres)<textarea name=\"texto\" rows=\"4\" maxlength=\"1500\" required>${v(FR, 'texto')}</textarea></label>\n    <label class=\"hp\" aria-hidden=\"true\">Não preencha<input name=\"website\" tabindex=\"-1\" autocomplete=\"off\" value=\"\"></label>\n    ${s.avErro ? `<p class=\"erro\" role=\"alert\">${esc(s.avErro)}</p>` : ''}\n    <button class=\"btn\" type=\"submit\"${s.avStatus === 'sending' ? ' disabled' : ''}>${s.avStatus === 'sending' ? 'Enviando...' : 'Enviar avaliação'}</button>\n  </form>`\n}\n\nfunction secAvaliacoes(d2, p, st) {\n  const av = arr(p.avaliacoes)\n  const todas = !!d2.state.todasAv\n  const lista = todas ? av : av.slice(0, 4)\n  const barra = (lbl, val) => `<div class=\"sub-nota\"><span>${lbl}</span>${estrelas(val, 'peq')}<strong>${fmt1(val)}</strong></div>`\n  return `\n  <section class=\"card\" id=\"avaliacoes\" aria-labelledby=\"t-av\">\n    <h2 id=\"t-av\">Avaliações de pacientes</h2>\n    ${st.n ? `\n    <div class=\"av-top\">\n      <div class=\"av-media\"><strong class=\"grande\">${fmt1(st.media)}</strong>${estrelas(st.media)}<span class=\"mut\">${st.n} avaliações moderadas</span></div>\n      <div class=\"av-dist\">${st.dist.map((d) => `<div class=\"dist\"><span>${d.k} ★</span><div class=\"bar\"><i style=\"width:${st.n ? Math.round(d.c / st.n * 100) : 0}%\"></i></div><span class=\"mut\">${d.c}</span></div>`).join('')}</div>\n      <div class=\"av-subs\">${barra('Pontualidade', st.pont)}${barra('Atenção', st.aten)}${barra('Estrutura', st.estr)}</div>\n    </div>` : '<p>Ainda não há avaliações publicadas.</p>'}\n    <ul class=\"reviews\">\n      ${lista.map((a) => `<li data-key=\"${esc(a.id)}\"><article class=\"review\">\n        <header><strong>${esc(a.autorNome)}</strong> ${estrelas(a.nota, 'peq')} <span class=\"mut\">${esc(a.tipoAtendimento)} · consulta em <time datetime=\"${esc(isoDia(a.dataConsulta))}\">${esc(dataBR(a.dataConsulta))}</time></span>${a.verificada ? ' <span class=\"pill ok\">Consulta verificada</span>' : ''}</header>\n        ${a.titulo ? `<h3>${esc(a.titulo)}</h3>` : ''}\n        <p>${esc(a.texto)}</p>\n        ${a.respostaMedico ? `<blockquote class=\"resp\"><strong>Resposta ${p.medico.genero === 'feminino' ? 'da' : 'do'} ${esc(nomeExib(p.medico))}:</strong> ${esc(a.respostaMedico)}</blockquote>` : ''}\n      </article></li>`).join('')}\n    </ul>\n    ${av.length > 4 ? `<button class=\"btn sec\" type=\"button\" data-acao=\"todas-av\">${todas ? 'Mostrar menos' : 'Ver todas as ' + av.length + ' avaliações'}</button>` : ''}\n    <details class=\"avaliar\"${d2.state.abrirAv ? ' open' : ''}><summary data-acao=\"abrir-av\">Já se consultou? Deixe sua avaliação</summary>${formAvaliar(d2)}</details>\n  </section>`\n}\n\nfunction secConteudos(p) {\n  const cs = arr(p.conteudos)\n  if (!cs.length) return ''\n  return `\n  <section class=\"card\" id=\"conteudos\" aria-labelledby=\"t-cont\">\n    <h2 id=\"t-cont\">Artigos ${p.medico.genero === 'feminino' ? 'da' : 'do'} ${esc(nomeExib(p.medico))}</h2>\n    <div class=\"artigos\">\n      ${cs.map((a) => `<article class=\"artigo\" id=\"artigo-${esc(a.slug)}\" data-key=\"${esc(a.slug)}\">\n        <h3>${esc(a.titulo)}</h3>\n        <p>${esc(a.resumo)}</p>\n        <p class=\"mut peq\">Publicado em <time datetime=\"${esc(isoDia(a.publicadoEm))}\">${esc(dataBR(a.publicadoEm))}</time>${a.revisadoEm && a.revisadoEm !== a.publicadoEm ? ' · revisado em <time datetime=\"' + esc(isoDia(a.revisadoEm)) + '\">' + esc(dataBR(a.revisadoEm)) + '</time>' : ''} · ${esc(a.tempoLeituraMin)} min de leitura</p>\n        <ul class=\"tags\">${arr(a.tags).map((t) => `<li>${esc(t)}</li>`).join('')}</ul>\n      </article>`).join('')}\n    </div>\n  </section>`\n}\n\nfunction secFaq(p) {\n  const fq = arr(p.faq)\n  if (!fq.length) return ''\n  return `\n  <section class=\"card\" id=\"faq\" aria-labelledby=\"t-faq\">\n    <h2 id=\"t-faq\">Perguntas frequentes</h2>\n    <div class=\"faq\">${fq.map((q, i) => `<details${i === 0 ? ' open' : ''}><summary><h3>${esc(q.pergunta)}</h3></summary><p>${esc(q.resposta)}</p></details>`).join('')}</div>\n  </section>`\n}\n\nfunction secAgendar(d2, p) {\n  const m = p.medico\n  const s = d2.state\n  if (s.agStatus === 'ok') {\n    return `<section class=\"card\" id=\"agendar\" aria-labelledby=\"t-ag\"><h2 id=\"t-ag\">Pedido enviado</h2>\n      <div class=\"ok-box\" role=\"status\">Recebemos seu pedido. Protocolo <strong>${esc(s.agProtocolo)}</strong>. A equipe ${m.genero === 'feminino' ? 'da' : 'do'} ${esc(nomeExib(m))} confirma o horário em até 1 dia útil.</div>\n      <button class=\"btn sec\" type=\"button\" data-acao=\"novo-pedido\">Fazer outro pedido</button></section>`\n  }\n  if (!FA.modalidade) FA.modalidade = 'presencial'\n  return `\n  <section class=\"card\" id=\"agendar\" aria-labelledby=\"t-ag\">\n    <h2 id=\"t-ag\">Pedir agendamento</h2>\n    <p class=\"mut\">Preencha e a equipe entra em contato para confirmar dia e horário. Não é necessário criar conta.</p>\n    <form class=\"form ag\" novalidate>\n      <div class=\"grid2\">\n        <label>Nome completo<input name=\"nome\" maxlength=\"80\" autocomplete=\"name\" value=\"${v(FA, 'nome')}\" required></label>\n        <label>Telefone com DDD<input name=\"telefone\" type=\"tel\" maxlength=\"20\" autocomplete=\"tel\" inputmode=\"tel\" value=\"${v(FA, 'telefone')}\" required></label>\n        <label>E-mail (opcional)<input name=\"email\" type=\"email\" maxlength=\"120\" autocomplete=\"email\" value=\"${v(FA, 'email')}\"></label>\n        <label>Convênio\n          <select name=\"convenio\"><option value=\"Particular\"${sel(FA, 'convenio', 'Particular')}>Particular</option>${arr(m.convenios).map((x) => `<option${sel(FA, 'convenio', x)}>${esc(x)}</option>`).join('')}</select></label>\n      </div>\n      <fieldset class=\"radios\"><legend>Modalidade</legend>\n        <label><input type=\"radio\" name=\"modalidade\" value=\"presencial\"${chk(FA, 'modalidade', 'presencial')}> Presencial</label>\n        ${m.atendeTeleconsulta ? `<label><input type=\"radio\" name=\"modalidade\" value=\"teleconsulta\"${chk(FA, 'modalidade', 'teleconsulta')}> Teleconsulta</label>` : ''}\n      </fieldset>\n      <label>Melhor período\n        <select name=\"periodo\">${['Qualquer horário', 'Manhã', 'Tarde', 'Noite', 'Sábado'].map((x) => `<option${sel(FA, 'periodo', x)}>${x}</option>`).join('')}</select></label>\n      <label>Mensagem (opcional)<textarea name=\"mensagem\" rows=\"3\" maxlength=\"1000\">${v(FA, 'mensagem')}</textarea></label>\n      <label class=\"check\"><input type=\"checkbox\" name=\"consentimento\"${FA.consentimento ? ' checked' : ''}> Autorizo o uso dos meus dados para contato sobre este agendamento, conforme a LGPD.</label>\n      <label class=\"hp\" aria-hidden=\"true\">Não preencha<input name=\"website\" tabindex=\"-1\" autocomplete=\"off\" value=\"\"></label>\n      ${s.agErro ? `<p class=\"erro\" role=\"alert\">${esc(s.agErro)}</p>` : ''}\n      <button class=\"btn\" type=\"submit\"${s.agStatus === 'sending' ? ' disabled' : ''}>${s.agStatus === 'sending' ? 'Enviando...' : 'Enviar pedido'}</button>\n    </form>\n  </section>`\n}\n\nfunction asideCard(p) {\n  const m = p.medico\n  const pr = principalDe(p)\n  return `\n  <aside class=\"aside\" aria-label=\"Agendamento rápido\">\n    <div class=\"card side\">\n      <p class=\"mut peq\">Consulta particular</p>\n      <p class=\"preco\">${esc(brl(m.valorConsulta))}<span class=\"mut peq\"> · ${esc(m.duracaoConsultaMin)} min</span></p>\n      ${m.atendeTeleconsulta ? `<p class=\"mut\">Teleconsulta: <strong>${esc(brl(m.valorTeleconsulta))}</strong></p>` : ''}\n      ${m.retornoDias ? `<p class=\"mut peq\">Retorno incluso em até ${esc(m.retornoDias)} dias</p>` : ''}\n      <button class=\"btn full\" type=\"button\" data-ir=\"agendar\">Pedir agendamento</button>\n      ${pr.whatsapp ? `<a class=\"btn sec full\" href=\"${esc(waUrl(pr.whatsapp))}\" target=\"_blank\" rel=\"noopener\">WhatsApp do consultório</a>` : ''}\n      ${pr.telefone ? `<a class=\"btn sec full\" href=\"${esc(telUrl(pr.telefone))}\">Ligar ${esc(pr.telefone)}</a>` : ''}\n      <p class=\"mut peq\">${esc(arr(m.convenios).length)} convênios aceitos · ${esc(arr(p.locais).length)} endereços</p>\n    </div>\n  </aside>`\n}\n\nfunction rodape(p, c) {\n  const m = p ? p.medico : null\n  return `<footer class=\"rodape\"><div class=\"wrap\">\n    <p><strong>${esc(c.siteNome)}</strong> · ${esc(c.siteDescricao)}</p>\n    ${m ? `<p class=\"mut peq\">Página atualizada em <time datetime=\"${esc(isoDia(m.atualizadoEm))}\">${esc(dataBR(m.atualizadoEm))}</time>. Informações fornecidas pelo profissional e verificadas pela equipe ${esc(c.siteNome)}. Este perfil não substitui uma consulta médica.</p>` : ''}\n    <p class=\"aviso\">${esc(c.aviso)}</p>\n  </div></footer>`\n}\n\nconst CSS = `\n:host{display:block;height:100%}\n*{box-sizing:border-box}\n.pg{--bg:#f4f7fa;--card:#fff;--ink:#0f1f2e;--mut:#526172;--line:#e1e7ee;--pri:#0b6e7f;--pri-ink:#fff;--pri-soft:#e3f3f5;--ok:#167a3e;--star:#f2a516;--erro:#b42318;\n  height:100%;overflow-y:auto;overflow-x:hidden;background:var(--bg);color:var(--ink);\n  font:15.5px/1.6 system-ui,-apple-system,\"Segoe UI\",Roboto,\"Helvetica Neue\",Arial,sans-serif;scroll-behavior:smooth;-webkit-font-smoothing:antialiased}\n@media (prefers-color-scheme:dark){.pg{--bg:#0d151d;--card:#14202b;--ink:#e6edf3;--mut:#9fb0c0;--line:#243442;--pri:#3fb6c6;--pri-ink:#04161a;--pri-soft:#123039;--ok:#4cc27a;--erro:#ff8a80}}\n.wrap{max-width:1140px;margin:0 auto;padding:0 20px}\na{color:var(--pri)}\nh1,h2,h3{line-height:1.25;margin:0 0 .5em}\nh1{font-size:clamp(26px,4vw,38px);letter-spacing:-.01em}\nh2{font-size:22px}\nh3{font-size:16.5px}\np{margin:0 0 .8em}\n.mut{color:var(--mut)}.peq{font-size:13px}\n.topo{background:var(--card);border-bottom:1px solid var(--line)}\n.topo .wrap{display:flex;align-items:center;justify-content:space-between;height:56px}\n.marca{font-weight:800;color:var(--ink);text-decoration:none;letter-spacing:-.01em}.marca b{color:var(--pri)}\n.hero{background:linear-gradient(180deg,var(--pri-soft),var(--bg));padding:18px 0 26px}\n.bread ol{list-style:none;display:flex;flex-wrap:wrap;gap:6px;margin:0 0 18px;padding:0;font-size:13px;color:var(--mut)}\n.bread li+li:before{content:\"›\";margin-right:6px}\n.bread a{color:var(--mut)}\n.hero-grid{display:flex;gap:22px;align-items:center}\n.foto{width:132px;height:132px;border-radius:50%;object-fit:cover;background:var(--card);border:4px solid var(--card);box-shadow:0 6px 24px rgba(0,0,0,.08);flex:none}\n.selo{display:inline-block;background:var(--card);color:var(--ok);font-weight:600;font-size:13px;padding:3px 10px;border-radius:999px;border:1px solid var(--line);margin-bottom:8px}\n.sub{color:var(--mut);font-size:16px}\n.nota-hero a{color:var(--ink);text-decoration:none}\n.chips,.tags{list-style:none;display:flex;flex-wrap:wrap;gap:8px;padding:0;margin:8px 0 0}\n.chips li{background:var(--card);border:1px solid var(--line);border-radius:999px;padding:4px 12px;font-size:13.5px}\n.tags li{background:var(--pri-soft);color:var(--ink);border-radius:8px;padding:3px 10px;font-size:13.5px}\n.secnav{position:sticky;top:0;z-index:5;background:var(--card);border-bottom:1px solid var(--line)}\n.secnav-in{display:flex;gap:4px;overflow-x:auto;scrollbar-width:none}\n.secnav a{white-space:nowrap;padding:12px 10px;font-size:14px;color:var(--mut);text-decoration:none;border-bottom:2px solid transparent}\n.secnav a:hover{color:var(--ink);border-bottom-color:var(--pri)}\n.layout{display:grid;grid-template-columns:minmax(0,1fr) 320px;gap:24px;padding:24px 20px 40px;max-width:1140px;margin:0 auto}\n.principal{display:flex;flex-direction:column;gap:20px;min-width:0}\n.card{background:var(--card);border:1px solid var(--line);border-radius:14px;padding:22px 24px;scroll-margin-top:60px}\n.lead{font-size:16.5px}\n.fatos{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px 24px;margin:12px 0 0}\n.fatos div{border-top:1px solid var(--line);padding-top:8px}\n.fatos dt{font-size:12.5px;text-transform:uppercase;letter-spacing:.04em;color:var(--mut)}\n.fatos dd{margin:2px 0 0;font-weight:600}\n.cols2{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:20px}\n.cols3{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:20px;margin:10px 0 14px}\n.lista2{columns:2;column-gap:28px;padding-left:18px;margin:0 0 .8em}\n.lista2 li{break-inside:avoid;margin-bottom:4px}\n.locais{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px}\n.local{border:1px solid var(--line);border-radius:12px;padding:16px}\n.local address{font-style:normal;color:var(--mut);margin-bottom:10px}\n.horas{width:100%;border-collapse:collapse;margin:6px 0 12px;font-size:14px}\n.horas caption{text-align:left;font-weight:600;margin-bottom:4px}\n.horas th{text-align:left;font-weight:500;padding:3px 0}\n.horas td{text-align:right;padding:3px 0}\n.horas tr+tr{border-top:1px dashed var(--line)}\n.pill{display:inline-block;font-size:11.5px;font-weight:600;background:var(--pri-soft);color:var(--pri);border-radius:999px;padding:1px 8px;vertical-align:middle}\n.pill.ok{color:var(--ok)}\n.acoes{display:flex;flex-wrap:wrap;gap:8px;margin:10px 0 0}\n.btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;font:inherit;font-weight:600;font-size:14.5px;color:var(--pri-ink);background:var(--pri);border:1px solid var(--pri);border-radius:10px;padding:9px 16px;cursor:pointer;text-decoration:none}\n.btn:disabled{opacity:.6;cursor:default}\n.btn.sec{background:transparent;color:var(--pri)}\n.btn.full{width:100%;margin-top:8px}\n.tabela-wrap{overflow-x:auto}\n.serv{width:100%;border-collapse:collapse;font-size:14.5px}\n.serv th{text-align:left;font-size:12.5px;text-transform:uppercase;letter-spacing:.04em;color:var(--mut);border-bottom:1px solid var(--line);padding:8px}\n.serv td{vertical-align:top;border-bottom:1px solid var(--line);padding:12px 8px}\n.serv td:nth-child(2),.serv td:nth-child(3),.serv td:nth-child(4){white-space:nowrap}\n.cat{font-size:11.5px;color:var(--mut);border:1px solid var(--line);border-radius:6px;padding:0 6px;margin-left:4px}\ndetails summary{cursor:pointer;color:var(--pri);font-weight:600}\n.serv details{margin-top:6px;font-size:14px}\n.timeline{list-style:none;padding:0;margin:0 0 16px;border-left:2px solid var(--pri-soft)}\n.timeline li{display:flex;gap:14px;padding:6px 0 10px 14px;position:relative}\n.timeline li:before{content:\"\";position:absolute;left:-7px;top:12px;width:12px;height:12px;border-radius:50%;background:var(--pri)}\n.ano{font-weight:700;min-width:44px;color:var(--pri)}\n.pubs{padding-left:18px}.pubs li{margin-bottom:6px}\n.stars{display:inline-block;font-size:18px;letter-spacing:1px;background:linear-gradient(90deg,var(--star) var(--v),var(--line) var(--v));-webkit-background-clip:text;background-clip:text;color:transparent;vertical-align:-2px}\n.stars.peq{font-size:14px}\n.av-top{display:grid;grid-template-columns:160px minmax(0,1fr) minmax(0,1fr);gap:20px;align-items:center;margin-bottom:16px}\n.av-media{display:flex;flex-direction:column;align-items:flex-start;gap:2px}\n.grande{font-size:44px;line-height:1}\n.dist{display:grid;grid-template-columns:34px 1fr 24px;gap:8px;align-items:center;font-size:13px}\n.bar{height:8px;background:var(--line);border-radius:6px;overflow:hidden}.bar i{display:block;height:100%;background:var(--star)}\n.sub-nota{display:grid;grid-template-columns:96px auto 30px;gap:8px;align-items:center;font-size:13.5px}\n.reviews{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:12px}\n.review{border:1px solid var(--line);border-radius:12px;padding:14px 16px}\n.review header{display:flex;flex-wrap:wrap;gap:6px 8px;align-items:center;margin-bottom:6px;font-size:14px}\n.review h3{font-size:15.5px;margin:4px 0}\n.resp{margin:10px 0 0;padding:10px 12px;border-left:3px solid var(--pri);background:var(--pri-soft);border-radius:0 8px 8px 0;font-size:14px}\n.avaliar{margin-top:16px;border-top:1px solid var(--line);padding-top:14px}\n.artigos{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:14px}\n.artigo{border:1px solid var(--line);border-radius:12px;padding:14px;scroll-margin-top:60px}\n.artigo h3{font-size:15.5px}\n.faq details{border-bottom:1px solid var(--line);padding:10px 0}\n.faq summary{list-style:none;display:flex;justify-content:space-between;gap:12px;color:var(--ink)}\n.faq summary::-webkit-details-marker{display:none}\n.faq summary:after{content:\"+\";color:var(--pri);font-size:20px;line-height:1}\n.faq details[open] summary:after{content:\"–\"}\n.faq summary h3{margin:0;font-size:15.5px}\n.faq p{margin:8px 0 2px;color:var(--mut)}\n.form{display:flex;flex-direction:column;gap:12px;margin-top:10px}\n.grid2{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}\n.form label{display:flex;flex-direction:column;gap:4px;font-size:13.5px;font-weight:600;color:var(--ink)}\n.form input,.form select,.form textarea{font:inherit;font-weight:400;font-size:15px;color:var(--ink);background:var(--bg);border:1px solid var(--line);border-radius:10px;padding:9px 11px;width:100%}\n.form input:focus,.form select:focus,.form textarea:focus{outline:2px solid var(--pri);outline-offset:1px}\n.radios{border:0;padding:0;margin:0;display:flex;gap:18px;flex-wrap:wrap}\n.radios legend{font-size:13.5px;font-weight:600;margin-bottom:4px}\n.form .radios label,.form label.check{flex-direction:row;align-items:center;gap:8px;font-weight:500}\n.form .radios input,.form label.check input{width:auto}\n.form label.check{align-items:flex-start}\n.form label.check input{margin-top:4px}\n.hp{position:absolute!important;left:-9999px!important;width:1px;height:1px;overflow:hidden}\n.erro{color:var(--erro);font-weight:600;margin:0}\n.ok-box{background:var(--pri-soft);border:1px solid var(--pri);border-radius:12px;padding:14px 16px;margin:10px 0}\n.aside{position:relative}\n.side{position:sticky;top:64px}\n.preco{font-size:30px;font-weight:800;margin:0}\n.rodape{border-top:1px solid var(--line);background:var(--card);padding:22px 0 34px;font-size:14px}\n.aviso{display:inline-block;background:#fff4d6;color:#6b4e00;border-radius:8px;padding:6px 10px;font-size:13px}\n.estado{max-width:640px;margin:80px auto;text-align:center;padding:0 20px}\n.sk{background:linear-gradient(90deg,var(--line),var(--card),var(--line));background-size:200% 100%;animation:sk 1.2s infinite;border-radius:10px}\n@keyframes sk{0%{background-position:200% 0}100%{background-position:-200% 0}}\n@media (max-width:900px){\n  .layout{grid-template-columns:minmax(0,1fr)}\n  .aside{order:-1}.side{position:static}\n  .av-top{grid-template-columns:1fr}\n  .artigos,.locais{grid-template-columns:1fr}\n}\n@media (max-width:600px){\n  .hero-grid{flex-direction:column;align-items:flex-start}\n  .foto{width:104px;height:104px}\n  .fatos,.cols2,.cols3,.grid2{grid-template-columns:1fr}\n  .lista2{columns:1}\n  .card{padding:18px 16px}\n  .serv thead{display:none}\n  .serv tr{display:block;border-bottom:1px solid var(--line);padding:8px 0}\n  .serv td{display:block;border:0;padding:2px 0}\n}\n`\n\nexport default {\n  css: CSS,\n\n  render(d2) {\n    const c = cfg(d2)\n    const s = d2.state\n    const topo = `<div class=\"topo\"><div class=\"wrap\"><a class=\"marca\" href=\"${esc(c.baseUrl)}/\"><b>+</b> ${esc(c.siteNome)}</a><span class=\"mut peq\">Encontre médicos verificados</span></div></div>`\n    if (!s.status || s.status === 'loading') {\n      return `<div class=\"pg\" aria-busy=\"true\">${topo}<div class=\"wrap\" style=\"padding-top:28px\">\n        <div class=\"sk\" style=\"height:132px;width:132px;border-radius:50%\"></div>\n        <div class=\"sk\" style=\"height:34px;width:60%;margin-top:18px\"></div>\n        <div class=\"sk\" style=\"height:18px;width:40%;margin-top:12px\"></div>\n        <div class=\"sk\" style=\"height:220px;margin-top:26px\"></div></div></div>`\n    }\n    if (s.status === 'notfound') {\n      return `<div class=\"pg\">${topo}<div class=\"estado\"><h1>Perfil não encontrado</h1><p class=\"mut\">O endereço pode ter mudado ou o perfil não está mais publicado.</p></div>${rodape(null, c)}</div>`\n    }\n    if (s.status === 'error') {\n      return `<div class=\"pg\">${topo}<div class=\"estado\"><h1>Não foi possível carregar o perfil</h1><p class=\"mut\">Verifique sua conexão e tente de novo.</p><button class=\"btn\" type=\"button\" data-acao=\"recarregar\">Tentar novamente</button></div>${rodape(null, c)}</div>`\n    }\n    const p = s.p\n    const st = stats(arr(p.avaliacoes))\n    return `<div class=\"pg\" itemscope itemtype=\"https://schema.org/MedicalWebPage\">\n      ${topo}\n      ${secHero(p, c, st)}\n      ${secNav()}\n      <div class=\"layout\">\n        <main class=\"principal\" id=\"conteudo\">\n          ${secResumo(p, st)}\n          ${secSobre(p)}\n          ${secLocais(p)}\n          ${secServicos(p)}\n          ${secConvenios(p)}\n          ${secFormacao(p)}\n          ${secAvaliacoes(d2, p, st)}\n          ${secConteudos(p)}\n          ${secFaq(p)}\n          ${secAgendar(d2, p)}\n        </main>\n        ${asideCard(p)}\n      </div>\n      ${rodape(p, c)}\n    </div>`\n  },\n\n  mounted(d2) {\n    // navegação interna: rola dentro do componente, sem mexer no hash (o hash acionaria o router)\n    d2.on('[data-ir]', 'click', (e, el) => {\n      e.preventDefault()\n      const alvo = d2.$('#' + el.getAttribute('data-ir'))\n      if (alvo) alvo.scrollIntoView({ behavior: 'smooth', block: 'start' })\n    })\n\n    d2.on('[data-acao]', 'click', (e, el) => {\n      const a = el.getAttribute('data-acao')\n      if (a === 'recarregar') { carregar(d2); return }\n      if (a === 'todas-av') { d2.state.todasAv = !d2.state.todasAv; return }\n      if (a === 'abrir-av') { d2.state.abrirAv = !d2.state.abrirAv; return }\n      if (a === 'novo-pedido') { d2.setState({ agStatus: '', agErro: '', agProtocolo: '' }); return }\n    })\n\n    // guarda o que a pessoa digita (o render devolve esses valores; nada se perde num re-render)\n    const guardar = (e, el) => {\n      const form = el.closest('form')\n      if (!form || !el.name) return\n      const alvo = form.classList.contains('ag') ? FA : FR\n      if (el.type === 'checkbox') alvo[el.name] = !!el.checked\n      else if (el.type === 'radio') { if (el.checked) alvo[el.name] = el.value }\n      else alvo[el.name] = el.value\n    }\n    d2.on('form input, form select, form textarea', 'input', guardar)\n    d2.on('form input, form select, form textarea', 'change', guardar)\n\n    d2.on('form.ag', 'submit', async (e, el) => {\n      e.preventDefault()\n      if (d2.state.agStatus === 'sending' || !d2.state.p) return\n      lerForm(el, FA)\n      const body = {\n        slug: d2.state.p.medico.slug,\n        nome: String(FA.nome || '').trim(),\n        telefone: String(FA.telefone || '').trim(),\n        email: String(FA.email || '').trim(),\n        modalidade: FA.modalidade || 'presencial',\n        convenio: FA.convenio || 'Particular',\n        periodo: FA.periodo || '',\n        mensagem: String(FA.mensagem || '').trim(),\n        consentimento: !!FA.consentimento,\n        website: FA.website || ''\n      }\n      let erro = ''\n      if (body.nome.length < 2) erro = ERROS['nome-invalido']\n      else if (digits(body.telefone).length < 10) erro = ERROS['telefone-invalido']\n      else if (body.email && !/^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$/.test(body.email)) erro = ERROS['email-invalido']\n      else if (!body.consentimento) erro = ERROS['consentimento-obrigatorio']\n      if (erro) { d2.setState({ agStatus: 'erro', agErro: erro }); return }\n      d2.setState({ agStatus: 'sending', agErro: '' })\n      try {\n        const r = unwrap(await d2.rush('contato').invoke(body))\n        if (r && r.ok) {\n          Object.keys(FA).forEach((k) => { delete FA[k] })\n          d2.setState({ agStatus: 'ok', agProtocolo: r.protocolo })\n          const alvo = d2.$('#agendar')\n          if (alvo) alvo.scrollIntoView({ behavior: 'smooth', block: 'start' })\n        } else {\n          d2.setState({ agStatus: 'erro', agErro: ERROS[r && r.erro] || 'Não foi possível enviar agora. Tente de novo.' })\n        }\n      } catch (err) {\n        d2.log('mgeo contato erro', err && err.message)\n        d2.setState({ agStatus: 'erro', agErro: 'Falha de conexão. Tente de novo.' })\n      }\n    })\n\n    d2.on('form.av', 'submit', async (e, el) => {\n      e.preventDefault()\n      if (d2.state.avStatus === 'sending' || !d2.state.p) return\n      lerForm(el, FR)\n      const body = {\n        slug: d2.state.p.medico.slug,\n        autorNome: String(FR.autorNome || '').trim(),\n        nota: Number(FR.nota || 0),\n        titulo: String(FR.titulo || '').trim(),\n        texto: String(FR.texto || '').trim(),\n        tipoAtendimento: FR.tipoAtendimento || '',\n        website: FR.website || ''\n      }\n      let erro = ''\n      if (body.autorNome.length < 2) erro = ERROS['nome-invalido']\n      else if (!(body.nota >= 1 && body.nota <= 5)) erro = ERROS['nota-invalida']\n      else if (body.texto.length < 20 || body.texto.length > 1500) erro = ERROS['texto-invalido']\n      if (erro) { d2.setState({ avStatus: 'erro', avErro: erro, abrirAv: true }); return }\n      d2.setState({ avStatus: 'sending', avErro: '', abrirAv: true })\n      try {\n        const r = unwrap(await d2.rush('avaliar').invoke(body))\n        if (r && r.ok) {\n          Object.keys(FR).forEach((k) => { delete FR[k] })\n          d2.setState({ avStatus: 'ok' })\n        } else {\n          d2.setState({ avStatus: 'erro', avErro: ERROS[r && r.erro] || 'Não foi possível enviar agora. Tente de novo.' })\n        }\n      } catch (err) {\n        d2.log('mgeo avaliar erro', err && err.message)\n        d2.setState({ avStatus: 'erro', avErro: 'Falha de conexão. Tente de novo.' })\n      }\n    })\n\n    d2.onUnmount(() => {\n      try { document.head.querySelectorAll('[data-mgeo]').forEach((n) => n.remove()) } catch (e) { /* noop */ }\n    })\n\n    carregar(d2)\n  }\n}\n"}},"api":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"api"}}}},"contato":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"contato"}}}},"avaliar":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"avaliar"}}}},"cfg":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"cfg"}}}}}}}}}}]}},{"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":{"component":"data2-core-types@Getter","displayName":"isData2User","params":{"module":{"component":"data2-core-functions@Match","params":{"pattern":{"component":"data2-core-types@Regex","params":{"pattern":"@data2\\.app$","flags":"i"}},"text":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$user.email"}}}}}},"prop":{"component":"data2-core-primitives@String","params":{"content":"0"}}}},"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":{"component":"data2-core-flow@If","displayName":"management exception never picks the system","params":{"compare":{"component":"data2-core-logical-operators@Or","params":{"components":[{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"is_data2_user"}}}},{"component":"data2-core-logical-operators@Not","params":{"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"is_data2_app_exception"}}}}}}]}},"then":{"system":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$metadata.system"}}}}},"else":{"d2_app":"management"}}},"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-10-29T19:05:43.007Z","updateMetadata":{"updatedBy":{"user":"5f1609be1ca96def427e1559"}}},{"_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"},{"component":"data2-core@DataSet","reference":"SessionsDataSet","params":{"requiresConfirmation":false,"pk":"key","datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"data2sessionsdatasource"}}}},{"component":"data2-core@ServerSessionsDataSource","reference":"data2sessionsdatasource","params":{}},{"reference":"UsersTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"_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}},"policies":[{"component":"data2-core-auth@PublicPolicy","params":{"reason":"Explicit so data2 can go private, 2026-11-05. Access is decided by the drive/file gate (applyFileTableGates, docs/drive-file-access.md), which runs after this policy; same behavior as today."}}]},"reference":"FileComponentInstancesDataSet","updatedAt":"2026-11-05T17:23:34.217Z","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"},"policies":[{"component":"data2-core-auth@PublicPolicy","params":{"reason":"Explicit so data2 can go private, 2026-11-05. Access is decided by the drive/file gate (applyFileTableGates, docs/drive-file-access.md), which runs after this policy; same behavior as today."}}]},"reference":"OneFileComponentInstancesDataSet","updatedAt":"2026-11-05T17:23:34.254Z","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}},"policies":[{"component":"data2-core-auth@PublicPolicy","params":{"reason":"Explicit so data2 can go private, 2026-11-05. Access is decided by the drive/file gate (applyFileTableGates, docs/drive-file-access.md), which runs after this policy; same behavior as today."}}]},"reference":"DriveFileComponentInstancesDataSet","updatedAt":"2026-11-05T17:23:34.347Z","createdAt":"2023-02-16T14:27:07.797Z"},{"reference":"ServiceComponentInstancesTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[{"_id":"6af88f34e462407219325d26","component":"data2-rush@HTTPListener","reference":"mgeo-avaliar","system":"66f6c624d8a4a0c67041a910","params":{}},{"_id":"6af88f07fd2b06e8c1673a73","component":"data2-rush@HTTPListener","reference":"mgeo-contato","system":"66f6c624d8a4a0c67041a910","params":{}},{"_id":"6af88ecb97303df26815d6c8","component":"data2-rush@HTTPListener","reference":"mgeo-perfil","system":"66f6c624d8a4a0c67041a910","params":{}}]}},{"reference":"ComponentInstancesTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[{"_id":"6af8914c8b6a65dcd9daf74b","component":"data2-core-primitives@Router","system":"66f6c624d8a4a0c67041a910","displayName":"mgeo · router","params":{"routerType":{"component":"data2-core-primitives@String","params":{"content":"browser"}},"routes":[{"component":"data2-core-primitives@Route","params":{"path":"","content":{"component":"data2-core-types@ArtboardReference","params":{"reference":"u5hKoqq75Q1gr4bnjafMK"}}}},{"component":"data2-core-primitives@Route","params":{"path":"/:slug","content":{"component":"data2-core-types@ArtboardReference","params":{"reference":"u5hKoqq75Q1gr4bnjafMK"}}}}],"notFound":{"component":"data2-core-types@ArtboardReference","params":{"reference":"u5hKoqq75Q1gr4bnjafMK"}}},"reference":"mgeo-router"},{"_id":"6af8912da7cb0a0e66d698a2","component":"data2-core-primitives@Artboard","system":"66f6c624d8a4a0c67041a910","displayName":"mgeo · Página do médico","params":{"title":{"component":"data2-core-primitives@String","params":{"content":"mgeo · Página do médico"}},"dimensions":{"component":"data2-core-types@Dimensions","params":{"width":1440,"height":900}},"position":{"component":"data2-core-types@Position","params":{"x":0,"y":0}}},"reference":"u5hKoqq75Q1gr4bnjafMK"},{"_id":"6f17b1d25a5288e266af6a3b","parent":"6af8912da7cb0a0e66d698a2","component":"fernando-playground@mgeo_Pagina_do_medico","system":"66f6c624d8a4a0c67041a910","displayName":"mgeo · página (code component)","params":{"api":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"mgeo-perfil"}},"contato":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"mgeo-contato"}},"avaliar":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"mgeo-avaliar"}},"cfg":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"mgeo-site-config"}},"super":{"position":{"component":"data2-core-types@Position","params":{"x":0,"y":0,"freeTransform":true,"left":true,"top":true}},"dimensions":{"component":"data2-core-types@Dimensions","params":{"width":"100%","height":"100%"}}}},"reference":"01UPgp80BPWAc4Hv-FbCb"}]}},{"_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":"6af8915bcd9a45d7379edf40","displayName":"mgeo · Página do médico (GEO)","reference":"0AmuHxo3LXl33s3LaKWeH","params":{"domain":{"component":"data2-core-primitives@String","params":{"content":"medico-geo"}},"entryPoint":{"component":"data2-core-types@ComponentInstanceReference","params":{"component":"data2-core-primitives@Router","reference":"mgeo-router"}}},"system":"66f6c624d8a4a0c67041a910","component":"data2-core-primitives@Application"}]}},{"reference":"DataComponentInstancesTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[{"_id":"6af88fa88b6a65dcd9daf2bf","component":"data2-core@Store","system":"66f6c624d8a4a0c67041a910","params":{"initialData":{"siteNome":"Guia Saúde Perto","siteDescricao":"Diretório de médicos com perfis verificados, valores, convênios e avaliações de pacientes.","baseUrl":"https://medico-geo.fernando-playground.next.data2.app","slugPadrao":"dra-helena-duarte-cardiologista-sao-paulo","idioma":"pt-BR","moeda":"BRL","aviso":"Perfil fictício criado para testes de GEO no Data2. Não é uma médica real."}},"reference":"mgeo-site-config"}]}},{"reference":"BundlesTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}}],"processesParams":{}}}}