adminizer 5.0.0-build.17 → 5.0.0-build.19

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 (121) hide show
  1. package/assets/abnfDiagram-VCTEODGH-C-KIr2DN.js +1 -0
  2. package/assets/{add-Cuxi35EK.js → add-Cw1LAxU4.js} +1 -1
  3. package/assets/add-group-BSMcCHSS.js +1 -0
  4. package/assets/add-user-0s1Oup1c.js +1 -0
  5. package/assets/ai-assistant/agent.es.js +9755 -8807
  6. package/assets/app-C5Ju5Zra.css +1 -0
  7. package/assets/app.js +19 -19
  8. package/assets/arc-Y0AFXkRV.js +1 -0
  9. package/assets/architectureDiagram-5GKGNRK7-BKVPNJ5l.js +36 -0
  10. package/assets/blockDiagram-NRAW4CY4-Cn2TfbEE.js +129 -0
  11. package/assets/c4Diagram-UCG6FXSJ-Db2qVS-6.js +38 -0
  12. package/assets/{catalog-A2JXLOqL.js → catalog-DGwfMVbZ.js} +4 -4
  13. package/assets/channel-CjXvI1iX.js +1 -0
  14. package/assets/chunk-2Q5K7J3B-Yd__2Q3B.js +1 -0
  15. package/assets/chunk-5VM5RSS4-DptthO82.js +15 -0
  16. package/assets/chunk-F27PBJKO-GHo2S8ga.js +1 -0
  17. package/assets/chunk-G27WJ6UU-Djg33RPp.js +231 -0
  18. package/assets/chunk-JWPE2WC7-CN26K2IW.js +1 -0
  19. package/assets/chunk-LCL6LL3I-6ABTDJvW.js +206 -0
  20. package/assets/chunk-POPQ4Y6H-CHVvrXnT.js +1 -0
  21. package/assets/chunk-SVP7TREG-C70LenRO.js +88 -0
  22. package/assets/chunk-XXDRQBXY-BWbsqWDN.js +1 -0
  23. package/assets/classDiagram-DTDB5LWJ-LxM5LYIS.js +1 -0
  24. package/assets/classDiagram-v2-JRS7N3AN-LxM5LYIS.js +1 -0
  25. package/assets/controls/ckeditor.es.js +7760 -7713
  26. package/assets/controls/handsontable.es.js +12387 -12359
  27. package/assets/cose-bilkent-JH36ORCC-BTYDzW0i.js +1 -0
  28. package/assets/cynefin-OW5HDTMX-BcP1RtCt.js +166 -0
  29. package/assets/cynefinDiagram-5FMLGOSQ-1KlNYFFa.js +62 -0
  30. package/assets/cytoscape.esm-yzknjiTM.js +321 -0
  31. package/assets/dagre-3AP2YEHR-D6OnShGz.js +4 -0
  32. package/assets/{dashboard-Dv9lzLtL.js → dashboard-BPA4kih_.js} +2 -2
  33. package/assets/debounce-B3mXI_sx.js +1 -0
  34. package/assets/defaultLocale-DX6XiGOO.js +1 -0
  35. package/assets/diagram-S7CK7UJ4-BQTIhEaz.js +30 -0
  36. package/assets/diagram-UQ7AKVKN-x2-llkN4.js +41 -0
  37. package/assets/diagram-VSXAHHWV-BIysqsIL.js +3 -0
  38. package/assets/diagram-VX7I27RA-D3wDuqSr.js +24 -0
  39. package/assets/diagram-Z3DM3KII-P23Ug9pv.js +24 -0
  40. package/assets/docs-BFuHg50m.js +1 -0
  41. package/assets/ebnfDiagram-PWID7BFC-cgbvQOxX.js +1 -0
  42. package/assets/erDiagram-SSCWMZ5O-Byu9EM1S.js +99 -0
  43. package/assets/flowDiagram-A5DVABFB-DaV_--G8.js +168 -0
  44. package/assets/ganttDiagram-EL5Y4UJY-BAnersoj.js +292 -0
  45. package/assets/gitGraphDiagram-WWUBYQGX-Dty4aBvB.js +106 -0
  46. package/assets/history-CIuxVr-3.js +1 -0
  47. package/assets/infoDiagram-RXCK75RN-DL8VhKx7.js +2 -0
  48. package/assets/init-Gi6I4Gst.js +1 -0
  49. package/assets/{init-user-QihBlzjm.js → init-user-CKH8B9ne.js} +1 -1
  50. package/assets/isObject-DL-BuaBl.js +1 -0
  51. package/assets/ishikawaDiagram-5VMMS53U-DObXGw8C.js +70 -0
  52. package/assets/journeyDiagram-EYS64GPL-DjVuA0D8.js +139 -0
  53. package/assets/kanban-definition-3QL26DDD-VyA40sQA.js +89 -0
  54. package/assets/katex-HP8lGamR.js +257 -0
  55. package/assets/layout-C-EtKOo-.js +1 -0
  56. package/assets/linear-TgDYAu68.js +1 -0
  57. package/assets/{list-BmoLVCUE.js → list-CStHPfyD.js} +1 -1
  58. package/assets/login-D2aEZ95h.js +1 -0
  59. package/assets/manifest.json +808 -41
  60. package/assets/{media-manager-CNfKCE87.js → media-manager-yRYZOBhn.js} +2 -2
  61. package/assets/mermaid.core-yOa8aWPy.js +310 -0
  62. package/assets/mindmap-definition-FBJOCRG2-B49srtiV.js +96 -0
  63. package/assets/{module-NlKWOaeV.js → module-B1uxT7Et.js} +1 -1
  64. package/assets/notification-B6vRx2jq.js +20 -0
  65. package/assets/ordinal-Cboi1Yqb.js +1 -0
  66. package/assets/pegDiagram-XKGWAZYB-SPSUI-A-.js +1 -0
  67. package/assets/pieDiagram-E7YTZNPT-KJ-KUUol.js +39 -0
  68. package/assets/quadrantDiagram-AXDQQJYC-DhyCBHP3.js +7 -0
  69. package/assets/railroadDiagram-O6MQD6OU-CMXLZL3u.js +1 -0
  70. package/assets/register-DGVCjjck.js +1 -0
  71. package/assets/requirementDiagram-EFPCY7ZU-CZEaWmSI.js +84 -0
  72. package/assets/{ru-3AOtVW4L.js → ru-B9Ga4xfs.js} +1 -1
  73. package/assets/sankeyDiagram-P5KCCOFB-D2vEFB50.js +40 -0
  74. package/assets/sequenceDiagram-WJ2MYXX4-ATlclNe_.js +162 -0
  75. package/assets/sizeCapture-X5ZJPWSS-CQKwfq1b.js +1 -0
  76. package/assets/stateDiagram-HBIQ2CUA-Bm_4wn5d.js +1 -0
  77. package/assets/stateDiagram-v2-4QOOHH4V-fZNqPlcN.js +1 -0
  78. package/assets/swimlanes-XN3QIQJK-CI_vmLhF.js +1 -0
  79. package/assets/swimlanesDiagram-VK2B7HYN-B901Zx0E.js +8 -0
  80. package/assets/timeline-definition-24CTP7MA-CNVYD5Mk.js +120 -0
  81. package/assets/toNumber-DZb-r9sy.js +1 -0
  82. package/assets/user-filters-list-CPlBORpG.js +1 -0
  83. package/assets/vennDiagram-4TSXK5OY-BxPNhRiA.js +34 -0
  84. package/assets/wardleyDiagram-VM6X3IG4-CcM-LR4x.js +78 -0
  85. package/assets/{welcome-CMq7mAP5.js → welcome-BW9UF5Z-.js} +1 -1
  86. package/assets/with-app-layout-G6B8P--q.js +31 -0
  87. package/assets/xychartDiagram-S5SC5T6Z-DVe2H_xl.js +7 -0
  88. package/controllers/docs/index.d.ts +22 -0
  89. package/controllers/docs/index.js +126 -0
  90. package/index.d.ts +3 -0
  91. package/index.js +3 -0
  92. package/interfaces/adminpanelConfig.d.ts +8 -0
  93. package/lib/Adminizer.d.ts +2 -0
  94. package/lib/Adminizer.js +9 -0
  95. package/lib/docs/AbstractDocumentation.d.ts +100 -0
  96. package/lib/docs/AbstractDocumentation.js +108 -0
  97. package/lib/docs/DocumentationHandler.d.ts +100 -0
  98. package/lib/docs/DocumentationHandler.js +198 -0
  99. package/lib/docs/FileDocumentation.d.ts +47 -0
  100. package/lib/docs/FileDocumentation.js +189 -0
  101. package/lib/docs/docsAgentSkills.d.ts +10 -0
  102. package/lib/docs/docsAgentSkills.js +93 -0
  103. package/lib/ui-i18n/uiTranslationKeys.d.ts +2 -1
  104. package/lib/ui-i18n/uiTranslationKeys.js +42 -1
  105. package/package.json +3 -2
  106. package/policies/permissionResolvers.d.ts +1 -0
  107. package/policies/permissionResolvers.js +3 -0
  108. package/system/Router.js +1 -0
  109. package/system/bindDocs.d.ts +13 -0
  110. package/system/bindDocs.js +77 -0
  111. package/system/bindInertia.js +13 -1
  112. package/assets/add-group-ByLLDf_E.js +0 -1
  113. package/assets/add-user-CkmT3PMT.js +0 -1
  114. package/assets/app-Lpo3bWGf.css +0 -1
  115. package/assets/debounce-BMmXVQ06.js +0 -1
  116. package/assets/history-D7FM_eNr.js +0 -1
  117. package/assets/login-Cenu5F6t.js +0 -1
  118. package/assets/notification-BZe5IRJT.js +0 -20
  119. package/assets/register-C9ZkVhe0.js +0 -1
  120. package/assets/user-filters-list-BtB906Lt.js +0 -1
  121. package/assets/with-app-layout-BNwvJ3R-.js +0 -1
