@evotecit/canopyx 0.1.3 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/CanopyX.Html/Assets/canopyx-calendar-edit.js +113 -0
  2. package/CanopyX.Html/Assets/canopyx-calendar-ics.js +87 -0
  3. package/CanopyX.Html/Assets/canopyx-calendar-recurrence.js +36 -0
  4. package/CanopyX.Html/Assets/canopyx-calendar.css +279 -0
  5. package/CanopyX.Html/Assets/canopyx-calendar.js +307 -0
  6. package/CanopyX.Html/Assets/canopyx-cell-range.css +38 -0
  7. package/CanopyX.Html/Assets/canopyx-cell-range.js +141 -0
  8. package/CanopyX.Html/Assets/canopyx-column-groups.css +18 -0
  9. package/CanopyX.Html/Assets/canopyx-column-groups.js +51 -0
  10. package/CanopyX.Html/Assets/canopyx-data.js +14 -0
  11. package/CanopyX.Html/Assets/canopyx-detail-rows.css +18 -0
  12. package/CanopyX.Html/Assets/canopyx-detail-rows.js +51 -0
  13. package/CanopyX.Html/Assets/canopyx-editing.css +44 -0
  14. package/CanopyX.Html/Assets/canopyx-editing.js +134 -0
  15. package/CanopyX.Html/Assets/canopyx-enhance.js +126 -0
  16. package/CanopyX.Html/Assets/canopyx-export.js +18 -0
  17. package/CanopyX.Html/Assets/canopyx-facets.css +86 -0
  18. package/CanopyX.Html/Assets/canopyx-facets.js +65 -0
  19. package/CanopyX.Html/Assets/canopyx-filter-editor.css +15 -18
  20. package/CanopyX.Html/Assets/canopyx-filter-editor.js +23 -17
  21. package/CanopyX.Html/Assets/canopyx-format-editor.css +77 -0
  22. package/CanopyX.Html/Assets/canopyx-format-editor.js +30 -0
  23. package/CanopyX.Html/Assets/canopyx-formatting.css +40 -0
  24. package/CanopyX.Html/Assets/canopyx-formatting.js +101 -0
  25. package/CanopyX.Html/Assets/canopyx-grid-module.mjs +352 -246
  26. package/CanopyX.Html/Assets/canopyx-grid.css +139 -117
  27. package/CanopyX.Html/Assets/canopyx-grid.js +352 -246
  28. package/CanopyX.Html/Assets/canopyx-grouping.css +39 -0
  29. package/CanopyX.Html/Assets/canopyx-grouping.js +85 -0
  30. package/CanopyX.Html/Assets/canopyx-highlight.css +34 -0
  31. package/CanopyX.Html/Assets/canopyx-highlight.js +80 -0
  32. package/CanopyX.Html/Assets/canopyx-history.js +13 -0
  33. package/CanopyX.Html/Assets/canopyx-interactive.css +18 -6
  34. package/CanopyX.Html/Assets/canopyx-interactive.js +179 -100
  35. package/CanopyX.Html/Assets/canopyx-labels-de.js +304 -0
  36. package/CanopyX.Html/Assets/canopyx-labels-es.js +304 -0
  37. package/CanopyX.Html/Assets/canopyx-labels-fr.js +529 -0
  38. package/CanopyX.Html/Assets/canopyx-labels-it.js +529 -0
  39. package/CanopyX.Html/Assets/canopyx-labels-pl.js +304 -0
  40. package/CanopyX.Html/Assets/canopyx-layouts.css +48 -0
  41. package/CanopyX.Html/Assets/canopyx-layouts.js +39 -0
  42. package/CanopyX.Html/Assets/canopyx-link.css +19 -0
  43. package/CanopyX.Html/Assets/canopyx-link.js +38 -0
  44. package/CanopyX.Html/Assets/canopyx-links.js +14 -0
  45. package/CanopyX.Html/Assets/canopyx-live.css +24 -0
  46. package/CanopyX.Html/Assets/canopyx-live.js +88 -0
  47. package/CanopyX.Html/Assets/canopyx-module.mjs +180 -100
  48. package/CanopyX.Html/Assets/canopyx-pager.css +10 -0
  49. package/CanopyX.Html/Assets/canopyx-pager.js +14 -0
  50. package/CanopyX.Html/Assets/canopyx-record-panel.css +111 -0
  51. package/CanopyX.Html/Assets/canopyx-record-panel.js +178 -0
  52. package/CanopyX.Html/Assets/canopyx-reporting-module.mjs +406 -342
  53. package/CanopyX.Html/Assets/canopyx-reporting.css +140 -135
  54. package/CanopyX.Html/Assets/canopyx-reporting.js +406 -342
  55. package/CanopyX.Html/Assets/canopyx-search.js +32 -0
  56. package/CanopyX.Html/Assets/canopyx-timeline.css +80 -0
  57. package/CanopyX.Html/Assets/canopyx-timeline.js +88 -0
  58. package/CanopyX.Html/Assets/canopyx-tree-tools.css +103 -0
  59. package/CanopyX.Html/Assets/canopyx-tree-tools.js +92 -0
  60. package/CanopyX.Html/Assets/canopyx.css +17 -5
  61. package/CanopyX.Html/Assets/canopyx.js +175 -96
  62. package/JavaScript/calendar.d.ts +362 -0
  63. package/JavaScript/cell-ranges.d.ts +76 -0
  64. package/JavaScript/column-groups.d.ts +32 -0
  65. package/JavaScript/editing.d.ts +257 -0
  66. package/JavaScript/enhance.d.ts +202 -0
  67. package/JavaScript/facets.d.ts +58 -0
  68. package/JavaScript/formatting.d.ts +88 -0
  69. package/JavaScript/grid.d.ts +409 -56
  70. package/JavaScript/hosts.d.ts +177 -2
  71. package/JavaScript/index.d.ts +53 -4
  72. package/JavaScript/live.d.ts +115 -0
  73. package/JavaScript/locales/de.mjs +304 -0
  74. package/JavaScript/locales/es.mjs +304 -0
  75. package/JavaScript/locales/fr.d.ts +6 -0
  76. package/JavaScript/locales/fr.mjs +527 -0
  77. package/JavaScript/locales/it.d.ts +6 -0
  78. package/JavaScript/locales/it.mjs +527 -0
  79. package/JavaScript/locales/pl.mjs +304 -0
  80. package/JavaScript/plugins.d.ts +113 -0
  81. package/JavaScript/protocol.d.ts +139 -6
  82. package/JavaScript/records.d.ts +136 -0
  83. package/README.md +61 -9
  84. package/README.nuget.md +1 -1
  85. package/package.json +99 -3
