@memberjunction/ng-entity-relationship-diagram 6.1.0-edge.4 → 6.1.0-edge.6
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/entity-details/entity-details.component.js +1 -1
- package/dist/lib/components/entity-filter-panel/entity-filter-panel.component.js +1 -1
- package/dist/lib/components/erd-composite/erd-composite.component.js +1 -1
- package/dist/lib/components/erd-diagram.component.js +92 -93
- package/dist/lib/components/erd-diagram.component.js.map +1 -1
- package/package.json +12 -12
|
@@ -670,7 +670,7 @@ export class EntityDetailsComponent extends BaseAngularComponent {
|
|
|
670
670
|
i0.ɵɵproperty("Fill", true)("FlushBody", true)("Expanded", ctx.relationshipsSectionExpanded);
|
|
671
671
|
i0.ɵɵadvance(2);
|
|
672
672
|
i0.ɵɵconditional(ctx.relationshipsSectionExpanded ? 28 : -1);
|
|
673
|
-
} }, dependencies: [i1.MJAccordionPanelComponent, i1.MJAccordionTitleDirective, i1.MJAccordionActionsDirective], styles: ["\n\n\n\n\n\n.details-panel[_ngcontent-%COMP%] {\n height: 100%;\n background: var(--mj-bg-page);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n min-height: 0; \n\n}\n\n.details-panel[_ngcontent-%COMP%] .panel-header[_ngcontent-%COMP%] {\n flex-shrink: 0;\n}\n\n.details-panel[_ngcontent-%COMP%] .entity-info[_ngcontent-%COMP%] {\n flex-shrink: 0;\n}\n\n\n\n\n\n\n\n.panel-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.panel-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.panel-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n\n\n.open-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 6px 12px;\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n border: none;\n border-radius: 20px;\n font-size: 11px;\n cursor: pointer;\n transition: all 0.2s ease;\n box-shadow: var(--mj-shadow-sm);\n}\n\n.open-btn[_ngcontent-%COMP%]:hover {\n box-shadow: var(--mj-shadow-md);\n}\n\n\n\n.close-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n padding: 0;\n background: transparent;\n color: var(--mj-text-secondary);\n border: none;\n border-radius: 50%;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.close-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-active);\n color: var(--mj-text-primary);\n}\n\n\n\n.entity-info[_ngcontent-%COMP%] {\n padding: 16px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.info-row[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n margin-bottom: 8px;\n font-size: 12px;\n}\n\n.info-row[_ngcontent-%COMP%]:last-child {\n margin-bottom: 0;\n}\n\n.info-row[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--mj-text-secondary);\n min-width: 60px;\n}\n\n.info-row[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n flex: 1;\n text-align: right;\n}\n\n\n\n.status-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n border-radius: 8px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.status-badge.status-active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface-card));\n color: var(--mj-status-success);\n}\n\n.status-badge.status-deprecated[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface-card));\n color: var(--mj-status-warning);\n}\n\n.status-badge.status-disabled[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface-card));\n color: var(--mj-status-error);\n}\n\n.extra-padding[_ngcontent-%COMP%] {\n padding: 4px;\n}\n\n\n\n\n\n\n\n.erd-section-title[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n\n\n.field-filters[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n}\n\n.filter-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 4px 10px;\n font-size: 11px;\n background: var(--mj-bg-page);\n color: var(--mj-text-secondary);\n border: 1px solid var(--mj-border-default);\n border-radius: 16px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.filter-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.filter-btn.active[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n\n\n.fields-list[_ngcontent-%COMP%], \n.related-entities-list[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 8px;\n overflow-y: auto;\n padding: 6px 16px 16px 16px;\n min-height: 0;\n}\n\n.fields-list[_ngcontent-%COMP%]::-webkit-scrollbar, \n.related-entities-list[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 6px;\n}\n\n.fields-list[_ngcontent-%COMP%]::-webkit-scrollbar-track, \n.related-entities-list[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background: var(--mj-bg-surface-sunken);\n border-radius: 3px;\n}\n\n.fields-list[_ngcontent-%COMP%]::-webkit-scrollbar-thumb, \n.related-entities-list[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background: var(--mj-text-disabled);\n border-radius: 3px;\n}\n\n.fields-list[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover, \n.related-entities-list[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-secondary);\n}\n\n\n\n.field-item[_ngcontent-%COMP%] {\n padding: 10px;\n background: var(--mj-bg-page);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n font-size: 12px;\n cursor: pointer;\n user-select: none;\n transition: all 0.2s ease;\n}\n\n.field-item[_ngcontent-%COMP%]:hover {\n transform: translateY(-1px);\n box-shadow: var(--mj-shadow-md);\n}\n\n.field-item.field-expanded[_ngcontent-%COMP%] {\n box-shadow: var(--mj-shadow-lg);\n transform: scale(1.01);\n}\n\n\n\n.field-item.primary-key-field[_ngcontent-%COMP%] {\n border-color: var(--mj-status-success);\n background: color-mix(in srgb, var(--mj-status-success) 12%, var(--mj-bg-surface-card));\n border-left: 4px solid var(--mj-status-success);\n}\n\n.field-item.primary-key-field.field-expanded[_ngcontent-%COMP%] {\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-status-success) 20%, transparent);\n}\n\n\n\n.field-item.foreign-key-field[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface-card));\n border-left: 4px solid var(--mj-brand-primary);\n}\n\n.field-item.foreign-key-field.field-expanded[_ngcontent-%COMP%] {\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n}\n\n\n\n.field-item.regular-field[_ngcontent-%COMP%] {\n border-color: var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n}\n\n.field-item.regular-field.field-expanded[_ngcontent-%COMP%] {\n box-shadow: var(--mj-shadow-md);\n}\n\n.field-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 4px;\n}\n\n.field-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.field-name[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.field-icon[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n.field-icon.fa-key[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n}\n\n.field-icon.fa-link[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n\n\n.field-badges[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n}\n\n.field-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 1px 6px;\n border-radius: 4px;\n font-size: 9px;\n font-weight: 700;\n text-transform: uppercase;\n}\n\n.field-badge.primary-key[_ngcontent-%COMP%] {\n background: var(--mj-status-success);\n color: var(--mj-brand-on-primary);\n}\n\n.field-badge.foreign-key[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n.field-type[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n font-size: 11px;\n}\n\n.field-relation[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 11px;\n margin-top: 4px;\n}\n\n.field-relation[_ngcontent-%COMP%] .fa-solid[_ngcontent-%COMP%] {\n margin-right: 4px;\n}\n\n\n\n.field-info-btn[_ngcontent-%COMP%], \n.field-values-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n padding: 0;\n background: transparent;\n color: var(--mj-text-secondary);\n border: none;\n border-radius: 50%;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.field-info-btn[_ngcontent-%COMP%]:hover, \n.field-values-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface-card));\n color: var(--mj-brand-primary);\n}\n\n.field-info-btn.expanded[_ngcontent-%COMP%], \n.field-values-btn.expanded[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface-card));\n color: var(--mj-brand-primary);\n}\n\n.field-info-btn[_ngcontent-%COMP%] .fa-solid[_ngcontent-%COMP%], \n.field-values-btn[_ngcontent-%COMP%] .fa-solid[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n\n\n.field-description[_ngcontent-%COMP%] {\n margin-top: 8px;\n padding: 8px;\n background: var(--mj-bg-surface-sunken);\n border-left: 3px solid var(--mj-brand-primary);\n border-radius: 0 8px 8px 0;\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-in-out;\n}\n\n.field-description[_ngcontent-%COMP%] .description-text[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-secondary);\n line-height: 1.4;\n font-style: italic;\n}\n\n.field-details[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from {\n opacity: 0;\n transform: translateY(-5px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n\n\n.field-values[_ngcontent-%COMP%] {\n margin-top: 8px;\n padding: 8px;\n background: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface-card));\n border-left: 3px solid var(--mj-status-warning);\n border-radius: 0 8px 8px 0;\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-in-out;\n}\n\n.field-values[_ngcontent-%COMP%] .values-header[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-primary);\n font-weight: 600;\n margin-bottom: 6px;\n}\n\n.field-values[_ngcontent-%COMP%] .values-list[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n}\n\n.field-values[_ngcontent-%COMP%] .value-tag[_ngcontent-%COMP%] {\n display: inline-block;\n padding: 2px 8px;\n background: var(--mj-bg-page);\n color: var(--mj-text-primary);\n font-size: 9px;\n border-radius: 12px;\n font-weight: 500;\n white-space: nowrap;\n max-width: 80px;\n overflow: hidden;\n text-overflow: ellipsis;\n border: 1px solid var(--mj-border-default);\n}\n\n.field-values[_ngcontent-%COMP%] .value-tag[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-active);\n cursor: default;\n}\n\n\n\n.field-comprehensive-details[_ngcontent-%COMP%] {\n margin-top: 12px;\n padding: 12px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n animation: _ngcontent-%COMP%_slideDown 0.3s ease-out;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .details-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin-bottom: 10px;\n padding-bottom: 6px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .details-header[_ngcontent-%COMP%] .fa-solid[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .details-grid[_ngcontent-%COMP%] {\n display: grid;\n gap: 6px;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-row[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 100px 1fr;\n gap: 8px;\n font-size: 12px;\n align-items: center;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-label[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-align: right;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n font-family: \"Courier New\", monospace;\n background: var(--mj-bg-page);\n padding: 2px 6px;\n border-radius: 4px;\n border: 1px solid var(--mj-border-default);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value.nullable-yes[_ngcontent-%COMP%], \n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value.nullable-no[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n background: var(--mj-bg-page);\n border-color: var(--mj-border-default);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value.virtual-yes[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n background: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface-card));\n border-color: var(--mj-status-warning);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value.virtual-no[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value.default-value[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface-card));\n border-color: var(--mj-status-success);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value.related-entity[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface-card));\n border-color: var(--mj-brand-primary);\n cursor: pointer;\n user-select: none;\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value.related-entity[_ngcontent-%COMP%]:hover {\n text-decoration: underline;\n background: color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-bg-surface-card));\n transform: translateX(2px);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value.related-entity[_ngcontent-%COMP%] .fa-external-link-alt[_ngcontent-%COMP%] {\n font-size: 8px;\n opacity: 0.7;\n transition: opacity 0.2s ease;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value.related-entity[_ngcontent-%COMP%]:hover .fa-external-link-alt[_ngcontent-%COMP%] {\n opacity: 1;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value.auto-increment[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface-card));\n border-color: var(--mj-status-success);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .comprehensive-description-top[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n padding-bottom: 10px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .comprehensive-description-top[_ngcontent-%COMP%] .description-content[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-primary);\n line-height: 1.4;\n font-style: italic;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface-card));\n padding: 10px;\n border-radius: 8px;\n border: 1px solid var(--mj-brand-primary);\n border-left: 4px solid var(--mj-brand-primary);\n}\n\n\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n padding: 12px;\n background: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface-card));\n border: 1px solid var(--mj-status-warning);\n border-radius: 8px;\n border-left: 4px solid var(--mj-status-warning);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .values-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin-bottom: 10px;\n padding-bottom: 6px;\n border-bottom: 1px solid color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .values-header[_ngcontent-%COMP%] .fa-solid[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .values-grid[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n max-height: 200px;\n overflow-y: auto;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .values-grid[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 4px;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .values-grid[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface-card));\n border-radius: 2px;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .values-grid[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background: var(--mj-status-warning);\n border-radius: 2px;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .values-grid[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-primary);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .value-item[_ngcontent-%COMP%] {\n padding: 8px;\n background: var(--mj-bg-page);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .value-item[_ngcontent-%COMP%] .value-main[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-bottom: 2px;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .value-item[_ngcontent-%COMP%] .value-main[_ngcontent-%COMP%] .value-text[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .value-item[_ngcontent-%COMP%] .value-main[_ngcontent-%COMP%] .value-code[_ngcontent-%COMP%] {\n font-size: 9px;\n color: var(--mj-text-primary);\n background: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface-card));\n padding: 1px 4px;\n border-radius: 4px;\n border: 1px solid var(--mj-status-warning);\n font-family: \"Courier New\", monospace;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .value-item[_ngcontent-%COMP%] .value-description[_ngcontent-%COMP%] {\n font-size: 9px;\n color: var(--mj-text-secondary);\n line-height: 1.3;\n font-style: italic;\n margin-top: 2px;\n}\n\n@keyframes _ngcontent-%COMP%_slideDown {\n from {\n opacity: 0;\n transform: translateY(-10px);\n max-height: 0;\n }\n to {\n opacity: 1;\n transform: translateY(0);\n max-height: 500px;\n }\n}\n\n\n\n.related-entity-item[_ngcontent-%COMP%] {\n padding: 12px 14px;\n background: var(--mj-bg-page);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n cursor: pointer;\n font-size: 14px;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n justify-content: space-between;\n transition: all 0.3s ease;\n position: relative;\n max-width: calc(100% - 4px);\n min-width: 0;\n flex-shrink: 1;\n}\n\n.related-entity-item[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface-card));\n border-color: var(--mj-brand-primary);\n transform: translateX(4px);\n box-shadow: var(--mj-shadow-md);\n}\n\n.related-entity-item[_ngcontent-%COMP%]:hover .zoom-indicator[_ngcontent-%COMP%] {\n opacity: 1;\n transform: scale(1.1);\n}\n\n.related-entity-item[_ngcontent-%COMP%]:hover .fa-database[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n transform: scale(1.1);\n}\n\n.related-entity-item[_ngcontent-%COMP%]:hover::before {\n content: \"\";\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 3px;\n background: linear-gradient(to bottom, var(--mj-brand-primary), var(--mj-status-warning));\n border-radius: 0 3px 3px 0;\n}\n\n.related-entity-item[_ngcontent-%COMP%] .fa-solid[_ngcontent-%COMP%] {\n margin-right: 10px;\n color: var(--mj-text-secondary);\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n\n.related-entity-item[_ngcontent-%COMP%] .fa-database[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.related-entity-item[_ngcontent-%COMP%] .entity-name[_ngcontent-%COMP%] {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n min-width: 0;\n}\n\n.related-entity-item[_ngcontent-%COMP%] .zoom-indicator[_ngcontent-%COMP%] {\n opacity: 0.4;\n color: var(--mj-brand-primary);\n font-size: 11px;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}"] });
|
|
673
|
+
} }, dependencies: [i1.MJAccordionPanelComponent, i1.MJAccordionTitleDirective, i1.MJAccordionActionsDirective], styles: ["\n\n\n\n\n.details-panel[_ngcontent-%COMP%] {\n height: 100%;\n background: var(--mj-bg-page);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n min-height: 0; \n}\n\n.details-panel[_ngcontent-%COMP%] .panel-header[_ngcontent-%COMP%] {\n flex-shrink: 0;\n}\n\n.details-panel[_ngcontent-%COMP%] .entity-info[_ngcontent-%COMP%] {\n flex-shrink: 0;\n}\n\n\n\n\n\n.panel-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.panel-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.panel-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n\n.open-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 6px 12px;\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n border: none;\n border-radius: 20px;\n font-size: 11px;\n cursor: pointer;\n transition: all 0.2s ease;\n box-shadow: var(--mj-shadow-sm);\n}\n\n.open-btn[_ngcontent-%COMP%]:hover {\n box-shadow: var(--mj-shadow-md);\n}\n\n\n.close-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n padding: 0;\n background: transparent;\n color: var(--mj-text-secondary);\n border: none;\n border-radius: 50%;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.close-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-active);\n color: var(--mj-text-primary);\n}\n\n\n.entity-info[_ngcontent-%COMP%] {\n padding: 16px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.info-row[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n margin-bottom: 8px;\n font-size: 12px;\n}\n\n.info-row[_ngcontent-%COMP%]:last-child {\n margin-bottom: 0;\n}\n\n.info-row[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--mj-text-secondary);\n min-width: 60px;\n}\n\n.info-row[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n flex: 1;\n text-align: right;\n}\n\n\n.status-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n border-radius: 8px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.status-badge.status-active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface-card));\n color: var(--mj-status-success);\n}\n\n.status-badge.status-deprecated[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface-card));\n color: var(--mj-status-warning);\n}\n\n.status-badge.status-disabled[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface-card));\n color: var(--mj-status-error);\n}\n\n.extra-padding[_ngcontent-%COMP%] {\n padding: 4px;\n}\n\n\n\n\n\n.erd-section-title[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n\n.field-filters[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n}\n\n.filter-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 4px 10px;\n font-size: 11px;\n background: var(--mj-bg-page);\n color: var(--mj-text-secondary);\n border: 1px solid var(--mj-border-default);\n border-radius: 16px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.filter-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.filter-btn.active[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n\n.fields-list[_ngcontent-%COMP%], \n.related-entities-list[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 8px;\n overflow-y: auto;\n padding: 6px 16px 16px 16px;\n min-height: 0;\n}\n\n.fields-list[_ngcontent-%COMP%]::-webkit-scrollbar, \n.related-entities-list[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 6px;\n}\n\n.fields-list[_ngcontent-%COMP%]::-webkit-scrollbar-track, \n.related-entities-list[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background: var(--mj-bg-surface-sunken);\n border-radius: 3px;\n}\n\n.fields-list[_ngcontent-%COMP%]::-webkit-scrollbar-thumb, \n.related-entities-list[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background: var(--mj-text-disabled);\n border-radius: 3px;\n}\n\n.fields-list[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover, \n.related-entities-list[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-secondary);\n}\n\n\n.field-item[_ngcontent-%COMP%] {\n padding: 10px;\n background: var(--mj-bg-page);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n font-size: 12px;\n cursor: pointer;\n user-select: none;\n transition: all 0.2s ease;\n}\n\n.field-item[_ngcontent-%COMP%]:hover {\n transform: translateY(-1px);\n box-shadow: var(--mj-shadow-md);\n}\n\n.field-item.field-expanded[_ngcontent-%COMP%] {\n box-shadow: var(--mj-shadow-lg);\n transform: scale(1.01);\n}\n\n\n.field-item.primary-key-field[_ngcontent-%COMP%] {\n border-color: var(--mj-status-success);\n background: color-mix(in srgb, var(--mj-status-success) 12%, var(--mj-bg-surface-card));\n border-left: 4px solid var(--mj-status-success);\n}\n\n.field-item.primary-key-field.field-expanded[_ngcontent-%COMP%] {\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-status-success) 20%, transparent);\n}\n\n\n.field-item.foreign-key-field[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface-card));\n border-left: 4px solid var(--mj-brand-primary);\n}\n\n.field-item.foreign-key-field.field-expanded[_ngcontent-%COMP%] {\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n}\n\n\n.field-item.regular-field[_ngcontent-%COMP%] {\n border-color: var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n}\n\n.field-item.regular-field.field-expanded[_ngcontent-%COMP%] {\n box-shadow: var(--mj-shadow-md);\n}\n\n.field-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 4px;\n}\n\n.field-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.field-name[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.field-icon[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n.field-icon.fa-key[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n}\n\n.field-icon.fa-link[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n\n.field-badges[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n}\n\n.field-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 1px 6px;\n border-radius: 4px;\n font-size: 9px;\n font-weight: 700;\n text-transform: uppercase;\n}\n\n.field-badge.primary-key[_ngcontent-%COMP%] {\n background: var(--mj-status-success);\n color: var(--mj-brand-on-primary);\n}\n\n.field-badge.foreign-key[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n.field-type[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n font-size: 11px;\n}\n\n.field-relation[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 11px;\n margin-top: 4px;\n}\n\n.field-relation[_ngcontent-%COMP%] .fa-solid[_ngcontent-%COMP%] {\n margin-right: 4px;\n}\n\n\n.field-info-btn[_ngcontent-%COMP%], \n.field-values-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n padding: 0;\n background: transparent;\n color: var(--mj-text-secondary);\n border: none;\n border-radius: 50%;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.field-info-btn[_ngcontent-%COMP%]:hover, \n.field-values-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface-card));\n color: var(--mj-brand-primary);\n}\n\n.field-info-btn.expanded[_ngcontent-%COMP%], \n.field-values-btn.expanded[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface-card));\n color: var(--mj-brand-primary);\n}\n\n.field-info-btn[_ngcontent-%COMP%] .fa-solid[_ngcontent-%COMP%], \n.field-values-btn[_ngcontent-%COMP%] .fa-solid[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n\n.field-description[_ngcontent-%COMP%] {\n margin-top: 8px;\n padding: 8px;\n background: var(--mj-bg-surface-sunken);\n border-left: 3px solid var(--mj-brand-primary);\n border-radius: 0 8px 8px 0;\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-in-out;\n}\n\n.field-description[_ngcontent-%COMP%] .description-text[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-secondary);\n line-height: 1.4;\n font-style: italic;\n}\n\n.field-details[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from {\n opacity: 0;\n transform: translateY(-5px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n\n.field-values[_ngcontent-%COMP%] {\n margin-top: 8px;\n padding: 8px;\n background: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface-card));\n border-left: 3px solid var(--mj-status-warning);\n border-radius: 0 8px 8px 0;\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-in-out;\n}\n\n.field-values[_ngcontent-%COMP%] .values-header[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-primary);\n font-weight: 600;\n margin-bottom: 6px;\n}\n\n.field-values[_ngcontent-%COMP%] .values-list[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n}\n\n.field-values[_ngcontent-%COMP%] .value-tag[_ngcontent-%COMP%] {\n display: inline-block;\n padding: 2px 8px;\n background: var(--mj-bg-page);\n color: var(--mj-text-primary);\n font-size: 9px;\n border-radius: 12px;\n font-weight: 500;\n white-space: nowrap;\n max-width: 80px;\n overflow: hidden;\n text-overflow: ellipsis;\n border: 1px solid var(--mj-border-default);\n}\n\n.field-values[_ngcontent-%COMP%] .value-tag[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-active);\n cursor: default;\n}\n\n\n.field-comprehensive-details[_ngcontent-%COMP%] {\n margin-top: 12px;\n padding: 12px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n animation: _ngcontent-%COMP%_slideDown 0.3s ease-out;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .details-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin-bottom: 10px;\n padding-bottom: 6px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .details-header[_ngcontent-%COMP%] .fa-solid[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .details-grid[_ngcontent-%COMP%] {\n display: grid;\n gap: 6px;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-row[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 100px 1fr;\n gap: 8px;\n font-size: 12px;\n align-items: center;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-label[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-align: right;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n font-family: \"Courier New\", monospace;\n background: var(--mj-bg-page);\n padding: 2px 6px;\n border-radius: 4px;\n border: 1px solid var(--mj-border-default);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value.nullable-yes[_ngcontent-%COMP%], \n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value.nullable-no[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n background: var(--mj-bg-page);\n border-color: var(--mj-border-default);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value.virtual-yes[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n background: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface-card));\n border-color: var(--mj-status-warning);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value.virtual-no[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value.default-value[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface-card));\n border-color: var(--mj-status-success);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value.related-entity[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface-card));\n border-color: var(--mj-brand-primary);\n cursor: pointer;\n user-select: none;\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value.related-entity[_ngcontent-%COMP%]:hover {\n text-decoration: underline;\n background: color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-bg-surface-card));\n transform: translateX(2px);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value.related-entity[_ngcontent-%COMP%] .fa-external-link-alt[_ngcontent-%COMP%] {\n font-size: 8px;\n opacity: 0.7;\n transition: opacity 0.2s ease;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value.related-entity[_ngcontent-%COMP%]:hover .fa-external-link-alt[_ngcontent-%COMP%] {\n opacity: 1;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value.auto-increment[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface-card));\n border-color: var(--mj-status-success);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .comprehensive-description-top[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n padding-bottom: 10px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .comprehensive-description-top[_ngcontent-%COMP%] .description-content[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-primary);\n line-height: 1.4;\n font-style: italic;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface-card));\n padding: 10px;\n border-radius: 8px;\n border: 1px solid var(--mj-brand-primary);\n border-left: 4px solid var(--mj-brand-primary);\n}\n\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n padding: 12px;\n background: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface-card));\n border: 1px solid var(--mj-status-warning);\n border-radius: 8px;\n border-left: 4px solid var(--mj-status-warning);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .values-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin-bottom: 10px;\n padding-bottom: 6px;\n border-bottom: 1px solid color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .values-header[_ngcontent-%COMP%] .fa-solid[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .values-grid[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n max-height: 200px;\n overflow-y: auto;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .values-grid[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 4px;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .values-grid[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface-card));\n border-radius: 2px;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .values-grid[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background: var(--mj-status-warning);\n border-radius: 2px;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .values-grid[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-primary);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .value-item[_ngcontent-%COMP%] {\n padding: 8px;\n background: var(--mj-bg-page);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .value-item[_ngcontent-%COMP%] .value-main[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-bottom: 2px;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .value-item[_ngcontent-%COMP%] .value-main[_ngcontent-%COMP%] .value-text[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .value-item[_ngcontent-%COMP%] .value-main[_ngcontent-%COMP%] .value-code[_ngcontent-%COMP%] {\n font-size: 9px;\n color: var(--mj-text-primary);\n background: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface-card));\n padding: 1px 4px;\n border-radius: 4px;\n border: 1px solid var(--mj-status-warning);\n font-family: \"Courier New\", monospace;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .value-item[_ngcontent-%COMP%] .value-description[_ngcontent-%COMP%] {\n font-size: 9px;\n color: var(--mj-text-secondary);\n line-height: 1.3;\n font-style: italic;\n margin-top: 2px;\n}\n\n@keyframes _ngcontent-%COMP%_slideDown {\n from {\n opacity: 0;\n transform: translateY(-10px);\n max-height: 0;\n }\n to {\n opacity: 1;\n transform: translateY(0);\n max-height: 500px;\n }\n}\n\n\n.related-entity-item[_ngcontent-%COMP%] {\n padding: 12px 14px;\n background: var(--mj-bg-page);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n cursor: pointer;\n font-size: 14px;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n justify-content: space-between;\n transition: all 0.3s ease;\n position: relative;\n max-width: calc(100% - 4px);\n min-width: 0;\n flex-shrink: 1;\n}\n\n.related-entity-item[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface-card));\n border-color: var(--mj-brand-primary);\n transform: translateX(4px);\n box-shadow: var(--mj-shadow-md);\n}\n\n.related-entity-item[_ngcontent-%COMP%]:hover .zoom-indicator[_ngcontent-%COMP%] {\n opacity: 1;\n transform: scale(1.1);\n}\n\n.related-entity-item[_ngcontent-%COMP%]:hover .fa-database[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n transform: scale(1.1);\n}\n\n.related-entity-item[_ngcontent-%COMP%]:hover::before {\n content: \"\";\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 3px;\n background: linear-gradient(to bottom, var(--mj-brand-primary), var(--mj-status-warning));\n border-radius: 0 3px 3px 0;\n}\n\n.related-entity-item[_ngcontent-%COMP%] .fa-solid[_ngcontent-%COMP%] {\n margin-right: 10px;\n color: var(--mj-text-secondary);\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n\n.related-entity-item[_ngcontent-%COMP%] .fa-database[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.related-entity-item[_ngcontent-%COMP%] .entity-name[_ngcontent-%COMP%] {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n min-width: 0;\n}\n\n.related-entity-item[_ngcontent-%COMP%] .zoom-indicator[_ngcontent-%COMP%] {\n opacity: 0.4;\n color: var(--mj-brand-primary);\n font-size: 11px;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}"] });
|
|
674
674
|
}
|
|
675
675
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(EntityDetailsComponent, [{
|
|
676
676
|
type: Component,
|
|
@@ -142,7 +142,7 @@ export class EntityFilterPanelComponent {
|
|
|
142
142
|
i0.ɵɵtwoWayProperty("ngModel", ctx.filters.baseTable);
|
|
143
143
|
i0.ɵɵadvance(5);
|
|
144
144
|
i0.ɵɵproperty("Data", ctx.statusOptions)("ValuePrimitive", true)("ngModel", ctx.filters.entityStatus);
|
|
145
|
-
} }, dependencies: [i1.DefaultValueAccessor, i1.NgControlStatus, i1.NgModel, i2.MJButtonDirective, i2.MJDropdownComponent], styles: ["\n\n\n\n\n\n
|
|
145
|
+
} }, dependencies: [i1.DefaultValueAccessor, i1.NgControlStatus, i1.NgModel, i2.MJButtonDirective, i2.MJDropdownComponent], styles: ["\n\n\n\n\n\n.filter-panel[_ngcontent-%COMP%] {\n height: 100%;\n background: var(--mj-bg-page);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n min-width: 0;\n}\n\n.filter-panel-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n min-width: 0;\n}\n\n.filter-panel-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n flex: 1;\n min-width: 0;\n}\n\n.filter-summary-inline[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n margin-right: 8px;\n}\n\n.filter-summary-inline[_ngcontent-%COMP%] .summary-value[_ngcontent-%COMP%] {\n font-size: 16px;\n font-weight: 700;\n color: var(--mj-brand-primary);\n}\n\n.filter-summary-inline[_ngcontent-%COMP%] .summary-label[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n.filter-content[_ngcontent-%COMP%] {\n padding: 16px;\n overflow-y: auto;\n overflow-x: hidden;\n flex: 1;\n}\n\n.filter-group[_ngcontent-%COMP%] {\n margin-bottom: 20px;\n}\n\n.filter-label[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 8px;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.filter-label[_ngcontent-%COMP%] .fa-solid[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n width: 16px;\n text-align: center;\n}\n\n\n.filter-dropdown[_ngcontent-%COMP%] {\n display: block;\n width: 100%;\n}\n\n.filter-input[_ngcontent-%COMP%] {\n width: 100%;\n}\n\n.filter-actions[_ngcontent-%COMP%] {\n margin-top: 24px;\n padding-top: 16px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.reset-btn[_ngcontent-%COMP%] {\n width: 100%;\n}"] });
|
|
146
146
|
}
|
|
147
147
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(EntityFilterPanelComponent, [{
|
|
148
148
|
type: Component,
|
|
@@ -390,7 +390,7 @@ export class ERDCompositeComponent extends BaseAngularComponent {
|
|
|
390
390
|
i0.ɵɵproperty("entities", ctx.filteredEntities)("allEntities", ctx.entities)("selectedEntityId", (ctx.selectedEntity == null ? null : ctx.selectedEntity.ID) || null)("focusEntityId", (ctx.selectedEntity == null ? null : ctx.selectedEntity.ID) || null)("isRefreshing", ctx.isRefreshingERD)("depth", ctx.depth)("includeIncoming", true)("includeOutgoing", true)("showHeader", ctx.showHeader)("config", ctx.erdConfig);
|
|
391
391
|
i0.ɵɵadvance();
|
|
392
392
|
i0.ɵɵconditional(ctx.selectedEntity ? 6 : -1);
|
|
393
|
-
} }, dependencies: [i1.SplitComponent, i1.SplitAreaComponent, i2.MJEntityERDComponent, i3.EntityDetailsComponent, i4.EntityFilterPanelComponent], styles: ["\n\n\n\n\n
|
|
393
|
+
} }, dependencies: [i1.SplitComponent, i1.SplitAreaComponent, i2.MJEntityERDComponent, i3.EntityDetailsComponent, i4.EntityFilterPanelComponent], styles: ["\n\n\n\n\n[_nghost-%COMP%] {\n display: block;\n height: 100%;\n width: 100%;\n}\n\n.erd-composite[_ngcontent-%COMP%] {\n overflow: hidden;\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n}\n\n.main-splitter[_ngcontent-%COMP%] {\n height: 100%;\n width: 100%;\n}\n\n.main-splitter[_ngcontent-%COMP%] .k-pane[_ngcontent-%COMP%] {\n overflow: hidden;\n}\n\n.erd-pane-container[_ngcontent-%COMP%] {\n position: relative;\n width: 100%;\n height: 100%;\n overflow: hidden;\n}\n\n\n.floating-details-panel[_ngcontent-%COMP%] {\n position: absolute;\n top: 50%;\n right: 20px;\n width: 380px;\n max-height: calc(100% - 40px);\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 28px;\n box-shadow: var(--mj-shadow-lg);\n z-index: 1000;\n overflow: hidden;\n transform: translateY(-50%);\n animation: _ngcontent-%COMP%_slideInFromRight 0.3s ease-out;\n}\n\n@media (max-width: 768px) {\n .floating-details-panel[_ngcontent-%COMP%] {\n right: 10px;\n left: 10px;\n width: auto;\n max-width: none;\n border-radius: 20px;\n }\n}\n\n@media (max-height: 600px) {\n .floating-details-panel[_ngcontent-%COMP%] {\n top: 20px;\n transform: none;\n max-height: calc(100vh - 40px);\n }\n}\n\n@keyframes _ngcontent-%COMP%_slideInFromRight {\n from {\n transform: translateY(-50%) translateX(100%);\n opacity: 0;\n }\n to {\n transform: translateY(-50%) translateX(0);\n opacity: 1;\n }\n}\n\n\n.explorer-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n overflow: hidden;\n}\n\n.explorer-header-bar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 8px 16px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n\n.back-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n background: var(--mj-bg-page);\n border: 1px solid var(--mj-border-default);\n border-radius: 20px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.back-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-color-neutral-400);\n color: var(--mj-text-primary);\n}\n\n.back-btn[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n.back-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n.explorer-container[_ngcontent-%COMP%] mj-entity-explorer[_ngcontent-%COMP%] {\n flex: 1;\n overflow: hidden;\n}"] });
|
|
394
394
|
}
|
|
395
395
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ERDCompositeComponent, [{
|
|
396
396
|
type: Component,
|
|
@@ -21,16 +21,16 @@ import * as i0 from "@angular/core";
|
|
|
21
21
|
import * as i1 from "@memberjunction/ng-ui-components";
|
|
22
22
|
const _c0 = ["canvasRef"];
|
|
23
23
|
function ERDDiagramComponent_Conditional_0_Conditional_16_Template(rf, ctx) { if (rf & 1) {
|
|
24
|
-
const
|
|
24
|
+
const _r3 = i0.ɵɵgetCurrentView();
|
|
25
25
|
i0.ɵɵelementStart(0, "button", 44);
|
|
26
|
-
i0.ɵɵlistener("click", function ERDDiagramComponent_Conditional_0_Conditional_16_Template_button_click_0_listener() { i0.ɵɵrestoreView(
|
|
26
|
+
i0.ɵɵlistener("click", function ERDDiagramComponent_Conditional_0_Conditional_16_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onClearSearch()); });
|
|
27
27
|
i0.ɵɵtext(1, "\u00D7");
|
|
28
28
|
i0.ɵɵelementEnd();
|
|
29
29
|
} }
|
|
30
30
|
function ERDDiagramComponent_Conditional_0_Conditional_18_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
31
|
-
const
|
|
31
|
+
const _r4 = i0.ɵɵgetCurrentView();
|
|
32
32
|
i0.ɵɵelementStart(0, "button", 46);
|
|
33
|
-
i0.ɵɵlistener("click", function ERDDiagramComponent_Conditional_0_Conditional_18_For_2_Template_button_click_0_listener() { const
|
|
33
|
+
i0.ɵɵlistener("click", function ERDDiagramComponent_Conditional_0_Conditional_18_For_2_Template_button_click_0_listener() { const chip_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.onSchemaChipToggle(chip_r5.name)); });
|
|
34
34
|
i0.ɵɵelementStart(1, "span", 47);
|
|
35
35
|
i0.ɵɵtext(2);
|
|
36
36
|
i0.ɵɵelementEnd();
|
|
@@ -38,25 +38,25 @@ function ERDDiagramComponent_Conditional_0_Conditional_18_For_2_Template(rf, ctx
|
|
|
38
38
|
i0.ɵɵtext(4);
|
|
39
39
|
i0.ɵɵelementEnd()();
|
|
40
40
|
} if (rf & 2) {
|
|
41
|
-
const
|
|
42
|
-
i0.ɵɵclassProp("active",
|
|
43
|
-
i0.ɵɵattribute("aria-pressed",
|
|
41
|
+
const chip_r5 = ctx.$implicit;
|
|
42
|
+
i0.ɵɵclassProp("active", chip_r5.active);
|
|
43
|
+
i0.ɵɵattribute("aria-pressed", chip_r5.active);
|
|
44
44
|
i0.ɵɵadvance(2);
|
|
45
|
-
i0.ɵɵtextInterpolate(
|
|
45
|
+
i0.ɵɵtextInterpolate(chip_r5.name);
|
|
46
46
|
i0.ɵɵadvance(2);
|
|
47
|
-
i0.ɵɵtextInterpolate(
|
|
47
|
+
i0.ɵɵtextInterpolate(chip_r5.count);
|
|
48
48
|
} }
|
|
49
49
|
function ERDDiagramComponent_Conditional_0_Conditional_18_Template(rf, ctx) { if (rf & 1) {
|
|
50
50
|
i0.ɵɵelementStart(0, "div", 30);
|
|
51
51
|
i0.ɵɵrepeaterCreate(1, ERDDiagramComponent_Conditional_0_Conditional_18_For_2_Template, 5, 5, "button", 45, i0.ɵɵcomponentInstance().trackByChip, true);
|
|
52
52
|
i0.ɵɵelementEnd();
|
|
53
53
|
} if (rf & 2) {
|
|
54
|
-
const
|
|
54
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
55
55
|
i0.ɵɵadvance();
|
|
56
|
-
i0.ɵɵrepeater(
|
|
56
|
+
i0.ɵɵrepeater(ctx_r1.schemaChips);
|
|
57
57
|
} }
|
|
58
58
|
function ERDDiagramComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
59
|
-
const
|
|
59
|
+
const _r1 = i0.ɵɵgetCurrentView();
|
|
60
60
|
i0.ɵɵelementStart(0, "header", 1)(1, "div", 19)(2, "div", 20);
|
|
61
61
|
i0.ɵɵtext(3);
|
|
62
62
|
i0.ɵɵelementEnd();
|
|
@@ -75,57 +75,57 @@ function ERDDiagramComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
|
75
75
|
i0.ɵɵelementStart(13, "label", 25);
|
|
76
76
|
i0.ɵɵelement(14, "i", 26);
|
|
77
77
|
i0.ɵɵelementStart(15, "input", 27);
|
|
78
|
-
i0.ɵɵlistener("input", function ERDDiagramComponent_Conditional_0_Template_input_input_15_listener($event) { i0.ɵɵrestoreView(
|
|
78
|
+
i0.ɵɵlistener("input", function ERDDiagramComponent_Conditional_0_Template_input_input_15_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onSearchChange($event.target.value)); });
|
|
79
79
|
i0.ɵɵelementEnd();
|
|
80
80
|
i0.ɵɵconditionalCreate(16, ERDDiagramComponent_Conditional_0_Conditional_16_Template, 2, 0, "button", 28);
|
|
81
81
|
i0.ɵɵelementEnd();
|
|
82
82
|
i0.ɵɵelementStart(17, "div", 29);
|
|
83
83
|
i0.ɵɵconditionalCreate(18, ERDDiagramComponent_Conditional_0_Conditional_18_Template, 3, 0, "div", 30);
|
|
84
84
|
i0.ɵɵelementStart(19, "div", 31)(20, "button", 32);
|
|
85
|
-
i0.ɵɵlistener("click", function ERDDiagramComponent_Conditional_0_Template_button_click_20_listener() { i0.ɵɵrestoreView(
|
|
85
|
+
i0.ɵɵlistener("click", function ERDDiagramComponent_Conditional_0_Template_button_click_20_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.setLayoutAlgorithm("schema-grid")); });
|
|
86
86
|
i0.ɵɵelement(21, "i", 33);
|
|
87
87
|
i0.ɵɵelementEnd();
|
|
88
88
|
i0.ɵɵelementStart(22, "button", 34);
|
|
89
|
-
i0.ɵɵlistener("click", function ERDDiagramComponent_Conditional_0_Template_button_click_22_listener() { i0.ɵɵrestoreView(
|
|
89
|
+
i0.ɵɵlistener("click", function ERDDiagramComponent_Conditional_0_Template_button_click_22_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.setLayoutAlgorithm("dagre")); });
|
|
90
90
|
i0.ɵɵelement(23, "i", 35);
|
|
91
91
|
i0.ɵɵelementEnd()();
|
|
92
92
|
i0.ɵɵelementStart(24, "div", 36)(25, "button", 37);
|
|
93
|
-
i0.ɵɵlistener("click", function ERDDiagramComponent_Conditional_0_Template_button_click_25_listener() { i0.ɵɵrestoreView(
|
|
93
|
+
i0.ɵɵlistener("click", function ERDDiagramComponent_Conditional_0_Template_button_click_25_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.zoomBy(1.2)); });
|
|
94
94
|
i0.ɵɵelement(26, "i", 38);
|
|
95
95
|
i0.ɵɵelementEnd();
|
|
96
96
|
i0.ɵɵelementStart(27, "button", 39);
|
|
97
|
-
i0.ɵɵlistener("click", function ERDDiagramComponent_Conditional_0_Template_button_click_27_listener() { i0.ɵɵrestoreView(
|
|
97
|
+
i0.ɵɵlistener("click", function ERDDiagramComponent_Conditional_0_Template_button_click_27_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.zoomBy(0.83)); });
|
|
98
98
|
i0.ɵɵelement(28, "i", 40);
|
|
99
99
|
i0.ɵɵelementEnd();
|
|
100
100
|
i0.ɵɵelementStart(29, "button", 41);
|
|
101
|
-
i0.ɵɵlistener("click", function ERDDiagramComponent_Conditional_0_Template_button_click_29_listener() { i0.ɵɵrestoreView(
|
|
101
|
+
i0.ɵɵlistener("click", function ERDDiagramComponent_Conditional_0_Template_button_click_29_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.fitToView()); });
|
|
102
102
|
i0.ɵɵelement(30, "i", 42);
|
|
103
103
|
i0.ɵɵelementEnd();
|
|
104
104
|
i0.ɵɵelementStart(31, "span", 43);
|
|
105
105
|
i0.ɵɵtext(32);
|
|
106
106
|
i0.ɵɵelementEnd()()()();
|
|
107
107
|
} if (rf & 2) {
|
|
108
|
-
const
|
|
108
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
109
109
|
i0.ɵɵadvance(3);
|
|
110
|
-
i0.ɵɵtextInterpolate(
|
|
110
|
+
i0.ɵɵtextInterpolate(ctx_r1.headerTitle);
|
|
111
111
|
i0.ɵɵadvance(3);
|
|
112
|
-
i0.ɵɵtextInterpolate(
|
|
112
|
+
i0.ɵɵtextInterpolate(ctx_r1.visibleCount);
|
|
113
113
|
i0.ɵɵadvance(2);
|
|
114
|
-
i0.ɵɵtextInterpolate1("of ",
|
|
114
|
+
i0.ɵɵtextInterpolate1("of ", ctx_r1.totalCount, " entities");
|
|
115
115
|
i0.ɵɵadvance(4);
|
|
116
|
-
i0.ɵɵtextInterpolate1("",
|
|
116
|
+
i0.ɵɵtextInterpolate1("", ctx_r1.layout.edges.length, " relationships");
|
|
117
117
|
i0.ɵɵadvance(3);
|
|
118
|
-
i0.ɵɵproperty("value",
|
|
118
|
+
i0.ɵɵproperty("value", ctx_r1.searchQuery);
|
|
119
119
|
i0.ɵɵadvance();
|
|
120
|
-
i0.ɵɵconditional(
|
|
120
|
+
i0.ɵɵconditional(ctx_r1.searchQuery ? 16 : -1);
|
|
121
121
|
i0.ɵɵadvance(2);
|
|
122
|
-
i0.ɵɵconditional(
|
|
122
|
+
i0.ɵɵconditional(ctx_r1.schemaChips.length > 1 ? 18 : -1);
|
|
123
123
|
i0.ɵɵadvance(2);
|
|
124
|
-
i0.ɵɵclassProp("active",
|
|
124
|
+
i0.ɵɵclassProp("active", ctx_r1.activeLayout === "schema-grid");
|
|
125
125
|
i0.ɵɵadvance(2);
|
|
126
|
-
i0.ɵɵclassProp("active",
|
|
126
|
+
i0.ɵɵclassProp("active", ctx_r1.activeLayout === "dagre");
|
|
127
127
|
i0.ɵɵadvance(10);
|
|
128
|
-
i0.ɵɵtextInterpolate(
|
|
128
|
+
i0.ɵɵtextInterpolate(ctx_r1.zoomPercent);
|
|
129
129
|
} }
|
|
130
130
|
function ERDDiagramComponent_Conditional_14_For_1_Template(rf, ctx) { if (rf & 1) {
|
|
131
131
|
i0.ɵɵnamespaceSVG();
|
|
@@ -135,28 +135,28 @@ function ERDDiagramComponent_Conditional_14_For_1_Template(rf, ctx) { if (rf & 1
|
|
|
135
135
|
i0.ɵɵtext(3);
|
|
136
136
|
i0.ɵɵelementEnd()();
|
|
137
137
|
} if (rf & 2) {
|
|
138
|
-
const
|
|
138
|
+
const band_r6 = ctx.$implicit;
|
|
139
139
|
i0.ɵɵadvance();
|
|
140
|
-
i0.ɵɵattribute("x",
|
|
140
|
+
i0.ɵɵattribute("x", band_r6.x)("y", band_r6.y)("width", band_r6.width)("height", band_r6.height);
|
|
141
141
|
i0.ɵɵadvance();
|
|
142
|
-
i0.ɵɵattribute("x",
|
|
142
|
+
i0.ɵɵattribute("x", band_r6.x + band_r6.width / 2)("y", band_r6.y + 32);
|
|
143
143
|
i0.ɵɵadvance();
|
|
144
|
-
i0.ɵɵtextInterpolate1(" ",
|
|
144
|
+
i0.ɵɵtextInterpolate1(" ", band_r6.schemaName, " ");
|
|
145
145
|
} }
|
|
146
146
|
function ERDDiagramComponent_Conditional_14_Template(rf, ctx) { if (rf & 1) {
|
|
147
147
|
i0.ɵɵrepeaterCreate(0, ERDDiagramComponent_Conditional_14_For_1_Template, 4, 7, ":svg:g", 49, i0.ɵɵcomponentInstance().trackByBand, true);
|
|
148
148
|
} if (rf & 2) {
|
|
149
|
-
const
|
|
150
|
-
i0.ɵɵrepeater(
|
|
149
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
150
|
+
i0.ɵɵrepeater(ctx_r1.layout.bands);
|
|
151
151
|
} }
|
|
152
152
|
function ERDDiagramComponent_For_17_Template(rf, ctx) { if (rf & 1) {
|
|
153
153
|
i0.ɵɵnamespaceSVG();
|
|
154
154
|
i0.ɵɵelement(0, "path", 52);
|
|
155
155
|
} if (rf & 2) {
|
|
156
|
-
const
|
|
157
|
-
const
|
|
158
|
-
i0.ɵɵclassProp("erd-edge-active",
|
|
159
|
-
i0.ɵɵattribute("d",
|
|
156
|
+
const edge_r7 = ctx.$implicit;
|
|
157
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
158
|
+
i0.ɵɵclassProp("erd-edge-active", ctx_r1.isEdgeActive(edge_r7))("erd-edge-dimmed", ctx_r1.isEdgeDimmed(edge_r7));
|
|
159
|
+
i0.ɵɵattribute("d", ctx_r1.edgePath(edge_r7))("marker-start", ctx_r1.config.crowsFoot ?? true ? ctx_r1.isEdgeActive(edge_r7) ? "url(#erd-many-active)" : "url(#erd-many)" : null)("marker-end", ctx_r1.isEdgeActive(edge_r7) ? "url(#erd-arrow-active)" : "url(#erd-arrow)");
|
|
160
160
|
} }
|
|
161
161
|
function ERDDiagramComponent_Conditional_18_For_2_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
162
162
|
i0.ɵɵnamespaceSVG();
|
|
@@ -166,25 +166,25 @@ function ERDDiagramComponent_Conditional_18_For_2_Conditional_1_Template(rf, ctx
|
|
|
166
166
|
i0.ɵɵtext(3);
|
|
167
167
|
i0.ɵɵelementEnd()();
|
|
168
168
|
} if (rf & 2) {
|
|
169
|
-
const
|
|
170
|
-
const
|
|
171
|
-
const
|
|
172
|
-
i0.ɵɵclassProp("erd-edge-label-active",
|
|
169
|
+
const edge_r8 = i0.ɵɵnextContext().$implicit;
|
|
170
|
+
const pos_r9 = i0.ɵɵreadContextLet(0);
|
|
171
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
172
|
+
i0.ɵɵclassProp("erd-edge-label-active", ctx_r1.isEdgeActive(edge_r8))("erd-edge-label-dimmed", ctx_r1.isEdgeDimmed(edge_r8));
|
|
173
173
|
i0.ɵɵadvance();
|
|
174
|
-
i0.ɵɵattribute("x",
|
|
174
|
+
i0.ɵɵattribute("x", pos_r9.x - pos_r9.w / 2 - 4)("y", pos_r9.y - 8)("width", pos_r9.w + 8);
|
|
175
175
|
i0.ɵɵadvance();
|
|
176
|
-
i0.ɵɵattribute("x",
|
|
176
|
+
i0.ɵɵattribute("x", pos_r9.x)("y", pos_r9.y + 4);
|
|
177
177
|
i0.ɵɵadvance();
|
|
178
|
-
i0.ɵɵtextInterpolate(
|
|
178
|
+
i0.ɵɵtextInterpolate(edge_r8.sourceField.name);
|
|
179
179
|
} }
|
|
180
180
|
function ERDDiagramComponent_Conditional_18_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
181
181
|
i0.ɵɵdeclareLet(0);
|
|
182
182
|
i0.ɵɵconditionalCreate(1, ERDDiagramComponent_Conditional_18_For_2_Conditional_1_Template, 4, 10, ":svg:g", 53);
|
|
183
183
|
} if (rf & 2) {
|
|
184
|
-
const
|
|
185
|
-
const
|
|
184
|
+
const edge_r8 = ctx.$implicit;
|
|
185
|
+
const pos_r10 = i0.ɵɵstoreLet(i0.ɵɵnextContext(2).edgeLabelPosition(edge_r8));
|
|
186
186
|
i0.ɵɵadvance();
|
|
187
|
-
i0.ɵɵconditional(
|
|
187
|
+
i0.ɵɵconditional(pos_r10 ? 1 : -1);
|
|
188
188
|
} }
|
|
189
189
|
function ERDDiagramComponent_Conditional_18_Template(rf, ctx) { if (rf & 1) {
|
|
190
190
|
i0.ɵɵnamespaceSVG();
|
|
@@ -192,19 +192,19 @@ function ERDDiagramComponent_Conditional_18_Template(rf, ctx) { if (rf & 1) {
|
|
|
192
192
|
i0.ɵɵrepeaterCreate(1, ERDDiagramComponent_Conditional_18_For_2_Template, 2, 2, null, null, i0.ɵɵcomponentInstance().trackByEdge, true);
|
|
193
193
|
i0.ɵɵelementEnd();
|
|
194
194
|
} if (rf & 2) {
|
|
195
|
-
const
|
|
195
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
196
196
|
i0.ɵɵadvance();
|
|
197
|
-
i0.ɵɵrepeater(
|
|
197
|
+
i0.ɵɵrepeater(ctx_r1.layout.edges);
|
|
198
198
|
} }
|
|
199
199
|
function ERDDiagramComponent_For_21_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
200
200
|
i0.ɵɵelementStart(0, "span", 64);
|
|
201
201
|
i0.ɵɵtext(1);
|
|
202
202
|
i0.ɵɵelementEnd();
|
|
203
203
|
} if (rf & 2) {
|
|
204
|
-
const
|
|
205
|
-
const
|
|
204
|
+
const node_r12 = i0.ɵɵnextContext().$implicit;
|
|
205
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
206
206
|
i0.ɵɵadvance();
|
|
207
|
-
i0.ɵɵtextInterpolate(
|
|
207
|
+
i0.ɵɵtextInterpolate(ctx_r1.formatCount(node_r12.customData.rows));
|
|
208
208
|
} }
|
|
209
209
|
function ERDDiagramComponent_For_21_For_11_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
210
210
|
i0.ɵɵelementStart(0, "span", 70);
|
|
@@ -221,10 +221,10 @@ function ERDDiagramComponent_For_21_For_11_Conditional_6_Template(rf, ctx) { if
|
|
|
221
221
|
i0.ɵɵtext(1);
|
|
222
222
|
i0.ɵɵelementEnd();
|
|
223
223
|
} if (rf & 2) {
|
|
224
|
-
const
|
|
225
|
-
i0.ɵɵproperty("title",
|
|
224
|
+
const field_r13 = i0.ɵɵnextContext().$implicit;
|
|
225
|
+
i0.ɵɵproperty("title", field_r13.type);
|
|
226
226
|
i0.ɵɵadvance();
|
|
227
|
-
i0.ɵɵtextInterpolate(
|
|
227
|
+
i0.ɵɵtextInterpolate(field_r13.type);
|
|
228
228
|
} }
|
|
229
229
|
function ERDDiagramComponent_For_21_For_11_Template(rf, ctx) { if (rf & 1) {
|
|
230
230
|
i0.ɵɵnamespaceSVG();
|
|
@@ -238,41 +238,41 @@ function ERDDiagramComponent_For_21_For_11_Template(rf, ctx) { if (rf & 1) {
|
|
|
238
238
|
i0.ɵɵconditionalCreate(6, ERDDiagramComponent_For_21_For_11_Conditional_6_Template, 2, 2, "span", 73);
|
|
239
239
|
i0.ɵɵelementEnd()();
|
|
240
240
|
} if (rf & 2) {
|
|
241
|
-
const
|
|
242
|
-
const ɵ$
|
|
243
|
-
const
|
|
244
|
-
i0.ɵɵattribute("y", 36 + ɵ$
|
|
241
|
+
const field_r13 = ctx.$implicit;
|
|
242
|
+
const ɵ$index_149_r14 = ctx.$index;
|
|
243
|
+
const node_r12 = i0.ɵɵnextContext().$implicit;
|
|
244
|
+
i0.ɵɵattribute("y", 36 + ɵ$index_149_r14 * 22)("width", node_r12.width);
|
|
245
245
|
i0.ɵɵadvance();
|
|
246
|
-
i0.ɵɵclassProp("erd-field-pk",
|
|
246
|
+
i0.ɵɵclassProp("erd-field-pk", field_r13.isPrimaryKey)("erd-field-fk", !field_r13.isPrimaryKey && field_r13.relatedNodeId);
|
|
247
247
|
i0.ɵɵadvance();
|
|
248
|
-
i0.ɵɵconditional(
|
|
248
|
+
i0.ɵɵconditional(field_r13.isPrimaryKey ? 2 : field_r13.relatedNodeId ? 3 : -1);
|
|
249
249
|
i0.ɵɵadvance(2);
|
|
250
|
-
i0.ɵɵproperty("title",
|
|
250
|
+
i0.ɵɵproperty("title", field_r13.name);
|
|
251
251
|
i0.ɵɵadvance();
|
|
252
|
-
i0.ɵɵtextInterpolate(
|
|
252
|
+
i0.ɵɵtextInterpolate(field_r13.name);
|
|
253
253
|
i0.ɵɵadvance();
|
|
254
|
-
i0.ɵɵconditional(
|
|
254
|
+
i0.ɵɵconditional(field_r13.type ? 6 : -1);
|
|
255
255
|
} }
|
|
256
256
|
function ERDDiagramComponent_For_21_Conditional_12_Template(rf, ctx) { if (rf & 1) {
|
|
257
|
-
const
|
|
257
|
+
const _r15 = i0.ɵɵgetCurrentView();
|
|
258
258
|
i0.ɵɵnamespaceSVG();
|
|
259
259
|
i0.ɵɵelementStart(0, "foreignObject", 74);
|
|
260
|
-
i0.ɵɵlistener("click", function ERDDiagramComponent_For_21_Conditional_12_Template_foreignObject_click_0_listener($event) { i0.ɵɵrestoreView(
|
|
260
|
+
i0.ɵɵlistener("click", function ERDDiagramComponent_For_21_Conditional_12_Template_foreignObject_click_0_listener($event) { i0.ɵɵrestoreView(_r15); const node_r12 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onToggleExpand(node_r12.id, $event)); });
|
|
261
261
|
i0.ɵɵnamespaceHTML();
|
|
262
262
|
i0.ɵɵelementStart(1, "div", 75);
|
|
263
263
|
i0.ɵɵtext(2);
|
|
264
264
|
i0.ɵɵelementEnd()();
|
|
265
265
|
} if (rf & 2) {
|
|
266
|
-
const
|
|
267
|
-
i0.ɵɵattribute("y", 36 +
|
|
266
|
+
const node_r12 = i0.ɵɵnextContext().$implicit;
|
|
267
|
+
i0.ɵɵattribute("y", 36 + node_r12.visibleFields.length * 22 + 6)("width", node_r12.width - 8);
|
|
268
268
|
i0.ɵɵadvance(2);
|
|
269
|
-
i0.ɵɵtextInterpolate1(" + ",
|
|
269
|
+
i0.ɵɵtextInterpolate1(" + ", node_r12.fields.length - node_r12.visibleFields.length, " more fields ");
|
|
270
270
|
} }
|
|
271
271
|
function ERDDiagramComponent_For_21_Template(rf, ctx) { if (rf & 1) {
|
|
272
|
-
const
|
|
272
|
+
const _r11 = i0.ɵɵgetCurrentView();
|
|
273
273
|
i0.ɵɵnamespaceSVG();
|
|
274
274
|
i0.ɵɵelementStart(0, "g", 57);
|
|
275
|
-
i0.ɵɵlistener("click", function ERDDiagramComponent_For_21_Template_g_click_0_listener($event) { const
|
|
275
|
+
i0.ɵɵlistener("click", function ERDDiagramComponent_For_21_Template_g_click_0_listener($event) { const node_r12 = i0.ɵɵrestoreView(_r11).$implicit; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onNodeClick(node_r12, $event)); })("mouseenter", function ERDDiagramComponent_For_21_Template_g_mouseenter_0_listener($event) { const node_r12 = i0.ɵɵrestoreView(_r11).$implicit; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onNodeMouseEnter(node_r12, $event)); })("mouseleave", function ERDDiagramComponent_For_21_Template_g_mouseleave_0_listener() { const node_r12 = i0.ɵɵrestoreView(_r11).$implicit; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onNodeMouseLeave(node_r12)); });
|
|
276
276
|
i0.ɵɵelement(1, "rect", 58)(2, "rect", 59)(3, "rect", 60);
|
|
277
277
|
i0.ɵɵelementStart(4, "foreignObject", 61);
|
|
278
278
|
i0.ɵɵnamespaceHTML();
|
|
@@ -288,38 +288,38 @@ function ERDDiagramComponent_For_21_Template(rf, ctx) { if (rf & 1) {
|
|
|
288
288
|
i0.ɵɵelement(13, "rect", 68);
|
|
289
289
|
i0.ɵɵelementEnd();
|
|
290
290
|
} if (rf & 2) {
|
|
291
|
-
const
|
|
292
|
-
const
|
|
293
|
-
i0.ɵɵclassProp("erd-node-focus",
|
|
294
|
-
i0.ɵɵattribute("transform", "translate(" +
|
|
291
|
+
const node_r12 = ctx.$implicit;
|
|
292
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
293
|
+
i0.ɵɵclassProp("erd-node-focus", ctx_r1.isFocus(node_r12.id))("erd-node-neighbour", ctx_r1.isNeighbour(node_r12.id))("erd-node-dimmed", ctx_r1.isDimmed(node_r12.id));
|
|
294
|
+
i0.ɵɵattribute("transform", "translate(" + node_r12.x + " " + node_r12.y + ")");
|
|
295
295
|
i0.ɵɵadvance();
|
|
296
|
-
i0.ɵɵattribute("width",
|
|
296
|
+
i0.ɵɵattribute("width", node_r12.width)("height", node_r12.height);
|
|
297
297
|
i0.ɵɵadvance();
|
|
298
|
-
i0.ɵɵattribute("width",
|
|
298
|
+
i0.ɵɵattribute("width", node_r12.width)("height", node_r12.height);
|
|
299
299
|
i0.ɵɵadvance();
|
|
300
|
-
i0.ɵɵattribute("width",
|
|
300
|
+
i0.ɵɵattribute("width", node_r12.width);
|
|
301
301
|
i0.ɵɵadvance();
|
|
302
|
-
i0.ɵɵattribute("width",
|
|
302
|
+
i0.ɵɵattribute("width", node_r12.width - 28);
|
|
303
303
|
i0.ɵɵadvance(2);
|
|
304
|
-
i0.ɵɵproperty("title",
|
|
304
|
+
i0.ɵɵproperty("title", node_r12.name);
|
|
305
305
|
i0.ɵɵadvance();
|
|
306
|
-
i0.ɵɵtextInterpolate(
|
|
306
|
+
i0.ɵɵtextInterpolate(node_r12.name);
|
|
307
307
|
i0.ɵɵadvance();
|
|
308
|
-
i0.ɵɵconditional(
|
|
308
|
+
i0.ɵɵconditional(node_r12.customData && node_r12.customData.rows != null ? 8 : -1);
|
|
309
309
|
i0.ɵɵadvance();
|
|
310
|
-
i0.ɵɵattribute("x2",
|
|
310
|
+
i0.ɵɵattribute("x2", node_r12.width);
|
|
311
311
|
i0.ɵɵadvance();
|
|
312
|
-
i0.ɵɵrepeater(
|
|
312
|
+
i0.ɵɵrepeater(node_r12.visibleFields);
|
|
313
313
|
i0.ɵɵadvance(2);
|
|
314
|
-
i0.ɵɵconditional(
|
|
314
|
+
i0.ɵɵconditional(node_r12.hasMore ? 12 : -1);
|
|
315
315
|
i0.ɵɵadvance();
|
|
316
|
-
i0.ɵɵattribute("width",
|
|
316
|
+
i0.ɵɵattribute("width", node_r12.width)("height", node_r12.height);
|
|
317
317
|
} }
|
|
318
318
|
function ERDDiagramComponent_Conditional_22_Template(rf, ctx) { if (rf & 1) {
|
|
319
319
|
i0.ɵɵelement(0, "mj-empty-state", 17);
|
|
320
320
|
} if (rf & 2) {
|
|
321
|
-
const
|
|
322
|
-
i0.ɵɵproperty("Variant",
|
|
321
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
322
|
+
i0.ɵɵproperty("Variant", ctx_r1.totalCount === 0 ? "empty" : "no-results")("Icon", ctx_r1.emptyStateIcon)("Title", ctx_r1.emptyStateTitle)("Message", ctx_r1.totalCount > 0 ? "Try adjusting schema filters or clearing search" : "");
|
|
323
323
|
} }
|
|
324
324
|
function ERDDiagramComponent_Conditional_23_Template(rf, ctx) { if (rf & 1) {
|
|
325
325
|
i0.ɵɵelementStart(0, "div", 18)(1, "div", 76);
|
|
@@ -976,12 +976,11 @@ export class ERDDiagramComponent {
|
|
|
976
976
|
} }, hostVars: 2, hostBindings: function ERDDiagramComponent_HostBindings(rf, ctx) { if (rf & 2) {
|
|
977
977
|
i0.ɵɵclassProp("erd-root", ctx.rootClass);
|
|
978
978
|
} }, inputs: { nodes: "nodes", selectedNodeId: "selectedNodeId", highlightedNodeIds: "highlightedNodeIds", focusNodeId: "focusNodeId", focusDepth: "focusDepth", isRefreshing: "isRefreshing", readOnly: "readOnly", config: "config", showHeader: "showHeader", headerTitle: "headerTitle" }, outputs: { nodeClick: "nodeClick", nodeDoubleClick: "nodeDoubleClick", nodeSelected: "nodeSelected", nodeDeselected: "nodeDeselected", linkClick: "linkClick", nodeHover: "nodeHover", nodeHoverEnd: "nodeHoverEnd", linkHover: "linkHover", linkHoverEnd: "linkHoverEnd", nodeContextMenu: "nodeContextMenu", linkContextMenu: "linkContextMenu", diagramContextMenu: "diagramContextMenu", nodeDragStart: "nodeDragStart", nodeDragEnd: "nodeDragEnd", zoomChange: "zoomChange", refreshRequested: "refreshRequested", layoutComplete: "layoutComplete", stateChange: "stateChange" }, standalone: false, features: [i0.ɵɵNgOnChangesFeature], decls: 24, vars: 7, consts: [["canvasRef", ""], [1, "erd-chrome"], [1, "erd-canvas-wrap"], [1, "erd-canvas", 3, "mousedown", "wheel"], ["id", "erd-arrow", "viewBox", "0 0 10 10", "refX", "9", "refY", "5", "markerWidth", "7", "markerHeight", "7", "orient", "auto"], ["d", "M 0 0 L 10 5 L 0 10 z", 1, "erd-marker"], ["id", "erd-arrow-active", "viewBox", "0 0 10 10", "refX", "9", "refY", "5", "markerWidth", "7", "markerHeight", "7", "orient", "auto"], ["d", "M 0 0 L 10 5 L 0 10 z", 1, "erd-marker", "erd-marker-active"], ["id", "erd-many", "viewBox", "-10 -6 14 12", "refX", "-8", "refY", "0", "markerWidth", "14", "markerHeight", "14", "orient", "auto"], ["d", "M 0 -5 L -8 0 L 0 5 M -8 0 L 4 0", 1, "erd-marker-stroke"], ["id", "erd-many-active", "viewBox", "-10 -6 14 12", "refX", "-8", "refY", "0", "markerWidth", "14", "markerHeight", "14", "orient", "auto"], ["d", "M 0 -5 L -8 0 L 0 5 M -8 0 L 4 0", 1, "erd-marker-stroke", "erd-marker-active"], [1, "erd-edges"], ["fill", "none", 1, "erd-edge", 3, "erd-edge-active", "erd-edge-dimmed"], [1, "erd-edge-labels"], [1, "erd-nodes"], [1, "erd-node", 3, "erd-node-focus", "erd-node-neighbour", "erd-node-dimmed"], [1, "erd-empty", 3, "Variant", "Icon", "Title", "Message"], [1, "erd-loading-overlay"], [1, "erd-title-group"], [1, "erd-title"], [1, "erd-subtitle"], [1, "erd-count-pill"], [1, "erd-count-label"], [1, "erd-dot"], [1, "erd-search"], ["aria-hidden", "true", 1, "fa-solid", "fa-magnifying-glass"], ["type", "text", "placeholder", "Search entities, schemas, fields\u2026", "spellcheck", "false", "aria-label", "Search entities", 3, "input", "value"], ["type", "button", "aria-label", "Clear search", 1, "erd-search-clear"], [1, "erd-chrome-right"], ["role", "group", "aria-label", "Filter by schema", 1, "erd-schema-chips"], ["role", "group", "aria-label", "Layout mode", 1, "erd-toolbar"], ["type", "button", "title", "Schema grid \u2014 grouped by schema, predictable", "aria-label", "Schema-grid layout", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-table-cells"], ["type", "button", "title", "Hierarchical \u2014 classic ERD, relationship-driven", "aria-label", "Hierarchical layout", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-sitemap"], ["role", "group", "aria-label", "Zoom controls", 1, "erd-toolbar"], ["type", "button", "title", "Zoom in", "aria-label", "Zoom in", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-magnifying-glass-plus"], ["type", "button", "title", "Zoom out", "aria-label", "Zoom out", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-magnifying-glass-minus"], ["type", "button", "title", "Fit to view", "aria-label", "Fit to view", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-expand"], [1, "erd-zoom-val"], ["type", "button", "aria-label", "Clear search", 1, "erd-search-clear", 3, "click"], ["type", "button", 1, "erd-chip", 3, "active"], ["type", "button", 1, "erd-chip", 3, "click"], [1, "erd-chip-label"], [1, "erd-chip-count"], [1, "erd-band"], ["rx", "16", 1, "erd-band-rect"], ["text-anchor", "middle", 1, "erd-band-title"], ["fill", "none", 1, "erd-edge"], [1, "erd-edge-label", 3, "erd-edge-label-active", "erd-edge-label-dimmed"], [1, "erd-edge-label"], ["height", "16", "rx", "3", 1, "erd-edge-label-bg"], ["text-anchor", "middle", 1, "erd-edge-label-text"], [1, "erd-node", 3, "click", "mouseenter", "mouseleave"], ["x", "0", "y", "2", "rx", "8", 1, "erd-node-shadow"], ["x", "0", "y", "0", "rx", "8", 1, "erd-node-body"], ["x", "0", "y", "0", "height", "36", "rx", "6", 1, "erd-node-header"], ["x", "14", "y", "8", "height", "22"], ["xmlns", "http://www.w3.org/1999/xhtml", 1, "erd-node-header-content"], [1, "erd-node-name", 3, "title"], [1, "erd-node-rows"], ["x1", "0", "y1", "36", "y2", "36", 1, "erd-node-separator"], ["x", "0", "height", "22"], ["x", "4", "height", "14"], ["x", "0", "y", "0", "rx", "8", 1, "erd-node-frame"], ["xmlns", "http://www.w3.org/1999/xhtml", 1, "erd-field-row"], [1, "erd-field-chip", "erd-field-chip-pk"], [1, "erd-field-chip", "erd-field-chip-fk"], [1, "erd-field-name", 3, "title"], [1, "erd-field-type", 3, "title"], ["x", "4", "height", "14", 3, "click"], ["xmlns", "http://www.w3.org/1999/xhtml", 1, "erd-field-more"], [1, "erd-loading-content"], ["aria-hidden", "true", 1, "fa-solid", "fa-circle-notch", "fa-spin"]], template: function ERDDiagramComponent_Template(rf, ctx) { if (rf & 1) {
|
|
979
|
-
const _r1 = i0.ɵɵgetCurrentView();
|
|
980
979
|
i0.ɵɵconditionalCreate(0, ERDDiagramComponent_Conditional_0_Template, 33, 12, "header", 1);
|
|
981
980
|
i0.ɵɵelementStart(1, "div", 2);
|
|
982
981
|
i0.ɵɵnamespaceSVG();
|
|
983
982
|
i0.ɵɵelementStart(2, "svg", 3, 0);
|
|
984
|
-
i0.ɵɵlistener("mousedown", function ERDDiagramComponent_Template_svg_mousedown_2_listener($event) {
|
|
983
|
+
i0.ɵɵlistener("mousedown", function ERDDiagramComponent_Template_svg_mousedown_2_listener($event) { return ctx.onBackgroundMouseDown($event); })("wheel", function ERDDiagramComponent_Template_svg_wheel_2_listener($event) { return ctx.onWheel($event); });
|
|
985
984
|
i0.ɵɵelementStart(4, "defs")(5, "marker", 4);
|
|
986
985
|
i0.ɵɵelement(6, "path", 5);
|
|
987
986
|
i0.ɵɵelementEnd();
|
|
@@ -1024,7 +1023,7 @@ export class ERDDiagramComponent {
|
|
|
1024
1023
|
i0.ɵɵconditional(ctx.visibleCount === 0 ? 22 : -1);
|
|
1025
1024
|
i0.ɵɵadvance();
|
|
1026
1025
|
i0.ɵɵconditional(ctx.isRefreshing ? 23 : -1);
|
|
1027
|
-
} }, dependencies: [i1.MJEmptyStateComponent], styles: ["\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n[_nghost-%COMP%] {\n display: flex !important;\n flex-direction: column !important;\n height: 100%;\n width: 100%;\n overflow: hidden;\n background: var(--mj-bg-page);\n color: var(--mj-text-primary);\n --erd-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, \"Liberation Mono\", monospace;\n}\n\n\n\n\n.erd-chrome[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 24px;\n padding: 14px 24px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n flex-shrink: 0;\n min-height: 64px;\n}\n\n.erd-title-group[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n flex-shrink: 0;\n}\n\n.erd-title[_ngcontent-%COMP%] {\n font-size: 15px;\n font-weight: 600;\n letter-spacing: -0.01em;\n color: var(--mj-text-primary);\n}\n\n.erd-subtitle[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n.erd-count-pill[_ngcontent-%COMP%] {\n font-family: var(--erd-mono);\n font-size: 11px;\n font-weight: 600;\n padding: 2px 8px;\n border-radius: 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent);\n color: var(--mj-brand-primary);\n line-height: 1.3;\n}\n\n.erd-count-label[_ngcontent-%COMP%] { color: var(--mj-text-secondary); }\n.erd-dot[_ngcontent-%COMP%] { color: var(--mj-text-muted); }\n\n.erd-search[_ngcontent-%COMP%] {\n flex: 1;\n max-width: 440px;\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface-card);\n transition: border-color .12s, background .12s, box-shadow .12s;\n}\n\n.erd-search[_ngcontent-%COMP%]:focus-within {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.erd-search[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n flex-shrink: 0;\n font-size: 13px;\n}\n\n.erd-search[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n flex: 1;\n border: 0;\n outline: 0;\n background: transparent;\n font: inherit;\n font-size: 13px;\n color: var(--mj-text-primary);\n}\n\n.erd-search[_ngcontent-%COMP%] input[_ngcontent-%COMP%]::placeholder { color: var(--mj-text-muted); }\n\n.erd-search-clear[_ngcontent-%COMP%] {\n border: 0;\n background: transparent;\n color: var(--mj-text-muted);\n font-size: 18px;\n line-height: 1;\n cursor: pointer;\n padding: 0 4px;\n}\n\n.erd-search-clear[_ngcontent-%COMP%]:hover { color: var(--mj-text-primary); }\n\n.erd-chrome-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n margin-left: auto;\n}\n\n\n\n.erd-schema-chips[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n padding: 3px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n}\n\n.erd-chip[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 5px 10px;\n border: 0;\n background: transparent;\n border-radius: 7px;\n font-family: var(--erd-mono);\n font-size: 11px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: background .1s, color .1s;\n}\n\n.erd-chip[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.erd-chip.active[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06);\n}\n\n.erd-chip-count[_ngcontent-%COMP%] {\n font-size: 10px;\n padding: 1px 5px;\n border-radius: 6px;\n background: color-mix(in srgb, var(--mj-bg-surface-card) 80%, transparent);\n color: var(--mj-text-muted);\n}\n\n\n\n.erd-toolbar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 2px;\n padding: 3px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n}\n\n.erd-toolbar[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n width: 28px;\n height: 28px;\n border: 0;\n background: transparent;\n border-radius: 5px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n transition: background .1s, color .1s;\n}\n\n.erd-toolbar[_ngcontent-%COMP%] button[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.erd-toolbar[_ngcontent-%COMP%] button.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.erd-zoom-val[_ngcontent-%COMP%] {\n padding: 0 8px;\n font-family: var(--erd-mono);\n font-size: 10px;\n color: var(--mj-text-secondary);\n min-width: 42px;\n text-align: right;\n}\n\n\n\n\n.erd-canvas-wrap[_ngcontent-%COMP%] {\n flex: 1;\n position: relative;\n overflow: hidden;\n background: var(--mj-bg-surface-sunken);\n min-height: 300px;\n}\n\n.erd-canvas[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n user-select: none;\n cursor: grab;\n display: block;\n}\n\n.erd-canvas[data-panning=\"true\"][_ngcontent-%COMP%] { cursor: grabbing; }\n\n.erd-canvas[_ngcontent-%COMP%] text[_ngcontent-%COMP%] { pointer-events: none; }\n\n\n\n.erd-band-rect[_ngcontent-%COMP%] {\n fill: color-mix(in srgb, var(--mj-text-primary) 4%, transparent);\n stroke: var(--mj-border-default);\n stroke-width: 1;\n}\n\n.erd-band-title[_ngcontent-%COMP%] {\n font-family: var(--erd-mono);\n font-size: 13px;\n font-weight: 600;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n fill: var(--mj-text-muted);\n}\n\n\n\n.erd-edge[_ngcontent-%COMP%] {\n stroke: var(--mj-border-strong);\n stroke-width: 1.2;\n transition: stroke-width .15s, opacity .15s;\n}\n\n.erd-edge-active[_ngcontent-%COMP%] {\n stroke: var(--mj-brand-primary);\n stroke-width: 1.8;\n}\n\n.erd-edge-dimmed[_ngcontent-%COMP%] { opacity: 0.18; }\n\n\n\n\n.erd-edge-label[_ngcontent-%COMP%] {\n pointer-events: none;\n transition: opacity .15s;\n}\n\n.erd-edge-label-bg[_ngcontent-%COMP%] {\n fill: var(--mj-bg-surface);\n stroke: var(--mj-border-default);\n stroke-width: 0.75;\n}\n\n.erd-edge-label-text[_ngcontent-%COMP%] {\n font-family: var(--erd-mono);\n font-size: 11px;\n fill: var(--mj-text-secondary);\n}\n\n.erd-edge-label-active[_ngcontent-%COMP%] .erd-edge-label-bg[_ngcontent-%COMP%] {\n stroke: var(--mj-brand-primary);\n}\n\n.erd-edge-label-active[_ngcontent-%COMP%] .erd-edge-label-text[_ngcontent-%COMP%] {\n fill: var(--mj-brand-primary);\n}\n\n.erd-edge-label-dimmed[_ngcontent-%COMP%] { opacity: 0.18; }\n\n\n\n.erd-marker[_ngcontent-%COMP%] { fill: var(--mj-border-strong); }\n.erd-marker-active[_ngcontent-%COMP%], \n.erd-marker-active.erd-marker[_ngcontent-%COMP%], \n.erd-marker-active.erd-marker-stroke[_ngcontent-%COMP%] { fill: var(--mj-brand-primary); stroke: var(--mj-brand-primary); }\n.erd-marker-stroke[_ngcontent-%COMP%] { stroke: var(--mj-border-strong); stroke-width: 1.4; fill: none; stroke-linecap: round; }\n\n\n\n.erd-node[_ngcontent-%COMP%] {\n cursor: pointer;\n transition: opacity .15s;\n}\n\n.erd-node-dimmed[_ngcontent-%COMP%] { opacity: 0.22; }\n\n.erd-node-shadow[_ngcontent-%COMP%] {\n fill: color-mix(in srgb, var(--mj-text-primary) 8%, transparent);\n}\n\n.erd-node-body[_ngcontent-%COMP%] {\n fill: var(--mj-bg-surface);\n}\n\n\n\n\n\n.erd-node-frame[_ngcontent-%COMP%] {\n fill: none;\n stroke: var(--mj-border-default);\n stroke-width: 1;\n pointer-events: none;\n}\n\n.erd-node-focus[_ngcontent-%COMP%] .erd-node-frame[_ngcontent-%COMP%] {\n stroke: var(--mj-brand-primary);\n stroke-width: 2;\n}\n\n.erd-node-neighbour[_ngcontent-%COMP%] .erd-node-frame[_ngcontent-%COMP%] {\n stroke-width: 1.5;\n}\n\n.erd-node-header[_ngcontent-%COMP%] {\n fill: var(--mj-bg-surface-card);\n}\n\n.erd-node-separator[_ngcontent-%COMP%] {\n stroke: var(--mj-border-default);\n stroke-width: 1;\n}\n\n\n\n.erd-node-header-content[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-family: var(--erd-mono);\n line-height: 22px;\n height: 22px;\n color: var(--mj-text-primary);\n}\n\n.erd-node-name[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n flex: 1;\n min-width: 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.erd-node-rows[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--mj-text-muted);\n flex-shrink: 0;\n}\n\n\n\n.erd-field-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n height: 22px;\n padding: 0 12px 0 8px;\n font-family: var(--erd-mono);\n line-height: 22px;\n box-sizing: border-box;\n}\n\n.erd-field-chip[_ngcontent-%COMP%] {\n flex-shrink: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 14px;\n border-radius: 3px;\n font-size: 8px;\n font-weight: 700;\n letter-spacing: 0.05em;\n line-height: 1;\n}\n\n.erd-field-chip-pk[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 20%, var(--mj-bg-surface));\n color: var(--mj-status-warning-text, var(--mj-status-warning));\n}\n\n.erd-field-chip-fk[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 18%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.erd-field-name[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n font-size: 11px;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.erd-field-type[_ngcontent-%COMP%] {\n flex-shrink: 0;\n font-size: 10px;\n color: var(--mj-text-muted);\n \n\n max-width: 45%;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n\n\n.erd-field-more[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 14px;\n border-radius: 3px;\n background: var(--mj-bg-surface-card);\n opacity: 0.7;\n font-family: inherit;\n font-size: 9px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: opacity .1s;\n}\n\n.erd-field-more[_ngcontent-%COMP%]:hover { opacity: 1; }\n\n\n\n\n\n\n.erd-empty[_ngcontent-%COMP%] {\n position: absolute;\n inset: 0;\n pointer-events: none;\n}\n\n.erd-loading-overlay[_ngcontent-%COMP%] {\n position: absolute;\n inset: 0;\n background: color-mix(in srgb, var(--mj-bg-page) 90%, transparent);\n backdrop-filter: blur(2px);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 100;\n}\n\n.erd-loading-content[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n color: var(--mj-text-secondary);\n font-size: 13px;\n}\n\n.erd-loading-content[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 20px;\n}"], changeDetection: 0 });
|
|
1026
|
+
} }, dependencies: [i1.MJEmptyStateComponent], styles: ["\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n[_nghost-%COMP%] {\n display: flex !important;\n flex-direction: column !important;\n height: 100%;\n width: 100%;\n overflow: hidden;\n background: var(--mj-bg-page);\n color: var(--mj-text-primary);\n --erd-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, \"Liberation Mono\", monospace;\n}\n\n\n\n.erd-chrome[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 24px;\n padding: 14px 24px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n flex-shrink: 0;\n min-height: 64px;\n}\n\n.erd-title-group[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n flex-shrink: 0;\n}\n\n.erd-title[_ngcontent-%COMP%] {\n font-size: 15px;\n font-weight: 600;\n letter-spacing: -0.01em;\n color: var(--mj-text-primary);\n}\n\n.erd-subtitle[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n.erd-count-pill[_ngcontent-%COMP%] {\n font-family: var(--erd-mono);\n font-size: 11px;\n font-weight: 600;\n padding: 2px 8px;\n border-radius: 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent);\n color: var(--mj-brand-primary);\n line-height: 1.3;\n}\n\n.erd-count-label[_ngcontent-%COMP%] { color: var(--mj-text-secondary); }\n.erd-dot[_ngcontent-%COMP%] { color: var(--mj-text-muted); }\n\n.erd-search[_ngcontent-%COMP%] {\n flex: 1;\n max-width: 440px;\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface-card);\n transition: border-color .12s, background .12s, box-shadow .12s;\n}\n\n.erd-search[_ngcontent-%COMP%]:focus-within {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.erd-search[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n flex-shrink: 0;\n font-size: 13px;\n}\n\n.erd-search[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n flex: 1;\n border: 0;\n outline: 0;\n background: transparent;\n font: inherit;\n font-size: 13px;\n color: var(--mj-text-primary);\n}\n\n.erd-search[_ngcontent-%COMP%] input[_ngcontent-%COMP%]::placeholder { color: var(--mj-text-muted); }\n\n.erd-search-clear[_ngcontent-%COMP%] {\n border: 0;\n background: transparent;\n color: var(--mj-text-muted);\n font-size: 18px;\n line-height: 1;\n cursor: pointer;\n padding: 0 4px;\n}\n\n.erd-search-clear[_ngcontent-%COMP%]:hover { color: var(--mj-text-primary); }\n\n.erd-chrome-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n margin-left: auto;\n}\n\n\n.erd-schema-chips[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n padding: 3px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n}\n\n.erd-chip[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 5px 10px;\n border: 0;\n background: transparent;\n border-radius: 7px;\n font-family: var(--erd-mono);\n font-size: 11px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: background .1s, color .1s;\n}\n\n.erd-chip[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.erd-chip.active[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06);\n}\n\n.erd-chip-count[_ngcontent-%COMP%] {\n font-size: 10px;\n padding: 1px 5px;\n border-radius: 6px;\n background: color-mix(in srgb, var(--mj-bg-surface-card) 80%, transparent);\n color: var(--mj-text-muted);\n}\n\n\n.erd-toolbar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 2px;\n padding: 3px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n}\n\n.erd-toolbar[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n width: 28px;\n height: 28px;\n border: 0;\n background: transparent;\n border-radius: 5px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n transition: background .1s, color .1s;\n}\n\n.erd-toolbar[_ngcontent-%COMP%] button[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.erd-toolbar[_ngcontent-%COMP%] button.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.erd-zoom-val[_ngcontent-%COMP%] {\n padding: 0 8px;\n font-family: var(--erd-mono);\n font-size: 10px;\n color: var(--mj-text-secondary);\n min-width: 42px;\n text-align: right;\n}\n\n\n\n.erd-canvas-wrap[_ngcontent-%COMP%] {\n flex: 1;\n position: relative;\n overflow: hidden;\n background: var(--mj-bg-surface-sunken);\n min-height: 300px;\n}\n\n.erd-canvas[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n user-select: none;\n cursor: grab;\n display: block;\n}\n\n.erd-canvas[data-panning=\"true\"][_ngcontent-%COMP%] { cursor: grabbing; }\n\n.erd-canvas[_ngcontent-%COMP%] text[_ngcontent-%COMP%] { pointer-events: none; }\n\n\n.erd-band-rect[_ngcontent-%COMP%] {\n fill: color-mix(in srgb, var(--mj-text-primary) 4%, transparent);\n stroke: var(--mj-border-default);\n stroke-width: 1;\n}\n\n.erd-band-title[_ngcontent-%COMP%] {\n font-family: var(--erd-mono);\n font-size: 13px;\n font-weight: 600;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n fill: var(--mj-text-muted);\n}\n\n\n.erd-edge[_ngcontent-%COMP%] {\n stroke: var(--mj-border-strong);\n stroke-width: 1.2;\n transition: stroke-width .15s, opacity .15s;\n}\n\n.erd-edge-active[_ngcontent-%COMP%] {\n stroke: var(--mj-brand-primary);\n stroke-width: 1.8;\n}\n\n.erd-edge-dimmed[_ngcontent-%COMP%] { opacity: 0.18; }\n\n\n\n.erd-edge-label[_ngcontent-%COMP%] {\n pointer-events: none;\n transition: opacity .15s;\n}\n\n.erd-edge-label-bg[_ngcontent-%COMP%] {\n fill: var(--mj-bg-surface);\n stroke: var(--mj-border-default);\n stroke-width: 0.75;\n}\n\n.erd-edge-label-text[_ngcontent-%COMP%] {\n font-family: var(--erd-mono);\n font-size: 11px;\n fill: var(--mj-text-secondary);\n}\n\n.erd-edge-label-active[_ngcontent-%COMP%] .erd-edge-label-bg[_ngcontent-%COMP%] {\n stroke: var(--mj-brand-primary);\n}\n\n.erd-edge-label-active[_ngcontent-%COMP%] .erd-edge-label-text[_ngcontent-%COMP%] {\n fill: var(--mj-brand-primary);\n}\n\n.erd-edge-label-dimmed[_ngcontent-%COMP%] { opacity: 0.18; }\n\n\n.erd-marker[_ngcontent-%COMP%] { fill: var(--mj-border-strong); }\n.erd-marker-active[_ngcontent-%COMP%], \n.erd-marker-active.erd-marker[_ngcontent-%COMP%], \n.erd-marker-active.erd-marker-stroke[_ngcontent-%COMP%] { fill: var(--mj-brand-primary); stroke: var(--mj-brand-primary); }\n.erd-marker-stroke[_ngcontent-%COMP%] { stroke: var(--mj-border-strong); stroke-width: 1.4; fill: none; stroke-linecap: round; }\n\n\n.erd-node[_ngcontent-%COMP%] {\n cursor: pointer;\n transition: opacity .15s;\n}\n\n.erd-node-dimmed[_ngcontent-%COMP%] { opacity: 0.22; }\n\n.erd-node-shadow[_ngcontent-%COMP%] {\n fill: color-mix(in srgb, var(--mj-text-primary) 8%, transparent);\n}\n\n.erd-node-body[_ngcontent-%COMP%] {\n fill: var(--mj-bg-surface);\n}\n\n\n\n\n.erd-node-frame[_ngcontent-%COMP%] {\n fill: none;\n stroke: var(--mj-border-default);\n stroke-width: 1;\n pointer-events: none;\n}\n\n.erd-node-focus[_ngcontent-%COMP%] .erd-node-frame[_ngcontent-%COMP%] {\n stroke: var(--mj-brand-primary);\n stroke-width: 2;\n}\n\n.erd-node-neighbour[_ngcontent-%COMP%] .erd-node-frame[_ngcontent-%COMP%] {\n stroke-width: 1.5;\n}\n\n.erd-node-header[_ngcontent-%COMP%] {\n fill: var(--mj-bg-surface-card);\n}\n\n.erd-node-separator[_ngcontent-%COMP%] {\n stroke: var(--mj-border-default);\n stroke-width: 1;\n}\n\n\n.erd-node-header-content[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-family: var(--erd-mono);\n line-height: 22px;\n height: 22px;\n color: var(--mj-text-primary);\n}\n\n.erd-node-name[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n flex: 1;\n min-width: 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.erd-node-rows[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--mj-text-muted);\n flex-shrink: 0;\n}\n\n\n.erd-field-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n height: 22px;\n padding: 0 12px 0 8px;\n font-family: var(--erd-mono);\n line-height: 22px;\n box-sizing: border-box;\n}\n\n.erd-field-chip[_ngcontent-%COMP%] {\n flex-shrink: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 14px;\n border-radius: 3px;\n font-size: 8px;\n font-weight: 700;\n letter-spacing: 0.05em;\n line-height: 1;\n}\n\n.erd-field-chip-pk[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 20%, var(--mj-bg-surface));\n color: var(--mj-status-warning-text, var(--mj-status-warning));\n}\n\n.erd-field-chip-fk[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 18%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.erd-field-name[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n font-size: 11px;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.erd-field-type[_ngcontent-%COMP%] {\n flex-shrink: 0;\n font-size: 10px;\n color: var(--mj-text-muted);\n \n max-width: 45%;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n\n.erd-field-more[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 14px;\n border-radius: 3px;\n background: var(--mj-bg-surface-card);\n opacity: 0.7;\n font-family: inherit;\n font-size: 9px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: opacity .1s;\n}\n\n.erd-field-more[_ngcontent-%COMP%]:hover { opacity: 1; }\n\n\n\n\n.erd-empty[_ngcontent-%COMP%] {\n position: absolute;\n inset: 0;\n pointer-events: none;\n}\n\n.erd-loading-overlay[_ngcontent-%COMP%] {\n position: absolute;\n inset: 0;\n background: color-mix(in srgb, var(--mj-bg-page) 90%, transparent);\n backdrop-filter: blur(2px);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 100;\n}\n\n.erd-loading-content[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n color: var(--mj-text-secondary);\n font-size: 13px;\n}\n\n.erd-loading-content[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 20px;\n}"], changeDetection: 0 });
|
|
1028
1027
|
}
|
|
1029
1028
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ERDDiagramComponent, [{
|
|
1030
1029
|
type: Component,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"erd-diagram.component.js","sourceRoot":"","sources":["../../../src/lib/components/erd-diagram.component.ts","../../../src/lib/components/erd-diagram.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * @module erd-diagram.component\n * @description\n * Schema-grouped Entity Relationship Diagram. Each schema becomes a rounded\n * rectangular band; entities tile in a grid within the band. Click a node to\n * enter focus mode (neighbours highlighted, everything else dimmed) and see a\n * floating details card with its inbound and outbound FKs.\n *\n * The component is pure Angular + SVG (no D3, no Dagre). Layout is computed\n * by a pure function in `../layout/compute-erd-layout.ts` that is easily\n * unit-tested.\n *\n * Public API is preserved from the previous D3-based implementation so\n * existing consumers (Database Designer wizard preview, admin ERD dashboard,\n * Entity Record view) continue to work without changes.\n */\n\nimport {\n Component,\n Input,\n Output,\n EventEmitter,\n ElementRef,\n ViewChild,\n HostBinding,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n AfterViewInit,\n OnDestroy,\n OnChanges,\n SimpleChanges,\n inject,\n} from '@angular/core';\nimport {\n ERDNode,\n ERDField,\n ERDLink,\n ERDConfig,\n ERDNodeClickEvent,\n ERDNodeDoubleClickEvent,\n ERDLinkClickEvent,\n ERDZoomEvent,\n ERDState,\n ERDNodeHoverEvent,\n ERDLinkHoverEvent,\n ERDNodeContextMenuEvent,\n ERDLinkContextMenuEvent,\n ERDDiagramContextMenuEvent,\n ERDNodeDragEvent,\n} from '../interfaces/erd-types';\nimport {\n computeErdLayout,\n pointsToPath,\n getNeighbors,\n type ErdLayout,\n type LaidOutNode,\n type LaidOutEdge,\n type LaidOutBand,\n} from '../layout/compute-erd-layout';\nimport { computeDagreLayout } from '../layout/compute-dagre-layout';\n\n// ──────────────────────────────────────────────────────────────────────────\n// Internal view-model types\n// ──────────────────────────────────────────────────────────────────────────\n\ninterface SchemaChip {\n name: string;\n count: number;\n active: boolean;\n}\n\n/** 2D transform (pan x/y + zoom scale) for the SVG stage. */\ninterface Transform {\n x: number;\n y: number;\n k: number;\n}\n\n@Component({\n standalone: false,\n selector: 'mj-erd-diagram',\n templateUrl: './erd-diagram.component.html',\n styleUrls: ['./erd-diagram.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class ERDDiagramComponent implements AfterViewInit, OnDestroy, OnChanges {\n\n private readonly cdr = inject(ChangeDetectorRef);\n private readonly host = inject(ElementRef);\n\n // ─── INPUTS ───────────────────────────────────────────────────────────\n\n @Input() public nodes: ERDNode[] = [];\n @Input() public selectedNodeId: string | null = null;\n @Input() public highlightedNodeIds: string[] = [];\n @Input() public focusNodeId: string | null = null;\n @Input() public focusDepth = 1;\n @Input() public isRefreshing = false;\n @Input() public readOnly = false;\n @Input() public config: ERDConfig = {};\n @Input() public showHeader = true;\n @Input() public headerTitle = 'Entity Relationship Diagram';\n\n // ─── OUTPUTS (preserved from legacy API) ──────────────────────────────\n\n @Output() public nodeClick = new EventEmitter<ERDNodeClickEvent>();\n @Output() public nodeDoubleClick = new EventEmitter<ERDNodeDoubleClickEvent>();\n @Output() public nodeSelected = new EventEmitter<ERDNode>();\n @Output() public nodeDeselected = new EventEmitter<void>();\n @Output() public linkClick = new EventEmitter<ERDLinkClickEvent>();\n @Output() public nodeHover = new EventEmitter<ERDNodeHoverEvent>();\n @Output() public nodeHoverEnd = new EventEmitter<ERDNode>();\n @Output() public linkHover = new EventEmitter<ERDLinkHoverEvent>();\n @Output() public linkHoverEnd = new EventEmitter<ERDLink>();\n @Output() public nodeContextMenu = new EventEmitter<ERDNodeContextMenuEvent>();\n @Output() public linkContextMenu = new EventEmitter<ERDLinkContextMenuEvent>();\n @Output() public diagramContextMenu = new EventEmitter<ERDDiagramContextMenuEvent>();\n @Output() public nodeDragStart = new EventEmitter<ERDNodeDragEvent>();\n @Output() public nodeDragEnd = new EventEmitter<ERDNodeDragEvent>();\n @Output() public zoomChange = new EventEmitter<ERDZoomEvent>();\n @Output() public refreshRequested = new EventEmitter<void>();\n @Output() public layoutComplete = new EventEmitter<void>();\n @Output() public stateChange = new EventEmitter<ERDState>();\n\n // ─── VIEW CHILDREN ────────────────────────────────────────────────────\n\n @ViewChild('canvasRef', { static: false }) private canvasRef?: ElementRef<SVGSVGElement>;\n\n // ─── STATE ────────────────────────────────────────────────────────────\n\n /** Current pan + zoom. */\n public transform: Transform = { x: 0, y: 0, k: 1 };\n\n /** Set of schema names the user has filtered IN. Null means \"all\". */\n public activeSchemas: Set<string> | null = null;\n\n /** Search query string. */\n public searchQuery = '';\n\n /** Node IDs the user has clicked \"+N more fields\" on. */\n public expandedNodeIds = new Set<string>();\n\n /** Node currently being hovered (for highlight preview). */\n public hoverNodeId: string | null = null;\n\n /** Cached layout — recomputed when nodes, filter, search or expansion changes. */\n public layout: ErdLayout = { nodes: [], edges: [], bands: [], totalWidth: 0, totalHeight: 0 };\n\n /**\n * Active layout algorithm. Starts from `config.layoutAlgorithm` (default\n * `schema-grid`) but can be toggled at runtime via `setLayoutAlgorithm`.\n * Exposed so the chrome toggle + saved user state can drive it.\n */\n public activeLayout: 'schema-grid' | 'dagre' = 'schema-grid';\n\n /** Derived schema summary for the chip row. */\n public schemaChips: SchemaChip[] = [];\n\n /** Derived — number of entities currently visible. */\n public visibleCount = 0;\n\n /** Icon for the empty state — honours `config.emptyStateIcon` when provided. */\n public get emptyStateIcon(): string {\n return this.config.emptyStateIcon || 'fa-solid fa-diagram-project';\n }\n\n /** Title for the empty state — distinguishes \"nothing here\" from \"filtered to nothing\". */\n public get emptyStateTitle(): string {\n return this.totalCount === 0\n ? (this.config.emptyStateMessage || 'No entities to display')\n : 'No entities match';\n }\n\n /** Derived — total entities in the input, before any filtering. */\n public totalCount = 0;\n\n /** Derived — the Set of IDs in the focus/hover neighbourhood (null when no highlight active). */\n public highlightSet: Set<string> | null = null;\n\n /** Derived — the single selected entity, if any. */\n public selectedEntity: ERDNode | null = null;\n\n // Panning bookkeeping (not reactive). Public so the template can bind a\n // cursor attribute to it; treat as internal state.\n public panning = false;\n private panStart: { x: number; y: number } | null = null;\n /** Raw mousedown coords — used to compute drag distance for the\n * pan-vs-click threshold. */\n private dragOrigin: { clientX: number; clientY: number } | null = null;\n /** True once movement crossed the drag threshold — used to suppress\n * the synthetic click that follows the mouseup. */\n private dragMoved = false;\n /** Pixels of movement before mousedown is treated as a drag. */\n private static readonly DRAG_THRESHOLD = 4;\n /** Bound window listeners — kept on the instance so we can detach. */\n private boundWindowMove?: (e: MouseEvent) => void;\n private boundWindowUp?: (e: MouseEvent) => void;\n\n private resizeObserver?: ResizeObserver;\n\n @HostBinding('class.erd-root') readonly rootClass = true;\n\n // ─── LIFECYCLE ────────────────────────────────────────────────────────\n\n public ngOnChanges(changes: SimpleChanges): void {\n const nodesChanged = !!changes['nodes'];\n // Compare config by the fields we actually use — consumers that bind\n // an inline `[config]=\"{...}\"` object literal get a new reference\n // every CD cycle, so a naive `changes['config']` check would\n // recompute + refit endlessly.\n const configChanged = this.configAffectsLayout(\n changes['config']?.previousValue as ERDConfig | undefined,\n changes['config']?.currentValue as ERDConfig | undefined,\n );\n if (nodesChanged || configChanged) {\n if (nodesChanged) {\n this.activeSchemas = null;\n this.expandedNodeIds = new Set();\n this.hoverNodeId = null;\n }\n // Honour `config.layoutAlgorithm` on first arrival; runtime\n // changes happen via `setLayoutAlgorithm`.\n if (this.config.layoutAlgorithm === 'dagre') this.activeLayout = 'dagre';\n else if (this.config.layoutAlgorithm === 'schema-grid') this.activeLayout = 'schema-grid';\n this.recompute();\n // Fit-to-view once the DOM has the new canvas dimensions.\n queueMicrotask(() => this.fitToView());\n }\n if (changes['focusNodeId']) {\n this.updateHighlightSet();\n this.cdr.markForCheck();\n }\n }\n\n /** True iff any config field that influences the cached layout changed. */\n private configAffectsLayout(prev: ERDConfig | undefined, curr: ERDConfig | undefined): boolean {\n if (prev === curr) return false;\n return (\n (prev?.nodeWidth ?? null) !== (curr?.nodeWidth ?? null) ||\n (prev?.fieldHeight ?? null) !== (curr?.fieldHeight ?? null) ||\n (prev?.showAllFields ?? null) !== (curr?.showAllFields ?? null) ||\n (prev?.showSchemaBands ?? null) !== (curr?.showSchemaBands ?? null) ||\n (prev?.crowsFoot ?? null) !== (curr?.crowsFoot ?? null) ||\n (prev?.maxFitZoom ?? null) !== (curr?.maxFitZoom ?? null) ||\n (prev?.minZoom ?? null) !== (curr?.minZoom ?? null) ||\n (prev?.maxZoom ?? null) !== (curr?.maxZoom ?? null)\n );\n }\n\n public ngAfterViewInit(): void {\n this.resizeObserver = this.watchResize();\n this.recompute();\n queueMicrotask(() => this.fitToView());\n }\n\n public ngOnDestroy(): void {\n this.resizeObserver?.disconnect();\n // Detach any pan listeners still bound from an in-progress drag.\n if (this.boundWindowMove) window.removeEventListener('mousemove', this.boundWindowMove);\n if (this.boundWindowUp) window.removeEventListener('mouseup', this.boundWindowUp);\n }\n\n // ─── RECOMPUTATION ────────────────────────────────────────────────────\n\n /** Rebuild the layout + derived view-model from current inputs/state. */\n private recompute(): void {\n this.totalCount = this.nodes.length;\n\n const filteredBySchema = this.activeSchemas\n ? this.nodes.filter(n => this.activeSchemas!.has(n.schemaName || '_'))\n : this.nodes;\n\n const q = this.searchQuery.trim().toLowerCase();\n const filtered = q\n ? filteredBySchema.filter(n =>\n n.name.toLowerCase().includes(q) ||\n (n.schemaName?.toLowerCase().includes(q) ?? false) ||\n n.fields.some(f => f.name.toLowerCase().includes(q)))\n : filteredBySchema;\n\n this.visibleCount = filtered.length;\n\n const commonOpts = {\n nodeWidth: this.config.nodeWidth ?? 220,\n fieldHeight: this.config.fieldHeight ?? 22,\n expandedNodeIds: this.expandedNodeIds,\n showAllFields: this.config.showAllFields ?? false,\n };\n\n this.layout = this.activeLayout === 'dagre'\n ? computeDagreLayout(filtered, {\n ...commonOpts,\n rankDir: this.config.dagreConfig?.rankDir ?? 'LR',\n nodeSep: this.config.dagreConfig?.nodeSep,\n rankSep: this.config.dagreConfig?.rankSep,\n })\n : computeErdLayout(filtered, commonOpts);\n\n this.schemaChips = this.buildSchemaChips();\n this.updateHighlightSet();\n this.updateSelectedEntity();\n this.cdr.markForCheck();\n }\n\n /**\n * Switch between the schema-grid and dagre hierarchical layouts at\n * runtime. Emits a state change so the consumer can persist the\n * user's preference (via `userStateChange` on `mj-erd-composite`).\n *\n * Also clears the current focus/selection — switching layouts moves\n * cards to entirely new positions, so the previously-selected entity\n * would otherwise stay highlighted in a different spot with the side\n * panel still open, which is jarring. A clean slate is better.\n */\n public setLayoutAlgorithm(algo: 'schema-grid' | 'dagre'): void {\n if (this.activeLayout === algo) return;\n this.activeLayout = algo;\n\n const hadSelection = !!(this.focusNodeId || this.selectedNodeId);\n this.focusNodeId = null;\n this.selectedNodeId = null;\n this.hoverNodeId = null;\n this.updateHighlightSet();\n this.updateSelectedEntity();\n if (hadSelection) this.nodeDeselected.emit();\n\n this.recompute();\n queueMicrotask(() => this.fitToView());\n this.stateChange.emit(this.getState());\n }\n\n private buildSchemaChips(): SchemaChip[] {\n const counts = new Map<string, number>();\n for (const n of this.nodes) {\n const s = n.schemaName || '_';\n counts.set(s, (counts.get(s) ?? 0) + 1);\n }\n return [...counts.entries()]\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([name, count]) => ({\n name,\n count,\n active: this.activeSchemas ? this.activeSchemas.has(name) : true,\n }));\n }\n\n private updateHighlightSet(): void {\n const id = this.focusNodeId ?? this.hoverNodeId;\n this.highlightSet = id ? getNeighbors(this.nodes, id) : null;\n }\n\n private updateSelectedEntity(): void {\n const id = this.focusNodeId ?? this.selectedNodeId;\n this.selectedEntity = id ? this.nodes.find(n => n.id === id) ?? null : null;\n }\n\n private watchResize(): ResizeObserver {\n const observer = new ResizeObserver(() => this.fitToView());\n observer.observe(this.host.nativeElement);\n return observer;\n }\n\n // ─── PAN / ZOOM / FIT ────────────────────────────────────────────────\n\n /**\n * Mousedown anywhere on the SVG (background OR a node card). We\n * arm a potential pan and attach window-level move/up listeners so\n * the drag continues even if the cursor leaves the canvas (passes\n * over the focus card, scrollbars, the chrome, etc.).\n *\n * The actual `panning = true` flip happens in the move handler once\n * the cursor crosses `DRAG_THRESHOLD` — that way short clicks still\n * register as clicks on cards (no accidental selection-toggle from\n * a tiny mouse jitter).\n */\n public onBackgroundMouseDown(e: MouseEvent): void {\n if (e.button !== 0) return;\n this.dragOrigin = { clientX: e.clientX, clientY: e.clientY };\n this.dragMoved = false;\n this.panStart = { x: e.clientX - this.transform.x, y: e.clientY - this.transform.y };\n\n this.boundWindowMove = (ev: MouseEvent) => this.onWindowMouseMove(ev);\n this.boundWindowUp = (ev: MouseEvent) => this.onWindowMouseUp(ev);\n window.addEventListener('mousemove', this.boundWindowMove);\n window.addEventListener('mouseup', this.boundWindowUp);\n }\n\n private onWindowMouseMove(e: MouseEvent): void {\n if (!this.dragOrigin || !this.panStart) return;\n\n if (!this.panning) {\n const dx = e.clientX - this.dragOrigin.clientX;\n const dy = e.clientY - this.dragOrigin.clientY;\n if (Math.hypot(dx, dy) < ERDDiagramComponent.DRAG_THRESHOLD) return;\n this.panning = true;\n this.dragMoved = true;\n }\n\n this.transform = {\n ...this.transform,\n x: e.clientX - this.panStart.x,\n y: e.clientY - this.panStart.y,\n };\n this.emitZoom();\n this.cdr.markForCheck();\n }\n\n private onWindowMouseUp(_e: MouseEvent): void {\n // If a drag actually happened, swallow the synthetic click that\n // browsers fire on mouseup so it doesn't reach the node click\n // handler and toggle the focus. We use capture phase + once so\n // we only catch the immediate next click from this mouse-up.\n if (this.dragMoved) {\n const swallow = (ev: MouseEvent) => {\n ev.stopPropagation();\n ev.preventDefault();\n };\n window.addEventListener('click', swallow, { capture: true, once: true });\n }\n\n this.panning = false;\n this.panStart = null;\n this.dragOrigin = null;\n this.dragMoved = false;\n\n if (this.boundWindowMove) {\n window.removeEventListener('mousemove', this.boundWindowMove);\n this.boundWindowMove = undefined;\n }\n if (this.boundWindowUp) {\n window.removeEventListener('mouseup', this.boundWindowUp);\n this.boundWindowUp = undefined;\n }\n }\n\n public onWheel(e: WheelEvent): void {\n if (this.config.enableZoom === false) return;\n e.preventDefault();\n const svg = this.canvasRef?.nativeElement;\n if (!svg) return;\n const rect = svg.getBoundingClientRect();\n const mx = e.clientX - rect.left;\n const my = e.clientY - rect.top;\n const delta = -e.deltaY * 0.001;\n const minZoom = this.config.minZoom ?? 0.15;\n const maxZoom = this.config.maxZoom ?? 2.5;\n const newK = Math.max(minZoom, Math.min(maxZoom, this.transform.k * (1 + delta)));\n const ratio = newK / this.transform.k;\n this.transform = {\n k: newK,\n x: mx - (mx - this.transform.x) * ratio,\n y: my - (my - this.transform.y) * ratio,\n };\n this.emitZoom();\n this.cdr.markForCheck();\n }\n\n public zoomBy(factor: number): void {\n const svg = this.canvasRef?.nativeElement;\n if (!svg) return;\n const rect = svg.getBoundingClientRect();\n const mx = rect.width / 2;\n const my = rect.height / 2;\n const minZoom = this.config.minZoom ?? 0.15;\n const maxZoom = this.config.maxZoom ?? 2.5;\n const newK = Math.max(minZoom, Math.min(maxZoom, this.transform.k * factor));\n const ratio = newK / this.transform.k;\n this.transform = {\n k: newK,\n x: mx - (mx - this.transform.x) * ratio,\n y: my - (my - this.transform.y) * ratio,\n };\n this.emitZoom();\n this.cdr.markForCheck();\n }\n\n public fitToView(): void {\n const svg = this.canvasRef?.nativeElement;\n if (!svg) return;\n const rect = svg.getBoundingClientRect();\n if (rect.width === 0 || rect.height === 0 || this.layout.totalWidth === 0) return;\n\n const padding = 60;\n // Allow fit to scale UP for small diagrams (e.g. the Database Designer\n // wizard preview, where a single entity + a couple of satellites\n // would otherwise look lost in the pane). Consumers can override via\n // `config.maxFitZoom`. Default 2.5x: a 220px card becomes ~550px,\n // which comfortably fills a typical preview pane without looking\n // cartoonish (13px text → ~33px, still a readable ceiling).\n const maxFit = this.config.maxFitZoom ?? 2.5;\n const idealK = Math.min(\n (rect.width - padding * 2) / this.layout.totalWidth,\n (rect.height - padding * 2) / this.layout.totalHeight,\n maxFit,\n );\n\n // Clamp the fit zoom so cards stay legible. On very large schemas\n // (hundreds of entities) fit-to-view would otherwise shrink each card\n // to a few pixels wide. We'd rather show part of the canvas at a\n // readable zoom and let the user pan to see the rest.\n const minZoom = this.config.minZoom ?? 0.35;\n const k = Math.max(idealK, minZoom);\n\n // Center horizontally only if the canvas fits; otherwise anchor at left\n // so the user starts at the first schema band instead of the middle.\n const canvasFitsX = this.layout.totalWidth * k <= rect.width - padding * 2;\n const canvasFitsY = this.layout.totalHeight * k <= rect.height - padding * 2;\n\n const newX = canvasFitsX ? (rect.width - this.layout.totalWidth * k) / 2 : padding;\n const newY = canvasFitsY ? (rect.height - this.layout.totalHeight * k) / 2 : padding;\n\n // Idempotent guard. If the computed transform is effectively identical\n // to the current one, bail out without reassigning or calling\n // markForCheck. Without this, a consumer that passes an inline\n // `[config]=\"{...}\"` object literal re-triggers ngOnChanges on every\n // change-detection tick, producing an infinite fitToView → markForCheck\n // → CD → ngOnChanges → fitToView loop (NG0103).\n const TOL = 0.001;\n if (\n Math.abs(this.transform.k - k) < TOL &&\n Math.abs(this.transform.x - newX) < 0.5 &&\n Math.abs(this.transform.y - newY) < 0.5\n ) {\n return;\n }\n\n this.transform = { k, x: newX, y: newY };\n this.emitZoom();\n this.layoutComplete.emit();\n this.cdr.markForCheck();\n }\n\n private centerOn(nodeId: string): void {\n const n = this.layout.nodes.find(x => x.id === nodeId);\n const svg = this.canvasRef?.nativeElement;\n if (!n || !svg) return;\n const rect = svg.getBoundingClientRect();\n const k = Math.max(this.transform.k, 0.9);\n this.transform = {\n k,\n x: rect.width / 2 - (n.x + n.width / 2) * k,\n y: rect.height / 2 - (n.y + n.height / 2) * k,\n };\n this.emitZoom();\n // External callers (e.g. zoomToNode invoked from the side panel)\n // need CD to pick up the new transform — onNodeClick used to do\n // this itself but external pathways were silently no-op'ing.\n this.cdr.markForCheck();\n }\n\n private emitZoom(): void {\n this.zoomChange.emit({\n zoomLevel: this.transform.k,\n translateX: this.transform.x,\n translateY: this.transform.y,\n });\n }\n\n // ─── NODE INTERACTIONS ───────────────────────────────────────────────\n\n public onNodeClick(node: LaidOutNode, e: MouseEvent): void {\n e.stopPropagation();\n const event: ERDNodeClickEvent = { node, mouseEvent: e, cancel: false };\n this.nodeClick.emit(event);\n if (event.cancel) return;\n\n if (this.focusNodeId === node.id) {\n // Toggle off — deselect.\n this.focusNodeId = null;\n this.selectedNodeId = null;\n this.nodeDeselected.emit();\n } else {\n this.focusNodeId = node.id;\n this.selectedNodeId = node.id;\n this.nodeSelected.emit(node);\n this.centerOn(node.id);\n }\n this.updateHighlightSet();\n this.updateSelectedEntity();\n this.cdr.markForCheck();\n }\n\n public onNodeMouseEnter(node: LaidOutNode, e: MouseEvent): void {\n this.hoverNodeId = node.id;\n this.updateHighlightSet();\n const related = this.nodes.filter(n => this.highlightSet?.has(n.id) && n.id !== node.id);\n this.nodeHover.emit({\n node, mouseEvent: e, relatedNodes: related,\n position: { x: e.clientX, y: e.clientY },\n });\n this.cdr.markForCheck();\n }\n\n public onNodeMouseLeave(node: LaidOutNode): void {\n this.hoverNodeId = null;\n this.updateHighlightSet();\n this.nodeHoverEnd.emit(node);\n this.cdr.markForCheck();\n }\n\n public onToggleExpand(nodeId: string, e: Event): void {\n e.stopPropagation();\n if (this.expandedNodeIds.has(nodeId)) this.expandedNodeIds.delete(nodeId);\n else this.expandedNodeIds.add(nodeId);\n // New Set reference so @for trackBy treats it as changed.\n this.expandedNodeIds = new Set(this.expandedNodeIds);\n this.recompute();\n }\n\n // ─── CHROME INTERACTIONS ─────────────────────────────────────────────\n\n public onSearchChange(value: string): void {\n this.searchQuery = value;\n this.recompute();\n }\n\n public onClearSearch(): void {\n this.searchQuery = '';\n this.recompute();\n }\n\n public onSchemaChipToggle(schemaName: string): void {\n const current = this.activeSchemas ?? new Set(this.schemaChips.map(c => c.name));\n const next = new Set(current);\n if (next.has(schemaName)) next.delete(schemaName);\n else next.add(schemaName);\n this.activeSchemas = next.size === this.schemaChips.length ? null : next;\n this.recompute();\n }\n\n public onRequestRefresh(): void {\n this.refreshRequested.emit();\n }\n\n // ─── DERIVED DATA FOR TEMPLATE ───────────────────────────────────────\n\n /** Path string for an edge — uses the orthogonal polyline from layout. */\n public edgePath(edge: LaidOutEdge): string {\n return pointsToPath(edge.points);\n }\n\n /**\n * Whether to render FK field labels along edges. Defaults to ON in\n * both layouts — the zoom-gate (>=0.55x) keeps the labels off when\n * the user is zoomed out far enough to see hundreds of entities, so\n * \"noise on dense views\" isn't a real concern. Consumers can still\n * force off via `config.showRelationshipLabels: false`.\n */\n public get showEdgeLabels(): boolean {\n const enabled = this.config.showRelationshipLabels ?? true;\n if (!enabled) return false;\n return this.transform.k >= 0.55;\n }\n\n /**\n * Pick a point along the edge polyline for a label and approximate\n * its width. Returns null for self-loops (no good place to put text).\n * Uses the longest horizontal segment when one exists; falls back to\n * the segment midpoint otherwise.\n */\n public edgeLabelPosition(edge: LaidOutEdge): { x: number; y: number; w: number } | null {\n if (edge.selfReference) return null;\n const pts = edge.points;\n if (pts.length < 2) return null;\n\n // Find the longest horizontal segment so the label sits on a\n // straight portion, not over a corner.\n let bestIdx = 0;\n let bestLen = 0;\n for (let i = 0; i < pts.length - 1; i++) {\n const [x1, y1] = pts[i];\n const [x2, y2] = pts[i + 1];\n if (Math.abs(y2 - y1) > 0.5) continue; // skip vertical segs\n const len = Math.abs(x2 - x1);\n if (len > bestLen) { bestLen = len; bestIdx = i; }\n }\n\n const [x1, y1] = pts[bestIdx];\n const [x2, y2] = pts[bestIdx + 1];\n const x = (x1 + x2) / 2;\n const y = (y1 + y2) / 2;\n\n // 6.5 px per char is a good approximation for the 11px mono we\n // use for labels — only used to size the background rect.\n const w = Math.max(20, edge.sourceField.name.length * 6.5);\n return { x, y, w };\n }\n\n /** Whether a node should appear dimmed (highlight mode active, node not in set). */\n public isDimmed(nodeId: string): boolean {\n return !!this.highlightSet && !this.highlightSet.has(nodeId);\n }\n\n /** Whether a node is the current focus (strong border). */\n public isFocus(nodeId: string): boolean {\n return this.focusNodeId === nodeId;\n }\n\n /** Whether a node is a 1-hop neighbour of the focus (medium border). */\n public isNeighbour(nodeId: string): boolean {\n return !!this.highlightSet && this.highlightSet.has(nodeId) && !this.isFocus(nodeId);\n }\n\n /** Whether an edge is part of the active highlight subgraph. */\n public isEdgeActive(edge: LaidOutEdge): boolean {\n return !!this.highlightSet && this.highlightSet.has(edge.sourceId) && this.highlightSet.has(edge.targetId);\n }\n\n /** Whether an edge should appear dimmed. */\n public isEdgeDimmed(edge: LaidOutEdge): boolean {\n return !!this.highlightSet && !this.isEdgeActive(edge);\n }\n\n /** Zoom percentage string for the toolbar readout. */\n public get zoomPercent(): string {\n return Math.round(this.transform.k * 100) + '%';\n }\n\n /** Short friendly row-count string (e.g. 1248 → \"1.2k\"). */\n public formatCount(n: number | undefined): string {\n if (n == null) return '';\n if (n >= 1000) return (n / 1000).toFixed(n >= 10000 ? 0 : 1) + 'k';\n return n.toString();\n }\n\n /** Number of PK fields — handy aggregate (kept for external API parity). */\n public pkCount(entity: ERDNode): number {\n return entity.fields.filter(f => f.isPrimaryKey).length;\n }\n\n /** Number of FK fields — handy aggregate (kept for external API parity). */\n public fkCount(entity: ERDNode): number {\n return entity.fields.filter(f => !!f.relatedNodeId).length;\n }\n\n // ─── LEGACY API SHIMS ────────────────────────────────────────────────\n // Kept so existing consumers (mj-entity-erd wrapper, admin ERD dashboard)\n // continue to compile and work. The new implementation doesn't need\n // most of these, but we preserve the shape.\n\n public zoomIn(): void { this.zoomBy(1.2); }\n public zoomOut(): void { this.zoomBy(0.83); }\n public resetZoom(): void { this.fitToView(); }\n public zoomToFit(_padding?: number): void { this.fitToView(); }\n public zoomToNode(nodeId: string, _scale?: number): void { this.centerOn(nodeId); }\n public triggerResize(): void { this.fitToView(); }\n\n public refresh(): void {\n this.recompute();\n queueMicrotask(() => this.fitToView());\n }\n\n public getState(): ERDState {\n return {\n selectedNodeId: this.selectedNodeId,\n highlightedNodeIds: [...this.highlightedNodeIds],\n zoomLevel: this.transform.k,\n translateX: this.transform.x,\n translateY: this.transform.y,\n focusNodeId: this.focusNodeId,\n focusDepth: this.focusDepth,\n nodePositions: {},\n layoutAlgorithm: this.activeLayout,\n };\n }\n\n public setState(state: Partial<ERDState>, _restorePositions?: boolean): void {\n if (state.selectedNodeId !== undefined) this.selectedNodeId = state.selectedNodeId;\n if (state.highlightedNodeIds !== undefined) this.highlightedNodeIds = [...state.highlightedNodeIds];\n if (state.focusNodeId !== undefined) this.focusNodeId = state.focusNodeId;\n if (state.focusDepth !== undefined) this.focusDepth = state.focusDepth;\n if (state.zoomLevel !== undefined || state.translateX !== undefined || state.translateY !== undefined) {\n this.transform = {\n k: state.zoomLevel ?? this.transform.k,\n x: state.translateX ?? this.transform.x,\n y: state.translateY ?? this.transform.y,\n };\n }\n if (state.layoutAlgorithm && state.layoutAlgorithm !== this.activeLayout) {\n this.activeLayout = state.layoutAlgorithm;\n this.recompute();\n }\n this.updateHighlightSet();\n this.updateSelectedEntity();\n this.cdr.markForCheck();\n }\n\n public exportAsSVG(): string {\n const svg = this.canvasRef?.nativeElement;\n if (!svg) return '';\n return new XMLSerializer().serializeToString(svg);\n }\n\n // ─── TRACK-BYs ───────────────────────────────────────────────────────\n\n public trackByBand = (_: number, b: LaidOutBand) => b.schemaName;\n public trackByEdge = (_: number, e: LaidOutEdge) => e.id;\n public trackByNode = (_: number, n: LaidOutNode) => n.id;\n public trackByField = (_: number, f: ERDField) => f.id || f.name;\n public trackByChip = (_: number, c: SchemaChip) => c.name;\n}\n","<!-- ── CHROME ──────────────────────────────────────────────────────────── -->\n@if (showHeader) {\n <header class=\"erd-chrome\">\n <div class=\"erd-title-group\">\n <div class=\"erd-title\">{{ headerTitle }}</div>\n <div class=\"erd-subtitle\">\n <span class=\"erd-count-pill\">{{ visibleCount }}</span>\n <span class=\"erd-count-label\">of {{ totalCount }} entities</span>\n <span class=\"erd-dot\">·</span>\n <span>{{ layout.edges.length }} relationships</span>\n </div>\n </div>\n\n <label class=\"erd-search\">\n <i class=\"fa-solid fa-magnifying-glass\" aria-hidden=\"true\"></i>\n <input\n type=\"text\"\n [value]=\"searchQuery\"\n (input)=\"onSearchChange($any($event.target).value)\"\n placeholder=\"Search entities, schemas, fields…\"\n spellcheck=\"false\"\n aria-label=\"Search entities\" />\n @if (searchQuery) {\n <button type=\"button\" class=\"erd-search-clear\" (click)=\"onClearSearch()\" aria-label=\"Clear search\">×</button>\n }\n </label>\n\n <div class=\"erd-chrome-right\">\n @if (schemaChips.length > 1) {\n <div class=\"erd-schema-chips\" role=\"group\" aria-label=\"Filter by schema\">\n @for (chip of schemaChips; track trackByChip($index, chip)) {\n <button\n type=\"button\"\n class=\"erd-chip\"\n [class.active]=\"chip.active\"\n (click)=\"onSchemaChipToggle(chip.name)\"\n [attr.aria-pressed]=\"chip.active\">\n <span class=\"erd-chip-label\">{{ chip.name }}</span>\n <span class=\"erd-chip-count\">{{ chip.count }}</span>\n </button>\n }\n </div>\n }\n\n <div class=\"erd-toolbar\" role=\"group\" aria-label=\"Layout mode\">\n <button\n type=\"button\"\n [class.active]=\"activeLayout === 'schema-grid'\"\n (click)=\"setLayoutAlgorithm('schema-grid')\"\n title=\"Schema grid — grouped by schema, predictable\"\n aria-label=\"Schema-grid layout\">\n <i class=\"fa-solid fa-table-cells\" aria-hidden=\"true\"></i>\n </button>\n <button\n type=\"button\"\n [class.active]=\"activeLayout === 'dagre'\"\n (click)=\"setLayoutAlgorithm('dagre')\"\n title=\"Hierarchical — classic ERD, relationship-driven\"\n aria-label=\"Hierarchical layout\">\n <i class=\"fa-solid fa-sitemap\" aria-hidden=\"true\"></i>\n </button>\n </div>\n\n <div class=\"erd-toolbar\" role=\"group\" aria-label=\"Zoom controls\">\n <button type=\"button\" (click)=\"zoomBy(1.2)\" title=\"Zoom in\" aria-label=\"Zoom in\">\n <i class=\"fa-solid fa-magnifying-glass-plus\" aria-hidden=\"true\"></i>\n </button>\n <button type=\"button\" (click)=\"zoomBy(0.83)\" title=\"Zoom out\" aria-label=\"Zoom out\">\n <i class=\"fa-solid fa-magnifying-glass-minus\" aria-hidden=\"true\"></i>\n </button>\n <button type=\"button\" (click)=\"fitToView()\" title=\"Fit to view\" aria-label=\"Fit to view\">\n <i class=\"fa-solid fa-expand\" aria-hidden=\"true\"></i>\n </button>\n <span class=\"erd-zoom-val\">{{ zoomPercent }}</span>\n </div>\n </div>\n </header>\n}\n\n<!-- ── CANVAS ──────────────────────────────────────────────────────────── -->\n<!-- Pan handling is window-level once mousedown fires (see component) so\n dragging continues even if the cursor leaves the canvas-wrap. -->\n<div class=\"erd-canvas-wrap\">\n\n <svg\n #canvasRef\n class=\"erd-canvas\"\n [attr.data-panning]=\"panning ? 'true' : null\"\n (mousedown)=\"onBackgroundMouseDown($event)\"\n (wheel)=\"onWheel($event)\">\n\n <defs>\n <marker id=\"erd-arrow\" viewBox=\"0 0 10 10\" refX=\"9\" refY=\"5\" markerWidth=\"7\" markerHeight=\"7\" orient=\"auto\">\n <path d=\"M 0 0 L 10 5 L 0 10 z\" class=\"erd-marker\" />\n </marker>\n <marker id=\"erd-arrow-active\" viewBox=\"0 0 10 10\" refX=\"9\" refY=\"5\" markerWidth=\"7\" markerHeight=\"7\" orient=\"auto\">\n <path d=\"M 0 0 L 10 5 L 0 10 z\" class=\"erd-marker erd-marker-active\" />\n </marker>\n <marker id=\"erd-many\" viewBox=\"-10 -6 14 12\" refX=\"-8\" refY=\"0\" markerWidth=\"14\" markerHeight=\"14\" orient=\"auto\">\n <path d=\"M 0 -5 L -8 0 L 0 5 M -8 0 L 4 0\" class=\"erd-marker-stroke\" />\n </marker>\n <marker id=\"erd-many-active\" viewBox=\"-10 -6 14 12\" refX=\"-8\" refY=\"0\" markerWidth=\"14\" markerHeight=\"14\" orient=\"auto\">\n <path d=\"M 0 -5 L -8 0 L 0 5 M -8 0 L 4 0\" class=\"erd-marker-stroke erd-marker-active\" />\n </marker>\n </defs>\n\n <g [attr.transform]=\"'translate(' + transform.x + ' ' + transform.y + ') scale(' + transform.k + ')'\">\n\n <!-- Schema bands -->\n @if ((config.showSchemaBands ?? true)) {\n @for (band of layout.bands; track trackByBand($index, band)) {\n <g class=\"erd-band\">\n <rect\n [attr.x]=\"band.x\" [attr.y]=\"band.y\"\n [attr.width]=\"band.width\" [attr.height]=\"band.height\"\n rx=\"16\"\n class=\"erd-band-rect\" />\n <text\n [attr.x]=\"band.x + band.width / 2\"\n [attr.y]=\"band.y + 32\"\n text-anchor=\"middle\"\n class=\"erd-band-title\">\n {{ band.schemaName }}\n </text>\n </g>\n }\n }\n\n <!-- Edges -->\n <g class=\"erd-edges\">\n @for (edge of layout.edges; track trackByEdge($index, edge)) {\n <path\n [attr.d]=\"edgePath(edge)\"\n fill=\"none\"\n class=\"erd-edge\"\n [class.erd-edge-active]=\"isEdgeActive(edge)\"\n [class.erd-edge-dimmed]=\"isEdgeDimmed(edge)\"\n [attr.marker-start]=\"(config.crowsFoot ?? true) ? (isEdgeActive(edge) ? 'url(#erd-many-active)' : 'url(#erd-many)') : null\"\n [attr.marker-end]=\"isEdgeActive(edge) ? 'url(#erd-arrow-active)' : 'url(#erd-arrow)'\" />\n }\n </g>\n\n <!-- Edge labels — FK field names rendered along edges. Only shown\n when zoom is high enough for the text to be legible, and only\n when config.showRelationshipLabels resolves true. -->\n @if (showEdgeLabels) {\n <g class=\"erd-edge-labels\">\n @for (edge of layout.edges; track trackByEdge($index, edge)) {\n @let pos = edgeLabelPosition(edge);\n @if (pos) {\n <g\n class=\"erd-edge-label\"\n [class.erd-edge-label-active]=\"isEdgeActive(edge)\"\n [class.erd-edge-label-dimmed]=\"isEdgeDimmed(edge)\">\n <rect\n [attr.x]=\"pos.x - pos.w / 2 - 4\"\n [attr.y]=\"pos.y - 8\"\n [attr.width]=\"pos.w + 8\"\n height=\"16\"\n rx=\"3\"\n class=\"erd-edge-label-bg\" />\n <text\n [attr.x]=\"pos.x\"\n [attr.y]=\"pos.y + 4\"\n text-anchor=\"middle\"\n class=\"erd-edge-label-text\">{{ edge.sourceField.name }}</text>\n </g>\n }\n }\n </g>\n }\n\n <!-- Nodes -->\n <g class=\"erd-nodes\">\n @for (node of layout.nodes; track trackByNode($index, node)) {\n <g\n class=\"erd-node\"\n [attr.transform]=\"'translate(' + node.x + ' ' + node.y + ')'\"\n [class.erd-node-focus]=\"isFocus(node.id)\"\n [class.erd-node-neighbour]=\"isNeighbour(node.id)\"\n [class.erd-node-dimmed]=\"isDimmed(node.id)\"\n (click)=\"onNodeClick(node, $event)\"\n (mouseenter)=\"onNodeMouseEnter(node, $event)\"\n (mouseleave)=\"onNodeMouseLeave(node)\">\n\n <!-- Card shadow -->\n <rect class=\"erd-node-shadow\"\n [attr.width]=\"node.width\" [attr.height]=\"node.height\"\n x=\"0\" y=\"2\" rx=\"8\" />\n\n <!-- Card body -->\n <rect class=\"erd-node-body\"\n [attr.width]=\"node.width\" [attr.height]=\"node.height\"\n x=\"0\" y=\"0\" rx=\"8\" />\n\n <!-- Header -->\n <rect class=\"erd-node-header\"\n x=\"0\" y=\"0\"\n [attr.width]=\"node.width\" height=\"36\"\n rx=\"6\" />\n <foreignObject x=\"14\" y=\"8\" [attr.width]=\"node.width - 28\" height=\"22\">\n <div xmlns=\"http://www.w3.org/1999/xhtml\" class=\"erd-node-header-content\">\n <span class=\"erd-node-name\" [title]=\"node.name\">{{ node.name }}</span>\n @if (node.customData && $any(node.customData).rows != null) {\n <span class=\"erd-node-rows\">{{ formatCount($any(node.customData).rows) }}</span>\n }\n </div>\n </foreignObject>\n\n <!-- Separator -->\n <line class=\"erd-node-separator\"\n x1=\"0\" [attr.x2]=\"node.width\" y1=\"36\" y2=\"36\" />\n\n <!-- Fields -->\n @for (field of node.visibleFields; track trackByField($index, field); let i = $index) {\n <foreignObject x=\"0\" [attr.y]=\"36 + i * 22\" [attr.width]=\"node.width\" height=\"22\">\n <div xmlns=\"http://www.w3.org/1999/xhtml\"\n class=\"erd-field-row\"\n [class.erd-field-pk]=\"field.isPrimaryKey\"\n [class.erd-field-fk]=\"!field.isPrimaryKey && field.relatedNodeId\">\n @if (field.isPrimaryKey) {\n <span class=\"erd-field-chip erd-field-chip-pk\">PK</span>\n } @else if (field.relatedNodeId) {\n <span class=\"erd-field-chip erd-field-chip-fk\">FK</span>\n }\n <span class=\"erd-field-name\" [title]=\"field.name\">{{ field.name }}</span>\n @if (field.type) {\n <span class=\"erd-field-type\" [title]=\"field.type\">{{ field.type }}</span>\n }\n </div>\n </foreignObject>\n }\n\n <!-- +N more toggle -->\n @if (node.hasMore) {\n <foreignObject\n x=\"4\"\n [attr.y]=\"36 + node.visibleFields.length * 22 + 6\"\n [attr.width]=\"node.width - 8\"\n height=\"14\"\n (click)=\"onToggleExpand(node.id, $event)\">\n <div xmlns=\"http://www.w3.org/1999/xhtml\" class=\"erd-field-more\">\n + {{ node.fields.length - node.visibleFields.length }} more fields\n </div>\n </foreignObject>\n }\n\n <!-- Outline frame — drawn last so the focus/neighbour stroke\n sits above the header instead of being clipped by it. -->\n <rect class=\"erd-node-frame\"\n [attr.width]=\"node.width\" [attr.height]=\"node.height\"\n x=\"0\" y=\"0\" rx=\"8\" />\n </g>\n }\n </g>\n </g>\n </svg>\n\n <!-- Focus details are rendered by the consumer's side panel\n (mj-entity-details inside mj-erd-composite); the in-canvas\n floating focus card was removed as it duplicated that content. -->\n\n <!-- ── Empty state ─────────────────────────────────────────────────── -->\n @if (visibleCount === 0) {\n <mj-empty-state\n class=\"erd-empty\"\n [Variant]=\"totalCount === 0 ? 'empty' : 'no-results'\"\n [Icon]=\"emptyStateIcon\"\n [Title]=\"emptyStateTitle\"\n [Message]=\"totalCount > 0 ? 'Try adjusting schema filters or clearing search' : ''\" />\n }\n\n <!-- ── Loading overlay ─────────────────────────────────────────────── -->\n @if (isRefreshing) {\n <div class=\"erd-loading-overlay\">\n <div class=\"erd-loading-content\">\n <i class=\"fa-solid fa-circle-notch fa-spin\" aria-hidden=\"true\"></i>\n <span>Loading…</span>\n </div>\n </div>\n }\n</div>\n"]}
|
|
1
|
+
{"version":3,"file":"erd-diagram.component.js","sourceRoot":"","sources":["../../../src/lib/components/erd-diagram.component.ts","../../../src/lib/components/erd-diagram.component.html"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EACH,SAAS,EACT,KAAK,EACL,MAAM,EACN,YAAY,EACZ,UAAU,EACV,SAAS,EACT,WAAW,EACX,uBAAuB,EACvB,iBAAiB,EAKjB,MAAM,GACT,MAAM,eAAe,CAAC;AAkBvB,OAAO,EACH,gBAAgB,EAChB,YAAY,EACZ,YAAY,GAKf,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;;;;;;ICpC5D,kCAAmG;IAApD,uMAAS,sBAAe,KAAC;IAA2B,sBAAC;IAAA,iBAAS;;;;IAQzG,kCAKoC;IADlC,uOAAS,uCAA6B,KAAC;IAEvC,gCAA6B;IAAA,YAAe;IAAA,iBAAO;IACnD,gCAA6B;IAAA,YAAgB;IAC/C,AAD+C,iBAAO,EAC7C;;;IALP,wCAA4B;;IAGC,eAAe;IAAf,kCAAe;IACf,eAAgB;IAAhB,mCAAgB;;;IATnD,+BAAyE;IACvE,uJAUC;IACH,iBAAM;;;IAXJ,cAUC;IAVD,iCAUC;;;;IApCL,AADF,AADF,iCAA2B,cACI,cACJ;IAAA,YAAiB;IAAA,iBAAM;IAE5C,AADF,+BAA0B,eACK;IAAA,YAAkB;IAAA,iBAAO;IACtD,gCAA8B;IAAA,YAA4B;IAAA,iBAAO;IACjE,gCAAsB;IAAA,uBAAC;IAAA,iBAAO;IAC9B,6BAAM;IAAA,aAAuC;IAEjD,AADE,AAD+C,iBAAO,EAChD,EACF;IAEN,kCAA0B;IACxB,yBAA+D;IAC/D,kCAMiC;IAH/B,6LAAS,0CAAyC,KAAC;IAHrD,iBAMiC;IACjC,yGAAmB;IAGrB,iBAAQ;IAER,gCAA8B;IAC5B,sGAA8B;IAiB5B,AADF,gCAA+D,kBAM3B;IAFhC,wLAAS,0BAAmB,aAAa,CAAC,KAAC;IAG3C,yBAA0D;IAC5D,iBAAS;IACT,mCAKmC;IAFjC,wLAAS,0BAAmB,OAAO,CAAC,KAAC;IAGrC,yBAAsD;IAE1D,AADE,iBAAS,EACL;IAGJ,AADF,gCAAiE,kBACkB;IAA3D,wLAAS,cAAO,GAAG,CAAC,KAAC;IACzC,yBAAoE;IACtE,iBAAS;IACT,mCAAoF;IAA9D,wLAAS,cAAO,IAAI,CAAC,KAAC;IAC1C,yBAAqE;IACvE,iBAAS;IACT,mCAAyF;IAAnE,wLAAS,kBAAW,KAAC;IACzC,yBAAqD;IACvD,iBAAS;IACT,iCAA2B;IAAA,aAAiB;IAGlD,AADE,AADE,AAD8C,iBAAO,EAC/C,EACF,EACC;;;IAxEkB,eAAiB;IAAjB,wCAAiB;IAET,eAAkB;IAAlB,yCAAkB;IACjB,eAA4B;IAA5B,4DAA4B;IAEpD,eAAuC;IAAvC,uEAAuC;IAQ7C,eAAqB;IAArB,0CAAqB;IAKvB,cAEC;IAFD,8CAEC;IAID,eAcC;IAdD,yDAcC;IAKG,eAA+C;IAA/C,+DAA+C;IAQ/C,eAAyC;IAAzC,yDAAyC;IAkBhB,gBAAiB;IAAjB,wCAAiB;;;;IAsC1C,6BAAoB;IAClB,2BAI0B;IAC1B,gCAIyB;IACvB,YACF;IACF,AADE,iBAAO,EACL;;;IAXA,cAAiB;;IAKjB,cAAkC;;IAIlC,cACF;IADE,mDACF;;;IAbJ,yIAeC;;;IAfD,kCAeC;;;;IAMC,2BAO0F;;;;IAFxF,AADA,+DAA4C,iDACA;;;;;IAc1C,6BAGqD;IACnD,2BAM8B;IAC9B,gCAI8B;IAAA,YAA2B;IAC3D,AAD2D,iBAAO,EAC9D;;;;;IAbF,AADA,qEAAkD,uDACA;IAEhD,cAAgC;;IAOhC,cAAgB;;IAGY,cAA2B;IAA3B,8CAA2B;;;IAjB7D,kBAAmC;IACnC,+GAAW;;;oBADX,cAAW,8CAAuB,CAAC;IACnC,cAkBC;IAlBD,kCAkBC;;;;IArBL,6BAA2B;IACzB,uIAqBC;IACH,iBAAI;;;IAtBF,cAqBC;IArBD,kCAqBC;;;IAoCO,gCAA4B;IAAA,YAA6C;IAAA,iBAAO;;;;IAApD,cAA6C;IAA7C,kEAA6C;;;IAiBvE,gCAA+C;IAAA,kBAAE;IAAA,iBAAO;;;IAExD,gCAA+C;IAAA,kBAAE;IAAA,iBAAO;;;IAIxD,gCAAkD;IAAA,YAAgB;IAAA,iBAAO;;;IAA5C,sCAAoB;IAAC,cAAgB;IAAhB,oCAAgB;;;;IAZxE,yCAAkF;;IAChF,+BAGuE;IAGnE,AAFF,qGAA0B,+EAEQ;IAGlC,gCAAkD;IAAA,YAAgB;IAAA,iBAAO;IACzE,qGAAkB;IAItB,AADE,iBAAM,EACQ;;;;;;IAZT,cAAyC;IACzC,AADA,sDAAyC,oEACwB;IACpE,cAIC;IAJD,+EAIC;IAC4B,eAAoB;IAApB,sCAAoB;IAAC,cAAgB;IAAhB,oCAAgB;IAClE,cAEC;IAFD,yCAEC;;;;;IAOL,yCAK4C;IAA1C,4PAAS,0CAA+B,KAAC;;IACzC,+BAAiE;IAC/D,YACF;IACF,AADE,iBAAM,EACQ;;;;IAFZ,eACF;IADE,qGACF;;;;;IApEN,6BAQwC;IAAtC,AADA,AADA,6MAAS,oCAAyB,KAAC,0MACrB,yCAA8B,KAAC,oMAC/B,iCAAsB,KAAC;IAarC,AALA,AALA,2BAEuB,eAKA,eAMZ;IACX,yCAAuE;;IAEnE,AADF,+BAA0E,eACxB;IAAA,YAAe;IAAA,iBAAO;IACtE,8FAA6D;IAIjE,AADE,iBAAM,EACQ;;IAGhB,2BACkD;IAGlD,iJAiBC;IAGD,8GAAoB;IAepB,4BAEuB;IACzB,iBAAI;;;;IAxEF,AADA,AADA,6DAAyC,uDACQ,iDACN;;IAOzC,cAAyB;;IAKzB,cAAyB;;IAMzB,cAAyB;;IAEC,cAA8B;;IAE1B,eAAmB;IAAnB,qCAAmB;IAAC,cAAe;IAAf,mCAAe;IAC/D,cAEC;IAFD,kFAEC;IAMI,cAAsB;;IAG/B,cAiBC;IAjBD,qCAiBC;IAGD,eAWC;IAXD,4CAWC;IAKC,cAAyB;;;;IAcnC,qCAKwF;;;IAAtF,AADA,AADA,AADA,0EAAqD,+BAC9B,iCACE,2FAC0D;;;IAMnF,AADF,+BAAiC,cACE;IAC/B,wBAAmE;IACnE,4BAAM;IAAA,6BAAQ;IAElB,AADE,AADgB,iBAAO,EACjB,EACF;;ADlMV,MAAM,OAAO,mBAAmB;IAEX,GAAG,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAC;IAChC,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;IAE3C,yEAAyE;IAEzD,KAAK,GAAc,EAAE,CAAC;IACtB,cAAc,GAAkB,IAAI,CAAC;IACrC,kBAAkB,GAAa,EAAE,CAAC;IAClC,WAAW,GAAkB,IAAI,CAAC;IAClC,UAAU,GAAG,CAAC,CAAC;IACf,YAAY,GAAG,KAAK,CAAC;IACrB,QAAQ,GAAG,KAAK,CAAC;IACjB,MAAM,GAAc,EAAE,CAAC;IACvB,UAAU,GAAG,IAAI,CAAC;IAClB,WAAW,GAAG,6BAA6B,CAAC;IAE5D,yEAAyE;IAExD,SAAS,GAAG,IAAI,YAAY,EAAqB,CAAC;IAClD,eAAe,GAAG,IAAI,YAAY,EAA2B,CAAC;IAC9D,YAAY,GAAG,IAAI,YAAY,EAAW,CAAC;IAC3C,cAAc,GAAG,IAAI,YAAY,EAAQ,CAAC;IAC1C,SAAS,GAAG,IAAI,YAAY,EAAqB,CAAC;IAClD,SAAS,GAAG,IAAI,YAAY,EAAqB,CAAC;IAClD,YAAY,GAAG,IAAI,YAAY,EAAW,CAAC;IAC3C,SAAS,GAAG,IAAI,YAAY,EAAqB,CAAC;IAClD,YAAY,GAAG,IAAI,YAAY,EAAW,CAAC;IAC3C,eAAe,GAAG,IAAI,YAAY,EAA2B,CAAC;IAC9D,eAAe,GAAG,IAAI,YAAY,EAA2B,CAAC;IAC9D,kBAAkB,GAAG,IAAI,YAAY,EAA8B,CAAC;IACpE,aAAa,GAAG,IAAI,YAAY,EAAoB,CAAC;IACrD,WAAW,GAAG,IAAI,YAAY,EAAoB,CAAC;IACnD,UAAU,GAAG,IAAI,YAAY,EAAgB,CAAC;IAC9C,gBAAgB,GAAG,IAAI,YAAY,EAAQ,CAAC;IAC5C,cAAc,GAAG,IAAI,YAAY,EAAQ,CAAC;IAC1C,WAAW,GAAG,IAAI,YAAY,EAAY,CAAC;IAE5D,yEAAyE;IAEtB,SAAS,CAA6B;IAEzF,yEAAyE;IAEzE,0BAA0B;IACnB,SAAS,GAAc,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;IAEnD,uEAAuE;IAChE,aAAa,GAAuB,IAAI,CAAC;IAEhD,2BAA2B;IACpB,WAAW,GAAG,EAAE,CAAC;IAExB,yDAAyD;IAClD,eAAe,GAAG,IAAI,GAAG,EAAU,CAAC;IAE3C,4DAA4D;IACrD,WAAW,GAAkB,IAAI,CAAC;IAEzC,kFAAkF;IAC3E,MAAM,GAAc,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC;IAE9F;;;;OAIG;IACI,YAAY,GAA4B,aAAa,CAAC;IAE7D,+CAA+C;IACxC,WAAW,GAAiB,EAAE,CAAC;IAEtC,sDAAsD;IAC/C,YAAY,GAAG,CAAC,CAAC;IAExB,gFAAgF;IAChF,IAAW,cAAc;QACrB,OAAO,IAAI,CAAC,MAAM,CAAC,cAAc,IAAI,6BAA6B,CAAC;IACvE,CAAC;IAED,2FAA2F;IAC3F,IAAW,eAAe;QACtB,OAAO,IAAI,CAAC,UAAU,KAAK,CAAC;YACxB,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,iBAAiB,IAAI,wBAAwB,CAAC;YAC7D,CAAC,CAAC,mBAAmB,CAAC;IAC9B,CAAC;IAED,mEAAmE;IAC5D,UAAU,GAAG,CAAC,CAAC;IAEtB,iGAAiG;IAC1F,YAAY,GAAuB,IAAI,CAAC;IAE/C,oDAAoD;IAC7C,cAAc,GAAmB,IAAI,CAAC;IAE7C,yEAAyE;IACzE,mDAAmD;IAC5C,OAAO,GAAG,KAAK,CAAC;IACf,QAAQ,GAAoC,IAAI,CAAC;IACzD;kCAC8B;IACtB,UAAU,GAAgD,IAAI,CAAC;IACvE;wDACoD;IAC5C,SAAS,GAAG,KAAK,CAAC;IAC1B,gEAAgE;IACxD,MAAM,CAAU,cAAc,GAAG,CAAC,CAAC;IAC3C,sEAAsE;IAC9D,eAAe,CAA2B;IAC1C,aAAa,CAA2B;IAExC,cAAc,CAAkB;IAEA,SAAS,GAAG,IAAI,CAAC;IAEzD,yEAAyE;IAElE,WAAW,CAAC,OAAsB;QACrC,MAAM,YAAY,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACxC,qEAAqE;QACrE,kEAAkE;QAClE,6DAA6D;QAC7D,+BAA+B;QAC/B,MAAM,aAAa,GAAG,IAAI,CAAC,mBAAmB,CAC1C,OAAO,CAAC,QAAQ,CAAC,EAAE,aAAsC,EACzD,OAAO,CAAC,QAAQ,CAAC,EAAE,YAAqC,CAC3D,CAAC;QACF,IAAI,YAAY,IAAI,aAAa,EAAE,CAAC;YAChC,IAAI,YAAY,EAAE,CAAC;gBACf,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;gBAC1B,IAAI,CAAC,eAAe,GAAG,IAAI,GAAG,EAAE,CAAC;gBACjC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;YAC5B,CAAC;YACD,4DAA4D;YAC5D,2CAA2C;YAC3C,IAAI,IAAI,CAAC,MAAM,CAAC,eAAe,KAAK,OAAO;gBAAE,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC;iBACpE,IAAI,IAAI,CAAC,MAAM,CAAC,eAAe,KAAK,aAAa;gBAAE,IAAI,CAAC,YAAY,GAAG,aAAa,CAAC;YAC1F,IAAI,CAAC,SAAS,EAAE,CAAC;YACjB,0DAA0D;YAC1D,cAAc,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;QAC3C,CAAC;QACD,IAAI,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC1B,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAC5B,CAAC;IACL,CAAC;IAED,2EAA2E;IACnE,mBAAmB,CAAC,IAA2B,EAAE,IAA2B;QAChF,IAAI,IAAI,KAAK,IAAI;YAAE,OAAO,KAAK,CAAC;QAChC,OAAO,CACH,CAAC,IAAI,EAAE,SAAS,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,IAAI,IAAI,CAAC;YACvD,CAAC,IAAI,EAAE,WAAW,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,WAAW,IAAI,IAAI,CAAC;YAC3D,CAAC,IAAI,EAAE,aAAa,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,aAAa,IAAI,IAAI,CAAC;YAC/D,CAAC,IAAI,EAAE,eAAe,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,eAAe,IAAI,IAAI,CAAC;YACnE,CAAC,IAAI,EAAE,SAAS,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,IAAI,IAAI,CAAC;YACvD,CAAC,IAAI,EAAE,UAAU,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,UAAU,IAAI,IAAI,CAAC;YACzD,CAAC,IAAI,EAAE,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,IAAI,IAAI,CAAC;YACnD,CAAC,IAAI,EAAE,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,IAAI,IAAI,CAAC,CACtD,CAAC;IACN,CAAC;IAEM,eAAe;QAClB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QACzC,IAAI,CAAC,SAAS,EAAE,CAAC;QACjB,cAAc,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;IAC3C,CAAC;IAEM,WAAW;QACd,IAAI,CAAC,cAAc,EAAE,UAAU,EAAE,CAAC;QAClC,iEAAiE;QACjE,IAAI,IAAI,CAAC,eAAe;YAAE,MAAM,CAAC,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;QACxF,IAAI,IAAI,CAAC,aAAa;YAAE,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;IACtF,CAAC;IAED,yEAAyE;IAEzE,yEAAyE;IACjE,SAAS;QACb,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;QAEpC,MAAM,gBAAgB,GAAG,IAAI,CAAC,aAAa;YACvC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,aAAc,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,IAAI,GAAG,CAAC,CAAC;YACtE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;QAEjB,MAAM,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAChD,MAAM,QAAQ,GAAG,CAAC;YACd,CAAC,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAC1B,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAChC,CAAC,CAAC,CAAC,UAAU,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC;gBAClD,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;YACzD,CAAC,CAAC,gBAAgB,CAAC;QAEvB,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC;QAEpC,MAAM,UAAU,GAAG;YACf,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,IAAI,GAAG;YACvC,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,EAAE;YAC1C,eAAe,EAAE,IAAI,CAAC,eAAe;YACrC,aAAa,EAAE,IAAI,CAAC,MAAM,CAAC,aAAa,IAAI,KAAK;SACpD,CAAC;QAEF,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,YAAY,KAAK,OAAO;YACvC,CAAC,CAAC,kBAAkB,CAAC,QAAQ,EAAE;gBAC3B,GAAG,UAAU;gBACb,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,IAAI,IAAI;gBACjD,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO;gBACzC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO;aAC5C,CAAC;YACF,CAAC,CAAC,gBAAgB,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QAE7C,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC3C,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC5B,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IAC5B,CAAC;IAED;;;;;;;;;OASG;IACI,kBAAkB,CAAC,IAA6B;QACnD,IAAI,IAAI,CAAC,YAAY,KAAK,IAAI;YAAE,OAAO;QACvC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QAEzB,MAAM,YAAY,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,cAAc,CAAC,CAAC;QACjE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC3B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC5B,IAAI,YAAY;YAAE,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;QAE7C,IAAI,CAAC,SAAS,EAAE,CAAC;QACjB,cAAc,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;QACvC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC3C,CAAC;IAEO,gBAAgB;QACpB,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;QACzC,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACzB,MAAM,CAAC,GAAG,CAAC,CAAC,UAAU,IAAI,GAAG,CAAC;YAC9B,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC5C,CAAC;QACD,OAAO,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;aACvB,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;aACtC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;YACrB,IAAI;YACJ,KAAK;YACL,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI;SACnE,CAAC,CAAC,CAAC;IACZ,CAAC;IAEO,kBAAkB;QACtB,MAAM,EAAE,GAAG,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,WAAW,CAAC;QAChD,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACjE,CAAC;IAEO,oBAAoB;QACxB,MAAM,EAAE,GAAG,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,cAAc,CAAC;QACnD,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IAChF,CAAC;IAEO,WAAW;QACf,MAAM,QAAQ,GAAG,IAAI,cAAc,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;QAC5D,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC1C,OAAO,QAAQ,CAAC;IACpB,CAAC;IAED,wEAAwE;IAExE;;;;;;;;;;OAUG;IACI,qBAAqB,CAAC,CAAa;QACtC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAC3B,IAAI,CAAC,UAAU,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;QAC7D,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACvB,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC;QAErF,IAAI,CAAC,eAAe,GAAG,CAAC,EAAc,EAAE,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;QACtE,IAAI,CAAC,aAAa,GAAG,CAAC,EAAc,EAAE,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;QAClE,MAAM,CAAC,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;QAC3D,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;IAC3D,CAAC;IAEO,iBAAiB,CAAC,CAAa;QACnC,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,QAAQ;YAAE,OAAO;QAE/C,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAChB,MAAM,EAAE,GAAG,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;YAC/C,MAAM,EAAE,GAAG,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;YAC/C,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,mBAAmB,CAAC,cAAc;gBAAE,OAAO;YACpE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YACpB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QAC1B,CAAC;QAED,IAAI,CAAC,SAAS,GAAG;YACb,GAAG,IAAI,CAAC,SAAS;YACjB,CAAC,EAAE,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC9B,CAAC,EAAE,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;SACjC,CAAC;QACF,IAAI,CAAC,QAAQ,EAAE,CAAC;QAChB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IAC5B,CAAC;IAEO,eAAe,CAAC,EAAc;QAClC,gEAAgE;QAChE,8DAA8D;QAC9D,gEAAgE;QAChE,6DAA6D;QAC7D,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACjB,MAAM,OAAO,GAAG,CAAC,EAAc,EAAE,EAAE;gBAC/B,EAAE,CAAC,eAAe,EAAE,CAAC;gBACrB,EAAE,CAAC,cAAc,EAAE,CAAC;YACxB,CAAC,CAAC;YACF,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7E,CAAC;QAED,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACrB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QAEvB,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACvB,MAAM,CAAC,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;YAC9D,IAAI,CAAC,eAAe,GAAG,SAAS,CAAC;QACrC,CAAC;QACD,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACrB,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;YAC1D,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC;QACnC,CAAC;IACL,CAAC;IAEM,OAAO,CAAC,CAAa;QACxB,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,KAAK,KAAK;YAAE,OAAO;QAC7C,CAAC,CAAC,cAAc,EAAE,CAAC;QACnB,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC;QAC1C,IAAI,CAAC,GAAG;YAAE,OAAO;QACjB,MAAM,IAAI,GAAG,GAAG,CAAC,qBAAqB,EAAE,CAAC;QACzC,MAAM,EAAE,GAAG,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC;QACjC,MAAM,EAAE,GAAG,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC;QAChC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,MAAM,GAAG,KAAK,CAAC;QAChC,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,IAAI,CAAC;QAC5C,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,GAAG,CAAC;QAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAClF,MAAM,KAAK,GAAG,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;QACtC,IAAI,CAAC,SAAS,GAAG;YACb,CAAC,EAAE,IAAI;YACP,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,KAAK;YACvC,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,KAAK;SAC1C,CAAC;QACF,IAAI,CAAC,QAAQ,EAAE,CAAC;QAChB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IAC5B,CAAC;IAEM,MAAM,CAAC,MAAc;QACxB,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC;QAC1C,IAAI,CAAC,GAAG;YAAE,OAAO;QACjB,MAAM,IAAI,GAAG,GAAG,CAAC,qBAAqB,EAAE,CAAC;QACzC,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;QAC1B,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;QAC3B,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,IAAI,CAAC;QAC5C,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,GAAG,CAAC;QAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;QAC7E,MAAM,KAAK,GAAG,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;QACtC,IAAI,CAAC,SAAS,GAAG;YACb,CAAC,EAAE,IAAI;YACP,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,KAAK;YACvC,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,KAAK;SAC1C,CAAC;QACF,IAAI,CAAC,QAAQ,EAAE,CAAC;QAChB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IAC5B,CAAC;IAEM,SAAS;QACZ,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC;QAC1C,IAAI,CAAC,GAAG;YAAE,OAAO;QACjB,MAAM,IAAI,GAAG,GAAG,CAAC,qBAAqB,EAAE,CAAC;QACzC,IAAI,IAAI,CAAC,KAAK,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,KAAK,CAAC;YAAE,OAAO;QAElF,MAAM,OAAO,GAAG,EAAE,CAAC;QACnB,uEAAuE;QACvE,iEAAiE;QACjE,sEAAsE;QACtE,mEAAmE;QACnE,iEAAiE;QACjE,4DAA4D;QAC5D,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,GAAG,CAAC;QAC7C,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CACnB,CAAC,IAAI,CAAC,KAAK,GAAG,OAAO,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,EACnD,CAAC,IAAI,CAAC,MAAM,GAAG,OAAO,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,EACrD,MAAM,CACT,CAAC;QAEF,mEAAmE;QACnE,sEAAsE;QACtE,kEAAkE;QAClE,sDAAsD;QACtD,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,IAAI,CAAC;QAC5C,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAEpC,wEAAwE;QACxE,qEAAqE;QACrE,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,GAAG,CAAC,IAAI,IAAI,CAAC,KAAK,GAAG,OAAO,GAAG,CAAC,CAAC;QAC3E,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,GAAG,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,OAAO,GAAG,CAAC,CAAC;QAE7E,MAAM,IAAI,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;QACnF,MAAM,IAAI,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;QAErF,wEAAwE;QACxE,8DAA8D;QAC9D,gEAAgE;QAChE,qEAAqE;QACrE,wEAAwE;QACxE,gDAAgD;QAChD,MAAM,GAAG,GAAG,KAAK,CAAC;QAClB,IACI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG;YACpC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,GAAG;YACvC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,GAAG,EACzC,CAAC;YACC,OAAO;QACX,CAAC;QAED,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC;QACzC,IAAI,CAAC,QAAQ,EAAE,CAAC;QAChB,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;QAC3B,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IAC5B,CAAC;IAEO,QAAQ,CAAC,MAAc;QAC3B,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC;QACvD,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC;QAC1C,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG;YAAE,OAAO;QACvB,MAAM,IAAI,GAAG,GAAG,CAAC,qBAAqB,EAAE,CAAC;QACzC,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAC1C,IAAI,CAAC,SAAS,GAAG;YACb,CAAC;YACD,CAAC,EAAE,IAAI,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC;YAC3C,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC;SAChD,CAAC;QACF,IAAI,CAAC,QAAQ,EAAE,CAAC;QAChB,iEAAiE;QACjE,gEAAgE;QAChE,6DAA6D;QAC7D,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IAC5B,CAAC;IAEO,QAAQ;QACZ,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YACjB,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YAC3B,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YAC5B,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;SAC/B,CAAC,CAAC;IACP,CAAC;IAED,wEAAwE;IAEjE,WAAW,CAAC,IAAiB,EAAE,CAAa;QAC/C,CAAC,CAAC,eAAe,EAAE,CAAC;QACpB,MAAM,KAAK,GAAsB,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;QACxE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3B,IAAI,KAAK,CAAC,MAAM;YAAE,OAAO;QAEzB,IAAI,IAAI,CAAC,WAAW,KAAK,IAAI,CAAC,EAAE,EAAE,CAAC;YAC/B,yBAAyB;YACzB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;YACxB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;YAC3B,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;QAC/B,CAAC;aAAM,CAAC;YACJ,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,EAAE,CAAC;YAC9B,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC7B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC3B,CAAC;QACD,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC5B,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IAC5B,CAAC;IAEM,gBAAgB,CAAC,IAAiB,EAAE,CAAa;QACpD,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,EAAE,CAAC;QAC3B,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC,CAAC;QACzF,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;YAChB,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE,YAAY,EAAE,OAAO;YAC1C,QAAQ,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE;SAC3C,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IAC5B,CAAC;IAEM,gBAAgB,CAAC,IAAiB;QACrC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IAC5B,CAAC;IAEM,cAAc,CAAC,MAAc,EAAE,CAAQ;QAC1C,CAAC,CAAC,eAAe,EAAE,CAAC;QACpB,IAAI,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC;YAAE,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;;YACrE,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACtC,0DAA0D;QAC1D,IAAI,CAAC,eAAe,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QACrD,IAAI,CAAC,SAAS,EAAE,CAAC;IACrB,CAAC;IAED,wEAAwE;IAEjE,cAAc,CAAC,KAAa;QAC/B,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QACzB,IAAI,CAAC,SAAS,EAAE,CAAC;IACrB,CAAC;IAEM,aAAa;QAChB,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;QACtB,IAAI,CAAC,SAAS,EAAE,CAAC;IACrB,CAAC;IAEM,kBAAkB,CAAC,UAAkB;QACxC,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QACjF,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;QAC9B,IAAI,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC;YAAE,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;;YAC7C,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC1B,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;QACzE,IAAI,CAAC,SAAS,EAAE,CAAC;IACrB,CAAC;IAEM,gBAAgB;QACnB,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC;IACjC,CAAC;IAED,wEAAwE;IAExE,0EAA0E;IACnE,QAAQ,CAAC,IAAiB;QAC7B,OAAO,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACrC,CAAC;IAED;;;;;;OAMG;IACH,IAAW,cAAc;QACrB,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,sBAAsB,IAAI,IAAI,CAAC;QAC3D,IAAI,CAAC,OAAO;YAAE,OAAO,KAAK,CAAC;QAC3B,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,IAAI,CAAC;IACpC,CAAC;IAED;;;;;OAKG;IACI,iBAAiB,CAAC,IAAiB;QACtC,IAAI,IAAI,CAAC,aAAa;YAAE,OAAO,IAAI,CAAC;QACpC,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC;QACxB,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;QAEhC,6DAA6D;QAC7D,uCAAuC;QACvC,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;YACxB,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAC5B,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,GAAG;gBAAE,SAAS,CAAC,qBAAqB;YAC5D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;YAC9B,IAAI,GAAG,GAAG,OAAO,EAAE,CAAC;gBAAC,OAAO,GAAG,GAAG,CAAC;gBAAC,OAAO,GAAG,CAAC,CAAC;YAAC,CAAC;QACtD,CAAC;QAED,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC;QAC9B,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;QAClC,MAAM,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;QACxB,MAAM,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;QAExB,+DAA+D;QAC/D,0DAA0D;QAC1D,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC;QAC3D,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;IACvB,CAAC;IAED,oFAAoF;IAC7E,QAAQ,CAAC,MAAc;QAC1B,OAAO,CAAC,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACjE,CAAC;IAED,2DAA2D;IACpD,OAAO,CAAC,MAAc;QACzB,OAAO,IAAI,CAAC,WAAW,KAAK,MAAM,CAAC;IACvC,CAAC;IAED,wEAAwE;IACjE,WAAW,CAAC,MAAc;QAC7B,OAAO,CAAC,CAAC,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACzF,CAAC;IAED,gEAAgE;IACzD,YAAY,CAAC,IAAiB;QACjC,OAAO,CAAC,CAAC,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC/G,CAAC;IAED,4CAA4C;IACrC,YAAY,CAAC,IAAiB;QACjC,OAAO,CAAC,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IAC3D,CAAC;IAED,sDAAsD;IACtD,IAAW,WAAW;QAClB,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;IACpD,CAAC;IAED,4DAA4D;IACrD,WAAW,CAAC,CAAqB;QACpC,IAAI,CAAC,IAAI,IAAI;YAAE,OAAO,EAAE,CAAC;QACzB,IAAI,CAAC,IAAI,IAAI;YAAE,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;QACnE,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC;IACxB,CAAC;IAED,4EAA4E;IACrE,OAAO,CAAC,MAAe;QAC1B,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC;IAC5D,CAAC;IAED,4EAA4E;IACrE,OAAO,CAAC,MAAe;QAC1B,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC;IAC/D,CAAC;IAED,wEAAwE;IACxE,0EAA0E;IAC1E,qEAAqE;IACrE,4CAA4C;IAErC,MAAM,KAAW,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACpC,OAAO,KAAW,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACtC,SAAS,KAAW,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;IACvC,SAAS,CAAC,QAAiB,IAAU,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;IACxD,UAAU,CAAC,MAAc,EAAE,MAAe,IAAU,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC5E,aAAa,KAAW,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;IAE3C,OAAO;QACV,IAAI,CAAC,SAAS,EAAE,CAAC;QACjB,cAAc,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;IAC3C,CAAC;IAEM,QAAQ;QACX,OAAO;YACH,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,kBAAkB,EAAE,CAAC,GAAG,IAAI,CAAC,kBAAkB,CAAC;YAChD,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YAC3B,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YAC5B,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YAC5B,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,aAAa,EAAE,EAAE;YACjB,eAAe,EAAE,IAAI,CAAC,YAAY;SACrC,CAAC;IACN,CAAC;IAEM,QAAQ,CAAC,KAAwB,EAAE,iBAA2B;QACjE,IAAI,KAAK,CAAC,cAAc,KAAK,SAAS;YAAE,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC,cAAc,CAAC;QACnF,IAAI,KAAK,CAAC,kBAAkB,KAAK,SAAS;YAAE,IAAI,CAAC,kBAAkB,GAAG,CAAC,GAAG,KAAK,CAAC,kBAAkB,CAAC,CAAC;QACpG,IAAI,KAAK,CAAC,WAAW,KAAK,SAAS;YAAE,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC;QAC1E,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS;YAAE,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC;QACvE,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YACpG,IAAI,CAAC,SAAS,GAAG;gBACb,CAAC,EAAE,KAAK,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC;gBACtC,CAAC,EAAE,KAAK,CAAC,UAAU,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC;gBACvC,CAAC,EAAE,KAAK,CAAC,UAAU,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC;aAC1C,CAAC;QACN,CAAC;QACD,IAAI,KAAK,CAAC,eAAe,IAAI,KAAK,CAAC,eAAe,KAAK,IAAI,CAAC,YAAY,EAAE,CAAC;YACvE,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,eAAe,CAAC;YAC1C,IAAI,CAAC,SAAS,EAAE,CAAC;QACrB,CAAC;QACD,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC5B,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IAC5B,CAAC;IAEM,WAAW;QACd,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC;QAC1C,IAAI,CAAC,GAAG;YAAE,OAAO,EAAE,CAAC;QACpB,OAAO,IAAI,aAAa,EAAE,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;IACtD,CAAC;IAED,wEAAwE;IAEjE,WAAW,GAAG,CAAC,CAAS,EAAE,CAAc,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC;IAC1D,WAAW,GAAG,CAAC,CAAS,EAAE,CAAc,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAClD,WAAW,GAAG,CAAC,CAAS,EAAE,CAAc,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAClD,YAAY,GAAG,CAAC,CAAS,EAAE,CAAW,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC;IAC1D,WAAW,GAAG,CAAC,CAAS,EAAE,CAAa,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;6GA1sBjD,mBAAmB;6DAAnB,mBAAmB;;;;;;YAAnB,yCAAmB;;YCpFhC,0FAAkB;YAiFlB,8BAA6B;;YAE3B,iCAK4B;YAA1B,AADA,2GAAa,iCAA6B,IAAC,sFAClC,mBAAe,IAAC;YAGvB,AADF,4BAAM,gBACwG;YAC1G,0BAAqD;YACvD,iBAAS;YACT,iCAAmH;YACjH,0BAAuE;YACzE,iBAAS;YACT,iCAAiH;YAC/G,2BAAuE;YACzE,iBAAS;YACT,mCAAwH;YACtH,4BAAyF;YAE7F,AADE,iBAAS,EACJ;YAEP,0BAAsG;YAGpG,6EAAwC;YAoBxC,8BAAqB;YACnB,0GASC;YACH,iBAAI;YAKJ,2FAAsB;YA4BtB,8BAAqB;YACnB,yGA+EC;YAGP,AADE,AADE,iBAAI,EACF,EACA;YAON,mGAA0B;YAU1B,wFAAoB;YAQtB,iBAAM;;YAxRN,yCA4EC;YAUG,eAA6C;;YAmB1C,gBAAkG;;YAGnG,cAiBC;YAjBD,8DAiBC;YAIC,eASC;YATD,+BASC;YAMH,eAyBC;YAzBD,8CAyBC;YAIC,eA+EC;YA/ED,+BA+EC;YAUP,eAOC;YAPD,kDAOC;YAGD,cAOC;YAPD,4CAOC;;;iFDnMU,mBAAmB;cAP/B,SAAS;6BACM,KAAK,YACP,gBAAgB,mBAGT,uBAAuB,CAAC,MAAM;;kBAS9C,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBAIL,MAAM;;kBACN,MAAM;;kBACN,MAAM;;kBACN,MAAM;;kBACN,MAAM;;kBACN,MAAM;;kBACN,MAAM;;kBACN,MAAM;;kBACN,MAAM;;kBACN,MAAM;;kBACN,MAAM;;kBACN,MAAM;;kBACN,MAAM;;kBACN,MAAM;;kBACN,MAAM;;kBACN,MAAM;;kBACN,MAAM;;kBACN,MAAM;;kBAIN,SAAS;mBAAC,WAAW,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;;kBA0ExC,WAAW;mBAAC,gBAAgB;;kFAnHpB,mBAAmB","sourcesContent":["/**\n * @module erd-diagram.component\n * @description\n * Schema-grouped Entity Relationship Diagram. Each schema becomes a rounded\n * rectangular band; entities tile in a grid within the band. Click a node to\n * enter focus mode (neighbours highlighted, everything else dimmed) and see a\n * floating details card with its inbound and outbound FKs.\n *\n * The component is pure Angular + SVG (no D3, no Dagre). Layout is computed\n * by a pure function in `../layout/compute-erd-layout.ts` that is easily\n * unit-tested.\n *\n * Public API is preserved from the previous D3-based implementation so\n * existing consumers (Database Designer wizard preview, admin ERD dashboard,\n * Entity Record view) continue to work without changes.\n */\n\nimport {\n Component,\n Input,\n Output,\n EventEmitter,\n ElementRef,\n ViewChild,\n HostBinding,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n AfterViewInit,\n OnDestroy,\n OnChanges,\n SimpleChanges,\n inject,\n} from '@angular/core';\nimport {\n ERDNode,\n ERDField,\n ERDLink,\n ERDConfig,\n ERDNodeClickEvent,\n ERDNodeDoubleClickEvent,\n ERDLinkClickEvent,\n ERDZoomEvent,\n ERDState,\n ERDNodeHoverEvent,\n ERDLinkHoverEvent,\n ERDNodeContextMenuEvent,\n ERDLinkContextMenuEvent,\n ERDDiagramContextMenuEvent,\n ERDNodeDragEvent,\n} from '../interfaces/erd-types';\nimport {\n computeErdLayout,\n pointsToPath,\n getNeighbors,\n type ErdLayout,\n type LaidOutNode,\n type LaidOutEdge,\n type LaidOutBand,\n} from '../layout/compute-erd-layout';\nimport { computeDagreLayout } from '../layout/compute-dagre-layout';\n\n// ──────────────────────────────────────────────────────────────────────────\n// Internal view-model types\n// ──────────────────────────────────────────────────────────────────────────\n\ninterface SchemaChip {\n name: string;\n count: number;\n active: boolean;\n}\n\n/** 2D transform (pan x/y + zoom scale) for the SVG stage. */\ninterface Transform {\n x: number;\n y: number;\n k: number;\n}\n\n@Component({\n standalone: false,\n selector: 'mj-erd-diagram',\n templateUrl: './erd-diagram.component.html',\n styleUrls: ['./erd-diagram.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class ERDDiagramComponent implements AfterViewInit, OnDestroy, OnChanges {\n\n private readonly cdr = inject(ChangeDetectorRef);\n private readonly host = inject(ElementRef);\n\n // ─── INPUTS ───────────────────────────────────────────────────────────\n\n @Input() public nodes: ERDNode[] = [];\n @Input() public selectedNodeId: string | null = null;\n @Input() public highlightedNodeIds: string[] = [];\n @Input() public focusNodeId: string | null = null;\n @Input() public focusDepth = 1;\n @Input() public isRefreshing = false;\n @Input() public readOnly = false;\n @Input() public config: ERDConfig = {};\n @Input() public showHeader = true;\n @Input() public headerTitle = 'Entity Relationship Diagram';\n\n // ─── OUTPUTS (preserved from legacy API) ──────────────────────────────\n\n @Output() public nodeClick = new EventEmitter<ERDNodeClickEvent>();\n @Output() public nodeDoubleClick = new EventEmitter<ERDNodeDoubleClickEvent>();\n @Output() public nodeSelected = new EventEmitter<ERDNode>();\n @Output() public nodeDeselected = new EventEmitter<void>();\n @Output() public linkClick = new EventEmitter<ERDLinkClickEvent>();\n @Output() public nodeHover = new EventEmitter<ERDNodeHoverEvent>();\n @Output() public nodeHoverEnd = new EventEmitter<ERDNode>();\n @Output() public linkHover = new EventEmitter<ERDLinkHoverEvent>();\n @Output() public linkHoverEnd = new EventEmitter<ERDLink>();\n @Output() public nodeContextMenu = new EventEmitter<ERDNodeContextMenuEvent>();\n @Output() public linkContextMenu = new EventEmitter<ERDLinkContextMenuEvent>();\n @Output() public diagramContextMenu = new EventEmitter<ERDDiagramContextMenuEvent>();\n @Output() public nodeDragStart = new EventEmitter<ERDNodeDragEvent>();\n @Output() public nodeDragEnd = new EventEmitter<ERDNodeDragEvent>();\n @Output() public zoomChange = new EventEmitter<ERDZoomEvent>();\n @Output() public refreshRequested = new EventEmitter<void>();\n @Output() public layoutComplete = new EventEmitter<void>();\n @Output() public stateChange = new EventEmitter<ERDState>();\n\n // ─── VIEW CHILDREN ────────────────────────────────────────────────────\n\n @ViewChild('canvasRef', { static: false }) private canvasRef?: ElementRef<SVGSVGElement>;\n\n // ─── STATE ────────────────────────────────────────────────────────────\n\n /** Current pan + zoom. */\n public transform: Transform = { x: 0, y: 0, k: 1 };\n\n /** Set of schema names the user has filtered IN. Null means \"all\". */\n public activeSchemas: Set<string> | null = null;\n\n /** Search query string. */\n public searchQuery = '';\n\n /** Node IDs the user has clicked \"+N more fields\" on. */\n public expandedNodeIds = new Set<string>();\n\n /** Node currently being hovered (for highlight preview). */\n public hoverNodeId: string | null = null;\n\n /** Cached layout — recomputed when nodes, filter, search or expansion changes. */\n public layout: ErdLayout = { nodes: [], edges: [], bands: [], totalWidth: 0, totalHeight: 0 };\n\n /**\n * Active layout algorithm. Starts from `config.layoutAlgorithm` (default\n * `schema-grid`) but can be toggled at runtime via `setLayoutAlgorithm`.\n * Exposed so the chrome toggle + saved user state can drive it.\n */\n public activeLayout: 'schema-grid' | 'dagre' = 'schema-grid';\n\n /** Derived schema summary for the chip row. */\n public schemaChips: SchemaChip[] = [];\n\n /** Derived — number of entities currently visible. */\n public visibleCount = 0;\n\n /** Icon for the empty state — honours `config.emptyStateIcon` when provided. */\n public get emptyStateIcon(): string {\n return this.config.emptyStateIcon || 'fa-solid fa-diagram-project';\n }\n\n /** Title for the empty state — distinguishes \"nothing here\" from \"filtered to nothing\". */\n public get emptyStateTitle(): string {\n return this.totalCount === 0\n ? (this.config.emptyStateMessage || 'No entities to display')\n : 'No entities match';\n }\n\n /** Derived — total entities in the input, before any filtering. */\n public totalCount = 0;\n\n /** Derived — the Set of IDs in the focus/hover neighbourhood (null when no highlight active). */\n public highlightSet: Set<string> | null = null;\n\n /** Derived — the single selected entity, if any. */\n public selectedEntity: ERDNode | null = null;\n\n // Panning bookkeeping (not reactive). Public so the template can bind a\n // cursor attribute to it; treat as internal state.\n public panning = false;\n private panStart: { x: number; y: number } | null = null;\n /** Raw mousedown coords — used to compute drag distance for the\n * pan-vs-click threshold. */\n private dragOrigin: { clientX: number; clientY: number } | null = null;\n /** True once movement crossed the drag threshold — used to suppress\n * the synthetic click that follows the mouseup. */\n private dragMoved = false;\n /** Pixels of movement before mousedown is treated as a drag. */\n private static readonly DRAG_THRESHOLD = 4;\n /** Bound window listeners — kept on the instance so we can detach. */\n private boundWindowMove?: (e: MouseEvent) => void;\n private boundWindowUp?: (e: MouseEvent) => void;\n\n private resizeObserver?: ResizeObserver;\n\n @HostBinding('class.erd-root') readonly rootClass = true;\n\n // ─── LIFECYCLE ────────────────────────────────────────────────────────\n\n public ngOnChanges(changes: SimpleChanges): void {\n const nodesChanged = !!changes['nodes'];\n // Compare config by the fields we actually use — consumers that bind\n // an inline `[config]=\"{...}\"` object literal get a new reference\n // every CD cycle, so a naive `changes['config']` check would\n // recompute + refit endlessly.\n const configChanged = this.configAffectsLayout(\n changes['config']?.previousValue as ERDConfig | undefined,\n changes['config']?.currentValue as ERDConfig | undefined,\n );\n if (nodesChanged || configChanged) {\n if (nodesChanged) {\n this.activeSchemas = null;\n this.expandedNodeIds = new Set();\n this.hoverNodeId = null;\n }\n // Honour `config.layoutAlgorithm` on first arrival; runtime\n // changes happen via `setLayoutAlgorithm`.\n if (this.config.layoutAlgorithm === 'dagre') this.activeLayout = 'dagre';\n else if (this.config.layoutAlgorithm === 'schema-grid') this.activeLayout = 'schema-grid';\n this.recompute();\n // Fit-to-view once the DOM has the new canvas dimensions.\n queueMicrotask(() => this.fitToView());\n }\n if (changes['focusNodeId']) {\n this.updateHighlightSet();\n this.cdr.markForCheck();\n }\n }\n\n /** True iff any config field that influences the cached layout changed. */\n private configAffectsLayout(prev: ERDConfig | undefined, curr: ERDConfig | undefined): boolean {\n if (prev === curr) return false;\n return (\n (prev?.nodeWidth ?? null) !== (curr?.nodeWidth ?? null) ||\n (prev?.fieldHeight ?? null) !== (curr?.fieldHeight ?? null) ||\n (prev?.showAllFields ?? null) !== (curr?.showAllFields ?? null) ||\n (prev?.showSchemaBands ?? null) !== (curr?.showSchemaBands ?? null) ||\n (prev?.crowsFoot ?? null) !== (curr?.crowsFoot ?? null) ||\n (prev?.maxFitZoom ?? null) !== (curr?.maxFitZoom ?? null) ||\n (prev?.minZoom ?? null) !== (curr?.minZoom ?? null) ||\n (prev?.maxZoom ?? null) !== (curr?.maxZoom ?? null)\n );\n }\n\n public ngAfterViewInit(): void {\n this.resizeObserver = this.watchResize();\n this.recompute();\n queueMicrotask(() => this.fitToView());\n }\n\n public ngOnDestroy(): void {\n this.resizeObserver?.disconnect();\n // Detach any pan listeners still bound from an in-progress drag.\n if (this.boundWindowMove) window.removeEventListener('mousemove', this.boundWindowMove);\n if (this.boundWindowUp) window.removeEventListener('mouseup', this.boundWindowUp);\n }\n\n // ─── RECOMPUTATION ────────────────────────────────────────────────────\n\n /** Rebuild the layout + derived view-model from current inputs/state. */\n private recompute(): void {\n this.totalCount = this.nodes.length;\n\n const filteredBySchema = this.activeSchemas\n ? this.nodes.filter(n => this.activeSchemas!.has(n.schemaName || '_'))\n : this.nodes;\n\n const q = this.searchQuery.trim().toLowerCase();\n const filtered = q\n ? filteredBySchema.filter(n =>\n n.name.toLowerCase().includes(q) ||\n (n.schemaName?.toLowerCase().includes(q) ?? false) ||\n n.fields.some(f => f.name.toLowerCase().includes(q)))\n : filteredBySchema;\n\n this.visibleCount = filtered.length;\n\n const commonOpts = {\n nodeWidth: this.config.nodeWidth ?? 220,\n fieldHeight: this.config.fieldHeight ?? 22,\n expandedNodeIds: this.expandedNodeIds,\n showAllFields: this.config.showAllFields ?? false,\n };\n\n this.layout = this.activeLayout === 'dagre'\n ? computeDagreLayout(filtered, {\n ...commonOpts,\n rankDir: this.config.dagreConfig?.rankDir ?? 'LR',\n nodeSep: this.config.dagreConfig?.nodeSep,\n rankSep: this.config.dagreConfig?.rankSep,\n })\n : computeErdLayout(filtered, commonOpts);\n\n this.schemaChips = this.buildSchemaChips();\n this.updateHighlightSet();\n this.updateSelectedEntity();\n this.cdr.markForCheck();\n }\n\n /**\n * Switch between the schema-grid and dagre hierarchical layouts at\n * runtime. Emits a state change so the consumer can persist the\n * user's preference (via `userStateChange` on `mj-erd-composite`).\n *\n * Also clears the current focus/selection — switching layouts moves\n * cards to entirely new positions, so the previously-selected entity\n * would otherwise stay highlighted in a different spot with the side\n * panel still open, which is jarring. A clean slate is better.\n */\n public setLayoutAlgorithm(algo: 'schema-grid' | 'dagre'): void {\n if (this.activeLayout === algo) return;\n this.activeLayout = algo;\n\n const hadSelection = !!(this.focusNodeId || this.selectedNodeId);\n this.focusNodeId = null;\n this.selectedNodeId = null;\n this.hoverNodeId = null;\n this.updateHighlightSet();\n this.updateSelectedEntity();\n if (hadSelection) this.nodeDeselected.emit();\n\n this.recompute();\n queueMicrotask(() => this.fitToView());\n this.stateChange.emit(this.getState());\n }\n\n private buildSchemaChips(): SchemaChip[] {\n const counts = new Map<string, number>();\n for (const n of this.nodes) {\n const s = n.schemaName || '_';\n counts.set(s, (counts.get(s) ?? 0) + 1);\n }\n return [...counts.entries()]\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([name, count]) => ({\n name,\n count,\n active: this.activeSchemas ? this.activeSchemas.has(name) : true,\n }));\n }\n\n private updateHighlightSet(): void {\n const id = this.focusNodeId ?? this.hoverNodeId;\n this.highlightSet = id ? getNeighbors(this.nodes, id) : null;\n }\n\n private updateSelectedEntity(): void {\n const id = this.focusNodeId ?? this.selectedNodeId;\n this.selectedEntity = id ? this.nodes.find(n => n.id === id) ?? null : null;\n }\n\n private watchResize(): ResizeObserver {\n const observer = new ResizeObserver(() => this.fitToView());\n observer.observe(this.host.nativeElement);\n return observer;\n }\n\n // ─── PAN / ZOOM / FIT ────────────────────────────────────────────────\n\n /**\n * Mousedown anywhere on the SVG (background OR a node card). We\n * arm a potential pan and attach window-level move/up listeners so\n * the drag continues even if the cursor leaves the canvas (passes\n * over the focus card, scrollbars, the chrome, etc.).\n *\n * The actual `panning = true` flip happens in the move handler once\n * the cursor crosses `DRAG_THRESHOLD` — that way short clicks still\n * register as clicks on cards (no accidental selection-toggle from\n * a tiny mouse jitter).\n */\n public onBackgroundMouseDown(e: MouseEvent): void {\n if (e.button !== 0) return;\n this.dragOrigin = { clientX: e.clientX, clientY: e.clientY };\n this.dragMoved = false;\n this.panStart = { x: e.clientX - this.transform.x, y: e.clientY - this.transform.y };\n\n this.boundWindowMove = (ev: MouseEvent) => this.onWindowMouseMove(ev);\n this.boundWindowUp = (ev: MouseEvent) => this.onWindowMouseUp(ev);\n window.addEventListener('mousemove', this.boundWindowMove);\n window.addEventListener('mouseup', this.boundWindowUp);\n }\n\n private onWindowMouseMove(e: MouseEvent): void {\n if (!this.dragOrigin || !this.panStart) return;\n\n if (!this.panning) {\n const dx = e.clientX - this.dragOrigin.clientX;\n const dy = e.clientY - this.dragOrigin.clientY;\n if (Math.hypot(dx, dy) < ERDDiagramComponent.DRAG_THRESHOLD) return;\n this.panning = true;\n this.dragMoved = true;\n }\n\n this.transform = {\n ...this.transform,\n x: e.clientX - this.panStart.x,\n y: e.clientY - this.panStart.y,\n };\n this.emitZoom();\n this.cdr.markForCheck();\n }\n\n private onWindowMouseUp(_e: MouseEvent): void {\n // If a drag actually happened, swallow the synthetic click that\n // browsers fire on mouseup so it doesn't reach the node click\n // handler and toggle the focus. We use capture phase + once so\n // we only catch the immediate next click from this mouse-up.\n if (this.dragMoved) {\n const swallow = (ev: MouseEvent) => {\n ev.stopPropagation();\n ev.preventDefault();\n };\n window.addEventListener('click', swallow, { capture: true, once: true });\n }\n\n this.panning = false;\n this.panStart = null;\n this.dragOrigin = null;\n this.dragMoved = false;\n\n if (this.boundWindowMove) {\n window.removeEventListener('mousemove', this.boundWindowMove);\n this.boundWindowMove = undefined;\n }\n if (this.boundWindowUp) {\n window.removeEventListener('mouseup', this.boundWindowUp);\n this.boundWindowUp = undefined;\n }\n }\n\n public onWheel(e: WheelEvent): void {\n if (this.config.enableZoom === false) return;\n e.preventDefault();\n const svg = this.canvasRef?.nativeElement;\n if (!svg) return;\n const rect = svg.getBoundingClientRect();\n const mx = e.clientX - rect.left;\n const my = e.clientY - rect.top;\n const delta = -e.deltaY * 0.001;\n const minZoom = this.config.minZoom ?? 0.15;\n const maxZoom = this.config.maxZoom ?? 2.5;\n const newK = Math.max(minZoom, Math.min(maxZoom, this.transform.k * (1 + delta)));\n const ratio = newK / this.transform.k;\n this.transform = {\n k: newK,\n x: mx - (mx - this.transform.x) * ratio,\n y: my - (my - this.transform.y) * ratio,\n };\n this.emitZoom();\n this.cdr.markForCheck();\n }\n\n public zoomBy(factor: number): void {\n const svg = this.canvasRef?.nativeElement;\n if (!svg) return;\n const rect = svg.getBoundingClientRect();\n const mx = rect.width / 2;\n const my = rect.height / 2;\n const minZoom = this.config.minZoom ?? 0.15;\n const maxZoom = this.config.maxZoom ?? 2.5;\n const newK = Math.max(minZoom, Math.min(maxZoom, this.transform.k * factor));\n const ratio = newK / this.transform.k;\n this.transform = {\n k: newK,\n x: mx - (mx - this.transform.x) * ratio,\n y: my - (my - this.transform.y) * ratio,\n };\n this.emitZoom();\n this.cdr.markForCheck();\n }\n\n public fitToView(): void {\n const svg = this.canvasRef?.nativeElement;\n if (!svg) return;\n const rect = svg.getBoundingClientRect();\n if (rect.width === 0 || rect.height === 0 || this.layout.totalWidth === 0) return;\n\n const padding = 60;\n // Allow fit to scale UP for small diagrams (e.g. the Database Designer\n // wizard preview, where a single entity + a couple of satellites\n // would otherwise look lost in the pane). Consumers can override via\n // `config.maxFitZoom`. Default 2.5x: a 220px card becomes ~550px,\n // which comfortably fills a typical preview pane without looking\n // cartoonish (13px text → ~33px, still a readable ceiling).\n const maxFit = this.config.maxFitZoom ?? 2.5;\n const idealK = Math.min(\n (rect.width - padding * 2) / this.layout.totalWidth,\n (rect.height - padding * 2) / this.layout.totalHeight,\n maxFit,\n );\n\n // Clamp the fit zoom so cards stay legible. On very large schemas\n // (hundreds of entities) fit-to-view would otherwise shrink each card\n // to a few pixels wide. We'd rather show part of the canvas at a\n // readable zoom and let the user pan to see the rest.\n const minZoom = this.config.minZoom ?? 0.35;\n const k = Math.max(idealK, minZoom);\n\n // Center horizontally only if the canvas fits; otherwise anchor at left\n // so the user starts at the first schema band instead of the middle.\n const canvasFitsX = this.layout.totalWidth * k <= rect.width - padding * 2;\n const canvasFitsY = this.layout.totalHeight * k <= rect.height - padding * 2;\n\n const newX = canvasFitsX ? (rect.width - this.layout.totalWidth * k) / 2 : padding;\n const newY = canvasFitsY ? (rect.height - this.layout.totalHeight * k) / 2 : padding;\n\n // Idempotent guard. If the computed transform is effectively identical\n // to the current one, bail out without reassigning or calling\n // markForCheck. Without this, a consumer that passes an inline\n // `[config]=\"{...}\"` object literal re-triggers ngOnChanges on every\n // change-detection tick, producing an infinite fitToView → markForCheck\n // → CD → ngOnChanges → fitToView loop (NG0103).\n const TOL = 0.001;\n if (\n Math.abs(this.transform.k - k) < TOL &&\n Math.abs(this.transform.x - newX) < 0.5 &&\n Math.abs(this.transform.y - newY) < 0.5\n ) {\n return;\n }\n\n this.transform = { k, x: newX, y: newY };\n this.emitZoom();\n this.layoutComplete.emit();\n this.cdr.markForCheck();\n }\n\n private centerOn(nodeId: string): void {\n const n = this.layout.nodes.find(x => x.id === nodeId);\n const svg = this.canvasRef?.nativeElement;\n if (!n || !svg) return;\n const rect = svg.getBoundingClientRect();\n const k = Math.max(this.transform.k, 0.9);\n this.transform = {\n k,\n x: rect.width / 2 - (n.x + n.width / 2) * k,\n y: rect.height / 2 - (n.y + n.height / 2) * k,\n };\n this.emitZoom();\n // External callers (e.g. zoomToNode invoked from the side panel)\n // need CD to pick up the new transform — onNodeClick used to do\n // this itself but external pathways were silently no-op'ing.\n this.cdr.markForCheck();\n }\n\n private emitZoom(): void {\n this.zoomChange.emit({\n zoomLevel: this.transform.k,\n translateX: this.transform.x,\n translateY: this.transform.y,\n });\n }\n\n // ─── NODE INTERACTIONS ───────────────────────────────────────────────\n\n public onNodeClick(node: LaidOutNode, e: MouseEvent): void {\n e.stopPropagation();\n const event: ERDNodeClickEvent = { node, mouseEvent: e, cancel: false };\n this.nodeClick.emit(event);\n if (event.cancel) return;\n\n if (this.focusNodeId === node.id) {\n // Toggle off — deselect.\n this.focusNodeId = null;\n this.selectedNodeId = null;\n this.nodeDeselected.emit();\n } else {\n this.focusNodeId = node.id;\n this.selectedNodeId = node.id;\n this.nodeSelected.emit(node);\n this.centerOn(node.id);\n }\n this.updateHighlightSet();\n this.updateSelectedEntity();\n this.cdr.markForCheck();\n }\n\n public onNodeMouseEnter(node: LaidOutNode, e: MouseEvent): void {\n this.hoverNodeId = node.id;\n this.updateHighlightSet();\n const related = this.nodes.filter(n => this.highlightSet?.has(n.id) && n.id !== node.id);\n this.nodeHover.emit({\n node, mouseEvent: e, relatedNodes: related,\n position: { x: e.clientX, y: e.clientY },\n });\n this.cdr.markForCheck();\n }\n\n public onNodeMouseLeave(node: LaidOutNode): void {\n this.hoverNodeId = null;\n this.updateHighlightSet();\n this.nodeHoverEnd.emit(node);\n this.cdr.markForCheck();\n }\n\n public onToggleExpand(nodeId: string, e: Event): void {\n e.stopPropagation();\n if (this.expandedNodeIds.has(nodeId)) this.expandedNodeIds.delete(nodeId);\n else this.expandedNodeIds.add(nodeId);\n // New Set reference so @for trackBy treats it as changed.\n this.expandedNodeIds = new Set(this.expandedNodeIds);\n this.recompute();\n }\n\n // ─── CHROME INTERACTIONS ─────────────────────────────────────────────\n\n public onSearchChange(value: string): void {\n this.searchQuery = value;\n this.recompute();\n }\n\n public onClearSearch(): void {\n this.searchQuery = '';\n this.recompute();\n }\n\n public onSchemaChipToggle(schemaName: string): void {\n const current = this.activeSchemas ?? new Set(this.schemaChips.map(c => c.name));\n const next = new Set(current);\n if (next.has(schemaName)) next.delete(schemaName);\n else next.add(schemaName);\n this.activeSchemas = next.size === this.schemaChips.length ? null : next;\n this.recompute();\n }\n\n public onRequestRefresh(): void {\n this.refreshRequested.emit();\n }\n\n // ─── DERIVED DATA FOR TEMPLATE ───────────────────────────────────────\n\n /** Path string for an edge — uses the orthogonal polyline from layout. */\n public edgePath(edge: LaidOutEdge): string {\n return pointsToPath(edge.points);\n }\n\n /**\n * Whether to render FK field labels along edges. Defaults to ON in\n * both layouts — the zoom-gate (>=0.55x) keeps the labels off when\n * the user is zoomed out far enough to see hundreds of entities, so\n * \"noise on dense views\" isn't a real concern. Consumers can still\n * force off via `config.showRelationshipLabels: false`.\n */\n public get showEdgeLabels(): boolean {\n const enabled = this.config.showRelationshipLabels ?? true;\n if (!enabled) return false;\n return this.transform.k >= 0.55;\n }\n\n /**\n * Pick a point along the edge polyline for a label and approximate\n * its width. Returns null for self-loops (no good place to put text).\n * Uses the longest horizontal segment when one exists; falls back to\n * the segment midpoint otherwise.\n */\n public edgeLabelPosition(edge: LaidOutEdge): { x: number; y: number; w: number } | null {\n if (edge.selfReference) return null;\n const pts = edge.points;\n if (pts.length < 2) return null;\n\n // Find the longest horizontal segment so the label sits on a\n // straight portion, not over a corner.\n let bestIdx = 0;\n let bestLen = 0;\n for (let i = 0; i < pts.length - 1; i++) {\n const [x1, y1] = pts[i];\n const [x2, y2] = pts[i + 1];\n if (Math.abs(y2 - y1) > 0.5) continue; // skip vertical segs\n const len = Math.abs(x2 - x1);\n if (len > bestLen) { bestLen = len; bestIdx = i; }\n }\n\n const [x1, y1] = pts[bestIdx];\n const [x2, y2] = pts[bestIdx + 1];\n const x = (x1 + x2) / 2;\n const y = (y1 + y2) / 2;\n\n // 6.5 px per char is a good approximation for the 11px mono we\n // use for labels — only used to size the background rect.\n const w = Math.max(20, edge.sourceField.name.length * 6.5);\n return { x, y, w };\n }\n\n /** Whether a node should appear dimmed (highlight mode active, node not in set). */\n public isDimmed(nodeId: string): boolean {\n return !!this.highlightSet && !this.highlightSet.has(nodeId);\n }\n\n /** Whether a node is the current focus (strong border). */\n public isFocus(nodeId: string): boolean {\n return this.focusNodeId === nodeId;\n }\n\n /** Whether a node is a 1-hop neighbour of the focus (medium border). */\n public isNeighbour(nodeId: string): boolean {\n return !!this.highlightSet && this.highlightSet.has(nodeId) && !this.isFocus(nodeId);\n }\n\n /** Whether an edge is part of the active highlight subgraph. */\n public isEdgeActive(edge: LaidOutEdge): boolean {\n return !!this.highlightSet && this.highlightSet.has(edge.sourceId) && this.highlightSet.has(edge.targetId);\n }\n\n /** Whether an edge should appear dimmed. */\n public isEdgeDimmed(edge: LaidOutEdge): boolean {\n return !!this.highlightSet && !this.isEdgeActive(edge);\n }\n\n /** Zoom percentage string for the toolbar readout. */\n public get zoomPercent(): string {\n return Math.round(this.transform.k * 100) + '%';\n }\n\n /** Short friendly row-count string (e.g. 1248 → \"1.2k\"). */\n public formatCount(n: number | undefined): string {\n if (n == null) return '';\n if (n >= 1000) return (n / 1000).toFixed(n >= 10000 ? 0 : 1) + 'k';\n return n.toString();\n }\n\n /** Number of PK fields — handy aggregate (kept for external API parity). */\n public pkCount(entity: ERDNode): number {\n return entity.fields.filter(f => f.isPrimaryKey).length;\n }\n\n /** Number of FK fields — handy aggregate (kept for external API parity). */\n public fkCount(entity: ERDNode): number {\n return entity.fields.filter(f => !!f.relatedNodeId).length;\n }\n\n // ─── LEGACY API SHIMS ────────────────────────────────────────────────\n // Kept so existing consumers (mj-entity-erd wrapper, admin ERD dashboard)\n // continue to compile and work. The new implementation doesn't need\n // most of these, but we preserve the shape.\n\n public zoomIn(): void { this.zoomBy(1.2); }\n public zoomOut(): void { this.zoomBy(0.83); }\n public resetZoom(): void { this.fitToView(); }\n public zoomToFit(_padding?: number): void { this.fitToView(); }\n public zoomToNode(nodeId: string, _scale?: number): void { this.centerOn(nodeId); }\n public triggerResize(): void { this.fitToView(); }\n\n public refresh(): void {\n this.recompute();\n queueMicrotask(() => this.fitToView());\n }\n\n public getState(): ERDState {\n return {\n selectedNodeId: this.selectedNodeId,\n highlightedNodeIds: [...this.highlightedNodeIds],\n zoomLevel: this.transform.k,\n translateX: this.transform.x,\n translateY: this.transform.y,\n focusNodeId: this.focusNodeId,\n focusDepth: this.focusDepth,\n nodePositions: {},\n layoutAlgorithm: this.activeLayout,\n };\n }\n\n public setState(state: Partial<ERDState>, _restorePositions?: boolean): void {\n if (state.selectedNodeId !== undefined) this.selectedNodeId = state.selectedNodeId;\n if (state.highlightedNodeIds !== undefined) this.highlightedNodeIds = [...state.highlightedNodeIds];\n if (state.focusNodeId !== undefined) this.focusNodeId = state.focusNodeId;\n if (state.focusDepth !== undefined) this.focusDepth = state.focusDepth;\n if (state.zoomLevel !== undefined || state.translateX !== undefined || state.translateY !== undefined) {\n this.transform = {\n k: state.zoomLevel ?? this.transform.k,\n x: state.translateX ?? this.transform.x,\n y: state.translateY ?? this.transform.y,\n };\n }\n if (state.layoutAlgorithm && state.layoutAlgorithm !== this.activeLayout) {\n this.activeLayout = state.layoutAlgorithm;\n this.recompute();\n }\n this.updateHighlightSet();\n this.updateSelectedEntity();\n this.cdr.markForCheck();\n }\n\n public exportAsSVG(): string {\n const svg = this.canvasRef?.nativeElement;\n if (!svg) return '';\n return new XMLSerializer().serializeToString(svg);\n }\n\n // ─── TRACK-BYs ───────────────────────────────────────────────────────\n\n public trackByBand = (_: number, b: LaidOutBand) => b.schemaName;\n public trackByEdge = (_: number, e: LaidOutEdge) => e.id;\n public trackByNode = (_: number, n: LaidOutNode) => n.id;\n public trackByField = (_: number, f: ERDField) => f.id || f.name;\n public trackByChip = (_: number, c: SchemaChip) => c.name;\n}\n","<!-- ── CHROME ──────────────────────────────────────────────────────────── -->\n@if (showHeader) {\n <header class=\"erd-chrome\">\n <div class=\"erd-title-group\">\n <div class=\"erd-title\">{{ headerTitle }}</div>\n <div class=\"erd-subtitle\">\n <span class=\"erd-count-pill\">{{ visibleCount }}</span>\n <span class=\"erd-count-label\">of {{ totalCount }} entities</span>\n <span class=\"erd-dot\">·</span>\n <span>{{ layout.edges.length }} relationships</span>\n </div>\n </div>\n\n <label class=\"erd-search\">\n <i class=\"fa-solid fa-magnifying-glass\" aria-hidden=\"true\"></i>\n <input\n type=\"text\"\n [value]=\"searchQuery\"\n (input)=\"onSearchChange($any($event.target).value)\"\n placeholder=\"Search entities, schemas, fields…\"\n spellcheck=\"false\"\n aria-label=\"Search entities\" />\n @if (searchQuery) {\n <button type=\"button\" class=\"erd-search-clear\" (click)=\"onClearSearch()\" aria-label=\"Clear search\">×</button>\n }\n </label>\n\n <div class=\"erd-chrome-right\">\n @if (schemaChips.length > 1) {\n <div class=\"erd-schema-chips\" role=\"group\" aria-label=\"Filter by schema\">\n @for (chip of schemaChips; track trackByChip($index, chip)) {\n <button\n type=\"button\"\n class=\"erd-chip\"\n [class.active]=\"chip.active\"\n (click)=\"onSchemaChipToggle(chip.name)\"\n [attr.aria-pressed]=\"chip.active\">\n <span class=\"erd-chip-label\">{{ chip.name }}</span>\n <span class=\"erd-chip-count\">{{ chip.count }}</span>\n </button>\n }\n </div>\n }\n\n <div class=\"erd-toolbar\" role=\"group\" aria-label=\"Layout mode\">\n <button\n type=\"button\"\n [class.active]=\"activeLayout === 'schema-grid'\"\n (click)=\"setLayoutAlgorithm('schema-grid')\"\n title=\"Schema grid — grouped by schema, predictable\"\n aria-label=\"Schema-grid layout\">\n <i class=\"fa-solid fa-table-cells\" aria-hidden=\"true\"></i>\n </button>\n <button\n type=\"button\"\n [class.active]=\"activeLayout === 'dagre'\"\n (click)=\"setLayoutAlgorithm('dagre')\"\n title=\"Hierarchical — classic ERD, relationship-driven\"\n aria-label=\"Hierarchical layout\">\n <i class=\"fa-solid fa-sitemap\" aria-hidden=\"true\"></i>\n </button>\n </div>\n\n <div class=\"erd-toolbar\" role=\"group\" aria-label=\"Zoom controls\">\n <button type=\"button\" (click)=\"zoomBy(1.2)\" title=\"Zoom in\" aria-label=\"Zoom in\">\n <i class=\"fa-solid fa-magnifying-glass-plus\" aria-hidden=\"true\"></i>\n </button>\n <button type=\"button\" (click)=\"zoomBy(0.83)\" title=\"Zoom out\" aria-label=\"Zoom out\">\n <i class=\"fa-solid fa-magnifying-glass-minus\" aria-hidden=\"true\"></i>\n </button>\n <button type=\"button\" (click)=\"fitToView()\" title=\"Fit to view\" aria-label=\"Fit to view\">\n <i class=\"fa-solid fa-expand\" aria-hidden=\"true\"></i>\n </button>\n <span class=\"erd-zoom-val\">{{ zoomPercent }}</span>\n </div>\n </div>\n </header>\n}\n\n<!-- ── CANVAS ──────────────────────────────────────────────────────────── -->\n<!-- Pan handling is window-level once mousedown fires (see component) so\n dragging continues even if the cursor leaves the canvas-wrap. -->\n<div class=\"erd-canvas-wrap\">\n\n <svg\n #canvasRef\n class=\"erd-canvas\"\n [attr.data-panning]=\"panning ? 'true' : null\"\n (mousedown)=\"onBackgroundMouseDown($event)\"\n (wheel)=\"onWheel($event)\">\n\n <defs>\n <marker id=\"erd-arrow\" viewBox=\"0 0 10 10\" refX=\"9\" refY=\"5\" markerWidth=\"7\" markerHeight=\"7\" orient=\"auto\">\n <path d=\"M 0 0 L 10 5 L 0 10 z\" class=\"erd-marker\" />\n </marker>\n <marker id=\"erd-arrow-active\" viewBox=\"0 0 10 10\" refX=\"9\" refY=\"5\" markerWidth=\"7\" markerHeight=\"7\" orient=\"auto\">\n <path d=\"M 0 0 L 10 5 L 0 10 z\" class=\"erd-marker erd-marker-active\" />\n </marker>\n <marker id=\"erd-many\" viewBox=\"-10 -6 14 12\" refX=\"-8\" refY=\"0\" markerWidth=\"14\" markerHeight=\"14\" orient=\"auto\">\n <path d=\"M 0 -5 L -8 0 L 0 5 M -8 0 L 4 0\" class=\"erd-marker-stroke\" />\n </marker>\n <marker id=\"erd-many-active\" viewBox=\"-10 -6 14 12\" refX=\"-8\" refY=\"0\" markerWidth=\"14\" markerHeight=\"14\" orient=\"auto\">\n <path d=\"M 0 -5 L -8 0 L 0 5 M -8 0 L 4 0\" class=\"erd-marker-stroke erd-marker-active\" />\n </marker>\n </defs>\n\n <g [attr.transform]=\"'translate(' + transform.x + ' ' + transform.y + ') scale(' + transform.k + ')'\">\n\n <!-- Schema bands -->\n @if ((config.showSchemaBands ?? true)) {\n @for (band of layout.bands; track trackByBand($index, band)) {\n <g class=\"erd-band\">\n <rect\n [attr.x]=\"band.x\" [attr.y]=\"band.y\"\n [attr.width]=\"band.width\" [attr.height]=\"band.height\"\n rx=\"16\"\n class=\"erd-band-rect\" />\n <text\n [attr.x]=\"band.x + band.width / 2\"\n [attr.y]=\"band.y + 32\"\n text-anchor=\"middle\"\n class=\"erd-band-title\">\n {{ band.schemaName }}\n </text>\n </g>\n }\n }\n\n <!-- Edges -->\n <g class=\"erd-edges\">\n @for (edge of layout.edges; track trackByEdge($index, edge)) {\n <path\n [attr.d]=\"edgePath(edge)\"\n fill=\"none\"\n class=\"erd-edge\"\n [class.erd-edge-active]=\"isEdgeActive(edge)\"\n [class.erd-edge-dimmed]=\"isEdgeDimmed(edge)\"\n [attr.marker-start]=\"(config.crowsFoot ?? true) ? (isEdgeActive(edge) ? 'url(#erd-many-active)' : 'url(#erd-many)') : null\"\n [attr.marker-end]=\"isEdgeActive(edge) ? 'url(#erd-arrow-active)' : 'url(#erd-arrow)'\" />\n }\n </g>\n\n <!-- Edge labels — FK field names rendered along edges. Only shown\n when zoom is high enough for the text to be legible, and only\n when config.showRelationshipLabels resolves true. -->\n @if (showEdgeLabels) {\n <g class=\"erd-edge-labels\">\n @for (edge of layout.edges; track trackByEdge($index, edge)) {\n @let pos = edgeLabelPosition(edge);\n @if (pos) {\n <g\n class=\"erd-edge-label\"\n [class.erd-edge-label-active]=\"isEdgeActive(edge)\"\n [class.erd-edge-label-dimmed]=\"isEdgeDimmed(edge)\">\n <rect\n [attr.x]=\"pos.x - pos.w / 2 - 4\"\n [attr.y]=\"pos.y - 8\"\n [attr.width]=\"pos.w + 8\"\n height=\"16\"\n rx=\"3\"\n class=\"erd-edge-label-bg\" />\n <text\n [attr.x]=\"pos.x\"\n [attr.y]=\"pos.y + 4\"\n text-anchor=\"middle\"\n class=\"erd-edge-label-text\">{{ edge.sourceField.name }}</text>\n </g>\n }\n }\n </g>\n }\n\n <!-- Nodes -->\n <g class=\"erd-nodes\">\n @for (node of layout.nodes; track trackByNode($index, node)) {\n <g\n class=\"erd-node\"\n [attr.transform]=\"'translate(' + node.x + ' ' + node.y + ')'\"\n [class.erd-node-focus]=\"isFocus(node.id)\"\n [class.erd-node-neighbour]=\"isNeighbour(node.id)\"\n [class.erd-node-dimmed]=\"isDimmed(node.id)\"\n (click)=\"onNodeClick(node, $event)\"\n (mouseenter)=\"onNodeMouseEnter(node, $event)\"\n (mouseleave)=\"onNodeMouseLeave(node)\">\n\n <!-- Card shadow -->\n <rect class=\"erd-node-shadow\"\n [attr.width]=\"node.width\" [attr.height]=\"node.height\"\n x=\"0\" y=\"2\" rx=\"8\" />\n\n <!-- Card body -->\n <rect class=\"erd-node-body\"\n [attr.width]=\"node.width\" [attr.height]=\"node.height\"\n x=\"0\" y=\"0\" rx=\"8\" />\n\n <!-- Header -->\n <rect class=\"erd-node-header\"\n x=\"0\" y=\"0\"\n [attr.width]=\"node.width\" height=\"36\"\n rx=\"6\" />\n <foreignObject x=\"14\" y=\"8\" [attr.width]=\"node.width - 28\" height=\"22\">\n <div xmlns=\"http://www.w3.org/1999/xhtml\" class=\"erd-node-header-content\">\n <span class=\"erd-node-name\" [title]=\"node.name\">{{ node.name }}</span>\n @if (node.customData && $any(node.customData).rows != null) {\n <span class=\"erd-node-rows\">{{ formatCount($any(node.customData).rows) }}</span>\n }\n </div>\n </foreignObject>\n\n <!-- Separator -->\n <line class=\"erd-node-separator\"\n x1=\"0\" [attr.x2]=\"node.width\" y1=\"36\" y2=\"36\" />\n\n <!-- Fields -->\n @for (field of node.visibleFields; track trackByField($index, field); let i = $index) {\n <foreignObject x=\"0\" [attr.y]=\"36 + i * 22\" [attr.width]=\"node.width\" height=\"22\">\n <div xmlns=\"http://www.w3.org/1999/xhtml\"\n class=\"erd-field-row\"\n [class.erd-field-pk]=\"field.isPrimaryKey\"\n [class.erd-field-fk]=\"!field.isPrimaryKey && field.relatedNodeId\">\n @if (field.isPrimaryKey) {\n <span class=\"erd-field-chip erd-field-chip-pk\">PK</span>\n } @else if (field.relatedNodeId) {\n <span class=\"erd-field-chip erd-field-chip-fk\">FK</span>\n }\n <span class=\"erd-field-name\" [title]=\"field.name\">{{ field.name }}</span>\n @if (field.type) {\n <span class=\"erd-field-type\" [title]=\"field.type\">{{ field.type }}</span>\n }\n </div>\n </foreignObject>\n }\n\n <!-- +N more toggle -->\n @if (node.hasMore) {\n <foreignObject\n x=\"4\"\n [attr.y]=\"36 + node.visibleFields.length * 22 + 6\"\n [attr.width]=\"node.width - 8\"\n height=\"14\"\n (click)=\"onToggleExpand(node.id, $event)\">\n <div xmlns=\"http://www.w3.org/1999/xhtml\" class=\"erd-field-more\">\n + {{ node.fields.length - node.visibleFields.length }} more fields\n </div>\n </foreignObject>\n }\n\n <!-- Outline frame — drawn last so the focus/neighbour stroke\n sits above the header instead of being clipped by it. -->\n <rect class=\"erd-node-frame\"\n [attr.width]=\"node.width\" [attr.height]=\"node.height\"\n x=\"0\" y=\"0\" rx=\"8\" />\n </g>\n }\n </g>\n </g>\n </svg>\n\n <!-- Focus details are rendered by the consumer's side panel\n (mj-entity-details inside mj-erd-composite); the in-canvas\n floating focus card was removed as it duplicated that content. -->\n\n <!-- ── Empty state ─────────────────────────────────────────────────── -->\n @if (visibleCount === 0) {\n <mj-empty-state\n class=\"erd-empty\"\n [Variant]=\"totalCount === 0 ? 'empty' : 'no-results'\"\n [Icon]=\"emptyStateIcon\"\n [Title]=\"emptyStateTitle\"\n [Message]=\"totalCount > 0 ? 'Try adjusting schema filters or clearing search' : ''\" />\n }\n\n <!-- ── Loading overlay ─────────────────────────────────────────────── -->\n @if (isRefreshing) {\n <div class=\"erd-loading-overlay\">\n <div class=\"erd-loading-content\">\n <i class=\"fa-solid fa-circle-notch fa-spin\" aria-hidden=\"true\"></i>\n <span>Loading…</span>\n </div>\n </div>\n }\n</div>\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/ng-entity-relationship-diagram",
|
|
3
|
-
"version": "6.1.0-edge.
|
|
3
|
+
"version": "6.1.0-edge.6",
|
|
4
4
|
"description": "MemberJunction: Entity Relationship Diagram (ERD) component for visualizing entity relationships using D3.js force-directed graphs",
|
|
5
5
|
"main": "./dist/public-api.js",
|
|
6
6
|
"typings": "./dist/public-api.d.ts",
|
|
@@ -18,24 +18,24 @@
|
|
|
18
18
|
"author": "",
|
|
19
19
|
"license": "BUSL-1.1",
|
|
20
20
|
"devDependencies": {
|
|
21
|
-
"@angular/compiler": "21.
|
|
22
|
-
"@angular/compiler-cli": "21.
|
|
23
|
-
"@memberjunction/ng-test-utils": "6.1.0-edge.
|
|
21
|
+
"@angular/compiler": "21.2.22",
|
|
22
|
+
"@angular/compiler-cli": "21.2.22",
|
|
23
|
+
"@memberjunction/ng-test-utils": "6.1.0-edge.6",
|
|
24
24
|
"sass": "^1.97.3",
|
|
25
25
|
"vitest": "^4.0.18"
|
|
26
26
|
},
|
|
27
27
|
"peerDependencies": {
|
|
28
|
-
"@angular/common": "^21.
|
|
29
|
-
"@angular/core": "^21.
|
|
30
|
-
"@angular/
|
|
28
|
+
"@angular/common": "^21.2.22",
|
|
29
|
+
"@angular/core": "^21.2.22",
|
|
30
|
+
"@angular/forms": "^21.2.22",
|
|
31
|
+
"@angular/platform-browser": "^21.2.22"
|
|
31
32
|
},
|
|
32
33
|
"dependencies": {
|
|
33
|
-
"@angular/forms": "21.1.3",
|
|
34
34
|
"@dagrejs/dagre": "^1.1.8",
|
|
35
|
-
"@memberjunction/core": "6.1.0-edge.
|
|
36
|
-
"@memberjunction/ng-base-types": "6.1.0-edge.
|
|
37
|
-
"@memberjunction/global": "6.1.0-edge.
|
|
38
|
-
"@memberjunction/ng-ui-components": "6.1.0-edge.
|
|
35
|
+
"@memberjunction/core": "6.1.0-edge.6",
|
|
36
|
+
"@memberjunction/ng-base-types": "6.1.0-edge.6",
|
|
37
|
+
"@memberjunction/global": "6.1.0-edge.6",
|
|
38
|
+
"@memberjunction/ng-ui-components": "6.1.0-edge.6",
|
|
39
39
|
"@types/d3": "^7.4.3",
|
|
40
40
|
"angular-split": "^20.0.0",
|
|
41
41
|
"d3": "^7.9.0",
|