@@ -0,0 +1,7 @@
1
+ import{s as pi,g as mi,o as $t,n as yi,a as bi,b as wi,_ as a,l as Ut,D as Ai,d as Ci,p as Si,y as Dt,i as Ri,A as Gt,B as _i,E as ki,aC as Ti,a9 as Xt}from"./mermaid.core-yOa8aWPy.js";import{i as Di}from"./init-Gi6I4Gst.js";import{o as Pi}from"./ordinal-Cboi1Yqb.js";import{l as Nt}from"./linear-TgDYAu68.js";import"./app.js";import"./isObject-DL-BuaBl.js";import"./defaultLocale-DX6XiGOO.js";function vi(e,t,i){e=+e,t=+t,i=(n=arguments.length)<2?(t=e,e=0,1):n<3?1:+i;for(var s=-1,n=Math.max(0,Math.ceil((t-e)/i))|0,o=new Array(n);++s<n;)o[s]=e+s*i;return o}function St(){var e=Pi().unknown(void 0),t=e.domain,i=e.range,s=0,n=1,o,h,p=!1,u=0,f=0,R=.5;delete e.unknown;function C(){var y=t().length,E=n<s,v=E?n:s,L=E?s:n;o=(L-v)/Math.max(1,y-u+f*2),p&&(o=Math.floor(o)),v+=(L-v-o*(y-u))*R,h=o*(1-u),p&&(v=Math.round(v),h=Math.round(h));var M=vi(y).map(function(b){return v+o*b});return i(E?M.reverse():M)}return e.domain=function(y){return arguments.length?(t(y),C()):t()},e.range=function(y){return arguments.length?([s,n]=y,s=+s,n=+n,C()):[s,n]},e.rangeRound=function(y){return[s,n]=y,s=+s,n=+n,p=!0,C()},e.bandwidth=function(){return h},e.step=function(){return o},e.round=function(y){return arguments.length?(p=!!y,C()):p},e.padding=function(y){return arguments.length?(u=Math.min(1,f=+y),C()):u},e.paddingInner=function(y){return arguments.length?(u=Math.min(1,y),C()):u},e.paddingOuter=function(y){return arguments.length?(f=+y,C()):f},e.align=function(y){return arguments.length?(R=Math.max(0,Math.min(1,y)),C()):R},e.copy=function(){return St(t(),[s,n]).round(p).paddingInner(u).paddingOuter(f).align(R)},Di.apply(C(),arguments)}var Rt=(function(){var e=a(function(W,l,g,d){for(g=g||{},d=W.length;d--;g[W[d]]=l);return g},"o"),t=[1,10,12,14,16,18,19,21,23],i=[2,6],s=[1,3],n=[1,5],o=[1,6],h=[1,7],p=[1,5,10,12,14,16,18,19,21,23,36,37,38],u=[1,25],f=[1,26],R=[1,28],C=[1,29],y=[1,30],E=[1,31],v=[1,32],L=[1,33],M=[1,34],b=[1,35],D=[1,36],c=[1,37],z=[1,43],F=[1,42],X=[1,47],N=[1,50],k=[1,10,12,14,16,18,19,21,23,36,37,38],H=[1,10,12,14,16,18,19,21,23,24,26,28,29,36,37,38],A=[1,10,12,14,16,18,19,21,23,24,26,28,29,36,37,38,42,43,44,45,46,47,48,49,50,51],S=[1,65],O=[26,28],T={trace:a(function(){},"trace"),yy:{},symbols_:{error:2,start:3,eol:4,XYCHART:5,chartConfig:6,document:7,CHART_ORIENTATION:8,statement:9,title:10,text:11,X_AXIS:12,parseXAxis:13,Y_AXIS:14,parseYAxis:15,LINE:16,plotData:17,BAR:18,acc_title:19,acc_title_value:20,acc_descr:21,acc_descr_value:22,acc_descr_multiline_value:23,SQUARE_BRACES_START:24,dataPoints:25,SQUARE_BRACES_END:26,dataPoint:27,COMMA:28,NUMBER_WITH_DECIMAL:29,STR:30,xAxisData:31,bandData:32,ARROW_DELIMITER:33,commaSeparatedTexts:34,yAxisData:35,NEWLINE:36,SEMI:37,EOF:38,alphaNum:39,MD_STR:40,alphaNumToken:41,AMP:42,NUM:43,ALPHA:44,PLUS:45,EQUALS:46,MULT:47,DOT:48,BRKT:49,MINUS:50,UNDERSCORE:51,$accept:0,$end:1},terminals_:{2:"error",5:"XYCHART",8:"CHART_ORIENTATION",10:"title",12:"X_AXIS",14:"Y_AXIS",16:"LINE",18:"BAR",19:"acc_title",20:"acc_title_value",21:"acc_descr",22:"acc_descr_value",23:"acc_descr_multiline_value",24:"SQUARE_BRACES_START",26:"SQUARE_BRACES_END",28:"COMMA",29:"NUMBER_WITH_DECIMAL",30:"STR",33:"ARROW_DELIMITER",36:"NEWLINE",37:"SEMI",38:"EOF",40:"MD_STR",42:"AMP",43:"NUM",44:"ALPHA",45:"PLUS",46:"EQUALS",47:"MULT",48:"DOT",49:"BRKT",50:"MINUS",51:"UNDERSCORE"},productions_:[0,[3,2],[3,3],[3,2],[3,1],[6,1],[7,0],[7,2],[9,2],[9,2],[9,2],[9,2],[9,2],[9,3],[9,2],[9,3],[9,2],[9,2],[9,1],[17,3],[25,3],[25,1],[27,2],[27,1],[13,1],[13,2],[13,1],[31,1],[31,3],[32,3],[34,3],[34,1],[15,1],[15,2],[15,1],[35,3],[4,1],[4,1],[4,1],[11,1],[11,1],[11,1],[39,1],[39,2],[41,1],[41,1],[41,1],[41,1],[41,1],[41,1],[41,1],[41,1],[41,1],[41,1]],performAction:a(function(l,g,d,x,_,r,lt){var m=r.length-1;switch(_){case 5:x.setOrientation(r[m]);break;case 9:x.setDiagramTitle(r[m].text.trim());break;case 12:x.setLineData({text:"",type:"text"},r[m]);break;case 13:x.setLineData(r[m-1],r[m]);break;case 14:x.setBarData({text:"",type:"text"},r[m]);break;case 15:x.setBarData(r[m-1],r[m]);break;case 16:this.$=r[m].trim(),x.setAccTitle(this.$);break;case 17:case 18:this.$=r[m].trim(),x.setAccDescription(this.$);break;case 19:this.$=r[m-1];break;case 20:case 30:this.$=[r[m-2],...r[m]];break;case 21:case 31:this.$=[r[m]];break;case 22:this.$={value:Number(r[m-1]),label:r[m]};break;case 23:this.$={value:Number(r[m]),label:""};break;case 24:x.setXAxisTitle(r[m]);break;case 25:x.setXAxisTitle(r[m-1]);break;case 26:x.setXAxisTitle({type:"text",text:""});break;case 27:x.setXAxisBand(r[m]);break;case 28:x.setXAxisRangeData(Number(r[m-2]),Number(r[m]));break;case 29:this.$=r[m-1];break;case 32:x.setYAxisTitle(r[m]);break;case 33:x.setYAxisTitle(r[m-1]);break;case 34:x.setYAxisTitle({type:"text",text:""});break;case 35:x.setYAxisRangeData(Number(r[m-2]),Number(r[m]));break;case 39:this.$={text:r[m],type:"text"};break;case 40:this.$={text:r[m],type:"text"};break;case 41:this.$={text:r[m],type:"markdown"};break;case 42:this.$=r[m];break;case 43:this.$=r[m-1]+""+r[m];break}},"anonymous"),table:[e(t,i,{3:1,4:2,7:4,5:s,36:n,37:o,38:h}),{1:[3]},e(t,i,{4:2,7:4,3:8,5:s,36:n,37:o,38:h}),e(t,i,{4:2,7:4,6:9,3:10,5:s,8:[1,11],36:n,37:o,38:h}),{1:[2,4],9:12,10:[1,13],12:[1,14],14:[1,15],16:[1,16],18:[1,17],19:[1,18],21:[1,19],23:[1,20]},e(p,[2,36]),e(p,[2,37]),e(p,[2,38]),{1:[2,1]},e(t,i,{4:2,7:4,3:21,5:s,36:n,37:o,38:h}),{1:[2,3]},e(p,[2,5]),e(t,[2,7],{4:22,36:n,37:o,38:h}),{11:23,30:u,39:24,40:f,41:27,42:R,43:C,44:y,45:E,46:v,47:L,48:M,49:b,50:D,51:c},{11:39,13:38,24:z,29:F,30:u,31:40,32:41,39:24,40:f,41:27,42:R,43:C,44:y,45:E,46:v,47:L,48:M,49:b,50:D,51:c},{11:45,15:44,29:X,30:u,35:46,39:24,40:f,41:27,42:R,43:C,44:y,45:E,46:v,47:L,48:M,49:b,50:D,51:c},{11:49,17:48,24:N,30:u,39:24,40:f,41:27,42:R,43:C,44:y,45:E,46:v,47:L,48:M,49:b,50:D,51:c},{11:52,17:51,24:N,30:u,39:24,40:f,41:27,42:R,43:C,44:y,45:E,46:v,47:L,48:M,49:b,50:D,51:c},{20:[1,53]},{22:[1,54]},e(k,[2,18]),{1:[2,2]},e(k,[2,8]),e(k,[2,9]),e(H,[2,39],{41:55,42:R,43:C,44:y,45:E,46:v,47:L,48:M,49:b,50:D,51:c}),e(H,[2,40]),e(H,[2,41]),e(A,[2,42]),e(A,[2,44]),e(A,[2,45]),e(A,[2,46]),e(A,[2,47]),e(A,[2,48]),e(A,[2,49]),e(A,[2,50]),e(A,[2,51]),e(A,[2,52]),e(A,[2,53]),e(k,[2,10]),e(k,[2,24],{32:41,31:56,24:z,29:F}),e(k,[2,26]),e(k,[2,27]),{33:[1,57]},{11:59,30:u,34:58,39:24,40:f,41:27,42:R,43:C,44:y,45:E,46:v,47:L,48:M,49:b,50:D,51:c},e(k,[2,11]),e(k,[2,32],{35:60,29:X}),e(k,[2,34]),{33:[1,61]},e(k,[2,12]),{17:62,24:N},{25:63,27:64,29:S},e(k,[2,14]),{17:66,24:N},e(k,[2,16]),e(k,[2,17]),e(A,[2,43]),e(k,[2,25]),{29:[1,67]},{26:[1,68]},{26:[2,31],28:[1,69]},e(k,[2,33]),{29:[1,70]},e(k,[2,13]),{26:[1,71]},{26:[2,21],28:[1,72]},e(O,[2,23],{30:[1,73]}),e(k,[2,15]),e(k,[2,28]),e(k,[2,29]),{11:59,30:u,34:74,39:24,40:f,41:27,42:R,43:C,44:y,45:E,46:v,47:L,48:M,49:b,50:D,51:c},e(k,[2,35]),e(k,[2,19]),{25:75,27:64,29:S},e(O,[2,22]),{26:[2,30]},{26:[2,20]}],defaultActions:{8:[2,1],10:[2,3],21:[2,2],74:[2,30],75:[2,20]},parseError:a(function(l,g){if(g.recoverable)this.trace(l);else{var d=new Error(l);throw d.hash=g,d}},"parseError"),parse:a(function(l){var g=this,d=[0],x=[],_=[null],r=[],lt=this.table,m="",dt=0,Ot=0,ui=2,Vt=1,di=r.slice.call(arguments,1),P=Object.create(this.lexer),$={yy:{}};for(var bt in this.yy)Object.prototype.hasOwnProperty.call(this.yy,bt)&&($.yy[bt]=this.yy[bt]);P.setInput(l,$.yy),$.yy.lexer=P,$.yy.parser=this,typeof P.yylloc>"u"&&(P.yylloc={});var wt=P.yylloc;r.push(wt);var xi=P.options&&P.options.ranges;typeof $.yy.parseError=="function"?this.parseError=$.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function fi(B){d.length=d.length-2*B,_.length=_.length-B,r.length=r.length-B}a(fi,"popStack");function Ft(){var B;return B=x.pop()||P.lex()||Vt,typeof B!="number"&&(B instanceof Array&&(x=B,B=x.pop()),B=g.symbols_[B]||B),B}a(Ft,"lex");for(var I,U,V,At,j={},xt,Y,Wt,ft;;){if(U=d[d.length-1],this.defaultActions[U]?V=this.defaultActions[U]:((I===null||typeof I>"u")&&(I=Ft()),V=lt[U]&&lt[U][I]),typeof V>"u"||!V.length||!V[0]){var Ct="";ft=[];for(xt in lt[U])this.terminals_[xt]&&xt>ui&&ft.push("'"+this.terminals_[xt]+"'");P.showPosition?Ct="Parse error on line "+(dt+1)+`:
2
+ `+P.showPosition()+`
3
+ Expecting `+ft.join(", ")+", got '"+(this.terminals_[I]||I)+"'":Ct="Parse error on line "+(dt+1)+": Unexpected "+(I==Vt?"end of input":"'"+(this.terminals_[I]||I)+"'"),this.parseError(Ct,{text:P.match,token:this.terminals_[I]||I,line:P.yylineno,loc:wt,expected:ft})}if(V[0]instanceof Array&&V.length>1)throw new Error("Parse Error: multiple actions possible at state: "+U+", token: "+I);switch(V[0]){case 1:d.push(I),_.push(P.yytext),r.push(P.yylloc),d.push(V[1]),I=null,Ot=P.yyleng,m=P.yytext,dt=P.yylineno,wt=P.yylloc;break;case 2:if(Y=this.productions_[V[1]][1],j.$=_[_.length-Y],j._$={first_line:r[r.length-(Y||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(Y||1)].first_column,last_column:r[r.length-1].last_column},xi&&(j._$.range=[r[r.length-(Y||1)].range[0],r[r.length-1].range[1]]),At=this.performAction.apply(j,[m,Ot,dt,$.yy,V[1],_,r].concat(di)),typeof At<"u")return At;Y&&(d=d.slice(0,-1*Y*2),_=_.slice(0,-1*Y),r=r.slice(0,-1*Y)),d.push(this.productions_[V[1]][0]),_.push(j.$),r.push(j._$),Wt=lt[d[d.length-2]][d[d.length-1]],d.push(Wt);break;case 3:return!0}}return!0},"parse")},ht=(function(){var W={EOF:1,parseError:a(function(g,d){if(this.yy.parser)this.yy.parser.parseError(g,d);else throw new Error(g)},"parseError"),setInput:a(function(l,g){return this.yy=g||this.yy||{},this._input=l,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:a(function(){var l=this._input[0];this.yytext+=l,this.yyleng++,this.offset++,this.match+=l,this.matched+=l;var g=l.match(/(?:\r\n?|\n).*/g);return g?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),l},"input"),unput:a(function(l){var g=l.length,d=l.split(/(?:\r\n?|\n)/g);this._input=l+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-g),this.offset-=g;var x=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),d.length-1&&(this.yylineno-=d.length-1);var _=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:d?(d.length===x.length?this.yylloc.first_column:0)+x[x.length-d.length].length-d[0].length:this.yylloc.first_column-g},this.options.ranges&&(this.yylloc.range=[_[0],_[0]+this.yyleng-g]),this.yyleng=this.yytext.length,this},"unput"),more:a(function(){return this._more=!0,this},"more"),reject:a(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).
4
+ `+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:a(function(l){this.unput(this.match.slice(l))},"less"),pastInput:a(function(){var l=this.matched.substr(0,this.matched.length-this.match.length);return(l.length>20?"...":"")+l.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:a(function(){var l=this.match;return l.length<20&&(l+=this._input.substr(0,20-l.length)),(l.substr(0,20)+(l.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:a(function(){var l=this.pastInput(),g=new Array(l.length+1).join("-");return l+this.upcomingInput()+`
5
+ `+g+"^"},"showPosition"),test_match:a(function(l,g){var d,x,_;if(this.options.backtrack_lexer&&(_={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(_.yylloc.range=this.yylloc.range.slice(0))),x=l[0].match(/(?:\r\n?|\n).*/g),x&&(this.yylineno+=x.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:x?x[x.length-1].length-x[x.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+l[0].length},this.yytext+=l[0],this.match+=l[0],this.matches=l,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(l[0].length),this.matched+=l[0],d=this.performAction.call(this,this.yy,this,g,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),d)return d;if(this._backtrack){for(var r in _)this[r]=_[r];return!1}return!1},"test_match"),next:a(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var l,g,d,x;this._more||(this.yytext="",this.match="");for(var _=this._currentRules(),r=0;r<_.length;r++)if(d=this._input.match(this.rules[_[r]]),d&&(!g||d[0].length>g[0].length)){if(g=d,x=r,this.options.backtrack_lexer){if(l=this.test_match(d,_[r]),l!==!1)return l;if(this._backtrack){g=!1;continue}else return!1}else if(!this.options.flex)break}return g?(l=this.test_match(g,_[x]),l!==!1?l:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text.
6
+ `+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:a(function(){var g=this.next();return g||this.lex()},"lex"),begin:a(function(g){this.conditionStack.push(g)},"begin"),popState:a(function(){var g=this.conditionStack.length-1;return g>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:a(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:a(function(g){return g=this.conditionStack.length-1-Math.abs(g||0),g>=0?this.conditionStack[g]:"INITIAL"},"topState"),pushState:a(function(g){this.begin(g)},"pushState"),stateStackSize:a(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:a(function(g,d,x,_){switch(x){case 0:break;case 1:break;case 2:return this.popState(),36;case 3:return this.popState(),36;case 4:return 36;case 5:break;case 6:return 10;case 7:return this.pushState("acc_title"),19;case 8:return this.popState(),"acc_title_value";case 9:return this.pushState("acc_descr"),21;case 10:return this.popState(),"acc_descr_value";case 11:this.pushState("acc_descr_multiline");break;case 12:this.popState();break;case 13:return"acc_descr_multiline_value";case 14:return 5;case 15:return 5;case 16:return 8;case 17:return this.pushState("axis_data"),"X_AXIS";case 18:return this.pushState("axis_data"),"Y_AXIS";case 19:return this.pushState("axis_band_data"),24;case 20:return 33;case 21:return this.pushState("data"),16;case 22:return this.pushState("data"),18;case 23:return this.pushState("data_inner"),24;case 24:return 29;case 25:return this.popState(),26;case 26:this.popState();break;case 27:this.pushState("string");break;case 28:this.popState();break;case 29:return"STR";case 30:return 24;case 31:return 26;case 32:return 44;case 33:return"COLON";case 34:return 45;case 35:return 28;case 36:return 46;case 37:return 47;case 38:return 49;case 39:return 51;case 40:return 48;case 41:return 42;case 42:return 50;case 43:return 43;case 44:break;case 45:return 37;case 46:return 38}},"anonymous"),rules:[/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:(\r?\n))/i,/^(?:(\r?\n))/i,/^(?:[\n\r]+)/i,/^(?:%%[^\n]*)/i,/^(?:title\b)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:\})/i,/^(?:[^\}]*)/i,/^(?:xychart-beta\b)/i,/^(?:xychart\b)/i,/^(?:(?:vertical|horizontal))/i,/^(?:x-axis\b)/i,/^(?:y-axis\b)/i,/^(?:\[)/i,/^(?:-->)/i,/^(?:line\b)/i,/^(?:bar\b)/i,/^(?:\[)/i,/^(?:[+-]?(?:\d+(?:\.\d+)?|\.\d+))/i,/^(?:\])/i,/^(?:(?:`\) \{ this\.pushState\(md_string\); \}\n<md_string>\(\?:\(\?!`"\)\.\)\+ \{ return MD_STR; \}\n<md_string>\(\?:`))/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:\[)/i,/^(?:\])/i,/^(?:[A-Za-z]+)/i,/^(?::)/i,/^(?:\+)/i,/^(?:,)/i,/^(?:=)/i,/^(?:\*)/i,/^(?:#)/i,/^(?:[\_])/i,/^(?:\.)/i,/^(?:&)/i,/^(?:-)/i,/^(?:[0-9]+)/i,/^(?:\s+)/i,/^(?:;)/i,/^(?:$)/i],conditions:{data_inner:{rules:[0,1,4,5,6,7,9,11,14,15,16,17,18,21,22,24,25,26,27,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46],inclusive:!0},data:{rules:[0,1,3,4,5,6,7,9,11,14,15,16,17,18,21,22,23,26,27,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46],inclusive:!0},axis_band_data:{rules:[0,1,4,5,6,7,9,11,14,15,16,17,18,21,22,25,26,27,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46],inclusive:!0},axis_data:{rules:[0,1,2,4,5,6,7,9,11,14,15,16,17,18,19,20,21,22,24,26,27,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46],inclusive:!0},acc_descr_multiline:{rules:[12,13],inclusive:!1},acc_descr:{rules:[10],inclusive:!1},acc_title:{rules:[8],inclusive:!1},title:{rules:[],inclusive:!1},md_string:{rules:[],inclusive:!1},string:{rules:[28,29],inclusive:!1},INITIAL:{rules:[0,1,4,5,6,7,9,11,14,15,16,17,18,21,22,26,27,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46],inclusive:!0}}};return W})();T.lexer=ht;function q(){this.yy={}}return a(q,"Parser"),q.prototype=T,T.Parser=q,new q})();Rt.parser=Rt;var Li=Rt;function pt(e){return e.type==="bar"}a(pt,"isBarPlot");function mt(e){return e.type==="band"}a(mt,"isBandAxisData");function Q(e){return e.type==="linear"}a(Q,"isLinearAxisData");var K,Pt=(K=class{constructor(t){this.parentGroup=t}getMaxDimension(t,i){if(!this.parentGroup)return{width:t.reduce((o,h)=>Math.max(h.length,o),0)*i,height:i};const s={width:0,height:0},n=this.parentGroup.append("g").attr("visibility","hidden").attr("font-size",i);for(const o of t){const h=Ti(n,1,o),p=h?h.width:o.length*i,u=h?h.height:i;s.width=Math.max(s.width,p),s.height=Math.max(s.height,u)}return n.remove(),s}},a(K,"TextDimensionCalculatorWithFont"),K),Yt=.7,Ht=.2,Z,qt=(Z=class{constructor(t,i,s,n){this.axisConfig=t,this.title=i,this.textDimensionCalculator=s,this.axisThemeConfig=n,this.boundingRect={x:0,y:0,width:0,height:0},this.axisPosition="left",this.showTitle=!1,this.showLabel=!1,this.showTick=!1,this.showAxisLine=!1,this.outerPadding=0,this.titleTextHeight=0,this.labelTextHeight=0,this.normalizedLabelRotationInRad=0,this.range=[0,10],this.boundingRect={x:0,y:0,width:0,height:0},this.axisPosition="left",this.normalizedLabelRotationInRad=this.axisConfig.labelRotation>=-90&&this.axisConfig.labelRotation<=90?this.axisConfig.labelRotation*Math.PI/180:0}setRange(t){this.range=t,this.axisPosition==="left"||this.axisPosition==="right"?this.boundingRect.height=t[1]-t[0]:this.boundingRect.width=t[1]-t[0],this.recalculateScale()}getRange(){return[this.range[0]+this.outerPadding,this.range[1]-this.outerPadding]}setAxisPosition(t){this.axisPosition=t,this.setRange(this.range)}getTickDistance(){const t=this.getRange();return Math.abs(t[0]-t[1])/this.getTickValues().length}getAxisOuterPadding(){return this.outerPadding}getLabelDimension(){return this.textDimensionCalculator.getMaxDimension(this.getTickValues().map(t=>t.toString()),this.axisConfig.labelFontSize)}recalculateOuterPaddingToDrawBar(){Yt*this.getTickDistance()>this.outerPadding*2&&(this.outerPadding=Math.floor(Yt*this.getTickDistance()/2)),this.recalculateScale()}calculateSpaceIfDrawnHorizontally(t){let i=t.height;if(this.axisConfig.showAxisLine&&i>this.axisConfig.axisLineWidth&&(i-=this.axisConfig.axisLineWidth,this.showAxisLine=!0),this.axisConfig.showLabel){const s=this.getLabelDimension(),n=Ht*t.width;this.outerPadding=Math.min(s.width/2,n);let o=s.height;this.axisPosition==="bottom"&&this.normalizedLabelRotationInRad!==0&&(o=Math.max(o,Math.abs(Math.sin(this.normalizedLabelRotationInRad)*s.width)+Math.abs(Math.cos(this.normalizedLabelRotationInRad)*s.height))),o+=this.axisConfig.labelPadding*2,this.labelTextHeight=s.height,o<=i&&(i-=o,this.showLabel=!0)}if(this.axisConfig.showTick&&i>=this.axisConfig.tickLength&&(this.showTick=!0,i-=this.axisConfig.tickLength),this.axisConfig.showTitle&&this.title){const s=this.textDimensionCalculator.getMaxDimension([this.title],this.axisConfig.titleFontSize),n=s.height+this.axisConfig.titlePadding*2;this.titleTextHeight=s.height,n<=i&&(i-=n,this.showTitle=!0)}this.boundingRect.width=t.width,this.boundingRect.height=t.height-i}calculateSpaceIfDrawnVertical(t){let i=t.width;if(this.axisConfig.showAxisLine&&i>this.axisConfig.axisLineWidth&&(i-=this.axisConfig.axisLineWidth,this.showAxisLine=!0),this.axisConfig.showLabel){const s=this.getLabelDimension(),n=Ht*t.height;this.outerPadding=Math.min(s.height/2,n);const o=s.width+this.axisConfig.labelPadding*2;o<=i&&(i-=o,this.showLabel=!0)}if(this.axisConfig.showTick&&i>=this.axisConfig.tickLength&&(this.showTick=!0,i-=this.axisConfig.tickLength),this.axisConfig.showTitle&&this.title){const s=this.textDimensionCalculator.getMaxDimension([this.title],this.axisConfig.titleFontSize),n=s.height+this.axisConfig.titlePadding*2;this.titleTextHeight=s.height,n<=i&&(i-=n,this.showTitle=!0)}this.boundingRect.width=t.width-i,this.boundingRect.height=t.height}calculateSpace(t){return this.axisPosition==="left"||this.axisPosition==="right"?this.calculateSpaceIfDrawnVertical(t):this.calculateSpaceIfDrawnHorizontally(t),this.recalculateScale(),{width:this.boundingRect.width,height:this.boundingRect.height}}setBoundingBoxXY(t){this.boundingRect.x=t.x,this.boundingRect.y=t.y}calculateOffsetByRotation(t){const i=this.normalizedLabelRotationInRad;return i===0?0:Math.sin(i)*this.getLabelDimension()[t]/2}getDrawableElementsForLeftAxis(){const t=[];if(this.showAxisLine){const i=this.boundingRect.x+this.boundingRect.width-this.axisConfig.axisLineWidth/2;t.push({type:"path",groupTexts:["left-axis","axisl-line"],data:[{path:`M ${i},${this.boundingRect.y} L ${i},${this.boundingRect.y+this.boundingRect.height} `,strokeFill:this.axisThemeConfig.axisLineColor,strokeWidth:this.axisConfig.axisLineWidth}]})}if(this.showLabel&&t.push({type:"text",groupTexts:["left-axis","label"],data:this.getTickValues().map(i=>({text:i.toString(),x:this.boundingRect.x+this.boundingRect.width-(this.showLabel?this.axisConfig.labelPadding:0)-(this.showTick?this.axisConfig.tickLength:0)-(this.showAxisLine?this.axisConfig.axisLineWidth:0),y:this.getScaleValue(i),fill:this.axisThemeConfig.labelColor,fontSize:this.axisConfig.labelFontSize,rotation:0,verticalPos:"middle",horizontalPos:"right"}))}),this.showTick){const i=this.boundingRect.x+this.boundingRect.width-(this.showAxisLine?this.axisConfig.axisLineWidth:0);t.push({type:"path",groupTexts:["left-axis","ticks"],data:this.getTickValues().map(s=>({path:`M ${i},${this.getScaleValue(s)} L ${i-this.axisConfig.tickLength},${this.getScaleValue(s)}`,strokeFill:this.axisThemeConfig.tickColor,strokeWidth:this.axisConfig.tickWidth}))})}return this.showTitle&&t.push({type:"text",groupTexts:["left-axis","title"],data:[{text:this.title,x:this.boundingRect.x+this.axisConfig.titlePadding,y:this.boundingRect.y+this.boundingRect.height/2,fill:this.axisThemeConfig.titleColor,fontSize:this.axisConfig.titleFontSize,rotation:270,verticalPos:"top",horizontalPos:"center"}]}),t}getDrawableElementsForBottomAxis(){const t=[];if(this.showAxisLine){const i=this.boundingRect.y+this.axisConfig.axisLineWidth/2;t.push({type:"path",groupTexts:["bottom-axis","axis-line"],data:[{path:`M ${this.boundingRect.x},${i} L ${this.boundingRect.x+this.boundingRect.width},${i}`,strokeFill:this.axisThemeConfig.axisLineColor,strokeWidth:this.axisConfig.axisLineWidth}]})}if(this.showLabel&&t.push({type:"text",groupTexts:["bottom-axis","label"],data:this.getTickValues().map(i=>({text:i.toString(),x:this.getScaleValue(i)+this.calculateOffsetByRotation("height"),y:this.boundingRect.y+this.axisConfig.labelPadding+(this.showTick?this.axisConfig.tickLength:0)+(this.showAxisLine?this.axisConfig.axisLineWidth:0)+Math.abs(this.calculateOffsetByRotation("width")),fill:this.axisThemeConfig.labelColor,fontSize:this.axisConfig.labelFontSize,rotation:this.normalizedLabelRotationInRad*180/Math.PI,verticalPos:"top",horizontalPos:"center"}))}),this.showTick){const i=this.boundingRect.y+(this.showAxisLine?this.axisConfig.axisLineWidth:0);t.push({type:"path",groupTexts:["bottom-axis","ticks"],data:this.getTickValues().map(s=>({path:`M ${this.getScaleValue(s)},${i} L ${this.getScaleValue(s)},${i+this.axisConfig.tickLength}`,strokeFill:this.axisThemeConfig.tickColor,strokeWidth:this.axisConfig.tickWidth}))})}return this.showTitle&&t.push({type:"text",groupTexts:["bottom-axis","title"],data:[{text:this.title,x:this.range[0]+(this.range[1]-this.range[0])/2,y:this.boundingRect.y+this.boundingRect.height-this.axisConfig.titlePadding-this.titleTextHeight,fill:this.axisThemeConfig.titleColor,fontSize:this.axisConfig.titleFontSize,rotation:0,verticalPos:"top",horizontalPos:"center"}]}),t}getDrawableElementsForTopAxis(){const t=[];if(this.showAxisLine){const i=this.boundingRect.y+this.boundingRect.height-this.axisConfig.axisLineWidth/2;t.push({type:"path",groupTexts:["top-axis","axis-line"],data:[{path:`M ${this.boundingRect.x},${i} L ${this.boundingRect.x+this.boundingRect.width},${i}`,strokeFill:this.axisThemeConfig.axisLineColor,strokeWidth:this.axisConfig.axisLineWidth}]})}if(this.showLabel&&t.push({type:"text",groupTexts:["top-axis","label"],data:this.getTickValues().map(i=>({text:i.toString(),x:this.getScaleValue(i),y:this.boundingRect.y+(this.showTitle?this.titleTextHeight+this.axisConfig.titlePadding*2:0)+this.axisConfig.labelPadding,fill:this.axisThemeConfig.labelColor,fontSize:this.axisConfig.labelFontSize,rotation:0,verticalPos:"top",horizontalPos:"center"}))}),this.showTick){const i=this.boundingRect.y;t.push({type:"path",groupTexts:["top-axis","ticks"],data:this.getTickValues().map(s=>({path:`M ${this.getScaleValue(s)},${i+this.boundingRect.height-(this.showAxisLine?this.axisConfig.axisLineWidth:0)} L ${this.getScaleValue(s)},${i+this.boundingRect.height-this.axisConfig.tickLength-(this.showAxisLine?this.axisConfig.axisLineWidth:0)}`,strokeFill:this.axisThemeConfig.tickColor,strokeWidth:this.axisConfig.tickWidth}))})}return this.showTitle&&t.push({type:"text",groupTexts:["top-axis","title"],data:[{text:this.title,x:this.boundingRect.x+this.boundingRect.width/2,y:this.boundingRect.y+this.axisConfig.titlePadding,fill:this.axisThemeConfig.titleColor,fontSize:this.axisConfig.titleFontSize,rotation:0,verticalPos:"top",horizontalPos:"center"}]}),t}getDrawableElements(){if(this.axisPosition==="left")return this.getDrawableElementsForLeftAxis();if(this.axisPosition==="right")throw Error("Drawing of right axis is not implemented");return this.axisPosition==="bottom"?this.getDrawableElementsForBottomAxis():this.axisPosition==="top"?this.getDrawableElementsForTopAxis():[]}},a(Z,"BaseAxis"),Z),J,Ei=(J=class extends qt{constructor(t,i,s,n,o){super(t,n,o,i),this.categories=s,this.scale=St().domain(this.categories).range(this.getRange())}setRange(t){super.setRange(t)}recalculateScale(){this.scale=St().domain(this.categories).range(this.getRange()).paddingInner(1).paddingOuter(0).align(.5),Ut.trace("BandAxis axis final categories, range: ",this.categories,this.getRange())}getTickValues(){return this.categories}getScaleValue(t){return this.scale(t)??this.getRange()[0]}},a(J,"BandAxis"),J),tt,Mi=(tt=class extends qt{constructor(t,i,s,n,o){super(t,n,o,i),this.domain=s,this.scale=Nt().domain(this.domain).range(this.getRange())}getTickValues(){return this.scale.ticks()}recalculateScale(){const t=[...this.domain];this.axisPosition==="left"&&t.reverse(),this.scale=Nt().domain(t).range(this.getRange())}getScaleValue(t){return this.scale(t)}},a(tt,"LinearAxis"),tt);function _t(e,t,i,s){const n=new Pt(s);return mt(e)?new Ei(t,i,e.categories,e.title,n):new Mi(t,i,[e.min,e.max],e.title,n)}a(_t,"getAxis");var it,Ii=(it=class{constructor(t,i,s,n){this.textDimensionCalculator=t,this.chartConfig=i,this.chartData=s,this.chartThemeConfig=n,this.boundingRect={x:0,y:0,width:0,height:0},this.showChartTitle=!1}setBoundingBoxXY(t){this.boundingRect.x=t.x,this.boundingRect.y=t.y}calculateSpace(t){const i=this.textDimensionCalculator.getMaxDimension([this.chartData.title],this.chartConfig.titleFontSize),s=Math.max(i.width,t.width),n=i.height+2*this.chartConfig.titlePadding;return i.width<=s&&i.height<=n&&this.chartConfig.showTitle&&this.chartData.title&&(this.boundingRect.width=s,this.boundingRect.height=n,this.showChartTitle=!0),{width:this.boundingRect.width,height:this.boundingRect.height}}getDrawableElements(){const t=[];return this.showChartTitle&&t.push({groupTexts:["chart-title"],type:"text",data:[{fontSize:this.chartConfig.titleFontSize,text:this.chartData.title,verticalPos:"middle",horizontalPos:"center",x:this.boundingRect.x+this.boundingRect.width/2,y:this.boundingRect.y+this.boundingRect.height/2,fill:this.chartThemeConfig.titleColor,rotation:0}]}),t}},a(it,"ChartTitle"),it);function jt(e,t,i,s){const n=new Pt(s);return new Ii(n,e,t,i)}a(jt,"getChartTitleComponent");var Bi=.75,zi=.5,Oi=.35;function kt(e){return{fontSize:e,markerSize:e*Bi,markerSpacing:e*Oi,itemSpacing:e*zi}}a(kt,"getLegendLayout");var et,Vi=(et=class{constructor(t,i,s,n){this.textDimensionCalculator=t,this.chartConfig=i,this.chartData=s,this.chartThemeConfig=n,this.boundingRect={x:0,y:0,width:0,height:0},this.visiblePlots=[]}setBoundingBoxXY(t){this.boundingRect.x=t.x,this.boundingRect.y=t.y}calculateSpace(t){if(this.visiblePlots=this.chartConfig.showLegend?this.chartData.plots.filter(f=>f.title):[],this.visiblePlots.length===0)return this.boundingRect.width=0,this.boundingRect.height=0,{width:0,height:0};const{fontSize:i,markerSize:s,markerSpacing:n,itemSpacing:o}=kt(this.chartConfig.legendFontSize),h=this.textDimensionCalculator.getMaxDimension(this.visiblePlots.map(f=>f.title),i),p=this.chartConfig.legendPadding*2+s+n+h.width,u=this.chartConfig.legendPadding*2+this.visiblePlots.length*i+(this.visiblePlots.length-1)*o;return p<=t.width&&u<=t.height?(this.boundingRect.width=p,this.boundingRect.height=u):(this.visiblePlots=[],this.boundingRect.width=0,this.boundingRect.height=0),{width:this.boundingRect.width,height:this.boundingRect.height}}getDrawableElements(){if(this.visiblePlots.length===0)return[];const{fontSize:t,markerSize:i,markerSpacing:s,itemSpacing:n}=kt(this.chartConfig.legendFontSize),o=t+n,h=this.boundingRect.x+this.chartConfig.legendPadding,p=this.boundingRect.y+this.chartConfig.legendPadding,u=[],f=[];for(const[R,C]of this.visiblePlots.entries())if(pt(C))u.push({x:h,y:p+R*o,width:i,height:i,fill:C.fill,strokeFill:C.fill,strokeWidth:0});else{const y=p+R*o+i/2;f.push({path:`M ${h},${y} L ${h+i},${y}`,strokeFill:C.strokeFill,strokeWidth:C.strokeWidth})}return[{groupTexts:["legend","markers"],type:"rect",data:u},{groupTexts:["legend","markers"],type:"path",data:f},{groupTexts:["legend","label"],type:"text",data:this.visiblePlots.map((R,C)=>({text:R.title,x:h+i+s,y:p+C*o+i/2,fill:this.chartThemeConfig.legendTextColor,fontSize:t,rotation:0,verticalPos:"middle",horizontalPos:"left"}))}]}},a(et,"ChartLegend"),et);function Qt(e,t,i,s){const n=new Pt(s);return new Vi(n,e,t,i)}a(Qt,"getChartLegendComponent");var st,Fi=(st=class{constructor(t,i,s,n,o){this.plotData=t,this.xAxis=i,this.yAxis=s,this.orientation=n,this.plotIndex=o}getDrawableElement(){const t=this.plotData.data.map(n=>[this.xAxis.getScaleValue(n[0]),this.yAxis.getScaleValue(n[1])]);let i;if(this.orientation==="horizontal"?i=Xt().y(n=>n[0]).x(n=>n[1])(t):i=Xt().x(n=>n[0]).y(n=>n[1])(t),!i)return[];const s=[{groupTexts:["plot",`line-plot-${this.plotIndex}`],type:"path",data:[{path:i,strokeFill:this.plotData.strokeFill,strokeWidth:this.plotData.strokeWidth}]}];if(this.plotData.pointLabels&&this.plotData.pointLabels.length>0){const h=[];for(const[p,[u,f]]of t.entries()){const R=this.plotData.pointLabels[p];R&&(this.orientation==="horizontal"?h.push({x:f+10,y:u,text:R,fill:this.plotData.strokeFill,verticalPos:"middle",horizontalPos:"left",fontSize:12,rotation:0}):h.push({x:u,y:f-10,text:R,fill:this.plotData.strokeFill,verticalPos:"middle",horizontalPos:"center",fontSize:12,rotation:0}))}h.length>0&&s.push({groupTexts:["plot",`line-plot-${this.plotIndex}`,"labels"],type:"text",data:h})}return s}},a(st,"LinePlot"),st),nt,Wi=(nt=class{constructor(t,i,s,n,o,h){this.barData=t,this.boundingRect=i,this.xAxis=s,this.yAxis=n,this.orientation=o,this.plotIndex=h}getDrawableElement(){const t=this.barData.data.map(o=>[this.xAxis.getScaleValue(o[0]),this.yAxis.getScaleValue(o[1])]),s=Math.min(this.xAxis.getAxisOuterPadding()*2,this.xAxis.getTickDistance())*(1-.05),n=s/2;return this.orientation==="horizontal"?[{groupTexts:["plot",`bar-plot-${this.plotIndex}`],type:"rect",data:t.map(o=>({x:this.boundingRect.x,y:o[0]-n,height:s,width:o[1]-this.boundingRect.x,fill:this.barData.fill,strokeWidth:0,strokeFill:this.barData.fill}))}]:[{groupTexts:["plot",`bar-plot-${this.plotIndex}`],type:"rect",data:t.map(o=>({x:o[0]-n,y:o[1],width:s,height:this.boundingRect.y+this.boundingRect.height-o[1],fill:this.barData.fill,strokeWidth:0,strokeFill:this.barData.fill}))}]}},a(nt,"BarPlot"),nt),at,Xi=(at=class{constructor(t,i,s){this.chartConfig=t,this.chartData=i,this.chartThemeConfig=s,this.boundingRect={x:0,y:0,width:0,height:0}}setAxes(t,i){this.xAxis=t,this.yAxis=i}setBoundingBoxXY(t){this.boundingRect.x=t.x,this.boundingRect.y=t.y}calculateSpace(t){return this.boundingRect.width=t.width,this.boundingRect.height=t.height,{width:this.boundingRect.width,height:this.boundingRect.height}}getDrawableElements(){if(!(this.xAxis&&this.yAxis))throw Error("Axes must be passed to render Plots");const t=[];for(const[i,s]of this.chartData.plots.entries())switch(s.type){case"line":{const n=new Fi(s,this.xAxis,this.yAxis,this.chartConfig.chartOrientation,i);t.push(...n.getDrawableElement())}break;case"bar":{const n=new Wi(s,this.boundingRect,this.xAxis,this.yAxis,this.chartConfig.chartOrientation,i);t.push(...n.getDrawableElement())}break}return t}},a(at,"BasePlot"),at);function Kt(e,t,i){return new Xi(e,t,i)}a(Kt,"getPlotComponent");var ot,Ni=(ot=class{constructor(t,i,s,n){this.chartConfig=t,this.chartData=i,this.componentStore={title:jt(t,i,s,n),plot:Kt(t,i,s),legend:Qt(t,i,s,n),xAxis:_t(i.xAxis,t.xAxis,{titleColor:s.xAxisTitleColor,labelColor:s.xAxisLabelColor,tickColor:s.xAxisTickColor,axisLineColor:s.xAxisLineColor},n),yAxis:_t(i.yAxis,t.yAxis,{titleColor:s.yAxisTitleColor,labelColor:s.yAxisLabelColor,tickColor:s.yAxisTickColor,axisLineColor:s.yAxisLineColor},n)}}calculateVerticalSpace(){let t=this.chartConfig.width,i=this.chartConfig.height,s=0,n=0,o={width:0,height:0},h=Math.floor(t*this.chartConfig.plotReservedSpacePercent/100),p=Math.floor(i*this.chartConfig.plotReservedSpacePercent/100),u=this.componentStore.plot.calculateSpace({width:h,height:p});t-=u.width,i-=u.height,u=this.componentStore.title.calculateSpace({width:this.chartConfig.width,height:i}),n=u.height,i-=u.height,this.componentStore.xAxis.setAxisPosition("bottom"),u=this.componentStore.xAxis.calculateSpace({width:t,height:i}),i-=u.height,this.componentStore.yAxis.setAxisPosition("left"),u=this.componentStore.yAxis.calculateSpace({width:t,height:i}),s=u.width,t-=u.width,o=this.componentStore.legend.calculateSpace({width:t,height:p}),t-=o.width,t>0&&(h+=t,t=0),i>0&&(p+=i,i=0),this.componentStore.plot.calculateSpace({width:h,height:p}),this.componentStore.plot.setBoundingBoxXY({x:s,y:n}),this.componentStore.legend.setBoundingBoxXY({x:s+h,y:n+Math.max((p-o.height)/2,0)}),this.componentStore.xAxis.setRange([s,s+h]),this.componentStore.xAxis.setBoundingBoxXY({x:s,y:n+p}),this.componentStore.yAxis.setRange([n,n+p]),this.componentStore.yAxis.setBoundingBoxXY({x:0,y:n}),this.chartData.plots.some(f=>pt(f))&&this.componentStore.xAxis.recalculateOuterPaddingToDrawBar()}calculateHorizontalSpace(){let t=this.chartConfig.width,i=this.chartConfig.height,s=0,n=0,o=0,h={width:0,height:0},p=Math.floor(t*this.chartConfig.plotReservedSpacePercent/100),u=Math.floor(i*this.chartConfig.plotReservedSpacePercent/100),f=this.componentStore.plot.calculateSpace({width:p,height:u});t-=f.width,i-=f.height,f=this.componentStore.title.calculateSpace({width:this.chartConfig.width,height:i}),s=f.height,i-=f.height,this.componentStore.xAxis.setAxisPosition("left"),f=this.componentStore.xAxis.calculateSpace({width:t,height:i}),t-=f.width,n=f.width,this.componentStore.yAxis.setAxisPosition("top"),f=this.componentStore.yAxis.calculateSpace({width:t,height:i}),i-=f.height,o=s+f.height,h=this.componentStore.legend.calculateSpace({width:t,height:u}),t-=h.width,t>0&&(p+=t,t=0),i>0&&(u+=i,i=0),this.componentStore.plot.calculateSpace({width:p,height:u}),this.componentStore.plot.setBoundingBoxXY({x:n,y:o}),this.componentStore.legend.setBoundingBoxXY({x:n+p,y:o+Math.max((u-h.height)/2,0)}),this.componentStore.yAxis.setRange([n,n+p]),this.componentStore.yAxis.setBoundingBoxXY({x:n,y:s}),this.componentStore.xAxis.setRange([o,o+u]),this.componentStore.xAxis.setBoundingBoxXY({x:0,y:o}),this.chartData.plots.some(R=>pt(R))&&this.componentStore.xAxis.recalculateOuterPaddingToDrawBar()}calculateSpace(){this.chartConfig.chartOrientation==="horizontal"?this.calculateHorizontalSpace():this.calculateVerticalSpace()}getDrawableElement(){this.calculateSpace();const t=[];this.componentStore.plot.setAxes(this.componentStore.xAxis,this.componentStore.yAxis);for(const i of Object.values(this.componentStore))t.push(...i.getDrawableElements());return t}},a(ot,"Orchestrator"),ot),rt,Yi=(rt=class{static build(t,i,s,n){return new Ni(t,i,s,n).getDrawableElement()}},a(rt,"XYChartBuilder"),rt),ct=0,Zt,gt=Et(),ut=Lt(),w=Mt(),Tt=ut.plotColorPalette.split(",").map(e=>e.trim()),yt=!1,vt=!1;function Lt(){const e=ki(),t=Dt();return Gt(e.xyChart,t.themeVariables.xyChart)}a(Lt,"getChartDefaultThemeConfig");function Et(){const e=Dt();return Gt(_i.xyChart,e.xyChart)}a(Et,"getChartDefaultConfig");function Mt(){return{yAxis:{type:"linear",title:"",min:1/0,max:-1/0},xAxis:{type:"band",title:"",categories:[]},title:"",plots:[]}}a(Mt,"getChartDefaultData");function G(e){const t=Dt();return Ri(e.trim(),t)}a(G,"textSanitizer");function Jt(e){Zt=e}a(Jt,"setTmpSVGG");function ti(e){e==="horizontal"?gt.chartOrientation="horizontal":gt.chartOrientation="vertical"}a(ti,"setOrientation");function ii(e){w.xAxis.title=G(e.text)}a(ii,"setXAxisTitle");function It(e,t){w.xAxis={type:"linear",title:w.xAxis.title,min:e,max:t},yt=!0}a(It,"setXAxisRangeData");function ei(e){w.xAxis={type:"band",title:w.xAxis.title,categories:e.map(t=>G(t.text))},yt=!0}a(ei,"setXAxisBand");function si(e){w.yAxis.title=G(e.text)}a(si,"setYAxisTitle");function ni(e,t){w.yAxis={type:"linear",title:w.yAxis.title,min:e,max:t},vt=!0}a(ni,"setYAxisRangeData");function ai(e){const t=Math.min(...e),i=Math.max(...e),s=Q(w.yAxis)?w.yAxis.min:1/0,n=Q(w.yAxis)?w.yAxis.max:-1/0;w.yAxis={type:"linear",title:w.yAxis.title,min:Math.min(s,t),max:Math.max(n,i)}}a(ai,"setYAxisRangeFromPlotData");function Bt(e){let t=[];if(e.length===0)return t;if(!yt){const i=Q(w.xAxis)?w.xAxis.min:1/0,s=Q(w.xAxis)?w.xAxis.max:-1/0;It(Math.min(i,1),Math.max(s,e.length))}if(mt(w.xAxis)&&e.length>w.xAxis.categories.length&&(e=e.slice(0,w.xAxis.categories.length)),vt||ai(e),mt(w.xAxis)&&(t=w.xAxis.categories.map((i,s)=>[i,e[s]])),Q(w.xAxis)){const i=w.xAxis.min,s=w.xAxis.max;if(e.length===1)t=[[`${i}`,e[0]]];else{const n=(s-i)/(e.length-1);t=e.map((o,h)=>[`${i+h*n}`,o])}}return t}a(Bt,"transformDataWithoutCategory");function zt(e){return Tt[e===0?0:e%Tt.length]}a(zt,"getPlotColorFromPalette");function oi(e,t){const i=t.map(h=>h.value),s=t.map(h=>h.label?G(h.label):""),n=Bt(i),o=s.some(h=>h!=="");w.plots.push({type:"line",title:G(e.text),strokeFill:zt(ct),strokeWidth:2,data:n,...o?{pointLabels:s}:{}}),ct++}a(oi,"setLineData");function ri(e,t){const i=t.map(n=>n.value),s=Bt(i);w.plots.push({type:"bar",title:G(e.text),fill:zt(ct),data:s}),ct++}a(ri,"setBarData");function hi(){if(w.plots.length===0)throw Error("No Plot to render, please provide a plot with some data");return w.title=$t(),Yi.build(gt,w,ut,Zt)}a(hi,"getDrawableElem");function li(){return ut}a(li,"getChartThemeConfig");function ci(){return gt}a(ci,"getChartConfig");function gi(){return w}a(gi,"getXYChartData");var Hi=a(function(){Si(),ct=0,gt=Et(),w=Mt(),ut=Lt(),Tt=ut.plotColorPalette.split(",").map(e=>e.trim()),yt=!1,vt=!1},"clear"),$i={getDrawableElem:hi,clear:Hi,setAccTitle:wi,getAccTitle:bi,setDiagramTitle:yi,getDiagramTitle:$t,getAccDescription:mi,setAccDescription:pi,setOrientation:ti,setXAxisTitle:ii,setXAxisRangeData:It,setXAxisBand:ei,setYAxisTitle:si,setYAxisRangeData:ni,setLineData:oi,setBarData:ri,setTmpSVGG:Jt,getChartThemeConfig:li,getChartConfig:ci,getXYChartData:gi},Ui=a((e,t,i,s)=>{const n=s.db,o=n.getChartThemeConfig(),h=n.getChartConfig(),p=n.getXYChartData().plots[0].data.map(b=>b[1]);function u(b){return b==="top"?"text-before-edge":"middle"}a(u,"getDominantBaseLine");function f(b){return b==="left"?"start":b==="right"?"end":"middle"}a(f,"getTextAnchor");function R(b){return`translate(${b.x}, ${b.y}) rotate(${b.rotation||0})`}a(R,"getTextTransformation"),Ut.debug(`Rendering xychart chart
7
+ `+e);const C=Ai(t),y=C.append("g").attr("class","main"),E=y.append("rect").attr("width",h.width).attr("height",h.height).attr("class","background");Ci(C,h.height,h.width,!0),C.attr("viewBox",`0 0 ${h.width} ${h.height}`),E.attr("fill",o.backgroundColor),n.setTmpSVGG(C.append("g").attr("class","mermaid-tmp-group"));const v=n.getDrawableElem(),L={};function M(b){let D=y,c="";for(const[z]of b.entries()){let F=y;z>0&&L[c]&&(F=L[c]),c+=b[z],D=L[c],D||(D=L[c]=F.append("g").attr("class",b[z]))}return D}a(M,"getGroup");for(const b of v){if(b.data.length===0)continue;const D=M(b.groupTexts);switch(b.type){case"rect":if(D.selectAll("rect").data(b.data).enter().append("rect").attr("x",c=>c.x).attr("y",c=>c.y).attr("width",c=>c.width).attr("height",c=>c.height).attr("fill",c=>c.fill).attr("stroke",c=>c.strokeFill).attr("stroke-width",c=>c.strokeWidth),h.showDataLabel){const c=h.showDataLabelOutsideBar;if(h.chartOrientation==="horizontal"){let z=function(S,O){const{data:T,label:ht}=S;return O*ht.length*F<=T.width-X};a(z,"fitsHorizontally");const F=.7,X=10,N=b.data.map((S,O)=>({data:S,label:p[O].toString()})).filter(S=>S.data.width>0&&S.data.height>0),k=N.map(S=>{const{data:O}=S;let T=O.height*.7;for(;!z(S,T)&&T>0;)T-=1;return T}),H=Math.floor(Math.min(...k)),A=a(S=>c?S.data.x+S.data.width+X:S.data.x+S.data.width-X,"determineLabelXPosition");D.selectAll("text").data(N).enter().append("text").attr("x",A).attr("y",S=>S.data.y+S.data.height/2).attr("text-anchor",c?"start":"end").attr("dominant-baseline","middle").attr("fill",o.dataLabelColor).attr("font-size",`${H}px`).text(S=>S.label)}else{let z=function(A,S,O){const{data:T,label:ht}=A,W=S*ht.length*.7,l=T.x+T.width/2,g=l-W/2,d=l+W/2,x=g>=T.x&&d<=T.x+T.width,_=T.y+O+S<=T.y+T.height;return x&&_};a(z,"fitsInBar");const F=10,X=b.data.map((A,S)=>({data:A,label:p[S].toString()})).filter(A=>A.data.width>0&&A.data.height>0),N=X.map(A=>{const{data:S,label:O}=A;let T=S.width/(O.length*.7);for(;!z(A,T,F)&&T>0;)T-=1;return T}),k=Math.floor(Math.min(...N)),H=a(A=>c?A.data.y-F:A.data.y+F,"determineLabelYPosition");D.selectAll("text").data(X).enter().append("text").attr("x",A=>A.data.x+A.data.width/2).attr("y",H).attr("text-anchor","middle").attr("dominant-baseline",c?"auto":"hanging").attr("fill",o.dataLabelColor).attr("font-size",`${k}px`).text(A=>A.label)}}break;case"text":D.selectAll("text").data(b.data).enter().append("text").attr("x",0).attr("y",0).attr("fill",c=>c.fill).attr("font-size",c=>c.fontSize).attr("dominant-baseline",c=>u(c.verticalPos)).attr("text-anchor",c=>f(c.horizontalPos)).attr("transform",c=>R(c)).text(c=>c.text);break;case"path":D.selectAll("path").data(b.data).enter().append("path").attr("d",c=>c.path).attr("fill",c=>c.fill?c.fill:"none").attr("stroke",c=>c.strokeFill).attr("stroke-width",c=>c.strokeWidth);break}}},"draw"),Gi={draw:Ui},ie={parser:Li,db:$i,renderer:Gi};export{ie as diagram};
@@ -0,0 +1,22 @@
1
+ export declare function docsList(req: ReqType, res: ResType): Promise<ResType>;
2
+ export declare function docsKeywords(req: ReqType, res: ResType): Promise<ResType>;
3
+ export declare function docsSearch(req: ReqType, res: ResType): Promise<ResType>;
4
+ export declare function docsContext(req: ReqType, res: ResType): Promise<ResType>;
5
+ export declare function docsDoc(req: ReqType, res: ResType): Promise<ResType>;
6
+ /**
7
+ * Resolves references written inside a document to document ids. How a
8
+ * reference is spelled is the implementation's business; the viewer only
9
+ * learns which of them point at a document this user may open — the rest stay
10
+ * unresolved and are rendered as plain text.
11
+ */
12
+ export declare function docsResolve(req: ReqType, res: ResType): Promise<ResType>;
13
+ /**
14
+ * The viewer page. The document itself is fetched by the page through the API,
15
+ * so a deep link only has to name the document it opens with.
16
+ */
17
+ export declare function docsPage(req: ReqType): Promise<import("express").Response<any, Record<string, any>>>;
18
+ /**
19
+ * Structure of a model resource as this user is allowed to see it — the same
20
+ * fields DataAccessor would hand to the list page, nothing more.
21
+ */
22
+ export declare function docsSchema(req: ReqType, res: ResType): Promise<ResType>;
@@ -0,0 +1,126 @@
1
+ import { resolveModelResource } from '../../helpers/modelResourceHelper.js';
2
+ import { getUiTranslations } from '../../lib/ui-i18n/getUiTranslations.js';
3
+ import { DOCS_UI_TRANSLATION_KEYS } from '../../lib/ui-i18n/uiTranslationKeys.js';
4
+ import { DataAccessor } from '../../lib/DataAccessor.js';
5
+ /**
6
+ * Thin JSON proxy of the documentation subsystem: policies have checked the
7
+ * auth and the base token, `DocumentationHandler` applies per-document rights,
8
+ * the implementation does the actual work. No logic lives here.
9
+ */
10
+ function requestedLocale(req) {
11
+ const locale = typeof req.query.locale === 'string' ? req.query.locale.trim() : '';
12
+ return locale || req.adminizer.documentationHandler.localeFor(req.user);
13
+ }
14
+ function describeMeta(meta) {
15
+ return {
16
+ id: meta.id,
17
+ title: meta.title,
18
+ section: meta.section,
19
+ keywords: meta.keywords,
20
+ models: meta.models,
21
+ urls: meta.urls,
22
+ locales: meta.locales,
23
+ };
24
+ }
25
+ export async function docsList(req, res) {
26
+ const documents = await req.adminizer.documentationHandler.list(req.user, requestedLocale(req));
27
+ return res.json({ documents: documents.map(describeMeta) });
28
+ }
29
+ export async function docsKeywords(req, res) {
30
+ const keywords = await req.adminizer.documentationHandler.keywords(req.user, requestedLocale(req));
31
+ return res.json({ keywords: Object.fromEntries(keywords) });
32
+ }
33
+ export async function docsSearch(req, res) {
34
+ const keywords = typeof req.query.keywords === 'string'
35
+ ? req.query.keywords.split(',').map((keyword) => keyword.trim()).filter(Boolean)
36
+ : undefined;
37
+ const results = await req.adminizer.documentationHandler.search(req.user, {
38
+ query: typeof req.query.q === 'string' ? req.query.q : undefined,
39
+ keywords,
40
+ url: typeof req.query.url === 'string' ? req.query.url : undefined,
41
+ model: typeof req.query.model === 'string' ? req.query.model : undefined,
42
+ }, requestedLocale(req));
43
+ return res.json({
44
+ results: results.map((result) => ({ ...describeMeta(result.meta), snippets: result.snippets })),
45
+ });
46
+ }
47
+ export async function docsContext(req, res) {
48
+ const documents = await req.adminizer.documentationHandler.forContext(req.user, {
49
+ url: typeof req.query.url === 'string' ? req.query.url : undefined,
50
+ model: typeof req.query.model === 'string' ? req.query.model : undefined,
51
+ }, requestedLocale(req));
52
+ return res.json({ documents: documents.map(describeMeta) });
53
+ }
54
+ export async function docsDoc(req, res) {
55
+ const content = await req.adminizer.documentationHandler.get(req.user, String(req.params.id ?? ''), requestedLocale(req));
56
+ // A document the user may not read does not exist for them.
57
+ if (!content) {
58
+ return res.status(404).json({ error: req.i18n?.__('Not found') || 'Not found' });
59
+ }
60
+ return res.json({ meta: describeMeta(content.meta), markdown: content.markdown, locale: content.locale });
61
+ }
62
+ /**
63
+ * Resolves references written inside a document to document ids. How a
64
+ * reference is spelled is the implementation's business; the viewer only
65
+ * learns which of them point at a document this user may open — the rest stay
66
+ * unresolved and are rendered as plain text.
67
+ */
68
+ export async function docsResolve(req, res) {
69
+ const from = typeof req.query.from === 'string' ? req.query.from : '';
70
+ // `refs` is the comma-separated form the viewer uses; repeated `ref`
71
+ // parameters are accepted as well for hand-written calls.
72
+ const raw = req.query.ref;
73
+ const refs = [
74
+ ...(typeof req.query.refs === 'string' ? req.query.refs.split(',') : []),
75
+ ...(Array.isArray(raw) ? raw : [raw]),
76
+ ]
77
+ .filter((ref) => typeof ref === 'string' && ref.trim() !== '')
78
+ .map((ref) => ref.trim());
79
+ const resolved = {};
80
+ for (const ref of refs) {
81
+ const id = await req.adminizer.documentationHandler.resolveLink(req.user, from, ref);
82
+ if (id)
83
+ resolved[ref] = id;
84
+ }
85
+ return res.json({ resolved });
86
+ }
87
+ /**
88
+ * The viewer page. The document itself is fetched by the page through the API,
89
+ * so a deep link only has to name the document it opens with.
90
+ */
91
+ export async function docsPage(req) {
92
+ return req.Inertia.render({
93
+ component: 'docs',
94
+ props: {
95
+ title: req.i18n.__('Documentation'),
96
+ docId: typeof req.params.id === 'string' ? req.params.id : null,
97
+ i18nPage: getUiTranslations(req, DOCS_UI_TRANSLATION_KEYS),
98
+ },
99
+ });
100
+ }
101
+ /**
102
+ * Structure of a model resource as this user is allowed to see it — the same
103
+ * fields DataAccessor would hand to the list page, nothing more.
104
+ */
105
+ export async function docsSchema(req, res) {
106
+ const name = typeof req.query.model === 'string' ? req.query.model.trim() : '';
107
+ const resource = name ? resolveModelResource(req.adminizer, name) : undefined;
108
+ if (!resource) {
109
+ return res.status(404).json({ error: req.i18n.__('Model not found') });
110
+ }
111
+ if (!await req.adminizer.accessRightsHelper.hasPermission(`read-${resource.name}-model`, req.user)) {
112
+ return res.status(403).json({ error: req.i18n.__('Access denied') });
113
+ }
114
+ const fields = new DataAccessor(req.adminizer, req.user, resource, 'list').getFieldsConfig() ?? {};
115
+ return res.json({
116
+ model: resource.name,
117
+ title: req.i18n.__(resource.config?.title ?? resource.name),
118
+ url: resource.uri,
119
+ fields: Object.entries(fields).map(([key, field]) => ({
120
+ name: key,
121
+ title: field.config?.title ? req.i18n.__(field.config.title) : key,
122
+ type: String(field.config?.type ?? field.model?.type ?? 'string'),
123
+ required: Boolean(field.config?.required ?? field.model?.required),
124
+ })),
125
+ });
126
+ }
package/index.d.ts CHANGED
@@ -27,6 +27,9 @@ export * from "./lib/media-manager/AbstractMediaManager.js";
27
27
  export * from "./lib/controls/Control.js";
28
28
  export * from "./lib/controls/ControlsHandler.js";
29
29
  export * from "./lib/Adminizer.js";
30
+ export * from "./lib/docs/AbstractDocumentation.js";
31
+ export * from "./lib/docs/DocumentationHandler.js";
32
+ export * from "./lib/docs/FileDocumentation.js";
30
33
  export * from "./lib/I18n.js";
31
34
  export * from "./models/Group.js";
32
35
  export * from "./models/User.js";
package/index.js CHANGED
@@ -27,6 +27,9 @@ export * from "./lib/media-manager/AbstractMediaManager.js";
27
27
  export * from "./lib/controls/Control.js";
28
28
  export * from "./lib/controls/ControlsHandler.js";
29
29
  export * from "./lib/Adminizer.js";
30
+ export * from "./lib/docs/AbstractDocumentation.js";
31
+ export * from "./lib/docs/DocumentationHandler.js";
32
+ export * from "./lib/docs/FileDocumentation.js";
30
33
  export * from "./lib/I18n.js";
31
34
  export * from "./models/Group.js";
32
35
  export * from "./models/User.js";
@@ -223,6 +223,14 @@ export interface AdminpanelConfig {
223
223
  defaultModel?: string;
224
224
  models?: string[];
225
225
  };
226
+ /**
227
+ * Knowledge base (built-in documentation). The implementation is
228
+ * registered separately: `adminizer.documentationHandler.register(service)`.
229
+ */
230
+ documentation?: {
231
+ /** Master switch of the subsystem; nothing is brought up unless `true` */
232
+ enabled?: boolean;
233
+ };
226
234
  cors?: {
227
235
  enabled: boolean;
228
236
  origin: string[] | string;
@@ -30,6 +30,7 @@ import { AccessRightsHandler } from "./access-rights/AccessRightsHandler.js";
30
30
  import { AiAssistantUiMethodHandler } from './ai-assistant/AiAssistantUiMethodHandler.js';
31
31
  import { AdminLinkHandler } from './admin-links/AdminLinkHandler.js';
32
32
  import { AiAssistantAgentSkillHandler } from './ai-assistant/AiAssistantAgentSkillHandler.js';
33
+ import { DocumentationHandler } from './docs/DocumentationHandler.js';
33
34
  export declare function createAdminizerLogger(): winston.Logger;
34
35
  export interface EmitAsyncOptions {
35
36
  /**
@@ -60,6 +61,7 @@ export declare class Adminizer {
60
61
  aiAssistantUiMethodHandler: AiAssistantUiMethodHandler;
61
62
  adminLinkHandler: AdminLinkHandler;
62
63
  aiAssistantAgentSkillHandler: AiAssistantAgentSkillHandler;
64
+ documentationHandler: DocumentationHandler;
63
65
  modelHandler: ModelHandler;
64
66
  widgetHandler: WidgetHandler;
65
67
  customFilterHandler: CustomFilterHandler;
package/lib/Adminizer.js CHANGED
@@ -46,6 +46,8 @@ import { AccessRightsHandler } from "./access-rights/AccessRightsHandler.js";
46
46
  import { AiAssistantUiMethodHandler } from './ai-assistant/AiAssistantUiMethodHandler.js';
47
47
  import { AdminLinkHandler } from './admin-links/AdminLinkHandler.js';
48
48
  import { AiAssistantAgentSkillHandler } from './ai-assistant/AiAssistantAgentSkillHandler.js';
49
+ import { DocumentationHandler } from './docs/DocumentationHandler.js';
50
+ import bindDocs from '../system/bindDocs.js';
49
51
  const logFilePath = "logs/app.log";
50
52
  function ensureLogDirectory(filePath) {
51
53
  const logDirectory = path.dirname(filePath);
@@ -115,6 +117,7 @@ export class Adminizer {
115
117
  aiAssistantUiMethodHandler;
116
118
  adminLinkHandler;
117
119
  aiAssistantAgentSkillHandler;
120
+ documentationHandler;
118
121
  modelHandler;
119
122
  widgetHandler;
120
123
  customFilterHandler;
@@ -150,6 +153,7 @@ export class Adminizer {
150
153
  this.aiAssistantUiMethodHandler = new AiAssistantUiMethodHandler(this);
151
154
  this.adminLinkHandler = new AdminLinkHandler(this);
152
155
  this.aiAssistantAgentSkillHandler = new AiAssistantAgentSkillHandler(this);
156
+ this.documentationHandler = new DocumentationHandler(this, () => bindDocs(this));
153
157
  this.controllerHandler = new ControllerHandler(this);
154
158
  this.assetHandler = new AssetHandler(this);
155
159
  this.configLayerHandler = new ConfigLayerHandler(this);
@@ -302,6 +306,11 @@ export class Adminizer {
302
306
  bindHistory(this);
303
307
  this.router = new Router(this);
304
308
  await this.router.bind(); // must be after binding policies and req/res functions
309
+ // Documentation (knowledge base) wires itself on register(); this call
310
+ // covers a service registered before the config was read. It runs after
311
+ // the router so those routes sit behind the same middleware stack a
312
+ // service registered after init() gets.
313
+ this.documentationHandler.activate();
305
314
  /**
306
315
  * Adminizer loaded
307
316
  * This call is used so that other apps can know that the admin panel is present in the panel and has been loaded, and can activate their logic.
@@ -0,0 +1,100 @@
1
+ import type { Adminizer } from '../Adminizer.js';
2
+ export interface DocMeta {
3
+ /** Stable document identifier; the only handle that ever leaves the abstraction. */
4
+ id: string;
5
+ /** Title in the requested locale when a translation exists. */
6
+ title: string;
7
+ /** Viewer grouping. */
8
+ section?: string;
9
+ keywords: string[];
10
+ /** Model resource names this document is about. */
11
+ models: string[];
12
+ /** Express-style admin path patterns (`:id` placeholders) the document is bound to. */
13
+ urls: string[];
14
+ /**
15
+ * Per-document access right, required on top of the base documentation
16
+ * token. References an existing token (registered by the host or an app);
17
+ * documentation never creates tokens itself.
18
+ */
19
+ accessRightsToken?: string;
20
+ /** Locales this document is available in. */
21
+ locales?: string[];
22
+ }
23
+ export interface DocContent {
24
+ meta: DocMeta;
25
+ /** Content in the locale that was actually served. */
26
+ markdown: string;
27
+ locale: string;
28
+ }
29
+ export interface DocSearchQuery {
30
+ /** Full-text query; matched against title, keywords and content. */
31
+ query?: string;
32
+ /** Every listed keyword must be present on the document. */
33
+ keywords?: string[];
34
+ /** Narrow the scope to documents bound to this admin path. */
35
+ url?: string;
36
+ /** Narrow the scope to documents bound to this model. */
37
+ model?: string;
38
+ }
39
+ export interface DocSearchResult {
40
+ meta: DocMeta;
41
+ /** Matched lines with a little surrounding context, best matches first. */
42
+ snippets: string[];
43
+ }
44
+ /**
45
+ * The single contract of the documentation subsystem. Everything adminizer
46
+ * does with documentation — listing, reading, searching, resolving links —
47
+ * goes through this class; where documents live, how translations are stored
48
+ * and how search works are private details of the implementation.
49
+ *
50
+ * One implementation is active per adminizer instance (a singleton registered
51
+ * on startup). Implementations know nothing about users or permissions: the
52
+ * access layer is applied by adminizer on top of every result.
53
+ *
54
+ * Only `list` and `get` are required. The base class implements search,
55
+ * context matching, the keyword map and link resolution on top of them; an
56
+ * implementation overrides any of those when it can do better (e.g. database
57
+ * full-text search).
58
+ */
59
+ export declare abstract class AbstractDocumentation {
60
+ /** Set when the implementation is registered; not part of the contract. */
61
+ adminizer: Adminizer;
62
+ /**
63
+ * Metadata of every document, without content, in the requested locale.
64
+ * Falls back to the best available translation per document.
65
+ */
66
+ abstract list(locale?: string): Promise<DocMeta[]>;
67
+ /**
68
+ * One document in the requested locale. How the translation is obtained
69
+ * is up to the implementation; when the locale is unavailable it serves
70
+ * the best available version and reports which locale it actually is.
71
+ */
72
+ abstract get(id: string, locale?: string): Promise<DocContent | undefined>;
73
+ /**
74
+ * Keyword filter plus full-text scan over `list()`/`get()`. Content is
75
+ * only fetched for documents that survive the metadata filters.
76
+ */
77
+ search(query: DocSearchQuery, locale?: string): Promise<DocSearchResult[]>;
78
+ /** Documents bound to a place in the admin panel: a URL and/or a model. */
79
+ forContext(ctx: {
80
+ url?: string;
81
+ model?: string;
82
+ }, locale?: string): Promise<DocMeta[]>;
83
+ /** Keyword → document ids, aggregated from metadata. */
84
+ keywords(locale?: string): Promise<Map<string, string[]>>;
85
+ /**
86
+ * Resolves a reference written inside `fromId` to the id of the target
87
+ * document. How authors spell references is implementation-specific; the
88
+ * default only understands plain document ids (with an optional anchor).
89
+ */
90
+ resolveLink(_fromId: string, ref: string): Promise<string | undefined>;
91
+ /**
92
+ * Change notification: consumers subscribe to drop their caches. Optional;
93
+ * implementations without it are treated as static.
94
+ */
95
+ onChange?(cb: (ids?: string[]) => void): void;
96
+ /** Matches an Express-style pattern (`/model/:name`) against a concrete path. */
97
+ protected matchesUrl(pattern: string, url: string): boolean;
98
+ /** Lines containing the query, trimmed to a little context around the match. */
99
+ protected extractSnippets(markdown: string, query: string): string[];
100
+ }
@@ -0,0 +1,108 @@
1
+ const SNIPPET_LIMIT = 3;
2
+ const SNIPPET_CONTEXT = 120;
3
+ /**
4
+ * The single contract of the documentation subsystem. Everything adminizer
5
+ * does with documentation — listing, reading, searching, resolving links —
6
+ * goes through this class; where documents live, how translations are stored
7
+ * and how search works are private details of the implementation.
8
+ *
9
+ * One implementation is active per adminizer instance (a singleton registered
10
+ * on startup). Implementations know nothing about users or permissions: the
11
+ * access layer is applied by adminizer on top of every result.
12
+ *
13
+ * Only `list` and `get` are required. The base class implements search,
14
+ * context matching, the keyword map and link resolution on top of them; an
15
+ * implementation overrides any of those when it can do better (e.g. database
16
+ * full-text search).
17
+ */
18
+ export class AbstractDocumentation {
19
+ /** Set when the implementation is registered; not part of the contract. */
20
+ adminizer;
21
+ /**
22
+ * Keyword filter plus full-text scan over `list()`/`get()`. Content is
23
+ * only fetched for documents that survive the metadata filters.
24
+ */
25
+ async search(query, locale) {
26
+ const wanted = (query.query ?? '').trim().toLowerCase();
27
+ const keywords = (query.keywords ?? []).map((keyword) => keyword.trim().toLowerCase()).filter(Boolean);
28
+ let candidates = await this.forContext({ url: query.url, model: query.model }, locale);
29
+ if (keywords.length > 0) {
30
+ candidates = candidates.filter((meta) => {
31
+ const present = meta.keywords.map((keyword) => keyword.toLowerCase());
32
+ return keywords.every((keyword) => present.includes(keyword));
33
+ });
34
+ }
35
+ if (!wanted)
36
+ return candidates.map((meta) => ({ meta, snippets: [] }));
37
+ const results = [];
38
+ for (const meta of candidates) {
39
+ const inMeta = meta.title.toLowerCase().includes(wanted)
40
+ || meta.keywords.some((keyword) => keyword.toLowerCase().includes(wanted));
41
+ const content = await this.get(meta.id, locale);
42
+ const snippets = content ? this.extractSnippets(content.markdown, wanted) : [];
43
+ if (inMeta || snippets.length > 0)
44
+ results.push({ meta, snippets });
45
+ }
46
+ return results;
47
+ }
48
+ /** Documents bound to a place in the admin panel: a URL and/or a model. */
49
+ async forContext(ctx, locale) {
50
+ const documents = await this.list(locale);
51
+ const url = ctx.url?.trim();
52
+ const model = ctx.model?.trim();
53
+ if (!url && !model)
54
+ return documents;
55
+ return documents.filter((meta) => (!url || meta.urls.some((pattern) => this.matchesUrl(pattern, url)))
56
+ && (!model || meta.models.includes(model)));
57
+ }
58
+ /** Keyword → document ids, aggregated from metadata. */
59
+ async keywords(locale) {
60
+ const map = new Map();
61
+ for (const meta of await this.list(locale)) {
62
+ for (const raw of meta.keywords) {
63
+ const keyword = raw.trim();
64
+ if (!keyword)
65
+ continue;
66
+ const ids = map.get(keyword) ?? [];
67
+ if (!ids.includes(meta.id))
68
+ ids.push(meta.id);
69
+ map.set(keyword, ids);
70
+ }
71
+ }
72
+ return map;
73
+ }
74
+ /**
75
+ * Resolves a reference written inside `fromId` to the id of the target
76
+ * document. How authors spell references is implementation-specific; the
77
+ * default only understands plain document ids (with an optional anchor).
78
+ */
79
+ async resolveLink(_fromId, ref) {
80
+ const id = ref.trim().replace(/#.*$/, '');
81
+ if (!id)
82
+ return undefined;
83
+ const documents = await this.list();
84
+ return documents.find((meta) => meta.id === id)?.id;
85
+ }
86
+ /** Matches an Express-style pattern (`/model/:name`) against a concrete path. */
87
+ matchesUrl(pattern, url) {
88
+ const path = url.replace(/[?#].*$/, '').replace(/\/+$/, '') || '/';
89
+ const source = pattern.replace(/\/+$/, '') || '/';
90
+ const regex = new RegExp(`^${source.replace(/[.*+?^${}()|[\]\\]/g, '\\$&').replace(/:[A-Za-z0-9_]+/g, '[^/]+')}$`);
91
+ return regex.test(path);
92
+ }
93
+ /** Lines containing the query, trimmed to a little context around the match. */
94
+ extractSnippets(markdown, query) {
95
+ const snippets = [];
96
+ for (const line of markdown.split('\n')) {
97
+ const index = line.toLowerCase().indexOf(query);
98
+ if (index === -1)
99
+ continue;
100
+ const start = Math.max(0, index - SNIPPET_CONTEXT / 2);
101
+ const snippet = line.slice(start, start + query.length + SNIPPET_CONTEXT).trim();
102
+ snippets.push(`${start > 0 ? '…' : ''}${snippet}${start + query.length + SNIPPET_CONTEXT < line.length ? '…' : ''}`);
103
+ if (snippets.length >= SNIPPET_LIMIT)
104
+ break;
105
+ }
106
+ return snippets;
107
+ }
108
+ }