@@ -0,0 +1,39 @@
1
+ /* ---------- row grouping: the group-by bar,headings and the totals row ---------- */
2
+ .cx-groupbar{flex:none;display:flex;align-items:center;flex-wrap:wrap;gap:var(--cx-size-8px);padding:var(--cx-size-6px) var(--cx-size-12px);border-bottom:var(--cx-size-1px) solid var(--cx-line);background:var(--cx-group-bg);font-size:var(--cx-size-13px);color:var(--cx-muted);min-height:var(--cx-size-38px);}
3
+ .cx-gchip{display:inline-flex;align-items:center;gap:var(--cx-size-6px);height:var(--cx-size-26px);padding:0 var(--cx-size-6px);border:var(--cx-size-1px) solid var(--cx-line-strong);border-radius:var(--cx-radius);background:var(--cx-surface);color:var(--cx-text);}
4
+ .cx-data-grid .cx-gchip .cx-button{width:var(--cx-size-18px);min-height:var(--cx-size-18px);height:var(--cx-size-18px);padding:0;}
5
+ .cx-data-grid .cx-grid-group{background:var(--cx-group-bg);font-weight:700;}
6
+ .cx-grid-group-toggle{flex:0 0 auto;padding:0;margin-right:var(--cx-size-6px);border:0;background:transparent;color:inherit;font:inherit;cursor:pointer;}
7
+ .cx-grid-group-toggle:focus-visible{outline:var(--cx-size-2px) solid var(--cx-accent);outline-offset:var(--cx-size-neg-2px);}
8
+ .cx-data-grid .cx-grid-group .cx-cell:first-child{overflow:visible;z-index:3;}
9
+ .cx-grid-group-label{flex:none;display:flex;align-items:center;min-width:0;overflow:hidden;white-space:nowrap;}
10
+ .cx-grid-group-text{flex:0 0 auto;max-width:100%;overflow:hidden;text-overflow:ellipsis;}
11
+ .cx-grid-group-count{flex:none;margin-left:var(--cx-size-8px);color:var(--cx-muted);font-size:var(--cx-size-12px);font-weight:400;}
12
+ .cx-data-grid .cx-grid-group .cx-cell{background:var(--cx-group-bg);}
13
+ .cx-data-grid .cx-grid-summary{position:sticky;bottom:0;z-index:4;background:var(--cx-head-bg);border-top:var(--cx-size-1px) solid var(--cx-line-strong);font:inherit;}
14
+ .cx-summary-row{display:flex;height:var(--cx-head-h);font-weight:700;}
15
+ .cx-data-grid .cx-summary-row .cx-cell[data-cx-pin]{background:var(--cx-head-bg);}
16
+ .cx-summary-row .cx-summary-caption{font-size:var(--cx-size-11d5px);letter-spacing:var(--cx-size-d04em);text-transform:uppercase;color:var(--cx-muted);}
17
+ .cx-groupbar-label{flex:none;}
18
+ .cx-groupbar-hint{font-style:italic;}
19
+ .cx-groupbar-spacer{flex:1 1 auto;}
20
+ .cx-groupbar.cx-group-drop{outline:var(--cx-size-2px) dashed var(--cx-accent);outline-offset:var(--cx-size-neg-2px);}
21
+ .cx-data-grid .cx-groupbar .cx-groupbar-all{min-height:var(--cx-size-26px);height:var(--cx-size-26px);padding:0 var(--cx-size-8px);font-size:var(--cx-size-12px);}
22
+ .cx-gchip-name{cursor:grab;touch-action:none;white-space:nowrap;}
23
+ .cx-data-grid .cx-gchip .cx-gchip-fold{font-weight:700;line-height:1;}
24
+ .cx-gchip-order{height:var(--cx-size-20px);max-width:var(--cx-size-140px);border:var(--cx-size-1px) solid var(--cx-control-border);border-radius:var(--cx-radius-sm);background:var(--cx-surface);color:var(--cx-text);font:inherit;font-size:var(--cx-size-12px);}
25
+ .cx-gchip:focus-within{border-color:var(--cx-accent);}
26
+ .cx-data-grid .cx-grid-group .cx-cell:first-child{padding-inline-start:calc(var(--cx-cell-px) + var(--cx-group-level,0) * var(--cx-size-16px));}
27
+ .cx-grid-group-column{color:var(--cx-muted);font-weight:400;}
28
+ .cx-grid-group-select{margin-inline-end:var(--cx-size-6px);}
29
+ .cx-aggregate{font-variant-numeric:tabular-nums;}
30
+ .cx-aggregate:not(:first-child){overflow:hidden;text-overflow:clip;}
31
+ .cx-grid-group-aggregates{flex:0 1000 auto;min-width:0;margin-inline-start:var(--cx-size-12px);overflow:hidden;text-overflow:ellipsis;color:var(--cx-muted);font:inherit;font-weight:400;font-variant-numeric:tabular-nums;border:0;background:transparent;padding:0;cursor:pointer;white-space:nowrap;}
32
+ .cx-grid-group-aggregates:focus-visible{outline:var(--cx-size-2px) solid var(--cx-accent);outline-offset:var(--cx-size-neg-2px);}
33
+ .cx-summary-row .cx-grid-group-aggregates{text-transform:none;letter-spacing:normal;font-size:var(--cx-size-13px);}
34
+ .cx-aggregate > .cx-aggregate-button{max-width:100%;margin-inline-start:0;font:inherit;color:inherit;flex:0 1 auto;text-align:left;}
35
+ .cx-phone .cx-groupbar{padding:var(--cx-size-4px) var(--cx-size-8px);gap:var(--cx-size-6px);}
36
+ .cx-phone .cx-gchip{max-width:100%;}
37
+ .cx-phone .cx-gchip-name{min-width:0;overflow:hidden;text-overflow:ellipsis;}
38
+ .cx-phone :is(.cx-groupbar-label,.cx-gchip-order,.cx-gchip-fold){display:none;}
39
+ @media (forced-colors:active){.cx-gchip{border-color:CanvasText;}}
@@ -0,0 +1,85 @@
1
+ (function(global){"use strict";const installed=new WeakSet();const part={version:"d942108ffbc023b6",requires:["detail-rows"],install(context){if(installed.has(context.DataGrid.prototype))return;const{DataGrid,GRID_ROWS,GRID_REPORTING,h,setText,fill,numberFormat,formatValue,cellValue,cellText,isCellObject,gridScalar,gridQuery,gridFreeze,gridOrder,gridQueryRows,gridButton,gridDecorateButton,gridCellRenderer,gridPresenterTone,GRID_TONE_RANK,validateGridRows,validateGridPage,checkDocument,requireIdentifier,validStructuralCount,PROTOCOL,gridOperationActive,reportingGroupKey,reportingGroupCompare,reportingSummaryEnabled,reportingDynamicGroups,GROUP_OPERATIONS,reportingAggregateParts,disposeRowHostCells,quietControls,TreeGrid}=context;const groupCounting=operation=>operation==="count"||operation==="distinctCount";function groupCustomAggregates(grid){const found=new Map();for(const plugin of grid.plugins)for(const[name,entry]of Object.entries(plugin.aggregates||{})){const definition=typeof entry==="function"?{compute:entry}:entry;if(!/^[a-z][a-zA-Z\d]{0,31}$/.test(name) || GROUP_OPERATIONS.includes(name) || !definition || typeof definition.compute !== "function" ||
2
+ definition.label!==undefined&&(typeof definition.label!=="string"||!definition.label.includes("{value}")||definition.label.length>64))
3
+ throw new Error("CanopyX: plugin '"+plugin.name+"' registers an invalid aggregate '"+name+"'.");found.set(name,definition)}
4
+ return found}
5
+ function groupAggregateValue(grid,aggregate,rows,first,last){const column=grid.view.columns.find(item=>item.id===aggregate.column),operation=aggregate.operation;if(!GROUP_OPERATIONS.includes(operation)){const values=[];for(let i=first;i<last;i++){const value=gridScalar(rows[i].cells[column.id],column);if(value!==null)values.push(value)}
6
+ const value=grid.groupAggregates.get(operation).compute(Object.freeze(values),Object.freeze({column:column.id,aggregate:aggregate.id}));if(value!==null&&(typeof value!=="number"||!Number.isFinite(value)||Math.abs(value)>Number.MAX_SAFE_INTEGER))
7
+ throw new Error("CanopyX: custom aggregate '"+operation+"' returned a value that is not a finite number or null.");return value}
8
+ let count=0,sum=0,correction=0,minimum=Infinity,maximum=-Infinity;const distinct=operation==="distinctCount"?new Set():null;for(let i=first;i<last;i++){const value=gridScalar(rows[i].cells[column.id],column);if(value===null)continue;count++;if(distinct)distinct.add(reportingGroupKey(value));else if(operation!=="count"){const next=value-correction,total=sum+next;correction=total-sum-next;sum=total;minimum=Math.min(minimum,value);maximum=Math.max(maximum,value)}}
9
+ return operation==="count"?count:distinct?distinct.size:!count?null:
10
+ operation==="sum"?sum:operation==="average"?sum / count : operation === "minimum" ? minimum : maximum;
11
+ }
12
+ function groupAggregateValues(grid,rows,first=0,last=rows.length){const values=Object.create(null);for(const aggregate of grid.view.reporting.aggregates||[])values[aggregate.id]=groupAggregateValue(grid,aggregate,rows,first,last);return values}
13
+ function groupCheckValues(view,values,count){const declarations=view.reporting.aggregates||[];if(!values||typeof values!=="object"||Array.isArray(values)||Object.keys(values).length!==declarations.length)
14
+ throw new Error("CanopyX: summary aggregate bindings differ.");for(const aggregate of declarations){const value=values[aggregate.id];if(!Object.hasOwn(values,aggregate.id)||value!==null&&(typeof value!=="number"||!Number.isFinite(value)||Math.abs(value)>Number.MAX_SAFE_INTEGER)||
15
+ groupCounting(aggregate.operation)&&(!validStructuralCount(value)||value>count)||
16
+ !count&&!groupCounting(aggregate.operation)&&value!==null)throw new Error("CanopyX: invalid aggregate value.")}}
17
+ const GROUP_MEASURE=DataGrid.prototype.measureGridColumn;Object.assign(DataGrid.prototype,{measureGridColumn(column){const result=GROUP_MEASURE.call(this,column),summary=this.summaryCandidate?.result||this.summary;const aggregates=this.rowsAttached&&summary&&!column.fixed&&(this.view.reporting.aggregates||[]).filter(item=>item.column===column.id);if(!aggregates?.length||!this.fitContext)return result;const context=this.fitContext,pad=this.fitFont[3];let widest=0,seen=0;context.font=this.fitFont[0].replace(/^\S+/, "700");
18
+ const measure=values=>{widest=Math.max(widest,context.measureText(reportingAggregateParts(this,column,aggregates,values).text).width)};measure(summary.aggregates);const walk=list=>{for(const group of list||[]){if(++seen>200)return;measure(group.aggregates);walk(group.groups)}};walk(summary.groups);const need=Math.min(Math.max(420,result.width),Math.ceil(widest+2*pad+4));return need>result.width?Object.freeze({...result,width:need}):result},paintAggregates(cell,column,aggregates,values){const parts=reportingAggregateParts(this,column,aggregates,values);cell.title=parts.title;cell.classList.add("cx-aggregate");if(parts.text)cell.setAttribute("aria-label",parts.title);else cell.removeAttribute("aria-label");if(!parts.text){cell.replaceChildren();return}
19
+ let button=cell.querySelector(":scope > .cx-aggregate-button");if(!button){button=h("button","cx-grid-group-aggregates cx-aggregate-button");button.type="button";button.setAttribute("aria-haspopup","dialog");cell.replaceChildren(button);button.addEventListener("click",event=>{event.stopPropagation();this.showReportingText(column,button._cxAggregateText,button)})}
20
+ if(button.textContent!==parts.text)setText(button,parts.text);button._cxAggregateText=parts.title;button.title=parts.title;button.setAttribute("aria-label",parts.title)}});function groupLevelsOf(view,query){const grouping=view.reporting?.grouping;return grouping?[{column:grouping.column,direction:grouping.direction}]:query?.groupBy||[]}
21
+ function groupOrder(view,level){const column=view.columns.find(item=>item.id===level.column),compare=reportingGroupCompare(GRID_REPORTING.compare(view));const byValue=(a,b,direction)=>compare({cells:{[column.id]:a.value}},{cells:{[column.id]:b.value}},column,direction);if(!level.aggregate)return(a,b)=>byValue(a,b,level.direction);return(a,b)=>{const x=a.aggregates[level.aggregate],y=b.aggregates[level.aggregate];if(x===null||y===null)return x===y?byValue(a,b,"asc"):x===null?1:-1;return(level.direction==="desc"?gridOrder(y,x):gridOrder(x,y))||byValue(a,b,"asc")}}
22
+ function groupSummaryResult(grid,query,page,summary){const view=grid.view;checkDocument(summary,"gridSummary");if(JSON.stringify(summary).length>4194304||summary.view!==view.id||summary.revision!==page.revision||summary.matched!==page.matched||
23
+ !Array.isArray(summary.groups)||!summary.query||
24
+ !["protocol","type","view","offset","limit","sort","filters","search","revision"].every(key=>Object.hasOwn(summary.query,key))||
25
+ summary.query.type!=="gridQuery"||summary.query.protocol!==PROTOCOL||summary.query.revision!==page.revision||summary.query.offset!==0||
26
+ JSON.stringify(gridQuery(view,summary.query))!==JSON.stringify(query))throw new Error("CanopyX: summary ownership or counts differ.");groupCheckValues(view,summary.aggregates,summary.matched);const levels=groupLevelsOf(view,query),keys=new Set();if(!levels.length&&summary.groups.length)throw new Error("CanopyX: an ungrouped summary has no groups.");const check=(groups,depth,start,count)=>{const level=levels[depth],column=view.columns.find(item=>item.id===level.column),order=groupOrder(view,level),values=new Set();let offset=start,previous=null;for(const group of groups){if(!group||typeof group!=="object"||!Object.hasOwn(group,"value")||
27
+ group.value!==null&&typeof group.value==="object")throw new Error("CanopyX: groups carry raw values.");requireIdentifier(group.key,"group key");const value=reportingGroupKey(gridScalar(group.value,column));if(group.cells!==undefined)validateGridRows([{id:group.key,cells:group.cells}],view.columns);if(keys.size>=10000||group.key.length>4096||keys.has(group.key)||values.has(value)||group.offset!==offset||
28
+ !validStructuralCount(group.count)||!group.count)throw new Error("CanopyX: invalid complete group range.");groupCheckValues(view,group.aggregates,group.count);if(previous&&order(previous,group)>=0)throw new Error("CanopyX: groups do not follow their level's order.");keys.add(group.key);values.add(value);previous=group;if(depth+1<levels.length){if(!Array.isArray(group.groups)||!group.groups.length)throw new Error("CanopyX: a group of an outer level lists its inner groups.");check(group.groups,depth+1,group.offset,group.count)}else if(group.groups!==undefined)throw new Error("CanopyX: a group of the innermost level has no inner groups.");offset +=group.count}
29
+ if(offset!==start+count)throw new Error("CanopyX: groups omit matching records.")};if(levels.length)check(summary.groups,0,0,summary.matched);return gridFreeze(JSON.parse(JSON.stringify(summary)))}
30
+ function groupPath(summary,ordinal){const path=[];for(let list=summary.groups;list?.length;){let low=0,high=list.length;while(low<high){const middle=(low+high)>>>1;if(list[middle].offset<=ordinal)low=middle+1;else high=middle}
31
+ const group=low?list[low-1]:null;if(!group||ordinal>=group.offset+group.count)break;path.push(group);list=group.groups}
32
+ return path}
33
+ const GROUP_GRIDS=new WeakMap();GRID_ROWS.order=(view,query)=>{const grid=GROUP_GRIDS.get(view),columns=new Map(view.columns.map(column=>[column.id,column])),levels=query.groupBy;const compare=GRID_REPORTING.compare(view),rest=query.sort.filter(sort=>!levels.some(level=>level.column===sort.column));const within=(a,b)=>{for(const sort of rest){const result=compare(a,b,columns.get(sort.column),sort.direction);if(result)return result}return gridOrder(a.id,b.id)};const arrange=(rows,depth)=>{if(depth===levels.length)return rows.sort(within);const level=levels[depth],column=columns.get(level.column),buckets=new Map();for(const row of rows){const key=reportingGroupKey(gridScalar(row.cells[column.id],column));if(!buckets.has(key))buckets.set(key,[]);buckets.get(key).push(row)}
34
+ const groups=[...buckets.values()].map(list=>({list,value:cellValue(list[0].cells[column.id])??null,aggregates:level.aggregate?{[level.aggregate]:groupAggregateValue(grid,view.reporting.aggregates.find(item=>item.id===level.aggregate),list,0,list.length)}:{}}));groups.sort(groupOrder(view,level));return groups.flatMap(group=>arrange(group.list,depth+1))};return arrange(gridQueryRows(view,query,columns,null),0)};function groupInnerKey(parent,key){const text=parent+"\u001f"+key;if(text.length<=4096)return text;let a=0x811c9dc5,b=0x01000193;for(let i=0;i<text.length;i++){const code=text.charCodeAt(i);a=Math.imul(a^code,16777619);b=Math.imul(b^code,2246822519)^(b>>>13)}
35
+ return "#" +(a>>>0).toString(36)+(b>>>0).toString(36)+ ":"+text.length}
36
+ function groupInlineSummary(grid,query){const view=grid.view,columns=new Map(view.columns.map(column=>[column.id,column])),levels=groupLevelsOf(view,query);const rows=query.groupBy?.length?GRID_ROWS.order(view,query):gridQueryRows(view,query,columns,GRID_REPORTING.compare(view));let total=0;const build=(start,end,depth,parent)=>{const column=columns.get(levels[depth].column),groups=[];for(let offset=start;offset<end;){const value=cellValue(rows[offset].cells[column.id])??null,key=reportingGroupKey(gridScalar(value,column));let last=offset+1;while(last<end&&reportingGroupKey(gridScalar(rows[last].cells[column.id],column))===key)last++;const id=parent===null?key:groupInnerKey(parent,key);if(++total>10000||id.length>4096)throw new Error("CanopyX: inline grouping exceeds its metadata bounds.");const group={key:id,value,offset,count:last-offset,aggregates:groupAggregateValues(grid,rows,offset,last),...groupWorstCells(view,rows,offset,last)};if(depth+1<levels.length)group.groups=build(offset,last,depth+1,id);groups.push(group);offset=last}
37
+ return groups};return{protocol:PROTOCOL,type:"gridSummary",view:view.id,revision:query.revision,query,matched:rows.length,groups:levels.length?build(0,rows.length,0,null):[],aggregates:groupAggregateValues(grid,rows)}}
38
+ function groupWorstCells(view,rows,first,last){const cells=Object.create(null);for(const declared of view.columns){const presenter=declared.presenter||view.reporting.presenters?.[declared.id];if(!presenter||!["state","enum"].includes(presenter.kind))continue;let worst=null,rank=-1;for(let index=first;index<last;index++){const cell=rows[index].cells[declared.id],raw=cellValue(cell);if(raw==null)continue;const next=GRID_TONE_RANK[gridPresenterTone(presenter,raw,isCellObject(cell)?cell.tone:null)]??2;if(next>rank){worst=cell;rank=next}}
39
+ if(worst!==null)cells[declared.id]=worst}
40
+ return Object.keys(cells).length?{cells}:{}}
41
+ const GROUP_ATTACH=DataGrid.prototype.attachRows;const groupSummaryQuery=(view,query,revision)=>gridQuery(view,{...query,offset:0,limit:view.pageSize,revision});const groupNeedsSummary=(view,query)=>!!view.reporting?.grouping||!!query.groupBy?.length||!!view.reporting?.aggregates?.length;GRID_ROWS.requestPage=async function(query,signal){const page=await GRID_ROWS.base.requestPage.call(this,query,signal);if(!reportingSummaryEnabled(this.view)||signal!==this.dataLifetime.signal||!groupNeedsSummary(this.view,query))return page;validateGridPage(page,this.view,query);const request=groupSummaryQuery(this.view,query,page.revision),key=JSON.stringify(request);if(this.summaryCandidate?.key!==key){const hook=this.source.summary||(this.view.source.kind==="inline"?request=>groupInlineSummary(this,request):null);if(!hook)throw new Error("CanopyX: hosted summaries need an explicit source summary hook.");const summary=await this.runGridHook(signal=>hook.call(this.source,request,{signal}),signal);gridOperationActive(this,signal);this.summaryCandidate={key,result:groupSummaryResult(this,request,page,summary)}}
42
+ const result=this.summaryCandidate.result,levels=groupLevelsOf(this.view,query);if(result.matched!==page.matched)throw new Error("CanopyX: a page differs from its complete-query summary count.");if(levels.length){const columns=levels.map(level=>this.view.columns.find(column=>column.id===level.column));for(let i=0;i<page.items.length;i++){const path=groupPath(result,page.offset+i);if(path.length!==levels.length||columns.some((column,depth)=>
43
+ reportingGroupKey(gridScalar(page.items[i].cells[column.id],column))!==reportingGroupKey(gridScalar(path[depth].value,column))))
44
+ throw new Error("CanopyX: a page record differs from its complete-query group.")}}
45
+ return page};Object.assign(DataGrid.prototype,{attachRows(){if(this.rowsAttached)return;GROUP_ATTACH.call(this);if(!reportingSummaryEnabled(this.view))return;GROUP_GRIDS.set(this.view,this);this.groupAggregates=groupCustomAggregates(this);for(const aggregate of this.view.reporting.aggregates||[])
46
+ if(!GROUP_OPERATIONS.includes(aggregate.operation)&&this.view.source.kind==="inline"&&!this.groupAggregates.has(aggregate.operation))
47
+ throw new Error("CanopyX: no plugin computes the aggregate '"+aggregate.operation+"' for inline data.");this.collapsedGroups||=new Set();this.groupHeaders=new Map();this.attachGroupControls()},acceptRows(){if(!this.groupHeaders)return;const query=this.acceptedQuery;if(!groupNeedsSummary(this.view,query)){if(this.summary){this.summary=null;this.groupHeaders.clear()}}
48
+ else{const key=JSON.stringify(groupSummaryQuery(this.view,query,this.snapshot.revision));if(this.summaryCandidate?.key===key&&this.summary!==this.summaryCandidate.result){this.summary=this.summaryCandidate.result;this.groupHeaders.clear()}}
49
+ this.groupLevels=this.summary?groupLevelsOf(this.view,query):[];const levelsKey=JSON.stringify(this.groupLevels);if(this.groupLevelsKey!==undefined&&this.groupLevelsKey!==levelsKey&&this.collapsedGroups.size){this.collapsedGroups.clear();this.groupCollapseVersion=(this.groupCollapseVersion||0)+ 1;this.version++}
50
+ this.groupLevelsKey=levelsKey;this.syncGroupAria();this.syncSummaryControls();this.syncGroupBar()},projectionGroups(){return this.groupLevels?.length?this.summary.groups:null},groupHeader(group,level){let header=this.groupHeaders.get(group.key);if(!header){header={_ri:-2-this.groupHeaders.size,hpx:this.rowH,h:{cells:{}},status:"group",group,level};this.groupHeaders.set(group.key,header)}
51
+ return header},revealRecord(row){if(!this.summary||!this.groupLevels?.length)return;const hidden=groupPath(this.summary,row._ri).filter(group=>this.collapsedGroups.has(group.key));if(hidden.length){hidden.forEach(group=>this.collapsedGroups.delete(group.key));hidden.forEach(group=>this.emit("group",{key:group.key,collapsed:false}));this.collapseChanged()}},focusedHeader(projection){const focus=this.focused;if(!this.summary||!this.groupLevels?.length)return;if(focus.group){const header=this.groupHeaders.get(focus.group.key);if(header&&projection.indexOf(header)>=0)this.focused=header;return}
52
+ if(focus._ri<0)return;const group=groupPath(this.summary,focus._ri).find(item=>this.collapsedGroups.has(item.key));const header=group&&this.groupHeaders.get(group.key);if(header&&projection.indexOf(header)>=0)this.focused=header},groupKeys(level){const keys=[],walk=(list,depth)=>{for(const group of list||[]){if(!level||depth===level)keys.push(group.key);walk(group.groups,depth+1)}};if(this.summary)walk(this.summary.groups,1);return keys},setGroupCollapsed(key,collapsed){if(this.destroyed||this.pendingQuery||!this.summary||!this.groupLevels?.length||typeof collapsed!=="boolean"||!this.groupHeaders.has(key)&&!this.groupKeys().includes(key))
53
+ throw new Error("CanopyX: choose an accepted group and a boolean collapse intent.");if(collapsed&&!this.collapsedGroups.has(key)&&this.collapsedGroups.size>=10000)throw new Error("CanopyX: at most 10,000 collapsed group keys are supported.");if(collapsed===this.collapsedGroups.has(key))return;if(collapsed)this.collapsedGroups.add(key);else this.collapsedGroups.delete(key);this.collapseChanged({key,collapsed})},setGroupLevelCollapsed(level,collapsed){if(!Number.isInteger(level)||level<0||level>(this.groupLevels?.length||0)||typeof collapsed!=="boolean"||this.pendingQuery||this.destroyed)
54
+ throw new Error("CanopyX: choose a grouping level (0 for all) and a boolean collapse intent.");const keys=this.groupKeys(level),changed=keys.filter(key=>this.collapsedGroups.has(key)!==collapsed);if(collapsed&&this.collapsedGroups.size+changed.length>10000)throw new Error("CanopyX: at most 10,000 collapsed group keys are supported.");changed.forEach(key=>collapsed?this.collapsedGroups.add(key):this.collapsedGroups.delete(key));if(changed.length)this.collapseChanged({level,collapsed,keys:changed})},expandAllGroups(){return this.setGroupLevelCollapsed(0,false)},collapseAllGroups(){return this.setGroupLevelCollapsed(0,true)},collapseChanged(detail){const ownedFocus=this.canvas.contains(document.activeElement);this.groupCollapseVersion=(this.groupCollapseVersion||0)+ 1;this.version++;this.render();if(ownedFocus&&this.focused)this.rendered.get(this.focused)?.focus({preventScroll:true});if(detail)this.emit("group",detail);this.noteViewPreferenceIntent?.();this.stateChanged()}});const GROUP_ROW_BASE=DataGrid.prototype.fillRow;Object.assign(DataGrid.prototype,{syncGroupAria(){const tree=(this.groupLevels?.length||0)>1;if(tree===!!this.groupTree)return;this.groupTree=tree;this.grid.setAttribute("role",tree?"treegrid":"grid");this.version++},fillRow(element,row){if(!row.group){element.removeAttribute("data-cx-group");element.removeAttribute("data-cx-level");GROUP_ROW_BASE.call(this,element,row);if(this.groupTree)element.setAttribute("aria-level",String(this.groupLevels.length +(row.status==="detail"?2:1)));else element.removeAttribute("aria-level");return}
55
+ const group=row.group,level=row.level,collapsed=this.collapsedGroups.has(group.key),levels=this.groupLevels;const previous=element._kind==="group"&&element._w===row&&element._layout===this.layout?element._cells:null;disposeRowHostCells(element);this.releaseDetailRow(element);this.observeDetail(element,false);const groupColumn=this.columns.find(item=>item.id===levels[level-1].column);if(!previous)element.textContent="";element._w=row;element._kind="group";element._layout=this.layout;element._attrs={};element._cls=null;element.className="cx-row cx-grid-group";element.setAttribute("role","row");element.removeAttribute("data-cx-id");element.removeAttribute("data-cx-status");element.removeAttribute("aria-selected");element.removeAttribute("aria-busy");element.dataset.cxGroup=group.key;element.dataset.cxLevel=String(level);if(this.groupTree){element.setAttribute("aria-level",String(level));element.setAttribute("aria-expanded",String(!collapsed))}
56
+ else{element.removeAttribute("aria-level");element.removeAttribute("aria-expanded")}
57
+ element.style.height=this.rowH+"px";element.style.width=this.rowWidth+"px";element.style.setProperty("--cx-group-level",String(level-1));const priorButton=previous?.[0].cell.querySelector(".cx-grid-group-toggle"),button=priorButton||h("button","cx-grid-group-toggle");if(!priorButton){button.type="button";button.tabIndex=-1}
58
+ if(button.disabled!==!!this.pendingQuery)button.disabled=!!this.pendingQuery;button.setAttribute("aria-expanded",String(!collapsed));button.setAttribute("aria-label",collapsed?this.labels.gridGroupExpand:this.labels.gridGroupCollapse);if(button.textContent!==(collapsed?"▸":"▾"))setText(button,collapsed?"▸":"▾");if(!priorButton)button.addEventListener("click",()=>{if(this.pendingQuery)return;try{this.setFocus(row,false);this.setGroupCollapsed(group.key,!this.collapsedGroups.has(group.key));this.setFocus(this.focused,true)}
59
+ catch(error){this.emit("error",{error})}});const value=group.value===null?this.labels.gridGroupMissing:formatValue(group.value,groupColumn.kind,this.fmt,groupColumn.format),count=numberFormat(this.lang).format(group.count);const label=fill(this.labels.gridGroupHeading,{column:groupColumn.title,value,count}),cells=[];this.cols.forEach((column,index)=>{const cell=previous?.[index].cell||this.cell(element,index,column.width,column.kind);cells.push({cell,content:cell});if(index===0){const priorHeading=cell.querySelector(".cx-grid-group-label"),heading=priorHeading||h("span","cx-grid-group-label");const text=heading.querySelector(".cx-grid-group-text")||h("span","cx-grid-group-text"),badge=heading.querySelector(".cx-grid-group-count")||h("span","cx-grid-group-count");text.replaceChildren();if(levels.length>1){const name=h("span","cx-grid-group-column");setText(name,groupColumn.title);text.append(name,document.createTextNode(" "))}
60
+ text.appendChild(document.createTextNode(value));setText(badge,count);if(!priorHeading)heading.append(text,badge);if(!priorButton)cell.append(button);this.paintGroupSelection(cell,group);if(!priorHeading)cell.append(heading);cell.title=label;this.paintHiddenAggregates(heading,group.aggregates,cell,column.id,label);return}
61
+ const aggregates=(this.view.reporting.aggregates||[]).filter(item=>item.column===column.id);if(aggregates.length)this.paintAggregates(cell,column,aggregates,group.aggregates);else{cell.replaceChildren();if(Object.hasOwn(group.cells||{},column.id)){const options=column.presenter||this.view.reporting.presenters?.[column.id];if(options)gridCellRenderer(this,column,options)({id:group.key,cells:group.cells},cell);else setText(cell,cellText(group.cells[column.id],column,this.fmt))}}});let room=this.cols[0].renderWidth??this.cols[0].width;for(let index=1;index<cells.length&&!cells[index].cell.textContent;index++)room +=this.cols[index].renderWidth??this.cols[index].width;const heading=cells[0].cell.querySelector(".cx-grid-group-label");heading.style.maxWidth=Math.max(40,room-44 -(level-1)*16 -(this.view.reporting.selectionControls&&this.multi?22:0))+ "px";element._cells=cells;quietControls(element);this.paintGridHighlights(element,row)},paintGroupSelection(cell,group){if(!this.view.reporting.selectionControls||!this.multi)return;const previous=cell.querySelector(".cx-grid-group-select"),check=previous||h("input","cx-grid-row-select cx-grid-group-select");if(!previous){check.type="checkbox";check.tabIndex=-1}
62
+ const state=this.groupSelection(group);check.checked=state===true;check.indeterminate=state==="mixed";check.disabled=!!this.pendingQuery;check.setAttribute("aria-label",fill(this.labels.gridSelectGroup,{group:group.value===null?this.labels.gridGroupMissing:String(group.value)}));if(!previous)check.addEventListener("click",event=>{event.preventDefault();event.stopPropagation();this.runReportingSelection(()=>this.selectRange(group.offset,group.offset+group.count-1,{selected:this.groupSelection(group)!==true,additive:true}))});if(!previous)cell.appendChild(check)},groupSelection(group){let selected=0,loaded=0;for(const[ordinal,record]of this.rowCache){if(ordinal<group.offset||ordinal>=group.offset+group.count)continue;loaded++;if(this.reportingRowSelected(record))selected++}
63
+ if(this.querySelection)return selected===loaded?true:selected?"mixed":false;return selected&&selected===group.count?true:selected?"mixed":false},paintHiddenAggregates(target,values,cell=target,headingColumn=null,title=this.labels.gridSummary||this.view.label){const shown=new Set(this.cols.filter(column=>column.id!==headingColumn).map(column=>column.id)),parts=[],details=[];for(const column of this.columns){const aggregates=shown.has(column.id)?[]:(this.view.reporting.aggregates||[]).filter(item=>item.column===column.id);if(aggregates.length){const formatted=reportingAggregateParts(this,column,aggregates,values);if(formatted.text){parts.push(column.title+" "+formatted.text);details.push(column.title+"\n"+formatted.title)}}}
64
+ const previous=target.querySelector(":scope > .cx-hidden-aggregates");if(!parts.length){previous?.remove();return}
65
+ const extra=previous||h("button","cx-grid-group-aggregates cx-hidden-aggregates");if(!previous)extra.type="button";extra.setAttribute("aria-haspopup","dialog");if(extra.textContent!==parts.join(" · "))setText(extra,parts.join(" · "));extra._cxAggregateText={title,text:details.join("\n")};extra.title=details.join("\n");extra.setAttribute("aria-label",details.join(", "));if(!previous){target.appendChild(extra);extra.addEventListener("click",event=>{event.stopPropagation();this.showReportingText({title:extra._cxAggregateText.title},extra._cxAggregateText.text,extra)})}
66
+ cell.title=(cell.title?cell.title+" · ":"")+ parts.join(" · ")},syncSummaryControls(){if(this.statusBar&&this.statusGroupSummary!==this.summary){this.statusGroupSummary=this.summary;this.statusGroups??=h("span");this.statusCount.after(this.statusGroups);this.statusGroups.hidden=!this.summary?.groups.length;if(this.summary)setText(this.statusGroups,fill(this.labels.gridGroupCount,{count:numberFormat(this.lang).format(this.summary.groups.length)}))}
67
+ if(!this.summaryControls)return;this.summaryControls.hidden=!this.summary;if(!this.summary)return;if(this.summaryControls.parentElement!==this.grid)this.grid.appendChild(this.summaryControls);const count=this.rowProjection?this.rowProjection.rowCount():this.rowCount();this.grid.setAttribute("aria-rowcount",String(count+2 +(this.headDepth||0)));const key=[this.summary,count,this.layout,this.rowWidth,this.lang,...this.cols.map(column=>column.renderWidth+":"+column.effectivePin)];if(this.summaryRenderKey?.every((value,index)=>value===key[index]))return;this.summaryRenderKey=key;this.summaryControls.replaceChildren();const row=h("div","cx-summary-row");row.setAttribute("role","row");row.setAttribute("aria-rowindex",String(count+2 +(this.headDepth||0)));row.style.width=this.rowWidth+"px";this.cols.forEach((column,index)=>{const cell=this.newCell(index,column.width,column.kind);cell.setAttribute("role","gridcell");cell.style.width=column.renderWidth+"px";const aggregates=this.view.reporting.aggregates.filter(item=>item.column===column.id);if(aggregates.length)this.paintAggregates(cell,column,aggregates,this.summary.aggregates);else if(index===0){setText(cell,this.labels.gridSummary);cell.classList.add("cx-summary-caption")}
68
+ if(index===0)this.paintHiddenAggregates(cell,this.summary.aggregates);row.appendChild(cell)});this.summaryControls.appendChild(row)}});const GROUP_CONTROL_BASE={};for(const name of["buildHeader","querySortHeader"])GROUP_CONTROL_BASE[name]=DataGrid.prototype[name];Object.assign(DataGrid.prototype,{attachGroupControls(){const reporting=this.view.reporting||{};this.groupingDynamic=reportingDynamicGroups(this.view);if(reporting.grouping||this.groupingDynamic){this.groupBar=h("div","cx-groupbar");this.groupBar.setAttribute("role","group");this.groupBar.setAttribute("aria-label",this.labels.gridGroupedBy);this.groupBar.hidden=this.opts.toolbar===false;this.notice.before(this.groupBar)}
69
+ if(reporting.aggregates?.length){this.summaryControls=h("div","cx-grid-summary");this.summaryControls.setAttribute("role","rowgroup");this.summaryControls.setAttribute("aria-label",this.labels.gridSummary);this.summaryControls.hidden=true}
70
+ if(this.groupingDynamic)document.addEventListener("canopyx:closemenus",event=>{const panel=event.detail?.source;if(panel?.classList?.contains("cx-column-menu"))queueMicrotask(()=>this.groupMenuItems(panel))},{signal:this.lifetime.signal});this.syncGroupBar();this.buildHeader()},buildHeader(){GROUP_CONTROL_BASE.buildHeader.call(this);const column=this.view.reporting?.grouping?.column;const header=column&&this.headCells.find(cell=>cell.getAttribute("data-cx-column")===column),button=header?.querySelector(".cx-sort");if(button){button.disabled=true;button.title=this.labels.gridGroupOrder}},groupLevelsNow(){return this.view.reporting.grouping?[this.view.reporting.grouping]:this.queryForChange().groupBy||[]},querySortHeader(id,event){const levels=this.groupingDynamic&&this.groupLevelsNow();if(!levels||!levels.some(level=>level.column===id))return GROUP_CONTROL_BASE.querySortHeader.call(this,id,event);this.setGroupBy(levels.map(level=>level.column===id?{...level,direction:level.direction==="asc"?"desc":"asc"}:level)).catch(()=>{})},groupMenuItems(panel){const id=this.gridPopover?.columnId,column=this.columns.find(item=>item.id===id),menu=panel.querySelector('[role="menu"]');if(!menu||!column?.sortable||this.gridPopover.panel!==panel)return;const levels=this.groupLevelsNow(),grouped=levels.some(level=>level.column===id);if(!grouped&&!this.view.reporting?.groupable)return;const item=gridButton(grouped?this.labels.gridUngroup:this.labels.gridGroupBy,()=>{this.closeGridPopover(false);this.setGroupBy(grouped?levels.filter(level=>level.column!==id):[...levels,{column:id,direction:"asc"}]).catch(error=>this.emit("error",{error}))});item.classList.add("cx-mi","cx-mi-group");item.setAttribute("role","menuitem");item.tabIndex=-1;item.disabled=!grouped&&levels.length>=4;item.prepend(h("span","ico"));menu.append(h("hr","cx-menu-rule"),item)},groupDrop(column){const levels=this.groupingDynamic&&this.groupLevelsNow();if(!levels||!this.view.reporting?.groupable||!column.sortable||levels.length>=4||levels.some(level=>level.column===column.id))return false;this.setGroupBy([...levels,{column:column.id,direction:"asc"}]).catch(error=>this.emit("error",{error}));return true},syncGroupBar(){const bar=this.groupBar;if(!bar)return;const levels=this.groupLevelsNow(),key=JSON.stringify([levels,this.groupCollapseVersion||0]);if(bar._key===key&&bar._summary===this.summary)return;const active=bar.contains(document.activeElement)?document.activeElement:null,chip=active?.closest(".cx-gchip");const place=this.groupChipFocus||active&&{level:chip?Number(chip.dataset.cxLevel):0,control:[...(chip||bar).querySelectorAll("button,select")].indexOf(active)};this.groupChipFocus=null;bar._key=key;bar._summary=this.summary;bar.replaceChildren();if(place)queueMicrotask(()=>{const scope=place.level?bar.querySelector('.cx-gchip[data-cx-level="'+place.level+'"]'):bar;const controls=[...(scope||bar).querySelectorAll("button,select")];(controls[Math.max(0,Math.min(controls.length-1,place.control))]||bar.querySelector("button,select"))?.focus()});const lead=h("span","cx-groupbar-label");setText(lead,this.labels.gridGroupedBy);bar.appendChild(lead);if(this.view.reporting.grouping){const chip=h("span","cx-gchip");setText(chip,this.columns.find(column=>column.id===levels[0].column).title);if(typeof this.opts.onUngroup==="function"){const remove=gridDecorateButton(gridButton("",()=>this.runGridHook(signal=>this.opts.onUngroup({query:this.getQuery(),signal}),this.dataLifetime.signal)
71
+ .catch(error=>this.emit("error",{error}))),"close",true);remove.setAttribute("aria-label",this.labels.gridRemoveGrouping);chip.appendChild(remove)}
72
+ bar.appendChild(chip);return}
73
+ if(!levels.length){const hint=h("span","cx-groupbar-hint");setText(hint,this.labels.gridGroupDrop);bar.appendChild(hint);return}
74
+ levels.forEach((level,index)=>{if(index){const next=h("span","cx-groupbar-next");next.setAttribute("aria-hidden","true");setText(next,"›");bar.appendChild(next)}
75
+ bar.appendChild(this.groupChip(levels,level,index))});const spacer=h("span","cx-groupbar-spacer");bar.appendChild(spacer);const busy=!this.summary;for(const[label,collapsed]of[[this.labels.gridExpandAll,false],[this.labels.gridCollapseAll,true]]){const button=gridButton(label,()=>{if(!this.pendingQuery)this.setGroupLevelCollapsed(0,collapsed)});button.classList.add("cx-groupbar-all");button.disabled=busy;bar.appendChild(button)}},groupChip(levels,level,index){const column=this.columns.find(item=>item.id===level.column),chip=h("span","cx-gchip"),name=h("span","cx-gchip-name");const change=next=>this.setGroupBy(next).catch(error=>this.emit("error",{error}));chip.dataset.cxLevel=String(index+1);chip.title=this.labels.gridGroupMove;setText(name,column.title);chip.appendChild(name);const descending=level.direction==="desc",direction=gridDecorateButton(gridButton("",()=>
76
+ change(levels.map(item=>item===level?{...item,direction:descending?"asc":"desc"}:item))),descending?"down":"up",true);direction.classList.add("cx-gchip-direction");direction.setAttribute("aria-label",column.title+": " +(descending?this.labels.gridSortAscending:this.labels.gridSortDescending));direction.setAttribute("aria-pressed",String(descending));chip.appendChild(direction);const aggregates=this.view.reporting.aggregates||[];if(aggregates.length){const order=h("select","cx-gchip-order");order.setAttribute("aria-label",column.title+": "+this.labels.gridGroupSortBy);const option=(value,text)=>{const item=h("option");item.value=value;setText(item,text);order.appendChild(item)};option("",this.labels.gridGroupSortValue);aggregates.forEach(item=>option(item.id,fill(this.labels.gridGroupSortAggregate,{aggregate:item.label})));order.value=level.aggregate||"";order.addEventListener("change",()=>change(levels.map(item=>{if(item!==level)return item;const{aggregate,...rest}=item;return order.value?{...rest,aggregate:order.value}:rest})));chip.appendChild(order)}
77
+ const keys=this.groupKeys(index+1),allCollapsed=keys.length>0&&keys.every(key=>this.collapsedGroups.has(key));const fold=gridButton(allCollapsed?"+":"−",()=>{if(!this.pendingQuery)this.setGroupLevelCollapsed(index+1,!allCollapsed)});fold.classList.add("cx-gchip-fold");fold.disabled=!keys.length;fold.setAttribute("aria-label",fill(allCollapsed?this.labels.gridExpandLevel:this.labels.gridCollapseLevel,{level:index+1}));fold.title=fold.getAttribute("aria-label");chip.appendChild(fold);const remove=gridDecorateButton(gridButton("",()=>change(levels.filter(item=>item!==level))),"close",true);remove.setAttribute("aria-label",column.title+": "+this.labels.gridUngroup);chip.appendChild(remove);chip.addEventListener("keydown",event=>{if(!event.altKey||!["ArrowLeft","ArrowRight"].includes(event.key))return;const target=index +(event.key==="ArrowLeft"?-1:1);if(target<0||target>=levels.length)return;event.preventDefault();const next=levels.slice();next.splice(target,0,next.splice(index,1)[0]);this.groupChipFocus={level:target+1,control:[...chip.querySelectorAll("button,select")].indexOf(event.target)};change(next)});name.addEventListener("pointerdown",event=>this.dragGroupChip(event,levels,index,chip));return chip},dragGroupChip(event,levels,index,chip){if(event.button!==0||this.pendingQuery)return;event.preventDefault();const pointer=event.pointerId,startX=event.clientX;let ghost=null,target=index;const chips=[...this.groupBar.querySelectorAll(".cx-gchip")];const move=ev=>{if(ev.pointerId!==pointer||!ghost&&Math.abs(ev.clientX-startX)<5)return;if(!ghost){ghost=h("div","cx-column-drag");ghost.setAttribute("aria-hidden","true");setText(ghost,chip.querySelector(".cx-gchip-name").textContent);document.body.appendChild(ghost)}
78
+ ghost.style.left=ev.clientX+12+"px";ghost.style.top=ev.clientY+12+"px";const before=chips.filter(item=>{const box=item.getBoundingClientRect();return ev.clientX>box.left+box.width / 2; }).length;
79
+ target=before>index?before-1:before};const stop=ev=>{if(ev&&ev.pointerId!==undefined&&ev.pointerId!==pointer)return;this.dragGroupChipEnd?.();const dropped=ghost&&ev?.type==="pointerup";ghost?.remove();if(dropped&&target!==index){const next=levels.slice();next.splice(target,0,next.splice(index,1)[0]);this.setGroupBy(next).catch(error=>this.emit("error",{error}))}};const cancel=ev=>{if(ev.pointerId===pointer){ghost?.remove();ghost=null;stop()}};const drag=new AbortController(),listen={signal:AbortSignal.any([drag.signal,this.lifetime.signal])};global.addEventListener("pointermove",move,listen);global.addEventListener("pointerup",stop,listen);global.addEventListener("pointercancel",cancel,listen);this.lifetime.signal.addEventListener("abort",()=>ghost?.remove(),{once:true,signal:drag.signal});this.dragGroupChipEnd=()=>drag.abort()}});const GROUP_QUERY=DataGrid.prototype.setQuery;Object.assign(DataGrid.prototype,{projectedRowKey(event,row){if(!row.group)return false;const cell=event.target.closest(".cx-cell");if(cell&&event.target===cell&&["Enter"," "].includes(event.key)){if(event.key==="Enter")this.focusCell(row,this.rowCells(cell.parentElement).indexOf(cell),0,true);event.preventDefault();return true}
80
+ if(cell&&(["ArrowLeft","ArrowRight","Home","End","Escape","F2"].includes(event.key)||
81
+ event.target!==cell&&["Enter"," "].includes(event.key)))return TreeGrid.prototype.onCellKey.call(this,event);if(event.key==="F2"){this.focusCell(row,0,0,true);event.preventDefault();return true}
82
+ if(!["ArrowLeft","ArrowRight","Enter"," "].includes(event.key))return false;if(event.target.closest("button,input,select")&&["Enter"," "].includes(event.key))return true;event.preventDefault();if(this.pendingQuery)return true;const collapsed=this.collapsedGroups.has(row.group.key),rows=this.rowProjection;if(event.key==="ArrowRight"&&!collapsed&&this.groupTree){const next=rows.rowItem(rows.indexOf(row)+ 1);if(next)this.focusProjected(next);return true}
83
+ if(event.key==="ArrowLeft"&&collapsed&&this.groupTree&&row.level>1){for(let index=rows.indexOf(row)- 1;index>=0;index--){const outer=rows.rowItem(index);if(outer?.group&&outer.level<row.level){this.setFocus(outer,true);break}}
84
+ return true}
85
+ this.setGroupCollapsed(row.group.key,event.key==="ArrowLeft"?true:event.key==="ArrowRight"?false:!collapsed);this.setFocus(this.focused,true);return true},focusProjected(target){if(target.group||target.status==="detail")this.setFocus(target,true);else this.focusResult(target._ri,true).catch(error=>{if(error.name!=="AbortError")this.emit("error",{error})})},setQuery(input,paging){const pending=GROUP_QUERY.call(this,input,paging);const sync=()=>{if(this.destroyed||!this.rowsAttached)return;for(const control of this.canvas.querySelectorAll(".cx-grid-group-toggle,.cx-grid-group-select,.cx-detail-toggle"))control.disabled=!!this.pendingQuery;this.syncGroupBar()};sync();pending.then(sync,sync);return pending}});const GROUP_REQUEST=GRID_REPORTING.exportRequest;GRID_REPORTING.exportRequest=(grid,options)=>{const extra=GROUP_REQUEST?.(grid,options)||{};if(options.scope!=="filtered"||!grid.summary||!grid.groupLevels?.length)return extra;const levels=grid.groupLevels.map(level=>({...level,title:grid.columns.find(column=>column.id===level.column).title}));const nested=(groups,depth)=>groups.map(group=>{const column=grid.columns.find(item=>item.id===levels[depth].column);return{key:group.key,value:group.value,offset:group.offset,count:group.count,aggregates:group.aggregates,text:group.value===null?grid.labels.gridGroupMissing:formatValue(group.value,column.kind,grid.fmt,column.format),...(group.groups?{groups:nested(group.groups,depth+1)}:{})}});return{...extra,grouping:{levels,aggregates:grid.view.reporting.aggregates||[],totals:grid.summary.aggregates,groups:nested(grid.summary.groups,0)}}};installed.add(context.DataGrid.prototype)}};(global.CanopyXParts||=[]).push(["grouping",part])})(typeof window!=="undefined"?window:globalThis);
@@ -0,0 +1,34 @@
1
+ /* Search hits and filter hits. Hosts restyle them with the tokens --cx-hit-search-bg,--cx-hit-filter-bg,--cx-hit-current-bg,
2
+ * --cx-hit-current-ring and --cx-hit-text;the defaults derive from the tones,so both palettes and host themes follow. */
3
+ mark.cx-hit{color:var(--cx-hit-text,var(--cx-text));background:var(--cx-hit-search-bg,color-mix(in srgb,var(--cx-tone-warning) var(--cx-hit-mix,28%),var(--cx-surface)));border-radius:var(--cx-size-2px);padding:0;box-decoration-break:clone;-webkit-box-decoration-break:clone;}
4
+ mark.cx-hit-filter{background:var(--cx-hit-filter-bg,color-mix(in srgb,var(--cx-tone-info) var(--cx-hit-mix,24%),var(--cx-surface)));box-shadow:inset 0 calc(-1 * var(--cx-size-1px)) 0 color-mix(in srgb,var(--cx-tone-info) 70%,transparent);}
5
+ mark.cx-hit-toned{background:color-mix(in srgb,var(--cx-hit-tone) var(--cx-hit-mix,24%),var(--cx-surface));box-shadow:inset 0 calc(-1 * var(--cx-size-1px)) 0 color-mix(in srgb,var(--cx-hit-tone) 75%,transparent);}
6
+ mark.cx-hit-current{background:var(--cx-hit-current-bg,color-mix(in srgb,var(--cx-tone-warning) calc(var(--cx-hit-mix,28%) + 24%),var(--cx-surface)));outline:var(--cx-size-2px) solid var(--cx-hit-current-ring,var(--cx-accent));outline-offset:0;}
7
+ .cx-host[data-cx-theme="dark"] mark.cx-hit{--cx-hit-mix:36%;}
8
+ .cx-host[data-cx-theme="dark"] mark.cx-hit-current{color:var(--cx-hit-text,var(--cx-surface));background:var(--cx-hit-current-bg,color-mix(in srgb,var(--cx-tone-warning) 88%,var(--cx-text)));}
9
+ @media (prefers-color-scheme:dark){
10
+ .cx-host[data-cx-theme="auto"] mark.cx-hit{--cx-hit-mix:36%;}
11
+ .cx-host[data-cx-theme="auto"] mark.cx-hit-current{color:var(--cx-hit-text,var(--cx-surface));background:var(--cx-hit-current-bg,color-mix(in srgb,var(--cx-tone-warning) 88%,var(--cx-text)));}
12
+ }
13
+ .cx-cell.cx-hit-cell{box-shadow:inset 0 0 0 var(--cx-size-2px) var(--cx-hit-current-ring,var(--cx-accent));}
14
+ .cx-search .cx-matches{display:inline-flex;align-items:center;gap:var(--cx-size-2px);flex:none;margin-left:auto;color:var(--cx-muted);font-size:var(--cx-size-12d5px);font-variant-numeric:tabular-nums;white-space:nowrap;}
15
+ .cx-toolbar > .cx-matches{display:inline-flex;align-items:center;gap:var(--cx-size-2px);color:var(--cx-muted);font-size:var(--cx-size-12d5px);}
16
+ .cx-matches-count{padding:0 var(--cx-size-4px);}
17
+ .cx-matches-step{display:inline-grid;place-items:center;width:var(--cx-size-24px);height:var(--cx-size-24px);padding:0;border:0;border-radius:var(--cx-radius-sm);background:transparent;color:var(--cx-text-2);cursor:pointer;}
18
+ .cx-matches-step:hover:not(:disabled){background:var(--cx-hover-bg);color:var(--cx-text);}
19
+ .cx-matches-step:disabled{opacity:.4;cursor:default;}
20
+ .cx-matches-step:focus-visible{outline:var(--cx-size-2px) solid var(--cx-accent);outline-offset:0;}
21
+ .cx-search.cx-has-matches kbd{display:none;}
22
+ .cx-phone .cx-matches-step{width:var(--cx-size-36px);height:var(--cx-size-36px);}
23
+ .cx-matches-toggle::before{content:"";flex:none;width:var(--cx-size-14px);height:var(--cx-size-14px);border:var(--cx-size-1px) solid var(--cx-control-border);border-radius:var(--cx-radius-sm);background:var(--cx-surface);}
24
+ .cx-matches-toggle.on::before{border-color:var(--cx-accent);background:var(--cx-accent) center/var(--cx-size-10px) no-repeat url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='m2.5 6.5 2.5 2.5 4.5-6' fill='none' stroke='white' stroke-width='2'/%3E%3C/svg%3E");}
25
+ @media (forced-colors:active){
26
+ mark.cx-hit{forced-color-adjust:none;background:Mark !important;color:MarkText !important;}
27
+ mark.cx-hit-filter,mark.cx-hit-toned{background:Canvas !important;color:CanvasText !important;box-shadow:none;text-decoration:underline var(--cx-size-2px) CanvasText;text-underline-offset:var(--cx-size-2px);}
28
+ mark.cx-hit-current{outline:var(--cx-size-2px) solid Highlight !important;}
29
+ .cx-cell.cx-hit-cell{forced-color-adjust:none;box-shadow:inset 0 0 0 var(--cx-size-2px) Highlight;}
30
+ .cx-matches-toggle.on::before{forced-color-adjust:none;background:Highlight;}
31
+ }
32
+ @media print{
33
+ mark.cx-hit{background:transparent;color:inherit;outline:0;box-shadow:none;}
34
+ }
@@ -0,0 +1,80 @@
1
+ (function(global){"use strict";const installed=new WeakSet();const part={version:"f39423961654c1e2",install(context){if(installed.has(context.VIEW_MODES))return;const{VIEW_MODES,TreeGrid,h,setText,fill,numberFormat,foldText,cellText,cellValue,isCellObject,setAttr,toneOf,watchFlyout,densityRowHeight,MAX_PROTOCOL_INTEGER,LAYOUT_DENSITIES,plural,svgIcon}=context;const HL_ASCII=/^[\x00-\x7f]*$/, HL_MARKS = /[\u0300-\u036f]/, HL_SEPARATOR = /[\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]/;
2
+ const HL_BASE=new Map(Object.entries({"\u0142":"l","\u0141":"L","\u0111":"d","\u0110":"D","\u00f8":"o","\u00d8":"O","\u0127":"h","\u0126":"H","\u0167":"t","\u0166":"T","\u0131":"i"}));function hlBase(unit){let base=HL_BASE.get(unit);if(base===undefined){const parts=unit.normalize("NFD");base=parts.length>1&&/^[\u0300-\u036f]+$/.test(parts.slice(1)) ? parts.charAt(0) : unit;
3
+ HL_BASE.set(unit,base)}
4
+ return base}
5
+ function hlFold(text,options){let value=String(text);if(HL_ASCII.test(value))return options.matchCase?value:value.toLowerCase();if(options.ignoreAccents){let out="";for(let i=0;i<value.length;i++){const unit=value.charAt(i);out +=unit.charCodeAt(0)<0xc0?unit:hlBase(unit)}
6
+ value=out}
7
+ return options.matchCase?value:foldText(value)}
8
+ function hlTermText(text,options){return hlFold(options.ignoreAccents?String(text).replace(/[\u0300-\u036f]/g, "") : text, options);
9
+ }
10
+ function hlSearchWords(text,mode){if(!text)return[];if(mode!=="words")return[text];return[...text.matchAll(/"([^"]*)(?:"|$)|([^\s"]+)/g)].map(match => match[1] === undefined ? match[2] : match[1]).filter(Boolean);
11
+ }
12
+ function hlPredicates(group){return group?[...group.filters,...group.groups.flatMap(hlPredicates)]:[]}
13
+ function hlCompile(view){const options=view.highlightOptions,terms=[],wholes=[],grid=view.kind==="grid",seen=new Set();const add=(raw,kind,columns,start,word,tone)=>{const text=hlTermText(raw,options),key=kind+"|" +(columns?[...columns].join(","):"")+ "|" +(start?1:0)+ "|"+text;if(text.trim().length<options.minLength||seen.has(key))return;seen.add(key);terms.push({text,kind,columns,start,word,tone})};if(view.highlightOn&&options.search){if(grid){const query=view.acceptedQuery,scope=view.view.searchColumns?new Set(view.view.searchColumns):null;if(query)for(const word of hlSearchWords(query.search,query.searchMode))add(word,"search",scope,false,false)}else if(view.searchInput){for(const word of view.searchInput.value.split(HL_SEPARATOR))if(word)add(word,"search",null,false,true)}}
14
+ if(view.highlightOn&&options.filters&&grid&&view.acceptedQuery){const query=view.acceptedQuery;for(const predicate of[...query.filters,...hlPredicates(query.filterGroup)]){const column=view.columns.find(item=>item.id===predicate.column),tone=options.filterTones[predicate.column]||null;if(!column)continue;if(predicate.operator==="contains"||predicate.operator==="startsWith")
15
+ add(predicate.values[0],"filter",new Set([column.id]),predicate.operator==="startsWith",false,tone);else if(["eq","in","gt","ge","lt","le"].includes(predicate.operator))wholes.push({predicate,column,tone})}}
16
+ terms.sort((a,b)=>b.text.length-a.text.length||(a.kind===b.kind?0:a.kind==="filter"?-1:1));return{terms,wholes,key:JSON.stringify([terms.map(term=>[term.text,term.kind,term.columns&&[...term.columns],term.start]),wholes.map(whole=>whole.predicate)])}}
17
+ function hlColumnTerms(compiled,column){const terms=compiled.terms.filter(term=>!term.columns||term.columns.has(column.id)),wholes=compiled.wholes.filter(whole=>whole.column.id===column.id);return terms.length||wholes.length?{terms,wholes}:null}
18
+ function hlRanges(folded,terms,out){let at=0;for(;;){let best=null,bestAt=-1;for(const term of terms){let index=term.start?at===0&&folded.startsWith(term.text)?0:-1:folded.indexOf(term.text,at);while(term.word&&index>0&&!HL_SEPARATOR.test(folded.charAt(index-1)))index=folded.indexOf(term.text,index+1);if(index>=0&&(bestAt<0||index<bestAt)){best=term;bestAt=index}}
19
+ if(!best)return out;out.push(bestAt,bestAt+best.text.length,best);at=bestAt+Math.max(1,best.text.length)}}
20
+ function hlCount(text,applicable,options,record){if(!text)return 0;for(const whole of applicable.wholes)if(hlWhole(whole,record))return 1;return applicable.terms.length?hlRanges(hlFold(text,options),applicable.terms,[]).length / 3 : 0;
21
+ }
22
+ function hlWhole(whole,record){try{return!!record?.cells&&VIEW_MODES.gridMatches(record,whole.predicate,whole.column)}catch(_){return false}}
23
+ const HL_SKIP="button,svg,input,select,textarea,script,style,mark,.cx-badge,.cx-hidden-fields,[aria-hidden=true],[contenteditable],[data-cx-no-highlight]";function hlHostDrawn(column){return!!column.render&&column.hostRenderer!==false}
24
+ function hlUnmark(element){const marks=element._cxMarks;if(!marks)return;element._cxMarks=null;for(const entry of marks){if(entry.cell){entry.cell.classList.remove("cx-hit-cell");continue}
25
+ for(const node of entry.added)node.remove();entry.node.data=entry.text}}
26
+ function hlMark(kind,tone,current){const mark=h("mark","cx-hit cx-hit-"+kind +(current?" cx-hit-current":"")+(tone?" cx-hit-toned":""));if(tone)mark.style.setProperty("--cx-hit-tone","var(--cx-tone-"+tone+")");return mark}
27
+ function hlMarkCell(owner,cell,applicable,options,record,current){const nodes=[],walker=document.createTreeWalker(cell,NodeFilter.SHOW_TEXT);for(let node=walker.nextNode();node;node=walker.nextNode()){const skip=node.data.trim()?node.parentElement.closest(HL_SKIP):cell;if(!skip||!cell.contains(skip)&&skip!==cell)nodes.push(node)}
28
+ if(!nodes.length)return 0;const whole=applicable.wholes.find(item=>hlWhole(item,record)),entries=owner._cxMarks||(owner._cxMarks=[]);let count=0;const wrap=(node,ranges)=>{const text=node.data,added=[];let cursor=ranges[0];const after=node.nextSibling,parent=node.parentNode;for(let i=0;i<ranges.length;i +=3){let end=ranges[i+1];while(end<text.length&&HL_MARKS.test(text.charAt(end)))end++;if(ranges[i]>cursor)added.push(document.createTextNode(text.slice(cursor,ranges[i])));const term=ranges[i+2],mark=hlMark(term.kind,term.tone,current===(whole?0:count));mark.appendChild(document.createTextNode(text.slice(ranges[i],end)));added.push(mark);cursor=end;if(!whole)count++}
29
+ if(cursor<text.length)added.push(document.createTextNode(text.slice(cursor)));node.data=text.slice(0,ranges[0]);for(const item of added)parent.insertBefore(item,after);entries.push({node,text,added})};if(whole){const term={kind:"filter",tone:whole.tone};for(const node of nodes)wrap(node,[0,node.data.length,term]);return 1}
30
+ for(const node of nodes){const ranges=hlRanges(hlFold(node.data,options),applicable.terms,[]);if(ranges.length)wrap(node,ranges)}
31
+ return count}
32
+ function hlPaintRow(view,element,row){const state=view.hl;if(!state||!state.active||!element._cells)return;const grid=view.kind==="grid";if(grid?row.status||row.group:element._kind!=="node")return;const record=row.h,cols=grid?view.cols:view.cols.slice(0,1),current=state.current&&state.current.key===record.id?state.current:null;cols.forEach((column,position)=>{const applicable=!hlHostDrawn(column)&&state.columns.get(column.id),slot=element._cells[position];if(!applicable||!slot)return;const target=current&&current.column===column.id?current.n:-1,count=hlMarkCell(element,slot.cell,applicable,view.highlightOptions,record,target);if(target>=0&&count<=target){slot.cell.classList.add("cx-hit-cell");(element._cxMarks||=[]).push({cell:slot.cell})}})}
33
+ function hlPaintDrawer(view,dialog){if(dialog._cxHighlight)return;dialog._cxHighlight=true;const paint=()=>{const state=view.hl,record=dialog._cxRecord;if(!dialog.isConnected||!state||!state.active||!record)return;for(const{column,value}of view.drawerFields(dialog)){const applicable=column&&!hlHostDrawn(column)&&state.columns.get(column.id);if(applicable)hlMarkCell(value,value,applicable,view.highlightOptions,record,-1)}};dialog.addEventListener("cx-drawer-paint",paint);paint()}
34
+ const HL_SLICE_MS=8;const hlYield=()=>new Promise(resolve=>setTimeout(resolve,0));async function hlRecords(view,signal){if(view.kind!=="grid")return{list:view.rows.map(row=>row.status||row.h.detail?null:row.h),complete:true};const query=view.acceptedQuery,matched=view.snapshot?.matched;if(!query)return{list:[],complete:true};if(view.view.source.kind==="inline"&&(!view.opts.source||view.enhanceStore)&&Number.isInteger(matched)){const page=await view.source.query({...query,offset:0,limit:Math.max(1,matched)},{signal});return{list:page.items,complete:true}}
35
+ let length=view.rowCount()||0;for(const index of view.rowCache.keys())length=Math.max(length,index+1);const list=new Array(length).fill(null);for(const[index,row]of view.rowCache)list[index]=row.h;return{list,complete:Number.isInteger(matched)&&view.rowCache.size>=matched}}
36
+ function hlCountedColumns(view){const state=view.hl,cols=view.kind==="grid"?view.columns:(view.cols||[]).slice(0,1);return cols.map(column=>[column,!hlHostDrawn(column)&&state.columns.get(column.id)]).filter(([,applicable])=>applicable)}
37
+ function hlCellText(view,record,column){const cell=view.kind==="grid"?record.cells[column.id]:view.cellOf(record,column,view.columns.indexOf(column));return cellText(cell,column,view.fmt)}
38
+ function hlRowHits(view,record){const hits=[];if(!record)return hits;for(const[column,applicable]of view.hl.counted){const count=hlCount(hlCellText(view,record,column),applicable,view.highlightOptions,record);if(count)hits.push([column,count])}
39
+ return hits}
40
+ function hlRecount(view){const state=view.hl;state.counter?.abort();clearTimeout(state.retopTimer);state.retopTimer=0;const controller=state.counter=new AbortController(),signal=controller.signal;state.counted=hlCountedColumns(view);state.complete=false;return state.counting=(async()=>{if(!state.active||!state.counted.length){Object.assign(state,{counts:new Uint32Array(0),list:[],total:0,complete:true,current:null});hlSync(view);return}
41
+ const{list,complete}=await hlRecords(view,signal);if(signal.aborted)return;const counts=new Uint32Array(list.length);let total=0,started=performance.now();for(let i=0;i<list.length;i++){const record=list[i];if(record){let sum=0;for(const[,count]of hlRowHits(view,record))sum +=count;counts[i]=sum;total +=sum}
42
+ if((i&127)===127&&performance.now()- started>HL_SLICE_MS){state.total=total;hlSync(view,true);await hlYield();if(signal.aborted)return;started=performance.now()}}
43
+ Object.assign(state,{counts,list,total,complete});const current=state.current;if(current){const index=list[current.index]?.id===current.key?current.index:list.findIndex(record=>record&&record.id===current.key);state.current=index>=0&&counts[index]>0?{...current,index}:null;if(state.current?.index!==current.index){view.version++;view.scheduleRender()}}
44
+ hlSync(view);clearTimeout(state.announceTimer);state.announceTimer=setTimeout(()=>{const text=!view.destroyed&&state.active&&hlCountText(view);if(text&&text!==state.announced){state.announced=text;hlAnnounce(view,text)}},700);view.emit("matches",{total,current:hlPosition(view),complete})})().catch(error=>{if(error.name!=="AbortError")view.emit("error",{error})})}
45
+ function hlPosition(view){const state=view.hl,current=state.current;if(!current||!state.counts||current.index>=state.counts.length)return 0;let rank=0;for(let i=0;i<current.index;i++)rank +=state.counts[i];for(const[column,count]of hlRowHits(view,state.list[current.index])){if(column.id===current.column)return rank+Math.min(current.n,count-1)+ 1;rank +=count}
46
+ return 0}
47
+ function hlFind(view,direction){const state=view.hl,counts=state.counts,length=counts.length;if(!state.total||!length)return null;const current=state.current;const focusedIndex=view.kind==="grid"?view.focused&&!view.focused.status?view.focused._ri:view.rowAt(view.logicalTop()):Math.max(0,view.indexOf(view.focused));const start=current?current.index:Math.max(0,Math.min(length-1,focusedIndex??0));const inRow=(index,from)=>{const record=state.list[index],flat=[];for(const[column,count]of hlRowHits(view,record))for(let n=0;n<count;n++)flat.push({index,key:record.id,column:column.id,n});if(!flat.length)return null;if(from===undefined)return direction>0?flat[0]:flat[flat.length-1];const at=flat.findIndex(item=>item.column===from.column&&item.n===from.n);return flat[at+direction]||null};if(current){const next=inRow(start,current);if(next)return next}
48
+ else if(counts[start]&&direction>0){const first=inRow(start);if(first)return first}
49
+ for(let step=1;step<=length;step++){const index=(start+direction*step+length*step)%length;if(counts[index])return inRow(index)}
50
+ return null}
51
+ async function hlStep(view,direction,focus){const state=view.hl;if(!state||!state.active)return false;if(state.retopTimer)hlRecount(view);for(let counting=state.counting;!state.complete&&counting;counting=state.counting===counting?null:state.counting)await counting;const next=hlFind(view,direction);if(!next){hlAnnounce(view,view.labels.matchesNone);return false}
52
+ state.current=next;view.version++;const position=hlPosition(view),column=view.columns.find(item=>item.id===next.column);let row;if(view.kind==="grid"){await view.focusResult(next.index,false);row=view.rowItem(next.index)}else{row=view.rows[next.index];view.setFocus(row,false)}
53
+ view.render();const element=row&&view.rendered.get(row),cells=view.rowCells(element),at=view.cols.indexOf(column);if(element&&at>=0){if(focus)view.focusCell(row,at,null);else view.revealInRow(cells[at],cells[at],cells[0])}else if(row&&view.kind==="grid"&&focus){await view.openDetails(row.key)}
54
+ hlSync(view);hlAnnounce(view,fill(view.labels.matchesAnnounce,{current:hlFormat(view,position),count:hlFormat(view,state.total),column:column?column.title:""}));view.emit("matches",{total:state.total,current:position,complete:state.complete});return true}
55
+ function hlFormat(view,value){return numberFormat(view.lang).format(value)}
56
+ function hlAnnounce(view,text){if(view.live){setText(view.live,"");setText(view.live,text)}}
57
+ const HL_ICONS={up:'<path d="m6 15 6-6 6 6"/>',down:'<path d="m6 9 6 6 6-6"/>'};function hlIcon(name){return svgIcon(HL_ICONS[name])}
58
+ function hlButton(className,label,run){const button=h("button",className);button.type="button";button.setAttribute("aria-label",label);button.title=label;button.addEventListener("click",event=>{event.preventDefault();run()});return button}
59
+ function hlRefresh(view){const state=view.hl,compiled=hlCompile(view);state.active=!!view.highlightOn&&(compiled.terms.length>0||compiled.wholes.length>0);if(compiled.key!==state.key){state.current=null;state.announced=null}
60
+ state.key=compiled.key;state.text=view.searchInput?.value;state.columns=new Map();for(const column of view.columns){const applicable=hlColumnTerms(compiled,column);if(applicable)state.columns.set(column.id,applicable)}
61
+ state.colsKey=hlColsKey(view);view.version++;view.scheduleRender();hlRecount(view)}
62
+ function hlColsKey(view){return(view.cols||[]).map(column=>column.id).join("\u0000")}
63
+ function hlCountText(view,counting){const state=view.hl,position=counting?0:hlPosition(view),total=state.total||0;return!total&&!counting?view.labels.matchesNone:position?fill(view.labels.matchesPosition,{current:hlFormat(view,position),count:hlFormat(view,total)}):
64
+ fill(plural(state.complete||counting?view.labels.matchesCount:view.labels.matchesLoaded,total,view.lang),{count:hlFormat(view,total)})}
65
+ function hlSync(view,counting){const state=view.hl,ui=state.ui;if(!ui)return;const shown=state.active;ui.box.hidden=!shown;ui.search?.classList.toggle("cx-has-matches",shown);if(shown){const text=hlCountText(view,counting);if(ui.count.textContent!==text)setText(ui.count,text);ui.previous.disabled=ui.next.disabled=!state.total}
66
+ if(ui.toggle){ui.toggle.setAttribute("aria-pressed",String(!!view.highlightOn));ui.toggle.classList.toggle("on",!!view.highlightOn)}}
67
+ function hlBuild(view){const state=view.hl,search=view.searchInput?.closest(".cx-search");if(view.tools.matches===false)return;const box=h("span","cx-matches"),count=h("span","cx-matches-count");const previous=hlButton("cx-matches-step",view.labels.matchesPrevious,()=>hlRun(view,-1,true));const next=hlButton("cx-matches-step",view.labels.matchesNext,()=>hlRun(view,1,true));previous.setAttribute("aria-keyshortcuts","Shift+F3");next.setAttribute("aria-keyshortcuts","F3");previous.appendChild(hlIcon("up"));next.appendChild(hlIcon("down"));box.append(count,previous,next);box.hidden=true;state.ui={box,count,previous,next,search};if(search)search.insertBefore(box,view.searchInput.nextSibling);else view.toolbar.prepend(box);if(view.overflow){const toggle=state.ui.toggle=h("button","cx-button cx-matches-toggle");toggle.type="button";setText(toggle,view.labels.matchesHighlight);toggle.addEventListener("click",()=>VIEW_MODES.setHighlight(view,!view.highlightOn).catch(error=>view.emit("error",{error})));view.overflow.panel.prepend(toggle)}}
68
+ function hlRun(view,direction,focus){hlStep(view,direction,focus).catch(error=>{if(error.name!=="AbortError")view.emit("error",{error})})}
69
+ VIEW_MODES.highlightStart=view=>{if(view.hl)return;const signal=view.lifetime.signal,state=view.hl={columns:new Map(),counts:new Uint32Array(0),list:[],total:0,complete:true,current:null};signal.addEventListener("abort",()=>{state.counter?.abort();clearTimeout(state.retopTimer);clearTimeout(state.announceTimer);clearTimeout(state.pageTimer)},{once:true});hlBuild(view);const host=view.host,input=view.searchInput,refresh=()=>view.destroyed||hlRefresh(view);if(view.kind==="grid"){state.shape=view.acceptedQuery&&VIEW_MODES.gridResultShape(view.acceptedQuery);host.addEventListener("canopyx:query",()=>{const shape=view.acceptedQuery&&VIEW_MODES.gridResultShape(view.acceptedQuery);if(shape!==state.shape){state.current=null;state.shape=shape}
70
+ refresh()},{signal})}else if(input){let timer=0;input.addEventListener("input",()=>{clearTimeout(timer);timer=setTimeout(refresh,150)},{signal});input.addEventListener("keydown",event=>{if(event.key==="Escape")setTimeout(()=>{if(state.text!==input.value)refresh()})},{signal})}
71
+ input?.addEventListener("keydown",event=>{if(event.key!=="Enter"||event.isComposing||!state.active||event.altKey||event.ctrlKey||event.metaKey)return;if(view.kind==="grid"?view.pendingQuery||view.searchTimer!=null||view.acceptedQuery?.search!==input.value:
72
+ input.getAttribute("aria-expanded")==="true")return;event.preventDefault();event.stopImmediatePropagation();hlRun(view,event.shiftKey?-1:1,false)},{signal,capture:true});host.addEventListener("keydown",event=>{if(event.key!=="F3"||!state.active||event.altKey||event.ctrlKey||event.metaKey)return;event.preventDefault();hlRun(view,event.shiftKey?-1:1,true)},{signal});hlRefresh(view)};VIEW_MODES.setHighlight=(view,enabled)=>{if(!view.hl)VIEW_MODES.highlightStart(view);if(!view.hl.ui)hlBuild(view);if(view.highlightOn!==enabled){view.highlightOn=enabled;hlRefresh(view);view.stateChanged()}
73
+ hlSync(view);return view.hl.counting.then(()=>undefined)};VIEW_MODES.refresh=view=>{if(view.hl)hlRefresh(view)};VIEW_MODES.matches=view=>{const state=view.hl;return Object.freeze(state?{enabled:!!view.highlightOn,total:state.active?state.total:0,current:state.active?hlPosition(view):0,complete:!state.active||state.complete}:
74
+ {enabled:!!view.highlightOn,total:0,current:0,complete:true})};VIEW_MODES.step=(view,direction,focus)=>{if(!view.hl)VIEW_MODES.highlightStart(view);return hlStep(view,direction,focus)};for(const View of[TreeGrid,VIEW_MODES.DataGrid]){if(!View)continue;const paint=View.prototype.fillRow;View.prototype.fillRow=function(element,row){hlUnmark(element);paint.call(this,element,row);if(this.hl)hlPaintRow(this,element,row)}}
75
+ if(VIEW_MODES.DataGrid){const proto=VIEW_MODES.DataGrid.prototype;VIEW_MODES.DataGrid.drawerHook(30,function(dialog){if(this.hl)hlPaintDrawer(this,dialog)});const store=proto.storePage;proto.storePage=function(...args){const result=store.apply(this,args),state=this.hl;if(state&&state.active&&!(this.view.source.kind==="inline"&&(!this.opts.source||this.enhanceStore))){clearTimeout(state.pageTimer);state.pageTimer=setTimeout(()=>this.destroyed||hlRecount(this),150)}
76
+ return result}}
77
+ for(const View of[TreeGrid,VIEW_MODES.DataGrid]){if(!View)continue;const header=View.prototype.buildHeader;View.prototype.buildHeader=function(...args){const result=header.apply(this,args),state=this.hl;if(state&&state.active&&!state.headerQueued&&hlColsKey(this)!==state.colsKey){state.headerQueued=true;queueMicrotask(()=>{state.headerQueued=false;if(!this.destroyed&&hlColsKey(this)!==state.colsKey)hlRefresh(this)})}
78
+ return result}}
79
+ const HL_RETOP=TreeGrid.prototype.retop;TreeGrid.prototype.retop=function(...args){const result=HL_RETOP.apply(this,args),state=this.hl;if(state&&state.active&&state.rowsSeen!==this.rows){state.rowsSeen=this.rows;clearTimeout(state.retopTimer);state.retopTimer=setTimeout(()=>this.destroyed||hlRecount(this),100)}
80
+ return result};installed.add(context.VIEW_MODES)}};(global.CanopyXParts||=[]).push(["highlight",part])})(typeof window!=="undefined"?window:globalThis);
@@ -0,0 +1,13 @@
1
+ (function(global){"use strict";const installed=new WeakSet();const part={version:"7d9901d2fe04df72",install(context){if(installed.has(context.GRID_HISTORY_IMPL))return;const{GRID_HISTORY_IMPL,h,setText,fill,gridSeries,gridPresenterTone,toneColors,toneOf,GRID_TONE_RANK}=context;function gridHistoryTone(point,options){return point.state==null&&point.value==null?"none":gridPresenterTone(options,point.value,point.tone||"success")}
2
+ function gridRenderHistory(grid,column,options,cell,element,text){const series=gridSeries(cell),width=Math.max(2,(column.renderWidth||column.width)-24);if(!series.length){const missing=h("span","p-missing");setText(missing,"—");element.appendChild(missing);return}
3
+ const title=point=>point.period+": "+(point.state??(point.value==null?grid.labels.gridNoData:String(point.value)));if(options.kind==="statusStrip"){const strip=h("span","p-strip");strip.setAttribute("role","img");strip.setAttribute("aria-label",column.title+": "+text);const capacity=Math.max(1,Math.floor((width+1)/3)),bucketSize=Math.max(1,Math.ceil(series.length/capacity)),buckets=[];
4
+ for(let start=0;start<series.length;start+=bucketSize){const points=series.slice(start,start+bucketSize);let worst=points[0];for(const point of points)if((GRID_TONE_RANK[gridHistoryTone(point,options)]??2)>(GRID_TONE_RANK[gridHistoryTone(worst,options)]??2))worst=point;buckets.push({points,worst})}
5
+ const segment=Math.max(2,Math.min(6,(width-buckets.length+1)/buckets.length));
6
+ for(const{points,worst}of buckets){const tone=gridHistoryTone(worst,options),item=h("i",tone);item.style.width=segment+"px";item.title=points.length===1?title(worst):fill(grid.labels.gridPeriodRange,{from:points[0].period,to:points[points.length-1].period,state:worst.state??(worst.value==null?grid.labels.gridNoData:String(worst.value))});item.setAttribute("data-cx-periods",String(points.length));item.setAttribute("aria-hidden","true");toneColors(item,toneOf(tone));strip.appendChild(item)}
7
+ element.appendChild(strip);return}
8
+ const values=series.filter(point=>typeof point.value==="number");if(!values.length){setText(element,"—");element.classList.add("p-missing");return}
9
+ const minimum=options.minimum??Math.min(0,...values.map(point=>point.value)),maximum=options.scaleMaximum??Math.max(...values.map(point=>point.value));const fraction=value=>Math.max(0,Math.min(1,(value-minimum)/(maximum-minimum||1)));
10
+ const worse=(point,previousPoint)=>{const rank=GRID_TONE_RANK[gridHistoryTone(point,options)]??2,previous=GRID_TONE_RANK[gridHistoryTone(previousPoint,options)]??2;return rank>previous||rank===previous&&(options.higherIsGood?point.value<previousPoint.value:point.value>previousPoint.value)};let marked=values[values.length-1];if(options.mark!=="last")for(const point of values)if(worse(point,marked))marked=point;if(options.kind==="sparklineBars"){const box=h("span","p-spark"),size=Math.max(1,Math.ceil(values.length/Math.max(1,Math.floor(width/6))));
11
+ box.setAttribute("role","img");box.setAttribute("aria-label",column.title+": "+text);for(let start=0;start<values.length;start+=size){const points=values.slice(start,start+size);let point=points[0];for(const sample of points)if(worse(sample,point))point=sample;const item=h("i",gridHistoryTone(point,options));item.style.height=Math.max(2,fraction(point.value)*20)+"px";item.title=points.length===1?title(point):fill(grid.labels.gridPeriodRange,{from:points[0].period,to:points[points.length-1].period,state:point.state??String(point.value)});if(points.includes(marked))item.classList.add("cx-history-mark");toneColors(item,toneOf(gridHistoryTone(point,options)));box.appendChild(item)}element.appendChild(box)}else{const ns="http://www.w3.org/2000/svg",svg=document.createElementNS(ns,"svg"),line=document.createElementNS(ns,"polyline"),mark=document.createElementNS(ns,"circle");svg.classList.add("p-line");svg.setAttribute("width","96");svg.setAttribute("height","22");svg.setAttribute("viewBox","0 0 96 22");svg.setAttribute("role","img");svg.setAttribute("aria-label",column.title+": "+text);const xy=(point,index)=>[values.length===1?48:1+index/(values.length-1)*94,20-fraction(point.value)*18];
12
+ line.setAttribute("points",values.map((point,index)=>xy(point,index).join(",")).join(" "));const[x,y]=xy(marked,values.indexOf(marked));mark.setAttribute("cx",String(x));mark.setAttribute("cy",String(y));mark.setAttribute("r","2.2");mark.classList.add(gridHistoryTone(marked,options));const tooltip=document.createElementNS(ns,"title");setText(tooltip,title(marked));mark.appendChild(tooltip);svg.append(line,mark);element.appendChild(svg)}}
13
+ GRID_HISTORY_IMPL.render=gridRenderHistory;installed.add(context.GRID_HISTORY_IMPL)}};(global.CanopyXParts||=[]).push(["history",part])})(typeof window!=="undefined"?window:globalThis);
@@ -157,6 +157,10 @@ font-size:var(--cx-font-size,var(--cx-size-14px));
157
157
  line-height:1.4;
