@memberjunction/ng-artifacts 5.33.0 → 5.34.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.
- package/dist/lib/components/artifact-viewer-panel.component.d.ts +9 -2
- package/dist/lib/components/artifact-viewer-panel.component.d.ts.map +1 -1
- package/dist/lib/components/artifact-viewer-panel.component.js +26 -10
- package/dist/lib/components/artifact-viewer-panel.component.js.map +1 -1
- package/dist/lib/components/plugins/component-feedback-panel/component-feedback-panel.component.js +2 -2
- package/package.json +16 -16
|
@@ -180,8 +180,15 @@ export declare class ArtifactViewerPanelComponent extends BaseAngularComponent i
|
|
|
180
180
|
onSaveToLibrary(): Promise<void>;
|
|
181
181
|
get excludedCollectionIds(): string[];
|
|
182
182
|
/**
|
|
183
|
-
*
|
|
184
|
-
*
|
|
183
|
+
* Reload the cached set of collections that contain the *current version* of this artifact.
|
|
184
|
+
* Called by the chat-area after the collection picker reports successful saves so the bookmark
|
|
185
|
+
* icon and "already saved" exclusion list refresh without a full artifact reload.
|
|
186
|
+
*/
|
|
187
|
+
ReloadCollectionAssociations(): Promise<void>;
|
|
188
|
+
/**
|
|
189
|
+
* @deprecated Writes are now owned by the picker modal so the dialog can render per-collection
|
|
190
|
+
* progress and partial-failure UI. Kept for any external consumer that still calls it; new code
|
|
191
|
+
* should pass `artifactVersionId` to the picker and listen for its `completed` event.
|
|
185
192
|
*/
|
|
186
193
|
saveToCollections(collectionIds: string[]): Promise<boolean>;
|
|
187
194
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"artifact-viewer-panel.component.d.ts","sourceRoot":"","sources":["../../../src/lib/components/artifact-viewer-panel.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,aAAa,EAA6C,IAAI,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACxL,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,YAAY,EAAY,MAAM,2BAA2B,CAAC;AACnE,OAAO,EAAE,QAAQ,EAA+B,YAAY,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzG,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,gCAAgC,EAAwB,kBAAkB,EAAE,0BAA0B,EAA0B,oBAAoB,EAAuF,MAAM,+BAA+B,CAAC;AACrU,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAE/B,OAAO,EAAE,iCAAiC,EAAE,MAAM,yCAAyC,CAAC;AAC5F,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACxF,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;;AAGxE,qBAMa,4BAA6B,SAAQ,oBAAqB,YAAW,MAAM,EAAE,SAAS,EAAE,SAAS;IAyL1G,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,mBAAmB;IAC3B,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,mBAAmB;IA3LpB,UAAU,EAAG,MAAM,CAAC;IACpB,WAAW,EAAG,QAAQ,CAAC;IACvB,aAAa,EAAG,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oBAAoB,EAAE,OAAO,CAAQ;IACrC,UAAU,EAAE,OAAO,CAAQ;IAC3B,QAAQ,EAAE,OAAO,CAAQ;IACzB,eAAe,EAAE,OAAO,CAAQ;IAChC,kBAAkB,EAAE,OAAO,CAAQ;IACnC,cAAc,CAAC,EAAE,OAAO,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAC,CAAC,CAAC;IACtE,WAAW,EAAE,cAAc,GAAG,YAAY,GAAG,IAAI,CAAQ;IACzD,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,OAAO,CAAS;IAC5B,MAAM,qBAA4B;IAClC,yBAAyB;oBAAiC,MAAM;+BAAyB,MAAM,EAAE;OAAK;IACtG,cAAc;cAA2B,cAAc,GAAG,YAAY;YAAM,MAAM;qBAAe,MAAM;wBAAkB,MAAM;oBAAc,MAAM;OAAK;IACxJ,cAAc,uBAA8B;IAC5C,eAAe,qBAA4B;IAC3C,gBAAgB;oBAAiC,MAAM;sBAAgB,YAAY;OAAK;IACxF,iBAAiB,kCAAyC;IAC1D,gBAAgB;oBAAkC,MAAM;kBAAY,YAAY;OAAM;IAElD,YAAY,CAAC,EAAE,iCAAiC,CAAC;IAE/F,OAAO,CAAC,QAAQ,CAAuB;IAEhC,QAAQ,EAAE,gBAAgB,GAAG,IAAI,CAAQ;IACzC,eAAe,EAAE,uBAAuB,GAAG,IAAI,CAAQ;IACvD,WAAW,EAAE,uBAAuB,EAAE,CAAM;IAC5C,qBAAqB,EAAE,MAAM,CAAK;IAClC,SAAS,UAAQ;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC5B,WAAW,SAAM;IACjB,mBAAmB,UAAS;IAC5B,mBAAmB,EAAE,0BAA0B,EAAE,CAAM;IACvD,yBAAyB,EAAE,0BAA0B,EAAE,CAAM;IAC7D,iBAAiB,EAAE,kBAAkB,GAAG,IAAI,CAAQ;IAGpD,SAAS,EAAE,MAAM,CAAa;IAC9B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAQ;IACtC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAQ;IAClC,iBAAiB,EAAE,gCAAgC,EAAE,CAAM;IAClE,OAAO,CAAC,uBAAuB,CAAuB;IACtD;2FACuF;IACvF,OAAO,CAAC,uBAAuB,CAAgC;IAGxD,kBAAkB,EAAE,oBAAoB,GAAG,IAAI,CAAQ;IACvD,cAAc,EAAE,kBAAkB,EAAE,CAAM;IAC1C,6BAA6B,EAAE,OAAO,CAAS;IAC/C,2BAA2B,EAAE,MAAM,GAAG,IAAI,CAAQ;IAGzD,IAAW,OAAO,IAAI,MAAM,EAAE,CAsC7B;IAED;;;OAGG;IACI,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI;IAuBlE;;;OAGG;IACI,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAoBlG;;OAEG;IACI,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAK/C;;;OAGG;IACI,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI;IAQ7D;;OAEG;IACI,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAU/D,OAAO,CAAC,mBAAmB,CAAsB;gBAGvC,GAAG,EAAE,iBAAiB,EACtB,mBAAmB,EAAE,qBAAqB,EAC1C,SAAS,EAAE,YAAY,EACvB,mBAAmB,EAAE,mBAAmB;IAM5C,QAAQ;
|
|
1
|
+
{"version":3,"file":"artifact-viewer-panel.component.d.ts","sourceRoot":"","sources":["../../../src/lib/components/artifact-viewer-panel.component.ts"],"names":[],"mappings":"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"}
|
|
@@ -730,14 +730,21 @@ export class ArtifactViewerPanelComponent extends BaseAngularComponent {
|
|
|
730
730
|
}
|
|
731
731
|
});
|
|
732
732
|
}
|
|
733
|
-
//
|
|
734
|
-
|
|
735
|
-
//
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
733
|
+
// Defer the initial load past Angular's first stable CD cycle so that the inner
|
|
734
|
+
// awaits in loadArtifact can't mutate `this.artifact`/`this.artifactVersion` between
|
|
735
|
+
// the main CD pass and dev-mode's verifyNoChanges pass (the classic NG0100
|
|
736
|
+
// "ExpressionChangedAfterItHasBeenCheckedError" we used to hit on the title).
|
|
737
|
+
// Using setTimeout(0) instead of Promise.resolve() because we need a fresh
|
|
738
|
+
// macrotask boundary — microtasks can still drain inside Angular's CD cycle.
|
|
739
|
+
setTimeout(async () => {
|
|
740
|
+
await this.loadArtifact(this.versionNumber);
|
|
741
|
+
// Track that user viewed this artifact (deferred so it runs after the load)
|
|
742
|
+
if (this.artifactVersion?.ID && this.currentUser) {
|
|
743
|
+
this.trackArtifactUsage('Viewed');
|
|
744
|
+
// Also log to User Record Logs for recents feature (fire-and-forget)
|
|
745
|
+
this.recentAccessService.logAccess('MJ: Artifacts', this.artifactId, 'artifact');
|
|
746
|
+
}
|
|
747
|
+
}, 0);
|
|
741
748
|
}
|
|
742
749
|
async ngOnChanges(changes) {
|
|
743
750
|
// Reload artifact when artifactId changes
|
|
@@ -1255,8 +1262,17 @@ export class ArtifactViewerPanelComponent extends BaseAngularComponent {
|
|
|
1255
1262
|
return excluded;
|
|
1256
1263
|
}
|
|
1257
1264
|
/**
|
|
1258
|
-
*
|
|
1259
|
-
*
|
|
1265
|
+
* Reload the cached set of collections that contain the *current version* of this artifact.
|
|
1266
|
+
* Called by the chat-area after the collection picker reports successful saves so the bookmark
|
|
1267
|
+
* icon and "already saved" exclusion list refresh without a full artifact reload.
|
|
1268
|
+
*/
|
|
1269
|
+
async ReloadCollectionAssociations() {
|
|
1270
|
+
await this.loadCollectionAssociations();
|
|
1271
|
+
}
|
|
1272
|
+
/**
|
|
1273
|
+
* @deprecated Writes are now owned by the picker modal so the dialog can render per-collection
|
|
1274
|
+
* progress and partial-failure UI. Kept for any external consumer that still calls it; new code
|
|
1275
|
+
* should pass `artifactVersionId` to the picker and listen for its `completed` event.
|
|
1260
1276
|
*/
|
|
1261
1277
|
async saveToCollections(collectionIds) {
|
|
1262
1278
|
if (!this.artifactId || collectionIds.length === 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"artifact-viewer-panel.component.js","sourceRoot":"","sources":["../../../src/lib/components/artifact-viewer-panel.component.ts","../../../src/lib/components/artifact-viewer-panel.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAA+C,SAAS,EAA2D,MAAM,eAAe,CAAC;AACxL,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAErE,OAAO,EAAsB,OAAO,EAAE,QAAQ,EAA8B,MAAM,sBAAsB,CAAC;AACzG,OAAO,EAAE,kBAAkB,EAAqB,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAC3F,OAAO,EAAqJ,sBAAsB,EAA6G,MAAM,+BAA+B,CAAC;AACrU,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,iCAAiC,EAAE,MAAM,yCAAyC,CAAC;AAG5F,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;;;;;;;;;;;;ICH9D,4BAA8B;IAAA,YAAwB;IAAA,iBAAI;;;IAA5B,cAAwB;IAAxB,+CAAwB;;;IAUpD,wBAAoF;;;IAAvC,kDAAkC;;;IAWvE,wBAA4B;;;;IANhC,+BAEgE;IAA3D,gOAAS,gCAAsB,wBAAE,wBAAwB,KAAC;IAC7D,gCAA6B;IAAA,YAA4B;IAAA,iBAAO;IAChE,gCAA2B;IAAA,YAA2C;;IAAA,iBAAO;IAC7E,gIAAuD;IAGzD,iBAAM;;;;IAPD,qFAAkE;IAExC,eAA4B;IAA5B,oDAA4B;IAC9B,eAA2C;IAA3C,8EAA2C;IACtE,eAEC;IAFD,oFAEC;;;;IATP,+BAAiE;IAAnC,+KAAS,wBAAwB,KAAC;IAC9D,6HAUC;IACH,iBAAM;;;IAXJ,cAUC;IAVD,iCAUC;;;;IAKL,kCAE0C;IADlC,kSAA4C;IAElD,wBAAuC;IACzC,iBAAS;;;;IAGT,kCAG4I;IADpI,gNAAS,wBAAiB,KAAC;IAEjC,oBAAwE;IAC1E,iBAAS;;;IAJD,sDAAsC;IAEtC,+JAAmI;IACtI,cAAgE;IAAhE,4EAAgE;;;;IAIrE,kCAEsB;IADd,gNAAS,gBAAS,KAAC;IAEzB,wBAAkC;IACpC,iBAAS;;;;IAQT,kCAEmE;IAD3D,gNAAS,yBAAkB,KAAC;IAElC,uBAA+F;IACjG,iBAAS;;;IAFD,+EAA0D;IACjD,cAA2E;IAA3E,gGAA2E;;;;IAI5F,kCAA4D;IAAlC,iNAAS,gBAAS,KAAC;IAC3C,wBAA4B;IAC9B,iBAAS;;;;IAtEX,AADF,AADF,8BAA0B,aACO,SACzB;IACF,uBAA4C;IAC5C,YACF;IAAA,iBAAK;IACL,0GAA0B;IAG5B,iBAAM;IAEJ,AADF,8BAAgC,cAGyC;IAAlE,oNAAyB,YAAY,IAAI,8BAAuB,KAAC;IACpE,wBAA8B;IAC9B,gCAA4B;IAAA,aAA4B;IAAA,iBAAO;IAC/D,6GAA8D;IAG9D,+GAA2B;IAe7B,iBAAM;IACN,kHAAsC;IAOtC,kHAA4B;IAQ5B,kHAAgB;IAOhB,mCAE8C;IADtC,iMAAS,kBAAW,KAAC;IAE3B,yBAA6C;IAC/C,iBAAS;IACT,kHAA0B;IAO1B,kHAAuB;IAM3B,AADE,iBAAM,EACF;;;IAxEe,eAAwB;IAAxB,6CAAwB;IACvC,cACF;IADE,mDACF;IACA,cAEC;IAFD,oDAEC;IAII,eAA0E;IAA1E,iGAA0E;IAGjD,eAA4B;IAA5B,wDAA4B;IACxD,cAEC;IAFD,gGAEC;IACD,cAcC;IAdD,sDAcC;IAEH,cAMC;IAND,uGAMC;IACD,cAOC;IAPD,uDAOC;IACD,cAMC;IAND,2CAMC;IAMD,eAMC;IAND,qDAMC;IACD,cAIC;IAJD,kDAIC;;;IAOH,8BAA2B;IACzB,wBAAsC;IACtC,4BAAM;IAAA,mCAAmB;IAC3B,AAD2B,iBAAO,EAC5B;;;IAIN,8BAAyB;IACvB,wBAA2C;IAC3C,4BAAM;IAAA,YAAW;IACnB,AADmB,iBAAO,EACpB;;;IADE,eAAW;IAAX,kCAAW;;;IAcP,oBAAkC;;;;IAA/B,yCAA0B;;;;IAJjC,kCAEoC;IAA5B,gPAAS,4BAAiB,KAAC;IACjC,+HAAuB;IAGvB,YACF;IAAA,iBAAS;;;;IAND,oEAAgD;IAEtD,cAEC;IAFD,qDAEC;IACD,cACF;IADE,wCACF;;;IATJ,+BAA4B;IAC1B,iJASC;IACH,iBAAM;;;IAVJ,cASC;IATD,6BASC;;;;IASC,AADF,+BAA8E,yCAS1C;IAAhC,AADA,AADA,AADA,oQAAoB,iCAA0B,KAAC,yPAC1B,kCAA2B,KAAC,yOACjC,uBAAgB,KAAC,uOAClB,sBAAe,KAAC;IAEnC,AADE,iBAAiC,EAC7B;;;IAXwB,+DAA+C;IAEzE,cAAmC;IAGnC,AADA,AADA,AADA,wDAAmC,6CACE,mCACV,kBACV;;;IAuBf,+BAA8B;IAC5B,kCAI+C;IACjD,iBAAM;;;IALS,cAAwB;IAIxB,AADA,AADA,AADA,AADA,6CAAwB,mCACU,2BACR,2BACA,oBACP;;;IAGlC,0BAA0D;;;IAAhC,iEAAyB;;;;IAhBnD,AADF,+BAA6B,iBAC8C;IAAlC,8NAAS,8BAAuB,KAAC;IACtE,wBAA4B;IAAC,uBAC/B;IAAA,iBAAS;IACT,kCAA+E;IAAjC,8NAAS,6BAAsB,KAAC;IAC5E,wBAA2B;IAAC,sBAC9B;IACF,AADE,iBAAS,EACL;IASJ,AARF,yIAAuB,mHAQG;;;IAR1B,eAUC;IAVD,0EAUC;;;IArBL,+BAA6B;IAC3B,gHAAsC;IAsBxC,iBAAM;;;IAtBJ,cAqBC;IArBD,uEAqBC;;;IAyBK,AADF,+BAAkC,YACzB;IAAA,oCAAoB;IAAA,iBAAQ;IACnC,4BAAM;IAAA,YAA0B;IAClC,AADkC,iBAAO,EACnC;;;IADE,eAA0B;IAA1B,iDAA0B;;;IAKhC,AADF,+BAAkC,YACzB;IAAA,mCAAmB;IAAA,iBAAQ;IAClC,4BAAM;IAAA,YAAkC;IAC1C,AAD0C,iBAAO,EAC3C;;;IADE,eAAkC;IAAlC,gGAAkC;;;IAclC,4BAAM;IAAA,YAAgB;IAAA,iBAAO;;;IAAvB,cAAgB;IAAhB,oCAAgB;;;IAEtB,gCAAmC;IAAA,qBAAK;IAAA,iBAAO;;;IAJjD,AADF,+BAA4B,YACnB;IAAA,YAAe;IAAA,iBAAQ;IAG5B,AAFF,+HAAkB,6GAET;IAGX,iBAAM;;;IANG,eAAe;IAAf,mCAAe;IACtB,cAIC;IAJD,wCAIC;;;IATP,AADF,+BAAgC,SAC1B;IAAA,kCAAkB;IAAA,iBAAK;IAC3B,+BAA6B;IAC3B,6HASC;IAEL,AADE,iBAAM,EACF;;;IAXF,eASC;IATD,wCASC;;;IAkBG,wBAA+B;;;IAE/B,wBAA6B;;;;IATnC,+BAI8D;IADzD,oQAA0B,iCAAsB,GAAG,IAAI,KAAC;IAE3D,+BAAuB;IAGnB,AAFF,gIAAoC,0GAE3B;IAGX,iBAAM;IAEJ,AADF,+BAA0B,cACD;IAAA,YAAe;IAAA,iBAAM;IAC5C,+BAAuB;IAAA,YAAkE;IAC3F,AAD2F,iBAAM,EAC3F;IACN,+BAA0B;IACxB,yBAAkC;IAEtC,AADE,iBAAM,EACF;;;IAjBD,AADA,+CAAkC,iCACA;IAElC,0EAAwD;IAEzD,eAIC;IAJD,0DAIC;IAGsB,eAAe;IAAf,mCAAe;IACf,eAAkE;IAAlE,sFAAkE;;;IAhBjG,+BAA2B;IACzB,8HAqBC;IACH,iBAAM;;;IAtBJ,cAqBC;IArBD,iCAqBC;;;IAGH,+BAAyB;IACvB,wBAA2B;IAC3B,yBAAG;IAAA,kCAAkB;IACvB,AADuB,iBAAI,EACrB;;;IASJ,wBAAuG;;;IADzG,+BAAmC;IACjC,2IAAwF;IAC1F,iBAAM;;;IADW,cAAkC;IAAA,AAAlC,uCAAkC,wEAAqC;;;IAOhF,+BAA6B;IAC3B,kCAI+C;IACjD,iBAAM;;;IALS,cAAwB;IAIxB,AADA,AADA,AADA,AADA,0CAAwB,mCACU,2BACR,2BACA,oBACP;;;;IAM9B,AADF,AADF,+BAAyB,cACG,iBACiD;IAA9B,oPAAS,0BAAmB,KAAC;IACtE,wBAA2B;IAAC,sBAC9B;IACF,AADE,iBAAS,EACL;IACN,+BAAmC;IACjC,qCAMiB;IAErB,AADE,iBAAM,EACF;;;IAPA,eAAyB;IAGzB,AADA,AADA,AADA,2CAAyB,oBACN,kBACF,sBACI;;;;IASvB,AADF,AADF,+BAAyB,cACG,iBACiD;IAA9B,oPAAS,0BAAmB,KAAC;IACtE,wBAA2B;IAAC,sBAC9B;IACF,AADE,iBAAS,EACL;IACN,+BAAmC;IACjC,qCAMiB;IAErB,AADE,iBAAM,EACF;;;IAPA,eAAyB;IAGzB,AADA,AADA,AADA,2CAAyB,kDACoB,kBAC5B,sBACI;;;IAO3B,0BAA6D;;;IAApC,kEAA6B;;;IAGtD,+BAA8B;IAAA,YAAqB;IAAA,iBAAM;;;IAA3B,cAAqB;IAArB,yCAAqB;;;IAnDzD,+BAAiC;IAkD7B,AAHA,AAlBA,AAlBA,AATA,iJAAoB,2HASJ,2HAkBA,2HAkBA,2HAGK;IAIzB,iBAAM;;;IArDJ,cAoDC;IApDD,0CAAA,UAAU,mBAAV,MAAM,mBAAN,MAAM,mBAAN,MAAM,mBAAN,WAAW,UAoDV;;;IAtDL,0IAA4C;;;;IAA5C,sFAwDC;;;IAzDD,AAJF,4HAAwD,2FAI/C;;;;IAJT,2FA8DC;;;IAxNP,+BAAkE;IAEhE,6GAAgB;IAgBhB,+BAAyB;IAEvB,6GAAwD;IAgBxD,6GAAmE;IA+B3D,AADF,AADF,AADJ,+BAA0E,cAC3C,cACF,YACd;IAAA,oBAAI;IAAA,iBAAQ;IACnB,6BAAM;IAAA,aAAmB;IAC3B,AAD2B,iBAAO,EAC5B;IAEJ,AADF,gCAAuB,aACd;IAAA,wBAAO;IAAA,iBAAQ;IACtB,6BAAM;IAAA,aAAyC;IACjD,AADiD,iBAAO,EAClD;IAEJ,AADF,gCAAuB,aACd;IAAA,wBAAO;IAAA,iBAAQ;IACtB,6BAAM;IAAA,aAA4C;;IACpD,AADoD,iBAAO,EACrD;IAEJ,AADF,gCAAuB,aACd;IAAA,wBAAO;IAAA,iBAAQ;IACtB,6BAAM;IAAA,aAAoD;;IAC5D,AAD4D,iBAAO,EAC7D;IACN,+GAA4B;IAM5B,+GAAqH;IAMvH,iBAAM;IAGN,+GAAqC;IAiBvC,iBAAM;IAGR,gCAAwE;IA0BpE,AAzBF,+GAA8B,yFAyBrB;IAMX,iBAAM;IAGN,oGAAmF;IAmEvF,AADE,iBAAM,EACF;;;IA3NgC,2CAA2B;IAE/D,cAaC;IAbD,0CAaC;IAKC,eAaC;IAbD,gGAaC;IAGD,cAyBC;IAzBD,2GAyBC;IAG4B,cAA4C;IAA5C,4DAA4C;IAI3D,eAAmB;IAAnB,0CAAmB;IAInB,eAAyC;IAAzC,yGAAyC;IAIzC,eAA4C;IAA5C,qFAA4C;IAI5C,eAAoD;IAApD,oIAAoD;IAE5D,eAKC;IALD,uDAKC;IACD,cAKC;IALD,uPAKC;IAIH,cAgBC;IAhBD,gEAgBC;IAIwB,cAA0C;IAA1C,0DAA0C;IACrE,cA8BC;IA9BD,yDA8BC;IAIH,eAiEC;IAjED,4HAiEC;;ADrSX,MAAM,OAAO,4BAA6B,SAAQ,oBAAoB;IAyL1D;IACA;IACA;IACA;IA3LD,UAAU,CAAU;IACpB,WAAW,CAAY;IACvB,aAAa,CAAU;IACvB,aAAa,CAAU,CAAC,qBAAqB;IAC7C,oBAAoB,GAAY,IAAI,CAAC,CAAC,qDAAqD;IAC3F,UAAU,GAAY,IAAI,CAAC,CAAC,8CAA8C;IAC1E,QAAQ,GAAY,IAAI,CAAC,CAAC,sFAAsF;IAChH,eAAe,GAAY,IAAI,CAAC,CAAC,sDAAsD;IACvF,kBAAkB,GAAY,IAAI,CAAC,CAAC,iEAAiE;IACrG,cAAc,CAAwD;IACtE,WAAW,GAAyC,IAAI,CAAC,CAAC,iCAAiC;IAC3F,mBAAmB,CAAU,CAAC,6CAA6C;IAC3E,QAAQ,CAAW,CAAC,uCAAuC;IAC3D,OAAO,CAAW,CAAC,sCAAsC;IACzD,WAAW,GAAY,KAAK,CAAC,CAAC,2CAA2C;IACxE,MAAM,GAAG,IAAI,YAAY,EAAQ,CAAC;IAClC,yBAAyB,GAAG,IAAI,YAAY,EAAyD,CAAC;IACtG,cAAc,GAAG,IAAI,YAAY,EAAsH,CAAC;IACxJ,cAAc,GAAG,IAAI,YAAY,EAAU,CAAC,CAAC,yCAAyC;IACtF,eAAe,GAAG,IAAI,YAAY,EAAQ,CAAC,CAAC,iDAAiD;IAC7F,gBAAgB,GAAG,IAAI,YAAY,EAAoD,CAAC;IACxF,iBAAiB,GAAG,IAAI,YAAY,EAAqB,CAAC;IAC1D,gBAAgB,GAAG,IAAI,YAAY,EAAkD,CAAC;IAElD,YAAY,CAAqC;IAEvF,QAAQ,GAAG,IAAI,OAAO,EAAQ,CAAC;IAEhC,QAAQ,GAA4B,IAAI,CAAC;IACzC,eAAe,GAAmC,IAAI,CAAC;IACvD,WAAW,GAA8B,EAAE,CAAC;IAC5C,qBAAqB,GAAW,CAAC,CAAC;IAClC,SAAS,GAAG,IAAI,CAAC;IACjB,KAAK,GAAkB,IAAI,CAAC;IAC5B,WAAW,GAAG,EAAE,CAAC;IACjB,mBAAmB,GAAG,KAAK,CAAC;IAC5B,mBAAmB,GAAiC,EAAE,CAAC,CAAC,mCAAmC;IAC3F,yBAAyB,GAAiC,EAAE,CAAC,CAAC,8CAA8C;IAC5G,iBAAiB,GAA8B,IAAI,CAAC;IAE3D,mBAAmB;IACZ,SAAS,GAAW,SAAS,CAAC,CAAC,4CAA4C;IAC3E,eAAe,GAAkB,IAAI,CAAC;IACtC,WAAW,GAAkB,IAAI,CAAC;IAClC,iBAAiB,GAAuC,EAAE,CAAC;IAC1D,uBAAuB,GAAkB,IAAI,CAAC;IACtD;2FACuF;IAC/E,uBAAuB,GAA2B,IAAI,CAAC;IAE/D,iBAAiB;IACV,kBAAkB,GAAgC,IAAI,CAAC;IACvD,cAAc,GAAyB,EAAE,CAAC;IAC1C,6BAA6B,GAAY,KAAK,CAAC;IAC/C,2BAA2B,GAAkB,IAAI,CAAC,CAAC,gDAAgD;IAE1G,2BAA2B;IAC3B,IAAW,OAAO;QAChB,MAAM,IAAI,GAAa,EAAE,CAAC;QAE1B,qDAAqD;QACrD,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACvB,CAAC;QAED,2FAA2F;QAC3F,IAAI,IAAI,CAAC,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,CAAC;YACzD,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,iBAAiB,EAAE,CAAC;YACxE,MAAM,eAAe,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAoB,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;YAC1E,IAAI,CAAC,IAAI,CAAC,GAAG,eAAe,CAAC,CAAC;QAChC,CAAC;QAED,oDAAoD;QACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,EAAE,cAAc,EAAE,sBAAsB,EAAE,EAAE,IAAI,EAAE,CAAC;QACrF,MAAM,aAAa,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;QAEzD,gFAAgF;QAChF,qFAAqF;QACrF,gGAAgG;QAChG,MAAM,cAAc,GAAG,IAAI,CAAC,uBAAuB,KAAK,MAAM,CAAC;QAE/D,8DAA8D;QAC9D,IAAI,CAAC,cAAc,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YACvD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACpB,CAAC;QACD,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YACvC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACvB,CAAC;QAED,sFAAsF;QACtF,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACrB,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;OAGG;IACI,gBAAgB,CAAC,OAAe;QACrC,yCAAyC;QACzC,IAAI,IAAI,CAAC,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,CAAC;YACzD,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,iBAAiB,EAAE,CAAC;YACxE,MAAM,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAoB,EAAE,EAAE,CACzD,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,OAAO,CAAC,WAAW,EAAE,CAChD,CAAC;YACF,IAAI,SAAS,EAAE,CAAC;gBACd,OAAO,SAAS,CAAC;YACnB,CAAC;QACH,CAAC;QAED,mBAAmB;QACnB,QAAQ,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC;YAC9B,KAAK,MAAM;gBACT,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;YAC7F,KAAK,SAAS;gBACZ,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,WAAW,IAAI,EAAE,EAAE,CAAC;YAC5G;gBACE,OAAO,IAAI,CAAC;QAChB,CAAC;IACH,CAAC;IAED;;;OAGG;IACI,aAAa,CAAC,OAAe;QAClC,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAC9C,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QAEzB,2CAA2C;QAC3C,IAAI,MAAM,CAAC,WAAW,KAAK,WAAW,EAAE,CAAC;YACvC,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,OAAO,GAAG,OAAO,MAAM,CAAC,OAAO,KAAK,UAAU;YAClD,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE;YAClB,CAAC,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC;QAEzB,OAAO;YACL,IAAI,EAAE,MAAM,CAAC,WAAW;YACxB,OAAO,EAAE,OAAO;YAChB,QAAQ,EAAE,MAAM,CAAC,QAAQ;SAC1B,CAAC;IACJ,CAAC;IAED;;OAEG;IACI,cAAc,CAAC,OAAe;QACnC,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAC9C,OAAO,MAAM,EAAE,WAAW,KAAK,WAAW,IAAI,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC;IACnE,CAAC;IAED;;;OAGG;IACI,mBAAmB,CAAC,OAAe;QACxC,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAC9C,IAAI,MAAM,EAAE,WAAW,KAAK,WAAW,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;YAC5D,OAAO,MAAM,CAAC,SAAS,CAAC;QAC1B,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACI,kBAAkB,CAAC,OAAe;QACvC,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAC9C,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,WAAW,KAAK,WAAW,EAAE,CAAC;YAClD,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,OAAO,OAAO,MAAM,CAAC,eAAe,KAAK,UAAU;YACjD,CAAC,CAAC,MAAM,CAAC,eAAe,EAAE;YAC1B,CAAC,CAAC,MAAM,CAAC,eAAe,IAAI,EAAE,CAAC;IACnC,CAAC;IAEO,mBAAmB,CAAsB;IAEjD,YACU,GAAsB,EACtB,mBAA0C,EAC1C,SAAuB,EACvB,mBAAwC;QAEhD,KAAK,EAAE,CAAC;QALA,QAAG,GAAH,GAAG,CAAmB;QACtB,wBAAmB,GAAnB,mBAAmB,CAAuB;QAC1C,cAAS,GAAT,SAAS,CAAc;QACvB,wBAAmB,GAAnB,mBAAmB,CAAqB;QAGhD,IAAI,CAAC,mBAAmB,GAAG,IAAI,mBAAmB,EAAE,CAAC;IACvD,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,2DAA2D;QAC3D,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;gBAC1E,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,CAAC,UAAU,EAAE,CAAC;oBACxC,0CAA0C;oBAC1C,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;gBAC9C,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;QAED,mDAAmD;QACnD,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAE5C,uCAAuC;QACvC,IAAI,IAAI,CAAC,eAAe,EAAE,EAAE,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACjD,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;YAClC,qEAAqE;YACrE,IAAI,CAAC,mBAAmB,CAAC,SAAS,CAAC,eAAe,EAAE,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;QACnF,CAAC;IACH,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,OAAsB;QACtC,0CAA0C;QAC1C,IAAI,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE,CAAC;YAChE,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC9C,CAAC;QAED,mFAAmF;QACnF,IAAI,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,WAAW,EAAE,CAAC;YACtE,MAAM,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,YAAY,CAAC;YAC/D,IAAI,gBAAgB,IAAI,IAAI,EAAE,CAAC;gBAC7B,oFAAoF;gBACpF,MAAM,aAAa,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,KAAK,gBAAgB,CAAC,CAAC;gBACvF,IAAI,aAAa,EAAE,CAAC;oBAClB,IAAI,CAAC,qBAAqB,GAAI,aAAa,CAAC,aAAwB,IAAI,CAAC,CAAC;oBAE1E,6CAA6C;oBAC7C,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;oBACpE,IAAI,WAAW,EAAE,CAAC;wBAChB,IAAI,CAAC,eAAe,GAAG,WAAW,CAAC;wBACnC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC;oBAClE,CAAC;oBAED,kDAAkD;oBAClD,MAAM,OAAO,CAAC,GAAG,CAAC;wBAChB,IAAI,CAAC,qBAAqB,EAAE;wBAC5B,IAAI,CAAC,0BAA0B,EAAE;wBACjC,IAAI,CAAC,aAAa,EAAE;qBACrB,CAAC,CAAC;oBAEH,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;gBAC3B,CAAC;qBAAM,CAAC;oBACN,iEAAiE;oBACjE,MAAM,IAAI,CAAC,YAAY,CAAC,gBAAgB,CAAC,CAAC;gBAC5C,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,WAAW;QACT,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACrB,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;IAC3B,CAAC;IAEO,KAAK,CAAC,YAAY,CAAC,mBAA4B;QACrD,IAAI,CAAC;YACH,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;YACtB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;YAElB,qEAAqE;YACrE,IAAI,CAAC,cAAc,EAAE,CAAC;YAEtB,MAAM,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC;YAE9B,wEAAwE;YACxE,MAAM,cAAc,GAAG,MAAM,EAAE,CAAC,eAAe,CAAmB,eAAe,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;YACrG,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAE1D,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,IAAI,CAAC,KAAK,GAAG,yBAAyB,CAAC;gBACvC,OAAO;YACT,CAAC;YACD,IAAI,CAAC,QAAQ,GAAG,cAAc,CAAC;YAE/B,qFAAqF;YACrF,mGAAmG;YACnG,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YAC5D,MAAM,YAAY,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC;gBACrC;oBACE,wDAAwD;oBACxD,UAAU,EAAE,uBAAuB;oBACnC,WAAW,EAAE,eAAe,IAAI,CAAC,UAAU,GAAG;oBAC9C,OAAO,EAAE,oBAAoB;oBAC7B,MAAM,EAAE,CAAC,IAAI,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,EAAE,aAAa,EAAE,gBAAgB,EAAE,gBAAgB,CAAC;oBACxG,UAAU,EAAE,QAAQ;iBACrB;gBACD;oBACE,gEAAgE;oBAChE,UAAU,EAAE,0BAA0B;oBACtC,WAAW,EAAE;2EACoD,IAAI,CAAC,UAAU;YAC9E;oBACF,MAAM,EAAE,CAAC,IAAI,EAAE,cAAc,EAAE,mBAAmB,EAAE,UAAU,CAAC;oBAC/D,UAAU,EAAE,QAAQ;iBACrB;gBACD;oBACE,yDAAyD;oBACzD,UAAU,EAAE,mCAAmC;oBAC/C,WAAW,EAAE;2EACoD,IAAI,CAAC,UAAU;YAC9E;oBACF,MAAM,EAAE,CAAC,IAAI,EAAE,sBAAsB,EAAE,mBAAmB,CAAC;oBAC3D,OAAO,EAAE,CAAC;oBACV,UAAU,EAAE,QAAQ;iBACrB;aACF,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;YAErB,MAAM,CAAC,cAAc,EAAE,iBAAiB,EAAE,gBAAgB,CAAC,GAAG,YAAY,CAAC;YAE3E,IAAI,CAAC,cAAc,CAAC,OAAO,IAAI,CAAC,cAAc,CAAC,OAAO,IAAI,cAAc,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC9F,IAAI,CAAC,KAAK,GAAG,2BAA2B,CAAC;gBACzC,OAAO;YACT,CAAC;YAED,uEAAuE;YACvE,IAAI,CAAC,WAAW,GAAG,cAAc,CAAC,OAAoC,CAAC;YAEvE,qCAAqC;YACrC,IAAI,eAAoD,CAAC;YACzD,IAAI,mBAAmB,EAAE,CAAC;gBACxB,eAAe,GAAG,cAAc,CAAC,OAAO,CAAC,IAAI,CAC3C,CAAC,CAA0B,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,KAAK,mBAAmB,CACxE,CAAC;YACJ,CAAC;YACD,oDAAoD;YACpD,MAAM,aAAa,GAAG,eAAe,IAAI,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YACnE,IAAI,CAAC,qBAAqB,GAAI,aAAa,CAAC,aAAwB,IAAI,CAAC,CAAC;YAE1E,qFAAqF;YACrF,MAAM,CAAC,EAAE,qBAAqB,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;gBAClD,IAAI,CAAC,gBAAgB,EAAE;gBACvB,IAAI,CAAC,kBAAkB,CAAC,aAAa,CAAC,EAAY,CAAC;aACpD,CAAC,CAAC;YAEH,IAAI,qBAAqB,EAAE,CAAC;gBAC1B,IAAI,CAAC,eAAe,GAAG,qBAAqB,CAAC;gBAC7C,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,UAAU,CAAC,qBAAqB,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC;YAC5E,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,KAAK,GAAG,yCAAyC,CAAC;gBACvD,OAAO;YACT,CAAC;YAED,wFAAwF;YACxF,MAAM,OAAO,CAAC,GAAG,CAAC;gBAChB,IAAI,CAAC,6BAA6B,CAAC,iBAAiB,CAAC;gBACrD,IAAI,CAAC,gBAAgB,CAAC,iBAAiB,EAAE,gBAAgB,CAAC;aAC3D,CAAC,CAAC;YAEH,kEAAkE;YAClE,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;QACrC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,GAAG,CAAC,CAAC;YAC9C,IAAI,CAAC,KAAK,GAAG,0BAA0B,GAAI,GAAa,CAAC,OAAO,CAAC;QACnE,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;YACvB,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC1B,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAC3B,CAAC;IACH,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,kBAAkB,CAAC,SAAiB;QAChD,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC;YAC9B,MAAM,aAAa,GAAG,MAAM,EAAE,CAAC,eAAe,CAA0B,uBAAuB,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;YACnH,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACnD,OAAO,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC;QACvC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,gCAAgC,EAAE,GAAG,CAAC,CAAC;YACrD,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED;;OAEG;IACK,cAAc;QACpB,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC;QACzB,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;QAC/B,IAAI,CAAC,6BAA6B,GAAG,KAAK,CAAC;QAC3C,IAAI,CAAC,2BAA2B,GAAG,IAAI,CAAC;IAC1C,CAAC;IAEO,KAAK,CAAC,gBAAgB;QAC5B,gFAAgF;QAChF,IAAI,CAAC,uBAAuB,GAAG,IAAI,CAAC;QACpC,IAAI,CAAC,uBAAuB,GAAG,IAAI,CAAC;QAEpC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC;YACzB,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,MAAM,sBAAsB,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;YAEtE,MAAM,YAAY,GAAG,sBAAsB,CAAC,QAAQ,CAAC,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC1F,IAAI,YAAY,EAAE,CAAC;gBACjB,+DAA+D;gBAC/D,IAAI,CAAC,uBAAuB,GAAG,MAAM,IAAI,CAAC,yBAAyB,CAAC,YAAY,CAAC,CAAC;gBAClF,IAAI,CAAC,uBAAuB,GAAG,YAAY,CAAC,eAAe,CAAC;YAC9D,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,GAAG,CAAC,CAAC;YACnD,8DAA8D;QAChE,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,qBAAqB;QACjC,IAAI,CAAC,IAAI,CAAC,eAAe;YAAE,OAAO;QAElC,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YAC5D,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAmC;gBAChE,UAAU,EAAE,iCAAiC;gBAC7C,WAAW,EAAE,sBAAsB,IAAI,CAAC,eAAe,CAAC,EAAE,GAAG;gBAC7D,UAAU,EAAE,QAAQ;aACrB,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;YAErB,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACrC,IAAI,CAAC,iBAAiB,GAAG,MAAM,CAAC,OAAO,CAAC;gBAExC,sDAAsD;gBACtD,MAAM,mBAAmB,GAAG,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,iBAAiB,CAAC,CAAC;gBAC1G,MAAM,eAAe,GAAG,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,aAAa,CAAC,CAAC;gBAElG,oDAAoD;gBACpD,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,mBAAmB,CAAC,mBAAmB,EAAE,KAAK,CAAC,CAAC;gBAC5E,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,mBAAmB,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;gBAEpE,mEAAmE;gBACnE,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;oBACrB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;gBACnE,CAAC;gBAED,4CAA4C;gBAC5C,IAAI,CAAC,4BAA4B,EAAE,CAAC;YACtC,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,mCAAmC,EAAE,GAAG,CAAC,CAAC;QAC1D,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,CAAC,iDAAiD;QAC7E,CAAC;IACH,CAAC;IAED,IAAI,WAAW;QACb,IAAI,IAAI,CAAC,eAAe,EAAE,IAAI,EAAE,CAAC;YAC/B,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC;QACnC,CAAC;QACD,OAAO,IAAI,CAAC,QAAQ,EAAE,IAAI,IAAI,UAAU,CAAC;IAC3C,CAAC;IAED,IAAI,kBAAkB;QACpB,IAAI,IAAI,CAAC,eAAe,EAAE,WAAW,EAAE,CAAC;YACtC,OAAO,IAAI,CAAC,eAAe,CAAC,WAAW,CAAC;QAC1C,CAAC;QACD,OAAO,IAAI,CAAC,QAAQ,EAAE,WAAW,IAAI,IAAI,CAAC;IAC5C,CAAC;IAED,IAAI,aAAa;QACf,uBAAuB;QACvB,mEAAmE;QACnE,0EAA0E;QAC1E,EAAE;QACF,2EAA2E;QAC3E,yEAAyE;QACzE,uFAAuF;QACvF,MAAM,gBAAgB,GAAG,IAAI,CAAC,YAAY,EAAE,cAAc,EAAE,iBAAiB,IAAI,KAAK,CAAC;QAEvF,OAAO,gBAAgB,IAAI,CAAC,CAAC,IAAI,CAAC,eAAe,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC;IAC1E,CAAC;IAED,IAAI,SAAS;QACX,0DAA0D;QAC1D,oDAAoD;QACpD,OAAO,CAAC,CAAC,IAAI,CAAC,uBAAuB,CAAC;IACxC,CAAC;IAED,IAAI,UAAU;QACZ,gFAAgF;QAChF,MAAM,cAAc,GAAG,IAAI,CAAC,YAAY,EAAE,cAAc,CAAC;QACzD,OAAO,cAAc,EAAE,0BAA0B,IAAI,KAAK,CAAC;IAC7D,CAAC;IAED,IAAI,gBAAgB;QAClB,OAAO,IAAI,CAAC,QAAQ,EAAE,IAAI,IAAI,EAAE,CAAC;IACnC,CAAC;IAED,IAAI,WAAW;QACb,2DAA2D;QAC3D,MAAM,eAAe,GAAG,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,aAAa,CAAC,CAAC;QAClG,OAAO,eAAe,EAAE,KAAK,IAAI,SAAS,CAAC;IAC7C,CAAC;IAED,IAAI,kBAAkB;QACpB,iFAAiF;QACjF,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;YAC1C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE,CAAC;YACtC,OAAO,IAAI,KAAK,iBAAiB,IAAI,IAAI,KAAK,aAAa,CAAC;QAC9D,CAAC,CAAC,CAAC;IACL,CAAC;IAED,YAAY,CAAC,GAA6C;QACxD,IAAI,CAAC,SAAS,GAAG,GAAG,CAAC;IACvB,CAAC;IAED;;;OAGG;IACK,4BAA4B;QAClC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC;QAC1B,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpB,wEAAwE;YACxE,MAAM,wBAAwB,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,CAAC;YAClG,IAAI,CAAC,wBAAwB,EAAE,CAAC;gBAC9B,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;YACzC,CAAC;QACH,CAAC;aAAM,CAAC;YACN,8DAA8D;YAC9D,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC7B,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,aAAa;QACX,wEAAwE;QACxE,wDAAwD;QACxD,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC;QAC1B,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,SAAS,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YAC3F,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC7B,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,CAAC,4EAA4E;IACxG,CAAC;IAED;;;OAGG;IACH,cAAc;QACZ,8DAA8D;QAC9D,6DAA6D;QAC7D,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC;QAC1B,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QACzC,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,CAAC,2DAA2D;IACvF,CAAC;IAEO,mBAAmB,CAAC,KAAgC;QAC1D,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QAExB,oEAAoE;QACpE,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACjD,IAAI,CAAC;gBACH,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC3B,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,OAAO,CAAC,IAAI,CAAC,0CAA0C,EAAE,CAAC,CAAC,CAAC;gBAC5D,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;OAGG;IACK,sBAAsB,CAAC,IAAY;QACzC,gDAAgD;QAChD,8EAA8E;QAC9E,IAAI,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAEvC,sBAAsB;QACtB,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAEtC,6BAA6B;QAC7B,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAExC,iCAAiC;QACjC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAExC,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,6BAA6B,CACzC,iBAA4E;QAE5E,IAAI,CAAC,IAAI,CAAC,UAAU;YAAE,OAAO;QAE7B,IAAI,CAAC;YACH,oFAAoF;YACpF,IAAI,cAAyC,CAAC;YAC9C,IAAI,iBAAiB,EAAE,OAAO,IAAI,iBAAiB,CAAC,OAAO,EAAE,CAAC;gBAC5D,cAAc,GAAG,iBAAiB,CAAC,OAAO,CAAC;YAC7C,CAAC;iBAAM,CAAC;gBACN,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;gBAC5D,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAoF;oBACjH,UAAU,EAAE,0BAA0B;oBACtC,WAAW,EAAE;2EACoD,IAAI,CAAC,UAAU;YAC9E;oBACF,MAAM,EAAE,CAAC,IAAI,EAAE,cAAc,EAAE,mBAAmB,EAAE,UAAU,CAAC;oBAC/D,UAAU,EAAE,QAAQ;iBACrB,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;gBACrB,cAAc,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAA8B,CAAC;YACvF,CAAC;YAED,6DAA6D;YAC7D,IAAI,CAAC,mBAAmB,GAAG,cAAyD,CAAC;YAErF,gEAAgE;YAChE,MAAM,gBAAgB,GAAG,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;YAClD,IAAI,gBAAgB,EAAE,CAAC;gBACrB,MAAM,YAAY,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC,WAAW,EAAE,CAAC;gBAC5D,IAAI,CAAC,yBAAyB,GAAG,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE;oBAC1D,MAAM,YAAY,GAAG,MAAM,CAAC,EAAE,CAAC,mBAAmB,CAAC,IAAI,EAAE,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;oBACjG,OAAO,YAAY,IAAI,YAAY,IAAI,YAAY,KAAK,YAAY,CAAC;gBACvE,CAAC,CAA4C,CAAC;YAChD,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,yBAAyB,GAAG,EAAE,CAAC;YACtC,CAAC;YAED,gDAAgD;YAChD,IAAI,IAAI,CAAC,mBAAmB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxC,MAAM,YAAY,GAAI,cAAc,CAAC,CAAC,CAA6B,CAAC,YAAsB;oBACpE,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAwC,CAAC,YAAsB,CAAC;gBAChH,IAAI,YAAY,EAAE,CAAC;oBACjB,MAAM,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC;oBAC9B,IAAI,CAAC,iBAAiB,GAAG,MAAM,EAAE,CAAC,eAAe,CAAqB,iBAAiB,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;oBAC3G,MAAM,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;gBAClD,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;YAChC,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,2CAA2C,EAAE,GAAG,CAAC,CAAC;QAClE,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAC3B,CAAC;IACH,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,0BAA0B;QACtC,OAAO,IAAI,CAAC,6BAA6B,EAAE,CAAC;IAC9C,CAAC;IAED,IAAI,cAAc;QAChB,OAAO,IAAI,CAAC,yBAAyB,CAAC,MAAM,GAAG,CAAC,CAAC;IACnD,CAAC;IAED;;;OAGG;IACH,IAAI,2BAA2B;QAC7B,OAAO,IAAI,CAAC,yBAAyB,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC;IACnE,CAAC;IAED,iBAAiB;QACf,kFAAkF;QAClF,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACnD,IAAI,OAAO,EAAE,OAAO,EAAE,CAAC;YACrB,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACjD,CAAC;aAAM,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YAC5B,mDAAmD;YACnD,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IAED,oBAAoB;QAClB,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,eAAe,CAAC;QACzD,IAAI,OAAO,EAAE,CAAC;YACZ,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;gBACjD,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,GAAG,CAAC,CAAC;YACrD,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,qBAAqB;QACnB,sDAAsD;QACtD,IAAI,IAAI,CAAC,YAAY,EAAE,cAAc,EAAE,CAAC;YACtC,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,cAAqB,CAAC;YACvD,IAAI,OAAO,MAAM,CAAC,SAAS,KAAK,UAAU,EAAE,CAAC;gBAC3C,MAAM,CAAC,SAAS,EAAE,CAAC;gBACnB,OAAO;YACT,CAAC;QACH,CAAC;QAED,gFAAgF;QAChF,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,eAAe,CAAC;QACzD,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;YAC9C,IAAI,WAAW,EAAE,CAAC;gBAChB,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;oBACrB,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBACtC,CAAC;qBAAM,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;oBAChC,2CAA2C;oBAC3C,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC;;;;;;;;;;;qBAWhB,OAAO;;;WAGjB,CAAC,CAAC;gBACL,CAAC;gBACD,WAAW,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;gBAC7B,WAAW,CAAC,KAAK,EAAE,CAAC;gBACpB,UAAU,CAAC,GAAG,EAAE;oBACd,WAAW,CAAC,KAAK,EAAE,CAAC;oBACpB,WAAW,CAAC,KAAK,EAAE,CAAC;gBACtB,CAAC,EAAE,GAAG,CAAC,CAAC;YACV,CAAC;QACH,CAAC;IACH,CAAC;IAED,qBAAqB;QACnB,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChC,IAAI,CAAC,mBAAmB,GAAG,CAAC,IAAI,CAAC,mBAAmB,CAAC;QACvD,CAAC;IACH,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,OAAgC;QAClD,IAAI,CAAC,qBAAqB,GAAI,OAAO,CAAC,aAAwB,IAAI,CAAC,CAAC;QACpE,IAAI,CAAC,mBAAmB,GAAG,KAAK,CAAC;QAEjC,6EAA6E;QAC7E,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAC9D,IAAI,WAAW,EAAE,CAAC;YAChB,IAAI,CAAC,eAAe,GAAG,WAAW,CAAC;YACnC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC;QAClE,CAAC;QAED,kDAAkD;QAClD,MAAM,OAAO,CAAC,GAAG,CAAC;YAChB,IAAI,CAAC,qBAAqB,EAAE;YAC5B,IAAI,CAAC,0BAA0B,EAAE;YACjC,IAAI,CAAC,aAAa,EAAE;SACrB,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC3B,CAAC;IAED,KAAK,CAAC,eAAe;QACnB,0CAA0C;QAC1C,iDAAiD;QACjD,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC;YAClC,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,qBAAqB,EAAE,IAAI,CAAC,qBAAqB;SAClD,CAAC,CAAC;IACL,CAAC;IAED,IAAI,qBAAqB;QACvB,qEAAqE;QACrE,+DAA+D;QAC/D,MAAM,QAAQ,GAAG,IAAI,CAAC,yBAAyB;aAC5C,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC;aAC7B,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;QACtC,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,iBAAiB,CAAC,aAAuB;QAC7C,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACnD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC;YAC9B,IAAI,YAAY,GAAG,CAAC,CAAC;YAErB,yDAAyD;YACzD,MAAM,gBAAgB,GAAG,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;YAClD,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBACtB,OAAO,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;gBACjD,qBAAqB,CAAC,QAAQ,CAAC,wBAAwB,CACrD,kCAAkC,EAClC,OAAO,CACR,CAAC;gBACF,OAAO,KAAK,CAAC;YACf,CAAC;YAED,oDAAoD;YACpD,KAAK,MAAM,YAAY,IAAI,aAAa,EAAE,CAAC;gBACzC,0EAA0E;gBAC1E,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;gBAC5D,MAAM,cAAc,GAAG,MAAM,EAAE,CAAC,OAAO,CAA6B;oBAClE,UAAU,EAAE,0BAA0B;oBACtC,WAAW,EAAE,iBAAiB,YAAY,4BAA4B,gBAAgB,GAAG;oBACzF,UAAU,EAAE,eAAe;iBAC5B,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;gBAErB,IAAI,cAAc,CAAC,OAAO,IAAI,cAAc,CAAC,OAAO,IAAI,cAAc,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC1F,SAAS;gBACX,CAAC;gBAED,yCAAyC;gBACzC,MAAM,kBAAkB,GAAG,MAAM,EAAE,CAAC,eAAe,CAA6B,0BAA0B,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;gBAC9H,kBAAkB,CAAC,YAAY,GAAG,YAAY,CAAC;gBAC/C,kBAAkB,CAAC,iBAAiB,GAAG,gBAAgB,CAAC;gBACxD,kBAAkB,CAAC,QAAQ,GAAG,CAAC,CAAC;gBAEhC,MAAM,KAAK,GAAG,MAAM,kBAAkB,CAAC,IAAI,EAAE,CAAC;gBAC9C,IAAI,KAAK,EAAE,CAAC;oBACV,YAAY,EAAE,CAAC;gBACjB,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,KAAK,CAAC,iDAAiD,YAAY,EAAE,CAAC,CAAC;gBACjF,CAAC;YACH,CAAC;YAED,IAAI,YAAY,GAAG,CAAC,EAAE,CAAC;gBACrB,qBAAqB,CAAC,QAAQ,CAAC,wBAAwB,CACrD,qBAAqB,YAAY,8BAA8B,EAC/D,SAAS,EACT,IAAI,CACL,CAAC;gBAEF,mEAAmE;gBACnE,MAAM,IAAI,CAAC,0BAA0B,EAAE,CAAC;gBACxC,OAAO,IAAI,CAAC;YACd,CAAC;iBAAM,CAAC;gBACN,qBAAqB,CAAC,QAAQ,CAAC,wBAAwB,CACrD,4CAA4C,EAC5C,OAAO,CACR,CAAC;gBACF,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,GAAG,CAAC,CAAC;YACnD,QAAQ,CAAC,GAAG,CAAC,CAAC;YACd,qBAAqB,CAAC,QAAQ,CAAC,wBAAwB,CACrD,yDAAyD,EACzD,OAAO,CACR,CAAC;YACF,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,gBAAgB,CAC5B,iBAA4E,EAC5E,gBAA2E;QAE3E,IAAI,CAAC,IAAI,CAAC,UAAU;YAAE,OAAO;QAE7B,0EAA0E;QAC1E,IAAI,CAAC,cAAc,EAAE,CAAC;QAEtB,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC;YAC9B,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YAE5D,2DAA2D;YAC3D,IAAI,cAAc,GAA8B,EAAE,CAAC;YACnD,IAAI,iBAAiB,EAAE,OAAO,IAAI,iBAAiB,CAAC,OAAO,EAAE,CAAC;gBAC5D,cAAc,GAAG,iBAAiB,CAAC,OAAO,CAAC;YAC7C,CAAC;iBAAM,CAAC;gBACN,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAkE;oBAC/F,UAAU,EAAE,0BAA0B;oBACtC,WAAW,EAAE;2EACoD,IAAI,CAAC,UAAU;YAC9E;oBACF,MAAM,EAAE,CAAC,IAAI,EAAE,cAAc,EAAE,mBAAmB,CAAC;oBACnD,UAAU,EAAE,QAAQ;iBACrB,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;gBACrB,cAAc,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAA8B,CAAC;YACvF,CAAC;YAED,wDAAwD;YACxD,MAAM,aAAa,GAAG,CAAC,GAAG,IAAI,GAAG,CAC/B,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC,YAAY,CAAW,CAAC,CAC5E,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAEnB,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC7B,MAAM,iBAAiB,GAAG,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBAC7E,MAAM,uBAAuB,GAAG,MAAM,EAAE,CAAC,OAAO,CAAqB;oBACnE,UAAU,EAAE,iBAAiB;oBAC7B,WAAW,EAAE,iBAAiB;oBAC9B,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,CAAC;oBAC/C,UAAU,EAAE,QAAQ;iBACrB,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;gBAErB,IAAI,uBAAuB,CAAC,OAAO,IAAI,uBAAuB,CAAC,OAAO,EAAE,CAAC;oBACvE,IAAI,CAAC,cAAc,GAAG,uBAAuB,CAAC,OAA0C,CAAC;gBAC3F,CAAC;YACH,CAAC;YAED,6EAA6E;YAC7E,IAAI,cAAc,GAA8B,EAAE,CAAC;YACnD,IAAI,gBAAgB,EAAE,OAAO,IAAI,gBAAgB,CAAC,OAAO,EAAE,CAAC;gBAC1D,cAAc,GAAG,gBAAgB,CAAC,OAAO,CAAC;YAC5C,CAAC;iBAAM,CAAC;gBACN,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACnD,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC1B,MAAM,aAAa,GAAG,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,sBAAsB,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;oBACrF,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAA0E;wBACvG,UAAU,EAAE,mCAAmC;wBAC/C,WAAW,EAAE,aAAa;wBAC1B,MAAM,EAAE,CAAC,IAAI,EAAE,sBAAsB,EAAE,mBAAmB,CAAC;wBAC3D,OAAO,EAAE,CAAC;wBACV,UAAU,EAAE,QAAQ;qBACrB,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;oBACrB,cAAc,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAA8B,CAAC;gBACvF,CAAC;YACH,CAAC;YAED,6CAA6C;YAC7C,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC9B,MAAM,oBAAoB,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,sBAAsB,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAW,CAAC;gBAC7H,MAAM,iBAAiB,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAW,CAAC;gBAEpH,IAAI,CAAC,2BAA2B,GAAG,iBAAiB,CAAC;gBAErD,kDAAkD;gBAClD,MAAM,kBAAkB,GAAG,MAAM,EAAE,CAAC,eAAe,CAA6B,0BAA0B,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;gBAC9H,MAAM,YAAY,GAAG,MAAM,kBAAkB,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;gBAEzE,IAAI,YAAY,IAAI,kBAAkB,CAAC,cAAc,EAAE,CAAC;oBACtD,MAAM,YAAY,GAAG,MAAM,EAAE,CAAC,eAAe,CAAuB,mBAAmB,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;oBAC3G,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAC;oBAE1E,IAAI,MAAM,EAAE,CAAC;wBACX,IAAI,CAAC,kBAAkB,GAAG,YAAY,CAAC;wBAEvC,qDAAqD;wBACrD,MAAM,WAAW,GAAG,UAAU,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;wBAEzE,MAAM,iBAAiB,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC;4BACzC,UAAU,EAAE,0BAA0B;4BACtC,WAAW,EAAE,mBAAmB,YAAY,CAAC,EAAE,iBAAiB,IAAI,CAAC,WAAW,CAAC,EAAE,GAAG;4BACtF,OAAO,EAAE,CAAC;4BACV,MAAM,EAAE,CAAC,IAAI,CAAC;4BACd,UAAU,EAAE,QAAQ;yBACrB,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;wBAErB,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,OAAO;4BACxB,iBAAiB,CAAC,OAAO;4BACzB,iBAAiB,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;wBAEhE,IAAI,CAAC,6BAA6B,GAAG,WAAW,IAAI,iBAAiB,CAAC;oBACxE,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,2BAA2B,EAAE,KAAK,CAAC,CAAC;QACpD,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAC3B,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,aAAa;QACzB,OAAO,IAAI,CAAC,gBAAgB,EAAE,CAAC;IACjC,CAAC;IAED,IAAI,WAAW;QACb,MAAM,KAAK,GAA+F,EAAE,CAAC;QAE7G,sCAAsC;QACtC,MAAM,gBAAgB,GAAG,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;QAElD,4DAA4D;QAC5D,4DAA4D;QAC5D,IAAI,IAAI,CAAC,WAAW,KAAK,cAAc,EAAE,CAAC;YACxC,8DAA8D;YAC9D,KAAK,MAAM,UAAU,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;gBAC7C,KAAK,CAAC,IAAI,CAAC;oBACT,IAAI,EAAE,YAAY;oBAClB,EAAE,EAAE,UAAU,CAAC,EAAE;oBACjB,IAAI,EAAE,UAAU,CAAC,IAAI;oBACrB,SAAS,EAAE,IAAI;iBAChB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;aAAM,IAAI,IAAI,CAAC,WAAW,KAAK,YAAY,EAAE,CAAC;YAC7C,wCAAwC;YACxC,sFAAsF;YACtF,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBAC5B,KAAK,CAAC,IAAI,CAAC;oBACT,IAAI,EAAE,cAAc;oBACpB,EAAE,EAAE,IAAI,CAAC,kBAAkB,CAAC,EAAE;oBAC9B,IAAI,EAAE,IAAI,CAAC,kBAAkB,CAAC,IAAI,IAAI,uBAAuB;oBAC7D,SAAS,EAAE,IAAI,CAAC,6BAA6B;iBAC9C,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QACD,kDAAkD;QAElD,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;OAEG;IACH,gBAAgB,CAAC,IAAyF;QACxG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,OAAO;QACT,CAAC;QAED,4GAA4G;QAC5G,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;YACvB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,aAAa,EAAE,IAAI,CAAC,qBAAqB;YACzC,SAAS,EAAE,IAAI,CAAC,eAAe,EAAE,EAAE;SACpC,CAAC,CAAC;IACL,CAAC;IAED,OAAO;QACL,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IACrB,CAAC;IAED,OAAO;QACL,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC5C,CAAC;IAED,gBAAgB;QACd,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC;IAC9B,CAAC;IAED;;;OAGG;IACH,kBAAkB,CAAC,KAAuD;QACxE,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;IAED;;;OAGG;IACH,mBAAmB,CAAC,KAAwB;QAC1C,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrC,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,yBAAyB,CAAC,YAAkC;QACxE,mDAAmD;QACnD,IAAI,YAAY,CAAC,WAAW,EAAE,CAAC;YAC7B,OAAO,YAAY,CAAC,WAAW,CAAC;QAClC,CAAC;QAED,4DAA4D;QAC5D,IAAI,YAAY,CAAC,QAAQ,EAAE,CAAC;YAC1B,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;YAEzE,IAAI,UAAU,EAAE,CAAC;gBACf,2BAA2B;gBAC3B,OAAO,MAAM,IAAI,CAAC,yBAAyB,CAAC,UAAU,CAAC,CAAC;YAC1D,CAAC;QACH,CAAC;QAED,mCAAmC;QACnC,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,mBAAmB,CAAC,EAAU;QAC1C,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC;YAC9B,MAAM,YAAY,GAAG,MAAM,EAAE,CAAC,eAAe,CAAuB,oBAAoB,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;YAC5G,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAE3C,IAAI,MAAM,EAAE,CAAC;gBACX,OAAO,YAAY,CAAC;YACtB,CAAC;YAED,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,oCAAoC,EAAE,GAAG,CAAC,CAAC;YACzD,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED;;OAEG;IACK,UAAU,CAAC,OAAe;QAChC,IAAI,CAAC;YACH,2CAA2C;YAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAEhC,iEAAiE;YACjE,MAAM,YAAY,GAAqB;gBACrC,iBAAiB,EAAE,IAAI;gBACvB,QAAQ,EAAE,GAAG;gBACb,KAAK,EAAE,KAAK;aACb,CAAC;YACF,MAAM,MAAM,GAAG,kBAAkB,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;YAErD,oCAAoC;YACpC,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QACzC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,iEAAiE;YACjE,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBAChC,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YACtC,CAAC;YAAC,OAAO,EAAE,EAAE,CAAC;gBACZ,2CAA2C;gBAC3C,OAAO,OAAO,CAAC;YACjB,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACI,UAAU,CAAC,OAAe;QAC/B,YAAY;QACZ,MAAM,SAAS,GAA2B;YACxC,SAAS,EAAE,YAAY;YACvB,MAAM,EAAE,aAAa;YACrB,MAAM,EAAE,kBAAkB;YAC1B,SAAS,EAAE,oBAAoB;YAC/B,OAAO,EAAE,aAAa;SACvB,CAAC;QAEF,IAAI,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;YACvB,OAAO,SAAS,CAAC,OAAO,CAAC,CAAC;QAC5B,CAAC;QAED,oBAAoB;QACpB,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,EAAE,cAAc,CAAC;QACjD,IAAI,MAAM,EAAE,iBAAiB,EAAE,CAAC;YAC9B,MAAM,SAAS,GAAG,MAAM,CAAC,iBAAiB,EAAE,CAAC,IAAI,CAAC,CAAC,CAAoB,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,OAAO,CAAC,CAAC;YACjG,IAAI,SAAS,EAAE,IAAI,EAAE,CAAC;gBACpB,OAAO,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,iCAAiC;YACnE,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACI,YAAY,CAAC,OAAe;QACjC,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IACzC,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,kBAAkB,CAAC,SAAgE;QAC/F,IAAI,CAAC;YACH,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,EAAE,CAAC;gBACvD,OAAO;YACT,CAAC;YAED,MAAM,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC;YAC9B,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,eAAe,CAAsB,mBAAmB,CAAC,CAAC;YAEjF,KAAK,CAAC,iBAAiB,GAAG,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC;YAClD,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;YACnC,KAAK,CAAC,SAAS,GAAG,SAAS,CAAC;YAC5B,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC;gBAClC,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;gBAC7C,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACpC,CAAC,CAAC;YAEH,uCAAuC;YACvC,KAAK,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;gBACzB,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,KAAK,CAAC,CAAC;YAC1D,CAAC,CAAC,CAAC;QAEL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,gCAAgC,EAAE,KAAK,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,mFAAmF;IAC5E,YAAY,GAAW,SAAS,CAAC;IAExC,sDAAsD;IAC9C,kBAAkB;QACxB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,QAAQ;YAC/B,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC;YACzD,CAAC,CAAC,SAAS,CAAC;IAChB,CAAC;IAED;;;OAGG;IACI,SAAS;QACd,MAAM,QAAQ,GAAG,IAAI,CAAC,uBAAuB,EAAE,CAAC;QAChD,IAAI,QAAQ,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC9B,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC;gBACzB,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE;gBAC5B,QAAQ;aACT,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,mBAAmB,CAAC,wBAAwB,CAC/C,8BAA8B,EAC9B,SAAS,EACT,IAAI,CACL,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;;OAGG;IACI,uBAAuB;QAC5B,OAAO,IAAI,CAAC,YAAY,EAAE,cAAc,EAAE,uBAAuB,EAAE,IAAI,IAAI,CAAC;IAC9E,CAAC;sHApuCU,4BAA4B;6DAA5B,4BAA4B;2BAyB5B,iCAAiC;;;;;YC7C9C,8BAAmE;YACjE,gGAAkB;YA+ElB,8BAA2B;YACzB,8FAAiB;YAOjB,8FAAa;YAOb,gGAAwC;YA+N5C,AADE,iBAAM,EACF;;YA9T6B,4CAA+B;YAChE,cA6EC;YA7ED,yCA6EC;YAGC,eAKC;YALD,wCAKC;YAED,cAKC;YALD,oCAKC;YAED,cA6NC;YA7ND,uEA6NC;;;iFDxSQ,4BAA4B;cANxC,SAAS;6BACI,KAAK,YACP,0BAA0B;;kBAKnC,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBACL,MAAM;;kBACN,MAAM;;kBACN,MAAM;;kBACN,MAAM;;kBACN,MAAM;;kBACN,MAAM;;kBACN,MAAM;;kBACN,MAAM;;kBAEN,SAAS;mBAAC,iCAAiC;;kFAzBjC,4BAA4B","sourcesContent":["import { Component, Input, Output, EventEmitter, OnInit, OnChanges, OnDestroy, SimpleChanges, ViewChild, ViewContainerRef, ComponentRef, Type, ChangeDetectorRef } from '@angular/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\nimport { UserInfo, Metadata, RunView, LogError, CompositeKey, DataSnapshot } from '@memberjunction/core';\nimport { ParseJSONRecursive, ParseJSONOptions , UUIDsEqual } from '@memberjunction/global';\nimport { MJArtifactEntity, MJArtifactVersionEntity, MJArtifactVersionAttributeEntity, MJArtifactTypeEntity, MJCollectionEntity, MJCollectionArtifactEntity, ArtifactMetadataEngine, MJConversationEntity, MJConversationDetailArtifactEntity, MJConversationDetailEntity, MJArtifactUseEntity } from '@memberjunction/core-entities';\nimport { MJNotificationService } from '@memberjunction/ng-notifications';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { ArtifactTypePluginViewerComponent } from './artifact-type-plugin-viewer.component';\nimport { ArtifactViewerTab, NavigationRequest } from './base-artifact-viewer.component';\nimport { ArtifactIconService } from '../services/artifact-icon.service';\nimport { RecentAccessService } from '@memberjunction/ng-shared-generic';\n\n@Component({\n standalone: false,\n selector: 'mj-artifact-viewer-panel',\n templateUrl: './artifact-viewer-panel.component.html',\n styleUrls: ['./artifact-viewer-panel.component.css']\n})\nexport class ArtifactViewerPanelComponent extends BaseAngularComponent implements OnInit, OnChanges, OnDestroy {\n @Input() artifactId!: string;\n @Input() currentUser!: UserInfo;\n @Input() environmentId!: string;\n @Input() versionNumber?: number; // Version to display\n @Input() showSaveToCollection: boolean = true; // Control whether Save to Collection button is shown\n @Input() showHeader: boolean = true; // Control whether the header section is shown\n @Input() showTabs: boolean = true; // Control whether the tab navigation is shown (false = show only Display tab content)\n @Input() showCloseButton: boolean = true; // Control whether the close button is shown in header\n @Input() showMaximizeButton: boolean = true; // Control whether the maximize/restore button is shown in header\n @Input() refreshTrigger?: Subject<{artifactId: string; versionNumber: number}>;\n @Input() viewContext: 'conversation' | 'collection' | null = null; // Where artifact is being viewed\n @Input() contextCollectionId?: string; // If viewing in collection, which collection\n @Input() canShare?: boolean; // Whether user can share this artifact\n @Input() canEdit?: boolean; // Whether user can edit this artifact\n @Input() isMaximized: boolean = false; // Whether the panel is currently maximized\n @Output() closed = new EventEmitter<void>();\n @Output() saveToCollectionRequested = new EventEmitter<{artifactId: string; excludedCollectionIds: string[]}>();\n @Output() navigateToLink = new EventEmitter<{type: 'conversation' | 'collection'; id: string; artifactId?: string; versionNumber?: number; versionId?: string}>();\n @Output() shareRequested = new EventEmitter<string>(); // Emits artifactId when share is clicked\n @Output() maximizeToggled = new EventEmitter<void>(); // Emits when user clicks maximize/restore button\n @Output() openEntityRecord = new EventEmitter<{entityName: string; compositeKey: CompositeKey}>();\n @Output() navigationRequest = new EventEmitter<NavigationRequest>();\n @Output() analyzeRequested = new EventEmitter<{ artifactId: string; snapshot: DataSnapshot }>();\n\n @ViewChild(ArtifactTypePluginViewerComponent) pluginViewer?: ArtifactTypePluginViewerComponent;\n\n private destroy$ = new Subject<void>();\n\n public artifact: MJArtifactEntity | null = null;\n public artifactVersion: MJArtifactVersionEntity | null = null;\n public allVersions: MJArtifactVersionEntity[] = [];\n public selectedVersionNumber: number = 1;\n public isLoading = true;\n public error: string | null = null;\n public jsonContent = '';\n public showVersionDropdown = false;\n public artifactCollections: MJCollectionArtifactEntity[] = []; // All collections for ALL versions\n public currentVersionCollections: MJCollectionArtifactEntity[] = []; // Collections containing CURRENT version only\n public primaryCollection: MJCollectionEntity | null = null;\n\n // Tabbed interface\n public activeTab: string = 'display'; // Changed to string to support dynamic tabs\n public displayMarkdown: string | null = null;\n public displayHtml: string | null = null;\n public versionAttributes: MJArtifactVersionAttributeEntity[] = [];\n private artifactTypeDriverClass: string | null = null;\n /** Populated from ArtifactType.ContentCategory. Used to suppress the JSON tab for\n * binary file-type artifacts — driven by metadata, not hardcoded plugin overrides. */\n private artifactContentCategory: 'File' | 'Text' | null = null;\n\n // Links tab data\n public originConversation: MJConversationEntity | null = null;\n public allCollections: MJCollectionEntity[] = [];\n public hasAccessToOriginConversation: boolean = false;\n public originConversationVersionId: string | null = null; // Version ID that came from origin conversation\n\n // Dynamic tabs from plugin\n public get allTabs(): string[] {\n const tabs: string[] = [];\n\n // Only add Display tab if there's content to display\n if (this.hasDisplayTab) {\n tabs.push('Display');\n }\n\n // Get plugin tabs directly from plugin instance (no caching needed - plugin always exists)\n if (this.pluginViewer?.pluginInstance?.GetAdditionalTabs) {\n const pluginTabs = this.pluginViewer.pluginInstance.GetAdditionalTabs();\n const pluginTabLabels = pluginTabs.map((t: ArtifactViewerTab) => t.label);\n tabs.push(...pluginTabLabels);\n }\n\n // Get tabs to remove from plugin (case-insensitive)\n const removals = this.pluginViewer?.pluginInstance?.GetStandardTabRemovals?.() || [];\n const removalsLower = removals.map(r => r.toLowerCase());\n\n // File-category artifacts (PDF, Excel, Word) have binary content — the JSON tab\n // would show a base64 blob or a storage reference, which is meaningless. Suppress it\n // using ArtifactType.ContentCategory from the database rather than a hardcoded plugin override.\n const isFileArtifact = this.artifactContentCategory === 'File';\n\n // Add standard tabs (unless suppressed by metadata or plugin)\n if (!isFileArtifact && !removalsLower.includes('json')) {\n tabs.push('JSON');\n }\n if (!removalsLower.includes('details')) {\n tabs.push('Details');\n }\n\n // Only add Links tab if there are links to show (unless plugin explicitly removes it)\n if (!removalsLower.includes('links') && this.linksToShow.length > 0) {\n tabs.push('Links');\n }\n\n return tabs;\n }\n\n /**\n * Get the full tab definition for a given tab name.\n * Returns the ArtifactViewerTab which may include component info for custom component tabs.\n */\n public GetTabDefinition(tabName: string): ArtifactViewerTab | null {\n // Check if this is a plugin-provided tab\n if (this.pluginViewer?.pluginInstance?.GetAdditionalTabs) {\n const pluginTabs = this.pluginViewer.pluginInstance.GetAdditionalTabs();\n const pluginTab = pluginTabs.find((t: ArtifactViewerTab) =>\n t.label.toLowerCase() === tabName.toLowerCase()\n );\n if (pluginTab) {\n return pluginTab;\n }\n }\n\n // Handle base tabs\n switch (tabName.toLowerCase()) {\n case 'json':\n return { label: 'JSON', contentType: 'json', content: this.jsonContent, language: 'json' };\n case 'details':\n return { label: 'Details', contentType: 'html', content: this.displayMarkdown || this.displayHtml || '' };\n default:\n return null;\n }\n }\n\n /**\n * Get resolved tab content for string-based tabs (non-component tabs).\n * For component tabs, use GetTabDefinition() and render the component directly.\n */\n public GetTabContent(tabName: string): { type: string; content: string; language?: string } | null {\n const tabDef = this.GetTabDefinition(tabName);\n if (!tabDef) return null;\n\n // Component tabs don't have string content\n if (tabDef.contentType === 'component') {\n return null;\n }\n\n const content = typeof tabDef.content === 'function'\n ? tabDef.content()\n : tabDef.content || '';\n\n return {\n type: tabDef.contentType,\n content: content,\n language: tabDef.language\n };\n }\n\n /**\n * Check if a tab is a component tab (renders a custom Angular component)\n */\n public IsComponentTab(tabName: string): boolean {\n const tabDef = this.GetTabDefinition(tabName);\n return tabDef?.contentType === 'component' && !!tabDef.component;\n }\n\n /**\n * Get the component type for a component tab.\n * Returns null if the tab is not a component tab (used for template type safety).\n */\n public GetComponentTabType(tabName: string): Type<any> | null {\n const tabDef = this.GetTabDefinition(tabName);\n if (tabDef?.contentType === 'component' && tabDef.component) {\n return tabDef.component;\n }\n return null;\n }\n\n /**\n * Get the component inputs for a component tab\n */\n public GetComponentInputs(tabName: string): Record<string, any> {\n const tabDef = this.GetTabDefinition(tabName);\n if (!tabDef || tabDef.contentType !== 'component') {\n return {};\n }\n return typeof tabDef.componentInputs === 'function'\n ? tabDef.componentInputs()\n : tabDef.componentInputs || {};\n }\n\n private recentAccessService: RecentAccessService;\n\n constructor(\n private cdr: ChangeDetectorRef,\n private notificationService: MJNotificationService,\n private sanitizer: DomSanitizer,\n private artifactIconService: ArtifactIconService\n ) {\n super();\n this.recentAccessService = new RecentAccessService();\n }\n\n async ngOnInit() {\n // Subscribe to refresh trigger for dynamic version changes\n if (this.refreshTrigger) {\n this.refreshTrigger.pipe(takeUntil(this.destroy$)).subscribe(async (data) => {\n if (data.artifactId === this.artifactId) {\n // Reload all versions to get any new ones\n await this.loadArtifact(data.versionNumber);\n }\n });\n }\n\n // Load artifact with specified version if provided\n await this.loadArtifact(this.versionNumber);\n\n // Track that user viewed this artifact\n if (this.artifactVersion?.ID && this.currentUser) {\n this.trackArtifactUsage('Viewed');\n // Also log to User Record Logs for recents feature (fire-and-forget)\n this.recentAccessService.logAccess('MJ: Artifacts', this.artifactId, 'artifact');\n }\n }\n\n async ngOnChanges(changes: SimpleChanges) {\n // Reload artifact when artifactId changes\n if (changes['artifactId'] && !changes['artifactId'].firstChange) {\n await this.loadArtifact(this.versionNumber);\n }\n\n // Switch to new version when versionNumber changes (but artifactId stays the same)\n if (changes['versionNumber'] && !changes['versionNumber'].firstChange) {\n const newVersionNumber = changes['versionNumber'].currentValue;\n if (newVersionNumber != null) {\n // Check if we have metadata for this version (allVersions has lightweight metadata)\n const targetVersion = this.allVersions.find(v => v.VersionNumber === newVersionNumber);\n if (targetVersion) {\n this.selectedVersionNumber = (targetVersion.VersionNumber as number) || 1;\n\n // Load full content for the selected version\n const fullVersion = await this.loadVersionContent(targetVersion.ID);\n if (fullVersion) {\n this.artifactVersion = fullVersion;\n this.jsonContent = this.FormatJSON(fullVersion.Content || '{}');\n }\n\n // Load attributes and collection data in parallel\n await Promise.all([\n this.loadVersionAttributes(),\n this.loadCollectionAssociations(),\n this.loadLinksData()\n ]);\n\n this.cdr.detectChanges();\n } else {\n // Need to reload to get this version (shouldn't normally happen)\n await this.loadArtifact(newVersionNumber);\n }\n }\n }\n }\n\n ngOnDestroy() {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n private async loadArtifact(targetVersionNumber?: number): Promise<void> {\n try {\n this.isLoading = true;\n this.error = null;\n\n // Clear links data from previous artifact to prevent stale Links tab\n this.clearLinksData();\n\n const md = this.ProviderToUse;\n\n // Load artifact — assign to local first to avoid mid-cycle icon flicker\n const artifactEntity = await md.GetEntityObject<MJArtifactEntity>('MJ: Artifacts', this.currentUser);\n const loaded = await artifactEntity.Load(this.artifactId);\n\n if (!loaded) {\n this.error = 'Failed to load artifact';\n return;\n }\n this.artifact = artifactEntity;\n\n // PERF: Batch load version metadata, collection associations, and conversation links\n // in a single RunViews call. Content is excluded here — loaded on-demand for the selected version.\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const batchResults = await rv.RunViews([\n {\n // [0] Version metadata (lightweight — no Content field)\n EntityName: 'MJ: Artifact Versions',\n ExtraFilter: `ArtifactID='${this.artifactId}'`,\n OrderBy: 'VersionNumber DESC',\n Fields: ['ID', 'ArtifactID', 'VersionNumber', 'Name', 'Description', '__mj_CreatedAt', '__mj_UpdatedAt'],\n ResultType: 'simple'\n },\n {\n // [1] Collection associations for all versions of this artifact\n EntityName: 'MJ: Collection Artifacts',\n ExtraFilter: `ArtifactVersionID IN (\n SELECT ID FROM [__mj].[vwArtifactVersions] WHERE ArtifactID='${this.artifactId}'\n )`,\n Fields: ['ID', 'CollectionID', 'ArtifactVersionID', 'Sequence'],\n ResultType: 'simple'\n },\n {\n // [2] Conversation detail artifact links (for Links tab)\n EntityName: 'MJ: Conversation Detail Artifacts',\n ExtraFilter: `ArtifactVersionID IN (\n SELECT ID FROM [__mj].[vwArtifactVersions] WHERE ArtifactID='${this.artifactId}'\n )`,\n Fields: ['ID', 'ConversationDetailID', 'ArtifactVersionID'],\n MaxRows: 1,\n ResultType: 'simple'\n }\n ], this.currentUser);\n\n const [versionsResult, collectionsResult, convDetailResult] = batchResults;\n\n if (!versionsResult.Success || !versionsResult.Results || versionsResult.Results.length === 0) {\n this.error = 'No artifact version found';\n return;\n }\n\n // Store version metadata as simple objects (used for dropdown display)\n this.allVersions = versionsResult.Results as MJArtifactVersionEntity[];\n\n // Determine which version to display\n let selectedVersion: Record<string, unknown> | undefined;\n if (targetVersionNumber) {\n selectedVersion = versionsResult.Results.find(\n (v: Record<string, unknown>) => v.VersionNumber === targetVersionNumber\n );\n }\n // Fall back to latest version (first in DESC order)\n const versionToLoad = selectedVersion || versionsResult.Results[0];\n this.selectedVersionNumber = (versionToLoad.VersionNumber as number) || 1;\n\n // PERF: Start artifact type resolution and selected version content load in parallel\n const [, selectedVersionEntity] = await Promise.all([\n this.loadArtifactType(),\n this.loadVersionContent(versionToLoad.ID as string)\n ]);\n\n if (selectedVersionEntity) {\n this.artifactVersion = selectedVersionEntity;\n this.jsonContent = this.FormatJSON(selectedVersionEntity.Content || '{}');\n } else {\n this.error = 'Failed to load artifact version content';\n return;\n }\n\n // PERF: Process collection and links data in parallel (uses already-fetched batch data)\n await Promise.all([\n this.processCollectionAssociations(collectionsResult),\n this.processLinksData(collectionsResult, convDetailResult)\n ]);\n\n // Load version attributes (depends on selected version being set)\n await this.loadVersionAttributes();\n } catch (err) {\n console.error('Error loading artifact:', err);\n this.error = 'Error loading artifact: ' + (err as Error).message;\n } finally {\n this.isLoading = false;\n this.updateArtifactIcon();\n this.cdr.detectChanges();\n }\n }\n\n /**\n * Load full content for a single version by ID.\n * This avoids downloading Content for ALL versions when only one is displayed.\n */\n private async loadVersionContent(versionId: string): Promise<MJArtifactVersionEntity | null> {\n try {\n const md = this.ProviderToUse;\n const versionEntity = await md.GetEntityObject<MJArtifactVersionEntity>('MJ: Artifact Versions', this.currentUser);\n const loaded = await versionEntity.Load(versionId);\n return loaded ? versionEntity : null;\n } catch (err) {\n console.error('Error loading version content:', err);\n return null;\n }\n }\n\n /**\n * Clear all links-related data to prevent stale data when switching artifacts\n */\n private clearLinksData(): void {\n this.allCollections = [];\n this.originConversation = null;\n this.hasAccessToOriginConversation = false;\n this.originConversationVersionId = null;\n }\n\n private async loadArtifactType(): Promise<void> {\n // Reset on every load so a previous artifact's values don't bleed into the next\n this.artifactTypeDriverClass = null;\n this.artifactContentCategory = null;\n\n if (!this.artifact?.Type) {\n return;\n }\n\n try {\n await ArtifactMetadataEngine.Instance.Config(false, this.currentUser);\n\n const artifactType = ArtifactMetadataEngine.Instance.FindArtifactType(this.artifact.Type);\n if (artifactType) {\n // Resolve DriverClass by traversing parent hierarchy if needed\n this.artifactTypeDriverClass = await this.resolveDriverClassForType(artifactType);\n this.artifactContentCategory = artifactType.ContentCategory;\n }\n } catch (err) {\n console.error('Error loading artifact type:', err);\n // Don't fail the whole load if we can't get the artifact type\n }\n }\n\n private async loadVersionAttributes(): Promise<void> {\n if (!this.artifactVersion) return;\n\n try {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<MJArtifactVersionAttributeEntity>({\n EntityName: 'MJ: Artifact Version Attributes',\n ExtraFilter: `ArtifactVersionID='${this.artifactVersion.ID}'`,\n ResultType: 'simple'\n }, this.currentUser);\n\n if (result.Success && result.Results) {\n this.versionAttributes = result.Results;\n\n // Check for displayMarkdown or displayHtml attributes\n const displayMarkdownAttr = this.versionAttributes.find(a => a.Name?.toLowerCase() === 'displaymarkdown');\n const displayHtmlAttr = this.versionAttributes.find(a => a.Name?.toLowerCase() === 'displayhtml');\n\n // Parse values - they might be JSON-encoded strings\n this.displayMarkdown = this.parseAttributeValue(displayMarkdownAttr?.Value);\n this.displayHtml = this.parseAttributeValue(displayHtmlAttr?.Value);\n\n // Clean up double-escaped characters in HTML (from LLM generation)\n if (this.displayHtml) {\n this.displayHtml = this.cleanEscapedCharacters(this.displayHtml);\n }\n\n // Set active tab to the first available tab\n this.setActiveTabToFirstAvailable();\n }\n } catch (err) {\n console.error('Error loading version attributes:', err);\n } finally {\n this.cdr.detectChanges(); // zone.js 0.15: async RunView doesn't trigger CD\n }\n }\n\n get displayName(): string {\n if (this.artifactVersion?.Name) {\n return this.artifactVersion.Name;\n }\n return this.artifact?.Name || 'Artifact';\n }\n\n get displayDescription(): string | null {\n if (this.artifactVersion?.Description) {\n return this.artifactVersion.Description;\n }\n return this.artifact?.Description || null;\n }\n\n get hasDisplayTab(): boolean {\n // Show Display tab if:\n // 1. We have a plugin AND it reports having content to display, OR\n // 2. We have displayMarkdown or displayHtml attributes from extract rules\n //\n // Note: hasDisplayContent defaults to false in base class, so plugins must\n // explicitly opt-in by overriding to return true when they have content.\n // This prevents showing Display tab before plugin loads or when plugin has no content.\n const pluginHasContent = this.pluginViewer?.pluginInstance?.hasDisplayContent ?? false;\n\n return pluginHasContent || !!this.displayMarkdown || !!this.displayHtml;\n }\n\n get hasPlugin(): boolean {\n // Check if the artifact type has a DriverClass configured\n // If DriverClass is set, we have a plugin available\n return !!this.artifactTypeDriverClass;\n }\n\n get hasJsonTab(): boolean {\n // Query plugin directly (no cache needed - plugin always exists when it should)\n const pluginInstance = this.pluginViewer?.pluginInstance;\n return pluginInstance?.parentShouldShowRawContent || false;\n }\n\n get artifactTypeName(): string {\n return this.artifact?.Type || '';\n }\n\n get contentType(): string | undefined {\n // Try to get content type from artifact type or attributes\n const contentTypeAttr = this.versionAttributes.find(a => a.Name?.toLowerCase() === 'contenttype');\n return contentTypeAttr?.Value || undefined;\n }\n\n get filteredAttributes(): MJArtifactVersionAttributeEntity[] {\n // Filter out displayMarkdown and displayHtml as they're shown in the Display tab\n return this.versionAttributes.filter(attr => {\n const name = attr.Name?.toLowerCase();\n return name !== 'displaymarkdown' && name !== 'displayhtml';\n });\n }\n\n setActiveTab(tab: 'display' | 'json' | 'details' | 'links'): void {\n this.activeTab = tab;\n }\n\n /**\n * Sets the active tab to the first available tab in the list.\n * Called when tabs change or when the currently active tab becomes unavailable.\n */\n private setActiveTabToFirstAvailable(): void {\n const tabs = this.allTabs;\n if (tabs.length > 0) {\n // If current tab is still available, keep it; otherwise switch to first\n const currentTabStillAvailable = tabs.some(t => t.toLowerCase() === this.activeTab.toLowerCase());\n if (!currentTabStillAvailable) {\n this.activeTab = tabs[0].toLowerCase();\n }\n } else {\n // Fallback to details if no tabs available (shouldn't happen)\n this.activeTab = 'details';\n }\n }\n\n /**\n * Called when a plugin's async tab data changes (e.g., ComponentArtifactViewer loads\n * the full spec from the registry after initial render with a stripped spec).\n * Forces re-evaluation of allTabs so new tab labels render correctly.\n */\n onTabsChanged(): void {\n // If Display tab just became available (e.g., after plugin async load),\n // switch to it — it should be the default when present.\n const tabs = this.allTabs;\n if (tabs.length > 0 && tabs[0].toLowerCase() === 'display' && this.activeTab !== 'display') {\n this.activeTab = 'display';\n }\n this.cdr.detectChanges(); // zone.js 0.15: plugin emitted tabsChanged, force CD to re-evaluate allTabs\n }\n\n /**\n * Called when the plugin viewer finishes loading.\n * Selects the first available tab now that plugin tabs are available.\n */\n onPluginLoaded(): void {\n // Now that plugin is loaded, we have accurate tab information\n // Always select the first tab since this is the initial load\n const tabs = this.allTabs;\n if (tabs.length > 0) {\n this.activeTab = tabs[0].toLowerCase();\n }\n this.cdr.detectChanges(); // zone.js 0.15: plugin loaded via async callback, force CD\n }\n\n private parseAttributeValue(value: string | null | undefined): string | null {\n if (!value) return null;\n\n // Check if it's a JSON-encoded string (starts and ends with quotes)\n if (value.startsWith('\"') && value.endsWith('\"')) {\n try {\n return JSON.parse(value);\n } catch (e) {\n console.warn('Failed to parse attribute value as JSON:', e);\n return value;\n }\n }\n\n return value;\n }\n\n /**\n * Clean up double-escaped characters that appear in LLM-generated HTML\n * Removes literal \"\\\\n\" and \"\\\\t\" which cause rendering issues\n */\n private cleanEscapedCharacters(html: string): string {\n // Remove escaped newlines (\\\\n becomes nothing)\n // HTML doesn't need whitespace for formatting, and these cause display issues\n let cleaned = html.replace(/\\\\n/g, '');\n\n // Remove escaped tabs\n cleaned = cleaned.replace(/\\\\t/g, '');\n\n // Remove double-escaped tabs\n cleaned = cleaned.replace(/\\\\\\\\t/g, '');\n\n // Remove double-escaped newlines\n cleaned = cleaned.replace(/\\\\\\\\n/g, '');\n\n return cleaned;\n }\n\n /**\n * Process pre-fetched collection association data.\n * Accepts the batch result from loadArtifact() to avoid duplicate queries.\n */\n private async processCollectionAssociations(\n collectionsResult?: { Success: boolean; Results: Record<string, unknown>[] }\n ): Promise<void> {\n if (!this.artifactId) return;\n\n try {\n // If no pre-fetched data, fetch it (used by selectVersion/saveToCollections reload)\n let collectionRows: Record<string, unknown>[];\n if (collectionsResult?.Success && collectionsResult.Results) {\n collectionRows = collectionsResult.Results;\n } else {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<{ ID: string; CollectionID: string; ArtifactVersionID: string; Sequence: number }>({\n EntityName: 'MJ: Collection Artifacts',\n ExtraFilter: `ArtifactVersionID IN (\n SELECT ID FROM [__mj].[vwArtifactVersions] WHERE ArtifactID='${this.artifactId}'\n )`,\n Fields: ['ID', 'CollectionID', 'ArtifactVersionID', 'Sequence'],\n ResultType: 'simple'\n }, this.currentUser);\n collectionRows = (result.Success ? result.Results : []) as Record<string, unknown>[];\n }\n\n // Store as simple objects — these are read-only display data\n this.artifactCollections = collectionRows as unknown as MJCollectionArtifactEntity[];\n\n // Filter to get only collections containing the CURRENT version\n const currentVersionId = this.artifactVersion?.ID;\n if (currentVersionId) {\n const currentIdStr = String(currentVersionId).toLowerCase();\n this.currentVersionCollections = collectionRows.filter(ca => {\n const versionIdStr = String(ca['ArtifactVersionID'] || ca.ArtifactVersionID || '').toLowerCase();\n return versionIdStr && currentIdStr && versionIdStr === currentIdStr;\n }) as unknown as MJCollectionArtifactEntity[];\n } else {\n this.currentVersionCollections = [];\n }\n\n // Load the primary collection details if exists\n if (this.artifactCollections.length > 0) {\n const collectionId = (collectionRows[0] as Record<string, unknown>).CollectionID as string ||\n (this.artifactCollections[0] as unknown as Record<string, unknown>).CollectionID as string;\n if (collectionId) {\n const md = this.ProviderToUse;\n this.primaryCollection = await md.GetEntityObject<MJCollectionEntity>('MJ: Collections', this.currentUser);\n await this.primaryCollection.Load(collectionId);\n }\n } else {\n this.primaryCollection = null;\n }\n } catch (err) {\n console.error('Error processing collection associations:', err);\n } finally {\n this.cdr.detectChanges();\n }\n }\n\n /**\n * @deprecated Use processCollectionAssociations() instead. Kept as a shim for callers\n * that don't have pre-fetched data (e.g., selectVersion, saveToCollections).\n */\n private async loadCollectionAssociations(): Promise<void> {\n return this.processCollectionAssociations();\n }\n\n get isInCollection(): boolean {\n return this.currentVersionCollections.length > 0;\n }\n\n /**\n * Get collection IDs that already contain the current version\n * Used to exclude them from the save picker\n */\n get currentVersionCollectionIds(): string[] {\n return this.currentVersionCollections.map(ca => ca.CollectionID);\n }\n\n onCopyToClipboard(): void {\n // Get content from the currently active tab instead of always copying jsonContent\n const tabData = this.GetTabContent(this.activeTab);\n if (tabData?.content) {\n navigator.clipboard.writeText(tabData.content);\n } else if (this.jsonContent) {\n // Fallback to jsonContent if tab content not found\n navigator.clipboard.writeText(this.jsonContent);\n }\n }\n\n onCopyDisplayContent(): void {\n const content = this.displayHtml || this.displayMarkdown;\n if (content) {\n navigator.clipboard.writeText(content).catch(err => {\n console.error('Failed to copy to clipboard:', err);\n });\n }\n }\n\n onPrintDisplayContent(): void {\n // Try to delegate to the plugin viewer's print method\n if (this.pluginViewer?.pluginInstance) {\n const plugin = this.pluginViewer.pluginInstance as any;\n if (typeof plugin.printHtml === 'function') {\n plugin.printHtml();\n return;\n }\n }\n\n // Fallback: create a temporary print window with displayHtml or displayMarkdown\n const content = this.displayHtml || this.displayMarkdown;\n if (content) {\n const printWindow = window.open('', '_blank');\n if (printWindow) {\n if (this.displayHtml) {\n printWindow.document.write(content);\n } else if (this.displayMarkdown) {\n // Wrap markdown in basic HTML for printing\n printWindow.document.write(`\n <!DOCTYPE html>\n <html>\n <head>\n <title>Print</title>\n <style>\n body { font-family: sans-serif; padding: 20px; }\n pre { background: #f5f5f5; padding: 10px; border-radius: 4px; }\n </style>\n </head>\n <body>\n <pre>${content}</pre>\n </body>\n </html>\n `);\n }\n printWindow.document.close();\n printWindow.focus();\n setTimeout(() => {\n printWindow.print();\n printWindow.close();\n }, 250);\n }\n }\n }\n\n toggleVersionDropdown(): void {\n if (this.allVersions.length > 1) {\n this.showVersionDropdown = !this.showVersionDropdown;\n }\n }\n\n async selectVersion(version: MJArtifactVersionEntity): Promise<void> {\n this.selectedVersionNumber = (version.VersionNumber as number) || 1;\n this.showVersionDropdown = false;\n\n // Load full content for the selected version (allVersions only has metadata)\n const fullVersion = await this.loadVersionContent(version.ID);\n if (fullVersion) {\n this.artifactVersion = fullVersion;\n this.jsonContent = this.FormatJSON(fullVersion.Content || '{}');\n }\n\n // Load attributes and collection data in parallel\n await Promise.all([\n this.loadVersionAttributes(),\n this.loadCollectionAssociations(),\n this.loadLinksData()\n ]);\n\n this.cdr.detectChanges();\n }\n\n async onSaveToLibrary(): Promise<void> {\n // Always show the collection picker modal\n // Artifacts can be saved to multiple collections\n this.saveToCollectionRequested.emit({\n artifactId: this.artifactId,\n excludedCollectionIds: this.excludedCollectionIds\n });\n }\n\n get excludedCollectionIds(): string[] {\n // Return IDs of collections that already contain the CURRENT VERSION\n // This allows saving different versions to the same collection\n const excluded = this.currentVersionCollections\n .filter(ca => ca.CollectionID)\n .map(ca => String(ca.CollectionID));\n return excluded;\n }\n\n /**\n * Called by parent component after user selects collections in the picker.\n * Saves the artifact to the selected collections.\n */\n async saveToCollections(collectionIds: string[]): Promise<boolean> {\n if (!this.artifactId || collectionIds.length === 0) {\n return false;\n }\n\n try {\n const md = this.ProviderToUse;\n let successCount = 0;\n\n // Get current version ID - save the version being viewed\n const currentVersionId = this.artifactVersion?.ID;\n if (!currentVersionId) {\n console.error('No current version ID available');\n MJNotificationService.Instance.CreateSimpleNotification(\n 'Cannot save: no version selected',\n 'error'\n );\n return false;\n }\n\n // Save artifact version to each selected collection\n for (const collectionId of collectionIds) {\n // Double check this exact version doesn't already exist in the collection\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const existingResult = await rv.RunView<MJCollectionArtifactEntity>({\n EntityName: 'MJ: Collection Artifacts',\n ExtraFilter: `CollectionID='${collectionId}' AND ArtifactVersionID='${currentVersionId}'`,\n ResultType: 'entity_object'\n }, this.currentUser);\n\n if (existingResult.Success && existingResult.Results && existingResult.Results.length > 0) {\n continue;\n }\n\n // Create junction record with version ID\n const collectionArtifact = await md.GetEntityObject<MJCollectionArtifactEntity>('MJ: Collection Artifacts', this.currentUser);\n collectionArtifact.CollectionID = collectionId;\n collectionArtifact.ArtifactVersionID = currentVersionId;\n collectionArtifact.Sequence = 0;\n\n const saved = await collectionArtifact.Save();\n if (saved) {\n successCount++;\n } else {\n console.error(`Failed to save artifact version to collection ${collectionId}`);\n }\n }\n\n if (successCount > 0) {\n MJNotificationService.Instance.CreateSimpleNotification(\n `Artifact saved to ${successCount} collection(s) successfully!`,\n 'success',\n 3000\n );\n\n // Reload collection associations to update the bookmark icon state\n await this.loadCollectionAssociations();\n return true;\n } else {\n MJNotificationService.Instance.CreateSimpleNotification(\n 'Failed to save artifact to any collections',\n 'error'\n );\n return false;\n }\n } catch (err) {\n console.error('Error saving to collections:', err);\n LogError(err);\n MJNotificationService.Instance.CreateSimpleNotification(\n 'Error saving artifact to collections. Please try again.',\n 'error'\n );\n return false;\n }\n }\n\n /**\n * Process links data using pre-fetched batch results from loadArtifact().\n * Reuses collection data from the same batch to avoid duplicate queries.\n */\n private async processLinksData(\n collectionsResult?: { Success: boolean; Results: Record<string, unknown>[] },\n convDetailResult?: { Success: boolean; Results: Record<string, unknown>[] }\n ): Promise<void> {\n if (!this.artifactId) return;\n\n // Clear old links data first to prevent stale data from previous artifact\n this.clearLinksData();\n\n try {\n const md = this.ProviderToUse;\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n\n // Use pre-fetched collection data or fetch if not provided\n let collectionRows: Record<string, unknown>[] = [];\n if (collectionsResult?.Success && collectionsResult.Results) {\n collectionRows = collectionsResult.Results;\n } else {\n const result = await rv.RunView<{ ID: string; CollectionID: string; ArtifactVersionID: string }>({\n EntityName: 'MJ: Collection Artifacts',\n ExtraFilter: `ArtifactVersionID IN (\n SELECT ID FROM [__mj].[vwArtifactVersions] WHERE ArtifactID='${this.artifactId}'\n )`,\n Fields: ['ID', 'CollectionID', 'ArtifactVersionID'],\n ResultType: 'simple'\n }, this.currentUser);\n collectionRows = (result.Success ? result.Results : []) as Record<string, unknown>[];\n }\n\n // Get unique collection IDs and load collection details\n const collectionIds = [...new Set(\n collectionRows.map(ca => (ca['CollectionID'] || ca.CollectionID) as string)\n )].filter(Boolean);\n\n if (collectionIds.length > 0) {\n const collectionsFilter = collectionIds.map(id => `ID='${id}'`).join(' OR ');\n const collectionsEntityResult = await rv.RunView<MJCollectionEntity>({\n EntityName: 'MJ: Collections',\n ExtraFilter: collectionsFilter,\n Fields: ['ID', 'Name', 'UserID', 'Description'],\n ResultType: 'simple'\n }, this.currentUser);\n\n if (collectionsEntityResult.Success && collectionsEntityResult.Results) {\n this.allCollections = collectionsEntityResult.Results as unknown as MJCollectionEntity[];\n }\n }\n\n // Use pre-fetched conversation detail artifact data or fetch if not provided\n let convDetailRows: Record<string, unknown>[] = [];\n if (convDetailResult?.Success && convDetailResult.Results) {\n convDetailRows = convDetailResult.Results;\n } else {\n const versionIds = this.allVersions.map(v => v.ID);\n if (versionIds.length > 0) {\n const versionFilter = versionIds.map(id => `ArtifactVersionID='${id}'`).join(' OR ');\n const result = await rv.RunView<{ ID: string; ConversationDetailID: string; ArtifactVersionID: string }>({\n EntityName: 'MJ: Conversation Detail Artifacts',\n ExtraFilter: versionFilter,\n Fields: ['ID', 'ConversationDetailID', 'ArtifactVersionID'],\n MaxRows: 1,\n ResultType: 'simple'\n }, this.currentUser);\n convDetailRows = (result.Success ? result.Results : []) as Record<string, unknown>[];\n }\n }\n\n // Load origin conversation if we have a link\n if (convDetailRows.length > 0) {\n const conversationDetailId = (convDetailRows[0]['ConversationDetailID'] || convDetailRows[0].ConversationDetailID) as string;\n const artifactVersionId = (convDetailRows[0]['ArtifactVersionID'] || convDetailRows[0].ArtifactVersionID) as string;\n\n this.originConversationVersionId = artifactVersionId;\n\n // Load conversation detail to get conversation ID\n const conversationDetail = await md.GetEntityObject<MJConversationDetailEntity>('MJ: Conversation Details', this.currentUser);\n const detailLoaded = await conversationDetail.Load(conversationDetailId);\n\n if (detailLoaded && conversationDetail.ConversationID) {\n const conversation = await md.GetEntityObject<MJConversationEntity>('MJ: Conversations', this.currentUser);\n const loaded = await conversation.Load(conversationDetail.ConversationID);\n\n if (loaded) {\n this.originConversation = conversation;\n\n // Check if user has access (is owner or participant)\n const userIsOwner = UUIDsEqual(conversation.UserID, this.currentUser.ID);\n\n const participantResult = await rv.RunView({\n EntityName: 'MJ: Conversation Details',\n ExtraFilter: `ConversationID='${conversation.ID}' AND UserID='${this.currentUser.ID}'`,\n MaxRows: 1,\n Fields: ['ID'],\n ResultType: 'simple'\n }, this.currentUser);\n\n const userIsParticipant = participantResult.Success &&\n participantResult.Results &&\n participantResult.Results.length > 0;\n\n this.hasAccessToOriginConversation = userIsOwner || userIsParticipant;\n }\n }\n }\n } catch (error) {\n console.error('Error loading links data:', error);\n } finally {\n this.cdr.detectChanges();\n }\n }\n\n /**\n * @deprecated Use processLinksData() instead. Kept as shim for callers without pre-fetched data.\n */\n private async loadLinksData(): Promise<void> {\n return this.processLinksData();\n }\n\n get linksToShow(): Array<{type: 'conversation' | 'collection'; id: string; name: string; hasAccess: boolean}> {\n const links: Array<{type: 'conversation' | 'collection'; id: string; name: string; hasAccess: boolean}> = [];\n\n // Get current version ID being viewed\n const currentVersionId = this.artifactVersion?.ID;\n\n // RULE: In conversation context, show ONLY collection links\n // RULE: In collection context, show ONLY conversation links\n if (this.viewContext === 'conversation') {\n // Show all collections containing this artifact (any version)\n for (const collection of this.allCollections) {\n links.push({\n type: 'collection',\n id: collection.ID,\n name: collection.Name,\n hasAccess: true\n });\n }\n } else if (this.viewContext === 'collection') {\n // Show origin conversation if it exists\n // Show for ALL versions of the artifact, not just the original version that was added\n if (this.originConversation) {\n links.push({\n type: 'conversation',\n id: this.originConversation.ID,\n name: this.originConversation.Name || 'Untitled Conversation',\n hasAccess: this.hasAccessToOriginConversation\n });\n }\n }\n // If viewContext is null, show nothing (no links)\n\n return links;\n }\n\n /**\n * Navigate to a linked conversation or collection\n */\n onNavigateToLink(link: {type: 'conversation' | 'collection'; id: string; name: string; hasAccess: boolean}): void {\n if (!link.hasAccess) {\n return;\n }\n\n // Include artifact ID, version number, and version ID so destination can show the artifact with correct URL\n this.navigateToLink.emit({\n type: link.type,\n id: link.id,\n artifactId: this.artifactId,\n versionNumber: this.selectedVersionNumber,\n versionId: this.artifactVersion?.ID\n });\n }\n\n onClose(): void {\n this.closed.emit();\n }\n\n onShare(): void {\n this.shareRequested.emit(this.artifactId);\n }\n\n onMaximizeToggle(): void {\n this.maximizeToggled.emit();\n }\n\n /**\n * Handle entity record open request from artifact viewer plugin (React component)\n * Propagates the event up to parent components\n */\n onOpenEntityRecord(event: {entityName: string; compositeKey: CompositeKey}): void {\n this.openEntityRecord.emit(event);\n }\n\n /**\n * Handle navigation request from artifact viewer plugin.\n * Propagates the event up to parent components for app-level navigation.\n */\n onNavigationRequest(event: NavigationRequest): void {\n this.navigationRequest.emit(event);\n }\n\n /**\n * Resolves the DriverClass for an artifact type by traversing up the parent hierarchy.\n * Returns the first DriverClass found, or null if none found in the hierarchy.\n */\n private async resolveDriverClassForType(artifactType: MJArtifactTypeEntity): Promise<string | null> {\n // Check if current artifact type has a DriverClass\n if (artifactType.DriverClass) {\n return artifactType.DriverClass;\n }\n\n // No DriverClass on current type - check if it has a parent\n if (artifactType.ParentID) {\n const parentType = await this.getArtifactTypeById(artifactType.ParentID);\n\n if (parentType) {\n // Recursively check parent\n return await this.resolveDriverClassForType(parentType);\n }\n }\n\n // Reached root with no DriverClass\n return null;\n }\n\n /**\n * Loads an artifact type by ID\n */\n private async getArtifactTypeById(id: string): Promise<MJArtifactTypeEntity | null> {\n try {\n const md = this.ProviderToUse;\n const artifactType = await md.GetEntityObject<MJArtifactTypeEntity>('MJ: Artifact Types', this.currentUser);\n const loaded = await artifactType.Load(id);\n\n if (loaded) {\n return artifactType;\n }\n\n return null;\n } catch (err) {\n console.error('Error loading artifact type by ID:', err);\n return null;\n }\n }\n\n /**\n * Format JSON content using ParseJSONRecursive for deep parsing and formatting\n */\n private FormatJSON(content: string): string {\n try {\n // First parse the JSON string to an object\n const obj = JSON.parse(content);\n\n // Then use ParseJSONRecursive to extract any inline JSON strings\n const parseOptions: ParseJSONOptions = {\n extractInlineJson: true,\n maxDepth: 100,\n debug: false\n };\n const parsed = ParseJSONRecursive(obj, parseOptions);\n\n // Finally stringify with formatting\n return JSON.stringify(parsed, null, 2);\n } catch (e) {\n // Fallback to simple parse/stringify if ParseJSONRecursive fails\n try {\n const obj = JSON.parse(content);\n return JSON.stringify(obj, null, 2);\n } catch (e2) {\n // If even simple parse fails, return as-is\n return content;\n }\n }\n }\n\n /**\n * Get icon class for a tab\n */\n public GetTabIcon(tabName: string): string | null {\n // Base tabs\n const baseIcons: Record<string, string> = {\n 'Display': 'fas fa-eye',\n 'Code': 'fas fa-code',\n 'JSON': 'fas fa-file-code',\n 'Details': 'fas fa-info-circle',\n 'Links': 'fas fa-link'\n };\n\n if (baseIcons[tabName]) {\n return baseIcons[tabName];\n }\n\n // Check plugin tabs\n const plugin = this.pluginViewer?.pluginInstance;\n if (plugin?.GetAdditionalTabs) {\n const pluginTab = plugin.GetAdditionalTabs().find((t: ArtifactViewerTab) => t.label === tabName);\n if (pluginTab?.icon) {\n return 'fas ' + pluginTab.icon; // Ensure full Font Awesome class\n }\n }\n\n return null;\n }\n\n /**\n * Set active tab\n */\n public SetActiveTab(tabName: string): void {\n this.activeTab = tabName.toLowerCase();\n }\n\n /**\n * Track artifact usage event\n */\n private async trackArtifactUsage(usageType: 'Viewed' | 'Opened' | 'Shared' | 'Saved' | 'Exported'): Promise<void> {\n try {\n if (!this.artifactVersion?.ID || !this.currentUser?.ID) {\n return;\n }\n\n const md = this.ProviderToUse;\n const usage = await md.GetEntityObject<MJArtifactUseEntity>('MJ: Artifact Uses');\n\n usage.ArtifactVersionID = this.artifactVersion.ID;\n usage.UserID = this.currentUser.ID;\n usage.UsageType = usageType;\n usage.UsageContext = JSON.stringify({\n viewContext: this.viewContext,\n contextCollectionId: this.contextCollectionId,\n timestamp: new Date().toISOString()\n });\n\n // Save asynchronously - don't block UI\n usage.Save().catch(error => {\n console.error('Failed to track artifact usage:', error);\n });\n\n } catch (error) {\n console.error('Error tracking artifact usage:', error);\n }\n }\n\n /**\n * Get the icon for this artifact using the centralized icon service.\n * Fallback priority: Plugin icon > Metadata icon > Hardcoded mapping > Generic icon\n */\n /** Cached icon class — set once after artifact loads to avoid mid-cycle flicker */\n public artifactIcon: string = 'fa-file';\n\n /** Update the cached icon from the loaded artifact */\n private updateArtifactIcon(): void {\n this.artifactIcon = this.artifact\n ? this.artifactIconService.getArtifactIcon(this.artifact)\n : 'fa-file';\n }\n\n /**\n * Capture the current snapshot and emit an analyze event.\n * The parent component handles routing this to an agent conversation.\n */\n public OnAnalyze(): void {\n const snapshot = this.GetCurrentStateSnapshot();\n if (snapshot && this.artifact) {\n this.analyzeRequested.emit({\n artifactId: this.artifact.ID,\n snapshot\n });\n } else {\n this.notificationService.CreateSimpleNotification(\n 'No data available to analyze',\n 'warning',\n 3000\n );\n }\n }\n\n /**\n * Passthrough to the active plugin's GetCurrentStateSnapshot().\n * Returns null if no plugin is loaded or the plugin has no snapshot.\n */\n public GetCurrentStateSnapshot(): DataSnapshot | null {\n return this.pluginViewer?.pluginInstance?.GetCurrentStateSnapshot() ?? null;\n }\n}\n","<div class=\"artifact-viewer-panel\" [class.no-header]=\"!showHeader\">\n @if (showHeader) {\n <div class=\"panel-header\">\n <div class=\"panel-header-left\">\n <h3>\n <i class=\"fas\" [ngClass]=\"artifactIcon\"></i>\n {{ displayName }}\n </h3>\n @if (displayDescription) {\n <p class=\"header-description\">{{ displayDescription }}</p>\n }\n </div>\n <div class=\"panel-header-right\">\n <div class=\"version-selector\"\n [class.clickable]=\"allVersions.length > 1 && viewContext !== 'collection'\"\n (click)=\"viewContext !== 'collection' && toggleVersionDropdown()\">\n <i class=\"fas fa-history\"></i>\n <span class=\"version-label\">v{{ selectedVersionNumber }}</span>\n @if (allVersions.length > 1 && viewContext !== 'collection') {\n <i class=\"fas fa-chevron-down dropdown-icon\" [class.open]=\"showVersionDropdown\"></i>\n }\n @if (showVersionDropdown) {\n <div class=\"version-dropdown\" (click)=\"$event.stopPropagation()\">\n @for (version of allVersions; track version.ID) {\n <div class=\"version-option\"\n [class.selected]=\"version.VersionNumber === selectedVersionNumber\"\n (click)=\"selectVersion(version); $event.stopPropagation()\">\n <span class=\"version-number\">v{{ version.VersionNumber }}</span>\n <span class=\"version-date\">{{ version.__mj_CreatedAt | date:'short' }}</span>\n @if (version.VersionNumber === selectedVersionNumber) {\n <i class=\"fas fa-check\"></i>\n }\n </div>\n }\n </div>\n }\n </div>\n @if (pluginViewer?.SupportsFeedback) {\n <button class=\"feedback-btn\"\n (click)=\"pluginViewer?.AskUserForFeedback()\"\n title=\"Inspect & rate components\">\n <i class=\"fas fa-star-half-stroke\"></i>\n </button>\n }\n @if (showSaveToCollection) {\n <button class=\"save-to-collection-btn\"\n [class.in-collection]=\"isInCollection\"\n (click)=\"onSaveToLibrary()\"\n [title]=\"isInCollection ? 'Current version saved to ' + currentVersionCollections.length + ' collection(s)' : 'Save to Collection'\">\n <i [class]=\"isInCollection ? 'fas fa-bookmark' : 'far fa-bookmark'\"></i>\n </button>\n }\n @if (canShare) {\n <button class=\"share-btn\"\n (click)=\"onShare()\"\n title=\"Share\">\n <i class=\"fas fa-share-nodes\"></i>\n </button>\n }\n <button class=\"analyze-btn\"\n (click)=\"OnAnalyze()\"\n title=\"Analyze this artifact with AI\">\n <i class=\"fas fa-magnifying-glass-chart\"></i>\n </button>\n @if (showMaximizeButton) {\n <button class=\"maximize-btn\"\n (click)=\"onMaximizeToggle()\"\n [title]=\"isMaximized ? 'Restore Width' : 'Maximize Width'\">\n <i class=\"fas\" [ngClass]=\"isMaximized ? 'fa-compress-arrows-alt' : 'fa-arrows-left-right'\"></i>\n </button>\n }\n @if (showCloseButton) {\n <button class=\"close-btn\" (click)=\"onClose()\" title=\"Close\">\n <i class=\"fas fa-times\"></i>\n </button>\n }\n </div>\n </div>\n }\n\n <div class=\"panel-content\">\n @if (isLoading) {\n <div class=\"loading-state\">\n <i class=\"fas fa-spinner fa-spin\"></i>\n <span>Loading artifact...</span>\n </div>\n }\n\n @if (error) {\n <div class=\"error-state\">\n <i class=\"fas fa-exclamation-triangle\"></i>\n <span>{{ error }}</span>\n </div>\n }\n\n @if (!isLoading && !error && artifact) {\n <div class=\"artifact-content-wrapper\" [class.no-tabs]=\"!showTabs\">\n <!-- Tab Navigation (Dynamic) - Hidden when showTabs is false -->\n @if (showTabs) {\n <div class=\"tab-navigation\">\n @for (tab of allTabs; track tab) {\n <button class=\"tab-btn\"\n [class.active]=\"activeTab === tab.toLowerCase()\"\n (click)=\"SetActiveTab(tab)\">\n @if (GetTabIcon(tab)) {\n <i [class]=\"GetTabIcon(tab)!\"></i>\n }\n {{ tab }}\n </button>\n }\n </div>\n }\n\n <!-- Tab Content (Dynamic) -->\n <div class=\"tab-content\">\n <!-- Plugin Viewer - Created once, kept alive, shown/hidden with CSS -->\n @if (hasPlugin && artifactVersion && artifactTypeName) {\n <div class=\"plugin-container\" [class.plugin-hidden]=\"activeTab !== 'display'\">\n <mj-artifact-type-plugin-viewer\n [artifactVersion]=\"artifactVersion\"\n [artifactTypeName]=\"artifactTypeName\"\n [contentType]=\"contentType\"\n [readonly]=\"true\"\n (openEntityRecord)=\"onOpenEntityRecord($event)\"\n (navigationRequest)=\"onNavigationRequest($event)\"\n (pluginLoaded)=\"onPluginLoaded()\"\n (tabsChanged)=\"onTabsChanged()\">\n </mj-artifact-type-plugin-viewer>\n </div>\n }\n\n <!-- Display Tab - Fallback content when no plugin -->\n @if (activeTab === 'display' && (!hasPlugin || !artifactVersion)) {\n <div class=\"display-content\">\n @if (displayMarkdown || displayHtml) {\n <!-- Fallback to extracted markdown/HTML attributes -->\n <div class=\"display-toolbar\">\n <button class=\"btn-icon\" title=\"Print\" (click)=\"onPrintDisplayContent()\">\n <i class=\"fas fa-print\"></i> Print\n </button>\n <button class=\"btn-icon\" title=\"Copy Content\" (click)=\"onCopyDisplayContent()\">\n <i class=\"fas fa-copy\"></i> Copy\n </button>\n </div>\n @if (displayMarkdown) {\n <div class=\"markdown-content\">\n <mj-markdown [data]=\"displayMarkdown\"\n [enableCollapsibleHeadings]=\"true\"\n [enableLineNumbers]=\"true\"\n [enableSmartypants]=\"true\"\n [enableHtml]=\"true\"></mj-markdown>\n </div>\n } @else if (displayHtml) {\n <div class=\"html-content\" [innerHTML]=\"displayHtml\"></div>\n }\n }\n </div>\n }\n\n <!-- Details Tab - Artifact metadata (always in DOM, hidden with CSS) -->\n <div class=\"details-content\" [class.tab-hidden]=\"activeTab !== 'details'\">\n <div class=\"artifact-meta\">\n <div class=\"meta-item\">\n <label>Type</label>\n <span>{{ artifact.Type }}</span>\n </div>\n <div class=\"meta-item\">\n <label>Version</label>\n <span>{{ artifactVersion?.VersionNumber || 1 }}</span>\n </div>\n <div class=\"meta-item\">\n <label>Created</label>\n <span>{{ artifact.__mj_CreatedAt | date:'short' }}</span>\n </div>\n <div class=\"meta-item\">\n <label>Updated</label>\n <span>{{ artifactVersion?.__mj_UpdatedAt | date:'short' }}</span>\n </div>\n @if (artifact.Description) {\n <div class=\"meta-item full-width\">\n <label>Artifact Description</label>\n <span>{{ artifact.Description }}</span>\n </div>\n }\n @if (artifactVersion?.Description && artifact.Description && artifactVersion?.Description !== artifact.Description) {\n <div class=\"meta-item full-width\">\n <label>Version Description</label>\n <span>{{ artifactVersion?.Description }}</span>\n </div>\n }\n </div>\n\n <!-- Version Attributes -->\n @if (filteredAttributes.length > 0) {\n <div class=\"attributes-section\">\n <h4>Version Attributes</h4>\n <div class=\"attributes-list\">\n @for (attr of filteredAttributes; track attr.ID) {\n <div class=\"attribute-item\">\n <label>{{ attr.Name }}</label>\n @if (attr.Value) {\n <span>{{ attr.Value }}</span>\n } @else {\n <span class=\"attribute-empty-pill\">Empty</span>\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Links Tab - Conversations and Collections (always in DOM, hidden with CSS) -->\n <div class=\"links-container\" [class.tab-hidden]=\"activeTab !== 'links'\">\n @if (linksToShow.length > 0) {\n <div class=\"links-section\">\n @for (link of linksToShow; track link.id) {\n <div class=\"link-item\"\n [class.disabled]=\"!link.hasAccess\"\n [class.clickable]=\"link.hasAccess\"\n (click)=\"link.hasAccess ? onNavigateToLink(link) : null\"\n [title]=\"link.hasAccess ? 'Click to open' : 'No access'\">\n <div class=\"link-icon\">\n @if (link.type === 'conversation') {\n <i class=\"fas fa-comments\"></i>\n } @else {\n <i class=\"fas fa-folder\"></i>\n }\n </div>\n <div class=\"link-content\">\n <div class=\"link-name\">{{ link.name }}</div>\n <div class=\"link-type\">{{ link.type === 'conversation' ? 'Conversation' : 'Collection' }}</div>\n </div>\n <div class=\"link-actions\">\n <i class=\"fas fa-arrow-right\"></i>\n </div>\n </div>\n }\n </div>\n } @else {\n <div class=\"empty-state\">\n <i class=\"fas fa-link\"></i>\n <p>No links available</p>\n </div>\n }\n </div>\n\n <!-- Dynamic Plugin Tabs and Base Tabs (JSON, etc.) -->\n @if (activeTab !== 'display' && activeTab !== 'details' && activeTab !== 'links') {\n <!-- Check if this is a component tab -->\n @if (GetComponentTabType(activeTab); as componentType) {\n <div class=\"component-tab-content\">\n <ng-container *ngComponentOutlet=\"componentType; inputs: GetComponentInputs(activeTab)\"></ng-container>\n </div>\n } @else {\n @if (GetTabContent(activeTab); as tabData) {\n <div class=\"dynamic-tab-content\">\n @switch (tabData.type) {\n @case ('markdown') {\n <div class=\"markdown-viewer\">\n <mj-markdown [data]=\"tabData.content\"\n [enableCollapsibleHeadings]=\"true\"\n [enableLineNumbers]=\"true\"\n [enableSmartypants]=\"true\"\n [enableHtml]=\"true\"></mj-markdown>\n </div>\n }\n @case ('json') {\n <div class=\"json-viewer\">\n <div class=\"json-toolbar\">\n <button class=\"btn-icon\" title=\"Copy JSON\" (click)=\"onCopyToClipboard()\">\n <i class=\"fas fa-copy\"></i> Copy\n </button>\n </div>\n <div class=\"json-editor-container\">\n <mj-code-editor\n [value]=\"tabData.content\"\n [language]=\"'json'\"\n [readonly]=\"true\"\n [lineWrapping]=\"true\"\n style=\"width: 100%; height: 100%;\">\n </mj-code-editor>\n </div>\n </div>\n }\n @case ('code') {\n <div class=\"code-viewer\">\n <div class=\"code-toolbar\">\n <button class=\"btn-icon\" title=\"Copy Code\" (click)=\"onCopyToClipboard()\">\n <i class=\"fas fa-copy\"></i> Copy\n </button>\n </div>\n <div class=\"code-editor-container\">\n <mj-code-editor\n [value]=\"tabData.content\"\n [language]=\"tabData.language || 'typescript'\"\n [readonly]=\"true\"\n [lineWrapping]=\"true\"\n style=\"width: 100%; height: 100%;\">\n </mj-code-editor>\n </div>\n </div>\n }\n @case ('html') {\n <div class=\"html-viewer\" [innerHTML]=\"tabData.content\"></div>\n }\n @case ('plaintext') {\n <pre class=\"plaintext-viewer\">{{ tabData.content }}</pre>\n }\n }\n </div>\n }\n }\n }\n </div>\n </div>\n }\n </div>\n</div>\n\n"]}
|
|
1
|
+
{"version":3,"file":"artifact-viewer-panel.component.js","sourceRoot":"","sources":["../../../src/lib/components/artifact-viewer-panel.component.ts","../../../src/lib/components/artifact-viewer-panel.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnInit, OnChanges, OnDestroy, SimpleChanges, ViewChild, ViewContainerRef, ComponentRef, Type, ChangeDetectorRef } from '@angular/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\nimport { UserInfo, Metadata, RunView, LogError, CompositeKey, DataSnapshot } from '@memberjunction/core';\nimport { ParseJSONRecursive, ParseJSONOptions , UUIDsEqual } from '@memberjunction/global';\nimport { MJArtifactEntity, MJArtifactVersionEntity, MJArtifactVersionAttributeEntity, MJArtifactTypeEntity, MJCollectionEntity, MJCollectionArtifactEntity, ArtifactMetadataEngine, MJConversationEntity, MJConversationDetailArtifactEntity, MJConversationDetailEntity, MJArtifactUseEntity } from '@memberjunction/core-entities';\nimport { MJNotificationService } from '@memberjunction/ng-notifications';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { ArtifactTypePluginViewerComponent } from './artifact-type-plugin-viewer.component';\nimport { ArtifactViewerTab, NavigationRequest } from './base-artifact-viewer.component';\nimport { ArtifactIconService } from '../services/artifact-icon.service';\nimport { RecentAccessService } from '@memberjunction/ng-shared-generic';\n\n@Component({\n standalone: false,\n selector: 'mj-artifact-viewer-panel',\n templateUrl: './artifact-viewer-panel.component.html',\n styleUrls: ['./artifact-viewer-panel.component.css']\n})\nexport class ArtifactViewerPanelComponent extends BaseAngularComponent implements OnInit, OnChanges, OnDestroy {\n @Input() artifactId!: string;\n @Input() currentUser!: UserInfo;\n @Input() environmentId!: string;\n @Input() versionNumber?: number; // Version to display\n @Input() showSaveToCollection: boolean = true; // Control whether Save to Collection button is shown\n @Input() showHeader: boolean = true; // Control whether the header section is shown\n @Input() showTabs: boolean = true; // Control whether the tab navigation is shown (false = show only Display tab content)\n @Input() showCloseButton: boolean = true; // Control whether the close button is shown in header\n @Input() showMaximizeButton: boolean = true; // Control whether the maximize/restore button is shown in header\n @Input() refreshTrigger?: Subject<{artifactId: string; versionNumber: number}>;\n @Input() viewContext: 'conversation' | 'collection' | null = null; // Where artifact is being viewed\n @Input() contextCollectionId?: string; // If viewing in collection, which collection\n @Input() canShare?: boolean; // Whether user can share this artifact\n @Input() canEdit?: boolean; // Whether user can edit this artifact\n @Input() isMaximized: boolean = false; // Whether the panel is currently maximized\n @Output() closed = new EventEmitter<void>();\n @Output() saveToCollectionRequested = new EventEmitter<{artifactId: string; excludedCollectionIds: string[]}>();\n @Output() navigateToLink = new EventEmitter<{type: 'conversation' | 'collection'; id: string; artifactId?: string; versionNumber?: number; versionId?: string}>();\n @Output() shareRequested = new EventEmitter<string>(); // Emits artifactId when share is clicked\n @Output() maximizeToggled = new EventEmitter<void>(); // Emits when user clicks maximize/restore button\n @Output() openEntityRecord = new EventEmitter<{entityName: string; compositeKey: CompositeKey}>();\n @Output() navigationRequest = new EventEmitter<NavigationRequest>();\n @Output() analyzeRequested = new EventEmitter<{ artifactId: string; snapshot: DataSnapshot }>();\n\n @ViewChild(ArtifactTypePluginViewerComponent) pluginViewer?: ArtifactTypePluginViewerComponent;\n\n private destroy$ = new Subject<void>();\n\n public artifact: MJArtifactEntity | null = null;\n public artifactVersion: MJArtifactVersionEntity | null = null;\n public allVersions: MJArtifactVersionEntity[] = [];\n public selectedVersionNumber: number = 1;\n public isLoading = true;\n public error: string | null = null;\n public jsonContent = '';\n public showVersionDropdown = false;\n public artifactCollections: MJCollectionArtifactEntity[] = []; // All collections for ALL versions\n public currentVersionCollections: MJCollectionArtifactEntity[] = []; // Collections containing CURRENT version only\n public primaryCollection: MJCollectionEntity | null = null;\n\n // Tabbed interface\n public activeTab: string = 'display'; // Changed to string to support dynamic tabs\n public displayMarkdown: string | null = null;\n public displayHtml: string | null = null;\n public versionAttributes: MJArtifactVersionAttributeEntity[] = [];\n private artifactTypeDriverClass: string | null = null;\n /** Populated from ArtifactType.ContentCategory. Used to suppress the JSON tab for\n * binary file-type artifacts — driven by metadata, not hardcoded plugin overrides. */\n private artifactContentCategory: 'File' | 'Text' | null = null;\n\n // Links tab data\n public originConversation: MJConversationEntity | null = null;\n public allCollections: MJCollectionEntity[] = [];\n public hasAccessToOriginConversation: boolean = false;\n public originConversationVersionId: string | null = null; // Version ID that came from origin conversation\n\n // Dynamic tabs from plugin\n public get allTabs(): string[] {\n const tabs: string[] = [];\n\n // Only add Display tab if there's content to display\n if (this.hasDisplayTab) {\n tabs.push('Display');\n }\n\n // Get plugin tabs directly from plugin instance (no caching needed - plugin always exists)\n if (this.pluginViewer?.pluginInstance?.GetAdditionalTabs) {\n const pluginTabs = this.pluginViewer.pluginInstance.GetAdditionalTabs();\n const pluginTabLabels = pluginTabs.map((t: ArtifactViewerTab) => t.label);\n tabs.push(...pluginTabLabels);\n }\n\n // Get tabs to remove from plugin (case-insensitive)\n const removals = this.pluginViewer?.pluginInstance?.GetStandardTabRemovals?.() || [];\n const removalsLower = removals.map(r => r.toLowerCase());\n\n // File-category artifacts (PDF, Excel, Word) have binary content — the JSON tab\n // would show a base64 blob or a storage reference, which is meaningless. Suppress it\n // using ArtifactType.ContentCategory from the database rather than a hardcoded plugin override.\n const isFileArtifact = this.artifactContentCategory === 'File';\n\n // Add standard tabs (unless suppressed by metadata or plugin)\n if (!isFileArtifact && !removalsLower.includes('json')) {\n tabs.push('JSON');\n }\n if (!removalsLower.includes('details')) {\n tabs.push('Details');\n }\n\n // Only add Links tab if there are links to show (unless plugin explicitly removes it)\n if (!removalsLower.includes('links') && this.linksToShow.length > 0) {\n tabs.push('Links');\n }\n\n return tabs;\n }\n\n /**\n * Get the full tab definition for a given tab name.\n * Returns the ArtifactViewerTab which may include component info for custom component tabs.\n */\n public GetTabDefinition(tabName: string): ArtifactViewerTab | null {\n // Check if this is a plugin-provided tab\n if (this.pluginViewer?.pluginInstance?.GetAdditionalTabs) {\n const pluginTabs = this.pluginViewer.pluginInstance.GetAdditionalTabs();\n const pluginTab = pluginTabs.find((t: ArtifactViewerTab) =>\n t.label.toLowerCase() === tabName.toLowerCase()\n );\n if (pluginTab) {\n return pluginTab;\n }\n }\n\n // Handle base tabs\n switch (tabName.toLowerCase()) {\n case 'json':\n return { label: 'JSON', contentType: 'json', content: this.jsonContent, language: 'json' };\n case 'details':\n return { label: 'Details', contentType: 'html', content: this.displayMarkdown || this.displayHtml || '' };\n default:\n return null;\n }\n }\n\n /**\n * Get resolved tab content for string-based tabs (non-component tabs).\n * For component tabs, use GetTabDefinition() and render the component directly.\n */\n public GetTabContent(tabName: string): { type: string; content: string; language?: string } | null {\n const tabDef = this.GetTabDefinition(tabName);\n if (!tabDef) return null;\n\n // Component tabs don't have string content\n if (tabDef.contentType === 'component') {\n return null;\n }\n\n const content = typeof tabDef.content === 'function'\n ? tabDef.content()\n : tabDef.content || '';\n\n return {\n type: tabDef.contentType,\n content: content,\n language: tabDef.language\n };\n }\n\n /**\n * Check if a tab is a component tab (renders a custom Angular component)\n */\n public IsComponentTab(tabName: string): boolean {\n const tabDef = this.GetTabDefinition(tabName);\n return tabDef?.contentType === 'component' && !!tabDef.component;\n }\n\n /**\n * Get the component type for a component tab.\n * Returns null if the tab is not a component tab (used for template type safety).\n */\n public GetComponentTabType(tabName: string): Type<any> | null {\n const tabDef = this.GetTabDefinition(tabName);\n if (tabDef?.contentType === 'component' && tabDef.component) {\n return tabDef.component;\n }\n return null;\n }\n\n /**\n * Get the component inputs for a component tab\n */\n public GetComponentInputs(tabName: string): Record<string, any> {\n const tabDef = this.GetTabDefinition(tabName);\n if (!tabDef || tabDef.contentType !== 'component') {\n return {};\n }\n return typeof tabDef.componentInputs === 'function'\n ? tabDef.componentInputs()\n : tabDef.componentInputs || {};\n }\n\n private recentAccessService: RecentAccessService;\n\n constructor(\n private cdr: ChangeDetectorRef,\n private notificationService: MJNotificationService,\n private sanitizer: DomSanitizer,\n private artifactIconService: ArtifactIconService\n ) {\n super();\n this.recentAccessService = new RecentAccessService();\n }\n\n async ngOnInit() {\n // Subscribe to refresh trigger for dynamic version changes\n if (this.refreshTrigger) {\n this.refreshTrigger.pipe(takeUntil(this.destroy$)).subscribe(async (data) => {\n if (data.artifactId === this.artifactId) {\n // Reload all versions to get any new ones\n await this.loadArtifact(data.versionNumber);\n }\n });\n }\n\n // Defer the initial load past Angular's first stable CD cycle so that the inner\n // awaits in loadArtifact can't mutate `this.artifact`/`this.artifactVersion` between\n // the main CD pass and dev-mode's verifyNoChanges pass (the classic NG0100\n // \"ExpressionChangedAfterItHasBeenCheckedError\" we used to hit on the title).\n // Using setTimeout(0) instead of Promise.resolve() because we need a fresh\n // macrotask boundary — microtasks can still drain inside Angular's CD cycle.\n setTimeout(async () => {\n await this.loadArtifact(this.versionNumber);\n\n // Track that user viewed this artifact (deferred so it runs after the load)\n if (this.artifactVersion?.ID && this.currentUser) {\n this.trackArtifactUsage('Viewed');\n // Also log to User Record Logs for recents feature (fire-and-forget)\n this.recentAccessService.logAccess('MJ: Artifacts', this.artifactId, 'artifact');\n }\n }, 0);\n }\n\n async ngOnChanges(changes: SimpleChanges) {\n // Reload artifact when artifactId changes\n if (changes['artifactId'] && !changes['artifactId'].firstChange) {\n await this.loadArtifact(this.versionNumber);\n }\n\n // Switch to new version when versionNumber changes (but artifactId stays the same)\n if (changes['versionNumber'] && !changes['versionNumber'].firstChange) {\n const newVersionNumber = changes['versionNumber'].currentValue;\n if (newVersionNumber != null) {\n // Check if we have metadata for this version (allVersions has lightweight metadata)\n const targetVersion = this.allVersions.find(v => v.VersionNumber === newVersionNumber);\n if (targetVersion) {\n this.selectedVersionNumber = (targetVersion.VersionNumber as number) || 1;\n\n // Load full content for the selected version\n const fullVersion = await this.loadVersionContent(targetVersion.ID);\n if (fullVersion) {\n this.artifactVersion = fullVersion;\n this.jsonContent = this.FormatJSON(fullVersion.Content || '{}');\n }\n\n // Load attributes and collection data in parallel\n await Promise.all([\n this.loadVersionAttributes(),\n this.loadCollectionAssociations(),\n this.loadLinksData()\n ]);\n\n this.cdr.detectChanges();\n } else {\n // Need to reload to get this version (shouldn't normally happen)\n await this.loadArtifact(newVersionNumber);\n }\n }\n }\n }\n\n ngOnDestroy() {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n private async loadArtifact(targetVersionNumber?: number): Promise<void> {\n try {\n this.isLoading = true;\n this.error = null;\n\n // Clear links data from previous artifact to prevent stale Links tab\n this.clearLinksData();\n\n const md = this.ProviderToUse;\n\n // Load artifact — assign to local first to avoid mid-cycle icon flicker\n const artifactEntity = await md.GetEntityObject<MJArtifactEntity>('MJ: Artifacts', this.currentUser);\n const loaded = await artifactEntity.Load(this.artifactId);\n\n if (!loaded) {\n this.error = 'Failed to load artifact';\n return;\n }\n this.artifact = artifactEntity;\n\n // PERF: Batch load version metadata, collection associations, and conversation links\n // in a single RunViews call. Content is excluded here — loaded on-demand for the selected version.\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const batchResults = await rv.RunViews([\n {\n // [0] Version metadata (lightweight — no Content field)\n EntityName: 'MJ: Artifact Versions',\n ExtraFilter: `ArtifactID='${this.artifactId}'`,\n OrderBy: 'VersionNumber DESC',\n Fields: ['ID', 'ArtifactID', 'VersionNumber', 'Name', 'Description', '__mj_CreatedAt', '__mj_UpdatedAt'],\n ResultType: 'simple'\n },\n {\n // [1] Collection associations for all versions of this artifact\n EntityName: 'MJ: Collection Artifacts',\n ExtraFilter: `ArtifactVersionID IN (\n SELECT ID FROM [__mj].[vwArtifactVersions] WHERE ArtifactID='${this.artifactId}'\n )`,\n Fields: ['ID', 'CollectionID', 'ArtifactVersionID', 'Sequence'],\n ResultType: 'simple'\n },\n {\n // [2] Conversation detail artifact links (for Links tab)\n EntityName: 'MJ: Conversation Detail Artifacts',\n ExtraFilter: `ArtifactVersionID IN (\n SELECT ID FROM [__mj].[vwArtifactVersions] WHERE ArtifactID='${this.artifactId}'\n )`,\n Fields: ['ID', 'ConversationDetailID', 'ArtifactVersionID'],\n MaxRows: 1,\n ResultType: 'simple'\n }\n ], this.currentUser);\n\n const [versionsResult, collectionsResult, convDetailResult] = batchResults;\n\n if (!versionsResult.Success || !versionsResult.Results || versionsResult.Results.length === 0) {\n this.error = 'No artifact version found';\n return;\n }\n\n // Store version metadata as simple objects (used for dropdown display)\n this.allVersions = versionsResult.Results as MJArtifactVersionEntity[];\n\n // Determine which version to display\n let selectedVersion: Record<string, unknown> | undefined;\n if (targetVersionNumber) {\n selectedVersion = versionsResult.Results.find(\n (v: Record<string, unknown>) => v.VersionNumber === targetVersionNumber\n );\n }\n // Fall back to latest version (first in DESC order)\n const versionToLoad = selectedVersion || versionsResult.Results[0];\n this.selectedVersionNumber = (versionToLoad.VersionNumber as number) || 1;\n\n // PERF: Start artifact type resolution and selected version content load in parallel\n const [, selectedVersionEntity] = await Promise.all([\n this.loadArtifactType(),\n this.loadVersionContent(versionToLoad.ID as string)\n ]);\n\n if (selectedVersionEntity) {\n this.artifactVersion = selectedVersionEntity;\n this.jsonContent = this.FormatJSON(selectedVersionEntity.Content || '{}');\n } else {\n this.error = 'Failed to load artifact version content';\n return;\n }\n\n // PERF: Process collection and links data in parallel (uses already-fetched batch data)\n await Promise.all([\n this.processCollectionAssociations(collectionsResult),\n this.processLinksData(collectionsResult, convDetailResult)\n ]);\n\n // Load version attributes (depends on selected version being set)\n await this.loadVersionAttributes();\n } catch (err) {\n console.error('Error loading artifact:', err);\n this.error = 'Error loading artifact: ' + (err as Error).message;\n } finally {\n this.isLoading = false;\n this.updateArtifactIcon();\n this.cdr.detectChanges();\n }\n }\n\n /**\n * Load full content for a single version by ID.\n * This avoids downloading Content for ALL versions when only one is displayed.\n */\n private async loadVersionContent(versionId: string): Promise<MJArtifactVersionEntity | null> {\n try {\n const md = this.ProviderToUse;\n const versionEntity = await md.GetEntityObject<MJArtifactVersionEntity>('MJ: Artifact Versions', this.currentUser);\n const loaded = await versionEntity.Load(versionId);\n return loaded ? versionEntity : null;\n } catch (err) {\n console.error('Error loading version content:', err);\n return null;\n }\n }\n\n /**\n * Clear all links-related data to prevent stale data when switching artifacts\n */\n private clearLinksData(): void {\n this.allCollections = [];\n this.originConversation = null;\n this.hasAccessToOriginConversation = false;\n this.originConversationVersionId = null;\n }\n\n private async loadArtifactType(): Promise<void> {\n // Reset on every load so a previous artifact's values don't bleed into the next\n this.artifactTypeDriverClass = null;\n this.artifactContentCategory = null;\n\n if (!this.artifact?.Type) {\n return;\n }\n\n try {\n await ArtifactMetadataEngine.Instance.Config(false, this.currentUser);\n\n const artifactType = ArtifactMetadataEngine.Instance.FindArtifactType(this.artifact.Type);\n if (artifactType) {\n // Resolve DriverClass by traversing parent hierarchy if needed\n this.artifactTypeDriverClass = await this.resolveDriverClassForType(artifactType);\n this.artifactContentCategory = artifactType.ContentCategory;\n }\n } catch (err) {\n console.error('Error loading artifact type:', err);\n // Don't fail the whole load if we can't get the artifact type\n }\n }\n\n private async loadVersionAttributes(): Promise<void> {\n if (!this.artifactVersion) return;\n\n try {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<MJArtifactVersionAttributeEntity>({\n EntityName: 'MJ: Artifact Version Attributes',\n ExtraFilter: `ArtifactVersionID='${this.artifactVersion.ID}'`,\n ResultType: 'simple'\n }, this.currentUser);\n\n if (result.Success && result.Results) {\n this.versionAttributes = result.Results;\n\n // Check for displayMarkdown or displayHtml attributes\n const displayMarkdownAttr = this.versionAttributes.find(a => a.Name?.toLowerCase() === 'displaymarkdown');\n const displayHtmlAttr = this.versionAttributes.find(a => a.Name?.toLowerCase() === 'displayhtml');\n\n // Parse values - they might be JSON-encoded strings\n this.displayMarkdown = this.parseAttributeValue(displayMarkdownAttr?.Value);\n this.displayHtml = this.parseAttributeValue(displayHtmlAttr?.Value);\n\n // Clean up double-escaped characters in HTML (from LLM generation)\n if (this.displayHtml) {\n this.displayHtml = this.cleanEscapedCharacters(this.displayHtml);\n }\n\n // Set active tab to the first available tab\n this.setActiveTabToFirstAvailable();\n }\n } catch (err) {\n console.error('Error loading version attributes:', err);\n } finally {\n this.cdr.detectChanges(); // zone.js 0.15: async RunView doesn't trigger CD\n }\n }\n\n get displayName(): string {\n if (this.artifactVersion?.Name) {\n return this.artifactVersion.Name;\n }\n return this.artifact?.Name || 'Artifact';\n }\n\n get displayDescription(): string | null {\n if (this.artifactVersion?.Description) {\n return this.artifactVersion.Description;\n }\n return this.artifact?.Description || null;\n }\n\n get hasDisplayTab(): boolean {\n // Show Display tab if:\n // 1. We have a plugin AND it reports having content to display, OR\n // 2. We have displayMarkdown or displayHtml attributes from extract rules\n //\n // Note: hasDisplayContent defaults to false in base class, so plugins must\n // explicitly opt-in by overriding to return true when they have content.\n // This prevents showing Display tab before plugin loads or when plugin has no content.\n const pluginHasContent = this.pluginViewer?.pluginInstance?.hasDisplayContent ?? false;\n\n return pluginHasContent || !!this.displayMarkdown || !!this.displayHtml;\n }\n\n get hasPlugin(): boolean {\n // Check if the artifact type has a DriverClass configured\n // If DriverClass is set, we have a plugin available\n return !!this.artifactTypeDriverClass;\n }\n\n get hasJsonTab(): boolean {\n // Query plugin directly (no cache needed - plugin always exists when it should)\n const pluginInstance = this.pluginViewer?.pluginInstance;\n return pluginInstance?.parentShouldShowRawContent || false;\n }\n\n get artifactTypeName(): string {\n return this.artifact?.Type || '';\n }\n\n get contentType(): string | undefined {\n // Try to get content type from artifact type or attributes\n const contentTypeAttr = this.versionAttributes.find(a => a.Name?.toLowerCase() === 'contenttype');\n return contentTypeAttr?.Value || undefined;\n }\n\n get filteredAttributes(): MJArtifactVersionAttributeEntity[] {\n // Filter out displayMarkdown and displayHtml as they're shown in the Display tab\n return this.versionAttributes.filter(attr => {\n const name = attr.Name?.toLowerCase();\n return name !== 'displaymarkdown' && name !== 'displayhtml';\n });\n }\n\n setActiveTab(tab: 'display' | 'json' | 'details' | 'links'): void {\n this.activeTab = tab;\n }\n\n /**\n * Sets the active tab to the first available tab in the list.\n * Called when tabs change or when the currently active tab becomes unavailable.\n */\n private setActiveTabToFirstAvailable(): void {\n const tabs = this.allTabs;\n if (tabs.length > 0) {\n // If current tab is still available, keep it; otherwise switch to first\n const currentTabStillAvailable = tabs.some(t => t.toLowerCase() === this.activeTab.toLowerCase());\n if (!currentTabStillAvailable) {\n this.activeTab = tabs[0].toLowerCase();\n }\n } else {\n // Fallback to details if no tabs available (shouldn't happen)\n this.activeTab = 'details';\n }\n }\n\n /**\n * Called when a plugin's async tab data changes (e.g., ComponentArtifactViewer loads\n * the full spec from the registry after initial render with a stripped spec).\n * Forces re-evaluation of allTabs so new tab labels render correctly.\n */\n onTabsChanged(): void {\n // If Display tab just became available (e.g., after plugin async load),\n // switch to it — it should be the default when present.\n const tabs = this.allTabs;\n if (tabs.length > 0 && tabs[0].toLowerCase() === 'display' && this.activeTab !== 'display') {\n this.activeTab = 'display';\n }\n this.cdr.detectChanges(); // zone.js 0.15: plugin emitted tabsChanged, force CD to re-evaluate allTabs\n }\n\n /**\n * Called when the plugin viewer finishes loading.\n * Selects the first available tab now that plugin tabs are available.\n */\n onPluginLoaded(): void {\n // Now that plugin is loaded, we have accurate tab information\n // Always select the first tab since this is the initial load\n const tabs = this.allTabs;\n if (tabs.length > 0) {\n this.activeTab = tabs[0].toLowerCase();\n }\n this.cdr.detectChanges(); // zone.js 0.15: plugin loaded via async callback, force CD\n }\n\n private parseAttributeValue(value: string | null | undefined): string | null {\n if (!value) return null;\n\n // Check if it's a JSON-encoded string (starts and ends with quotes)\n if (value.startsWith('\"') && value.endsWith('\"')) {\n try {\n return JSON.parse(value);\n } catch (e) {\n console.warn('Failed to parse attribute value as JSON:', e);\n return value;\n }\n }\n\n return value;\n }\n\n /**\n * Clean up double-escaped characters that appear in LLM-generated HTML\n * Removes literal \"\\\\n\" and \"\\\\t\" which cause rendering issues\n */\n private cleanEscapedCharacters(html: string): string {\n // Remove escaped newlines (\\\\n becomes nothing)\n // HTML doesn't need whitespace for formatting, and these cause display issues\n let cleaned = html.replace(/\\\\n/g, '');\n\n // Remove escaped tabs\n cleaned = cleaned.replace(/\\\\t/g, '');\n\n // Remove double-escaped tabs\n cleaned = cleaned.replace(/\\\\\\\\t/g, '');\n\n // Remove double-escaped newlines\n cleaned = cleaned.replace(/\\\\\\\\n/g, '');\n\n return cleaned;\n }\n\n /**\n * Process pre-fetched collection association data.\n * Accepts the batch result from loadArtifact() to avoid duplicate queries.\n */\n private async processCollectionAssociations(\n collectionsResult?: { Success: boolean; Results: Record<string, unknown>[] }\n ): Promise<void> {\n if (!this.artifactId) return;\n\n try {\n // If no pre-fetched data, fetch it (used by selectVersion/saveToCollections reload)\n let collectionRows: Record<string, unknown>[];\n if (collectionsResult?.Success && collectionsResult.Results) {\n collectionRows = collectionsResult.Results;\n } else {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<{ ID: string; CollectionID: string; ArtifactVersionID: string; Sequence: number }>({\n EntityName: 'MJ: Collection Artifacts',\n ExtraFilter: `ArtifactVersionID IN (\n SELECT ID FROM [__mj].[vwArtifactVersions] WHERE ArtifactID='${this.artifactId}'\n )`,\n Fields: ['ID', 'CollectionID', 'ArtifactVersionID', 'Sequence'],\n ResultType: 'simple'\n }, this.currentUser);\n collectionRows = (result.Success ? result.Results : []) as Record<string, unknown>[];\n }\n\n // Store as simple objects — these are read-only display data\n this.artifactCollections = collectionRows as unknown as MJCollectionArtifactEntity[];\n\n // Filter to get only collections containing the CURRENT version\n const currentVersionId = this.artifactVersion?.ID;\n if (currentVersionId) {\n const currentIdStr = String(currentVersionId).toLowerCase();\n this.currentVersionCollections = collectionRows.filter(ca => {\n const versionIdStr = String(ca['ArtifactVersionID'] || ca.ArtifactVersionID || '').toLowerCase();\n return versionIdStr && currentIdStr && versionIdStr === currentIdStr;\n }) as unknown as MJCollectionArtifactEntity[];\n } else {\n this.currentVersionCollections = [];\n }\n\n // Load the primary collection details if exists\n if (this.artifactCollections.length > 0) {\n const collectionId = (collectionRows[0] as Record<string, unknown>).CollectionID as string ||\n (this.artifactCollections[0] as unknown as Record<string, unknown>).CollectionID as string;\n if (collectionId) {\n const md = this.ProviderToUse;\n this.primaryCollection = await md.GetEntityObject<MJCollectionEntity>('MJ: Collections', this.currentUser);\n await this.primaryCollection.Load(collectionId);\n }\n } else {\n this.primaryCollection = null;\n }\n } catch (err) {\n console.error('Error processing collection associations:', err);\n } finally {\n this.cdr.detectChanges();\n }\n }\n\n /**\n * @deprecated Use processCollectionAssociations() instead. Kept as a shim for callers\n * that don't have pre-fetched data (e.g., selectVersion, saveToCollections).\n */\n private async loadCollectionAssociations(): Promise<void> {\n return this.processCollectionAssociations();\n }\n\n get isInCollection(): boolean {\n return this.currentVersionCollections.length > 0;\n }\n\n /**\n * Get collection IDs that already contain the current version\n * Used to exclude them from the save picker\n */\n get currentVersionCollectionIds(): string[] {\n return this.currentVersionCollections.map(ca => ca.CollectionID);\n }\n\n onCopyToClipboard(): void {\n // Get content from the currently active tab instead of always copying jsonContent\n const tabData = this.GetTabContent(this.activeTab);\n if (tabData?.content) {\n navigator.clipboard.writeText(tabData.content);\n } else if (this.jsonContent) {\n // Fallback to jsonContent if tab content not found\n navigator.clipboard.writeText(this.jsonContent);\n }\n }\n\n onCopyDisplayContent(): void {\n const content = this.displayHtml || this.displayMarkdown;\n if (content) {\n navigator.clipboard.writeText(content).catch(err => {\n console.error('Failed to copy to clipboard:', err);\n });\n }\n }\n\n onPrintDisplayContent(): void {\n // Try to delegate to the plugin viewer's print method\n if (this.pluginViewer?.pluginInstance) {\n const plugin = this.pluginViewer.pluginInstance as any;\n if (typeof plugin.printHtml === 'function') {\n plugin.printHtml();\n return;\n }\n }\n\n // Fallback: create a temporary print window with displayHtml or displayMarkdown\n const content = this.displayHtml || this.displayMarkdown;\n if (content) {\n const printWindow = window.open('', '_blank');\n if (printWindow) {\n if (this.displayHtml) {\n printWindow.document.write(content);\n } else if (this.displayMarkdown) {\n // Wrap markdown in basic HTML for printing\n printWindow.document.write(`\n <!DOCTYPE html>\n <html>\n <head>\n <title>Print</title>\n <style>\n body { font-family: sans-serif; padding: 20px; }\n pre { background: #f5f5f5; padding: 10px; border-radius: 4px; }\n </style>\n </head>\n <body>\n <pre>${content}</pre>\n </body>\n </html>\n `);\n }\n printWindow.document.close();\n printWindow.focus();\n setTimeout(() => {\n printWindow.print();\n printWindow.close();\n }, 250);\n }\n }\n }\n\n toggleVersionDropdown(): void {\n if (this.allVersions.length > 1) {\n this.showVersionDropdown = !this.showVersionDropdown;\n }\n }\n\n async selectVersion(version: MJArtifactVersionEntity): Promise<void> {\n this.selectedVersionNumber = (version.VersionNumber as number) || 1;\n this.showVersionDropdown = false;\n\n // Load full content for the selected version (allVersions only has metadata)\n const fullVersion = await this.loadVersionContent(version.ID);\n if (fullVersion) {\n this.artifactVersion = fullVersion;\n this.jsonContent = this.FormatJSON(fullVersion.Content || '{}');\n }\n\n // Load attributes and collection data in parallel\n await Promise.all([\n this.loadVersionAttributes(),\n this.loadCollectionAssociations(),\n this.loadLinksData()\n ]);\n\n this.cdr.detectChanges();\n }\n\n async onSaveToLibrary(): Promise<void> {\n // Always show the collection picker modal\n // Artifacts can be saved to multiple collections\n this.saveToCollectionRequested.emit({\n artifactId: this.artifactId,\n excludedCollectionIds: this.excludedCollectionIds\n });\n }\n\n get excludedCollectionIds(): string[] {\n // Return IDs of collections that already contain the CURRENT VERSION\n // This allows saving different versions to the same collection\n const excluded = this.currentVersionCollections\n .filter(ca => ca.CollectionID)\n .map(ca => String(ca.CollectionID));\n return excluded;\n }\n\n /**\n * Reload the cached set of collections that contain the *current version* of this artifact.\n * Called by the chat-area after the collection picker reports successful saves so the bookmark\n * icon and \"already saved\" exclusion list refresh without a full artifact reload.\n */\n public async ReloadCollectionAssociations(): Promise<void> {\n await this.loadCollectionAssociations();\n }\n\n /**\n * @deprecated Writes are now owned by the picker modal so the dialog can render per-collection\n * progress and partial-failure UI. Kept for any external consumer that still calls it; new code\n * should pass `artifactVersionId` to the picker and listen for its `completed` event.\n */\n async saveToCollections(collectionIds: string[]): Promise<boolean> {\n if (!this.artifactId || collectionIds.length === 0) {\n return false;\n }\n\n try {\n const md = this.ProviderToUse;\n let successCount = 0;\n\n // Get current version ID - save the version being viewed\n const currentVersionId = this.artifactVersion?.ID;\n if (!currentVersionId) {\n console.error('No current version ID available');\n MJNotificationService.Instance.CreateSimpleNotification(\n 'Cannot save: no version selected',\n 'error'\n );\n return false;\n }\n\n // Save artifact version to each selected collection\n for (const collectionId of collectionIds) {\n // Double check this exact version doesn't already exist in the collection\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const existingResult = await rv.RunView<MJCollectionArtifactEntity>({\n EntityName: 'MJ: Collection Artifacts',\n ExtraFilter: `CollectionID='${collectionId}' AND ArtifactVersionID='${currentVersionId}'`,\n ResultType: 'entity_object'\n }, this.currentUser);\n\n if (existingResult.Success && existingResult.Results && existingResult.Results.length > 0) {\n continue;\n }\n\n // Create junction record with version ID\n const collectionArtifact = await md.GetEntityObject<MJCollectionArtifactEntity>('MJ: Collection Artifacts', this.currentUser);\n collectionArtifact.CollectionID = collectionId;\n collectionArtifact.ArtifactVersionID = currentVersionId;\n collectionArtifact.Sequence = 0;\n\n const saved = await collectionArtifact.Save();\n if (saved) {\n successCount++;\n } else {\n console.error(`Failed to save artifact version to collection ${collectionId}`);\n }\n }\n\n if (successCount > 0) {\n MJNotificationService.Instance.CreateSimpleNotification(\n `Artifact saved to ${successCount} collection(s) successfully!`,\n 'success',\n 3000\n );\n\n // Reload collection associations to update the bookmark icon state\n await this.loadCollectionAssociations();\n return true;\n } else {\n MJNotificationService.Instance.CreateSimpleNotification(\n 'Failed to save artifact to any collections',\n 'error'\n );\n return false;\n }\n } catch (err) {\n console.error('Error saving to collections:', err);\n LogError(err);\n MJNotificationService.Instance.CreateSimpleNotification(\n 'Error saving artifact to collections. Please try again.',\n 'error'\n );\n return false;\n }\n }\n\n /**\n * Process links data using pre-fetched batch results from loadArtifact().\n * Reuses collection data from the same batch to avoid duplicate queries.\n */\n private async processLinksData(\n collectionsResult?: { Success: boolean; Results: Record<string, unknown>[] },\n convDetailResult?: { Success: boolean; Results: Record<string, unknown>[] }\n ): Promise<void> {\n if (!this.artifactId) return;\n\n // Clear old links data first to prevent stale data from previous artifact\n this.clearLinksData();\n\n try {\n const md = this.ProviderToUse;\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n\n // Use pre-fetched collection data or fetch if not provided\n let collectionRows: Record<string, unknown>[] = [];\n if (collectionsResult?.Success && collectionsResult.Results) {\n collectionRows = collectionsResult.Results;\n } else {\n const result = await rv.RunView<{ ID: string; CollectionID: string; ArtifactVersionID: string }>({\n EntityName: 'MJ: Collection Artifacts',\n ExtraFilter: `ArtifactVersionID IN (\n SELECT ID FROM [__mj].[vwArtifactVersions] WHERE ArtifactID='${this.artifactId}'\n )`,\n Fields: ['ID', 'CollectionID', 'ArtifactVersionID'],\n ResultType: 'simple'\n }, this.currentUser);\n collectionRows = (result.Success ? result.Results : []) as Record<string, unknown>[];\n }\n\n // Get unique collection IDs and load collection details\n const collectionIds = [...new Set(\n collectionRows.map(ca => (ca['CollectionID'] || ca.CollectionID) as string)\n )].filter(Boolean);\n\n if (collectionIds.length > 0) {\n const collectionsFilter = collectionIds.map(id => `ID='${id}'`).join(' OR ');\n const collectionsEntityResult = await rv.RunView<MJCollectionEntity>({\n EntityName: 'MJ: Collections',\n ExtraFilter: collectionsFilter,\n Fields: ['ID', 'Name', 'UserID', 'Description'],\n ResultType: 'simple'\n }, this.currentUser);\n\n if (collectionsEntityResult.Success && collectionsEntityResult.Results) {\n this.allCollections = collectionsEntityResult.Results as unknown as MJCollectionEntity[];\n }\n }\n\n // Use pre-fetched conversation detail artifact data or fetch if not provided\n let convDetailRows: Record<string, unknown>[] = [];\n if (convDetailResult?.Success && convDetailResult.Results) {\n convDetailRows = convDetailResult.Results;\n } else {\n const versionIds = this.allVersions.map(v => v.ID);\n if (versionIds.length > 0) {\n const versionFilter = versionIds.map(id => `ArtifactVersionID='${id}'`).join(' OR ');\n const result = await rv.RunView<{ ID: string; ConversationDetailID: string; ArtifactVersionID: string }>({\n EntityName: 'MJ: Conversation Detail Artifacts',\n ExtraFilter: versionFilter,\n Fields: ['ID', 'ConversationDetailID', 'ArtifactVersionID'],\n MaxRows: 1,\n ResultType: 'simple'\n }, this.currentUser);\n convDetailRows = (result.Success ? result.Results : []) as Record<string, unknown>[];\n }\n }\n\n // Load origin conversation if we have a link\n if (convDetailRows.length > 0) {\n const conversationDetailId = (convDetailRows[0]['ConversationDetailID'] || convDetailRows[0].ConversationDetailID) as string;\n const artifactVersionId = (convDetailRows[0]['ArtifactVersionID'] || convDetailRows[0].ArtifactVersionID) as string;\n\n this.originConversationVersionId = artifactVersionId;\n\n // Load conversation detail to get conversation ID\n const conversationDetail = await md.GetEntityObject<MJConversationDetailEntity>('MJ: Conversation Details', this.currentUser);\n const detailLoaded = await conversationDetail.Load(conversationDetailId);\n\n if (detailLoaded && conversationDetail.ConversationID) {\n const conversation = await md.GetEntityObject<MJConversationEntity>('MJ: Conversations', this.currentUser);\n const loaded = await conversation.Load(conversationDetail.ConversationID);\n\n if (loaded) {\n this.originConversation = conversation;\n\n // Check if user has access (is owner or participant)\n const userIsOwner = UUIDsEqual(conversation.UserID, this.currentUser.ID);\n\n const participantResult = await rv.RunView({\n EntityName: 'MJ: Conversation Details',\n ExtraFilter: `ConversationID='${conversation.ID}' AND UserID='${this.currentUser.ID}'`,\n MaxRows: 1,\n Fields: ['ID'],\n ResultType: 'simple'\n }, this.currentUser);\n\n const userIsParticipant = participantResult.Success &&\n participantResult.Results &&\n participantResult.Results.length > 0;\n\n this.hasAccessToOriginConversation = userIsOwner || userIsParticipant;\n }\n }\n }\n } catch (error) {\n console.error('Error loading links data:', error);\n } finally {\n this.cdr.detectChanges();\n }\n }\n\n /**\n * @deprecated Use processLinksData() instead. Kept as shim for callers without pre-fetched data.\n */\n private async loadLinksData(): Promise<void> {\n return this.processLinksData();\n }\n\n get linksToShow(): Array<{type: 'conversation' | 'collection'; id: string; name: string; hasAccess: boolean}> {\n const links: Array<{type: 'conversation' | 'collection'; id: string; name: string; hasAccess: boolean}> = [];\n\n // Get current version ID being viewed\n const currentVersionId = this.artifactVersion?.ID;\n\n // RULE: In conversation context, show ONLY collection links\n // RULE: In collection context, show ONLY conversation links\n if (this.viewContext === 'conversation') {\n // Show all collections containing this artifact (any version)\n for (const collection of this.allCollections) {\n links.push({\n type: 'collection',\n id: collection.ID,\n name: collection.Name,\n hasAccess: true\n });\n }\n } else if (this.viewContext === 'collection') {\n // Show origin conversation if it exists\n // Show for ALL versions of the artifact, not just the original version that was added\n if (this.originConversation) {\n links.push({\n type: 'conversation',\n id: this.originConversation.ID,\n name: this.originConversation.Name || 'Untitled Conversation',\n hasAccess: this.hasAccessToOriginConversation\n });\n }\n }\n // If viewContext is null, show nothing (no links)\n\n return links;\n }\n\n /**\n * Navigate to a linked conversation or collection\n */\n onNavigateToLink(link: {type: 'conversation' | 'collection'; id: string; name: string; hasAccess: boolean}): void {\n if (!link.hasAccess) {\n return;\n }\n\n // Include artifact ID, version number, and version ID so destination can show the artifact with correct URL\n this.navigateToLink.emit({\n type: link.type,\n id: link.id,\n artifactId: this.artifactId,\n versionNumber: this.selectedVersionNumber,\n versionId: this.artifactVersion?.ID\n });\n }\n\n onClose(): void {\n this.closed.emit();\n }\n\n onShare(): void {\n this.shareRequested.emit(this.artifactId);\n }\n\n onMaximizeToggle(): void {\n this.maximizeToggled.emit();\n }\n\n /**\n * Handle entity record open request from artifact viewer plugin (React component)\n * Propagates the event up to parent components\n */\n onOpenEntityRecord(event: {entityName: string; compositeKey: CompositeKey}): void {\n this.openEntityRecord.emit(event);\n }\n\n /**\n * Handle navigation request from artifact viewer plugin.\n * Propagates the event up to parent components for app-level navigation.\n */\n onNavigationRequest(event: NavigationRequest): void {\n this.navigationRequest.emit(event);\n }\n\n /**\n * Resolves the DriverClass for an artifact type by traversing up the parent hierarchy.\n * Returns the first DriverClass found, or null if none found in the hierarchy.\n */\n private async resolveDriverClassForType(artifactType: MJArtifactTypeEntity): Promise<string | null> {\n // Check if current artifact type has a DriverClass\n if (artifactType.DriverClass) {\n return artifactType.DriverClass;\n }\n\n // No DriverClass on current type - check if it has a parent\n if (artifactType.ParentID) {\n const parentType = await this.getArtifactTypeById(artifactType.ParentID);\n\n if (parentType) {\n // Recursively check parent\n return await this.resolveDriverClassForType(parentType);\n }\n }\n\n // Reached root with no DriverClass\n return null;\n }\n\n /**\n * Loads an artifact type by ID\n */\n private async getArtifactTypeById(id: string): Promise<MJArtifactTypeEntity | null> {\n try {\n const md = this.ProviderToUse;\n const artifactType = await md.GetEntityObject<MJArtifactTypeEntity>('MJ: Artifact Types', this.currentUser);\n const loaded = await artifactType.Load(id);\n\n if (loaded) {\n return artifactType;\n }\n\n return null;\n } catch (err) {\n console.error('Error loading artifact type by ID:', err);\n return null;\n }\n }\n\n /**\n * Format JSON content using ParseJSONRecursive for deep parsing and formatting\n */\n private FormatJSON(content: string): string {\n try {\n // First parse the JSON string to an object\n const obj = JSON.parse(content);\n\n // Then use ParseJSONRecursive to extract any inline JSON strings\n const parseOptions: ParseJSONOptions = {\n extractInlineJson: true,\n maxDepth: 100,\n debug: false\n };\n const parsed = ParseJSONRecursive(obj, parseOptions);\n\n // Finally stringify with formatting\n return JSON.stringify(parsed, null, 2);\n } catch (e) {\n // Fallback to simple parse/stringify if ParseJSONRecursive fails\n try {\n const obj = JSON.parse(content);\n return JSON.stringify(obj, null, 2);\n } catch (e2) {\n // If even simple parse fails, return as-is\n return content;\n }\n }\n }\n\n /**\n * Get icon class for a tab\n */\n public GetTabIcon(tabName: string): string | null {\n // Base tabs\n const baseIcons: Record<string, string> = {\n 'Display': 'fas fa-eye',\n 'Code': 'fas fa-code',\n 'JSON': 'fas fa-file-code',\n 'Details': 'fas fa-info-circle',\n 'Links': 'fas fa-link'\n };\n\n if (baseIcons[tabName]) {\n return baseIcons[tabName];\n }\n\n // Check plugin tabs\n const plugin = this.pluginViewer?.pluginInstance;\n if (plugin?.GetAdditionalTabs) {\n const pluginTab = plugin.GetAdditionalTabs().find((t: ArtifactViewerTab) => t.label === tabName);\n if (pluginTab?.icon) {\n return 'fas ' + pluginTab.icon; // Ensure full Font Awesome class\n }\n }\n\n return null;\n }\n\n /**\n * Set active tab\n */\n public SetActiveTab(tabName: string): void {\n this.activeTab = tabName.toLowerCase();\n }\n\n /**\n * Track artifact usage event\n */\n private async trackArtifactUsage(usageType: 'Viewed' | 'Opened' | 'Shared' | 'Saved' | 'Exported'): Promise<void> {\n try {\n if (!this.artifactVersion?.ID || !this.currentUser?.ID) {\n return;\n }\n\n const md = this.ProviderToUse;\n const usage = await md.GetEntityObject<MJArtifactUseEntity>('MJ: Artifact Uses');\n\n usage.ArtifactVersionID = this.artifactVersion.ID;\n usage.UserID = this.currentUser.ID;\n usage.UsageType = usageType;\n usage.UsageContext = JSON.stringify({\n viewContext: this.viewContext,\n contextCollectionId: this.contextCollectionId,\n timestamp: new Date().toISOString()\n });\n\n // Save asynchronously - don't block UI\n usage.Save().catch(error => {\n console.error('Failed to track artifact usage:', error);\n });\n\n } catch (error) {\n console.error('Error tracking artifact usage:', error);\n }\n }\n\n /**\n * Get the icon for this artifact using the centralized icon service.\n * Fallback priority: Plugin icon > Metadata icon > Hardcoded mapping > Generic icon\n */\n /** Cached icon class — set once after artifact loads to avoid mid-cycle flicker */\n public artifactIcon: string = 'fa-file';\n\n /** Update the cached icon from the loaded artifact */\n private updateArtifactIcon(): void {\n this.artifactIcon = this.artifact\n ? this.artifactIconService.getArtifactIcon(this.artifact)\n : 'fa-file';\n }\n\n /**\n * Capture the current snapshot and emit an analyze event.\n * The parent component handles routing this to an agent conversation.\n */\n public OnAnalyze(): void {\n const snapshot = this.GetCurrentStateSnapshot();\n if (snapshot && this.artifact) {\n this.analyzeRequested.emit({\n artifactId: this.artifact.ID,\n snapshot\n });\n } else {\n this.notificationService.CreateSimpleNotification(\n 'No data available to analyze',\n 'warning',\n 3000\n );\n }\n }\n\n /**\n * Passthrough to the active plugin's GetCurrentStateSnapshot().\n * Returns null if no plugin is loaded or the plugin has no snapshot.\n */\n public GetCurrentStateSnapshot(): DataSnapshot | null {\n return this.pluginViewer?.pluginInstance?.GetCurrentStateSnapshot() ?? null;\n }\n}\n","<div class=\"artifact-viewer-panel\" [class.no-header]=\"!showHeader\">\n @if (showHeader) {\n <div class=\"panel-header\">\n <div class=\"panel-header-left\">\n <h3>\n <i class=\"fas\" [ngClass]=\"artifactIcon\"></i>\n {{ displayName }}\n </h3>\n @if (displayDescription) {\n <p class=\"header-description\">{{ displayDescription }}</p>\n }\n </div>\n <div class=\"panel-header-right\">\n <div class=\"version-selector\"\n [class.clickable]=\"allVersions.length > 1 && viewContext !== 'collection'\"\n (click)=\"viewContext !== 'collection' && toggleVersionDropdown()\">\n <i class=\"fas fa-history\"></i>\n <span class=\"version-label\">v{{ selectedVersionNumber }}</span>\n @if (allVersions.length > 1 && viewContext !== 'collection') {\n <i class=\"fas fa-chevron-down dropdown-icon\" [class.open]=\"showVersionDropdown\"></i>\n }\n @if (showVersionDropdown) {\n <div class=\"version-dropdown\" (click)=\"$event.stopPropagation()\">\n @for (version of allVersions; track version.ID) {\n <div class=\"version-option\"\n [class.selected]=\"version.VersionNumber === selectedVersionNumber\"\n (click)=\"selectVersion(version); $event.stopPropagation()\">\n <span class=\"version-number\">v{{ version.VersionNumber }}</span>\n <span class=\"version-date\">{{ version.__mj_CreatedAt | date:'short' }}</span>\n @if (version.VersionNumber === selectedVersionNumber) {\n <i class=\"fas fa-check\"></i>\n }\n </div>\n }\n </div>\n }\n </div>\n @if (pluginViewer?.SupportsFeedback) {\n <button class=\"feedback-btn\"\n (click)=\"pluginViewer?.AskUserForFeedback()\"\n title=\"Inspect & rate components\">\n <i class=\"fas fa-star-half-stroke\"></i>\n </button>\n }\n @if (showSaveToCollection) {\n <button class=\"save-to-collection-btn\"\n [class.in-collection]=\"isInCollection\"\n (click)=\"onSaveToLibrary()\"\n [title]=\"isInCollection ? 'Current version saved to ' + currentVersionCollections.length + ' collection(s)' : 'Save to Collection'\">\n <i [class]=\"isInCollection ? 'fas fa-bookmark' : 'far fa-bookmark'\"></i>\n </button>\n }\n @if (canShare) {\n <button class=\"share-btn\"\n (click)=\"onShare()\"\n title=\"Share\">\n <i class=\"fas fa-share-nodes\"></i>\n </button>\n }\n <button class=\"analyze-btn\"\n (click)=\"OnAnalyze()\"\n title=\"Analyze this artifact with AI\">\n <i class=\"fas fa-magnifying-glass-chart\"></i>\n </button>\n @if (showMaximizeButton) {\n <button class=\"maximize-btn\"\n (click)=\"onMaximizeToggle()\"\n [title]=\"isMaximized ? 'Restore Width' : 'Maximize Width'\">\n <i class=\"fas\" [ngClass]=\"isMaximized ? 'fa-compress-arrows-alt' : 'fa-arrows-left-right'\"></i>\n </button>\n }\n @if (showCloseButton) {\n <button class=\"close-btn\" (click)=\"onClose()\" title=\"Close\">\n <i class=\"fas fa-times\"></i>\n </button>\n }\n </div>\n </div>\n }\n\n <div class=\"panel-content\">\n @if (isLoading) {\n <div class=\"loading-state\">\n <i class=\"fas fa-spinner fa-spin\"></i>\n <span>Loading artifact...</span>\n </div>\n }\n\n @if (error) {\n <div class=\"error-state\">\n <i class=\"fas fa-exclamation-triangle\"></i>\n <span>{{ error }}</span>\n </div>\n }\n\n @if (!isLoading && !error && artifact) {\n <div class=\"artifact-content-wrapper\" [class.no-tabs]=\"!showTabs\">\n <!-- Tab Navigation (Dynamic) - Hidden when showTabs is false -->\n @if (showTabs) {\n <div class=\"tab-navigation\">\n @for (tab of allTabs; track tab) {\n <button class=\"tab-btn\"\n [class.active]=\"activeTab === tab.toLowerCase()\"\n (click)=\"SetActiveTab(tab)\">\n @if (GetTabIcon(tab)) {\n <i [class]=\"GetTabIcon(tab)!\"></i>\n }\n {{ tab }}\n </button>\n }\n </div>\n }\n\n <!-- Tab Content (Dynamic) -->\n <div class=\"tab-content\">\n <!-- Plugin Viewer - Created once, kept alive, shown/hidden with CSS -->\n @if (hasPlugin && artifactVersion && artifactTypeName) {\n <div class=\"plugin-container\" [class.plugin-hidden]=\"activeTab !== 'display'\">\n <mj-artifact-type-plugin-viewer\n [artifactVersion]=\"artifactVersion\"\n [artifactTypeName]=\"artifactTypeName\"\n [contentType]=\"contentType\"\n [readonly]=\"true\"\n (openEntityRecord)=\"onOpenEntityRecord($event)\"\n (navigationRequest)=\"onNavigationRequest($event)\"\n (pluginLoaded)=\"onPluginLoaded()\"\n (tabsChanged)=\"onTabsChanged()\">\n </mj-artifact-type-plugin-viewer>\n </div>\n }\n\n <!-- Display Tab - Fallback content when no plugin -->\n @if (activeTab === 'display' && (!hasPlugin || !artifactVersion)) {\n <div class=\"display-content\">\n @if (displayMarkdown || displayHtml) {\n <!-- Fallback to extracted markdown/HTML attributes -->\n <div class=\"display-toolbar\">\n <button class=\"btn-icon\" title=\"Print\" (click)=\"onPrintDisplayContent()\">\n <i class=\"fas fa-print\"></i> Print\n </button>\n <button class=\"btn-icon\" title=\"Copy Content\" (click)=\"onCopyDisplayContent()\">\n <i class=\"fas fa-copy\"></i> Copy\n </button>\n </div>\n @if (displayMarkdown) {\n <div class=\"markdown-content\">\n <mj-markdown [data]=\"displayMarkdown\"\n [enableCollapsibleHeadings]=\"true\"\n [enableLineNumbers]=\"true\"\n [enableSmartypants]=\"true\"\n [enableHtml]=\"true\"></mj-markdown>\n </div>\n } @else if (displayHtml) {\n <div class=\"html-content\" [innerHTML]=\"displayHtml\"></div>\n }\n }\n </div>\n }\n\n <!-- Details Tab - Artifact metadata (always in DOM, hidden with CSS) -->\n <div class=\"details-content\" [class.tab-hidden]=\"activeTab !== 'details'\">\n <div class=\"artifact-meta\">\n <div class=\"meta-item\">\n <label>Type</label>\n <span>{{ artifact.Type }}</span>\n </div>\n <div class=\"meta-item\">\n <label>Version</label>\n <span>{{ artifactVersion?.VersionNumber || 1 }}</span>\n </div>\n <div class=\"meta-item\">\n <label>Created</label>\n <span>{{ artifact.__mj_CreatedAt | date:'short' }}</span>\n </div>\n <div class=\"meta-item\">\n <label>Updated</label>\n <span>{{ artifactVersion?.__mj_UpdatedAt | date:'short' }}</span>\n </div>\n @if (artifact.Description) {\n <div class=\"meta-item full-width\">\n <label>Artifact Description</label>\n <span>{{ artifact.Description }}</span>\n </div>\n }\n @if (artifactVersion?.Description && artifact.Description && artifactVersion?.Description !== artifact.Description) {\n <div class=\"meta-item full-width\">\n <label>Version Description</label>\n <span>{{ artifactVersion?.Description }}</span>\n </div>\n }\n </div>\n\n <!-- Version Attributes -->\n @if (filteredAttributes.length > 0) {\n <div class=\"attributes-section\">\n <h4>Version Attributes</h4>\n <div class=\"attributes-list\">\n @for (attr of filteredAttributes; track attr.ID) {\n <div class=\"attribute-item\">\n <label>{{ attr.Name }}</label>\n @if (attr.Value) {\n <span>{{ attr.Value }}</span>\n } @else {\n <span class=\"attribute-empty-pill\">Empty</span>\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Links Tab - Conversations and Collections (always in DOM, hidden with CSS) -->\n <div class=\"links-container\" [class.tab-hidden]=\"activeTab !== 'links'\">\n @if (linksToShow.length > 0) {\n <div class=\"links-section\">\n @for (link of linksToShow; track link.id) {\n <div class=\"link-item\"\n [class.disabled]=\"!link.hasAccess\"\n [class.clickable]=\"link.hasAccess\"\n (click)=\"link.hasAccess ? onNavigateToLink(link) : null\"\n [title]=\"link.hasAccess ? 'Click to open' : 'No access'\">\n <div class=\"link-icon\">\n @if (link.type === 'conversation') {\n <i class=\"fas fa-comments\"></i>\n } @else {\n <i class=\"fas fa-folder\"></i>\n }\n </div>\n <div class=\"link-content\">\n <div class=\"link-name\">{{ link.name }}</div>\n <div class=\"link-type\">{{ link.type === 'conversation' ? 'Conversation' : 'Collection' }}</div>\n </div>\n <div class=\"link-actions\">\n <i class=\"fas fa-arrow-right\"></i>\n </div>\n </div>\n }\n </div>\n } @else {\n <div class=\"empty-state\">\n <i class=\"fas fa-link\"></i>\n <p>No links available</p>\n </div>\n }\n </div>\n\n <!-- Dynamic Plugin Tabs and Base Tabs (JSON, etc.) -->\n @if (activeTab !== 'display' && activeTab !== 'details' && activeTab !== 'links') {\n <!-- Check if this is a component tab -->\n @if (GetComponentTabType(activeTab); as componentType) {\n <div class=\"component-tab-content\">\n <ng-container *ngComponentOutlet=\"componentType; inputs: GetComponentInputs(activeTab)\"></ng-container>\n </div>\n } @else {\n @if (GetTabContent(activeTab); as tabData) {\n <div class=\"dynamic-tab-content\">\n @switch (tabData.type) {\n @case ('markdown') {\n <div class=\"markdown-viewer\">\n <mj-markdown [data]=\"tabData.content\"\n [enableCollapsibleHeadings]=\"true\"\n [enableLineNumbers]=\"true\"\n [enableSmartypants]=\"true\"\n [enableHtml]=\"true\"></mj-markdown>\n </div>\n }\n @case ('json') {\n <div class=\"json-viewer\">\n <div class=\"json-toolbar\">\n <button class=\"btn-icon\" title=\"Copy JSON\" (click)=\"onCopyToClipboard()\">\n <i class=\"fas fa-copy\"></i> Copy\n </button>\n </div>\n <div class=\"json-editor-container\">\n <mj-code-editor\n [value]=\"tabData.content\"\n [language]=\"'json'\"\n [readonly]=\"true\"\n [lineWrapping]=\"true\"\n style=\"width: 100%; height: 100%;\">\n </mj-code-editor>\n </div>\n </div>\n }\n @case ('code') {\n <div class=\"code-viewer\">\n <div class=\"code-toolbar\">\n <button class=\"btn-icon\" title=\"Copy Code\" (click)=\"onCopyToClipboard()\">\n <i class=\"fas fa-copy\"></i> Copy\n </button>\n </div>\n <div class=\"code-editor-container\">\n <mj-code-editor\n [value]=\"tabData.content\"\n [language]=\"tabData.language || 'typescript'\"\n [readonly]=\"true\"\n [lineWrapping]=\"true\"\n style=\"width: 100%; height: 100%;\">\n </mj-code-editor>\n </div>\n </div>\n }\n @case ('html') {\n <div class=\"html-viewer\" [innerHTML]=\"tabData.content\"></div>\n }\n @case ('plaintext') {\n <pre class=\"plaintext-viewer\">{{ tabData.content }}</pre>\n }\n }\n </div>\n }\n }\n }\n </div>\n </div>\n }\n </div>\n</div>\n\n"]}
|
package/dist/lib/components/plugins/component-feedback-panel/component-feedback-panel.component.js
CHANGED
|
@@ -565,11 +565,11 @@ export class ComponentFeedbackPanelComponent extends BaseAngularComponent {
|
|
|
565
565
|
i0.ɵɵconditional(ctx.ComponentSpec ? 15 : 16);
|
|
566
566
|
i0.ɵɵadvance(3);
|
|
567
567
|
i0.ɵɵconditional(ctx.SelectedSpec ? 18 : 19);
|
|
568
|
-
} }, dependencies: [CommonModule, FormsModule, i1.DefaultValueAccessor, i1.NgControlStatus, i1.MaxLengthValidator, i1.NgModel, MarkdownModule, i2.MarkdownComponent], styles: ["\n\n.feedback-panel-overlay[_ngcontent-%COMP%] {\n position: fixed;\n top: 60px;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: var(--mj-bg-overlay, rgba(0, 0, 0, 0.4));\n z-index: 9999;\n display: flex;\n justify-content: flex-start;\n animation: _ngcontent-%COMP%_fadeIn 0.2s ease-in-out;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n\n\n.feedback-panel[_ngcontent-%COMP%] {\n width: 540px;\n height: 100%;\n background-color: var(--mj-bg-surface, #ffffff);\n box-shadow: 2px 0 8px rgba(0, 0, 0, 0.15);\n display: flex;\n flex-direction: column;\n animation: _ngcontent-%COMP%_slideInFromLeft 0.3s ease-out;\n}\n\n@keyframes _ngcontent-%COMP%_slideInFromLeft {\n from { transform: translateX(-100%); }\n to { transform: translateX(0); }\n}\n\n\n\n.panel-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default, #e0e0e0);\n background-color: var(--mj-bg-surface-card, #f8f9fa);\n}\n\n.panel-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary, #333);\n}\n\n.panel-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary, #3B82F6);\n font-size: 20px;\n}\n\n.close-button[_ngcontent-%COMP%] {\n min-width: 32px;\n height: 32px;\n padding: 0;\n border: none;\n background: none;\n border-radius: 4px;\n cursor: pointer;\n color: var(--mj-text-secondary, #555);\n font-size: 16px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.close-button[_ngcontent-%COMP%]:hover {\n background-color: var(--mj-bg-surface-hover, #e0e0e0);\n}\n\n\n\n.panel-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: 20px;\n padding: 20px;\n}\n\n\n\n.section-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-secondary, #555);\n margin-bottom: 12px;\n padding-bottom: 8px;\n border-bottom: 2px solid var(--mj-brand-primary, #3B82F6);\n}\n\n.section-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary, #3B82F6);\n}\n\n\n\n.tree-section[_ngcontent-%COMP%] {\n background-color: var(--mj-bg-surface-card, #f8f9fa);\n border-radius: 8px;\n padding: 16px;\n}\n\n.component-tree[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.tree-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.2s ease;\n user-select: none;\n}\n\n.tree-item[_ngcontent-%COMP%]:hover {\n background-color: color-mix(in srgb, var(--mj-brand-primary, #3B82F6) 10%, var(--mj-bg-surface, #ffffff));\n}\n\n.tree-item.selected[_ngcontent-%COMP%] {\n background-color: var(--mj-brand-primary, #3B82F6);\n color: var(--mj-text-inverse, #ffffff);\n font-weight: 500;\n}\n\n.tree-item.selected[_ngcontent-%COMP%] .component-icon[_ngcontent-%COMP%], \n.tree-item.selected[_ngcontent-%COMP%] .tree-toggle[_ngcontent-%COMP%] {\n color: var(--mj-text-inverse, #ffffff);\n}\n\n.tree-item.selected[_ngcontent-%COMP%] .component-badge[_ngcontent-%COMP%] {\n background-color: rgba(255, 255, 255, 0.2);\n color: var(--mj-text-inverse, #ffffff);\n border-color: rgba(255, 255, 255, 0.3);\n}\n\n.tree-toggle[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted, #666);\n cursor: pointer;\n transition: transform 0.2s ease;\n width: 16px;\n text-align: center;\n}\n\n.tree-spacer[_ngcontent-%COMP%] {\n width: 16px;\n display: inline-block;\n}\n\n.component-icon[_ngcontent-%COMP%] {\n font-size: 16px;\n color: var(--mj-brand-primary, #3B82F6);\n}\n\n.component-info[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n align-items: center;\n gap: 8px;\n overflow: hidden;\n}\n\n.component-name[_ngcontent-%COMP%] {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n font-size: 14px;\n}\n\n.component-badge[_ngcontent-%COMP%] {\n font-size: 10px;\n padding: 2px 6px;\n border-radius: 10px;\n background-color: color-mix(in srgb, var(--mj-brand-primary, #3B82F6) 10%, var(--mj-bg-surface, #ffffff));\n color: var(--mj-brand-primary, #3B82F6);\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary, #3B82F6) 30%, var(--mj-bg-surface, #ffffff));\n white-space: nowrap;\n font-weight: 500;\n}\n\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 20px;\n color: var(--mj-text-disabled, #999);\n font-size: 14px;\n}\n\n\n\n.feedback-section[_ngcontent-%COMP%] {\n background-color: var(--mj-bg-surface, #ffffff);\n border-radius: 8px;\n border: 1px solid var(--mj-border-default, #e0e0e0);\n padding: 16px;\n min-height: 300px;\n}\n\n.selected-component-info[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n}\n\n.component-description[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-secondary, #666);\n line-height: 1.5;\n margin: 0;\n padding: 12px;\n background-color: var(--mj-bg-surface-card, #f8f9fa);\n border-radius: 6px;\n border-left: 3px solid var(--mj-brand-primary, #3B82F6);\n}\n\n\n\n.star-rating-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.rating-label[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary, #333);\n}\n\n.star-rating[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.star-wrapper[_ngcontent-%COMP%] {\n position: relative;\n display: inline-block;\n cursor: pointer;\n}\n\n.star-wrapper[_ngcontent-%COMP%]:hover .star[_ngcontent-%COMP%] {\n transform: scale(1.2);\n filter: brightness(1.1);\n}\n\n.star-zone[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n height: 100%;\n width: 50%;\n z-index: 1;\n}\n\n.star-zone-left[_ngcontent-%COMP%] {\n left: 0;\n}\n\n.star-zone-right[_ngcontent-%COMP%] {\n right: 0;\n}\n\n.star[_ngcontent-%COMP%] {\n font-size: 32px;\n color: #ffd700;\n transition: all 0.2s ease;\n pointer-events: none;\n}\n\n.star.fa-regular[_ngcontent-%COMP%] {\n color: var(--mj-border-default, #d0d0d0);\n}\n\n.rating-text[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-secondary, #666);\n margin-top: 4px;\n}\n\n.rating-text.placeholder[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled, #999);\n font-style: italic;\n}\n\n\n\n.comment-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n position: relative;\n}\n\n.comment-label[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary, #333);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.optional-label[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: normal;\n color: var(--mj-text-disabled, #999);\n}\n\n.comment-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 12px;\n border: 1px solid var(--mj-border-default, #d0d0d0);\n border-radius: 6px;\n font-size: 14px;\n font-family: inherit;\n resize: vertical;\n min-height: 80px;\n transition: border-color 0.2s ease;\n background-color: var(--mj-bg-surface, #ffffff);\n color: var(--mj-text-primary, #333);\n box-sizing: border-box;\n}\n\n.comment-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary, #3B82F6);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary, #3B82F6) 15%, transparent);\n}\n\n.char-count[_ngcontent-%COMP%] {\n position: absolute;\n bottom: 8px;\n right: 12px;\n font-size: 11px;\n color: var(--mj-text-disabled, #999);\n background-color: var(--mj-bg-surface, #ffffff);\n padding: 2px 4px;\n}\n\n\n\n.submit-container[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-start;\n}\n\n.submit-button[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n font-size: 14px;\n font-weight: 500;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n background-color: var(--mj-brand-primary, #3B82F6);\n color: var(--mj-text-inverse, #ffffff);\n transition: background-color 0.2s ease;\n}\n\n.submit-button[_ngcontent-%COMP%]:hover:not(:disabled) {\n background-color: var(--mj-brand-primary-hover, #2563EB);\n}\n\n.submit-button[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n\n\n.message[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 16px;\n border-radius: 6px;\n font-size: 14px;\n animation: _ngcontent-%COMP%_slideDown 0.3s ease-out;\n}\n\n@keyframes _ngcontent-%COMP%_slideDown {\n from { opacity: 0; transform: translateY(-10px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n.success-message[_ngcontent-%COMP%] {\n background-color: var(--mj-status-success-bg, #d4edda);\n color: var(--mj-status-success-text, #155724);\n border: 1px solid var(--mj-status-success-border, #c3e6cb);\n}\n\n.success-message[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-success, #28a745);\n}\n\n.error-message[_ngcontent-%COMP%] {\n background-color: var(--mj-status-error-bg, #f8d7da);\n color: var(--mj-status-error-text, #721c24);\n border: 1px solid var(--mj-status-error-border, #f5c6cb);\n}\n\n.error-message[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-error, #dc3545);\n}\n\n\n\n.no-selection-message[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 12px;\n padding: 40px 20px;\n color: var(--mj-text-disabled, #999);\n text-align: center;\n}\n\n.no-selection-message[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 48px;\n color: var(--mj-border-default, #d0d0d0);\n}\n\n.no-selection-message[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n line-height: 1.5;\n}\n\n\n\n.panel-content[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 8px;\n}\n\n.panel-content[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background-color: var(--mj-bg-surface-sunken, #f1f1f1);\n}\n\n.panel-content[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background-color: var(--mj-border-strong, #c0c0c0);\n border-radius: 4px;\n}\n\n.panel-content[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background-color: var(--mj-text-disabled, #a0a0a0);\n}"] });
|
|
568
|
+
} }, dependencies: [CommonModule, FormsModule, i1.DefaultValueAccessor, i1.NgControlStatus, i1.MaxLengthValidator, i1.NgModel, MarkdownModule, i2.MarkdownComponent], styles: ["\n\n.feedback-panel-overlay[_ngcontent-%COMP%] {\n position: fixed;\n top: 60px;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: var(--mj-bg-overlay);\n z-index: 9999;\n display: flex;\n justify-content: flex-start;\n animation: _ngcontent-%COMP%_fadeIn 0.2s ease-in-out;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n\n\n.feedback-panel[_ngcontent-%COMP%] {\n width: 540px;\n height: 100%;\n background-color: var(--mj-bg-surface);\n \n\n\n box-shadow: 2px 0 8px rgba(0, 0, 0, 0.15);\n display: flex;\n flex-direction: column;\n animation: _ngcontent-%COMP%_slideInFromLeft 0.3s ease-out;\n}\n\n@keyframes _ngcontent-%COMP%_slideInFromLeft {\n from { transform: translateX(-100%); }\n to { transform: translateX(0); }\n}\n\n\n\n.panel-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background-color: var(--mj-bg-surface-card);\n}\n\n.panel-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.panel-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 20px;\n}\n\n.close-button[_ngcontent-%COMP%] {\n min-width: 32px;\n height: 32px;\n padding: 0;\n border: none;\n background: none;\n border-radius: 4px;\n cursor: pointer;\n color: var(--mj-text-secondary);\n font-size: 16px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.close-button[_ngcontent-%COMP%]:hover {\n background-color: var(--mj-bg-surface-hover);\n}\n\n\n\n.panel-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: 20px;\n padding: 20px;\n}\n\n\n\n.section-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n margin-bottom: 12px;\n padding-bottom: 8px;\n border-bottom: 2px solid var(--mj-brand-primary);\n}\n\n.section-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n\n\n.tree-section[_ngcontent-%COMP%] {\n background-color: var(--mj-bg-surface-card);\n border-radius: 8px;\n padding: 16px;\n}\n\n.component-tree[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.tree-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.2s ease;\n user-select: none;\n}\n\n.tree-item[_ngcontent-%COMP%]:hover {\n background-color: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.tree-item.selected[_ngcontent-%COMP%] {\n background-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-weight: 500;\n}\n\n.tree-item.selected[_ngcontent-%COMP%] .component-icon[_ngcontent-%COMP%], \n.tree-item.selected[_ngcontent-%COMP%] .tree-toggle[_ngcontent-%COMP%] {\n color: var(--mj-text-inverse);\n}\n\n.tree-item.selected[_ngcontent-%COMP%] .component-badge[_ngcontent-%COMP%] {\n background-color: rgba(255, 255, 255, 0.2);\n color: var(--mj-text-inverse);\n border-color: rgba(255, 255, 255, 0.3);\n}\n\n.tree-toggle[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n cursor: pointer;\n transition: transform 0.2s ease;\n width: 16px;\n text-align: center;\n}\n\n.tree-spacer[_ngcontent-%COMP%] {\n width: 16px;\n display: inline-block;\n}\n\n.component-icon[_ngcontent-%COMP%] {\n font-size: 16px;\n color: var(--mj-brand-primary);\n}\n\n.component-info[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n align-items: center;\n gap: 8px;\n overflow: hidden;\n}\n\n.component-name[_ngcontent-%COMP%] {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n font-size: 14px;\n}\n\n.component-badge[_ngcontent-%COMP%] {\n font-size: 10px;\n padding: 2px 6px;\n border-radius: 10px;\n background-color: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, var(--mj-bg-surface));\n white-space: nowrap;\n font-weight: 500;\n}\n\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 20px;\n color: var(--mj-text-disabled);\n font-size: 14px;\n}\n\n\n\n.feedback-section[_ngcontent-%COMP%] {\n background-color: var(--mj-bg-surface);\n border-radius: 8px;\n border: 1px solid var(--mj-border-default);\n padding: 16px;\n min-height: 300px;\n}\n\n.selected-component-info[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n}\n\n.component-description[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-secondary);\n line-height: 1.5;\n margin: 0;\n padding: 12px;\n background-color: var(--mj-bg-surface-card);\n border-radius: 6px;\n border-left: 3px solid var(--mj-brand-primary);\n}\n\n\n\n.star-rating-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.rating-label[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.star-rating[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.star-wrapper[_ngcontent-%COMP%] {\n position: relative;\n display: inline-block;\n cursor: pointer;\n}\n\n.star-wrapper[_ngcontent-%COMP%]:hover .star[_ngcontent-%COMP%] {\n transform: scale(1.2);\n filter: brightness(1.1);\n}\n\n.star-zone[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n height: 100%;\n width: 50%;\n z-index: 1;\n}\n\n.star-zone-left[_ngcontent-%COMP%] {\n left: 0;\n}\n\n.star-zone-right[_ngcontent-%COMP%] {\n right: 0;\n}\n\n.star[_ngcontent-%COMP%] {\n font-size: 32px;\n \n\n color: #ffd700;\n transition: all 0.2s ease;\n pointer-events: none;\n}\n\n.star.fa-regular[_ngcontent-%COMP%] {\n color: var(--mj-border-strong);\n}\n\n.rating-text[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-secondary);\n margin-top: 4px;\n}\n\n.rating-text.placeholder[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled);\n font-style: italic;\n}\n\n\n\n.comment-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n position: relative;\n}\n\n.comment-label[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.optional-label[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: normal;\n color: var(--mj-text-disabled);\n}\n\n.comment-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 14px;\n font-family: inherit;\n resize: vertical;\n min-height: 80px;\n transition: border-color 0.2s ease;\n background-color: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n box-sizing: border-box;\n}\n\n.comment-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.char-count[_ngcontent-%COMP%] {\n position: absolute;\n bottom: 8px;\n right: 12px;\n font-size: 11px;\n color: var(--mj-text-disabled);\n background-color: var(--mj-bg-surface);\n padding: 2px 4px;\n}\n\n\n\n.submit-container[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-start;\n}\n\n.submit-button[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n font-size: 14px;\n font-weight: 500;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n background-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n transition: background-color 0.2s ease;\n}\n\n.submit-button[_ngcontent-%COMP%]:hover:not(:disabled) {\n background-color: var(--mj-brand-primary-hover);\n}\n\n.submit-button[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n\n\n.message[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 16px;\n border-radius: 6px;\n font-size: 14px;\n animation: _ngcontent-%COMP%_slideDown 0.3s ease-out;\n}\n\n@keyframes _ngcontent-%COMP%_slideDown {\n from { opacity: 0; transform: translateY(-10px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n.success-message[_ngcontent-%COMP%] {\n background-color: var(--mj-status-success-bg);\n color: var(--mj-status-success-text);\n border: 1px solid var(--mj-status-success-border);\n}\n\n.success-message[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n}\n\n.error-message[_ngcontent-%COMP%] {\n background-color: var(--mj-status-error-bg);\n color: var(--mj-status-error-text);\n border: 1px solid var(--mj-status-error-border);\n}\n\n.error-message[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n\n\n.no-selection-message[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 12px;\n padding: 40px 20px;\n color: var(--mj-text-disabled);\n text-align: center;\n}\n\n.no-selection-message[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 48px;\n color: var(--mj-border-strong);\n}\n\n.no-selection-message[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n line-height: 1.5;\n}\n\n\n\n.panel-content[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 8px;\n}\n\n.panel-content[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background-color: var(--mj-bg-surface-sunken);\n}\n\n.panel-content[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background-color: var(--mj-border-strong);\n border-radius: 4px;\n}\n\n.panel-content[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background-color: var(--mj-text-disabled);\n}"] });
|
|
569
569
|
}
|
|
570
570
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ComponentFeedbackPanelComponent, [{
|
|
571
571
|
type: Component,
|
|
572
|
-
args: [{ selector: 'mj-component-feedback-panel', standalone: true, imports: [CommonModule, FormsModule, MarkdownModule], template: "<div class=\"feedback-panel-overlay\" (click)=\"ClosePanel()\">\n <div class=\"feedback-panel\" (click)=\"$event.stopPropagation()\">\n <!-- Header -->\n <div class=\"panel-header\">\n <div class=\"panel-title\">\n <i class=\"fa-solid fa-magnifying-glass\"></i>\n <span>Inspect & Rate</span>\n </div>\n <button class=\"close-button\" (click)=\"ClosePanel()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <!-- Content -->\n <div class=\"panel-content\">\n <!-- Component Tree Section -->\n <div class=\"tree-section\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-sitemap\"></i>\n <span>Select Component</span>\n </div>\n\n @if (ComponentSpec) {\n <div class=\"component-tree\">\n @for (item of GetTreeItems(); track item.spec.name) {\n <div\n class=\"tree-item\"\n [class.selected]=\"IsSelected(item.spec)\"\n [style.padding-left]=\"GetIndentation(item.depth)\"\n (click)=\"SelectComponent(item.spec)\"\n (mouseenter)=\"HoverTreeItem(item.spec)\"\n (mouseleave)=\"ClearTreeItemHover()\">\n\n @if (item.hasChildren) {\n <i\n class=\"tree-toggle fa-solid\"\n [class.fa-chevron-right]=\"!IsNodeExpanded(item.spec)\"\n [class.fa-chevron-down]=\"IsNodeExpanded(item.spec)\"\n (click)=\"ToggleNode(item.spec, $event)\">\n </i>\n } @else {\n <span class=\"tree-spacer\"></span>\n }\n\n <i class=\"fa-solid fa-cube component-icon\"></i>\n\n <div class=\"component-info\">\n <span class=\"component-name\">{{ item.spec.title || item.spec.name }}</span>\n @if (item.spec.location === 'registry') {\n <span class=\"component-badge registry\">Registry</span>\n }\n </div>\n </div>\n }\n </div>\n } @else {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>No component hierarchy available</span>\n </div>\n }\n </div>\n\n <!-- Feedback Form Section -->\n <div class=\"feedback-section\">\n @if (SelectedSpec) {\n <div class=\"selected-component-info\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-star\"></i>\n <span>Rate: {{ SelectedSpec.title || SelectedSpec.name }}</span>\n </div>\n\n @if (SelectedSpec.description) {\n <mj-markdown [data]=\"SelectedSpec.description\" class=\"component-description\"></mj-markdown>\n }\n\n <!-- Star Rating (half-star support) -->\n <div class=\"star-rating-container\">\n <label class=\"rating-label\">Your Rating</label>\n <div class=\"star-rating\" (mouseleave)=\"ClearHoverRating()\">\n @for (star of [1, 2, 3, 4, 5]; track star) {\n <span class=\"star-wrapper\">\n <!-- Left half (sets X.5 for previous half) -->\n <span class=\"star-zone star-zone-left\"\n (click)=\"SetRating(star - 0.5)\"\n (mouseenter)=\"SetHoverRating(star - 0.5)\"></span>\n <!-- Right half (sets full star) -->\n <span class=\"star-zone star-zone-right\"\n (click)=\"SetRating(star)\"\n (mouseenter)=\"SetHoverRating(star)\"></span>\n <!-- Star icon -->\n @switch (GetStarState(star)) {\n @case ('full') {\n <i class=\"star fa-solid fa-star\"></i>\n }\n @case ('half') {\n <i class=\"star fa-solid fa-star-half-stroke\"></i>\n }\n @default {\n <i class=\"star fa-regular fa-star\"></i>\n }\n }\n </span>\n }\n </div>\n @if (StarRating === 0) {\n <span class=\"rating-text placeholder\">Click to rate</span>\n }\n </div>\n\n <!-- Comment Input -->\n <div class=\"comment-container\">\n <label class=\"comment-label\">\n Comments\n <span class=\"optional-label\">(optional)</span>\n </label>\n <textarea\n class=\"comment-input\"\n [(ngModel)]=\"FeedbackComments\"\n placeholder=\"Share your thoughts about this component...\"\n rows=\"4\"\n maxlength=\"1000\">\n </textarea>\n @if (FeedbackComments.length > 0) {\n <span class=\"char-count\">{{ FeedbackComments.length }}/1000</span>\n }\n </div>\n\n <!-- Submit Button -->\n <div class=\"submit-container\">\n <button\n class=\"submit-button\"\n [disabled]=\"!CanSubmit()\"\n (click)=\"SubmitFeedback()\">\n @if (IsSubmitting) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Submitting...</span>\n } @else {\n <i class=\"fa-solid fa-paper-plane\"></i>\n <span>Submit Feedback</span>\n }\n </button>\n </div>\n\n <!-- Success/Error Messages -->\n @if (SubmitSuccess) {\n <div class=\"message success-message\">\n <i class=\"fa-solid fa-check-circle\"></i>\n <span>Feedback submitted successfully!</span>\n </div>\n }\n @if (SubmitError) {\n <div class=\"message error-message\">\n <i class=\"fa-solid fa-exclamation-circle\"></i>\n <span>{{ SubmitError }}</span>\n </div>\n }\n </div>\n } @else {\n <div class=\"no-selection-message\">\n <i class=\"fa-solid fa-hand-pointer\"></i>\n <p>Select a component from the tree to provide feedback</p>\n </div>\n }\n </div>\n </div>\n </div>\n</div>\n", styles: ["/* Overlay */\n.feedback-panel-overlay {\n position: fixed;\n top: 60px;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: var(--mj-bg-overlay, rgba(0, 0, 0, 0.4));\n z-index: 9999;\n display: flex;\n justify-content: flex-start;\n animation: fadeIn 0.2s ease-in-out;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n/* Panel Container */\n.feedback-panel {\n width: 540px;\n height: 100%;\n background-color: var(--mj-bg-surface, #ffffff);\n box-shadow: 2px 0 8px rgba(0, 0, 0, 0.15);\n display: flex;\n flex-direction: column;\n animation: slideInFromLeft 0.3s ease-out;\n}\n\n@keyframes slideInFromLeft {\n from { transform: translateX(-100%); }\n to { transform: translateX(0); }\n}\n\n/* Header */\n.panel-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default, #e0e0e0);\n background-color: var(--mj-bg-surface-card, #f8f9fa);\n}\n\n.panel-title {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary, #333);\n}\n\n.panel-title i {\n color: var(--mj-brand-primary, #3B82F6);\n font-size: 20px;\n}\n\n.close-button {\n min-width: 32px;\n height: 32px;\n padding: 0;\n border: none;\n background: none;\n border-radius: 4px;\n cursor: pointer;\n color: var(--mj-text-secondary, #555);\n font-size: 16px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.close-button:hover {\n background-color: var(--mj-bg-surface-hover, #e0e0e0);\n}\n\n/* Content */\n.panel-content {\n flex: 1;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: 20px;\n padding: 20px;\n}\n\n/* Section Headers */\n.section-header {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-secondary, #555);\n margin-bottom: 12px;\n padding-bottom: 8px;\n border-bottom: 2px solid var(--mj-brand-primary, #3B82F6);\n}\n\n.section-header i {\n color: var(--mj-brand-primary, #3B82F6);\n}\n\n/* Component Tree */\n.tree-section {\n background-color: var(--mj-bg-surface-card, #f8f9fa);\n border-radius: 8px;\n padding: 16px;\n}\n\n.component-tree {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.tree-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.2s ease;\n user-select: none;\n}\n\n.tree-item:hover {\n background-color: color-mix(in srgb, var(--mj-brand-primary, #3B82F6) 10%, var(--mj-bg-surface, #ffffff));\n}\n\n.tree-item.selected {\n background-color: var(--mj-brand-primary, #3B82F6);\n color: var(--mj-text-inverse, #ffffff);\n font-weight: 500;\n}\n\n.tree-item.selected .component-icon,\n.tree-item.selected .tree-toggle {\n color: var(--mj-text-inverse, #ffffff);\n}\n\n.tree-item.selected .component-badge {\n background-color: rgba(255, 255, 255, 0.2);\n color: var(--mj-text-inverse, #ffffff);\n border-color: rgba(255, 255, 255, 0.3);\n}\n\n.tree-toggle {\n font-size: 12px;\n color: var(--mj-text-muted, #666);\n cursor: pointer;\n transition: transform 0.2s ease;\n width: 16px;\n text-align: center;\n}\n\n.tree-spacer {\n width: 16px;\n display: inline-block;\n}\n\n.component-icon {\n font-size: 16px;\n color: var(--mj-brand-primary, #3B82F6);\n}\n\n.component-info {\n flex: 1;\n display: flex;\n align-items: center;\n gap: 8px;\n overflow: hidden;\n}\n\n.component-name {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n font-size: 14px;\n}\n\n.component-badge {\n font-size: 10px;\n padding: 2px 6px;\n border-radius: 10px;\n background-color: color-mix(in srgb, var(--mj-brand-primary, #3B82F6) 10%, var(--mj-bg-surface, #ffffff));\n color: var(--mj-brand-primary, #3B82F6);\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary, #3B82F6) 30%, var(--mj-bg-surface, #ffffff));\n white-space: nowrap;\n font-weight: 500;\n}\n\n.empty-state {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 20px;\n color: var(--mj-text-disabled, #999);\n font-size: 14px;\n}\n\n/* Feedback Form Section */\n.feedback-section {\n background-color: var(--mj-bg-surface, #ffffff);\n border-radius: 8px;\n border: 1px solid var(--mj-border-default, #e0e0e0);\n padding: 16px;\n min-height: 300px;\n}\n\n.selected-component-info {\n display: flex;\n flex-direction: column;\n gap: 20px;\n}\n\n.component-description {\n font-size: 13px;\n color: var(--mj-text-secondary, #666);\n line-height: 1.5;\n margin: 0;\n padding: 12px;\n background-color: var(--mj-bg-surface-card, #f8f9fa);\n border-radius: 6px;\n border-left: 3px solid var(--mj-brand-primary, #3B82F6);\n}\n\n/* Star Rating */\n.star-rating-container {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.rating-label {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary, #333);\n}\n\n.star-rating {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.star-wrapper {\n position: relative;\n display: inline-block;\n cursor: pointer;\n}\n\n.star-wrapper:hover .star {\n transform: scale(1.2);\n filter: brightness(1.1);\n}\n\n.star-zone {\n position: absolute;\n top: 0;\n height: 100%;\n width: 50%;\n z-index: 1;\n}\n\n.star-zone-left {\n left: 0;\n}\n\n.star-zone-right {\n right: 0;\n}\n\n.star {\n font-size: 32px;\n color: #ffd700;\n transition: all 0.2s ease;\n pointer-events: none;\n}\n\n.star.fa-regular {\n color: var(--mj-border-default, #d0d0d0);\n}\n\n.rating-text {\n font-size: 13px;\n color: var(--mj-text-secondary, #666);\n margin-top: 4px;\n}\n\n.rating-text.placeholder {\n color: var(--mj-text-disabled, #999);\n font-style: italic;\n}\n\n/* Comment Input */\n.comment-container {\n display: flex;\n flex-direction: column;\n gap: 8px;\n position: relative;\n}\n\n.comment-label {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary, #333);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.optional-label {\n font-size: 12px;\n font-weight: normal;\n color: var(--mj-text-disabled, #999);\n}\n\n.comment-input {\n width: 100%;\n padding: 12px;\n border: 1px solid var(--mj-border-default, #d0d0d0);\n border-radius: 6px;\n font-size: 14px;\n font-family: inherit;\n resize: vertical;\n min-height: 80px;\n transition: border-color 0.2s ease;\n background-color: var(--mj-bg-surface, #ffffff);\n color: var(--mj-text-primary, #333);\n box-sizing: border-box;\n}\n\n.comment-input:focus {\n outline: none;\n border-color: var(--mj-brand-primary, #3B82F6);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary, #3B82F6) 15%, transparent);\n}\n\n.char-count {\n position: absolute;\n bottom: 8px;\n right: 12px;\n font-size: 11px;\n color: var(--mj-text-disabled, #999);\n background-color: var(--mj-bg-surface, #ffffff);\n padding: 2px 4px;\n}\n\n/* Submit Button */\n.submit-container {\n display: flex;\n justify-content: flex-start;\n}\n\n.submit-button {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n font-size: 14px;\n font-weight: 500;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n background-color: var(--mj-brand-primary, #3B82F6);\n color: var(--mj-text-inverse, #ffffff);\n transition: background-color 0.2s ease;\n}\n\n.submit-button:hover:not(:disabled) {\n background-color: var(--mj-brand-primary-hover, #2563EB);\n}\n\n.submit-button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* Messages */\n.message {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 16px;\n border-radius: 6px;\n font-size: 14px;\n animation: slideDown 0.3s ease-out;\n}\n\n@keyframes slideDown {\n from { opacity: 0; transform: translateY(-10px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n.success-message {\n background-color: var(--mj-status-success-bg, #d4edda);\n color: var(--mj-status-success-text, #155724);\n border: 1px solid var(--mj-status-success-border, #c3e6cb);\n}\n\n.success-message i {\n color: var(--mj-status-success, #28a745);\n}\n\n.error-message {\n background-color: var(--mj-status-error-bg, #f8d7da);\n color: var(--mj-status-error-text, #721c24);\n border: 1px solid var(--mj-status-error-border, #f5c6cb);\n}\n\n.error-message i {\n color: var(--mj-status-error, #dc3545);\n}\n\n/* No Selection Message */\n.no-selection-message {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 12px;\n padding: 40px 20px;\n color: var(--mj-text-disabled, #999);\n text-align: center;\n}\n\n.no-selection-message i {\n font-size: 48px;\n color: var(--mj-border-default, #d0d0d0);\n}\n\n.no-selection-message p {\n margin: 0;\n font-size: 14px;\n line-height: 1.5;\n}\n\n/* Scrollbar Styling */\n.panel-content::-webkit-scrollbar {\n width: 8px;\n}\n\n.panel-content::-webkit-scrollbar-track {\n background-color: var(--mj-bg-surface-sunken, #f1f1f1);\n}\n\n.panel-content::-webkit-scrollbar-thumb {\n background-color: var(--mj-border-strong, #c0c0c0);\n border-radius: 4px;\n}\n\n.panel-content::-webkit-scrollbar-thumb:hover {\n background-color: var(--mj-text-disabled, #a0a0a0);\n}\n"] }]
|
|
572
|
+
args: [{ selector: 'mj-component-feedback-panel', standalone: true, imports: [CommonModule, FormsModule, MarkdownModule], template: "<div class=\"feedback-panel-overlay\" (click)=\"ClosePanel()\">\n <div class=\"feedback-panel\" (click)=\"$event.stopPropagation()\">\n <!-- Header -->\n <div class=\"panel-header\">\n <div class=\"panel-title\">\n <i class=\"fa-solid fa-magnifying-glass\"></i>\n <span>Inspect & Rate</span>\n </div>\n <button class=\"close-button\" (click)=\"ClosePanel()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <!-- Content -->\n <div class=\"panel-content\">\n <!-- Component Tree Section -->\n <div class=\"tree-section\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-sitemap\"></i>\n <span>Select Component</span>\n </div>\n\n @if (ComponentSpec) {\n <div class=\"component-tree\">\n @for (item of GetTreeItems(); track item.spec.name) {\n <div\n class=\"tree-item\"\n [class.selected]=\"IsSelected(item.spec)\"\n [style.padding-left]=\"GetIndentation(item.depth)\"\n (click)=\"SelectComponent(item.spec)\"\n (mouseenter)=\"HoverTreeItem(item.spec)\"\n (mouseleave)=\"ClearTreeItemHover()\">\n\n @if (item.hasChildren) {\n <i\n class=\"tree-toggle fa-solid\"\n [class.fa-chevron-right]=\"!IsNodeExpanded(item.spec)\"\n [class.fa-chevron-down]=\"IsNodeExpanded(item.spec)\"\n (click)=\"ToggleNode(item.spec, $event)\">\n </i>\n } @else {\n <span class=\"tree-spacer\"></span>\n }\n\n <i class=\"fa-solid fa-cube component-icon\"></i>\n\n <div class=\"component-info\">\n <span class=\"component-name\">{{ item.spec.title || item.spec.name }}</span>\n @if (item.spec.location === 'registry') {\n <span class=\"component-badge registry\">Registry</span>\n }\n </div>\n </div>\n }\n </div>\n } @else {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>No component hierarchy available</span>\n </div>\n }\n </div>\n\n <!-- Feedback Form Section -->\n <div class=\"feedback-section\">\n @if (SelectedSpec) {\n <div class=\"selected-component-info\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-star\"></i>\n <span>Rate: {{ SelectedSpec.title || SelectedSpec.name }}</span>\n </div>\n\n @if (SelectedSpec.description) {\n <mj-markdown [data]=\"SelectedSpec.description\" class=\"component-description\"></mj-markdown>\n }\n\n <!-- Star Rating (half-star support) -->\n <div class=\"star-rating-container\">\n <label class=\"rating-label\">Your Rating</label>\n <div class=\"star-rating\" (mouseleave)=\"ClearHoverRating()\">\n @for (star of [1, 2, 3, 4, 5]; track star) {\n <span class=\"star-wrapper\">\n <!-- Left half (sets X.5 for previous half) -->\n <span class=\"star-zone star-zone-left\"\n (click)=\"SetRating(star - 0.5)\"\n (mouseenter)=\"SetHoverRating(star - 0.5)\"></span>\n <!-- Right half (sets full star) -->\n <span class=\"star-zone star-zone-right\"\n (click)=\"SetRating(star)\"\n (mouseenter)=\"SetHoverRating(star)\"></span>\n <!-- Star icon -->\n @switch (GetStarState(star)) {\n @case ('full') {\n <i class=\"star fa-solid fa-star\"></i>\n }\n @case ('half') {\n <i class=\"star fa-solid fa-star-half-stroke\"></i>\n }\n @default {\n <i class=\"star fa-regular fa-star\"></i>\n }\n }\n </span>\n }\n </div>\n @if (StarRating === 0) {\n <span class=\"rating-text placeholder\">Click to rate</span>\n }\n </div>\n\n <!-- Comment Input -->\n <div class=\"comment-container\">\n <label class=\"comment-label\">\n Comments\n <span class=\"optional-label\">(optional)</span>\n </label>\n <textarea\n class=\"comment-input\"\n [(ngModel)]=\"FeedbackComments\"\n placeholder=\"Share your thoughts about this component...\"\n rows=\"4\"\n maxlength=\"1000\">\n </textarea>\n @if (FeedbackComments.length > 0) {\n <span class=\"char-count\">{{ FeedbackComments.length }}/1000</span>\n }\n </div>\n\n <!-- Submit Button -->\n <div class=\"submit-container\">\n <button\n class=\"submit-button\"\n [disabled]=\"!CanSubmit()\"\n (click)=\"SubmitFeedback()\">\n @if (IsSubmitting) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Submitting...</span>\n } @else {\n <i class=\"fa-solid fa-paper-plane\"></i>\n <span>Submit Feedback</span>\n }\n </button>\n </div>\n\n <!-- Success/Error Messages -->\n @if (SubmitSuccess) {\n <div class=\"message success-message\">\n <i class=\"fa-solid fa-check-circle\"></i>\n <span>Feedback submitted successfully!</span>\n </div>\n }\n @if (SubmitError) {\n <div class=\"message error-message\">\n <i class=\"fa-solid fa-exclamation-circle\"></i>\n <span>{{ SubmitError }}</span>\n </div>\n }\n </div>\n } @else {\n <div class=\"no-selection-message\">\n <i class=\"fa-solid fa-hand-pointer\"></i>\n <p>Select a component from the tree to provide feedback</p>\n </div>\n }\n </div>\n </div>\n </div>\n</div>\n", styles: ["/* Overlay */\n.feedback-panel-overlay {\n position: fixed;\n top: 60px;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: var(--mj-bg-overlay);\n z-index: 9999;\n display: flex;\n justify-content: flex-start;\n animation: fadeIn 0.2s ease-in-out;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n/* Panel Container */\n.feedback-panel {\n width: 540px;\n height: 100%;\n background-color: var(--mj-bg-surface);\n /* Side-panel shadow (horizontal): no semantic token covers a horizontal panel shadow,\n and the alpha keeps it readable in both light and dark themes. */\n box-shadow: 2px 0 8px rgba(0, 0, 0, 0.15);\n display: flex;\n flex-direction: column;\n animation: slideInFromLeft 0.3s ease-out;\n}\n\n@keyframes slideInFromLeft {\n from { transform: translateX(-100%); }\n to { transform: translateX(0); }\n}\n\n/* Header */\n.panel-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background-color: var(--mj-bg-surface-card);\n}\n\n.panel-title {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.panel-title i {\n color: var(--mj-brand-primary);\n font-size: 20px;\n}\n\n.close-button {\n min-width: 32px;\n height: 32px;\n padding: 0;\n border: none;\n background: none;\n border-radius: 4px;\n cursor: pointer;\n color: var(--mj-text-secondary);\n font-size: 16px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.close-button:hover {\n background-color: var(--mj-bg-surface-hover);\n}\n\n/* Content */\n.panel-content {\n flex: 1;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: 20px;\n padding: 20px;\n}\n\n/* Section Headers */\n.section-header {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n margin-bottom: 12px;\n padding-bottom: 8px;\n border-bottom: 2px solid var(--mj-brand-primary);\n}\n\n.section-header i {\n color: var(--mj-brand-primary);\n}\n\n/* Component Tree */\n.tree-section {\n background-color: var(--mj-bg-surface-card);\n border-radius: 8px;\n padding: 16px;\n}\n\n.component-tree {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.tree-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.2s ease;\n user-select: none;\n}\n\n.tree-item:hover {\n background-color: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.tree-item.selected {\n background-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-weight: 500;\n}\n\n.tree-item.selected .component-icon,\n.tree-item.selected .tree-toggle {\n color: var(--mj-text-inverse);\n}\n\n.tree-item.selected .component-badge {\n background-color: rgba(255, 255, 255, 0.2);\n color: var(--mj-text-inverse);\n border-color: rgba(255, 255, 255, 0.3);\n}\n\n.tree-toggle {\n font-size: 12px;\n color: var(--mj-text-muted);\n cursor: pointer;\n transition: transform 0.2s ease;\n width: 16px;\n text-align: center;\n}\n\n.tree-spacer {\n width: 16px;\n display: inline-block;\n}\n\n.component-icon {\n font-size: 16px;\n color: var(--mj-brand-primary);\n}\n\n.component-info {\n flex: 1;\n display: flex;\n align-items: center;\n gap: 8px;\n overflow: hidden;\n}\n\n.component-name {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n font-size: 14px;\n}\n\n.component-badge {\n font-size: 10px;\n padding: 2px 6px;\n border-radius: 10px;\n background-color: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, var(--mj-bg-surface));\n white-space: nowrap;\n font-weight: 500;\n}\n\n.empty-state {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 20px;\n color: var(--mj-text-disabled);\n font-size: 14px;\n}\n\n/* Feedback Form Section */\n.feedback-section {\n background-color: var(--mj-bg-surface);\n border-radius: 8px;\n border: 1px solid var(--mj-border-default);\n padding: 16px;\n min-height: 300px;\n}\n\n.selected-component-info {\n display: flex;\n flex-direction: column;\n gap: 20px;\n}\n\n.component-description {\n font-size: 13px;\n color: var(--mj-text-secondary);\n line-height: 1.5;\n margin: 0;\n padding: 12px;\n background-color: var(--mj-bg-surface-card);\n border-radius: 6px;\n border-left: 3px solid var(--mj-brand-primary);\n}\n\n/* Star Rating */\n.star-rating-container {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.rating-label {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.star-rating {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.star-wrapper {\n position: relative;\n display: inline-block;\n cursor: pointer;\n}\n\n.star-wrapper:hover .star {\n transform: scale(1.2);\n filter: brightness(1.1);\n}\n\n.star-zone {\n position: absolute;\n top: 0;\n height: 100%;\n width: 50%;\n z-index: 1;\n}\n\n.star-zone-left {\n left: 0;\n}\n\n.star-zone-right {\n right: 0;\n}\n\n.star {\n font-size: 32px;\n /* Iconic gold star \u2014 categorical/branding color, not theme-dependent */\n color: #ffd700;\n transition: all 0.2s ease;\n pointer-events: none;\n}\n\n.star.fa-regular {\n color: var(--mj-border-strong);\n}\n\n.rating-text {\n font-size: 13px;\n color: var(--mj-text-secondary);\n margin-top: 4px;\n}\n\n.rating-text.placeholder {\n color: var(--mj-text-disabled);\n font-style: italic;\n}\n\n/* Comment Input */\n.comment-container {\n display: flex;\n flex-direction: column;\n gap: 8px;\n position: relative;\n}\n\n.comment-label {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.optional-label {\n font-size: 12px;\n font-weight: normal;\n color: var(--mj-text-disabled);\n}\n\n.comment-input {\n width: 100%;\n padding: 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 14px;\n font-family: inherit;\n resize: vertical;\n min-height: 80px;\n transition: border-color 0.2s ease;\n background-color: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n box-sizing: border-box;\n}\n\n.comment-input:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.char-count {\n position: absolute;\n bottom: 8px;\n right: 12px;\n font-size: 11px;\n color: var(--mj-text-disabled);\n background-color: var(--mj-bg-surface);\n padding: 2px 4px;\n}\n\n/* Submit Button */\n.submit-container {\n display: flex;\n justify-content: flex-start;\n}\n\n.submit-button {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n font-size: 14px;\n font-weight: 500;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n background-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n transition: background-color 0.2s ease;\n}\n\n.submit-button:hover:not(:disabled) {\n background-color: var(--mj-brand-primary-hover);\n}\n\n.submit-button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* Messages */\n.message {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 16px;\n border-radius: 6px;\n font-size: 14px;\n animation: slideDown 0.3s ease-out;\n}\n\n@keyframes slideDown {\n from { opacity: 0; transform: translateY(-10px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n.success-message {\n background-color: var(--mj-status-success-bg);\n color: var(--mj-status-success-text);\n border: 1px solid var(--mj-status-success-border);\n}\n\n.success-message i {\n color: var(--mj-status-success);\n}\n\n.error-message {\n background-color: var(--mj-status-error-bg);\n color: var(--mj-status-error-text);\n border: 1px solid var(--mj-status-error-border);\n}\n\n.error-message i {\n color: var(--mj-status-error);\n}\n\n/* No Selection Message */\n.no-selection-message {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 12px;\n padding: 40px 20px;\n color: var(--mj-text-disabled);\n text-align: center;\n}\n\n.no-selection-message i {\n font-size: 48px;\n color: var(--mj-border-strong);\n}\n\n.no-selection-message p {\n margin: 0;\n font-size: 14px;\n line-height: 1.5;\n}\n\n/* Scrollbar Styling */\n.panel-content::-webkit-scrollbar {\n width: 8px;\n}\n\n.panel-content::-webkit-scrollbar-track {\n background-color: var(--mj-bg-surface-sunken);\n}\n\n.panel-content::-webkit-scrollbar-thumb {\n background-color: var(--mj-border-strong);\n border-radius: 4px;\n}\n\n.panel-content::-webkit-scrollbar-thumb:hover {\n background-color: var(--mj-text-disabled);\n}\n"] }]
|
|
573
573
|
}], null, { ComponentSpec: [{
|
|
574
574
|
type: Input
|
|
575
575
|
}], ReactContainerElement: [{
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/ng-artifacts",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.34.1",
|
|
4
4
|
"description": "MemberJunction: Artifact viewer plugin system for rendering different artifact types (JSON, Code, Markdown, HTML, SVG, Components)",
|
|
5
5
|
"main": "./dist/public-api.js",
|
|
6
6
|
"typings": "./dist/public-api.d.ts",
|
|
@@ -32,21 +32,21 @@
|
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@angular/cdk": "21.1.3",
|
|
34
34
|
"@angular/forms": "21.1.3",
|
|
35
|
-
"@memberjunction/core": "5.
|
|
36
|
-
"@memberjunction/core-entities": "5.
|
|
37
|
-
"@memberjunction/global": "5.
|
|
38
|
-
"@memberjunction/interactive-component-types": "5.
|
|
39
|
-
"@memberjunction/ng-base-types": "5.
|
|
40
|
-
"@memberjunction/ng-code-editor": "5.
|
|
41
|
-
"@memberjunction/ng-notifications": "5.
|
|
42
|
-
"@memberjunction/ng-react": "5.
|
|
43
|
-
"@memberjunction/ng-pagination": "5.
|
|
44
|
-
"@memberjunction/ng-shared-generic": "5.
|
|
45
|
-
"@memberjunction/ng-query-viewer": "5.
|
|
46
|
-
"@memberjunction/ng-trees": "5.
|
|
47
|
-
"@memberjunction/ng-export-service": "5.
|
|
48
|
-
"@memberjunction/ng-markdown": "5.
|
|
49
|
-
"@memberjunction/graphql-dataprovider": "5.
|
|
35
|
+
"@memberjunction/core": "5.34.1",
|
|
36
|
+
"@memberjunction/core-entities": "5.34.1",
|
|
37
|
+
"@memberjunction/global": "5.34.1",
|
|
38
|
+
"@memberjunction/interactive-component-types": "5.34.1",
|
|
39
|
+
"@memberjunction/ng-base-types": "5.34.1",
|
|
40
|
+
"@memberjunction/ng-code-editor": "5.34.1",
|
|
41
|
+
"@memberjunction/ng-notifications": "5.34.1",
|
|
42
|
+
"@memberjunction/ng-react": "5.34.1",
|
|
43
|
+
"@memberjunction/ng-pagination": "5.34.1",
|
|
44
|
+
"@memberjunction/ng-shared-generic": "5.34.1",
|
|
45
|
+
"@memberjunction/ng-query-viewer": "5.34.1",
|
|
46
|
+
"@memberjunction/ng-trees": "5.34.1",
|
|
47
|
+
"@memberjunction/ng-export-service": "5.34.1",
|
|
48
|
+
"@memberjunction/ng-markdown": "5.34.1",
|
|
49
|
+
"@memberjunction/graphql-dataprovider": "5.34.1",
|
|
50
50
|
"mammoth": "^1.8.0",
|
|
51
51
|
"pdfjs-dist": "^4.10.38",
|
|
52
52
|
"rxjs": "^7.8.2",
|