@sabrish/power-platform-solution-blueprint 0.5.1

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 (129) hide show
  1. package/CHANGELOG.md +166 -0
  2. package/LICENSE +21 -0
  3. package/README.md +331 -0
  4. package/dist/assets/BusinessProcessFlowDiscovery-BSDgBoIA.js +2 -0
  5. package/dist/assets/BusinessProcessFlowDiscovery-BSDgBoIA.js.map +1 -0
  6. package/dist/assets/ColumnSecurityDiscovery-B3yVn0LZ.js +2 -0
  7. package/dist/assets/ColumnSecurityDiscovery-B3yVn0LZ.js.map +1 -0
  8. package/dist/assets/ConnectionReferenceDiscovery-DFTQuo-S.js +2 -0
  9. package/dist/assets/ConnectionReferenceDiscovery-DFTQuo-S.js.map +1 -0
  10. package/dist/assets/CustomAPIDiscovery-BiQS_ENt.js +2 -0
  11. package/dist/assets/CustomAPIDiscovery-BiQS_ENt.js.map +1 -0
  12. package/dist/assets/CustomConnectorDiscovery-TvNjElP3.js +2 -0
  13. package/dist/assets/CustomConnectorDiscovery-TvNjElP3.js.map +1 -0
  14. package/dist/assets/EnvironmentVariableDiscovery-DG_tXCcQ.js +2 -0
  15. package/dist/assets/EnvironmentVariableDiscovery-DG_tXCcQ.js.map +1 -0
  16. package/dist/assets/GlobalChoiceDiscovery-nivz9yGs.js +2 -0
  17. package/dist/assets/GlobalChoiceDiscovery-nivz9yGs.js.map +1 -0
  18. package/dist/assets/HtmlReporter-Cu9NwA6b.js +1894 -0
  19. package/dist/assets/HtmlReporter-Cu9NwA6b.js.map +1 -0
  20. package/dist/assets/JsonReporter-BqDJorX-.js +2 -0
  21. package/dist/assets/JsonReporter-BqDJorX-.js.map +1 -0
  22. package/dist/assets/MarkdownReporter-B1FEpc6-.js +53 -0
  23. package/dist/assets/MarkdownReporter-B1FEpc6-.js.map +1 -0
  24. package/dist/assets/ZipPackager-B4xx8LbF.js +3 -0
  25. package/dist/assets/ZipPackager-B4xx8LbF.js.map +1 -0
  26. package/dist/assets/_baseUniq-Nm59UrQz.js +2 -0
  27. package/dist/assets/_baseUniq-Nm59UrQz.js.map +1 -0
  28. package/dist/assets/arc-BVr5R-xB.js +2 -0
  29. package/dist/assets/arc-BVr5R-xB.js.map +1 -0
  30. package/dist/assets/architectureDiagram-VXUJARFQ-C-olLUHb.js +37 -0
  31. package/dist/assets/architectureDiagram-VXUJARFQ-C-olLUHb.js.map +1 -0
  32. package/dist/assets/blockDiagram-VD42YOAC-B4incSX8.js +123 -0
  33. package/dist/assets/blockDiagram-VD42YOAC-B4incSX8.js.map +1 -0
  34. package/dist/assets/c4Diagram-YG6GDRKO-BJxhcb17.js +11 -0
  35. package/dist/assets/c4Diagram-YG6GDRKO-BJxhcb17.js.map +1 -0
  36. package/dist/assets/channel-CjhOgOS9.js +2 -0
  37. package/dist/assets/channel-CjhOgOS9.js.map +1 -0
  38. package/dist/assets/chunk-4BX2VUAB-BIe6iK-b.js +2 -0
  39. package/dist/assets/chunk-4BX2VUAB-BIe6iK-b.js.map +1 -0
  40. package/dist/assets/chunk-55IACEB6-CA6P5Ey6.js +2 -0
  41. package/dist/assets/chunk-55IACEB6-CA6P5Ey6.js.map +1 -0
  42. package/dist/assets/chunk-B4BG7PRW-licIQLj-.js +166 -0
  43. package/dist/assets/chunk-B4BG7PRW-licIQLj-.js.map +1 -0
  44. package/dist/assets/chunk-DI55MBZ5-CxFpzZDS.js +221 -0
  45. package/dist/assets/chunk-DI55MBZ5-CxFpzZDS.js.map +1 -0
  46. package/dist/assets/chunk-FMBD7UC4-VjnBPAq9.js +16 -0
  47. package/dist/assets/chunk-FMBD7UC4-VjnBPAq9.js.map +1 -0
  48. package/dist/assets/chunk-QN33PNHL-BcMwEixv.js +2 -0
  49. package/dist/assets/chunk-QN33PNHL-BcMwEixv.js.map +1 -0
  50. package/dist/assets/chunk-QZHKN3VN-6eOG0UZ6.js +2 -0
  51. package/dist/assets/chunk-QZHKN3VN-6eOG0UZ6.js.map +1 -0
  52. package/dist/assets/chunk-TZMSLE5B-B38vDpWG.js +2 -0
  53. package/dist/assets/chunk-TZMSLE5B-B38vDpWG.js.map +1 -0
  54. package/dist/assets/classDiagram-2ON5EDUG-CEjpoRuI.js +2 -0
  55. package/dist/assets/classDiagram-2ON5EDUG-CEjpoRuI.js.map +1 -0
  56. package/dist/assets/classDiagram-v2-WZHVMYZB-CEjpoRuI.js +2 -0
  57. package/dist/assets/classDiagram-v2-WZHVMYZB-CEjpoRuI.js.map +1 -0
  58. package/dist/assets/clone-FgHYDKfb.js +2 -0
  59. package/dist/assets/clone-FgHYDKfb.js.map +1 -0
  60. package/dist/assets/cose-bilkent-S5V4N54A-BFz6nI_Q.js +2 -0
  61. package/dist/assets/cose-bilkent-S5V4N54A-BFz6nI_Q.js.map +1 -0
  62. package/dist/assets/cytoscape.esm-CyJtwmzi.js +332 -0
  63. package/dist/assets/cytoscape.esm-CyJtwmzi.js.map +1 -0
  64. package/dist/assets/dagre-6UL2VRFP-B9xCTGce.js +5 -0
  65. package/dist/assets/dagre-6UL2VRFP-B9xCTGce.js.map +1 -0
  66. package/dist/assets/defaultLocale-DX6XiGOO.js +2 -0
  67. package/dist/assets/defaultLocale-DX6XiGOO.js.map +1 -0
  68. package/dist/assets/diagram-PSM6KHXK-BG-mPBdn.js +25 -0
  69. package/dist/assets/diagram-PSM6KHXK-BG-mPBdn.js.map +1 -0
  70. package/dist/assets/diagram-QEK2KX5R-BAd41szY.js +44 -0
  71. package/dist/assets/diagram-QEK2KX5R-BAd41szY.js.map +1 -0
  72. package/dist/assets/diagram-S2PKOQOG-Qhy7nrMX.js +25 -0
  73. package/dist/assets/diagram-S2PKOQOG-Qhy7nrMX.js.map +1 -0
  74. package/dist/assets/erDiagram-Q2GNP2WA-HJD-sygr.js +61 -0
  75. package/dist/assets/erDiagram-Q2GNP2WA-HJD-sygr.js.map +1 -0
  76. package/dist/assets/flowDiagram-NV44I4VS-DcFzPV5l.js +163 -0
  77. package/dist/assets/flowDiagram-NV44I4VS-DcFzPV5l.js.map +1 -0
  78. package/dist/assets/ganttDiagram-JELNMOA3-5hzmn_YM.js +268 -0
  79. package/dist/assets/ganttDiagram-JELNMOA3-5hzmn_YM.js.map +1 -0
  80. package/dist/assets/gitGraphDiagram-NY62KEGX-BJoaRoQP.js +66 -0
  81. package/dist/assets/gitGraphDiagram-NY62KEGX-BJoaRoQP.js.map +1 -0
  82. package/dist/assets/graph-iTkoc_Qp.js +2 -0
  83. package/dist/assets/graph-iTkoc_Qp.js.map +1 -0
  84. package/dist/assets/index-C0N3Q-wf.js +404 -0
  85. package/dist/assets/index-C0N3Q-wf.js.map +1 -0
  86. package/dist/assets/index-Dau71uup.css +1 -0
  87. package/dist/assets/infoDiagram-WHAUD3N6-Dm-9Locf.js +3 -0
  88. package/dist/assets/infoDiagram-WHAUD3N6-Dm-9Locf.js.map +1 -0
  89. package/dist/assets/init-Gi6I4Gst.js +2 -0
  90. package/dist/assets/init-Gi6I4Gst.js.map +1 -0
  91. package/dist/assets/journeyDiagram-XKPGCS4Q-Cn4q49x5.js +140 -0
  92. package/dist/assets/journeyDiagram-XKPGCS4Q-Cn4q49x5.js.map +1 -0
  93. package/dist/assets/kanban-definition-3W4ZIXB7-lUx8-faE.js +90 -0
  94. package/dist/assets/kanban-definition-3W4ZIXB7-lUx8-faE.js.map +1 -0
  95. package/dist/assets/katex-CBSAILhF.js +262 -0
  96. package/dist/assets/katex-CBSAILhF.js.map +1 -0
  97. package/dist/assets/layout-BNMvCxLN.js +2 -0
  98. package/dist/assets/layout-BNMvCxLN.js.map +1 -0
  99. package/dist/assets/linear-OqJg3PPm.js +2 -0
  100. package/dist/assets/linear-OqJg3PPm.js.map +1 -0
  101. package/dist/assets/min-N_DZlU1c.js +2 -0
  102. package/dist/assets/min-N_DZlU1c.js.map +1 -0
  103. package/dist/assets/mindmap-definition-VGOIOE7T-C43AGCOz.js +69 -0
  104. package/dist/assets/mindmap-definition-VGOIOE7T-C43AGCOz.js.map +1 -0
  105. package/dist/assets/ordinal-Cboi1Yqb.js +2 -0
  106. package/dist/assets/ordinal-Cboi1Yqb.js.map +1 -0
  107. package/dist/assets/pieDiagram-ADFJNKIX-COl1BPcc.js +31 -0
  108. package/dist/assets/pieDiagram-ADFJNKIX-COl1BPcc.js.map +1 -0
  109. package/dist/assets/quadrantDiagram-AYHSOK5B-C-fSINkS.js +8 -0
  110. package/dist/assets/quadrantDiagram-AYHSOK5B-C-fSINkS.js.map +1 -0
  111. package/dist/assets/requirementDiagram-UZGBJVZJ-DSag9Z4m.js +65 -0
  112. package/dist/assets/requirementDiagram-UZGBJVZJ-DSag9Z4m.js.map +1 -0
  113. package/dist/assets/sankeyDiagram-TZEHDZUN-JyvYJ7BV.js +11 -0
  114. package/dist/assets/sankeyDiagram-TZEHDZUN-JyvYJ7BV.js.map +1 -0
  115. package/dist/assets/sequenceDiagram-WL72ISMW-GkUPZQOc.js +146 -0
  116. package/dist/assets/sequenceDiagram-WL72ISMW-GkUPZQOc.js.map +1 -0
  117. package/dist/assets/stateDiagram-FKZM4ZOC-DiJHFrza.js +2 -0
  118. package/dist/assets/stateDiagram-FKZM4ZOC-DiJHFrza.js.map +1 -0
  119. package/dist/assets/stateDiagram-v2-4FDKWEC3-BgdSYitm.js +2 -0
  120. package/dist/assets/stateDiagram-v2-4FDKWEC3-BgdSYitm.js.map +1 -0
  121. package/dist/assets/timeline-definition-IT6M3QCI-BIeoFfU5.js +62 -0
  122. package/dist/assets/timeline-definition-IT6M3QCI-BIeoFfU5.js.map +1 -0
  123. package/dist/assets/treemap-KMMF4GRG-BDDqLxLB.js +129 -0
  124. package/dist/assets/treemap-KMMF4GRG-BDDqLxLB.js.map +1 -0
  125. package/dist/assets/xychartDiagram-PRI3JC2R-CUzWjNyv.js +8 -0
  126. package/dist/assets/xychartDiagram-PRI3JC2R-CUzWjNyv.js.map +1 -0
  127. package/dist/index.html +13 -0
  128. package/index.html +12 -0
  129. package/package.json +74 -0