158
158
  }
159
159
  .cx-host *,.cx-host *::before,.cx-host *::after{box-sizing:border-box;}
160
+ .cx-host .cx-button.cx-filter-chip{display:inline-flex;align-items:center;justify-content:flex-start;gap:var(--cx-size-6px);min-width:0;}
161
+ .cx-filter-chip > .cx-chip-label{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
162
+ .cx-filter-chip > .cx-chip-remove{flex:none;}
163
+ @media print{.cx-filter-chip > .cx-chip-label{white-space:normal;overflow:visible;text-overflow:clip;}}
160
164
  @media not (forced-colors:active){
161
165
  :where(.cx-host,.cx-host *){scrollbar-color:var(--cx-scrollbar-thumb) var(--cx-scrollbar-track);scrollbar-width:thin;}
162
166
  .cx-host::-webkit-scrollbar,.cx-host ::-webkit-scrollbar{width:var(--cx-scrollbar-size);height:var(--cx-scrollbar-size);}
@@ -217,7 +221,7 @@ flex:none;position:relative;display:flex;align-items:center;padding:0 var(--cx-s
217
221
  font-weight:600;font-size:var(--cx-size-d92em);color:var(--cx-text);border-right:var(--cx-size-1px) solid var(--cx-row-line);user-select:none;
218
222
  }
219
223
  .cx-hcell.cx-kind-number{justify-content:flex-end;}
220
- .cx-sort{font:inherit;color:inherit;background:none;border:0;padding:0;cursor:pointer;display:inline-flex;gap:var(--cx-size-4px);align-items:center;}
224
+ .cx-sort{font:inherit;color:inherit;background:none;border:0;padding:0;cursor:pointer;display:inline-flex;gap:var(--cx-size-4px);align-items:center;min-height:var(--cx-size-24px);min-width:var(--cx-size-24px);}
221
225
  .cx-hcell[aria-sort="ascending"] .cx-sort::after{content:"\25B2";font-size:var(--cx-size-9px);}
222
226
  .cx-hcell[aria-sort="descending"] .cx-sort::after{content:"\25BC";font-size:var(--cx-size-9px);}
223
227
  .cx-resize{padding:0;border:0;background:transparent;position:absolute;right:var(--cx-size-neg-3px);top:0;bottom:0;width:var(--cx-size-7px);cursor:col-resize;z-index:1;}
@@ -247,12 +251,14 @@ white-space:nowrap;text-overflow:ellipsis;
247
251
  .cx-content{display:inline-flex;align-items:center;gap:var(--cx-size-6px);min-width:0;max-width:100%;}
248
252
  .cx-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
249
253
  .cx-indent{flex:none;display:inline-block;}
254
+ .cx-ico{width:var(--cx-size-16px);height:var(--cx-size-16px);flex:none;stroke:currentColor;fill:none;stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round;}
250
255
  .cx-icon{flex:none;display:inline-flex;width:var(--cx-size-16px);height:var(--cx-size-16px);margin-right:var(--cx-size-4px);color:var(--cx-muted);}
251
256
  .cx-icon svg{width:var(--cx-size-16px);height:var(--cx-size-16px);}
252
257
  .cx-exp{
253
258
  flex:none;width:var(--cx-size-18px);height:var(--cx-size-18px);display:inline-flex;align-items:center;justify-content:center;
254
- cursor:pointer;color:var(--cx-muted);border-radius:var(--cx-size-4px);
259
+ cursor:pointer;color:var(--cx-muted);border-radius:var(--cx-size-4px);position:relative;
255
260
  }
261
+ .cx-exp:not(.cx-leaf)::after{content:"";position:absolute;inset:var(--cx-size-neg-3px);}
256
262
  .cx-exp::before{content:"";width:var(--cx-size-7px);height:var(--cx-size-7px);border-right:var(--cx-size-1d6px) solid currentColor;border-bottom:var(--cx-size-1d6px) solid currentColor;transform:rotate(-45deg);transition:transform .12s ease;}
257
263
  .cx-row[aria-expanded="true"] > .cx-tree .cx-exp::before{transform:rotate(45deg);}
258
264
  .cx-exp.cx-leaf{cursor:default;}
@@ -261,8 +267,7 @@ cursor:pointer;color:var(--cx-muted);border-radius:var(--cx-size-4px);
261
267
  .cx-row[aria-busy="true"] .cx-exp::before{width:var(--cx-size-10px);height:var(--cx-size-10px);transform:none;border:var(--cx-size-1d6px) solid var(--cx-line-strong);border-top-color:var(--cx-accent);border-radius:50%;animation:cx-spin .8s linear infinite;}
262
268
  @keyframes cx-spin{to{transform:rotate(360deg);}}
263
269
  @media (prefers-reduced-motion:reduce){
264
- .cx-exp::before{transition:none;}
265
- .cx-row[aria-busy="true"] .cx-exp::before{animation:none;}
270
+ .cx-host,.cx-host *,.cx-host ::before,.cx-host ::after{transition:none!important;animation:none!important;scroll-behavior:auto!important;}
266
271
  }
267
272
  .cx-group .cx-text{font-weight:600;}
268
273
  .cx-row.cx-status .cx-cell{color:var(--cx-muted);font-style:italic;}
@@ -315,15 +320,22 @@ color-scheme:light;height:auto !important;color:var(--cx-text);background:var(--
315
320
  }
316
321
  .cx-outline-table{color:var(--cx-text);background:var(--cx-surface);}
317
322
  .cx-grid,.cx-toolbar{display:none !important;}
323
+ .cx-host:has(> .cx-outline:empty) > .cx-grid{display:block !important;}
318
324
  .cx-outline{display:block;}
319
325
  }
320
326
  body.cx-page{margin:0;font-family:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;}
321
327
  body.cx-page > .cx-host,body.cx-page > .cx-main > .cx-host{height:var(--cx-size-100vh);padding:var(--cx-size-12px) var(--cx-size-16px);}
322
328
  .cx-resize:focus{outline:var(--cx-size-2px) solid var(--cx-accent);outline-offset:var(--cx-size-neg-2px);}
323
329
  @media (forced-colors:active){
324
- .cx-row[aria-selected="true"],.cx-result[aria-selected="true"]{border:var(--cx-size-1px) solid Highlight;}
330
+ :is(.cx-row,.cx-result)[aria-selected="true"]{forced-color-adjust:none;background:Highlight;color:HighlightText;border:var(--cx-size-1px) solid Highlight;}
331
+ :is(.cx-row,.cx-result)[aria-selected="true"] :not(input,select){forced-color-adjust:none;color:HighlightText!important;background-color:transparent!important;border-color:HighlightText!important;outline-color:HighlightText!important;}
332
+ :is(.cx-row,.cx-result)[aria-selected="true"] .cx-cell{background-color:Highlight!important;}
333
+ :is(.cx-row,.cx-result)[aria-selected="true"]:focus-visible{outline-color:HighlightText;}
334
+ :where(.cx-host) :is([role^="menuitem"],[role="option"],.cx-result,summary,button):focus-visible{outline:var(--cx-size-2px) solid;outline-offset:var(--cx-size-neg-2px);}
335
+ :where(.cx-host) [aria-pressed="true"]{forced-color-adjust:none;background:Highlight;color:HighlightText;}
336
+ .cx-badge{outline:var(--cx-size-1px) solid;outline-offset:calc(-1 * var(--cx-size-1px));}
325
337
  }
326
- .cx-check{flex:none;margin:0;width:var(--cx-size-16px);height:var(--cx-size-16px);accent-color:var(--cx-accent);}
338
+ .cx-check{flex:none;margin:0 0 0 var(--cx-size-6px);width:var(--cx-size-16px);height:var(--cx-size-16px);accent-color:var(--cx-accent);}
327
339
  .cx-check:focus-visible{outline:var(--cx-size-2px) solid var(--cx-accent);outline-offset:var(--cx-size-1px);}
328
340
  .cx-interaction-panel{position:fixed;z-index:20;box-sizing:border-box;width:min(var(--cx-size-340px),calc(var(--cx-size-100vw) - var(--cx-size-16px)));max-height:calc(var(--cx-size-100vh) - var(--cx-size-16px));overflow:auto;padding:var(--cx-size-12px);border:var(--cx-size-1px) solid var(--cx-line-strong);border-radius:var(--cx-size-10px);background:var(--cx-surface);color:var(--cx-text);box-shadow:var(--cx-panel-shadow);font:inherit;}
329
341
  .cx-interaction-panel button,.cx-editor{box-sizing:border-box;font:inherit;color:inherit;background:var(--cx-surface);border:var(--cx-size-1px) solid var(--cx-line-strong);border-radius:var(--cx-size-6px);min-height:var(--cx-size-34px);padding:var(--cx-size-6px) var(--cx-size-12px);}