1const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/vega-embed.module-C3fE6OkY.js","assets/diverging-C1SZqrmz.js","assets/string-DIqgPFIh.js","assets/timer-BU0aTmFO.js"])))=>i.map(i=>d[i]); 2import{j as l,r as g,_ as Te,y as ze,l as ue,n as Oe,P as Be,b as Ue}from"./entry-BCe1jibU.js";import{e as Ne}from"./globalNodeIds-DS3fRevW.js";import{c as G}from"./createLucideIcon-Br0wfJyU.js";import{e as Pe}from"./graphql-4Y3Cu4kt.js";import{f as We}from"./operations-Dn0xY-u2.js";import{probeSessionAuthentication as Ge}from"./session-C75oaowB.js";import{View as Ze}from"./notFoundView-m7qfABMe.js";import"./pathPrefix-DU8I2oCO.js";import"./types-CjJu7saM.js";import"./identity-X0DTFeA9.js";import"./Identity-QN8NXWkM.js";import"./billing-XWNTP5pu.js";import"./EvalCloneMarker-DeoTUGFR.js";import"./speechToText-BOPKEWM6.js";import"./types-CLw4uLQj.js";import"./gradientBackground-CoOCbPbc.js";/** 3 * @license lucide-react v0.536.0 - ISC 4 * 5 * This source code is licensed under the ISC license. 6 * See the LICENSE file in the root directory of this source tree. 7 */const Qe=[["path",{d:"m12 19-7-7 7-7",key:"1l729n"}],["path",{d:"M19 12H5",key:"x3x0zl"}]],Ye=G("arrow-left",Qe);/** 8 * @license lucide-react v0.536.0 - ISC 9 * 10 * This source code is licensed under the ISC license. 11 * See the LICENSE file in the root directory of this source tree. 12 */const Je=[["path",{d:"M3 3v16a2 2 0 0 0 2 2h16",key:"c24i48"}],["path",{d:"M18 17V9",key:"2bz60n"}],["path",{d:"M13 17V5",key:"1frdt8"}],["path",{d:"M8 17v-3",key:"17ska0"}]],Fe=G("chart-column",Je);/** 13 * @license lucide-react v0.536.0 - ISC 14 * 15 * This source code is licensed under the ISC license. 16 * See the LICENSE file in the root directory of this source tree. 17 */const Ke=[["rect",{width:"7",height:"9",x:"3",y:"3",rx:"1",key:"10lvy0"}],["rect",{width:"7",height:"5",x:"14",y:"3",rx:"1",key:"16une8"}],["rect",{width:"7",height:"9",x:"14",y:"12",rx:"1",key:"1hutg5"}],["rect",{width:"7",height:"5",x:"3",y:"16",rx:"1",key:"ldoo1y"}]],Xe=G("layout-dashboard",Ke);/** 18 * @license lucide-react v0.536.0 - ISC 19 * 20 * This source code is licensed under the ISC license. 21 * See the LICENSE file in the root directory of this source tree. 22 */const He=[["path",{d:"M21 12a9 9 0 0 0-9-9 9.75 9.75 0 0 0-6.74 2.74L3 8",key:"14sxne"}],["path",{d:"M3 3v5h5",key:"1xhq8a"}],["path",{d:"M3 12a9 9 0 0 0 9 9 9.75 9.75 0 0 0 6.74-2.74L21 16",key:"1hlbsb"}],["path",{d:"M16 16h5v5",key:"ccwih5"}]],H=G("refresh-ccw",He);/** 23 * @license lucide-react v0.536.0 - ISC 24 * 25 * This source code is licensed under the ISC license. 26 * See the LICENSE file in the root directory of this source tree. 27 */const et=[["path",{d:"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z",key:"oel41y"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]],Ae=G("shield-check",et);/** 28 * @license lucide-react v0.536.0 - ISC 29 * 30 * This source code is licensed under the ISC license. 31 * See the LICENSE file in the root directory of this source tree. 32 */const tt=[["path",{d:"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3",key:"wmoenq"}],["path",{d:"M12 9v4",key:"juzpu7"}],["path",{d:"M12 17h.01",key:"p32p05"}]],T=G("triangle-alert",tt),oe=` 33 id workspaceId sourceRef slug title description folder status visibility ownerId 34 currentVersionId currentVersionNumber createdAt updatedAt updatedById 35`,nt=` 36 id dashboardId workspaceId versionNumber layoutSpec tiles runtimeBindingDefaults 37 createdById createdAt changeSummary baseVersionId restoredFromVersionId 38`,at=` 39 id workspaceId sourceRef currentVersionId currentVersionNumber createdById createdAt 40 updatedAt updatedById status tags 41`,st=` 42 id chartId workspaceId versionNumber title subtitle querySpec chartSpec compiledRendererSpec 43 chartSpecCompilerVersion displaySpec validation createdById createdAt changeSummary 44 baseVersionId restoredFromVersionId 45`,fe=` 46 id workspaceId key title description status visibility currentVersionId 47 currentVersionNumber updatedAt 48`,it=` 49 id sectionId workspaceId versionNumber dashboardRefs changeSummary createdById createdAt 50 baseVersionId restoredFromVersionId 51`,Z={AnalyticsContext:`query AnalyticsContext($workspaceUrl: String!) { 52 admin { 53 analytics { 54 context(workspaceUrl: $workspaceUrl) { 55 email 56 workspaceId 57 workspaceUrl 58 } 59 } 60 } 61 }`,AnalyticsSnapshotChartDataDownload:`query AnalyticsSnapshotChartDataDownload($chartVersionId: ID!) { 62 analyticsSnapshotChartDataDownload(chartVersionId: $chartVersionId) { 63 isFragment 64 url 65 } 66 }`,DashboardBundle:`query DashboardBundle($id: ID!) { 67 admin { 68 analytics { 69 dashboard(id: $id) { 70 dashboard { ${oe} } 71 currentVersion { ${nt} } 72 charts { 73 tile 74 chart { ${at} } 75 chartVersion { ${st} } 76 } 77 } 78 } 79 } 80 }`,Dashboards:`query Dashboards($workspaceId: ID!) { 81 admin { 82 analytics { 83 dashboards( 84 workspaceId: $workspaceId 85 includeArchived: false 86 status: active 87 ) { 88 ${oe} 89 } 90 } 91 } 92 }`,Section:`query Section($id: ID!) { 93 admin { 94 analytics { 95 dashboardSection(id: $id) { 96 section { ${fe} } 97 currentVersion { ${it} } 98 dashboards { ${oe} } 99 } 100 } 101 } 102 }`,Sections:`query Sections($workspaceId: ID!) { 103 admin { 104 analytics { 105 dashboardSections(workspaceId: $workspaceId) { 106 ${fe} 107 } 108 } 109 } 110 }`};let te={};function rt(e){te={apiOrigin:pe(e.apiOrigin),artifactOrigin:pe(e.artifactOrigin)}}function De(){return te.apiOrigin?new URL("/graphql",te.apiOrigin).href:"/api/gra
110phql"}function ot(e){const t=`/api/data/${encodeURIComponent(e)}`;return te.artifactOrigin?new URL(t,te.artifactOrigin).href:null}function pe(e){return e?new URL(e).origin:null}async function lt(e){return(await Q("AnalyticsContext",Z.AnalyticsContext,{workspaceUrl:e})).admin.analytics.context}async function Q(e,t,n){const s=await globalThis.fetch(De(),{body:JSON.stringify({operationName:e,query:t,variables:n}),credentials:"include",headers:{Accept:"application/graphql-response+json, application/json","Content-Type":"application/json","X-Lindy-CSRF-Protection":"1"},method:"POST"});let a;try{a=await s.json()}catch{throw new Error(`Analytics request failed with status ${s.status}`)}if(!s.ok)throw new Error(a.error??a.errors?.[0]?.message??"Analytics request failed");if(a.errors?.length)throw new Error(a.errors[0]?.message??"Analytics request failed");if(!a.data)throw new Error("Analytics response did not include data");return a.data}function se(e){e.catch(t=>globalThis.reportError(t))}const ct=new Set(["snapshot.json","core-sources.json","daily-history.json","refresh-status.json","semantic-reliability-dashboard.json","semantic-email-dashboard.json"]),dt=new Set(["line","area","bar","stacked_bar","histogram","heatmap","table","kpi","markdown","sankey"]),ut=new Set(["vega_lite","vega","cos_table","cos_cohort_matrix","cos_kpi","cos_markdown","cos_sankey"]),he=new Set(["time","category","number"]),ne=new Set(["number","currency","percent","duration","date"]),le=new Set(["filter_nonzero_any","filter_eq","filter_neq","filter_in","filter_date_range","derive_scale","derive_ratio","derive_sum","derive_constant","derive_date_grains","derive_date_prefix","group_sum","group_average","sort","limit","unpivot_weeks","retention_w4_flow"]),ft=new Set(["=","==","eq","!=","neq","in"]),me=new Set(["date_range","string","number","boolean","enum","string_list","number_list","boolean_list","enum_list"]);function x(e){return!!(e&&typeof e=="object"&&!Array.isArray(e))}function p(e){return typeof e=="string"?e:""}function O(e){return Array.isArray(e)?e.filter(t=>typeof t=="string"&&t.length>0):[]}function S(e){return typeof e=="number"&&Number.isFinite(e)?e:null}function y(e){return/^[A-Za-z_][A-Za-z0-9_]*$/.test(e)&&!["__proto__","constructor","prototype"].includes(e)}function ce(e){return/^[A-Za-z0-9][A-Za-z0-9_-]{0,119}$/.test(e)&&!["__proto__","constructor","prototype"].includes(e)}function pt(e){return/^[A-Za-z0-9][A-Za-z0-9._-]{0,119}$/.test(e)&&!["__proto__","constructor","prototype"].includes(e)}function ht(e,t){const n=new Map;return Array.isArray(e)?(e.length>50&&t.push("querySpec.declaredParameters cannot exceed 50 entries"),e.forEach((s,a)=>{const r=`querySpec.declaredParameters[${a}]`;if(!x(s)){t.push(`${r} must be an object`);return}const i=p(s.name),o=p(s.type);y(i)?n.has(i)&&t.push(`${r}.name duplicates parameter '${i}'`):t.push(`${r}.name must be a safe field name`),me.has(o)||t.push(`${r}.type is unsupported`),typeof s.required!="boolean"&&t.push(`${r}.required must be a boolean`),y(i)&&me.has(o)&&!n.has(i)&&n.set(i,o)}),n):(t.push("querySpec.declaredParameters must be an array"),n)}function I(e,t,n,s){const a=p(e[t]);(!a||!y(a))&&n.push(`${s} ${t} must be a safe field name`)}function J(e,t,n,s){const a=e[t];if(!Array.isArray(a)||a.length===0){n.push(`${s} ${t} must be a non-empty string array`);return}for(const r of a){if(typeof r!="string"||!r){n.push(`${s} ${t} must contain only non-empty strings`);continue}const i=r;y(i)||n.push(`${s} ${t} contains unsafe field '${i}'`)}}function K(e,t,n,s){e[t]!=null&&S(e[t])==null&&n.push(`${s} ${t} must be a finite number`)}function ee(e,t,n,s=200){e!=null&&(typeof e!="string"||!e.trim()||e.length>s)&&t.push(`${n} must be a non-empty string no longer than ${s} characters`)}function mt(e,t,n){if(e.grains!=null){if(!Array.isArray(e.grains)||e.grains.length===0){t.push(`${n} grains must be a non-empty array`);return}for(const s of e.grains)s!=="day"&&s!=="week"&&s!=="month"&&t.push(`${n} grains must contain only day, week, or month`)}}function Ie(e,t,n,s){const a=`transform ${n} (${e})`;switch(e){case"filter_nonzero_any":{J(t,"fields",s,a);break}case"filter_eq":{I(t,"field",s,a),(t.value==null||!V(t.value))&&s.push(`${a} value must be a string, number, or boolean`);break}case"filter_neq":{I(t,"field",s,a),(t.value==null||!V(t.value))&&s.push(`${a} value must be a string, number, or boolean`);break}case"filter_in":{I(t,"field",s,a),(!Array.isArray(t.values)||t.values.length===0||!t.values.every(V))&&s.push(`${a}
110 values must be a non-empty array of strings, numbers, or booleans`);break}case"filter_date_range":{I(t,"field",s,a),t.start!=null&&typeof t.start!="string"&&s.push(`${a} start must be a date string`),t.end!=null&&typeof t.end!="string"&&s.push(`${a} end must be a date string`),typeof t.start=="string"&&t.start&&!B(t.start)&&s.push(`${a} start is not a parseable date`),typeof t.end=="string"&&t.end&&!B(t.end)&&s.push(`${a} end is not a parseable date`),t.start==null&&t.end==null&&s.push(`${a} requires start and/or end`);break}case"derive_scale":{I(t,"field",s,a),I(t,"source",s,a),K(t,"scale",s,a);break}case"derive_ratio":{I(t,"field",s,a),I(t,"numerator",s,a),I(t,"denominator",s,a),K(t,"scale",s,a);break}case"derive_sum":{I(t,"field",s,a),J(t,"fields",s,a),K(t,"scale",s,a);break}case"derive_constant":{I(t,"field",s,a),(t.value==null||!V(t.value))&&s.push(`${a} value must be a string, number, or boolean`);break}case"derive_date_grains":{I(t,"dateField",s,a),t.periodField!=null&&I(t,"periodField",s,a),t.grainField!=null&&I(t,"grainField",s,a),mt(t,s,a);break}case"derive_date_prefix":{I(t,"field",s,a),t.source!=null&&I(t,"source",s,a);break}case"group_sum":case"group_average":{J(t,"groupBy",s,a),J(t,"fields",s,a);break}case"sort":{I(t,"field",s,a),t.direction!=null&&t.direction!=="asc"&&t.direction!=="desc"&&s.push(`${a} direction must be asc or desc`);break}case"limit":{const r=S(t.count);(r==null||!Number.isInteger(r)||r<1||r>5e3)&&s.push(`${a} count must be an integer from 1 to 5000`);break}case"unpivot_weeks":{t.sourceField!=null&&I(t,"sourceField",s,a),t.indexField!=null&&I(t,"indexField",s,a),t.valueField!=null&&I(t,"valueField",s,a),t.keepFields!=null&&J(t,"keepFields",s,a),K(t,"startIndex",s,a),K(t,"valueScale",s,a);break}case"retention_w4_flow":{const r=["cohortField","signupField","w1Field","w4Field","sourceField","targetField","valueField","cohortOutputField"];for(const i of r)t[i]!=null&&I(t,i,s,a);break}}}function bt(e,t){return!e.length||e.some(n=>Object.prototype.hasOwnProperty.call(n,t))}function yt(e,t){return e.length?e.map(s=>s[t]).filter(s=>s!=null).every(s=>typeof s=="number"&&Number.isFinite(s)):!0}function gt(e){const t=[],n=[];if(!x(e))return{ok:!1,errors:["querySpec must be an object"],warnings:n};const s=p(e.kind),a=ht(e.declaredParameters,t);switch(s){case"snapshot_artifact":{const r=p(e.artifact),i=p(e.jsonPath);ct.has(r)||t.push("snapshot_artifact querySpec must use an allowlisted artifact"),Ce(i)||t.push("snapshot_artifact querySpec must include a safe jsonPath"),e.transforms!=null&&(Array.isArray(e.transforms)?(e.transforms.length>50&&t.push("snapshot_artifact transforms cannot exceed 50 entries"),e.transforms.forEac
110h((o,d)=>{if(!x(o)){t.push(`transform ${d} must be an object`);return}const u=p(o.op);le.has(u)||t.push(`transform ${d} uses unsupported op '${u||"(missing)"}'`),x(o.args)||t.push(`transform ${d} args must be an object`),le.has(u)&&x(o.args)&&Ie(u,o.args,d,t)})):t.push("snapshot_artifact transforms must be an array"));break}case"semantic_metric":{if(!Array.isArray(e.metricIds)||e.metricIds.length===0)t.push("semantic_metric querySpec requires metricIds");else{e.metricIds.length>50&&t.push("semantic_metric metricIds cannot exceed 50 entries");const i=new Set;for(const o of e.metricIds)typeof o!="string"||!ce(o)?t.push("semantic_metric metricIds must be safe identifiers"):i.has(o)&&t.push(`semantic_metric metricId '${o}' must be unique`),typeof o=="string"&&i.add(o)}if(!Array.isArray(e.dimensions))t.push("semantic_metric dimensions must be an array");else{e.dimensions.length>50&&t.push("semantic_metric dimensions cannot exceed 50 entries");const i=new Set;for(const o of e.dimensions)typeof o!="string"||!y(o)?t.push("semantic_metric dimensions must be safe field names"):i.has(o)&&t.push(`semantic_metric dimension '${o}' must be unique`),typeof o=="string"&&i.add(o)}if(!Array.isArray(e.filters))t.push("semantic_metric filters must be an array");else{e.filters.length>100&&t.push("semantic_metric filters cannot exceed 100 entries");for(const[i,o]of e.filters.entries()){if(!x(o)){t.push(`semantic_metric filters[${i}] must be an object`);continue}
110y(p(o.field))||t.push(`semantic_metric filters[${i}].field must be safe`),ft.has(p(o.op))||t.push(`semantic_metric filters[${i}].op is unsupported`),o.op==="in"?(!Array.isArray(o.value)||o.value.length===0||o.value.some(d=>!V(d)))&&t.push(`semantic_metric filters[${i}].value must be a primitive array for op in`):(o.value==null||!V(o.value))&&t.push(`semantic_metric filters[${i}].value must be a string, number, or boolean`)}}(!x(e.time)||!["day","week","month"].includes(p(e.time.grain)))&&t.push("semantic_metric time.grain must be day, week, or month");const r=x(e.time)?p(e.time.parameter):"";if(x(e.time)&&e.time.parameter!=null&&!y(r)&&t.push("semantic_metric time.parameter must be a safe field name"),r&&a.get(r)!=="date_range"&&t.push("semantic_metric time.parameter must reference a date_range parameter"),e.sort!=null)if(!Array.isArray(e.sort))t.push("semantic_metric sort must be an array");else{e.sort.length>20&&t.push("semantic_metric sort cannot exceed 20 entries");for(const[i,o]of e.sort.entries()){if(!x(o)){t.push(`semantic_metric sort[${i}] must be an object`);continue}
110y(p(o.field))||t.push(`semantic_metric sort[${i}].field must be safe`),o.direction!=="asc"&&o.direction!=="desc"&&t.push(`semantic_metric sort[${i}].direction must be asc or desc`)}}if(e.limit!=null){const i=S(e.limit);(!Number.isInteger(i)||i<1||i>5e3)&&t.push("semantic_metric limit must be an integer from 1 to 5000")}break}case"approved_sql":{ce(p(e.queryId))||t.push("approved_sql queryId must be a safe identifier"),pt(p(e.queryVersion))||t.push("approved_sql queryVersion must be a safe version identifier");break}default:t.push("querySpec.kind must be snapshot_artifact, semantic_metric, or approved_sql")}return{ok:t.length===0,errors:t,warnings:n}}function vt(e,t=[]){const n=[],s=[];if(!x(e))return{ok:!1,errors:["chartSpec must be an object"],warnings:s};e.schemaVersion!=="cos-chart-spec/v1"&&n.push("chartSpec.schemaVersion must be cos-chart-spec/v1");const a=p(e.renderer),r=p(e.chartType);ut.has(a)||n.push("chartSpec.renderer is not supported"),dt.has(r)||n.push("chartSpec.chartType is not supported"),a==="vega"&&n.push("Raw Vega renderer is reserved until guarded raw spec authoring is implemented"),a==="cos_cohort_matrix"&&r!=="heatmap"&&n.push("cos_cohort_matrix renderer requires chartType heatmap"),a==="cos_kpi"&&r!=="kpi"&&n.push("cos_kpi renderer requires chartType kpi"),a==="cos_markdown"&&r!=="markdown"&&n.push("cos_markdown renderer requires chartType markdown"),a==="cos_table"&&r!=="table"&&n.push("cos_table renderer requires chartType table"),a==="cos_sankey"&&r!=="sankey"&&n.push("cos_sankey renderer requires chartType sankey"),x(e.encodings)||n.push("chartSpec.encodings must be an object"),e.axes!=null&&!x(e.axes)&&n.push("chartSpec.axes must be an object");const i=x(e.encodings)?e.encodings:{},o=x(e.axes)?e.axes:{},d=x(i.x)?i.x:void 0,u=Array.isArray(i.y)?i.y:[],c=x(i.y2)?i.y2:void 0,f=x(i.color)?i.color:void 0,h=Array.isArray(i.tooltip)?i.tooltip:[],v=e.dataLabels==null?void 0:x(e.dataLabels)?e.dataLabels:null,j=!["table","kpi","markdown"].includes(r),M=!["table","kpi","markdown","histogram"].includes(r);i.y!=null&&!Array.isArray(i.y)&&n.push("y encoding must be an array"),u.length>50&&n.push("y encoding cannot exceed 50 entries"),h.length>100&&n.push("tooltip encoding cannot exceed 100 entries"),j&&!d?.field&&n.push(`${r} chart requires an x encoding`),M&&u.length===0&&n.push(`${r} chart requires at least one y encoding`),!t.length&&(d?.field||u.length||c?.field||f?.field||h.length)&&s.push("chartSpec field validation was not proven because preview rows are empty");const D=(b,k,_=!1)=>{if(!b){n.push(`${k} requires field`);return}if(!y(b)){n.push(`${k} field '${b}' must be a safe field name`);return}bt(t,b)||n.push(`${k} field '${b}' is not present in preview rows`),_&&!yt(t,b)&&n.push(`${k} field '${b}' must be numeric`)};if(d){const b=p(d.field);D(b,"x encoding"),ee(d.label,n,"x encoding label"),he.has(p(d.type))||n.push("x encoding type must be time, category, or number")}for(const b of u){if(!x(b)){n.push("y encoding entries must be objects");continue}const k=p(b.field);D(k,"y encoding",r!=="table"),ee(b.label,n,"y encoding label"),b.format&&!ne.has(p(b.format))&&n.push(`format '${String(b.format)}' is not supported`)}if(v===null?n.push("dataLabels must be an object"):v&&v.visible!=null&&typeof v.visible!="boolean"&&n.push("dataLabels.visible must be a boolean"),v?.visible===!0){v.mode!=null&&v.mode!=="last"&&v.mode!=="spaced"&&v.mode!=="all"&&n.push("dataLabels.mode must be last, spaced, or all");const b=v.sampleEvery;if(b!=null&&(typeof b!="number"||!Number.isInteger(b)||b<2||b>52)&&n.push("dataLabels.sampleEvery must be an integer from 2 to 52"),v.format!=null&&!ne.has(p(v.format))&&n.push(`dataLabels.format '${String(v.format)}' is not supported`),v.fields!=null)if(!Array.isArray(v.fields))n.push("dataLabels.fields must be an array");
110else{const k=new Set(u.flatMap(_=>x(_)?[p(_.field)]:[]));for(const _ of v.fields)typeof _!="string"||!_||!y(_)?n.push("dataLabels.fields entries must be safe field names"):k.has(_)||n.push(`dataLabels field '${_}' must match a y encoding field`)}["line","bar","stacked_bar"].includes(r)||s.push("dataLabels are only rendered for line and bar-style charts")}if(c){const b=p(c.field);D(b,"y2 encoding"),ee(c.label,n,"y2 encoding label"),c.type&&!he.has(p(c.type))&&n.push("y2 encoding type must be time, category, or number")}f?.field&&D(p(f.field),"color encoding",r==="heatmap"),f?.scale!=null&&(!x(f.scale)||Object.entries(f.scale).some(([b,k])=>!b||b.length>200||typeof k!="string"||!k||k.length>100))&&n.push("color encoding scale must map bounded strings to bounded colors");for(const b of h){if(typeof b!="string"||!b){n.push("tooltip fields must be non-empty strings");continue}D(b,"tooltip")}if(i.tooltip!=null&&!Array.isArray(i.tooltip)&&n.push("tooltip encoding must be an array"),e.legend!=null&&(x(e.legend)?(typeof e.legend.visible!="boolean"&&n.push("legend.visible must be a boolean"),e.legend.position!=null&&e.legend.position!=="top"&&e.legend.position!=="bottom"&&e.legend.position!=="right"&&n.push("legend.position must be top, bottom, or right")):n.push("legend must be an object")),e.interaction!=null&&(x(e.interaction)?(e.interaction.expandable!=null&&typeof e.interaction.expandable!="boolean"&&n.push("interaction.expandable must be a boolean"),e.interaction.annotations!=null&&typeof e.interaction.annotations!="boolean"&&n.push("interaction.annotations must be a boolean")):n.push("interaction must be an object")),r==="heatmap"&&!c?.field&&n.push("heatmap chart requires a y2 encoding"),r==="sankey"&&(a!=="cos_sankey"&&n.push("sankey charts should use the cos_sankey renderer"),d?.field||n.push("sankey chart requires an x source encoding"),c?.field||n.push("sankey chart requires a y2 target encoding"),d?.type&&d.type!=="category"&&n.push("sankey x encoding must be category"),c?.type&&c.type!=="category"&&n.push("sankey y2 encoding must be category")),(r==="line"||r==="area")&&d?.type!=="time"&&s.push("Lindy dashboard defaults prefer time on the x-axis for line and area charts"),a==="vega_lite"&&r==="table"&&n.push("table charts should use the cos_table renderer"),a.startsWith("cos_")&&r!=="table"&&r!=="kpi"&&r!=="heatmap"&&r!=="markdown"&&r!=="sankey"&&s.push("COS-native renderers are reserved for tables, KPI tiles, markdown headings, dense matrix-style views, and flow views"),o.yDomain!=null)if(!Array.isArray(o.yDomain)||o.yDomain.length!==2)n.push("axes.yDomain must be a two-value numeric domain");else{const b=S(o.yDomain[0]),k=S(o.yDomain[1]);(b==null||k==null||b>=k)&&n.push("axes.yDomain must contain finite ascending numbers")}if(o.y2Domain!=null)if(!Array.isArray(o.y2Domain)||o.y2Domain.length!==2)n.push("axes.y2Domain must be a two-value numeric domain");else{const b=S(o.y2Domain[0]),k=S(o.y2Domain[1]);(b==null||k==null||b>=k)&&n.push("axes.y2Domain must contain finite ascending numbers")}return o.zeroBaseline!=null&&typeof o.zeroBaseline!="boolean"&&n.push("axes.zeroBaseline must be a boolean"),o.orientation!=null&&o.orientation!=="horizontal"&&o.orientation!=="vertical"&&n.push("axes.orientation must be horizontal or vertical"),o.matrixMetaFields!=null&&(!Array.isArray(o.matrixMetaFields)||o.matrixMetaFields.length>50||o.matrixMetaFields.some(b=>typeof b!="string"||!y(b)))&&n.push("axes.matrixMetaFields must contain at most 50 safe field names"),xt(o.tableColumns,n),St(o.seriesStyles,u,n),{ok:n.length===0,errors:n,warnings:s}}function xt(e,t){if(e!=null){if(!Array.isArray(e)||e.length===0||e.length>100){t.push("axes.tableColumns must contain 1 to 100 columns");return}e.forEach((n,s)=>{const a=`axes.tableColumns[${s}]`;if(!x(n)){t.push(`${a} must be an object`);return}
110y(p(n.field))||t.push(`${a}.field must be a safe field name`),ee(n.label,t,`${a}.label`),n.format!=null&&!ne.has(p(n.format))&&t.push(`${a}.format is unsupported`),n.width!=null&&(typeof n.width!="string"||!/^\d+(\.\d+)?(px|%)$/.test(n.width))&&t.push(`${a}.width must use px or percent units`)})}}function St(e,t,n){if(e==null)return;if(!Array.isArray(e)||e.length>50){n.push("axes.seriesStyles must contain at most 50 entries");return}const s=new Set(t.flatMap(a=>x(a)?[p(a.field)]:[]));e.forEach((a,r)=>{const i=`axes.seriesStyles[${r}]`;if(!x(a)){n.push(`${i} must be an object`);return}const o=p(a.field);(!y(o)||!s.has(o))&&n.push(`${i}.field must reference a safe y encoding field`),ee(a.label,n,`${i}.label`),a.mark!=null&&!["area","bar","line"].includes(p(a.mark))&&n.push(`${i}.mark must be area, bar, or line`),a.axis!=null&&a.axis!=="y"&&a.axis!=="y2"&&n.push(`${i}.axis must be y or y2`),a.format!=null&&!ne.has(p(a.format))&&n.push(`${i}.format is unsupported`),a.color!=null&&(typeof a.color!="string"||!/^#[0-9A-Fa-f]{6}$/.test(a.color))&&n.push(`${i}.color must be a six-digit hex color`),a.strokeDash!=null&&(!Array.isArray(a.strokeDash)||a.strokeDash.length===0||a.strokeDash.length>4||a.strokeDash.some(d=>S(d)==null||d<0))&&n.push(`${i}.strokeDash must contain 1 to 4 non-negative numbers`)})}function V(e){return typeof e=="string"||typeof e=="number"&&Number.isFinite(e)||typeof e=="boolean"}function be(e){return x(e)&&Object.entries(e).every(([t,n])=>t.length>0&&t.length<=200&&!["__proto__","constructor","prototype"].includes(t)&&V(n))}function $t(e,t){const n=[];if(!x(e))return{errors:["displaySpec must be an object"]};const s=(c,f)=>{if(typeof f!="string"||!y(f)){n.push(`${c}.control must be a safe field name`);return}},a=["wide"];for(const c of a)e[c]!=null&&typeof e[c]!="boolean"&&n.push(`displaySpec.${c} must be a boolean`);const r={designNotes:5e3,emptyState:500,kpiComparisonLabel:200,kpiLabel:200,markdown:25e4,resultCacheKey:200,sourceDashboardRef:500,sourceLabel:200,sourceTileRef:500};for(const[c,f]of Object.entries(r))e[c]!=null&&(typeof e[c]!="string"||e[c].length>f)&&n.push(`displaySpec.${c} must be a string no longer than ${f} characters`);const i=["kpiComparisonField","kpiValueField"];for(const c of i)e[c]!=null&&!y(p(e[c]))&&n.push(`displaySpec.${c} must be a safe field name`);const o=S(e.height);e.height!=null&&(o==null||o<48||o>1e3)&&n.push("displaySpec.height must be a number from 48 to 1000");const d=S(e.tableMaxRows);e.tableMaxRows!=null&&(!Number.isInteger(d)||d==null||d<1||d>5e3)&&n.push("displaySpec.tableMaxRows must be an integer from 1 to 5000");const u=[["cacheMode",["preview","result_cache"]],["chrome",["standard","control"]],["kpiFormat",[...ne]],["kpiNotation",["compact","standard"]],["kpiRow",["first","last"]],["scope",["range","point-in-time","daily","weekly","monthly"]],["tableDensity",["standard","compact"]],["trust",["verified","measured","sample","proxy","external"]]];for(const[c,f]of u)e[c]!=null&&!f.includes(p(e[c]))&&n.push(`displaySpec.${c} is unsupported`);if(e.semanticMetricIds!=null)if(!Array.isArray(e.semanticMetricIds))n.push("displaySpec.semanticMetricIds must be an array");else{e.semanticMetricIds.length>50&&n.push("displaySpec.semanticMetricIds cannot exceed 50 entries");const c=new Set;e.semanticMetricIds.forEach((f,h)=>{typeof f!="string"||!ce(f)?n.push(`displaySpec.semanticMetricIds[${h}] must be a safe identifier`):c.has(f)&&n.push(`displaySpec.semanticMetricIds contains duplicate '${f}'`),typeof f=="string"&&c.add(f)})}return e.visibleWhen!==void 0&&(Array.isArray(e.visibleWhen)?(e.visibleWhen.length>50&&n.push("displaySpec.visibleWhen cannot exceed 50 entries"),e.visibleWhen.forEach((c,f)=>{const h=`displaySpec.visibleWhen[${f}]`;if(!x(c)){n.push(`${h} must be an object`);return}s(h,c.control),c.value!==void 0&&!V(c.value)&&n.push(`${h}.value must be a string, number, or boolean`),c.values!==void 0&&(!Array.isArray(c.values)||!c.values.every(V))&&n.push(`${h}.values must be an array of strings, numbers, or booleans`),Array.isArray(c.values)&&c.values.length>100&&n.push(`${h}.values cannot exceed 100 entries`),c.valueMap!==void 0&&!be(c.valueMap)&&n.push(`${h}.valueMap must map strings to primitive values`)})):n.push("displaySpec.visibleWhen must be an array of rules")),e.clientFilters!==void 0&&(Array.isArray(e.clientFilters)?(e.clientFilters.length>50&&n.push("displaySpec.clientFilters cannot exceed 50 entries"),e.clientFilters.forEac
110h((c,f)=>{const h=`displaySpec.clientFilters[${f}]`;if(!x(c)){n.push(`${h} must be an object`);return}s(h,c.control),c.op!=="date_range"&&c.op!=="eq"&&n.push(`${h}.op must be date_range or eq`),c.op==="eq"&&!p(c.field).trim()&&n.push(`${h}.field is required for eq filters`),c.field!==void 0&&(typeof c.field!="string"||!y(c.field))&&n.push(`${h}.field must be a safe field name`),c.valueMap!==void 0&&!be(c.valueMap)&&n.push(`${h}.valueMap must map strings to primitive values`)})):n.push("displaySpec.clientFilters must be an array of filters")),{errors:n}}function kt(e){const t=[],n=new Set;return e==null?{errors:t,controlNames:n}:Array.isArray(e)?(e.length>20&&t.push("dashboard.layoutSpec.controls cannot exceed 20 entries"),e.forEach((s,a)=>{const r=`dashboard.layoutSpec.controls[${a}]`;if(!x(s)){t.push(`${r} must be an object`);return}const i=p(s.name);if(y(i)?n.has(i)?t.push(`${r}.name duplicates control "${i}"`):n.add(i):t.push(`${r}.name must be a safe field name`),p(s.label).trim()||t.push(`${r}.label is required`),s.disabled!=null&&typeof s.disabled!="boolean"&&t.push(`${r}.disabled must be a boolean`),s.note!=null&&typeof s.note!="string"&&t.push(`${r}.note must be a string`),s.sourceLabel!=null&&typeof s.sourceLabel!="string"&&t.push(`${r}.sourceLabel must be a string`),s.type==="date_range")if(!x(s.defaultValue))t.push(`${r}.defaultValue must be an object with start/end`);else for(const o of["start","end"]){const d=s.defaultValue[o];d!=null&&(typeof d!="string"||!B(d))&&t.push(`${r}.defaultValue.${o} must be a parseable date string`)}else if(s.type==="enum")if(typeof s.defaultValue!="string"&&t.push(`${r}.defaultValue must be a string`),!Array.isArray(s.options)||s.options.length===0||s.options.length>100||!s.options.every(o=>x(o)&&typeof o.value=="string"&&o.value.length>0&&o.value.length<=200&&typeof o.label=="string"&&o.label.trim().length>0&&o.label.length<=200))t.push(`${r}.options must contain 1 to 100 bounded { label, value } strings`);else{const o=s.options.map(d=>p(d.value));new Set(o).size!==o.length&&t.push(`${r}.options values must be unique`),typeof s.defaultValue=="string"&&!o.includes(s.defaultValue)&&t.push(`${r}.defaultValue must match an option value`)}else t.push(`${r}.type must be date_range or enum`)}),{errors:t,controlNames:n}):{errors:["dashboard.layoutSpec.controls must be an array"],controlNames:n}}function jt(e,t){if(!Ce(t))return;const n=t.replace(/^\$?\./,"");return n?n.split(".").reduce((s,a)=>{if(Array.isArray(s)){const r=Number(a);return Number.isInteger(r)?s[r]:void 0}if(x(s))return s[a]},e):e}function Ce(e){if(typeof e!="string")return!1;const t=e.startsWith("$.")?e.slice(2):e;return/^[A-Za-z0-9_-]+(?:\.[A-Za-z0-9_-]+)*$/.test(t)?t.split(".").every(n=>!["__proto__","constructor","prototype"].includes(n)):!1}function $(e){return we(e)}function B(e){if(typeof e!="string"||!e)return null;const t=/^\d{4}-\d{2}-\d{2}$/.test(e),n=t?new Date(`${e}T00:00:00Z`):new Date(e);return Number.isNaN(n.getTime())||t&&n.toISOString().slice(0,10)!==e?null:n}function ye(e){return e.toISOString().slice(0,10)}function _t(e,t){const n=B(e);if(!n)return"";if(t==="day")return ye(n);if(t==="month")return new Date(Date.UTC(n.getUTCFullYear(),n.getUTCMonth(),1)).toISOString().slice(0,10);const s=new Date(Date.UTC(n.getUTCFullYear(),n.getUTCMonth(),n.getUTCDate())),a=(s.getUTCDay()+6)%7;return s.setUTCDate(s.getUTCDate()-a),ye(s)}function Me(e,t){const n=S(e),s=S(t);if(n!=null&&s!=null)return n-s;const a=typeof e=="string"?Date.parse(e):Number.NaN,r=typeof t=="string"?Date.parse(t):Number.NaN;return Number.isFinite(a)&&Number.isFinite(r)?a-r:String(e??"").localeCompare(String(t??""))}function Nt(e,t){const n=p(t.cohortField)||"cohort_week",s=p(t.signupField)||"signups",a=p(t.w1Field)||"w1",r=p(t.w4Field)||"w4",i=p(t.sourceField)||"source",o=p(t.targetField)||"target",d=p(t.valueField)||"value",u=p(t.cohortOutputField)||"cohort_week";if([n,s,a,r,i,o,d,u].some(_=>!y(_)))return e;const f=[...e].filter(_=>{const q=S(_[s]),m=S(_[a]),F=S(_[r]);return q!=null&&q>0&&m!=null&&m>0&&F!=null&&F>0}).sort((_,q)=>Me(q[n],_[n]))[0];if(!f)return[];const h=S(f[s])??0,v=Math.min(S(f[a])??0,h),j=Math.min(S(f[r])??0,v),M=Math.max(h-v,0),D=Math.max(v-j,0),b=f[n],k={[u]:b};return[{...k,[i]:"Signup cohort",[o]:"Active in W1",[d]:v},{...k,[i]:"Signup cohort",[o]:"No W1 activity",[d]:M},{...k,[i]:"Active in W1",[o]:"Active in W4",[d]:j},{...k,[i]:"Active in W1",[o]:"Dropped before W4",[d]:D}]}function Ft(e,t=[]){At(t);let n=e;for(const s of t){const a=x(s.args)?s.args:{};switch(s.op){case"filter_nonzero_any":{const r=O(a.fields).filter(y);n=$(n).filter(i=>r.some(o=>{const d=S(i[o]);return d!=null&&d!==0}));break}case"filter_eq":{const r=p(a.field),i=a.value;if(!y(r)||i==null||!V(i)){n=$(n);continue}n=$(n).filter(o=>o[r]===i);break}case"filter_neq":{const r=p(a.field),i=a.value;if(!y(r)||i==null||!V(i)){n=$(n);continue}n=$(n).filter(o=>o[r]!==i);break}case"filter_in":{const r=p(a.field),i=Array.isArray(a.values)?a.values.filter(V):[];if(!y(r)||!i.length){n=$(n);continue}n=$(n).filter(o=>i.includes(o[r]));break}case"filter_date_range":{const r=p(a.field),i=B(a.start),o=B(a.end);if(!y(r)||!i&&!o){n=$(n);continue}n=$(n).filter(d=>{const u=B(d[r]);return!(!u||i&&u<i||o&&u>o)});break}case"derive_scale":{const r=p(a.field),i=p(a.source),o=S(a.scale);if(!y(r)||!y(i)||o==null){n=$(n);continue}n=$(n).map(d=>{const u=S(d[i]);return{...d,[r]:u==null?null:u*o}});break}case"derive_ratio":{const r=p(a.field),i=p(a.numerator),o=p(a.denominator),d=S(a.scale)??1;if(!y(r)||!y(i)||!y(o)){n=$(n);continue}n=$(n).map(u=>{const c=S(u[i]),f=S(u[o]);return{...u,[r]:c!=null&&f?c/f*d:null}});break}case"derive_sum":{const r=p(a.field),i=O(a.fields).filter(y),o=S(a.scale)??1;if(!y(r)){n=$(n);continue}n=$(n).map(d=>({...d,[r]:i.reduce((u,c)=>u+(S(d[c])??0),0)*o}));break}case"derive_constant":{const r=p(a.field),i=a.value;if(!y(r)||i==null||!V(i)){n=$(n);continue}n=$(n).map(o=>({...o,[r]:i}));break}case"derive_date_grains":{const r=p(a.dateField),i=p(a.periodField)||"periodStart",o=p(a.grainField)||"grain",u=(Array.isArray(a.grains)?a.grains:["week","month"]).filter(c=>c==="day"||c==="week"||c==="month");if(!y(r)||!y(i)||!y(o)||!u.length){n=$(n);continue}n=$(n).flatMap(c=>u.flatMap(f=>{const h=_t(c[r],f);return h?[{...c,[i]:h,[o]:f}]:[]}));break}case"derive_date_prefix":{const r=p(a.field),i=p(a.source)||r;if(!y(r)||!y(i)){n=$(n);continue}n=$(n).map(o=>
110{const d=o[i],u=typeof d=="string"?d.match(/^\d{4}-\d{2}-\d{2}/):null;return u?{...o,[r]:u[0]}:o});break}case"group_sum":{const r=O(a.groupBy).filter(y),i=O(a.fields).filter(y);if(!r.length||!i.length){n=$(n);continue}const o=new Map;for(const d of $(n)){const u=JSON.stringify(r.map(f=>d[f]??null)),c=o.get(u)??Object.fromEntries(r.map(f=>[f,d[f]]));for(const f of i)c[f]=(S(c[f])??0)+(S(d[f])??0);o.set(u,c)}n=[...o.values()];break}case"group_average":{const r=O(a.groupBy).filter(y),i=O(a.fields).filter(y);if(!r.length||!i.length){n=$(n);continue}const o=new Map;for(const d of $(n)){const u=JSON.stringify(r.map(f=>d[f]??null)),c=o.get(u)??{row:Object.fromEntries(r.map(f=>[f,d[f]])),sums:{},counts:{}};for(const f of i){const h=S(d[f]);h!=null&&(c.sums[f]=(c.sums[f]??0)+h,c.counts[f]=(c.counts[f]??0)+1)}o.set(u,c)}n=[...o.values()].map(({row:d,sums:u,counts:c})=>{const f={...d};for(const h of i){const v=c[h]??0;f[h]=v>0?(u[h]??0)/v:null}return f});break}case"unpivot_weeks":{const r=p(a.sourceField)||"weeks",i=p(a.indexField)||"week",o=p(a.valueField)||"value",d=O(a.keepFields).filter(y),u=S(a.startIndex)??0,c=S(a.valueScale)??1;if(!y(r)||!y(i)||!y(o)){n=$(n);continue}n=$(n).flatMap(f=>{const h=f[r];return Array.isArray(h)?h.flatMap((v,j)=>{const M=S(v);return M==null?[]:[{...Object.fromEntries(d.map(b=>[b,f[b]])),[i]:j+u,[o]:M*c}]}):[]});break}case"retention_w4_flow":{n=Nt($(n),a);break}case"sort":{const r=p(a.field),i=a.direction==="desc"?-1:1;n=y(r)?[...$(n)].sort((o,d)=>Me(o[r],d[r])*i):$(n);break}case"limit":{const r=Math.max(0,Math.min(5e3,Number(a.count??5e3)));n=$(n).slice(0,r);break}}}return n}function we(e){return Array.isArray(e)?e.filter(x):[]}function At(e){const t=[];if(!Array.isArray(e))throw new Error("Dashboard query transforms must be an array");if(e.length>50&&t.push("snapshot_artifact transforms cannot exceed 50 entries"),e.forEach((n,s)=>{if(!x(n)){t.push(`transform ${s} must be an object`);return}const a=p(n.op);if(!le.has(a)){t.push(`transform ${s} uses unsupported op '${a||"(missing)"}'`);return}if(!x(n.args)){t.push(`transform ${s} args must be an object`);return}Ie(a,n.args,s,t)}),t.length)throw new Error(`Invalid dashboard query transforms: ${t.join("; ")}`)}const Dt=new Set(["table","cohort_matrix","kpi","markdown","sankey"]);function It(e){const t=[];w(e)||ge(["bundle must be an object"]),(!w(e.dashboard)||typeof e.dashboard.id!="string")&&t.push("dashboard must include an id"),Array.isArray(e.charts)?e.charts.forEach((n,s)=>Mt(n,s,t)):t.push("charts must be an array"),e.currentVersion!=null&&wt(e.currentVersion,t),t.length&&ge(t)}function Ct(e){const t=[];w(e)||ve(["bundle must be an object"]),(!w(e.section)||typeof e.section.id!="string")&&t.push("section must include an id"),Array.isArray(e.dashboards)||t.push("dashboards must be an array"),e.currentVersion!=null&&(w(e.currentVersion)?Et(e.currentVersion.dashboardRefs,t):t.push("currentVersion must be an object or null")),t.length&&ve(t)}function Mt(e,t,n){const s=`charts[${t}]`;if(!w(e)){n.push(`${s} must be an object`);return}if(Ve(e.tile,`${s}.tile`,n),!w(e.chartVersion)){n.push(`${s}.chartVersion must be an object`);return}const a=gt(e.chartVersion.querySpec);n.push(...a.errors.map(o=>`${s}.${o}`));const r=vt(e.chartVersion.chartSpec);n.push(...r.errors.map(o=>`${s}.${o}`));const i=$t(e.chartVersion.displaySpec);n.push(...i.errors.map(o=>`${s}.${o}`)),qt(e.chartVersion.compiledRendererSpec,s,n),Rt(e.chartVersion.validation,s,n)}function wt(e,t){if(!w(e)){t.push("currentVersion must be an object or null");return}if(Vt(e.layoutSpec,t),!Array.isArray(e.tiles)){t.push("currentVersion.tiles must be an array");return}e.tiles.forEach((n,s)=>Ve(n,`currentVersion.tiles[${s}]`,t))}function Vt(e,t){if(!w(e)){t.push("currentVersion.layoutSpec must be an object");return}if(e.columns!=null&&!de(e.columns,1,24)&&t.push("currentVersion.layoutSpec.columns must be an integer from 1 to 24"),e.gap!=null&&!Lt(e.gap,0,64)&&t.push("currentVersion.layoutSpec.gap must be a number from 0 to 64"),e.controls==null)return;if(!Array.isArray(e.controls)){t.push("currentVersion.layoutSpec.controls must be an array");return}const n=kt(e.controls);t.push(...n.errors.map(s=>s.replace("dashboard.layoutSpec","currentVersion.layoutSpec")))}
110function Ve(e,t,n){if(!w(e)||typeof e.tileId!="string"||typeof e.chartId!="string"||typeof e.chartVersionId!="string"){n.push(`${t} must include tileId, chartId, and chartVersionId`);return}if(e.titleOverride!=null&&typeof e.titleOverride!="string"&&n.push(`${t}.titleOverride must be a string`),e.hidden!=null&&typeof e.hidden!="boolean"&&n.push(`${t}.hidden must be a boolean`),e.layout!=null){if(!w(e.layout)){n.push(`${t}.layout must be an object`);return}e.layout.colSpan!=null&&!de(e.layout.colSpan,1,24)&&n.push(`${t}.layout.colSpan must be an integer from 1 to 24`),e.layout.rowSpan!=null&&!de(e.layout.rowSpan,1,12)&&n.push(`${t}.layout.rowSpan must be an integer from 1 to 12`)}}function qt(e,t,n){if(!w(e)||typeof e.compilerVersion!="string"){n.push(`${t}.compiledRendererSpec must be an object with a compilerVersion`);return}if(e.target==="vega_lite"){w(e.spec)||n.push(`${t}.compiledRendererSpec.spec must be an object`);return}if(e.target==="cos_native"){(!Dt.has(String(e.component))||!w(e.props))&&n.push(`${t}.compiledRendererSpec must use a supported native component`);return}n.push(`${t}.compiledRendererSpec.target is unsupported`)}function Rt(e,t,n){(!w(e)||typeof e.ok!="boolean"||typeof e.proven!="boolean"||!xe(e.errors)||!xe(e.warnings))&&n.push(`${t}.validation must include status booleans and string arrays`)}function Et(e,t){if(!Array.isArray(e)){t.push("currentVersion.dashboardRefs must be an array");return}e.forEach((n,s)=>{(!w(n)||typeof n.dashboardId!="string"||typeof n.default!="boolean"||!Number.isInteger(n.order)||n.label!=null&&typeof n.label!="string")&&t.push(`currentVersion.dashboardRefs[${s}] must include dashboardId, default, and order`)})}function ge(e){throw new Error(`Dashboard configuration is invalid: ${e.slice(0,3).join("; ")}`)}function ve(e){throw new Error(`Dashboard section configuration is invalid: ${e.slice(0,3).join("; ")}`)}function w(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function xe(e){return Array.isArray(e)&&e.every(t=>typeof t=="string")}function de(e,t,n){return typeof e=="number"&&Number.isInteger(e)&&e>=t&&e<=n}function Lt(e,t,n){return typeof e=="number"&&Number.isFinite(e)&&e>=t&&e<=n}async function Tt(e){return(await Q("AnalyticsSnapshotChartDataDownload",Z.AnalyticsSnapshotChartDataDownload,{chartVersionId:e})).analyticsSnapshotChartDataDownload}async function zt(e){return(await Q("Dashboards",Z.Dashboards,{workspaceId:e})).admin.analytics.dashboards}async function Ot(e){const n=(await Q("DashboardBundle",Z.DashboardBundle,{id:Ne("AnalyticsDashboard",e)})).admin.analytics.dashboard;return n&&It(n),n}async function Bt(e){return(await Q("Sections",Z.Sections,{workspaceId:e})).admin.analytics.dashboardSections}async function Ut(e){const n=(await Q("Section",Z.Section,{id:Ne("AnalyticsDashboardSection",e)})).admin.analytics.dashboardSection;return n&&Ct(n),n}function Pt({children:e,source:t,subtitle:n,title:s}){return l.jsxs("article",{className:"dashboard-panel",children:[l.jsxs("header",{className:"dashboard-panel-header",children:[l.jsxs("div",{children:[l.jsx("h2",{children:s}),n?l.jsx("p",{children:n}):null]}),t?l.jsxs("span",{className:"dashboard-source",title:`Source: ${t}`,children:[l.jsx(Ae,{"aria-hidden":"true",size:14}),l.jsx("span",{children:t})]}):null]}),l.jsx("div",{className:"dashboard-panel-body",children:e})]})}const X=new Map;function Wt(e){if(e.kind==="approved_sql")return"approved_sql is not supported by the snapshot-only dashboard shell.";if(e.kind==="semantic_metric")return"semantic_metric is not supported by the snapshot-only dashboard shell."}async function Gt(e){const{querySpec:t}=e,n=Wt(t);if(n)throw new Error(n);if(t.kind!=="snapshot_artifact")throw new Error("Unsupported dashboard query");const s=ot(t.artifact),a=s??`${De()}:${e.id}`;let r=X.get(a);r||(r=s?qe(s,"include").then(d=>({isFragment:!1,root:d})):Zt(e.id),X.set(a,r));let i;try{i=await r}catch(d){throw X.get(a)===r&&X.delete(a),d}const o=i.isFragment?i.root:jt(i.root,t.jsonPath);return we(Ft(o,t.transforms))}function Se(){X.clear()}async function Zt(e){const t=await Tt(e);if(!t)throw new Error("Snapshot chart data is unavailable");return{isFragment:t.isFragment,root:await qe(t.url,"omit")}}async function qe(e,t){const n=await globalThis.fetch(e,{credentials:t});if(!n.ok)throw new Error(`Snapshot artifact request failed with status ${n.status}`);try{return await n.json()}
110catch{throw new Error("Snapshot artifact did not return JSON")}}function Qt(e){const t=Number.isInteger(e?.columns)?Math.max(1,Math.min(24,Number(e?.columns))):12,n=typeof e?.gap=="number"&&Number.isFinite(e.gap)?Math.max(0,Math.min(64,e.gap)):16;return{columns:t,gap:n}}function $e(e,t){const n=Number(e.layout?.colSpan??t);return{gridColumn:`span ${Number.isInteger(n)?Math.max(1,Math.min(t,n)):t}`}}function Yt(e){return Array.isArray(e)?e.filter(t=>!t||typeof t!="object"||!t.name?!1:t.type==="date_range"||Array.isArray(t.options)):[]}function ke(e){return Object.fromEntries(e.map(t=>[t.name,t.type==="date_range"?{end:t.defaultValue.end??"",start:t.defaultValue.start??""}:t.defaultValue]))}function Jt(e,t,n,s){const a=[...t.displaySpec.clientFilters??[]],r=n.find(i=>i.type==="date_range");return r&&!a.some(i=>i.op==="date_range")&&a.push({control:r.name,op:"date_range"}),!a.length||!e.length?e:a.reduce((i,o)=>{const d=s[o.control];if(o.op==="date_range"){if(!d||typeof d=="string")return i;const c=Xt(i,t,o.field);if(!c)return i;const f=Ht(ae(d.start),n,s),h=ae(d.end);return!f&&!h?i:i.filter(v=>{const j=ae(v[c]);return j?!(f&&j<f||h&&j>h):!0})}const u=tn(d,o.valueMap);return u===void 0||u==="__all"?i:i.filter(c=>c[o.field]===u)},e)}const Kt=["date","day","periodStart","month","weekStart","triggerWeek","cohortDate","cohort","cohortWeek","week","report_date"];function ae(e){if(typeof e!="string"||!e)return"";if(/^\d{4}-\d{2}-\d{2}$/.test(e))return e;const t=new Date(e);return Number.isNaN(t.getTime())?"":t.toISOString().slice(0,10)}function Xt(e,t,n){if(n)return n;const s=t.chartSpec.encodings.x;return s?.type==="time"&&s.field?s.field:Kt.find(a=>e.some(r=>ae(r[a])))}function Ht(e,t,n){if(!e)return e;const s=t.filter(i=>i.type==="enum"&&en(i.name)&&i.options.some(o=>o.value==="week"||o.value==="month")).map(i=>n[i.name]).find(i=>i==="week"||i==="month");if(!s)return e;const a=new Date(`${e}T00:00:00.000Z`);if(Number.isNaN(a.getTime()))return e;if(s==="month")return new Date(Date.UTC(a.getUTCFullYear(),a.getUTCMonth(),1)).toISOString().slice(0,10);const r=(a.getUTCDay()+6)%7;return a.setUTCDate(a.getUTCDate()-r),a.toISOString().slice(0,10)}function en(e){return e.replace(/([a-z0-9])([A-Z])/g,"$1_$2").toLowerCase().split(/[^a-z0-9]+/).some(n=>["grain","granularity","timeframe"].includes(n))}function tn(e,t){if(typeof e=="string")return e?t&&Object.prototype.hasOwnProperty.call(t,e)?t[e]:e:"__all"}function nn(e,t){return(e.displaySpec.visibleWhen??[]).every(n=>{const s=t[n.control];if(typeof s!="string"||!s)return!0;const a=n.valueMap?.[s]??s;return n.values?.length?n.values.includes(a):a===n.value})}function an({controls:e,onChange:t,values:n}){const s=g.useCallback((a,r)=>t({...n,[a]:r}),[t,n]);return e.length?l.jsx("div",{"aria-label":"Dashboard filters",className:"dashboard-filter-bar",children:e.map(a=>l.jsxs("div",{className:"dashboard-filter-control",children:[l.jsx("span",{children:a.label}),a.type==="date_range"?l.jsx(sn,{control:a,update:s,value:n[a.name]}):l.jsx("div",{"aria-label":a.label,className:"dashboard-segmented-control",role:"group",children:a.options.map(r=>l.jsx(rn,{active:n[a.name]===r.value,controlName:a.name,disabled:a.disabled,label:r.label,onSelect:s,value:r.value},r.value))}),a.note?l.jsx("small",{children:a.note}):null]},a.name))}):null}function sn({control:e,update:t,value:n}){const s=g.useMemo(()=>typeof n=="object"?n:{},[n]),a=g.useCallback(i=>{t(e.name,{...s,start:i.target.value})},[e.name,s,t]),r=g.useCallback(i=>{t(e.name,{...s,end:i.target.value})},[e.name,s,t]);return l.jsxs("div",{className:"dashboard-date-range-control",children:[l.jsx("input",{"aria-label":`${e.label} start`,disabled:e.disabled,onChange:a,type:"date",value:s.start??""}),l.jsx("span",{children:"to"}),l.jsx("input",{"aria-label":`${e.label} end`,disabled:e.disabled,onChange:r,type:"date",value:s.end??""})]})}function rn({active:e,controlName:t,disabled:n,label:s,onSelect:a,value:r}){const i=g.useCallback(()=>a(t,r),[t,a,r]);return l.jsx("button",{"aria-pressed":e,className:e?"active":void 0,disabled:n,onClick:i,type:"button",children:s})}function on(e){return(e.split(/\r?\n/).map(n=>n.trim()).find(Boolean)??"").replace(/^#{1,6}\s+/,"").replace(/\*\*/g,"").trim()}function ln({columns:e,controls:t,controlValues:n,item:s}){const[a,r]=g.useState([]),[i,o]=g.useState(null),[d,u]=g.useState(!0),{chartVersion:c,tile:f}=s;g.useEffect(()=>{let D=!0;return u(!0),o(null),Gt({id:c.id,querySpec:c.querySpec}).then(b=>{D&&r(b)}).catch(b=>{D&&o(Re(b))}).finally(()=>{D&&u(!1)}),()=>{D=!1}},[c.id,c.querySpec]);const h=g.useMemo(()=>Jt(a,c,t,n),[c,t,n,a]),v=c.validation.errors??[],j=f.titleOverride??c.title,M=c.compiledRendererSpec;if(c.displaySpec.chrome==="control"){const D=M.target==="cos_native"&&M.component==="markdown"&&typeof M.props.markdown=="string"?on(M.props.markdown):j;return l.jsx("div",{className:"dashboard-render-tile dashboard-render-control-tile","data-chart-id":c.chartId,style:$e(f,e),children:l.jsx("div",{className:"dashboard-control-tile","data-chart-id":c.chartId,"data-panel-id":f.tileId,"data-panel-title":j,"data-tile-id":f.tileId,children:d?l.jsxs("div",{className:"dashboard-render-loading dashboard-render-status",children:[l.jsx(H,{"aria-hidden":"true",className:"analytics-spin",size:14}
110),"Loading"]}):i?l.jsxs("div",{className:"dashboard-render-error dashboard-render-status error",role:"alert",children:[l.jsx(T,{"aria-hidden":"true",size:14}),i]}):v.length?l.jsxs("div",{className:"dashboard-render-error dashboard-render-status error",role:"alert",children:[l.jsx(T,{"aria-hidden":"true",size:14}),v.join("; ")]}):l.jsx("span",{className:"dashboard-control-pill",children:D||j})})})}return l.jsx("div",{className:"dashboard-render-tile","data-chart-id":c.chartId,"data-panel-id":f.tileId,"data-panel-title":j,"data-rendered-row-count":d||i?void 0:h.length,"data-source-row-count":d||i?void 0:a.length,"data-tile-id":f.tileId,style:$e(f,e),children:l.jsx(Pt,{source:c.displaySpec.sourceLabel,subtitle:c.subtitle,title:j,children:d?l.jsxs("div",{className:"dashboard-render-loading dashboard-render-status",children:[l.jsx(H,{"aria-hidden":"true",className:"analytics-spin",size:16}),"Loading chart data"]}):i?l.jsxs("div",{className:"dashboard-render-error dashboard-render-status error",role:"alert",children:[l.jsx(T,{"aria-hidden":"true",size:16}),i]}):v.length?l.jsxs("div",{className:"dashboard-render-error dashboard-render-status error",role:"alert",children:[l.jsx(T,{"aria-hidden":"true",size:16}),v.join("; ")]}):!h.length&&!dn(c.compiledRendererSpec,"markdown")?l.jsx("div",{className:"dashboard-render-empty",children:c.displaySpec.emptyState||"No data for the selected filters and date range."}):l.jsx(cn,{compiled:c.compiledRendererSpec,displaySpec:c.displaySpec,rows:h})})})}function cn({compiled:e,displaySpec:t,rows:n}){return e.target==="vega_lite"?l.jsx(un,{compiled:e,rows:n}):e.component==="table"?l.jsx(fn,{compiled:e,displaySpec:t,rows:n}):e.component==="kpi"?l.jsx(mn,{compiled:e,rows:n}):e.component==="markdown"?l.jsx(bn,{compiled:e}):e.component==="cohort_matrix"?l.jsx(yn,{compiled:e,rows:n}):e.component==="sankey"?l.jsx(vn,{compiled:e,rows:n}):l.jsxs("div",{className:"dashboard-render-status error",role:"alert",children:[l.jsx(T,{"aria-hidden":"true",size:16}),"Unsupported chart renderer"]})}function dn(e,t){return e.target==="cos_native"&&e.component===t}function un({compiled:e,rows:t}){const n=g.useRef(null);return g.useEffect(()=>{const s=n.current;if(!s)return;s.removeAttribute("role"),s.textContent="";let a=!1,r;return Te(async()=>{const{default:i}=await import("./vega-embed.module-C3fE6OkY.js");return{default:i}},__vite__mapDeps([0,1,2,3])).then(({default:i})=>a?null:i(s,{...e.spec,autosize:{contains:"padding",resize:!0,type:"fit"},data:{values:t},width:"container"},{actions:!1,renderer:"svg"})).then(i=>{i&&(r=i.view,a&&r.finalize())}).catch(i=>{a||(s.textContent=Re(i),s.setAttribute("role","alert"))}),()=>{a=!0,r?.finalize()}},[e,t]),l.jsx("div",{"aria-label":"Vega-Lite chart",className:"dashboard-vega-chart",ref:n})}function fn({compiled:e,displaySpec:t,rows:n}){const s=Array.isArray(e.props.columns)?e.props.columns:[],a=pn(s,Object.keys(n[0]??{}).slice(0,8)),r=n.slice(0,hn(t)),i=t.tableDensity==="compact";return l.jsxs(l.Fragment,{children:[l.jsx("div",{className:"dashboard-native-table-wrap dashboard-table-wrap",children:l.jsxs("table",{className:`dashboard-native-table ${i?"compact":""}`,children:[a.some(o=>o.width)?l.jsx("colgroup",{children:a.map(o=>l.jsx("col",{style:o.width?{width:o.width}:void 0},o.field))}):null,l.jsx("thead",{children:l.jsx("tr",{children:a.map(o=>l.jsx("th",{scope:"col",children:o.label},o.field))})}),l.jsx("tbody",{children:r.map((o,d)=>l.jsx("tr",{children:a.map(u=>{const c=U(o[u.field],u.format);return l.jsx("td",{"data-label":u.label,title:c,children:c},u.field)})},`${d}-${a.map(u=>o[u.field]).join("|")}`))})]})}),n.length>r.length?l.jsxs("div",{className:"dashboard-native-table-count",children:["Showing ",r.length.toLocaleString()," of ",n.length.toLocaleString()," ","rows"]}):null]})}function pn(e,t){const n=e.flatMap(s=>{if(typeof s=="string")return[{field:s,label:s}];const a=xn(s);return!a||typeof a.field!="string"?[]:[{field:a.field,format:ie(a.format)?a.format:void 0,label:typeof a.label=="string"&&a.label?a.label:a.field,width:typeof a.width=="string"&&/^\d+(\.\d+)?(px|%)$/.test(a.width)?a.width:void 0}]});return n.length?n:t.map(s=>({field:s,label:s}))}function hn(e){const t=Number(e.tableMaxRows);return Number.isInteger(t)?Math.max(1,Math.min(5e3,t)):40}function mn({compiled:e,rows:t}){const n=e.props.row==="first"?t[0]:t.at(-1),s=e.props.row==="first"?t[1]:t.at(-2),a=typeof e.props.valueField=="str
110ing"?e.props.valueField:"value",r=typeof e.props.comparisonField=="string"?e.props.comparisonField:void 0,i=ie(e.props.format)?e.props.format:void 0,o=e.props.notation==="compact"||e.props.notation==="standard"?e.props.notation:void 0,d=n?.[a],u=r?n?.[r]:s?.[a],c=typeof d=="number"&&typeof u=="number"?d-u:null;return l.jsxs("div",{className:"dashboard-kpi-tile dashboard-native-kpi",children:[l.jsx("span",{children:typeof e.props.label=="string"?e.props.label:a}),l.jsx("strong",{children:U(d,i,{notation:o})}),c==null?null:l.jsxs("small",{className:c>=0?"positive":"negative",children:[c>=0?"+":"",U(c,i,{notation:o})," ",typeof e.props.comparisonLabel=="string"?e.props.comparisonLabel:"vs prior"]})]})}function bn({compiled:e}){const n=(typeof e.props.markdown=="string"?e.props.markdown:"").split(/\r?\n/).map(s=>s.trim()).filter(Boolean);return n.length?l.jsx("div",{className:"dashboard-markdown-tile dashboard-native-markdown",children:n.map((s,a)=>{const r=/^(#{1,3})\s+(.+)$/.exec(s);if(r){const i=r[2];return r[1]?.length===1?l.jsx("h2",{children:i},`${a}-${i}`):r[1]?.length===2?l.jsx("h3",{children:i},`${a}-${i}`):l.jsx("h4",{children:i},`${a}-${i}`)}return l.jsx("p",{children:s.replace(/\*\*/g,"")},`${a}-${s}`)})}):l.jsx("div",{className:"dashboard-markdown-tile dashboard-native-markdown"})}function yn({compiled:e,rows:t}){const n=typeof e.props.xField=="string"?e.props.xField:void 0,s=typeof e.props.yField=="string"?e.props.yField:void 0,a=typeof e.props.valueField=="string"?e.props.valueField:void 0,r=ie(e.props.valueFormat)?e.props.valueFormat:void 0;if(!n||!s||!a)return l.jsxs("div",{className:"dashboard-render-error",role:"alert",children:[l.jsx(T,{"aria-hidden":"true",size:16}),"Matrix spec is missing required fields."]});const i=[...new Set(t.map(c=>c[n]))].sort(je),o=[...new Set(t.map(c=>c[s]))].sort(je),d=new Map(t.map(c=>[`${String(c[s])}::${String(c[n])}`,c])),u=(Array.isArray(e.props.metaFields)?e.props.metaFields:[]).filter(c=>typeof c=="string");return l.jsxs("div",{className:"dashboard-cohort-matrix",style:{"--matrix-value-cols":i.length},children:[l.jsx("div",{className:"dashboard-cohort-matrix-head",children:"Cohort"}),i.map(c=>l.jsx("div",{className:"dashboard-cohort-matrix-head",children:String(c)},`head-${String(c)}`)),o.map(c=>{const f=t.find(h=>h[s]===c)??{};return l.jsxs("div",{className:"dashboard-cohort-matrix-row",children:[l.jsxs("div",{className:"dashboard-cohort-matrix-label",children:[l.jsx("strong",{children:String(c)}),u.map(h=>f[h]==null?null:l.jsx("span",{children:U(f[h],h.toLowerCase().includes("arr")?"currency":"number")},h))]}),i.map(h=>{const v=d.get(`${String(c)}::${String(h)}`)?.[a];return l.jsx("div",{className:`dashboard-cohort-matrix-cell ${gn(v)}`,children:U(v,r)},`${String(c)}-${String(h)}`)})]},`row-${String(c)}`)})]})}function je(e,t){const n=typeof e=="number"?e:Number.NaN,s=typeof t=="number"?t:Number.NaN;if(Number.isFinite(n)&&Number.isFinite(s))return n-s;const a=typeof e=="string"?Date.parse(e):Number.NaN,r=typeof t=="string"?Date.parse(t):Number.NaN;return Number.isFinite(a)&&Number.isFinite(r)?a-r:String(e??"").localeCompare(String(t??""))}function gn(e){return typeof e!="number"||!Number.isFinite(e)?"empty":e>=1?"excellent":e>=.85?"good":e>=.7?"ok":e>=.5?"weak":"bad"}function vn({compiled:e,rows:t}){const n=typeof e.props.sourceField=="string"?e.props.sourceField:void 0,s=typeof e.props.targetField=="string"?e.props.targetField:void 0,a=typeof e.props.valueField=="string"?e.props.valueField:void 0,r=ie(e.props.valueFormat)?e.props.valueFormat:void 0;if(!n||!s||!a)return l.jsxs("div",{className:"dashboard-render-error",role:"alert",children:[l.jsx(T,{"aria-hidden":"true",size:16}),"Flow spec is missing required fields."]});const i=t.flatMap(m=>{const F=m[n]==null?"":String(m[n]),A=m[s]==null?"":String(m[s]),R=typeof m[a]=="number"&&Number.isFinite(m[a])?m[a]:null;return F&&A&&R!=null&&R>0?[{source:F,target:A,value:R}]:[]});if(!i.length)return l.jsx("div",{className:"dashboard-render-empty",children:"No flow rows returned for this chart."});const o=new Set(i.map(m=>m.source)),d=new Set(i.map(m=>m.target)),u=new Map;for(const m of i){const F=u.get(m.source)??{in:0,out:0};F.out+=m.value,u.set(m.source,F);const A=u.get(m.target)??{in:0,out:0};A.in+=m.value,u.set(m.target,A)}
110const c=[...u.keys()],f=[c.filter(m=>o.has(m)&&!d.has(m)),c.filter(m=>o.has(m)&&d.has(m)),c.filter(m=>!o.has(m)&&d.has(m))].map(m=>m.sort((F,A)=>Math.max(u.get(A)?.in??0,u.get(A)?.out??0)-Math.max(u.get(F)?.in??0,u.get(F)?.out??0))),h=960,v=160,j=42,M=[52,h/2-v/2,h-v-52],D=Math.max(...f.map(m=>m.length),1),b=Math.max(260,96+D*72),k=new Map;f.forEach((m,F)=>{const A=m.length>1?Math.min(92,Math.max(58,(b-104-j)/(m.length-1))):0,R=m.length>1?(m.length-1)*A+j:j,P=Math.max(48,(b-R)/2);m.forEach((E,W)=>{k.set(E,{column:F,name:E,total:Math.max(u.get(E)?.in??0,u.get(E)?.out??0),x:M[F]??0,y:P+W*A})})});const _=Math.max(...i.map(m=>m.value),1),q=["#4f5be8","#276b31","#079294","#dc8b06","#7c3aed"];return l.jsx("div",{className:"dashboard-sankey",children:l.jsxs("svg",{"aria-label":"Flow chart",className:"dashboard-native-sankey dashboard-sankey-svg",role:"img",viewBox:`0 0 ${h} ${b}`,children:[l.jsx("g",{className:"dashboard-sankey-links",children:i.map((m,F)=>{const A=k.get(m.source),R=k.get(m.target);if(!A||!R)return null;const P=A.x+v,E=A.y+j/2,W=R.x,N=R.y+j/2,C=(P+W)/2,Y=(E+N)/2,L=Math.max(8,Math.min(46,8+m.value/_*36));return l.jsxs("g",{children:[l.jsx("path",{className:"dashboard-sankey-link",d:`M ${P} ${E} C ${C} ${E}, ${C} ${N}, ${W} ${N}`,stroke:q[F%q.length],strokeWidth:L}),l.jsx("text",{className:"dashboard-sankey-link-label",textAnchor:"middle",x:C,y:Y-Math.max(8,L/3),children:U(m.value,r)})]},`${m.source}-${m.target}-${F}`)})}),l.jsx("g",{className:"dashboard-sankey-nodes",children:[...k.values()].map(m=>l.jsxs("g",{transform:`translate(${m.x} ${m.y})`,children:[l.jsx("rect",{className:`dashboard-sankey-node column-${m.column}`,height:j,rx:"7",width:v}),l.jsx("text",{className:"dashboard-sankey-node-title",x:"12",y:"17",children:m.name}),l.jsx("text",{className:"dashboard-sankey-node-value",x:"12",y:"32",children:U(m.total,r)})]},m.name))})]})})}function U(e,t,n){if(e==null||e==="")return"-";if(t==="date"){const s=String(e),a=/^\d{4}-\d{2}-\d{2}$/.test(s)?new Date(`${s}T00:00:00Z`):new Date(s);return Number.isNaN(a.getTime())?s:new Intl.DateTimeFormat("en-US",{day:"numeric",month:"short",timeZone:"UTC",year:"numeric"}).format(a)}if(typeof e!="number")return String(e);if(t==="currency"){const s=n?.notation??(Math.abs(e)>=1e6?"compact":"standard");return new Intl.NumberFormat("en-US",{currency:"USD",maximumFractionDigits:s==="compact"?1:0,notation:s,style:"currency"}).format(e)}return t==="percent"?new Intl.NumberFormat("en-US",{maximumFractionDigits:1,style:"percent"}).format(e):Math.abs(e)>=1e6?new Intl.NumberFormat("en-US",{maximumFractionDigits:1,notation:"compact"}).format(e):new Intl.NumberFormat("en-US",{maximumFractionDigits:2}).format(e)}function ie(e){return["currency","date","duration","number","percent"].includes(String(e))}function xn(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)?e:null}function Re(e){return e instanceof Error?e.message:"Dashboard data request failed"}function Sn({dashboardId:e,layoutSpec:t,tiles:n}
110){const s=n.filter(({tile:d})=>!d.hidden),a=Qt(t),r=g.useMemo(()=>Yt(t?.controls),[t?.controls]),[i,o]=g.useState(()=>ke(r));return g.useEffect(()=>{o(ke(r))},[r,e]),s.length?l.jsxs(l.Fragment,{children:[l.jsx(an,{controls:r,onChange:o,values:i}),l.jsx("section",{"aria-label":"Dashboard tiles",className:"dashboard-render-grid",style:{gap:a.gap,gridTemplateColumns:`repeat(${a.columns}, minmax(0, 1fr))`},children:s.map(d=>nn(d.chartVersion,i)?l.jsx(ln,{columns:a.columns,controls:r,controlValues:i,item:d},d.tile.tileId):null)})]}):l.jsx("div",{className:"dashboard-render-empty",children:"This dashboard has no visible charts."})}function $n({workspaceId:e}){const[t,n]=g.useState([]),[s,a]=g.useState([]),[r,i]=g.useState(null),[o,d]=g.useState(null),[u,c]=g.useState(null),[f,h]=g.useState(null),[v,j]=g.useState(!0),[M,D]=g.useState(!1),[b,k]=g.useState(0),_=g.useRef(0),q=g.useCallback(async()=>{const N=++_.current;c(null),j(!0);try{const[C,Y]=await Promise.all([zt(e),Bt(e)]),L=(await Promise.all(Y.map(z=>Ut(z.id)))).filter(z=>z!==null);if(_.current!==N)return;n(C),a(L),i(z=>{if(z&&C.some(re=>re.id===z))return z;const Le=_n(window.location.hash);return C.find(re=>re.slug===Le)?.id??Nn(C,L)})}catch(C){_.current===N&&c(_e(C))}finally{_.current===N&&j(!1)}},[e]);g.useEffect(()=>(Se(),n([]),a([]),i(null),d(null),h(null),D(!1),se(q()),()=>{_.current+=1}),[q]),g.useEffect(()=>{if(!r){d(null);return}let N=!0;return d(null),h(null),D(!0),Ot(r).then(C=>{N&&(d(C),C||h("Dashboard version not found"))}).catch(C=>{N&&h(_e(C))}).finally(()=>{N&&D(!1)}),()=>{N=!1}},[r,b]);const m=g.useMemo(()=>Fn(t,s),[t,s]),F=t.find(N=>N.id===r)??null,A=o?.dashboard.id===r?o:null,R=g.useMemo(()=>A?.charts.map(({chartVersion:N,tile:C})=>({chartVersion:N,tile:C}))??[],[A]),P=g.useCallback(N=>{i(N.id),window.history.replaceState(null,"",`#dashboard:${N.slug}`)},[]),E=g.useCallback(()=>se(q()),[q]),W=g.useCallback(()=>{Se(),k(N=>N+1)},[]);return v&&!t.length?l.jsxs("div",{className:"analytics-loading",children:[l.jsx(H,{"aria-hidden":"true",className:"analytics-spin",size:17}),"Loading dashboards"]}):u&&!t.length?l.jsxs("div",{className:"analytics-error",role:"alert",children:[l.jsx(T,{"aria-hidden":"true",size:18}),l.jsx("span",{children:u}),l.jsx("button",{onClick:E,type:"button",children:"Retry"})]}):t.length?l.jsxs("div",{className:"dashboard-catalog",children:[l.jsxs("aside",{"aria-label":"Dashboard catalog",className:"dashboard-catalog-navigation",children:[l.jsxs("div",{className:"dashboard-catalog-navigation-heading",children:[l.jsx("span",{children:"Dashboards"}),l.jsx("span",{children:t.length})]}),m.map(([N,C],Y)=>l.jsxs("div",{className:"dashboard-catalog-group",children:[l.jsx("h2",{children:N}),C.map(L=>l.jsx(kn,{active:L.id===r,dashboard:L,onSelect:P},L.id))]},`${N}:${Y}`))]}),l.jsxs("section",{className:"dashboard-catalog-content",children:[F?l.jsxs("header",{className:"dashboard-heading",children:[l.jsxs("div",{children:[l.jsx("span",{children:Ee(F.folder)}),l.jsx("h1",{children:F.title}),F.description?l.jsx("p",{children:F.description}):null]}),l.jsx("button",{"aria-label":"Reload dashboard",className:"analytics-icon-button",disabled:M,onClick:W,title:"Reload dashboard",type:"button",children:l.jsx(H,{"aria-hidden":"true",className:M?"analytics-spin":void 0,size:16})})]}):null,u||f?l.jsxs("div",{className:"analytics-error compact",role:"alert",children:[l.jsx(T,{"aria-hidden":"true",size:16}),f??u]}):null,M&&!A?l.jsxs("div",{className:"analytics-loading compact",children:[l.jsx(H,{"aria-hidden":"true",className:"analytics-spin",size:16}),"Loading dashboard"]}):null,A?l.jsx(Sn,{dashboardId:A.dashboard.id,layoutSpec:A.currentVersion?.layoutSpec,tiles:R}):null]})]}):l.jsx(jn,{})}function kn({active:e,dashboard:t,onSelect:n}){const s=g.useCallback(()=>n(t),[t,n]);return l.jsxs("button",{"aria-current":e?"page":void 0,className:e?"active":void 0,onClick:s,type:"button",children:[l.jsx(Xe,{"aria-hidden":"true",size:15}),l.jsx("span",{children:t.title})]})}function jn(){return l.jsxs("section",{className:"dashboard-catalog-empty",children:[l.jsx("span",{className:"dashboard-catalog-empty-icon","aria-hidden":"true",children:l.jsx(Fe,{size:24})}),l.jsx("h1",{children:"No dashboards yet"}),l.jsx("p",{children:"Published analytics dashboards will appear here."})]})}function _n(e){return/^#dashboard:([a-z0-9][a-z0-9-]*)$/.exec(e)?.[1]??null}function Nn(e,t){for(const n of t){const s=n.currentVersion?.dashboardRefs.find(a=>a.default);if(s&&e.some(a=>a.id===s.dashboardId))return s.dashboardId}return e[0]?.id??null}function Fn(e,t){const n=new Set,s=t.flatMap(i=>{if(i.section.status!=="active"||i.section.visibility!=="workspace"||!i.currentVersion)return[];const o=new Map(i.currentVersion.dashboardRefs.map(u=>[u.dashboardId,u.order])),d=i.dashboards.filter(u=>e.some(c=>
110c.id===u.id)).sort((u,c)=>(o.get(u.id)??0)-(o.get(c.id)??0));return d.forEach(u=>n.add(u.id)),d.length?[[i.section.title,d]]:[]}),a=e.filter(i=>!n.has(i.id)),r=new Map;for(const i of a){const o=Ee(i.folder);r.set(o,[...r.get(o)??[],i])}return[...s,...r.entries()]}function Ee(e){return e?e.replace(/[-_]/g," ").replace(/\b\w/g,t=>t.toUpperCase()):"Other"}function _e(e){return e instanceof Error?e.message:"Dashboard request failed"}function An({workspaceUrl:e}){const[t,n]=g.useState(null),[s,a]=g.useState(null),[r,i]=g.useState(!0),o=g.useRef(0),d=g.useCallback(async()=>{const c=++o.current;if(n(null),!e){a("Analytics workspace not found"),i(!1);return}a(null),i(!0);try{const f=await lt(e);o.current===c&&n(f)}catch(f){if(o.current!==c)return;n(null),a(Dn(f))}finally{o.current===c&&i(!1)}},[e]),u=g.useCallback(()=>se(d()),[d]);return g.useEffect(()=>(se(d()),()=>{o.current+=1}),[d]),l.jsxs("div",{className:"analytics-platform-root",children:[l.jsxs("header",{className:"analytics-topbar",children:[l.jsxs("div",{className:"analytics-brand",children:[l.jsx("a",{"aria-label":"Back to Lindy",className:"analytics-icon-button",href:e?`/${e}/home`:"/home",title:"Back to Lindy",children:l.jsx(Ye,{"aria-hidden":"true",size:17})}),l.jsx("span",{className:"analytics-brand-mark","aria-hidden":"true",children:l.jsx(Fe,{size:17})}),l.jsx("strong",{children:"Lindy analytics"})]}),t?l.jsxs("div",{className:"analytics-session",title:"Internal administrator",children:[l.jsx(Ae,{"aria-hidden":"true",size:16}),l.jsx("span",{children:t.email})]}):null]}),l.jsx("main",{className:"analytics-main",children:s?l.jsxs("div",{className:"analytics-error",role:"alert",children:[l.jsx("span",{children:s}),l.jsx("button",{onClick:u,type:"button",children:"Retry"})]}):r||!t?l.jsx("div",{className:"analytics-loading",children:"Loading analytics"}):l.jsx($n,{workspaceId:t.workspaceId})})]})}function Dn(e){return e instanceof Error?e.message:"Analytics request failed"}rt({apiOrigin:Ue.apiOrigin,artifactOrigin:void 0});function Gn(){const e=ze(),[t,n]=g.useState("checking");return g.useEffect(()=>{document.title="Analytics | Lindy"},[]),g.useEffect(()=>{let s=!1;async function a(){try{const r=await Pe(We);s||n(r.me.isAdmin?"allowed":"denied")}catch(r){const i=await Ge();if(s)return;if(i===!1){n("logged-out");return}ue(r,{tags:{source:"analytics-admin-access"}}),n("denied")}}return a().catch(r=>{ue(r,{tags:{source:"analytics-admin-access"}}),s||n("denied")}),()=>{s=!0}},[]),g.useEffect(()=>{t==="logged-out"&&Oe(`/login${window.location.search}`,{replace:!0})},[t]),t==="checking"||t==="logged-out"?l.jsx(Be,{}):t==="denied"?l.jsx(Ze,{}):l.jsx(An,{workspaceUrl:e})}export{Gn as View};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.