@@ -0,0 +1,1894 @@
1
+ var k=Object.defineProperty;var T=(g,e,s)=>e in g?k(g,e,{enumerable:!0,configurable:!0,writable:!0,value:s}):g[e]=s;var v=(g,e,s)=>T(g,typeof e!="symbol"?e+"":e,s);class E{htmlHead(e){const s=`Blueprint - ${e.metadata.environment||"Power Platform"}`;return`<head>
2
+ <meta charset="UTF-8">
3
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
4
+ <meta name="generator" content="Power Platform Solution Blueprint (PPSB)">
5
+ <meta name="description" content="Complete architectural blueprint for Power Platform solutions">
6
+ <title>${this.escapeHtml(s)}</title>
7
+ <script src="https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.min.js"><\/script>
8
+ <style>
9
+ ${this.embeddedCSS()}
10
+ </style>
11
+ </head>`}htmlNavigation(){return`<nav class="sidebar" id="sidebar" role="navigation" aria-label="Main navigation">
12
+ <div class="sidebar-header">
13
+ <h3>Blueprint</h3>
14
+ <button class="nav-toggle" id="navToggle" aria-label="Toggle navigation">☰</button>
15
+ </div>
16
+ <ul class="nav-links">
17
+ <li><a href="#summary">📊 Summary</a></li>
18
+ <li><a href="#erd">🔗 Entity Relationship Diagram</a></li>
19
+ <li><a href="#entities">📦 Entities</a></li>
20
+ <li><a href="#plugins">🔌 Plugins</a></li>
21
+ <li><a href="#flows">⚡ Flows</a></li>
22
+ <li><a href="#business-rules">📋 Business Rules</a></li>
23
+ <li><a href="#classic-workflows">⏱️ Classic Workflows</a></li>
24
+ <li><a href="#business-process-flows">🔄 Business Process Flows</a></li>
25
+ <li><a href="#web-resources">🌐 Web Resources</a></li>
26
+ <li><a href="#custom-apis">🔧 Custom APIs</a></li>
27
+ <li><a href="#environment-variables">⚙️ Environment Variables</a></li>
28
+ <li><a href="#connection-references">🔗 Connection References</a></li>
29
+ <li><a href="#security">🔒 Security</a></li>
30
+ <li><a href="#external-dependencies">🌍 External Dependencies</a></li>
31
+ <li><a href="#cross-entity">🔀 Cross-Entity Automation</a></li>
32
+ </ul>
33
+ <div class="nav-footer">
34
+ <button class="btn-print" onclick="window.print()" aria-label="Print blueprint">🖨️ Print</button>
35
+ </div>
36
+ </nav>`}htmlHeader(e){const s=e.generatedAt.toLocaleString();return`<header class="report-header" role="banner">
37
+ <h1>Power Platform Solution Blueprint</h1>
38
+ <div class="metadata-grid">
39
+ <div class="metadata-item">
40
+ <span class="metadata-label">Environment:</span>
41
+ <span class="metadata-value">${this.escapeHtml(e.environment)}</span>
42
+ </div>
43
+ <div class="metadata-item">
44
+ <span class="metadata-label">Generated:</span>
45
+ <span class="metadata-value">${this.escapeHtml(s)}</span>
46
+ </div>
47
+ <div class="metadata-item">
48
+ <span class="metadata-label">Scope:</span>
49
+ <span class="metadata-value">${this.escapeHtml(e.scope.description)}</span>
50
+ </div>
51
+ <div class="metadata-item">
52
+ <span class="metadata-label">Entities:</span>
53
+ <span class="metadata-value">${e.entityCount}</span>
54
+ </div>
55
+ </div>
56
+ </header>`}htmlErdSection(e){if(!e||e.diagrams.length===0)return`<section id="erd" class="content-section">
57
+ <h2>Entity Relationship Diagram</h2>
58
+ <div class="empty-state">No ERD available</div>
59
+ </section>`;const s=this.generateLegendHtml(e.legend),t=e.diagrams[0],a=`<div class="erd-diagram">
60
+ <h3>${this.escapeHtml(t.title)}</h3>
61
+ <p class="diagram-description">${this.escapeHtml(t.description)}</p>
62
+ <div class="mermaid" id="diagram-0">
63
+ ${t.mermaidDiagram}
64
+ </div>
65
+ <p class="diagram-stats">Entities: ${t.entityCount} | Relationships: ${t.relationshipCount}</p>
66
+ </div>`;return`<section id="erd" class="content-section">
67
+ <h2>Entity Relationship Diagram</h2>
68
+ ${s}
69
+ ${a}
70
+ </section>`}generateLegendHtml(e){return!e||e.length===0?"":`<div class="erd-legend">
71
+ <h4>Publishers</h4>
72
+ <div class="legend-items">
73
+ ${e.map(t=>`<div class="legend-item">
74
+ <span class="legend-color" style="background-color: ${t.color}"></span>
75
+ <span class="legend-label">${this.escapeHtml(t.publisherName)} (${t.entityCount})</span>
76
+ </div>`).join(`
77
+ `)}
78
+ </div>
79
+ </div>`}htmlSummary(e){return`<section id="summary" class="content-section">
80
+ <h2>Summary</h2>
81
+ <div class="summary-grid">
82
+ <div class="summary-card">
83
+ <div class="card-number">${e.totalEntities}</div>
84
+ <div class="card-label">Entities</div>
85
+ </div>
86
+ <div class="summary-card">
87
+ <div class="card-number">${e.totalAttributes}</div>
88
+ <div class="card-label">Attributes</div>
89
+ </div>
90
+ <div class="summary-card">
91
+ <div class="card-number">${e.totalPlugins}</div>
92
+ <div class="card-label">Plugins</div>
93
+ </div>
94
+ <div class="summary-card">
95
+ <div class="card-number">${e.totalFlows}</div>
96
+ <div class="card-label">Flows</div>
97
+ </div>
98
+ <div class="summary-card">
99
+ <div class="card-number">${e.totalBusinessRules}</div>
100
+ <div class="card-label">Business Rules</div>
101
+ </div>
102
+ <div class="summary-card">
103
+ <div class="card-number">${e.totalWebResources}</div>
104
+ <div class="card-label">Web Resources</div>
105
+ </div>
106
+ <div class="summary-card">
107
+ <div class="card-number">${e.totalCustomAPIs}</div>
108
+ <div class="card-label">Custom APIs</div>
109
+ </div>
110
+ <div class="summary-card">
111
+ <div class="card-number">${e.totalSecurityRoles}</div>
112
+ <div class="card-label">Security Roles</div>
113
+ </div>
114
+ <div class="summary-card">
115
+ <div class="card-number">${e.totalFieldSecurityProfiles}</div>
116
+ <div class="card-label">Field Security Profiles</div>
117
+ </div>
118
+ <div class="summary-card ${e.totalClassicWorkflows>0?"card-warning":""}">
119
+ <div class="card-number">${e.totalClassicWorkflows}</div>
120
+ <div class="card-label">Classic Workflows</div>
121
+ </div>
122
+ </div>
123
+ </section>`}htmlEntitiesAccordion(e){if(e.length===0)return`<section id="entities" class="content-section">
124
+ <h2>Entities</h2>
125
+ <div class="empty-state">No entities found</div>
126
+ </section>`;const s=e.map((t,a)=>{var p,b,d,m,u,f;const n=t.entity,i=((b=(p=n.DisplayName)==null?void 0:p.UserLocalizedLabel)==null?void 0:b.Label)||n.LogicalName,o=((d=n.Attributes)==null?void 0:d.length)||0,r=((m=t.plugins)==null?void 0:m.length)||0,c=((u=t.flows)==null?void 0:u.length)||0,l=((f=t.businessRules)==null?void 0:f.length)||0,h=this.hasEntityExecutionPipeline(t);return`<div class="accordion-item">
127
+ <div class="accordion-header" onclick="toggleAccordion('entity-${a}')">
128
+ <span class="accordion-icon" id="icon-entity-${a}">+</span>
129
+ <h3>${this.escapeHtml(i)}</h3>
130
+ <span class="entity-badges">
131
+ ${o>0?`<span class="badge badge-info">${o} fields</span>`:""}
132
+ ${r>0?`<span class="badge badge-success">${r} plugins</span>`:""}
133
+ ${c>0?`<span class="badge badge-primary">${c} flows</span>`:""}
134
+ ${l>0?`<span class="badge badge-warning">${l} rules</span>`:""}
135
+ </span>
136
+ </div>
137
+ <div class="accordion-content" id="entity-${a}" style="display: none;">
138
+ <!-- Entity Tabs -->
139
+ <div class="entity-tabs">
140
+ <div class="tabs-header">
141
+ <button class="tab-button active" onclick="switchEntityTab('entity-${a}', 'overview')">Overview</button>
142
+ <button class="tab-button" onclick="switchEntityTab('entity-${a}', 'schema')">Schema</button>
143
+ ${this.hasEntityAutomation(t)?`<button class="tab-button" onclick="switchEntityTab('entity-${a}', 'automation')">Automation</button>`:""}
144
+ ${h?`<button class="tab-button" onclick="switchEntityTab('entity-${a}', 'pipeline')">Execution Pipeline</button>`:""}
145
+ </div>
146
+
147
+ <!-- Overview Tab -->
148
+ <div class="tab-content active" id="entity-${a}-overview">
149
+ ${this.generateEntityOverviewTab(t)}
150
+ </div>
151
+
152
+ <!-- Schema Tab -->
153
+ <div class="tab-content" id="entity-${a}-schema">
154
+ ${this.generateEntitySchemaTab(t)}
155
+ </div>
156
+
157
+ ${this.hasEntityAutomation(t)?`<!-- Automation Tab -->
158
+ <div class="tab-content" id="entity-${a}-automation">
159
+ ${this.generateEntityAutomationTab(t)}
160
+ </div>`:""}
161
+
162
+ ${h?`<!-- Execution Pipeline Tab -->
163
+ <div class="tab-content" id="entity-${a}-pipeline">
164
+ ${this.generateEntityPipelineTab(t)}
165
+ </div>`:""}
166
+ </div>
167
+ </div>
168
+ </div>`}).join(`
169
+ `);return`<section id="entities" class="content-section">
170
+ <h2>Entities (${e.length})</h2>
171
+ <div class="accordion">
172
+ ${s}
173
+ </div>
174
+ </section>`}generateAttributesTable(e){if(e.length===0)return"";const s=e.slice(0,50).map(a=>{var c,l,h,p,b;const n=((l=(c=a.DisplayName)==null?void 0:c.UserLocalizedLabel)==null?void 0:l.Label)||a.LogicalName,i=((p=(h=a.Description)==null?void 0:h.UserLocalizedLabel)==null?void 0:p.Label)||"",o=((b=a.RequiredLevel)==null?void 0:b.Value)||"None",r=a.AttributeType||"Unknown";return`<tr>
175
+ <td>${this.escapeHtml(a.LogicalName)}</td>
176
+ <td>${this.escapeHtml(n)}</td>
177
+ <td>${this.escapeHtml(r)}</td>
178
+ <td><span class="badge badge-${o==="SystemRequired"?"error":o==="ApplicationRequired"?"warning":"info"}">${o}</span></td>
179
+ <td style="word-break: break-word;">${this.escapeHtml(i)}</td>
180
+ </tr>`}).join(`
181
+ `),t=e.length>50?`<p class="table-note">Showing 50 of ${e.length} attributes</p>`:"";return`<div class="entity-subsection">
182
+ <h4>Attributes (${e.length})</h4>
183
+ <table class="data-table">
184
+ <thead>
185
+ <tr>
186
+ <th>Logical Name</th>
187
+ <th>Display Name</th>
188
+ <th>Type</th>
189
+ <th>Required</th>
190
+ <th>Description</th>
191
+ </tr>
192
+ </thead>
193
+ <tbody>
194
+ ${s}
195
+ </tbody>
196
+ </table>
197
+ ${t}
198
+ </div>`}generateEntityPluginsTable(e){if(e.length===0)return"";const s=e.map(t=>`<tr>
199
+ <td>${this.escapeHtml(t.name)}</td>
200
+ <td>${this.escapeHtml(t.message||"")}</td>
201
+ <td>${this.escapeHtml(t.stageName||"")}</td>
202
+ <td>${this.escapeHtml(t.modeName||"")}</td>
203
+ <td style="word-break: break-word;">${this.escapeHtml(t.description||"")}</td>
204
+ </tr>`).join(`
205
+ `);return`<div class="entity-subsection">
206
+ <h4>Plugins (${e.length})</h4>
207
+ <table class="data-table">
208
+ <thead>
209
+ <tr>
210
+ <th>Name</th>
211
+ <th>Message</th>
212
+ <th>Stage</th>
213
+ <th>Mode</th>
214
+ <th>Description</th>
215
+ </tr>
216
+ </thead>
217
+ <tbody>
218
+ ${s}
219
+ </tbody>
220
+ </table>
221
+ </div>`}generateEntityFlowsTable(e){if(e.length===0)return"";const s=e.map(t=>`<tr>
222
+ <td>${this.escapeHtml(t.name)}</td>
223
+ <td><span class="badge badge-${t.state==="Active"?"success":t.state==="Draft"?"warning":"error"}">${t.state}</span></td>
224
+ <td>${this.escapeHtml(t.definition.triggerEvent)}</td>
225
+ <td style="word-break: break-word;">${this.escapeHtml(t.description||"")}</td>
226
+ </tr>`).join(`
227
+ `);return`<div class="entity-subsection">
228
+ <h4>Flows (${e.length})</h4>
229
+ <table class="data-table">
230
+ <thead>
231
+ <tr>
232
+ <th>Name</th>
233
+ <th>State</th>
234
+ <th>Trigger</th>
235
+ <th>Description</th>
236
+ </tr>
237
+ </thead>
238
+ <tbody>
239
+ ${s}
240
+ </tbody>
241
+ </table>
242
+ </div>`}hasEntityAutomation(e){return e.plugins.length>0||e.flows.length>0||e.businessRules.length>0}hasEntityExecutionPipeline(e){return!!(e.plugins.length>0||e.businessRules.some(a=>a.scopeName==="Entity")||e.flows.some(a=>a.definition.triggerType==="Dataverse"))}generateEntityOverviewTab(e){var i,o,r;const s=e.entity,t=((o=(i=s.Description)==null?void 0:i.UserLocalizedLabel)==null?void 0:o.Label)||"",a=[["Logical Name",s.LogicalName],["Schema Name",s.SchemaName],["Primary Field",s.PrimaryNameAttribute||"N/A"],["Ownership",s.OwnershipTypeName||"N/A"],["Is Activity",s.IsActivity?"Yes":"No"],["Is Custom",s.IsCustomEntity?"Yes":"No"]],n=`
243
+ <div class="automation-summary">
244
+ <div class="summary-row">
245
+ <span class="summary-label">Plugins:</span>
246
+ <span class="summary-value">${e.plugins.length}</span>
247
+ </div>
248
+ <div class="summary-row">
249
+ <span class="summary-label">Cloud Flows:</span>
250
+ <span class="summary-value">${e.flows.length}</span>
251
+ </div>
252
+ <div class="summary-row">
253
+ <span class="summary-label">Business Rules:</span>
254
+ <span class="summary-value">${e.businessRules.length}</span>
255
+ </div>
256
+ <div class="summary-row">
257
+ <span class="summary-label">Attributes:</span>
258
+ <span class="summary-value">${((r=s.Attributes)==null?void 0:r.length)||0}</span>
259
+ </div>
260
+ </div>
261
+ `;return`
262
+ ${t?`<div class="entity-description">${this.escapeHtml(t)}</div>`:""}
263
+ <div class="entity-metadata">
264
+ <h4>Entity Information</h4>
265
+ <table class="metadata-table">
266
+ ${a.map(([c,l])=>`<tr><th>${c}</th><td>${this.escapeHtml(l)}</td></tr>`).join(`
267
+ `)}
268
+ </table>
269
+ </div>
270
+ ${n}
271
+ `}generateEntitySchemaTab(e){const s=e.entity,t=s.Attributes||[],a=s.OneToManyRelationships||[],n=s.ManyToOneRelationships||[],i=s.ManyToManyRelationships||[];let o="";t.length>0?o+=this.generateAttributesTable(t):o+='<div class="empty-state">No attributes found</div>';const r=a.length+n.length+i.length;return r>0&&(o+=`<div class="entity-subsection">
272
+ <h4>Relationships (${r})</h4>
273
+ ${a.length>0?this.generateRelationshipsSection("One-to-Many",a):""}
274
+ ${n.length>0?this.generateRelationshipsSection("Many-to-One",n):""}
275
+ ${i.length>0?this.generateRelationshipsSection("Many-to-Many",i):""}
276
+ </div>`),e.fieldSecurity&&e.fieldSecurity.securedFields.length>0&&(o+=this.generateFieldSecuritySection(e.fieldSecurity)),o}generateEntityAutomationTab(e){let s="";return e.plugins.length>0||e.flows.length>0||e.businessRules.length>0?(e.plugins.length>0&&(s+=this.generateEntityPluginsTable(e.plugins)),e.flows.length>0&&(s+=this.generateEntityFlowsTable(e.flows)),e.businessRules.length>0&&(s+=this.generateEntityBusinessRulesTable(e.businessRules)),s):'<div class="empty-state">No automation configured for this entity</div>'}generateEntityPipelineTab(e){var o,r;const s=e.entity,t=((r=(o=s.DisplayName)==null?void 0:o.UserLocalizedLabel)==null?void 0:r.Label)||s.LogicalName;let a=`<div class="pipeline-intro">
277
+ <p>This shows the execution order of server-side automation on <strong>${this.escapeHtml(t)}</strong>.</p>
278
+ </div>`;const n=new Map;for(const c of e.plugins){const l=c.message;n.has(l)||n.set(l,[]),n.get(l).push(c)}const i=e.businessRules.filter(c=>c.scopeName==="Entity");if(e.plugins.length===0){a+="<p><strong>No plugins registered on this entity.</strong></p>",i.length>0&&(a+=`<div class="entity-subsection">
279
+ <h4>Business Rules (Server-side)</h4>
280
+ ${this.generateEntityBusinessRulesTable(i)}
281
+ </div>`);const c=e.flows.filter(l=>l.definition.triggerType==="Dataverse");return c.length>0&&(a+=`<div class="entity-subsection">
282
+ <h4>Dataverse Flows</h4>
283
+ ${this.generateEntityFlowsTable(c)}
284
+ </div>`),a}for(const[c,l]of n){a+=`<div class="pipeline-message">
285
+ <h4>${this.escapeHtml(c)} Event</h4>`;const h=[...l].sort((d,m)=>d.stage!==m.stage?d.stage-m.stage:d.rank-m.rank),p=new Map;for(const d of h)p.has(d.stage)||p.set(d.stage,[]),p.get(d.stage).push(d);a+=this.generatePipelineVisualization(p,i),a+="<h5>Execution Details</h5>",a+=this.generatePipelineDetailsTable(h,i);const b=h.filter(d=>d.mode===0);b.length>0&&(a+=`<div class="info-box">
286
+ <strong>ℹ️ Synchronous Plugins</strong>
287
+ <p>${b.length} synchronous plugin(s) execute in this pipeline. Synchronous plugins block the transaction and should complete quickly.</p>
288
+ </div>`),a+="</div>"}return e.businessRules.length>0&&(a+=`<div class="entity-subsection">
289
+ <h4>All Business Rules</h4>
290
+ <p>Business rules execute on the client (form) or server depending on their scope.</p>
291
+ ${this.generateEntityBusinessRulesTable(e.businessRules)}
292
+ </div>`),a}generatePipelineVisualization(e,s){let t='<div class="pipeline-visual">';s.length>0&&(t+=`<div class="pipeline-stage stage-business-rules">
293
+ <div class="stage-header">Business Rules (Server-side, Entity-scoped)</div>
294
+ <div class="stage-steps">`,s.forEach((a,n)=>{const i=a.state==="Active"?"active":"draft";t+=`<div class="pipeline-step step-${i}">
295
+ ${n+1}. ${this.escapeHtml(a.name)} <span class="step-badge badge-${i}">[${i.toUpperCase()}]</span>
296
+ </div>`}),t+="</div></div>");for(const[a,n]of e){const i=n[0].stageName,o=this.getStageClass(a);t+=`<div class="pipeline-stage ${o}">
297
+ <div class="stage-header">Stage ${a}: ${this.escapeHtml(i)}</div>
298
+ <div class="stage-steps">`,n.forEach((r,c)=>{const l=r.mode===0?"sync":"async";t+=`<div class="pipeline-step step-${l}">
299
+ ${c+1}. ${this.escapeHtml(r.name)} <span class="step-badge badge-${l}">[${l.toUpperCase()}]</span>
300
+ <span class="step-rank">Rank: ${r.rank}</span>
301
+ </div>`}),t+="</div></div>"}return t+="</div>",t}getStageClass(e){switch(e){case 10:return"stage-prevalidation";case 20:return"stage-preoperation";case 30:return"stage-mainoperation";case 40:return"stage-postoperation";default:return"stage-unknown"}}generatePipelineDetailsTable(e,s){const t=[];return s.forEach((a,n)=>{const i=a.state==="Active"?'<span class="badge badge-success">Active</span>':'<span class="badge badge-warning">Draft</span>';t.push(`<tr>
302
+ <td>${n+1}</td>
303
+ <td>Business Rule</td>
304
+ <td>${this.escapeHtml(a.name)}</td>
305
+ <td>Server-side (Entity scope)</td>
306
+ <td>${i}</td>
307
+ <td>-</td>
308
+ </tr>`)}),e.forEach((a,n)=>{const i=a.mode===0?'<span class="badge badge-sync">Synchronous</span>':'<span class="badge badge-async">Asynchronous</span>';t.push(`<tr>
309
+ <td>${s.length+n+1}</td>
310
+ <td>Plugin</td>
311
+ <td>${this.escapeHtml(a.name)}</td>
312
+ <td>${this.escapeHtml(a.stageName)}</td>
313
+ <td>${i}</td>
314
+ <td>${a.rank}</td>
315
+ </tr>`)}),`<table class="data-table pipeline-table">
316
+ <thead>
317
+ <tr>
318
+ <th>Order</th>
319
+ <th>Type</th>
320
+ <th>Name</th>
321
+ <th>Stage/Details</th>
322
+ <th>Mode</th>
323
+ <th>Rank</th>
324
+ </tr>
325
+ </thead>
326
+ <tbody>
327
+ ${t.join(`
328
+ `)}
329
+ </tbody>
330
+ </table>`}generateEntityBusinessRulesTable(e){if(e.length===0)return"";const s=e.map(t=>{const a=t.state==="Active"?'<span class="badge badge-success">Active</span>':'<span class="badge badge-warning">Draft</span>';return`<tr>
331
+ <td>${this.escapeHtml(t.name)}</td>
332
+ <td>${this.escapeHtml(t.scopeName)}</td>
333
+ <td>${this.escapeHtml(t.definition.executionContext)}</td>
334
+ <td>${a}</td>
335
+ <td>${t.definition.conditions.length}</td>
336
+ <td>${t.definition.actions.length}</td>
337
+ </tr>`}).join(`
338
+ `);return`<div class="entity-subsection">
339
+ <h4>Business Rules (${e.length})</h4>
340
+ <table class="data-table">
341
+ <thead>
342
+ <tr>
343
+ <th>Name</th>
344
+ <th>Scope</th>
345
+ <th>Context</th>
346
+ <th>State</th>
347
+ <th>Conditions</th>
348
+ <th>Actions</th>
349
+ </tr>
350
+ </thead>
351
+ <tbody>
352
+ ${s}
353
+ </tbody>
354
+ </table>
355
+ </div>`}generateRelationshipsSection(e,s){if(s.length===0)return"";const t=s.slice(0,20).map(n=>{const i=n.SchemaName||"N/A",o=n.ReferencingEntity||n.ReferencedEntity||"N/A",r=n.ReferencedAttribute||n.ReferencingAttribute||"N/A";return`<tr>
356
+ <td>${this.escapeHtml(i)}</td>
357
+ <td>${this.escapeHtml(o)}</td>
358
+ <td>${this.escapeHtml(r)}</td>
359
+ </tr>`}).join(`
360
+ `),a=s.length>20?`<p class="table-note">Showing 20 of ${s.length} relationships</p>`:"";return`<div class="relationship-section">
361
+ <h5>${e} (${s.length})</h5>
362
+ <table class="data-table">
363
+ <thead>
364
+ <tr>
365
+ <th>Schema Name</th>
366
+ <th>Related Entity</th>
367
+ <th>Related Attribute</th>
368
+ </tr>
369
+ </thead>
370
+ <tbody>
371
+ ${t}
372
+ </tbody>
373
+ </table>
374
+ ${a}
375
+ </div>`}htmlPluginsTable(e){if(e.length===0)return`<section id="plugins" class="content-section">
376
+ <h2>Plugins</h2>
377
+ <div class="empty-state">No plugins found</div>
378
+ </section>`;const s=e.map(t=>{const a=[];t.preImage&&a.push(t.preImage.imageType),t.postImage&&a.push(t.postImage.imageType);const n=a.length>0?a.join(", "):"None";return`<tr>
379
+ <td>${this.escapeHtml(t.name)}</td>
380
+ <td>${this.escapeHtml(t.entity||"N/A")}</td>
381
+ <td>${this.escapeHtml(t.message||"N/A")}</td>
382
+ <td>${this.escapeHtml(t.stageName||"N/A")}</td>
383
+ <td>${this.escapeHtml(t.modeName||"N/A")}</td>
384
+ <td>${String(t.rank||0)}</td>
385
+ <td>${this.escapeHtml(n)}</td>
386
+ </tr>`}).join(`
387
+ `);return`<section id="plugins" class="content-section">
388
+ <h2>Plugins (${e.length})</h2>
389
+ <div class="table-container">
390
+ <table class="data-table sortable" id="plugins-table">
391
+ <thead>
392
+ <tr>
393
+ <th onclick="sortTable('plugins-table', 0)">Name <span class="sort-indicator"></span></th>
394
+ <th onclick="sortTable('plugins-table', 1)">Entity <span class="sort-indicator"></span></th>
395
+ <th onclick="sortTable('plugins-table', 2)">Message <span class="sort-indicator"></span></th>
396
+ <th onclick="sortTable('plugins-table', 3)">Stage <span class="sort-indicator"></span></th>
397
+ <th onclick="sortTable('plugins-table', 4)">Mode <span class="sort-indicator"></span></th>
398
+ <th onclick="sortTable('plugins-table', 5)">Rank <span class="sort-indicator"></span></th>
399
+ <th>Images</th>
400
+ </tr>
401
+ </thead>
402
+ <tbody>
403
+ ${s}
404
+ </tbody>
405
+ </table>
406
+ </div>
407
+ </section>`}htmlFlowsTable(e){if(e.length===0)return`<section id="flows" class="content-section">
408
+ <h2>Flows</h2>
409
+ <div class="empty-state">No flows found</div>
410
+ </section>`;const s=e.map(t=>{const a=t.entityDisplayName||t.entity||"N/A",n=t.hasExternalCalls;return`<tr>
411
+ <td>${this.escapeHtml(t.name)}</td>
412
+ <td>${this.escapeHtml(a)}</td>
413
+ <td><span class="badge badge-${t.state==="Active"?"success":t.state==="Draft"?"warning":"error"}">${t.state}</span></td>
414
+ <td>${this.escapeHtml(t.definition.triggerEvent)}</td>
415
+ <td>${this.escapeHtml(t.definition.scopeType)}</td>
416
+ <td>${t.definition.actionsCount}</td>
417
+ <td>${n?'<span class="badge badge-warning">Yes</span>':'<span class="badge badge-info">No</span>'}</td>
418
+ </tr>`}).join(`
419
+ `);return`<section id="flows" class="content-section">
420
+ <h2>Flows (${e.length})</h2>
421
+ <div class="table-container">
422
+ <table class="data-table sortable" id="flows-table">
423
+ <thead>
424
+ <tr>
425
+ <th onclick="sortTable('flows-table', 0)">Name <span class="sort-indicator"></span></th>
426
+ <th onclick="sortTable('flows-table', 1)">Entity <span class="sort-indicator"></span></th>
427
+ <th onclick="sortTable('flows-table', 2)">State <span class="sort-indicator"></span></th>
428
+ <th onclick="sortTable('flows-table', 3)">Trigger <span class="sort-indicator"></span></th>
429
+ <th onclick="sortTable('flows-table', 4)">Scope <span class="sort-indicator"></span></th>
430
+ <th onclick="sortTable('flows-table', 5)">Actions <span class="sort-indicator"></span></th>
431
+ <th>External Calls</th>
432
+ </tr>
433
+ </thead>
434
+ <tbody>
435
+ ${s}
436
+ </tbody>
437
+ </table>
438
+ </div>
439
+ </section>`}htmlBusinessRulesTable(e){if(e.length===0)return`<section id="business-rules" class="content-section">
440
+ <h2>Business Rules</h2>
441
+ <div class="empty-state">No business rules found</div>
442
+ </section>`;const s=e.map(t=>{var o,r;const a=t.entityDisplayName||t.entity,n=((o=t.definition.conditions)==null?void 0:o.length)||0,i=((r=t.definition.actions)==null?void 0:r.length)||0;return`<tr>
443
+ <td>${this.escapeHtml(t.name)}</td>
444
+ <td>${this.escapeHtml(a)}</td>
445
+ <td><span class="badge badge-${t.state==="Active"?"success":"warning"}">${t.state}</span></td>
446
+ <td>${this.escapeHtml(t.scope)}</td>
447
+ <td>${n}</td>
448
+ <td>${i}</td>
449
+ </tr>`}).join(`
450
+ `);return`<section id="business-rules" class="content-section">
451
+ <h2>Business Rules (${e.length})</h2>
452
+ <div class="table-container">
453
+ <table class="data-table sortable" id="business-rules-table">
454
+ <thead>
455
+ <tr>
456
+ <th onclick="sortTable('business-rules-table', 0)">Name <span class="sort-indicator"></span></th>
457
+ <th onclick="sortTable('business-rules-table', 1)">Entity <span class="sort-indicator"></span></th>
458
+ <th onclick="sortTable('business-rules-table', 2)">State <span class="sort-indicator"></span></th>
459
+ <th onclick="sortTable('business-rules-table', 3)">Scope <span class="sort-indicator"></span></th>
460
+ <th onclick="sortTable('business-rules-table', 4)">Conditions <span class="sort-indicator"></span></th>
461
+ <th onclick="sortTable('business-rules-table', 5)">Actions <span class="sort-indicator"></span></th>
462
+ </tr>
463
+ </thead>
464
+ <tbody>
465
+ ${s}
466
+ </tbody>
467
+ </table>
468
+ </div>
469
+ </section>`}htmlClassicWorkflowsTable(e){if(e.length===0)return`<section id="classic-workflows" class="content-section">
470
+ <h2>Classic Workflows (Deprecated)</h2>
471
+ <div class="empty-state">No classic workflows found</div>
472
+ </section>`;const s=e.map(t=>{var o,r;const a=t.entityDisplayName||t.entity,n=((o=t.migrationRecommendation)==null?void 0:o.complexity)||"Unknown",i=((r=t.migrationRecommendation)==null?void 0:r.effort)||"Unknown";return`<tr>
473
+ <td>${this.escapeHtml(t.name)}</td>
474
+ <td>${this.escapeHtml(a)}</td>
475
+ <td><span class="badge badge-${t.state==="Active"?"success":t.state==="Draft"?"warning":"error"}">${t.state}</span></td>
476
+ <td>${this.escapeHtml(t.modeName)}</td>
477
+ <td><span class="badge badge-${n==="Critical"?"error":n==="High"?"warning":"info"}">${n}</span></td>
478
+ <td>${this.escapeHtml(i)}</td>
479
+ </tr>`}).join(`
480
+ `);return`<section id="classic-workflows" class="content-section">
481
+ <h2>Classic Workflows - Migration Required (${e.length})</h2>
482
+ <div class="alert alert-warning">
483
+ <strong>⚠️ Migration Required:</strong> Classic workflows are deprecated and will be removed. Please migrate to Power Automate cloud flows.
484
+ </div>
485
+ <div class="table-container">
486
+ <table class="data-table sortable" id="classic-workflows-table">
487
+ <thead>
488
+ <tr>
489
+ <th onclick="sortTable('classic-workflows-table', 0)">Name <span class="sort-indicator"></span></th>
490
+ <th onclick="sortTable('classic-workflows-table', 1)">Entity <span class="sort-indicator"></span></th>
491
+ <th onclick="sortTable('classic-workflows-table', 2)">State <span class="sort-indicator"></span></th>
492
+ <th onclick="sortTable('classic-workflows-table', 3)">Mode <span class="sort-indicator"></span></th>
493
+ <th onclick="sortTable('classic-workflows-table', 4)">Complexity <span class="sort-indicator"></span></th>
494
+ <th onclick="sortTable('classic-workflows-table', 5)">Effort <span class="sort-indicator"></span></th>
495
+ </tr>
496
+ </thead>
497
+ <tbody>
498
+ ${s}
499
+ </tbody>
500
+ </table>
501
+ </div>
502
+ </section>`}htmlBusinessProcessFlowsTable(e){if(e.length===0)return`<section id="business-process-flows" class="content-section">
503
+ <h2>Business Process Flows</h2>
504
+ <div class="empty-state">No business process flows found</div>
505
+ </section>`;const s=e.map(t=>{var o;const a=t.primaryEntityDisplayName||t.primaryEntity,n=((o=t.definition.stages)==null?void 0:o.length)||0,i=t.definition.crossEntityFlow;return`<tr>
506
+ <td>${this.escapeHtml(t.name)}</td>
507
+ <td>${this.escapeHtml(a)}</td>
508
+ <td><span class="badge badge-${t.state==="Active"?"success":"warning"}">${t.state}</span></td>
509
+ <td>${n}</td>
510
+ <td>${t.definition.totalSteps}</td>
511
+ <td>${i?'<span class="badge badge-info">Yes</span>':"No"}</td>
512
+ </tr>`}).join(`
513
+ `);return`<section id="business-process-flows" class="content-section">
514
+ <h2>Business Process Flows (${e.length})</h2>
515
+ <div class="table-container">
516
+ <table class="data-table sortable" id="bpfs-table">
517
+ <thead>
518
+ <tr>
519
+ <th onclick="sortTable('bpfs-table', 0)">Name <span class="sort-indicator"></span></th>
520
+ <th onclick="sortTable('bpfs-table', 1)">Primary Entity <span class="sort-indicator"></span></th>
521
+ <th onclick="sortTable('bpfs-table', 2)">State <span class="sort-indicator"></span></th>
522
+ <th onclick="sortTable('bpfs-table', 3)">Stages <span class="sort-indicator"></span></th>
523
+ <th onclick="sortTable('bpfs-table', 4)">Steps <span class="sort-indicator"></span></th>
524
+ <th>Cross-Entity</th>
525
+ </tr>
526
+ </thead>
527
+ <tbody>
528
+ ${s}
529
+ </tbody>
530
+ </table>
531
+ </div>
532
+ </section>`}htmlWebResourcesTable(e){if(e.length===0)return`<section id="web-resources" class="content-section">
533
+ <h2>Web Resources</h2>
534
+ <div class="empty-state">No web resources found</div>
535
+ </section>`;const s=e.map(t=>{const a=(t.contentSize/1024).toFixed(2),n=t.hasExternalCalls,i=t.isDeprecated;return`<tr>
536
+ <td>${this.escapeHtml(t.name)}</td>
537
+ <td>${this.escapeHtml(t.displayName)}</td>
538
+ <td>${this.escapeHtml(t.typeName)}</td>
539
+ <td>${a} KB</td>
540
+ <td>${n?'<span class="badge badge-warning">Yes</span>':"No"}</td>
541
+ <td>${i?'<span class="badge badge-error">Yes</span>':"No"}</td>
542
+ </tr>`}).join(`
543
+ `);return`<section id="web-resources" class="content-section">
544
+ <h2>Web Resources (${e.length})</h2>
545
+ <div class="table-container">
546
+ <table class="data-table sortable" id="web-resources-table">
547
+ <thead>
548
+ <tr>
549
+ <th onclick="sortTable('web-resources-table', 0)">Name <span class="sort-indicator"></span></th>
550
+ <th onclick="sortTable('web-resources-table', 1)">Display Name <span class="sort-indicator"></span></th>
551
+ <th onclick="sortTable('web-resources-table', 2)">Type <span class="sort-indicator"></span></th>
552
+ <th onclick="sortTable('web-resources-table', 3)">Size <span class="sort-indicator"></span></th>
553
+ <th>External Calls</th>
554
+ <th>Deprecated</th>
555
+ </tr>
556
+ </thead>
557
+ <tbody>
558
+ ${s}
559
+ </tbody>
560
+ </table>
561
+ </div>
562
+ </section>`}htmlCustomAPIsTable(e){if(e.length===0)return`<section id="custom-apis" class="content-section">
563
+ <h2>Custom APIs</h2>
564
+ <div class="empty-state">No custom APIs found</div>
565
+ </section>`;const s=e.map(t=>{var r,c;const a=t.isFunction?"Function":"Action",n=t.bindingType,i=((r=t.requestParameters)==null?void 0:r.length)||0,o=((c=t.responseProperties)==null?void 0:c.length)||0;return`<tr>
566
+ <td>${this.escapeHtml(t.uniqueName)}</td>
567
+ <td>${this.escapeHtml(t.displayName)}</td>
568
+ <td><span class="badge badge-${t.isFunction?"info":"primary"}">${a}</span></td>
569
+ <td>${this.escapeHtml(n)}</td>
570
+ <td>${i}</td>
571
+ <td>${o}</td>
572
+ </tr>`}).join(`
573
+ `);return`<section id="custom-apis" class="content-section">
574
+ <h2>Custom APIs (${e.length})</h2>
575
+ <div class="table-container">
576
+ <table class="data-table sortable" id="custom-apis-table">
577
+ <thead>
578
+ <tr>
579
+ <th onclick="sortTable('custom-apis-table', 0)">Unique Name <span class="sort-indicator"></span></th>
580
+ <th onclick="sortTable('custom-apis-table', 1)">Display Name <span class="sort-indicator"></span></th>
581
+ <th onclick="sortTable('custom-apis-table', 2)">Type <span class="sort-indicator"></span></th>
582
+ <th onclick="sortTable('custom-apis-table', 3)">Binding <span class="sort-indicator"></span></th>
583
+ <th onclick="sortTable('custom-apis-table', 4)">Parameters <span class="sort-indicator"></span></th>
584
+ <th onclick="sortTable('custom-apis-table', 5)">Responses <span class="sort-indicator"></span></th>
585
+ </tr>
586
+ </thead>
587
+ <tbody>
588
+ ${s}
589
+ </tbody>
590
+ </table>
591
+ </div>
592
+ </section>`}htmlEnvironmentVariablesTable(e){if(e.length===0)return`<section id="environment-variables" class="content-section">
593
+ <h2>Environment Variables</h2>
594
+ <div class="empty-state">No environment variables found</div>
595
+ </section>`;const s=e.map(t=>{const a=!!t.currentValue,n=t.isRequired;return`<tr>
596
+ <td>${this.escapeHtml(t.schemaName)}</td>
597
+ <td>${this.escapeHtml(t.displayName)}</td>
598
+ <td>${this.escapeHtml(t.typeName)}</td>
599
+ <td>${n?'<span class="badge badge-error">Required</span>':"Optional"}</td>
600
+ <td>${a?'<span class="badge badge-success">Set</span>':'<span class="badge badge-warning">Not Set</span>'}</td>
601
+ </tr>`}).join(`
602
+ `);return`<section id="environment-variables" class="content-section">
603
+ <h2>Environment Variables (${e.length})</h2>
604
+ <div class="table-container">
605
+ <table class="data-table sortable" id="env-vars-table">
606
+ <thead>
607
+ <tr>
608
+ <th onclick="sortTable('env-vars-table', 0)">Schema Name <span class="sort-indicator"></span></th>
609
+ <th onclick="sortTable('env-vars-table', 1)">Display Name <span class="sort-indicator"></span></th>
610
+ <th onclick="sortTable('env-vars-table', 2)">Type <span class="sort-indicator"></span></th>
611
+ <th onclick="sortTable('env-vars-table', 3)">Required <span class="sort-indicator"></span></th>
612
+ <th>Value Status</th>
613
+ </tr>
614
+ </thead>
615
+ <tbody>
616
+ ${s}
617
+ </tbody>
618
+ </table>
619
+ </div>
620
+ </section>`}htmlConnectionReferencesTable(e){if(e.length===0)return`<section id="connection-references" class="content-section">
621
+ <h2>Connection References</h2>
622
+ <div class="empty-state">No connection references found</div>
623
+ </section>`;const s=e.map(t=>{const a=t.connectorDisplayName||"Unknown",n=!!t.connectionId;return`<tr>
624
+ <td>${this.escapeHtml(t.name)}</td>
625
+ <td>${this.escapeHtml(t.displayName)}</td>
626
+ <td>${this.escapeHtml(a)}</td>
627
+ <td>${n?'<span class="badge badge-success">Connected</span>':'<span class="badge badge-error">Not Connected</span>'}</td>
628
+ </tr>`}).join(`
629
+ `);return`<section id="connection-references" class="content-section">
630
+ <h2>Connection References (${e.length})</h2>
631
+ <div class="table-container">
632
+ <table class="data-table sortable" id="conn-refs-table">
633
+ <thead>
634
+ <tr>
635
+ <th onclick="sortTable('conn-refs-table', 0)">Name <span class="sort-indicator"></span></th>
636
+ <th onclick="sortTable('conn-refs-table', 1)">Display Name <span class="sort-indicator"></span></th>
637
+ <th onclick="sortTable('conn-refs-table', 2)">Connector <span class="sort-indicator"></span></th>
638
+ <th>Status</th>
639
+ </tr>
640
+ </thead>
641
+ <tbody>
642
+ ${s}
643
+ </tbody>
644
+ </table>
645
+ </div>
646
+ </section>`}htmlExternalDependenciesSection(e){if(!e||e.length===0)return`<section id="external-dependencies" class="content-section">
647
+ <h2>External Dependencies</h2>
648
+ <div class="empty-state">No external dependencies detected</div>
649
+ </section>`;const s=e.map(t=>{const a=t.riskLevel==="Trusted"?"success":t.riskLevel==="Known"?"warning":"error",n=t.riskFactors.map(i=>i.factor).join(", ")||"None";return`<tr>
650
+ <td>${this.escapeHtml(t.domain)}</td>
651
+ <td>${this.escapeHtml(t.protocol.toUpperCase())}</td>
652
+ <td><span class="badge badge-${a}">${t.riskLevel}</span></td>
653
+ <td>${t.callCount}</td>
654
+ <td>${this.escapeHtml(n)}</td>
655
+ </tr>`}).join(`
656
+ `);return`<section id="external-dependencies" class="content-section">
657
+ <h2>External Dependencies (${e.length})</h2>
658
+ <div class="alert alert-info">
659
+ <strong>ℹ️ Note:</strong> External API calls can introduce security risks and performance concerns. Review each endpoint carefully.
660
+ </div>
661
+ <div class="table-container">
662
+ <table class="data-table sortable" id="external-deps-table">
663
+ <thead>
664
+ <tr>
665
+ <th onclick="sortTable('external-deps-table', 0)">Domain <span class="sort-indicator"></span></th>
666
+ <th onclick="sortTable('external-deps-table', 1)">Protocol <span class="sort-indicator"></span></th>
667
+ <th onclick="sortTable('external-deps-table', 2)">Risk Level <span class="sort-indicator"></span></th>
668
+ <th onclick="sortTable('external-deps-table', 3)">Calls <span class="sort-indicator"></span></th>
669
+ <th>Risk Factors</th>
670
+ </tr>
671
+ </thead>
672
+ <tbody>
673
+ ${s}
674
+ </tbody>
675
+ </table>
676
+ </div>
677
+ </section>`}htmlCrossEntitySection(e){if(!e||e.length===0)return`<section id="cross-entity" class="content-section">
678
+ <h2>Cross-Entity Automation</h2>
679
+ <div class="empty-state">
680
+ <strong>Note:</strong> Cross-entity automation analysis is coming in a future update.
681
+ </div>
682
+ </section>`;const s=e.map(t=>`<tr>
683
+ <td>${this.escapeHtml(t.sourceEntityDisplayName)}</td>
684
+ <td>${this.escapeHtml(t.targetEntityDisplayName)}</td>
685
+ <td>${this.escapeHtml(t.automationType)}</td>
686
+ <td>${this.escapeHtml(t.automationName)}</td>
687
+ <td>${this.escapeHtml(t.operation)}</td>
688
+ <td>${t.isAsynchronous?"Async":"Sync"}</td>
689
+ </tr>`).join(`
690
+ `);return`<section id="cross-entity" class="content-section">
691
+ <h2>Cross-Entity Automation (${e.length})</h2>
692
+ <p class="section-description">Automation that operates on multiple entities (e.g., when Contact changes, update related Account)</p>
693
+ <div class="table-container">
694
+ <table class="data-table sortable" id="cross-entity-table">
695
+ <thead>
696
+ <tr>
697
+ <th onclick="sortTable('cross-entity-table', 0)">Source Entity <span class="sort-indicator"></span></th>
698
+ <th onclick="sortTable('cross-entity-table', 1)">Target Entity <span class="sort-indicator"></span></th>
699
+ <th onclick="sortTable('cross-entity-table', 2)">Type <span class="sort-indicator"></span></th>
700
+ <th onclick="sortTable('cross-entity-table', 3)">Name <span class="sort-indicator"></span></th>
701
+ <th onclick="sortTable('cross-entity-table', 4)">Operation <span class="sort-indicator"></span></th>
702
+ <th>Mode</th>
703
+ </tr>
704
+ </thead>
705
+ <tbody>
706
+ ${s}
707
+ </tbody>
708
+ </table>
709
+ </div>
710
+ </section>`}htmlFooter(){return`<footer class="report-footer" role="contentinfo">
711
+ <p>Generated by <strong>Power Platform Solution Blueprint (PPSB)</strong></p>
712
+ <p>For PPTB Desktop | <a href="https://powerplatformtoolbox.com" target="_blank">powerplatformtoolbox.com</a></p>
713
+ </footer>`}htmlScripts(){return`<script>
714
+ ${this.embeddedJavaScript()}
715
+ <\/script>`}embeddedCSS(){return` /* Base styles */
716
+ * {
717
+ box-sizing: border-box;
718
+ margin: 0;
719
+ padding: 0;
720
+ }
721
+
722
+ body {
723
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
724
+ line-height: 1.6;
725
+ color: #242424;
726
+ background-color: #fafafa;
727
+ margin: 0;
728
+ padding: 0;
729
+ }
730
+
731
+ /* Sidebar navigation */
732
+ .sidebar {
733
+ position: fixed;
734
+ top: 0;
735
+ left: 0;
736
+ width: 250px;
737
+ height: 100vh;
738
+ background: #323130;
739
+ color: white;
740
+ overflow-y: auto;
741
+ z-index: 1000;
742
+ padding: 20px 0;
743
+ }
744
+
745
+ .sidebar-header {
746
+ padding: 0 20px 20px;
747
+ border-bottom: 1px solid #484644;
748
+ }
749
+
750
+ .sidebar-header h3 {
751
+ color: white;
752
+ font-size: 1.2rem;
753
+ margin-bottom: 10px;
754
+ }
755
+
756
+ .nav-toggle {
757
+ display: none;
758
+ background: transparent;
759
+ border: 1px solid white;
760
+ color: white;
761
+ padding: 5px 10px;
762
+ cursor: pointer;
763
+ border-radius: 4px;
764
+ }
765
+
766
+ .nav-links {
767
+ list-style: none;
768
+ padding: 10px 0;
769
+ }
770
+
771
+ .nav-links li {
772
+ margin: 0;
773
+ }
774
+
775
+ .nav-links a {
776
+ display: block;
777
+ padding: 10px 20px;
778
+ color: #e1dfdd;
779
+ text-decoration: none;
780
+ transition: background-color 0.2s, color 0.2s;
781
+ }
782
+
783
+ .nav-links a:hover {
784
+ background-color: #484644;
785
+ color: white;
786
+ }
787
+
788
+ .nav-footer {
789
+ padding: 20px;
790
+ border-top: 1px solid #484644;
791
+ margin-top: 20px;
792
+ }
793
+
794
+ .btn-print {
795
+ width: 100%;
796
+ padding: 10px;
797
+ background: #0078d4;
798
+ color: white;
799
+ border: none;
800
+ border-radius: 4px;
801
+ cursor: pointer;
802
+ font-size: 0.9rem;
803
+ }
804
+
805
+ .btn-print:hover {
806
+ background: #106ebe;
807
+ }
808
+
809
+ /* Main content */
810
+ main {
811
+ margin-left: 250px;
812
+ padding: 30px;
813
+ max-width: 1400px;
814
+ }
815
+
816
+ /* Header */
817
+ .report-header {
818
+ background: white;
819
+ padding: 30px;
820
+ border-radius: 8px;
821
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
822
+ margin-bottom: 30px;
823
+ }
824
+
825
+ .report-header h1 {
826
+ color: #0078d4;
827
+ font-size: 2rem;
828
+ margin-bottom: 20px;
829
+ }
830
+
831
+ .metadata-grid {
832
+ display: grid;
833
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
834
+ gap: 15px;
835
+ }
836
+
837
+ .metadata-item {
838
+ padding: 10px;
839
+ background: #f3f2f1;
840
+ border-radius: 4px;
841
+ }
842
+
843
+ .metadata-label {
844
+ font-weight: 600;
845
+ color: #605e5c;
846
+ display: block;
847
+ font-size: 0.9rem;
848
+ }
849
+
850
+ .metadata-value {
851
+ font-size: 1.1rem;
852
+ color: #242424;
853
+ display: block;
854
+ margin-top: 5px;
855
+ }
856
+
857
+ /* Content sections */
858
+ .content-section {
859
+ background: white;
860
+ padding: 30px;
861
+ border-radius: 8px;
862
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
863
+ margin-bottom: 30px;
864
+ }
865
+
866
+ .content-section h2 {
867
+ color: #323130;
868
+ font-size: 1.75rem;
869
+ margin-bottom: 20px;
870
+ padding-bottom: 10px;
871
+ border-bottom: 2px solid #0078d4;
872
+ }
873
+
874
+ .section-description {
875
+ color: #605e5c;
876
+ margin-bottom: 20px;
877
+ }
878
+
879
+ /* Summary cards */
880
+ .summary-grid {
881
+ display: grid;
882
+ grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
883
+ gap: 20px;
884
+ }
885
+
886
+ .summary-card {
887
+ background: linear-gradient(135deg, #0078d4 0%, #106ebe 100%);
888
+ color: white;
889
+ padding: 20px;
890
+ border-radius: 8px;
891
+ text-align: center;
892
+ box-shadow: 0 2px 8px rgba(0,0,0,0.1);
893
+ }
894
+
895
+ .summary-card.card-warning {
896
+ background: linear-gradient(135deg, #ffb900 0%, #e3008c 100%);
897
+ }
898
+
899
+ .card-number {
900
+ font-size: 2.5rem;
901
+ font-weight: bold;
902
+ margin-bottom: 5px;
903
+ }
904
+
905
+ .card-label {
906
+ font-size: 0.9rem;
907
+ opacity: 0.95;
908
+ }
909
+
910
+ /* ERD */
911
+ .erd-legend {
912
+ background: #f3f2f1;
913
+ padding: 15px;
914
+ border-radius: 4px;
915
+ margin-bottom: 20px;
916
+ }
917
+
918
+ .erd-legend h4 {
919
+ margin-bottom: 10px;
920
+ color: #323130;
921
+ }
922
+
923
+ .legend-items {
924
+ display: flex;
925
+ flex-wrap: wrap;
926
+ gap: 15px;
927
+ }
928
+
929
+ .legend-item {
930
+ display: flex;
931
+ align-items: center;
932
+ gap: 8px;
933
+ }
934
+
935
+ .legend-color {
936
+ width: 20px;
937
+ height: 20px;
938
+ border-radius: 4px;
939
+ border: 1px solid #d1d1d1;
940
+ }
941
+
942
+ .legend-label {
943
+ font-size: 0.9rem;
944
+ }
945
+
946
+ .erd-diagram {
947
+ margin-bottom: 40px;
948
+ }
949
+
950
+ .erd-diagram h3 {
951
+ color: #323130;
952
+ margin-bottom: 10px;
953
+ }
954
+
955
+ .diagram-description {
956
+ color: #605e5c;
957
+ margin-bottom: 15px;
958
+ }
959
+
960
+ .diagram-stats {
961
+ color: #605e5c;
962
+ font-size: 0.9rem;
963
+ margin-top: 10px;
964
+ }
965
+
966
+ /* Accordion */
967
+ .accordion-item {
968
+ border: 1px solid #edebe9;
969
+ border-radius: 4px;
970
+ margin-bottom: 10px;
971
+ overflow: hidden;
972
+ }
973
+
974
+ .accordion-header {
975
+ background: #f3f2f1;
976
+ padding: 15px 20px;
977
+ cursor: pointer;
978
+ display: flex;
979
+ align-items: center;
980
+ gap: 10px;
981
+ transition: background-color 0.2s;
982
+ }
983
+
984
+ .accordion-header:hover {
985
+ background: #edebe9;
986
+ }
987
+
988
+ .accordion-icon {
989
+ font-weight: bold;
990
+ font-size: 1.2rem;
991
+ width: 20px;
992
+ text-align: center;
993
+ color: #0078d4;
994
+ }
995
+
996
+ .accordion-header h3 {
997
+ flex: 1;
998
+ font-size: 1.1rem;
999
+ color: #323130;
1000
+ margin: 0;
1001
+ }
1002
+
1003
+ .entity-badges {
1004
+ display: flex;
1005
+ gap: 8px;
1006
+ }
1007
+
1008
+ .accordion-content {
1009
+ padding: 20px;
1010
+ border-top: 1px solid #edebe9;
1011
+ }
1012
+
1013
+ .entity-details {
1014
+ margin-bottom: 20px;
1015
+ padding: 15px;
1016
+ background: #faf9f8;
1017
+ border-radius: 4px;
1018
+ }
1019
+
1020
+ .entity-details p {
1021
+ margin: 5px 0;
1022
+ color: #323130;
1023
+ }
1024
+
1025
+ .entity-subsection {
1026
+ margin-top: 20px;
1027
+ }
1028
+
1029
+ .entity-subsection h4 {
1030
+ color: #323130;
1031
+ margin-bottom: 10px;
1032
+ font-size: 1rem;
1033
+ }
1034
+
1035
+ /* Entity Tabs */
1036
+ .entity-tabs {
1037
+ margin-top: 15px;
1038
+ }
1039
+
1040
+ .tabs-header {
1041
+ display: flex;
1042
+ gap: 0;
1043
+ border-bottom: 2px solid #edebe9;
1044
+ margin-bottom: 20px;
1045
+ }
1046
+
1047
+ .tab-button {
1048
+ padding: 12px 20px;
1049
+ background: transparent;
1050
+ border: none;
1051
+ border-bottom: 3px solid transparent;
1052
+ cursor: pointer;
1053
+ font-size: 0.95rem;
1054
+ font-weight: 500;
1055
+ color: #605e5c;
1056
+ transition: all 0.2s;
1057
+ }
1058
+
1059
+ .tab-button:hover {
1060
+ color: #323130;
1061
+ background: #faf9f8;
1062
+ }
1063
+
1064
+ .tab-button.active {
1065
+ color: #0078d4;
1066
+ border-bottom-color: #0078d4;
1067
+ font-weight: 600;
1068
+ }
1069
+
1070
+ .tab-content {
1071
+ display: none;
1072
+ }
1073
+
1074
+ .tab-content.active {
1075
+ display: block;
1076
+ }
1077
+
1078
+ /* Entity Overview */
1079
+ .entity-description {
1080
+ padding: 15px;
1081
+ background: #fff3cd;
1082
+ border-left: 4px solid #ffc107;
1083
+ margin-bottom: 20px;
1084
+ border-radius: 4px;
1085
+ color: #323130;
1086
+ }
1087
+
1088
+ .entity-metadata {
1089
+ margin-bottom: 20px;
1090
+ }
1091
+
1092
+ .metadata-table {
1093
+ width: 100%;
1094
+ border-collapse: collapse;
1095
+ }
1096
+
1097
+ .metadata-table th {
1098
+ text-align: left;
1099
+ padding: 8px 12px;
1100
+ font-weight: 600;
1101
+ color: #605e5c;
1102
+ width: 40%;
1103
+ background: #faf9f8;
1104
+ }
1105
+
1106
+ .metadata-table td {
1107
+ padding: 8px 12px;
1108
+ color: #323130;
1109
+ }
1110
+
1111
+ .metadata-table tr {
1112
+ border-bottom: 1px solid #edebe9;
1113
+ }
1114
+
1115
+ .automation-summary {
1116
+ background: #f3f2f1;
1117
+ padding: 15px;
1118
+ border-radius: 4px;
1119
+ }
1120
+
1121
+ .summary-row {
1122
+ display: flex;
1123
+ justify-content: space-between;
1124
+ padding: 8px 0;
1125
+ border-bottom: 1px solid #e1dfdd;
1126
+ }
1127
+
1128
+ .summary-row:last-child {
1129
+ border-bottom: none;
1130
+ }
1131
+
1132
+ .summary-label {
1133
+ font-weight: 500;
1134
+ color: #605e5c;
1135
+ }
1136
+
1137
+ .summary-value {
1138
+ font-weight: 600;
1139
+ color: #0078d4;
1140
+ }
1141
+
1142
+ /* Pipeline Visualization */
1143
+ .pipeline-intro {
1144
+ margin-bottom: 20px;
1145
+ padding: 15px;
1146
+ background: #e7f3ff;
1147
+ border-left: 4px solid #0078d4;
1148
+ border-radius: 4px;
1149
+ }
1150
+
1151
+ .pipeline-message {
1152
+ margin-bottom: 30px;
1153
+ padding: 20px;
1154
+ background: #fafafa;
1155
+ border-radius: 4px;
1156
+ }
1157
+
1158
+ .pipeline-message h4 {
1159
+ color: #323130;
1160
+ margin-bottom: 15px;
1161
+ padding-bottom: 10px;
1162
+ border-bottom: 2px solid #edebe9;
1163
+ }
1164
+
1165
+ .pipeline-message h5 {
1166
+ color: #323130;
1167
+ margin: 20px 0 10px;
1168
+ }
1169
+
1170
+ .pipeline-visual {
1171
+ margin: 20px 0;
1172
+ padding: 15px;
1173
+ background: white;
1174
+ border: 1px solid #edebe9;
1175
+ border-radius: 4px;
1176
+ }
1177
+
1178
+ .pipeline-stage {
1179
+ margin-bottom: 15px;
1180
+ border-left: 4px solid #d1d1d1;
1181
+ padding-left: 15px;
1182
+ }
1183
+
1184
+ .stage-business-rules {
1185
+ border-left-color: #ffc107;
1186
+ }
1187
+
1188
+ .stage-prevalidation {
1189
+ border-left-color: #dc3545;
1190
+ }
1191
+
1192
+ .stage-preoperation {
1193
+ border-left-color: #fd7e14;
1194
+ }
1195
+
1196
+ .stage-mainoperation {
1197
+ border-left-color: #0078d4;
1198
+ }
1199
+
1200
+ .stage-postoperation {
1201
+ border-left-color: #28a745;
1202
+ }
1203
+
1204
+ .stage-header {
1205
+ font-weight: 600;
1206
+ color: #323130;
1207
+ margin-bottom: 10px;
1208
+ font-size: 0.95rem;
1209
+ }
1210
+
1211
+ .stage-steps {
1212
+ display: flex;
1213
+ flex-direction: column;
1214
+ gap: 8px;
1215
+ }
1216
+
1217
+ .pipeline-step {
1218
+ padding: 10px 15px;
1219
+ background: #fafafa;
1220
+ border-radius: 4px;
1221
+ display: flex;
1222
+ align-items: center;
1223
+ justify-content: space-between;
1224
+ gap: 10px;
1225
+ }
1226
+
1227
+ .step-sync {
1228
+ border-left: 3px solid #dc3545;
1229
+ }
1230
+
1231
+ .step-async {
1232
+ border-left: 3px solid #28a745;
1233
+ }
1234
+
1235
+ .step-active {
1236
+ border-left: 3px solid #28a745;
1237
+ }
1238
+
1239
+ .step-draft {
1240
+ border-left: 3px solid #ffc107;
1241
+ }
1242
+
1243
+ .step-badge {
1244
+ padding: 2px 8px;
1245
+ border-radius: 3px;
1246
+ font-size: 0.75rem;
1247
+ font-weight: 600;
1248
+ white-space: nowrap;
1249
+ }
1250
+
1251
+ .badge-sync {
1252
+ background: #f8d7da;
1253
+ color: #721c24;
1254
+ }
1255
+
1256
+ .badge-async {
1257
+ background: #d4edda;
1258
+ color: #155724;
1259
+ }
1260
+
1261
+ .badge-active {
1262
+ background: #d4edda;
1263
+ color: #155724;
1264
+ }
1265
+
1266
+ .badge-draft {
1267
+ background: #fff3cd;
1268
+ color: #856404;
1269
+ }
1270
+
1271
+ .step-rank {
1272
+ font-size: 0.85rem;
1273
+ color: #605e5c;
1274
+ }
1275
+
1276
+ .info-box {
1277
+ margin: 15px 0;
1278
+ padding: 15px;
1279
+ background: #e7f3ff;
1280
+ border-left: 4px solid #0078d4;
1281
+ border-radius: 4px;
1282
+ }
1283
+
1284
+ .info-box strong {
1285
+ display: block;
1286
+ margin-bottom: 5px;
1287
+ color: #323130;
1288
+ }
1289
+
1290
+ .info-box p {
1291
+ margin: 0;
1292
+ color: #605e5c;
1293
+ }
1294
+
1295
+ .pipeline-table {
1296
+ margin-top: 15px;
1297
+ }
1298
+
1299
+ .relationship-section {
1300
+ margin-top: 15px;
1301
+ }
1302
+
1303
+ .relationship-section h5 {
1304
+ color: #323130;
1305
+ margin-bottom: 10px;
1306
+ font-size: 0.95rem;
1307
+ }
1308
+
1309
+ .table-note {
1310
+ margin-top: 10px;
1311
+ color: #605e5c;
1312
+ font-size: 0.9rem;
1313
+ font-style: italic;
1314
+ }
1315
+
1316
+ /* Tables */
1317
+ .table-container {
1318
+ overflow-x: auto;
1319
+ }
1320
+
1321
+ .data-table {
1322
+ width: 100%;
1323
+ border-collapse: collapse;
1324
+ margin-top: 15px;
1325
+ }
1326
+
1327
+ .data-table thead {
1328
+ background: #f3f2f1;
1329
+ }
1330
+
1331
+ .data-table th {
1332
+ padding: 12px;
1333
+ text-align: left;
1334
+ font-weight: 600;
1335
+ color: #323130;
1336
+ border-bottom: 2px solid #d1d1d1;
1337
+ cursor: pointer;
1338
+ user-select: none;
1339
+ position: relative;
1340
+ }
1341
+
1342
+ .data-table th:hover {
1343
+ background: #edebe9;
1344
+ }
1345
+
1346
+ .sort-indicator {
1347
+ margin-left: 5px;
1348
+ color: #605e5c;
1349
+ font-size: 0.8rem;
1350
+ }
1351
+
1352
+ .data-table td {
1353
+ padding: 12px;
1354
+ border-bottom: 1px solid #edebe9;
1355
+ color: #323130;
1356
+ }
1357
+
1358
+ .data-table tbody tr:hover {
1359
+ background: #faf9f8;
1360
+ }
1361
+
1362
+ .data-table tbody tr:nth-child(even) {
1363
+ background: #f9f9f9;
1364
+ }
1365
+
1366
+ .data-table tbody tr:nth-child(even):hover {
1367
+ background: #f3f2f1;
1368
+ }
1369
+
1370
+ .table-note {
1371
+ margin-top: 10px;
1372
+ color: #605e5c;
1373
+ font-size: 0.9rem;
1374
+ font-style: italic;
1375
+ }
1376
+
1377
+ /* Badges */
1378
+ .badge {
1379
+ display: inline-block;
1380
+ padding: 4px 10px;
1381
+ border-radius: 12px;
1382
+ font-size: 0.8rem;
1383
+ font-weight: 600;
1384
+ white-space: nowrap;
1385
+ }
1386
+
1387
+ .badge-success {
1388
+ background: #dff6dd;
1389
+ color: #107c10;
1390
+ }
1391
+
1392
+ .badge-warning {
1393
+ background: #fff4ce;
1394
+ color: #8a5100;
1395
+ }
1396
+
1397
+ .badge-error {
1398
+ background: #fde7e9;
1399
+ color: #d13438;
1400
+ }
1401
+
1402
+ .badge-info {
1403
+ background: #cfe4f7;
1404
+ color: #004578;
1405
+ }
1406
+
1407
+ .badge-primary {
1408
+ background: #deecf9;
1409
+ color: #0078d4;
1410
+ }
1411
+
1412
+ /* Security-specific styles */
1413
+ .profile-badge {
1414
+ display: inline-block;
1415
+ padding: 6px 12px;
1416
+ margin: 4px;
1417
+ background: #f3f2f1;
1418
+ border: 1px solid #d2d0ce;
1419
+ border-radius: 4px;
1420
+ font-size: 0.85rem;
1421
+ }
1422
+
1423
+ .profile-badge .permissions {
1424
+ color: #0078d4;
1425
+ font-weight: 600;
1426
+ margin-left: 4px;
1427
+ }
1428
+
1429
+ .legend {
1430
+ padding: 12px;
1431
+ background: #faf9f8;
1432
+ border-left: 3px solid #0078d4;
1433
+ border-radius: 4px;
1434
+ font-size: 0.9rem;
1435
+ color: #605e5c;
1436
+ margin-top: 10px;
1437
+ }
1438
+
1439
+ .center {
1440
+ text-align: center;
1441
+ }
1442
+
1443
+ /* Alerts */
1444
+ .alert {
1445
+ padding: 15px 20px;
1446
+ border-radius: 4px;
1447
+ margin-bottom: 20px;
1448
+ }
1449
+
1450
+ .alert-warning {
1451
+ background: #fff4ce;
1452
+ border-left: 4px solid #ffb900;
1453
+ color: #3d2e00;
1454
+ }
1455
+
1456
+ .alert-info {
1457
+ background: #deecf9;
1458
+ border-left: 4px solid #0078d4;
1459
+ color: #004578;
1460
+ }
1461
+
1462
+ .alert strong {
1463
+ display: block;
1464
+ margin-bottom: 5px;
1465
+ }
1466
+
1467
+ /* Empty state */
1468
+ .empty-state {
1469
+ text-align: center;
1470
+ padding: 40px;
1471
+ color: #605e5c;
1472
+ font-style: italic;
1473
+ }
1474
+
1475
+ /* Footer */
1476
+ .report-footer {
1477
+ text-align: center;
1478
+ padding: 30px;
1479
+ color: #605e5c;
1480
+ font-size: 0.9rem;
1481
+ margin-top: 40px;
1482
+ border-top: 1px solid #edebe9;
1483
+ }
1484
+
1485
+ .report-footer a {
1486
+ color: #0078d4;
1487
+ text-decoration: none;
1488
+ }
1489
+
1490
+ .report-footer a:hover {
1491
+ text-decoration: underline;
1492
+ }
1493
+
1494
+ /* Responsive */
1495
+ @media (max-width: 768px) {
1496
+ .sidebar {
1497
+ transform: translateX(-100%);
1498
+ transition: transform 0.3s;
1499
+ }
1500
+
1501
+ .sidebar.open {
1502
+ transform: translateX(0);
1503
+ }
1504
+
1505
+ .nav-toggle {
1506
+ display: inline-block;
1507
+ }
1508
+
1509
+ main {
1510
+ margin-left: 0;
1511
+ padding: 15px;
1512
+ }
1513
+
1514
+ .metadata-grid {
1515
+ grid-template-columns: 1fr;
1516
+ }
1517
+
1518
+ .summary-grid {
1519
+ grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
1520
+ }
1521
+ }
1522
+
1523
+ /* Print styles */
1524
+ @media print {
1525
+ .sidebar,
1526
+ .nav-toggle,
1527
+ .btn-print {
1528
+ display: none !important;
1529
+ }
1530
+
1531
+ main {
1532
+ margin-left: 0;
1533
+ padding: 0;
1534
+ }
1535
+
1536
+ .content-section {
1537
+ page-break-inside: avoid;
1538
+ box-shadow: none;
1539
+ }
1540
+
1541
+ .accordion-content {
1542
+ display: block !important;
1543
+ }
1544
+
1545
+ .accordion-icon {
1546
+ display: none;
1547
+ }
1548
+
1549
+ body {
1550
+ background: white;
1551
+ }
1552
+ }`}embeddedJavaScript(){return` // Initialize Mermaid
1553
+ mermaid.initialize({
1554
+ startOnLoad: true,
1555
+ theme: 'default',
1556
+ securityLevel: 'loose',
1557
+ flowchart: {
1558
+ useMaxWidth: true,
1559
+ htmlLabels: true
1560
+ }
1561
+ });
1562
+
1563
+ // Accordion toggle
1564
+ function toggleAccordion(id) {
1565
+ const content = document.getElementById(id);
1566
+ const icon = document.getElementById('icon-' + id);
1567
+
1568
+ if (content.style.display === 'none' || content.style.display === '') {
1569
+ content.style.display = 'block';
1570
+ icon.textContent = '−';
1571
+ } else {
1572
+ content.style.display = 'none';
1573
+ icon.textContent = '+';
1574
+ }
1575
+ }
1576
+
1577
+ // Table sorting
1578
+ function sortTable(tableId, columnIndex) {
1579
+ const table = document.getElementById(tableId);
1580
+ const tbody = table.querySelector('tbody');
1581
+ const rows = Array.from(tbody.querySelectorAll('tr'));
1582
+ const header = table.querySelectorAll('th')[columnIndex];
1583
+ const isAscending = header.classList.contains('sort-asc');
1584
+
1585
+ // Clear all sort indicators
1586
+ table.querySelectorAll('th').forEach(th => {
1587
+ th.classList.remove('sort-asc', 'sort-desc');
1588
+ const indicator = th.querySelector('.sort-indicator');
1589
+ if (indicator) indicator.textContent = '';
1590
+ });
1591
+
1592
+ // Sort rows
1593
+ rows.sort((a, b) => {
1594
+ const aVal = a.cells[columnIndex].textContent.trim();
1595
+ const bVal = b.cells[columnIndex].textContent.trim();
1596
+
1597
+ // Try to parse as number
1598
+ const aNum = parseFloat(aVal.replace(/[^0-9.-]/g, ''));
1599
+ const bNum = parseFloat(bVal.replace(/[^0-9.-]/g, ''));
1600
+
1601
+ if (!isNaN(aNum) && !isNaN(bNum)) {
1602
+ return isAscending ? bNum - aNum : aNum - bNum;
1603
+ }
1604
+
1605
+ // String comparison
1606
+ return isAscending ? bVal.localeCompare(aVal) : aVal.localeCompare(bVal);
1607
+ });
1608
+
1609
+ // Update DOM
1610
+ rows.forEach(row => tbody.appendChild(row));
1611
+
1612
+ // Update sort indicator
1613
+ if (isAscending) {
1614
+ header.classList.add('sort-desc');
1615
+ header.querySelector('.sort-indicator').textContent = '▼';
1616
+ } else {
1617
+ header.classList.add('sort-asc');
1618
+ header.querySelector('.sort-indicator').textContent = '▲';
1619
+ }
1620
+ }
1621
+
1622
+ // Smooth scroll for navigation
1623
+ document.querySelectorAll('.nav-links a').forEach(link => {
1624
+ link.addEventListener('click', function(e) {
1625
+ e.preventDefault();
1626
+ const targetId = this.getAttribute('href').substring(1);
1627
+ const targetElement = document.getElementById(targetId);
1628
+
1629
+ if (targetElement) {
1630
+ targetElement.scrollIntoView({
1631
+ behavior: 'smooth',
1632
+ block: 'start'
1633
+ });
1634
+ }
1635
+ });
1636
+ });
1637
+
1638
+ // Mobile navigation toggle
1639
+ const navToggle = document.getElementById('navToggle');
1640
+ const sidebar = document.getElementById('sidebar');
1641
+
1642
+ if (navToggle && sidebar) {
1643
+ navToggle.addEventListener('click', function() {
1644
+ sidebar.classList.toggle('open');
1645
+ });
1646
+
1647
+ // Close sidebar when clicking outside on mobile
1648
+ document.addEventListener('click', function(e) {
1649
+ if (window.innerWidth <= 768) {
1650
+ if (!sidebar.contains(e.target) && !navToggle.contains(e.target)) {
1651
+ sidebar.classList.remove('open');
1652
+ }
1653
+ }
1654
+ });
1655
+ }
1656
+
1657
+ // Entity tab switching
1658
+ function switchEntityTab(entityId, tabName) {
1659
+ // Hide all tab contents for this entity
1660
+ const allTabContents = document.querySelectorAll('[id^="' + entityId + '-"]');
1661
+ allTabContents.forEach(tab => {
1662
+ tab.classList.remove('active');
1663
+ });
1664
+
1665
+ // Remove active class from all tab buttons in this entity
1666
+ const entityAccordion = document.getElementById(entityId);
1667
+ if (entityAccordion) {
1668
+ const tabButtons = entityAccordion.parentElement.querySelectorAll('.tab-button');
1669
+ tabButtons.forEach(btn => {
1670
+ btn.classList.remove('active');
1671
+ });
1672
+ }
1673
+
1674
+ // Show selected tab content
1675
+ const selectedTab = document.getElementById(entityId + '-' + tabName);
1676
+ if (selectedTab) {
1677
+ selectedTab.classList.add('active');
1678
+ }
1679
+
1680
+ // Add active class to clicked button
1681
+ event.target.classList.add('active');
1682
+ }
1683
+
1684
+ // Security tab switching
1685
+ function switchTab(sectionId, tabName) {
1686
+ // Hide all tab contents in this section
1687
+ const section = document.getElementById(sectionId);
1688
+ if (section) {
1689
+ const allTabs = section.querySelectorAll('.tab-content');
1690
+ allTabs.forEach(tab => {
1691
+ tab.classList.remove('active');
1692
+ });
1693
+
1694
+ // Remove active class from all tab buttons in this section
1695
+ const tabButtons = section.querySelectorAll('.tab-button');
1696
+ tabButtons.forEach(btn => {
1697
+ btn.classList.remove('active');
1698
+ });
1699
+
1700
+ // Show selected tab content
1701
+ const selectedTab = document.getElementById(sectionId + '-' + tabName);
1702
+ if (selectedTab) {
1703
+ selectedTab.classList.add('active');
1704
+ }
1705
+
1706
+ // Add active class to clicked button
1707
+ event.target.classList.add('active');
1708
+ }
1709
+ }`}htmlSecuritySection(e,s,t,a){if(!e&&!s&&!t&&!a||!(e!=null&&e.length)&&!(s!=null&&s.length)&&!(t!=null&&t.length)&&!(a!=null&&a.length))return"";let n=`
1710
+ <section id="security" class="content-section">
1711
+ <h2 class="section-title">🔒 Security</h2>
1712
+ <p class="section-description">Security roles and field security profiles in the selected solution(s).</p>
1713
+
1714
+ <div class="tabs-container">
1715
+ <div class="tabs">`;const i=e&&e.length>0,o=s&&s.length>0,r=t&&t.length>0,c=a&&a.length>0,l=i?"roles":o?"profiles":r?"masking":"columnsecurity";return i&&(n+=`<button class="tab-button active" onclick="switchTab('security', 'roles')">Security Roles (${e.length})</button>`),o&&(n+=`<button class="tab-button${l==="profiles"?" active":""}" onclick="switchTab('security', 'profiles')">Field Security Profiles (${s.length})</button>`),r&&(n+=`<button class="tab-button${l==="masking"?" active":""}" onclick="switchTab('security', 'masking')">Attribute Masking (${t.length})</button>`),c&&(n+=`<button class="tab-button${l==="columnsecurity"?" active":""}" onclick="switchTab('security', 'columnsecurity')">Column Security (${a.length})</button>`),n+="</div>",e&&e.length>0&&(n+=`
1716
+ <div class="tab-content${l==="roles"?" active":""}" id="security-roles">
1717
+ <h3>Security Roles</h3>
1718
+
1719
+ <div class="subsection">
1720
+ <h4>Special Permissions Matrix</h4>
1721
+ <p>This table shows which security roles have special/miscellaneous permissions.</p>
1722
+ ${this.generateSpecialPermissionsTable(e)}
1723
+ </div>
1724
+
1725
+ <div class="subsection">
1726
+ <h4>Role Details</h4>
1727
+ ${this.generateSecurityRolesAccordion(e)}
1728
+ </div>
1729
+ </div>`),s&&s.length>0&&(n+=`
1730
+ <div class="tab-content${l==="profiles"?" active":""}" id="security-profiles">
1731
+ <h3>Field Security Profiles</h3>
1732
+ <p>Field security profiles control who can read, create, or update specific secured fields.</p>
1733
+ ${this.generateFieldSecurityProfilesTable(s)}
1734
+ <p class="legend"><strong>Note:</strong> Field-level permissions for specific entities are documented in each entity's schema tab.</p>
1735
+ </div>`),t&&t.length>0&&(n+=`
1736
+ <div class="tab-content${l==="masking"?" active":""}" id="security-masking">
1737
+ <h3>Attribute Masking Rules</h3>
1738
+ <p>Attribute masking rules control how sensitive data is masked when displayed to users without appropriate permissions.</p>
1739
+ ${this.generateAttributeMaskingTable(t)}
1740
+ <p class="legend"><strong>Masking Types:</strong> Full = Entire value masked, Partial = Part of value shown, Email = Email format preserved, Custom = Custom masking format</p>
1741
+ </div>`),a&&a.length>0&&(n+=`
1742
+ <div class="tab-content${l==="columnsecurity"?" active":""}" id="security-columnsecurity">
1743
+ <h3>Column Security Profiles</h3>
1744
+ <p>Column security profiles define which users can access specific secured columns across entities.</p>
1745
+ ${this.generateColumnSecurityTable(a)}
1746
+ <p class="legend"><strong>Note:</strong> Column-level permissions control create, read, and update access to secured fields.</p>
1747
+ </div>`),n+=`
1748
+ </div>
1749
+ </section>`,n}generateSpecialPermissionsTable(e){const s=["documentGeneration","dynamics365ForMobile","exportToExcel","goOfflineInOutlook","mailMerge","print","syncToOutlook","useDynamics365AppForOutlook","activateRealtimeProcesses","executeWorkflowJob","runFlows"];let t=`
1750
+ <table class="data-table">
1751
+ <thead>
1752
+ <tr>
1753
+ <th>Role Name</th>
1754
+ <th>Business Unit</th>`;for(const a of s)t+=`<th>${this.formatSpecialPermissionName(a)}</th>`;t+=`
1755
+ </tr>
1756
+ </thead>
1757
+ <tbody>`;for(const a of e){t+=`
1758
+ <tr>
1759
+ <td><strong>${this.escapeHtml(a.name)}</strong></td>
1760
+ <td>${this.escapeHtml(a.businessunitname||"Unknown")}</td>`;for(const n of s)t+=`<td class="center">${a.specialPermissions[n]?"✓":""}</td>`;t+="</tr>"}return t+=`
1761
+ </tbody>
1762
+ </table>`,t}generateSecurityRolesAccordion(e){let s='<div class="accordion">';for(let t=0;t<e.length;t++){const a=e[t];s+=`
1763
+ <div class="accordion-item">
1764
+ <div class="accordion-header" onclick="toggleAccordion('role-${t}')">
1765
+ <span class="accordion-icon" id="icon-role-${t}">+</span>
1766
+ <div class="accordion-title">
1767
+ <strong>${this.escapeHtml(a.name)}</strong>
1768
+ <span class="badge">${a.totalEntities} entities</span>
1769
+ ${a.hasSystemAdminPrivileges?'<span class="badge badge-warning">System Admin</span>':""}
1770
+ ${a.ismanaged?'<span class="badge badge-info">Managed</span>':""}
1771
+ </div>
1772
+ </div>
1773
+ <div class="accordion-content" id="role-${t}" style="display: none;">
1774
+ <p><strong>Business Unit:</strong> ${this.escapeHtml(a.businessunitname||"Unknown")}</p>
1775
+ ${a.description?`<p><strong>Description:</strong> ${this.escapeHtml(a.description)}</p>`:""}
1776
+
1777
+ <h5>Entity Permissions</h5>
1778
+ ${this.generateEntityPermissionsTable(a.entityPermissions)}
1779
+ </div>
1780
+ </div>`}return s+="</div>",s}generateEntityPermissionsTable(e){if(e.length===0)return'<p class="empty-state">No entity permissions defined</p>';let s=`
1781
+ <table class="data-table">
1782
+ <thead>
1783
+ <tr>
1784
+ <th>Entity</th>
1785
+ <th>Create</th>
1786
+ <th>Read</th>
1787
+ <th>Write</th>
1788
+ <th>Delete</th>
1789
+ <th>Append</th>
1790
+ <th>AppendTo</th>
1791
+ <th>Assign</th>
1792
+ <th>Share</th>
1793
+ </tr>
1794
+ </thead>
1795
+ <tbody>`;for(const t of e){if(t.privileges.length===0)continue;const a=new Map(t.privileges.map(n=>[n.type,n]));s+=`
1796
+ <tr>
1797
+ <td><strong>${this.escapeHtml(t.entityLogicalName)}</strong></td>`;for(const n of["Create","Read","Write","Delete","Append","AppendTo","Assign","Share"]){const i=a.get(n);s+=`<td class="center">${i?this.escapeHtml(i.depth):""}</td>`}s+="</tr>"}return s+=`
1798
+ </tbody>
1799
+ </table>
1800
+ <p class="legend"><strong>Privilege Depth:</strong> Basic = User, Local = Business Unit, Deep = Parent+Child BU, Global = Organization</p>`,s}generateFieldSecurityProfilesTable(e){let s=`
1801
+ <table class="data-table">
1802
+ <thead>
1803
+ <tr>
1804
+ <th>Profile Name</th>
1805
+ <th>Description</th>
1806
+ </tr>
1807
+ </thead>
1808
+ <tbody>`;for(const t of e)s+=`
1809
+ <tr>
1810
+ <td><strong>${this.escapeHtml(t.name)}</strong></td>
1811
+ <td>${t.description?this.escapeHtml(t.description):"<em>No description</em>"}</td>
1812
+ </tr>`;return s+=`
1813
+ </tbody>
1814
+ </table>`,s}generateAttributeMaskingTable(e){let s=`
1815
+ <table class="data-table">
1816
+ <thead>
1817
+ <tr>
1818
+ <th>Entity</th>
1819
+ <th>Attribute</th>
1820
+ <th>Masking Type</th>
1821
+ <th>Managed</th>
1822
+ </tr>
1823
+ </thead>
1824
+ <tbody>`;for(const t of e){const a=t.maskingtype===1?"Full":t.maskingtype===2?"Partial":t.maskingtype===3?"Email":"Custom";s+=`
1825
+ <tr>
1826
+ <td><strong>${this.escapeHtml(t.entitylogicalname)}</strong></td>
1827
+ <td>${this.escapeHtml(t.attributelogicalname)}</td>
1828
+ <td><span class="badge">${a}</span></td>
1829
+ <td>${t.ismanaged?'<span class="badge">Managed</span>':""}</td>
1830
+ </tr>`}return s+=`
1831
+ </tbody>
1832
+ </table>`,s}generateColumnSecurityTable(e){let s=`
1833
+ <table class="data-table">
1834
+ <thead>
1835
+ <tr>
1836
+ <th>Profile Name</th>
1837
+ <th>Description</th>
1838
+ <th>Managed</th>
1839
+ </tr>
1840
+ </thead>
1841
+ <tbody>`;for(const t of e)s+=`
1842
+ <tr>
1843
+ <td><strong>${this.escapeHtml(t.name)}</strong></td>
1844
+ <td>${t.description?this.escapeHtml(t.description):"<em>No description</em>"}</td>
1845
+ <td>${t.ismanaged?'<span class="badge">Managed</span>':""}</td>
1846
+ </tr>`;return s+=`
1847
+ </tbody>
1848
+ </table>`,s}formatSpecialPermissionName(e){return e.replace(/([A-Z])/g," $1").replace(/^./,s=>s.toUpperCase()).trim()}generateFieldSecuritySection(e){if(!e||e.securedFields.length===0)return"";let s=`
1849
+ <div class="entity-subsection">
1850
+ <h4>🛡️ Field Security (${e.securedFields.length} secured field${e.securedFields.length>1?"s":""})</h4>
1851
+ <p class="subsection-description">The following fields have field-level security permissions:</p>
1852
+ <table class="data-table">
1853
+ <thead>
1854
+ <tr>
1855
+ <th>Field</th>
1856
+ <th>Profiles with Access</th>
1857
+ </tr>
1858
+ </thead>
1859
+ <tbody>`;for(const t of e.securedFields){const a=t.profiles.map(n=>{const i=[];return n.canRead&&i.push("R"),n.canCreate&&i.push("C"),n.canUpdate&&i.push("U"),`<div class="profile-badge">${this.escapeHtml(n.profileName)} <span class="permissions">(${i.join(", ")})</span></div>`}).join("");s+=`
1860
+ <tr>
1861
+ <td><strong>${this.escapeHtml(t.attributeLogicalName)}</strong></td>
1862
+ <td>${a}</td>
1863
+ </tr>`}return s+=`
1864
+ </tbody>
1865
+ </table>
1866
+ <p class="legend"><strong>Permissions:</strong> R = Read, C = Create, U = Update</p>
1867
+ </div>`,s}escapeHtml(e){return(e||"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}}class S{constructor(){v(this,"templates");this.templates=new E}generate(e){const s=this.templates.htmlHead(e),t=this.templates.htmlNavigation(),a=this.templates.htmlHeader(e.metadata),n=this.templates.htmlSummary(e.summary),i=this.templates.htmlErdSection(e.erd),o=this.templates.htmlEntitiesAccordion(e.entities),r=this.templates.htmlPluginsTable(e.plugins),c=this.templates.htmlFlowsTable(e.flows),l=this.templates.htmlBusinessRulesTable(e.businessRules),h=this.templates.htmlClassicWorkflowsTable(e.classicWorkflows),p=this.templates.htmlBusinessProcessFlowsTable(e.businessProcessFlows),b=this.templates.htmlWebResourcesTable(e.webResources),d=this.templates.htmlCustomAPIsTable(e.customAPIs),m=this.templates.htmlEnvironmentVariablesTable(e.environmentVariables),u=this.templates.htmlConnectionReferencesTable(e.connectionReferences),f=this.templates.htmlExternalDependenciesSection(e.externalEndpoints),y=this.templates.htmlCrossEntitySection(e.crossEntityLinks),$=this.templates.htmlSecuritySection(e.securityRoles,e.fieldSecurityProfiles,e.attributeMaskingRules,e.columnSecurityProfiles),x=this.templates.htmlFooter(),w=this.templates.htmlScripts();return`<!DOCTYPE html>
1868
+ <html lang="en">
1869
+ ${s}
1870
+ <body>
1871
+ ${t}
1872
+ <main>
1873
+ ${a}
1874
+ ${n}
1875
+ ${i}
1876
+ ${o}
1877
+ ${r}
1878
+ ${c}
1879
+ ${l}
1880
+ ${h}
1881
+ ${p}
1882
+ ${b}
1883
+ ${d}
1884
+ ${m}
1885
+ ${u}
1886
+ ${$}
1887
+ ${f}
1888
+ ${y}
1889
+ </main>
1890
+ ${x}
1891
+ ${w}
1892
+ </body>
1893
+ </html>`}}export{S as HtmlReporter};
1894
+ //# sourceMappingURL=HtmlReporter-Cu9NwA6b.js.map