@memberjunction/ng-dashboards 5.23.0 → 5.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts +677 -5
  2. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts.map +1 -1
  3. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js +6879 -1873
  4. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js.map +1 -1
  5. package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts +46 -1
  6. package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts.map +1 -1
  7. package/dist/AI/components/duplicates/duplicate-detection-resource.component.js +758 -491
  8. package/dist/AI/components/duplicates/duplicate-detection-resource.component.js.map +1 -1
  9. package/dist/AI/components/vectors/vector-management-resource.component.d.ts +19 -0
  10. package/dist/AI/components/vectors/vector-management-resource.component.d.ts.map +1 -1
  11. package/dist/AI/components/vectors/vector-management-resource.component.js +410 -208
  12. package/dist/AI/components/vectors/vector-management-resource.component.js.map +1 -1
  13. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
  14. package/dist/DataExplorer/data-explorer-dashboard.component.js +17 -17
  15. package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
  16. package/dist/Integration/components/activity/activity.component.d.ts.map +1 -1
  17. package/dist/Integration/components/activity/activity.component.js +1 -0
  18. package/dist/Integration/components/activity/activity.component.js.map +1 -1
  19. package/dist/Integration/components/connections/connections.component.d.ts.map +1 -1
  20. package/dist/Integration/components/connections/connections.component.js +1 -0
  21. package/dist/Integration/components/connections/connections.component.js.map +1 -1
  22. package/dist/Integration/components/mapping-workspace/mapping-workspace.component.d.ts.map +1 -1
  23. package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js +1 -0
  24. package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js.map +1 -1
  25. package/dist/Integration/components/overview/overview.component.d.ts.map +1 -1
  26. package/dist/Integration/components/overview/overview.component.js +1 -0
  27. package/dist/Integration/components/overview/overview.component.js.map +1 -1
  28. package/dist/Integration/components/pipelines/pipelines.component.d.ts.map +1 -1
  29. package/dist/Integration/components/pipelines/pipelines.component.js +1 -0
  30. package/dist/Integration/components/pipelines/pipelines.component.js.map +1 -1
  31. package/dist/Integration/components/schedules/schedules.component.d.ts.map +1 -1
  32. package/dist/Integration/components/schedules/schedules.component.js +1 -0
  33. package/dist/Integration/components/schedules/schedules.component.js.map +1 -1
  34. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.d.ts +411 -0
  35. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.d.ts.map +1 -0
  36. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js +4266 -0
  37. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js.map +1 -0
  38. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts +35 -1
  39. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts.map +1 -1
  40. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js +186 -13
  41. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js.map +1 -1
  42. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.d.ts +1 -0
  43. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.d.ts.map +1 -1
  44. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js +188 -165
  45. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js.map +1 -1
  46. package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.d.ts +75 -0
  47. package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.d.ts.map +1 -0
  48. package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.js +601 -0
  49. package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.js.map +1 -0
  50. package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.d.ts +93 -12
  51. package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.d.ts.map +1 -1
  52. package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.js +637 -107
  53. package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.js.map +1 -1
  54. package/dist/KnowledgeHub/index.d.ts +2 -0
  55. package/dist/KnowledgeHub/index.d.ts.map +1 -1
  56. package/dist/KnowledgeHub/index.js +2 -0
  57. package/dist/KnowledgeHub/index.js.map +1 -1
  58. package/dist/__tests__/analytics-resource.test.d.ts +2 -0
  59. package/dist/__tests__/analytics-resource.test.d.ts.map +1 -0
  60. package/dist/__tests__/analytics-resource.test.js +181 -0
  61. package/dist/__tests__/analytics-resource.test.js.map +1 -0
  62. package/dist/__tests__/scheduling.test.d.ts +2 -0
  63. package/dist/__tests__/scheduling.test.d.ts.map +1 -0
  64. package/dist/__tests__/scheduling.test.js +205 -0
  65. package/dist/__tests__/scheduling.test.js.map +1 -0
  66. package/dist/ai-dashboards.module.d.ts +18 -14
  67. package/dist/ai-dashboards.module.d.ts.map +1 -1
  68. package/dist/ai-dashboards.module.js +25 -5
  69. package/dist/ai-dashboards.module.js.map +1 -1
  70. package/dist/public-api.d.ts +1 -0
  71. package/dist/public-api.d.ts.map +1 -1
  72. package/dist/public-api.js +1 -0
  73. package/dist/public-api.js.map +1 -1
  74. package/dist/shared/entity-field-display.d.ts +44 -0
  75. package/dist/shared/entity-field-display.d.ts.map +1 -0
  76. package/dist/shared/entity-field-display.js +118 -0
  77. package/dist/shared/entity-field-display.js.map +1 -0
  78. package/package.json +47 -46
@@ -12,10 +12,10 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
12
12
  * Supports triggering new detection runs with real-time progress via
13
13
  * GraphQL subscriptions.
14
14
  */
15
- import { Component, ChangeDetectorRef, Input, inject, ViewEncapsulation } from '@angular/core';
15
+ import { Component, ChangeDetectorRef, Input, inject, ViewEncapsulation, HostListener } from '@angular/core';
16
16
  import { Subject } from 'rxjs';
17
17
  import { debounceTime, takeUntil } from 'rxjs/operators';
18
- import { CompositeKey, Metadata, RecordMergeRequest, RunView } from '@memberjunction/core';
18
+ import { CompositeKey, LogStatus, Metadata, RecordMergeRequest, RunView } from '@memberjunction/core';
19
19
  import { MJNotificationService } from '@memberjunction/ng-notifications';
20
20
  import { KnowledgeHubMetadataEngine } from '@memberjunction/core-entities';
21
21
  import { RegisterClass, UUIDsEqual } from '@memberjunction/global';
@@ -41,15 +41,15 @@ function DuplicateDetectionResourceComponent_For_12_Template(rf, ctx) { if (rf &
41
41
  i0.ɵɵtextInterpolate2("", doc_r1.Name, " (", doc_r1.EntityName, ")");
42
42
  } }
43
43
  function DuplicateDetectionResourceComponent_Conditional_14_Template(rf, ctx) { if (rf & 1) {
44
- i0.ɵɵelement(0, "i", 33);
44
+ i0.ɵɵelement(0, "i", 34);
45
45
  i0.ɵɵtext(1, " Detecting... ");
46
46
  } }
47
47
  function DuplicateDetectionResourceComponent_Conditional_15_Template(rf, ctx) { if (rf & 1) {
48
- i0.ɵɵelement(0, "i", 34);
48
+ i0.ɵɵelement(0, "i", 35);
49
49
  i0.ɵɵtext(1, " Run Detection ");
50
50
  } }
51
51
  function DuplicateDetectionResourceComponent_Conditional_16_Conditional_9_Template(rf, ctx) { if (rf & 1) {
52
- i0.ɵɵelementStart(0, "span", 40);
52
+ i0.ɵɵelementStart(0, "span", 41);
53
53
  i0.ɵɵtext(1);
54
54
  i0.ɵɵelementEnd();
55
55
  } if (rf & 2) {
@@ -58,17 +58,17 @@ function DuplicateDetectionResourceComponent_Conditional_16_Conditional_9_Templa
58
58
  i0.ɵɵtextInterpolate(ctx_r1.DetectionCurrentItem);
59
59
  } }
60
60
  function DuplicateDetectionResourceComponent_Conditional_16_Template(rf, ctx) { if (rf & 1) {
61
- i0.ɵɵelementStart(0, "div", 11)(1, "div", 35)(2, "span", 36);
62
- i0.ɵɵelement(3, "i", 33);
61
+ i0.ɵɵelementStart(0, "div", 11)(1, "div", 36)(2, "span", 37);
62
+ i0.ɵɵelement(3, "i", 34);
63
63
  i0.ɵɵtext(4);
64
64
  i0.ɵɵelementEnd();
65
- i0.ɵɵelementStart(5, "span", 37);
65
+ i0.ɵɵelementStart(5, "span", 38);
66
66
  i0.ɵɵtext(6);
67
67
  i0.ɵɵelementEnd()();
68
- i0.ɵɵelementStart(7, "div", 38);
69
- i0.ɵɵelement(8, "div", 39);
68
+ i0.ɵɵelementStart(7, "div", 39);
69
+ i0.ɵɵelement(8, "div", 40);
70
70
  i0.ɵɵelementEnd();
71
- i0.ɵɵconditionalCreate(9, DuplicateDetectionResourceComponent_Conditional_16_Conditional_9_Template, 2, 1, "span", 40);
71
+ i0.ɵɵconditionalCreate(9, DuplicateDetectionResourceComponent_Conditional_16_Conditional_9_Template, 2, 1, "span", 41);
72
72
  i0.ɵɵelementEnd();
73
73
  } if (rf & 2) {
74
74
  const ctx_r1 = i0.ɵɵnextContext();
@@ -83,28 +83,28 @@ function DuplicateDetectionResourceComponent_Conditional_16_Template(rf, ctx) {
83
83
  } }
84
84
  function DuplicateDetectionResourceComponent_Conditional_17_Template(rf, ctx) { if (rf & 1) {
85
85
  const _r3 = i0.ɵɵgetCurrentView();
86
- i0.ɵɵelementStart(0, "div", 12)(1, "div", 41)(2, "label", 42);
87
- i0.ɵɵelement(3, "i", 43);
86
+ i0.ɵɵelementStart(0, "div", 12)(1, "div", 42)(2, "label", 43);
87
+ i0.ɵɵelement(3, "i", 44);
88
88
  i0.ɵɵtext(4, " Potential Match ");
89
- i0.ɵɵelementStart(5, "span", 44);
89
+ i0.ɵɵelementStart(5, "span", 45);
90
90
  i0.ɵɵtext(6);
91
91
  i0.ɵɵelementEnd()();
92
- i0.ɵɵelementStart(7, "input", 45);
92
+ i0.ɵɵelementStart(7, "input", 46);
93
93
  i0.ɵɵlistener("input", function DuplicateDetectionResourceComponent_Conditional_17_Template_input_input_7_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnPotentialThresholdChanged($event.target.value / 100)); });
94
94
  i0.ɵɵelementEnd();
95
- i0.ɵɵelementStart(8, "span", 46);
95
+ i0.ɵɵelementStart(8, "span", 47);
96
96
  i0.ɵɵtext(9, "Score above which duplicates are flagged for review");
97
97
  i0.ɵɵelementEnd()();
98
- i0.ɵɵelementStart(10, "div", 41)(11, "label", 42);
99
- i0.ɵɵelement(12, "i", 47);
98
+ i0.ɵɵelementStart(10, "div", 42)(11, "label", 43);
99
+ i0.ɵɵelement(12, "i", 48);
100
100
  i0.ɵɵtext(13, " Absolute Match ");
101
- i0.ɵɵelementStart(14, "span", 44);
101
+ i0.ɵɵelementStart(14, "span", 45);
102
102
  i0.ɵɵtext(15);
103
103
  i0.ɵɵelementEnd()();
104
- i0.ɵɵelementStart(16, "input", 45);
104
+ i0.ɵɵelementStart(16, "input", 46);
105
105
  i0.ɵɵlistener("input", function DuplicateDetectionResourceComponent_Conditional_17_Template_input_input_16_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnAbsoluteThresholdChanged($event.target.value / 100)); });
106
106
  i0.ɵɵelementEnd();
107
- i0.ɵɵelementStart(17, "span", 46);
107
+ i0.ɵɵelementStart(17, "span", 47);
108
108
  i0.ɵɵtext(18, "Score above which duplicates are auto-confirmed");
109
109
  i0.ɵɵelementEnd()()();
110
110
  } if (rf & 2) {
@@ -135,32 +135,43 @@ function DuplicateDetectionResourceComponent_For_44_Template(rf, ctx) { if (rf &
135
135
  } }
136
136
  function DuplicateDetectionResourceComponent_Conditional_61_Template(rf, ctx) { if (rf & 1) {
137
137
  const _r5 = i0.ɵɵgetCurrentView();
138
- i0.ɵɵelementStart(0, "button", 48);
138
+ i0.ɵɵelementStart(0, "button", 49);
139
139
  i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_61_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ClearFilters()); });
140
- i0.ɵɵelement(1, "i", 49);
140
+ i0.ɵɵelement(1, "i", 50);
141
141
  i0.ɵɵtext(2, " Clear Filters ");
142
142
  i0.ɵɵelementEnd();
143
143
  } }
144
144
  function DuplicateDetectionResourceComponent_Conditional_62_Template(rf, ctx) { if (rf & 1) {
145
145
  i0.ɵɵelementStart(0, "div", 28);
146
- i0.ɵɵelement(1, "mj-loading", 50);
146
+ i0.ɵɵelement(1, "i", 51);
147
+ i0.ɵɵtext(2, " Merging is not available for this entity. Detection results are read-only. ");
147
148
  i0.ɵɵelementEnd();
148
149
  } }
149
150
  function DuplicateDetectionResourceComponent_Conditional_63_Template(rf, ctx) { if (rf & 1) {
150
151
  i0.ɵɵelementStart(0, "div", 29);
151
- i0.ɵɵelement(1, "i", 51);
152
- i0.ɵɵelementStart(2, "p", 52);
152
+ i0.ɵɵelement(1, "mj-loading", 52);
153
+ i0.ɵɵelementEnd();
154
+ } }
155
+ function DuplicateDetectionResourceComponent_Conditional_64_Template(rf, ctx) { if (rf & 1) {
156
+ i0.ɵɵelementStart(0, "div", 29);
157
+ i0.ɵɵelement(1, "mj-loading", 52);
158
+ i0.ɵɵelementEnd();
159
+ } }
160
+ function DuplicateDetectionResourceComponent_Conditional_65_Template(rf, ctx) { if (rf & 1) {
161
+ i0.ɵɵelementStart(0, "div", 30);
162
+ i0.ɵɵelement(1, "i", 53);
163
+ i0.ɵɵelementStart(2, "p", 54);
153
164
  i0.ɵɵtext(3, "No duplicate detection results found.");
154
165
  i0.ɵɵelementEnd();
155
- i0.ɵɵelementStart(4, "p", 53);
166
+ i0.ɵɵelementStart(4, "p", 55);
156
167
  i0.ɵɵtext(5, "Select an entity document and click \"Run Detection\" to start.");
157
168
  i0.ɵɵelementEnd()();
158
169
  } }
159
- function DuplicateDetectionResourceComponent_Conditional_64_For_10_Conditional_13_For_2_Template(rf, ctx) { if (rf & 1) {
160
- i0.ɵɵelementStart(0, "div", 84)(1, "span", 86);
170
+ function DuplicateDetectionResourceComponent_Conditional_66_For_10_Conditional_13_For_2_Template(rf, ctx) { if (rf & 1) {
171
+ i0.ɵɵelementStart(0, "div", 86)(1, "span", 88);
161
172
  i0.ɵɵtext(2);
162
173
  i0.ɵɵelementEnd();
163
- i0.ɵɵelementStart(3, "span", 87);
174
+ i0.ɵɵelementStart(3, "span", 89);
164
175
  i0.ɵɵtext(4);
165
176
  i0.ɵɵelementEnd()();
166
177
  } if (rf & 2) {
@@ -170,8 +181,8 @@ function DuplicateDetectionResourceComponent_Conditional_64_For_10_Conditional_1
170
181
  i0.ɵɵadvance(2);
171
182
  i0.ɵɵtextInterpolate(ms_r9.Name);
172
183
  } }
173
- function DuplicateDetectionResourceComponent_Conditional_64_For_10_Conditional_13_Conditional_3_Template(rf, ctx) { if (rf & 1) {
174
- i0.ɵɵelementStart(0, "div", 85);
184
+ function DuplicateDetectionResourceComponent_Conditional_66_For_10_Conditional_13_Conditional_3_Template(rf, ctx) { if (rf & 1) {
185
+ i0.ɵɵelementStart(0, "div", 87);
175
186
  i0.ɵɵtext(1);
176
187
  i0.ɵɵelementEnd();
177
188
  } if (rf & 2) {
@@ -179,10 +190,10 @@ function DuplicateDetectionResourceComponent_Conditional_64_For_10_Conditional_1
179
190
  i0.ɵɵadvance();
180
191
  i0.ɵɵtextInterpolate1("+", group_r8.MatchCount - group_r8.TopMatchSummaries.length, " more");
181
192
  } }
182
- function DuplicateDetectionResourceComponent_Conditional_64_For_10_Conditional_13_Template(rf, ctx) { if (rf & 1) {
183
- i0.ɵɵelementStart(0, "div", 75);
184
- i0.ɵɵrepeaterCreate(1, DuplicateDetectionResourceComponent_Conditional_64_For_10_Conditional_13_For_2_Template, 5, 2, "div", 84, _forTrack2);
185
- i0.ɵɵconditionalCreate(3, DuplicateDetectionResourceComponent_Conditional_64_For_10_Conditional_13_Conditional_3_Template, 2, 1, "div", 85);
193
+ function DuplicateDetectionResourceComponent_Conditional_66_For_10_Conditional_13_Template(rf, ctx) { if (rf & 1) {
194
+ i0.ɵɵelementStart(0, "div", 77);
195
+ i0.ɵɵrepeaterCreate(1, DuplicateDetectionResourceComponent_Conditional_66_For_10_Conditional_13_For_2_Template, 5, 2, "div", 86, _forTrack2);
196
+ i0.ɵɵconditionalCreate(3, DuplicateDetectionResourceComponent_Conditional_66_For_10_Conditional_13_Conditional_3_Template, 2, 1, "div", 87);
186
197
  i0.ɵɵelementEnd();
187
198
  } if (rf & 2) {
188
199
  const group_r8 = i0.ɵɵnextContext().$implicit;
@@ -191,40 +202,40 @@ function DuplicateDetectionResourceComponent_Conditional_64_For_10_Conditional_1
191
202
  i0.ɵɵadvance(2);
192
203
  i0.ɵɵconditional(group_r8.MatchCount > group_r8.TopMatchSummaries.length ? 3 : -1);
193
204
  } }
194
- function DuplicateDetectionResourceComponent_Conditional_64_For_10_Template(rf, ctx) { if (rf & 1) {
205
+ function DuplicateDetectionResourceComponent_Conditional_66_For_10_Template(rf, ctx) { if (rf & 1) {
195
206
  const _r7 = i0.ɵɵgetCurrentView();
196
- i0.ɵɵelementStart(0, "div", 66);
197
- i0.ɵɵlistener("dragstart", function DuplicateDetectionResourceComponent_Conditional_64_For_10_Template_div_dragstart_0_listener($event) { const group_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDragStart($event, group_r8)); })("dragend", function DuplicateDetectionResourceComponent_Conditional_64_For_10_Template_div_dragend_0_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDragEnd()); })("click", function DuplicateDetectionResourceComponent_Conditional_64_For_10_Template_div_click_0_listener() { const group_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OpenComparison(group_r8)); });
198
- i0.ɵɵelementStart(1, "div", 67)(2, "div", 68)(3, "div", 69);
207
+ i0.ɵɵelementStart(0, "div", 68);
208
+ i0.ɵɵlistener("dragstart", function DuplicateDetectionResourceComponent_Conditional_66_For_10_Template_div_dragstart_0_listener($event) { const group_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDragStart($event, group_r8)); })("dragend", function DuplicateDetectionResourceComponent_Conditional_66_For_10_Template_div_dragend_0_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDragEnd()); })("click", function DuplicateDetectionResourceComponent_Conditional_66_For_10_Template_div_click_0_listener() { const group_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OpenComparison(group_r8)); });
209
+ i0.ɵɵelementStart(1, "div", 69)(2, "div", 70)(3, "div", 71);
199
210
  i0.ɵɵelement(4, "i");
200
211
  i0.ɵɵelementEnd();
201
- i0.ɵɵelementStart(5, "div", 70)(6, "div", 71);
212
+ i0.ɵɵelementStart(5, "div", 72)(6, "div", 73);
202
213
  i0.ɵɵtext(7);
203
214
  i0.ɵɵelementEnd();
204
- i0.ɵɵelementStart(8, "span", 72);
215
+ i0.ɵɵelementStart(8, "span", 74);
205
216
  i0.ɵɵtext(9);
206
217
  i0.ɵɵelementEnd()()();
207
- i0.ɵɵelementStart(10, "span", 73);
218
+ i0.ɵɵelementStart(10, "span", 75);
208
219
  i0.ɵɵtext(11);
209
220
  i0.ɵɵelementEnd()();
210
- i0.ɵɵelementStart(12, "div", 74);
211
- i0.ɵɵconditionalCreate(13, DuplicateDetectionResourceComponent_Conditional_64_For_10_Conditional_13_Template, 4, 1, "div", 75);
212
- i0.ɵɵelementStart(14, "div", 76)(15, "span", 77);
213
- i0.ɵɵelement(16, "i", 78);
221
+ i0.ɵɵelementStart(12, "div", 76);
222
+ i0.ɵɵconditionalCreate(13, DuplicateDetectionResourceComponent_Conditional_66_For_10_Conditional_13_Template, 4, 1, "div", 77);
223
+ i0.ɵɵelementStart(14, "div", 78)(15, "span", 79);
224
+ i0.ɵɵelement(16, "i", 80);
214
225
  i0.ɵɵtext(17);
215
226
  i0.ɵɵelementEnd();
216
- i0.ɵɵelementStart(18, "span", 77);
217
- i0.ɵɵelement(19, "i", 79);
227
+ i0.ɵɵelementStart(18, "span", 79);
228
+ i0.ɵɵelement(19, "i", 81);
218
229
  i0.ɵɵtext(20);
219
230
  i0.ɵɵelementEnd()()();
220
- i0.ɵɵelementStart(21, "div", 80)(22, "button", 81);
221
- i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_64_For_10_Template_button_click_22_listener($event) { const group_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); ctx_r1.ApproveMatch(group_r8); return i0.ɵɵresetView($event.stopPropagation()); });
222
- i0.ɵɵelement(23, "i", 82);
231
+ i0.ɵɵelementStart(21, "div", 82)(22, "button", 83);
232
+ i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_66_For_10_Template_button_click_22_listener($event) { const group_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); ctx_r1.ApproveMatch(group_r8); return i0.ɵɵresetView($event.stopPropagation()); });
233
+ i0.ɵɵelement(23, "i", 84);
223
234
  i0.ɵɵtext(24, " Approve ");
224
235
  i0.ɵɵelementEnd();
225
- i0.ɵɵelementStart(25, "button", 83);
226
- i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_64_For_10_Template_button_click_25_listener($event) { const group_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); ctx_r1.RejectMatch(group_r8); return i0.ɵɵresetView($event.stopPropagation()); });
227
- i0.ɵɵelement(26, "i", 49);
236
+ i0.ɵɵelementStart(25, "button", 85);
237
+ i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_66_For_10_Template_button_click_25_listener($event) { const group_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); ctx_r1.RejectMatch(group_r8); return i0.ɵɵresetView($event.stopPropagation()); });
238
+ i0.ɵɵelement(26, "i", 50);
228
239
  i0.ɵɵtext(27, " Reject ");
229
240
  i0.ɵɵelementEnd()()();
230
241
  } if (rf & 2) {
@@ -253,18 +264,18 @@ function DuplicateDetectionResourceComponent_Conditional_64_For_10_Template(rf,
253
264
  i0.ɵɵadvance(3);
254
265
  i0.ɵɵproperty("disabled", ctx_r1.IsSaving);
255
266
  } }
256
- function DuplicateDetectionResourceComponent_Conditional_64_Conditional_11_Template(rf, ctx) { if (rf & 1) {
257
- i0.ɵɵelementStart(0, "div", 61);
258
- i0.ɵɵelement(1, "i", 63);
267
+ function DuplicateDetectionResourceComponent_Conditional_66_Conditional_11_Template(rf, ctx) { if (rf & 1) {
268
+ i0.ɵɵelementStart(0, "div", 63);
269
+ i0.ɵɵelement(1, "i", 65);
259
270
  i0.ɵɵelementStart(2, "span");
260
271
  i0.ɵɵtext(3, "No pending items");
261
272
  i0.ɵɵelementEnd()();
262
273
  } }
263
- function DuplicateDetectionResourceComponent_Conditional_64_For_21_Conditional_13_For_2_Template(rf, ctx) { if (rf & 1) {
264
- i0.ɵɵelementStart(0, "div", 84)(1, "span", 86);
274
+ function DuplicateDetectionResourceComponent_Conditional_66_For_21_Conditional_13_For_2_Template(rf, ctx) { if (rf & 1) {
275
+ i0.ɵɵelementStart(0, "div", 86)(1, "span", 88);
265
276
  i0.ɵɵtext(2);
266
277
  i0.ɵɵelementEnd();
267
- i0.ɵɵelementStart(3, "span", 87);
278
+ i0.ɵɵelementStart(3, "span", 89);
268
279
  i0.ɵɵtext(4);
269
280
  i0.ɵɵelementEnd()();
270
281
  } if (rf & 2) {
@@ -274,8 +285,8 @@ function DuplicateDetectionResourceComponent_Conditional_64_For_21_Conditional_1
274
285
  i0.ɵɵadvance(2);
275
286
  i0.ɵɵtextInterpolate(ms_r12.Name);
276
287
  } }
277
- function DuplicateDetectionResourceComponent_Conditional_64_For_21_Conditional_13_Conditional_3_Template(rf, ctx) { if (rf & 1) {
278
- i0.ɵɵelementStart(0, "div", 85);
288
+ function DuplicateDetectionResourceComponent_Conditional_66_For_21_Conditional_13_Conditional_3_Template(rf, ctx) { if (rf & 1) {
289
+ i0.ɵɵelementStart(0, "div", 87);
279
290
  i0.ɵɵtext(1);
280
291
  i0.ɵɵelementEnd();
281
292
  } if (rf & 2) {
@@ -283,10 +294,10 @@ function DuplicateDetectionResourceComponent_Conditional_64_For_21_Conditional_1
283
294
  i0.ɵɵadvance();
284
295
  i0.ɵɵtextInterpolate1("+", group_r11.MatchCount - group_r11.TopMatchSummaries.length, " more");
285
296
  } }
286
- function DuplicateDetectionResourceComponent_Conditional_64_For_21_Conditional_13_Template(rf, ctx) { if (rf & 1) {
287
- i0.ɵɵelementStart(0, "div", 75);
288
- i0.ɵɵrepeaterCreate(1, DuplicateDetectionResourceComponent_Conditional_64_For_21_Conditional_13_For_2_Template, 5, 2, "div", 84, _forTrack2);
289
- i0.ɵɵconditionalCreate(3, DuplicateDetectionResourceComponent_Conditional_64_For_21_Conditional_13_Conditional_3_Template, 2, 1, "div", 85);
297
+ function DuplicateDetectionResourceComponent_Conditional_66_For_21_Conditional_13_Template(rf, ctx) { if (rf & 1) {
298
+ i0.ɵɵelementStart(0, "div", 77);
299
+ i0.ɵɵrepeaterCreate(1, DuplicateDetectionResourceComponent_Conditional_66_For_21_Conditional_13_For_2_Template, 5, 2, "div", 86, _forTrack2);
300
+ i0.ɵɵconditionalCreate(3, DuplicateDetectionResourceComponent_Conditional_66_For_21_Conditional_13_Conditional_3_Template, 2, 1, "div", 87);
290
301
  i0.ɵɵelementEnd();
291
302
  } if (rf & 2) {
292
303
  const group_r11 = i0.ɵɵnextContext().$implicit;
@@ -295,30 +306,30 @@ function DuplicateDetectionResourceComponent_Conditional_64_For_21_Conditional_1
295
306
  i0.ɵɵadvance(2);
296
307
  i0.ɵɵconditional(group_r11.MatchCount > group_r11.TopMatchSummaries.length ? 3 : -1);
297
308
  } }
298
- function DuplicateDetectionResourceComponent_Conditional_64_For_21_Template(rf, ctx) { if (rf & 1) {
309
+ function DuplicateDetectionResourceComponent_Conditional_66_For_21_Template(rf, ctx) { if (rf & 1) {
299
310
  const _r10 = i0.ɵɵgetCurrentView();
300
- i0.ɵɵelementStart(0, "div", 66);
301
- i0.ɵɵlistener("dragstart", function DuplicateDetectionResourceComponent_Conditional_64_For_21_Template_div_dragstart_0_listener($event) { const group_r11 = i0.ɵɵrestoreView(_r10).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDragStart($event, group_r11)); })("dragend", function DuplicateDetectionResourceComponent_Conditional_64_For_21_Template_div_dragend_0_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDragEnd()); })("click", function DuplicateDetectionResourceComponent_Conditional_64_For_21_Template_div_click_0_listener() { const group_r11 = i0.ɵɵrestoreView(_r10).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OpenComparison(group_r11)); });
302
- i0.ɵɵelementStart(1, "div", 67)(2, "div", 68)(3, "div", 69);
311
+ i0.ɵɵelementStart(0, "div", 68);
312
+ i0.ɵɵlistener("dragstart", function DuplicateDetectionResourceComponent_Conditional_66_For_21_Template_div_dragstart_0_listener($event) { const group_r11 = i0.ɵɵrestoreView(_r10).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDragStart($event, group_r11)); })("dragend", function DuplicateDetectionResourceComponent_Conditional_66_For_21_Template_div_dragend_0_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDragEnd()); })("click", function DuplicateDetectionResourceComponent_Conditional_66_For_21_Template_div_click_0_listener() { const group_r11 = i0.ɵɵrestoreView(_r10).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OpenComparison(group_r11)); });
313
+ i0.ɵɵelementStart(1, "div", 69)(2, "div", 70)(3, "div", 71);
303
314
  i0.ɵɵelement(4, "i");
304
315
  i0.ɵɵelementEnd();
305
- i0.ɵɵelementStart(5, "div", 70)(6, "div", 71);
316
+ i0.ɵɵelementStart(5, "div", 72)(6, "div", 73);
306
317
  i0.ɵɵtext(7);
307
318
  i0.ɵɵelementEnd();
308
- i0.ɵɵelementStart(8, "span", 72);
319
+ i0.ɵɵelementStart(8, "span", 74);
309
320
  i0.ɵɵtext(9);
310
321
  i0.ɵɵelementEnd()()();
311
- i0.ɵɵelementStart(10, "span", 73);
322
+ i0.ɵɵelementStart(10, "span", 75);
312
323
  i0.ɵɵtext(11);
313
324
  i0.ɵɵelementEnd()();
314
- i0.ɵɵelementStart(12, "div", 74);
315
- i0.ɵɵconditionalCreate(13, DuplicateDetectionResourceComponent_Conditional_64_For_21_Conditional_13_Template, 4, 1, "div", 75);
316
- i0.ɵɵelementStart(14, "div", 76)(15, "span", 77);
317
- i0.ɵɵelement(16, "i", 78);
325
+ i0.ɵɵelementStart(12, "div", 76);
326
+ i0.ɵɵconditionalCreate(13, DuplicateDetectionResourceComponent_Conditional_66_For_21_Conditional_13_Template, 4, 1, "div", 77);
327
+ i0.ɵɵelementStart(14, "div", 78)(15, "span", 79);
328
+ i0.ɵɵelement(16, "i", 80);
318
329
  i0.ɵɵtext(17);
319
330
  i0.ɵɵelementEnd();
320
- i0.ɵɵelementStart(18, "span", 77);
321
- i0.ɵɵelement(19, "i", 79);
331
+ i0.ɵɵelementStart(18, "span", 79);
332
+ i0.ɵɵelement(19, "i", 81);
322
333
  i0.ɵɵtext(20);
323
334
  i0.ɵɵelementEnd()()()();
324
335
  } if (rf & 2) {
@@ -343,18 +354,18 @@ function DuplicateDetectionResourceComponent_Conditional_64_For_21_Template(rf,
343
354
  i0.ɵɵadvance(3);
344
355
  i0.ɵɵtextInterpolate1(" ", ctx_r1.FormatDate(group_r11.MatchedAt), " ");
345
356
  } }
346
- function DuplicateDetectionResourceComponent_Conditional_64_Conditional_22_Template(rf, ctx) { if (rf & 1) {
347
- i0.ɵɵelementStart(0, "div", 61);
348
- i0.ɵɵelement(1, "i", 88);
357
+ function DuplicateDetectionResourceComponent_Conditional_66_Conditional_22_Template(rf, ctx) { if (rf & 1) {
358
+ i0.ɵɵelementStart(0, "div", 63);
359
+ i0.ɵɵelement(1, "i", 90);
349
360
  i0.ɵɵelementStart(2, "span");
350
361
  i0.ɵɵtext(3, "No approved items");
351
362
  i0.ɵɵelementEnd()();
352
363
  } }
353
- function DuplicateDetectionResourceComponent_Conditional_64_For_32_Conditional_13_For_2_Template(rf, ctx) { if (rf & 1) {
354
- i0.ɵɵelementStart(0, "div", 84)(1, "span", 86);
364
+ function DuplicateDetectionResourceComponent_Conditional_66_For_32_Conditional_13_For_2_Template(rf, ctx) { if (rf & 1) {
365
+ i0.ɵɵelementStart(0, "div", 86)(1, "span", 88);
355
366
  i0.ɵɵtext(2);
356
367
  i0.ɵɵelementEnd();
357
- i0.ɵɵelementStart(3, "span", 87);
368
+ i0.ɵɵelementStart(3, "span", 89);
358
369
  i0.ɵɵtext(4);
359
370
  i0.ɵɵelementEnd()();
360
371
  } if (rf & 2) {
@@ -364,8 +375,8 @@ function DuplicateDetectionResourceComponent_Conditional_64_For_32_Conditional_1
364
375
  i0.ɵɵadvance(2);
365
376
  i0.ɵɵtextInterpolate(ms_r15.Name);
366
377
  } }
367
- function DuplicateDetectionResourceComponent_Conditional_64_For_32_Conditional_13_Conditional_3_Template(rf, ctx) { if (rf & 1) {
368
- i0.ɵɵelementStart(0, "div", 85);
378
+ function DuplicateDetectionResourceComponent_Conditional_66_For_32_Conditional_13_Conditional_3_Template(rf, ctx) { if (rf & 1) {
379
+ i0.ɵɵelementStart(0, "div", 87);
369
380
  i0.ɵɵtext(1);
370
381
  i0.ɵɵelementEnd();
371
382
  } if (rf & 2) {
@@ -373,10 +384,10 @@ function DuplicateDetectionResourceComponent_Conditional_64_For_32_Conditional_1
373
384
  i0.ɵɵadvance();
374
385
  i0.ɵɵtextInterpolate1("+", group_r14.MatchCount - group_r14.TopMatchSummaries.length, " more");
375
386
  } }
376
- function DuplicateDetectionResourceComponent_Conditional_64_For_32_Conditional_13_Template(rf, ctx) { if (rf & 1) {
377
- i0.ɵɵelementStart(0, "div", 75);
378
- i0.ɵɵrepeaterCreate(1, DuplicateDetectionResourceComponent_Conditional_64_For_32_Conditional_13_For_2_Template, 5, 2, "div", 84, _forTrack2);
379
- i0.ɵɵconditionalCreate(3, DuplicateDetectionResourceComponent_Conditional_64_For_32_Conditional_13_Conditional_3_Template, 2, 1, "div", 85);
387
+ function DuplicateDetectionResourceComponent_Conditional_66_For_32_Conditional_13_Template(rf, ctx) { if (rf & 1) {
388
+ i0.ɵɵelementStart(0, "div", 77);
389
+ i0.ɵɵrepeaterCreate(1, DuplicateDetectionResourceComponent_Conditional_66_For_32_Conditional_13_For_2_Template, 5, 2, "div", 86, _forTrack2);
390
+ i0.ɵɵconditionalCreate(3, DuplicateDetectionResourceComponent_Conditional_66_For_32_Conditional_13_Conditional_3_Template, 2, 1, "div", 87);
380
391
  i0.ɵɵelementEnd();
381
392
  } if (rf & 2) {
382
393
  const group_r14 = i0.ɵɵnextContext().$implicit;
@@ -385,30 +396,30 @@ function DuplicateDetectionResourceComponent_Conditional_64_For_32_Conditional_1
385
396
  i0.ɵɵadvance(2);
386
397
  i0.ɵɵconditional(group_r14.MatchCount > group_r14.TopMatchSummaries.length ? 3 : -1);
387
398
  } }
388
- function DuplicateDetectionResourceComponent_Conditional_64_For_32_Template(rf, ctx) { if (rf & 1) {
399
+ function DuplicateDetectionResourceComponent_Conditional_66_For_32_Template(rf, ctx) { if (rf & 1) {
389
400
  const _r13 = i0.ɵɵgetCurrentView();
390
- i0.ɵɵelementStart(0, "div", 66);
391
- i0.ɵɵlistener("dragstart", function DuplicateDetectionResourceComponent_Conditional_64_For_32_Template_div_dragstart_0_listener($event) { const group_r14 = i0.ɵɵrestoreView(_r13).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDragStart($event, group_r14)); })("dragend", function DuplicateDetectionResourceComponent_Conditional_64_For_32_Template_div_dragend_0_listener() { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDragEnd()); })("click", function DuplicateDetectionResourceComponent_Conditional_64_For_32_Template_div_click_0_listener() { const group_r14 = i0.ɵɵrestoreView(_r13).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OpenComparison(group_r14)); });
392
- i0.ɵɵelementStart(1, "div", 67)(2, "div", 68)(3, "div", 69);
401
+ i0.ɵɵelementStart(0, "div", 68);
402
+ i0.ɵɵlistener("dragstart", function DuplicateDetectionResourceComponent_Conditional_66_For_32_Template_div_dragstart_0_listener($event) { const group_r14 = i0.ɵɵrestoreView(_r13).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDragStart($event, group_r14)); })("dragend", function DuplicateDetectionResourceComponent_Conditional_66_For_32_Template_div_dragend_0_listener() { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDragEnd()); })("click", function DuplicateDetectionResourceComponent_Conditional_66_For_32_Template_div_click_0_listener() { const group_r14 = i0.ɵɵrestoreView(_r13).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OpenComparison(group_r14)); });
403
+ i0.ɵɵelementStart(1, "div", 69)(2, "div", 70)(3, "div", 71);
393
404
  i0.ɵɵelement(4, "i");
394
405
  i0.ɵɵelementEnd();
395
- i0.ɵɵelementStart(5, "div", 70)(6, "div", 71);
406
+ i0.ɵɵelementStart(5, "div", 72)(6, "div", 73);
396
407
  i0.ɵɵtext(7);
397
408
  i0.ɵɵelementEnd();
398
- i0.ɵɵelementStart(8, "span", 72);
409
+ i0.ɵɵelementStart(8, "span", 74);
399
410
  i0.ɵɵtext(9);
400
411
  i0.ɵɵelementEnd()()();
401
- i0.ɵɵelementStart(10, "span", 73);
412
+ i0.ɵɵelementStart(10, "span", 75);
402
413
  i0.ɵɵtext(11);
403
414
  i0.ɵɵelementEnd()();
404
- i0.ɵɵelementStart(12, "div", 74);
405
- i0.ɵɵconditionalCreate(13, DuplicateDetectionResourceComponent_Conditional_64_For_32_Conditional_13_Template, 4, 1, "div", 75);
406
- i0.ɵɵelementStart(14, "div", 76)(15, "span", 77);
407
- i0.ɵɵelement(16, "i", 78);
415
+ i0.ɵɵelementStart(12, "div", 76);
416
+ i0.ɵɵconditionalCreate(13, DuplicateDetectionResourceComponent_Conditional_66_For_32_Conditional_13_Template, 4, 1, "div", 77);
417
+ i0.ɵɵelementStart(14, "div", 78)(15, "span", 79);
418
+ i0.ɵɵelement(16, "i", 80);
408
419
  i0.ɵɵtext(17);
409
420
  i0.ɵɵelementEnd();
410
- i0.ɵɵelementStart(18, "span", 77);
411
- i0.ɵɵelement(19, "i", 79);
421
+ i0.ɵɵelementStart(18, "span", 79);
422
+ i0.ɵɵelement(19, "i", 81);
412
423
  i0.ɵɵtext(20);
413
424
  i0.ɵɵelementEnd()()()();
414
425
  } if (rf & 2) {
@@ -433,53 +444,53 @@ function DuplicateDetectionResourceComponent_Conditional_64_For_32_Template(rf,
433
444
  i0.ɵɵadvance(3);
434
445
  i0.ɵɵtextInterpolate1(" ", ctx_r1.FormatDate(group_r14.MatchedAt), " ");
435
446
  } }
436
- function DuplicateDetectionResourceComponent_Conditional_64_Conditional_33_Template(rf, ctx) { if (rf & 1) {
437
- i0.ɵɵelementStart(0, "div", 61);
438
- i0.ɵɵelement(1, "i", 88);
447
+ function DuplicateDetectionResourceComponent_Conditional_66_Conditional_33_Template(rf, ctx) { if (rf & 1) {
448
+ i0.ɵɵelementStart(0, "div", 63);
449
+ i0.ɵɵelement(1, "i", 90);
439
450
  i0.ɵɵelementStart(2, "span");
440
451
  i0.ɵɵtext(3, "No rejected items");
441
452
  i0.ɵɵelementEnd()();
442
453
  } }
443
- function DuplicateDetectionResourceComponent_Conditional_64_Template(rf, ctx) { if (rf & 1) {
454
+ function DuplicateDetectionResourceComponent_Conditional_66_Template(rf, ctx) { if (rf & 1) {
444
455
  const _r6 = i0.ɵɵgetCurrentView();
445
- i0.ɵɵelementStart(0, "div", 30)(1, "div", 54)(2, "div", 55);
446
- i0.ɵɵelement(3, "i", 56);
447
- i0.ɵɵelementStart(4, "span", 57);
456
+ i0.ɵɵelementStart(0, "div", 31)(1, "div", 56)(2, "div", 57);
457
+ i0.ɵɵelement(3, "i", 58);
458
+ i0.ɵɵelementStart(4, "span", 59);
448
459
  i0.ɵɵtext(5, "Pending Review");
449
460
  i0.ɵɵelementEnd();
450
- i0.ɵɵelementStart(6, "span", 58);
461
+ i0.ɵɵelementStart(6, "span", 60);
451
462
  i0.ɵɵtext(7);
452
463
  i0.ɵɵelementEnd()();
453
- i0.ɵɵelementStart(8, "div", 59);
454
- i0.ɵɵlistener("dragover", function DuplicateDetectionResourceComponent_Conditional_64_Template_div_dragover_8_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDragOver($event, "Pending")); })("dragleave", function DuplicateDetectionResourceComponent_Conditional_64_Template_div_dragleave_8_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDragLeave($event, "Pending")); })("drop", function DuplicateDetectionResourceComponent_Conditional_64_Template_div_drop_8_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDrop($event, "Pending")); });
455
- i0.ɵɵrepeaterCreate(9, DuplicateDetectionResourceComponent_Conditional_64_For_10_Template, 28, 14, "div", 60, _forTrack1);
456
- i0.ɵɵconditionalCreate(11, DuplicateDetectionResourceComponent_Conditional_64_Conditional_11_Template, 4, 0, "div", 61);
464
+ i0.ɵɵelementStart(8, "div", 61);
465
+ i0.ɵɵlistener("dragover", function DuplicateDetectionResourceComponent_Conditional_66_Template_div_dragover_8_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDragOver($event, "Pending")); })("dragleave", function DuplicateDetectionResourceComponent_Conditional_66_Template_div_dragleave_8_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDragLeave($event, "Pending")); })("drop", function DuplicateDetectionResourceComponent_Conditional_66_Template_div_drop_8_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDrop($event, "Pending")); });
466
+ i0.ɵɵrepeaterCreate(9, DuplicateDetectionResourceComponent_Conditional_66_For_10_Template, 28, 14, "div", 62, _forTrack1);
467
+ i0.ɵɵconditionalCreate(11, DuplicateDetectionResourceComponent_Conditional_66_Conditional_11_Template, 4, 0, "div", 63);
457
468
  i0.ɵɵelementEnd()();
458
- i0.ɵɵelementStart(12, "div", 54)(13, "div", 62);
459
- i0.ɵɵelement(14, "i", 63);
460
- i0.ɵɵelementStart(15, "span", 57);
469
+ i0.ɵɵelementStart(12, "div", 56)(13, "div", 64);
470
+ i0.ɵɵelement(14, "i", 65);
471
+ i0.ɵɵelementStart(15, "span", 59);
461
472
  i0.ɵɵtext(16, "Approved");
462
473
  i0.ɵɵelementEnd();
463
- i0.ɵɵelementStart(17, "span", 58);
474
+ i0.ɵɵelementStart(17, "span", 60);
464
475
  i0.ɵɵtext(18);
465
476
  i0.ɵɵelementEnd()();
466
- i0.ɵɵelementStart(19, "div", 59);
467
- i0.ɵɵlistener("dragover", function DuplicateDetectionResourceComponent_Conditional_64_Template_div_dragover_19_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDragOver($event, "Approved")); })("dragleave", function DuplicateDetectionResourceComponent_Conditional_64_Template_div_dragleave_19_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDragLeave($event, "Approved")); })("drop", function DuplicateDetectionResourceComponent_Conditional_64_Template_div_drop_19_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDrop($event, "Approved")); });
468
- i0.ɵɵrepeaterCreate(20, DuplicateDetectionResourceComponent_Conditional_64_For_21_Template, 21, 12, "div", 60, _forTrack1);
469
- i0.ɵɵconditionalCreate(22, DuplicateDetectionResourceComponent_Conditional_64_Conditional_22_Template, 4, 0, "div", 61);
477
+ i0.ɵɵelementStart(19, "div", 61);
478
+ i0.ɵɵlistener("dragover", function DuplicateDetectionResourceComponent_Conditional_66_Template_div_dragover_19_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDragOver($event, "Approved")); })("dragleave", function DuplicateDetectionResourceComponent_Conditional_66_Template_div_dragleave_19_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDragLeave($event, "Approved")); })("drop", function DuplicateDetectionResourceComponent_Conditional_66_Template_div_drop_19_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDrop($event, "Approved")); });
479
+ i0.ɵɵrepeaterCreate(20, DuplicateDetectionResourceComponent_Conditional_66_For_21_Template, 21, 12, "div", 62, _forTrack1);
480
+ i0.ɵɵconditionalCreate(22, DuplicateDetectionResourceComponent_Conditional_66_Conditional_22_Template, 4, 0, "div", 63);
470
481
  i0.ɵɵelementEnd()();
471
- i0.ɵɵelementStart(23, "div", 54)(24, "div", 64);
472
- i0.ɵɵelement(25, "i", 65);
473
- i0.ɵɵelementStart(26, "span", 57);
482
+ i0.ɵɵelementStart(23, "div", 56)(24, "div", 66);
483
+ i0.ɵɵelement(25, "i", 67);
484
+ i0.ɵɵelementStart(26, "span", 59);
474
485
  i0.ɵɵtext(27, "Rejected");
475
486
  i0.ɵɵelementEnd();
476
- i0.ɵɵelementStart(28, "span", 58);
487
+ i0.ɵɵelementStart(28, "span", 60);
477
488
  i0.ɵɵtext(29);
478
489
  i0.ɵɵelementEnd()();
479
- i0.ɵɵelementStart(30, "div", 59);
480
- i0.ɵɵlistener("dragover", function DuplicateDetectionResourceComponent_Conditional_64_Template_div_dragover_30_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDragOver($event, "Rejected")); })("dragleave", function DuplicateDetectionResourceComponent_Conditional_64_Template_div_dragleave_30_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDragLeave($event, "Rejected")); })("drop", function DuplicateDetectionResourceComponent_Conditional_64_Template_div_drop_30_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDrop($event, "Rejected")); });
481
- i0.ɵɵrepeaterCreate(31, DuplicateDetectionResourceComponent_Conditional_64_For_32_Template, 21, 12, "div", 60, _forTrack1);
482
- i0.ɵɵconditionalCreate(33, DuplicateDetectionResourceComponent_Conditional_64_Conditional_33_Template, 4, 0, "div", 61);
490
+ i0.ɵɵelementStart(30, "div", 61);
491
+ i0.ɵɵlistener("dragover", function DuplicateDetectionResourceComponent_Conditional_66_Template_div_dragover_30_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDragOver($event, "Rejected")); })("dragleave", function DuplicateDetectionResourceComponent_Conditional_66_Template_div_dragleave_30_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDragLeave($event, "Rejected")); })("drop", function DuplicateDetectionResourceComponent_Conditional_66_Template_div_drop_30_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDrop($event, "Rejected")); });
492
+ i0.ɵɵrepeaterCreate(31, DuplicateDetectionResourceComponent_Conditional_66_For_32_Template, 21, 12, "div", 62, _forTrack1);
493
+ i0.ɵɵconditionalCreate(33, DuplicateDetectionResourceComponent_Conditional_66_Conditional_33_Template, 4, 0, "div", 63);
483
494
  i0.ɵɵelementEnd()()();
484
495
  } if (rf & 2) {
485
496
  const ctx_r1 = i0.ɵɵnextContext();
@@ -508,34 +519,34 @@ function DuplicateDetectionResourceComponent_Conditional_64_Template(rf, ctx) {
508
519
  i0.ɵɵadvance(2);
509
520
  i0.ɵɵconditional(ctx_r1.RejectedGroups.length === 0 ? 33 : -1);
510
521
  } }
511
- function DuplicateDetectionResourceComponent_Conditional_65_Template(rf, ctx) { if (rf & 1) {
512
- i0.ɵɵelementStart(0, "div", 31);
513
- i0.ɵɵelement(1, "mj-loading", 89);
522
+ function DuplicateDetectionResourceComponent_Conditional_67_Template(rf, ctx) { if (rf & 1) {
523
+ i0.ɵɵelementStart(0, "div", 32);
524
+ i0.ɵɵelement(1, "mj-loading", 91);
514
525
  i0.ɵɵelementEnd();
515
526
  } }
516
- function DuplicateDetectionResourceComponent_Conditional_66_Conditional_21_Template(rf, ctx) { if (rf & 1) {
517
- i0.ɵɵelementStart(0, "div", 102);
518
- i0.ɵɵelement(1, "mj-loading", 127);
527
+ function DuplicateDetectionResourceComponent_Conditional_68_Conditional_21_Template(rf, ctx) { if (rf & 1) {
528
+ i0.ɵɵelementStart(0, "div", 104);
529
+ i0.ɵɵelement(1, "mj-loading", 130);
519
530
  i0.ɵɵelementEnd();
520
531
  } }
521
- function DuplicateDetectionResourceComponent_Conditional_66_Conditional_44_Template(rf, ctx) { if (rf & 1) {
522
- i0.ɵɵelementStart(0, "span", 118);
523
- i0.ɵɵelement(1, "i", 128);
532
+ function DuplicateDetectionResourceComponent_Conditional_68_Conditional_44_Template(rf, ctx) { if (rf & 1) {
533
+ i0.ɵɵelementStart(0, "span", 120);
534
+ i0.ɵɵelement(1, "i", 131);
524
535
  i0.ɵɵtext(2, " Most deps");
525
536
  i0.ɵɵelementEnd();
526
537
  } }
527
- function DuplicateDetectionResourceComponent_Conditional_66_Conditional_45_Conditional_4_For_2_Conditional_7_Conditional_1_Template(rf, ctx) { if (rf & 1) {
528
- i0.ɵɵelementStart(0, "div", 137);
529
- i0.ɵɵelement(1, "i", 33);
538
+ function DuplicateDetectionResourceComponent_Conditional_68_Conditional_45_Conditional_4_For_2_Conditional_7_Conditional_1_Template(rf, ctx) { if (rf & 1) {
539
+ i0.ɵɵelementStart(0, "div", 140);
540
+ i0.ɵɵelement(1, "i", 34);
530
541
  i0.ɵɵtext(2, " Loading...");
531
542
  i0.ɵɵelementEnd();
532
543
  } }
533
- function DuplicateDetectionResourceComponent_Conditional_66_Conditional_45_Conditional_4_For_2_Conditional_7_For_3_Template(rf, ctx) { if (rf & 1) {
544
+ function DuplicateDetectionResourceComponent_Conditional_68_Conditional_45_Conditional_4_For_2_Conditional_7_For_3_Template(rf, ctx) { if (rf & 1) {
534
545
  const _r20 = i0.ɵɵgetCurrentView();
535
- i0.ɵɵelementStart(0, "div", 139);
536
- i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_66_Conditional_45_Conditional_4_For_2_Conditional_7_For_3_Template_div_click_0_listener($event) { const record_r21 = i0.ɵɵrestoreView(_r20).$implicit; const ctx_r1 = i0.ɵɵnextContext(6); ctx_r1.OpenDepRecord(record_r21); return i0.ɵɵresetView($event.stopPropagation()); });
537
- i0.ɵɵelement(1, "i", 140);
538
- i0.ɵɵelementStart(2, "span", 141);
546
+ i0.ɵɵelementStart(0, "div", 142);
547
+ i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_68_Conditional_45_Conditional_4_For_2_Conditional_7_For_3_Template_div_click_0_listener($event) { const record_r21 = i0.ɵɵrestoreView(_r20).$implicit; const ctx_r1 = i0.ɵɵnextContext(6); ctx_r1.OpenDepRecord(record_r21); return i0.ɵɵresetView($event.stopPropagation()); });
548
+ i0.ɵɵelement(1, "i", 143);
549
+ i0.ɵɵelementStart(2, "span", 144);
539
550
  i0.ɵɵtext(3);
540
551
  i0.ɵɵelementEnd()();
541
552
  } if (rf & 2) {
@@ -543,10 +554,10 @@ function DuplicateDetectionResourceComponent_Conditional_66_Conditional_45_Condi
543
554
  i0.ɵɵadvance(3);
544
555
  i0.ɵɵtextInterpolate(record_r21.Name);
545
556
  } }
546
- function DuplicateDetectionResourceComponent_Conditional_66_Conditional_45_Conditional_4_For_2_Conditional_7_Template(rf, ctx) { if (rf & 1) {
547
- i0.ɵɵelementStart(0, "div", 136);
548
- i0.ɵɵconditionalCreate(1, DuplicateDetectionResourceComponent_Conditional_66_Conditional_45_Conditional_4_For_2_Conditional_7_Conditional_1_Template, 3, 0, "div", 137);
549
- i0.ɵɵrepeaterCreate(2, DuplicateDetectionResourceComponent_Conditional_66_Conditional_45_Conditional_4_For_2_Conditional_7_For_3_Template, 4, 1, "div", 138, i0.ɵɵrepeaterTrackByIndex);
557
+ function DuplicateDetectionResourceComponent_Conditional_68_Conditional_45_Conditional_4_For_2_Conditional_7_Template(rf, ctx) { if (rf & 1) {
558
+ i0.ɵɵelementStart(0, "div", 139);
559
+ i0.ɵɵconditionalCreate(1, DuplicateDetectionResourceComponent_Conditional_68_Conditional_45_Conditional_4_For_2_Conditional_7_Conditional_1_Template, 3, 0, "div", 140);
560
+ i0.ɵɵrepeaterCreate(2, DuplicateDetectionResourceComponent_Conditional_68_Conditional_45_Conditional_4_For_2_Conditional_7_For_3_Template, 4, 1, "div", 141, i0.ɵɵrepeaterTrackByIndex);
550
561
  i0.ɵɵelementEnd();
551
562
  } if (rf & 2) {
552
563
  const dep_r19 = i0.ɵɵnextContext().$implicit;
@@ -556,18 +567,18 @@ function DuplicateDetectionResourceComponent_Conditional_66_Conditional_45_Condi
556
567
  i0.ɵɵadvance();
557
568
  i0.ɵɵrepeater(ctx_r1.GetDepRecords(0, dep_r19.Entity));
558
569
  } }
559
- function DuplicateDetectionResourceComponent_Conditional_66_Conditional_45_Conditional_4_For_2_Template(rf, ctx) { if (rf & 1) {
570
+ function DuplicateDetectionResourceComponent_Conditional_68_Conditional_45_Conditional_4_For_2_Template(rf, ctx) { if (rf & 1) {
560
571
  const _r18 = i0.ɵɵgetCurrentView();
561
- i0.ɵɵelementStart(0, "div", 131)(1, "div", 132);
562
- i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_66_Conditional_45_Conditional_4_For_2_Template_div_click_1_listener($event) { const dep_r19 = i0.ɵɵrestoreView(_r18).$implicit; const ctx_r1 = i0.ɵɵnextContext(4); ctx_r1.ToggleDepEntityGroup(0, dep_r19.Entity); return i0.ɵɵresetView($event.stopPropagation()); });
563
- i0.ɵɵelementStart(2, "span", 133);
564
- i0.ɵɵelement(3, "i", 134);
572
+ i0.ɵɵelementStart(0, "div", 134)(1, "div", 135);
573
+ i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_68_Conditional_45_Conditional_4_For_2_Template_div_click_1_listener($event) { const dep_r19 = i0.ɵɵrestoreView(_r18).$implicit; const ctx_r1 = i0.ɵɵnextContext(4); ctx_r1.ToggleDepEntityGroup(0, dep_r19.Entity); return i0.ɵɵresetView($event.stopPropagation()); });
574
+ i0.ɵɵelementStart(2, "span", 136);
575
+ i0.ɵɵelement(3, "i", 137);
565
576
  i0.ɵɵtext(4);
566
577
  i0.ɵɵelementEnd();
567
- i0.ɵɵelementStart(5, "span", 135);
578
+ i0.ɵɵelementStart(5, "span", 138);
568
579
  i0.ɵɵtext(6);
569
580
  i0.ɵɵelementEnd()();
570
- i0.ɵɵconditionalCreate(7, DuplicateDetectionResourceComponent_Conditional_66_Conditional_45_Conditional_4_For_2_Conditional_7_Template, 4, 1, "div", 136);
581
+ i0.ɵɵconditionalCreate(7, DuplicateDetectionResourceComponent_Conditional_68_Conditional_45_Conditional_4_For_2_Conditional_7_Template, 4, 1, "div", 139);
571
582
  i0.ɵɵelementEnd();
572
583
  } if (rf & 2) {
573
584
  const dep_r19 = ctx.$implicit;
@@ -581,25 +592,25 @@ function DuplicateDetectionResourceComponent_Conditional_66_Conditional_45_Condi
581
592
  i0.ɵɵadvance();
582
593
  i0.ɵɵconditional(ctx_r1.IsDepEntityGroupExpanded(0, dep_r19.Entity) ? 7 : -1);
583
594
  } }
584
- function DuplicateDetectionResourceComponent_Conditional_66_Conditional_45_Conditional_4_Template(rf, ctx) { if (rf & 1) {
585
- i0.ɵɵelementStart(0, "div", 130);
586
- i0.ɵɵrepeaterCreate(1, DuplicateDetectionResourceComponent_Conditional_66_Conditional_45_Conditional_4_For_2_Template, 8, 7, "div", 131, _forTrack5);
595
+ function DuplicateDetectionResourceComponent_Conditional_68_Conditional_45_Conditional_4_Template(rf, ctx) { if (rf & 1) {
596
+ i0.ɵɵelementStart(0, "div", 133);
597
+ i0.ɵɵrepeaterCreate(1, DuplicateDetectionResourceComponent_Conditional_68_Conditional_45_Conditional_4_For_2_Template, 8, 7, "div", 134, _forTrack5);
587
598
  i0.ɵɵelementEnd();
588
599
  } if (rf & 2) {
589
600
  const ctx_r1 = i0.ɵɵnextContext(3);
590
601
  i0.ɵɵadvance();
591
602
  i0.ɵɵrepeater(ctx_r1.GetGroupedDeps(0));
592
603
  } }
593
- function DuplicateDetectionResourceComponent_Conditional_66_Conditional_45_Template(rf, ctx) { if (rf & 1) {
604
+ function DuplicateDetectionResourceComponent_Conditional_68_Conditional_45_Template(rf, ctx) { if (rf & 1) {
594
605
  const _r17 = i0.ɵɵgetCurrentView();
595
- i0.ɵɵelementStart(0, "div", 129);
596
- i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_66_Conditional_45_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r17); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.ToggleDepsExpanded(0)); });
606
+ i0.ɵɵelementStart(0, "div", 132);
607
+ i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_68_Conditional_45_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r17); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.ToggleDepsExpanded(0)); });
597
608
  i0.ɵɵelementStart(1, "span");
598
609
  i0.ɵɵtext(2);
599
610
  i0.ɵɵelementEnd();
600
- i0.ɵɵelement(3, "i", 113);
611
+ i0.ɵɵelement(3, "i", 115);
601
612
  i0.ɵɵelementEnd();
602
- i0.ɵɵconditionalCreate(4, DuplicateDetectionResourceComponent_Conditional_66_Conditional_45_Conditional_4_Template, 3, 0, "div", 130);
613
+ i0.ɵɵconditionalCreate(4, DuplicateDetectionResourceComponent_Conditional_68_Conditional_45_Conditional_4_Template, 3, 0, "div", 133);
603
614
  } if (rf & 2) {
604
615
  const ctx_r1 = i0.ɵɵnextContext(2);
605
616
  i0.ɵɵadvance(2);
@@ -609,24 +620,24 @@ function DuplicateDetectionResourceComponent_Conditional_66_Conditional_45_Templ
609
620
  i0.ɵɵadvance();
610
621
  i0.ɵɵconditional(ctx_r1.IsDepsExpanded(0) ? 4 : -1);
611
622
  } }
612
- function DuplicateDetectionResourceComponent_Conditional_66_For_47_Conditional_21_Template(rf, ctx) { if (rf & 1) {
613
- i0.ɵɵelementStart(0, "span", 118);
614
- i0.ɵɵelement(1, "i", 128);
623
+ function DuplicateDetectionResourceComponent_Conditional_68_For_47_Conditional_21_Template(rf, ctx) { if (rf & 1) {
624
+ i0.ɵɵelementStart(0, "span", 120);
625
+ i0.ɵɵelement(1, "i", 131);
615
626
  i0.ɵɵtext(2, " Most deps");
616
627
  i0.ɵɵelementEnd();
617
628
  } }
618
- function DuplicateDetectionResourceComponent_Conditional_66_For_47_Conditional_22_Conditional_4_For_2_Conditional_7_Conditional_1_Template(rf, ctx) { if (rf & 1) {
619
- i0.ɵɵelementStart(0, "div", 137);
620
- i0.ɵɵelement(1, "i", 33);
629
+ function DuplicateDetectionResourceComponent_Conditional_68_For_47_Conditional_22_Conditional_4_For_2_Conditional_7_Conditional_1_Template(rf, ctx) { if (rf & 1) {
630
+ i0.ɵɵelementStart(0, "div", 140);
631
+ i0.ɵɵelement(1, "i", 34);
621
632
  i0.ɵɵtext(2, " Loading...");
622
633
  i0.ɵɵelementEnd();
623
634
  } }
624
- function DuplicateDetectionResourceComponent_Conditional_66_For_47_Conditional_22_Conditional_4_For_2_Conditional_7_For_3_Template(rf, ctx) { if (rf & 1) {
635
+ function DuplicateDetectionResourceComponent_Conditional_68_For_47_Conditional_22_Conditional_4_For_2_Conditional_7_For_3_Template(rf, ctx) { if (rf & 1) {
625
636
  const _r27 = i0.ɵɵgetCurrentView();
626
- i0.ɵɵelementStart(0, "div", 139);
627
- i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_66_For_47_Conditional_22_Conditional_4_For_2_Conditional_7_For_3_Template_div_click_0_listener($event) { const record_r28 = i0.ɵɵrestoreView(_r27).$implicit; const ctx_r1 = i0.ɵɵnextContext(7); ctx_r1.OpenDepRecord(record_r28); return i0.ɵɵresetView($event.stopPropagation()); });
628
- i0.ɵɵelement(1, "i", 140);
629
- i0.ɵɵelementStart(2, "span", 141);
637
+ i0.ɵɵelementStart(0, "div", 142);
638
+ i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_68_For_47_Conditional_22_Conditional_4_For_2_Conditional_7_For_3_Template_div_click_0_listener($event) { const record_r28 = i0.ɵɵrestoreView(_r27).$implicit; const ctx_r1 = i0.ɵɵnextContext(7); ctx_r1.OpenDepRecord(record_r28); return i0.ɵɵresetView($event.stopPropagation()); });
639
+ i0.ɵɵelement(1, "i", 143);
640
+ i0.ɵɵelementStart(2, "span", 144);
630
641
  i0.ɵɵtext(3);
631
642
  i0.ɵɵelementEnd()();
632
643
  } if (rf & 2) {
@@ -634,341 +645,369 @@ function DuplicateDetectionResourceComponent_Conditional_66_For_47_Conditional_2
634
645
  i0.ɵɵadvance(3);
635
646
  i0.ɵɵtextInterpolate(record_r28.Name);
636
647
  } }
637
- function DuplicateDetectionResourceComponent_Conditional_66_For_47_Conditional_22_Conditional_4_For_2_Conditional_7_Template(rf, ctx) { if (rf & 1) {
638
- i0.ɵɵelementStart(0, "div", 136);
639
- i0.ɵɵconditionalCreate(1, DuplicateDetectionResourceComponent_Conditional_66_For_47_Conditional_22_Conditional_4_For_2_Conditional_7_Conditional_1_Template, 3, 0, "div", 137);
640
- i0.ɵɵrepeaterCreate(2, DuplicateDetectionResourceComponent_Conditional_66_For_47_Conditional_22_Conditional_4_For_2_Conditional_7_For_3_Template, 4, 1, "div", 138, i0.ɵɵrepeaterTrackByIndex);
648
+ function DuplicateDetectionResourceComponent_Conditional_68_For_47_Conditional_22_Conditional_4_For_2_Conditional_7_Template(rf, ctx) { if (rf & 1) {
649
+ i0.ɵɵelementStart(0, "div", 139);
650
+ i0.ɵɵconditionalCreate(1, DuplicateDetectionResourceComponent_Conditional_68_For_47_Conditional_22_Conditional_4_For_2_Conditional_7_Conditional_1_Template, 3, 0, "div", 140);
651
+ i0.ɵɵrepeaterCreate(2, DuplicateDetectionResourceComponent_Conditional_68_For_47_Conditional_22_Conditional_4_For_2_Conditional_7_For_3_Template, 4, 1, "div", 141, i0.ɵɵrepeaterTrackByIndex);
641
652
  i0.ɵɵelementEnd();
642
653
  } if (rf & 2) {
643
654
  const dep_r26 = i0.ɵɵnextContext().$implicit;
644
- const ɵ$index_556_r23 = i0.ɵɵnextContext(3).$index;
655
+ const ɵ$index_567_r23 = i0.ɵɵnextContext(3).$index;
645
656
  const ctx_r1 = i0.ɵɵnextContext(2);
646
657
  i0.ɵɵadvance();
647
- i0.ɵɵconditional(ctx_r1.IsDepRecordsLoading(ɵ$index_556_r23 + 1, dep_r26.Entity) ? 1 : -1);
658
+ i0.ɵɵconditional(ctx_r1.IsDepRecordsLoading(ɵ$index_567_r23 + 1, dep_r26.Entity) ? 1 : -1);
648
659
  i0.ɵɵadvance();
649
- i0.ɵɵrepeater(ctx_r1.GetDepRecords(ɵ$index_556_r23 + 1, dep_r26.Entity));
660
+ i0.ɵɵrepeater(ctx_r1.GetDepRecords(ɵ$index_567_r23 + 1, dep_r26.Entity));
650
661
  } }
651
- function DuplicateDetectionResourceComponent_Conditional_66_For_47_Conditional_22_Conditional_4_For_2_Template(rf, ctx) { if (rf & 1) {
662
+ function DuplicateDetectionResourceComponent_Conditional_68_For_47_Conditional_22_Conditional_4_For_2_Template(rf, ctx) { if (rf & 1) {
652
663
  const _r25 = i0.ɵɵgetCurrentView();
653
- i0.ɵɵelementStart(0, "div", 131)(1, "div", 132);
654
- i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_66_For_47_Conditional_22_Conditional_4_For_2_Template_div_click_1_listener($event) { const dep_r26 = i0.ɵɵrestoreView(_r25).$implicit; const ɵ$index_556_r23 = i0.ɵɵnextContext(3).$index; const ctx_r1 = i0.ɵɵnextContext(2); ctx_r1.ToggleDepEntityGroup(ɵ$index_556_r23 + 1, dep_r26.Entity); return i0.ɵɵresetView($event.stopPropagation()); });
655
- i0.ɵɵelementStart(2, "span", 133);
656
- i0.ɵɵelement(3, "i", 134);
664
+ i0.ɵɵelementStart(0, "div", 134)(1, "div", 135);
665
+ i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_68_For_47_Conditional_22_Conditional_4_For_2_Template_div_click_1_listener($event) { const dep_r26 = i0.ɵɵrestoreView(_r25).$implicit; const ɵ$index_567_r23 = i0.ɵɵnextContext(3).$index; const ctx_r1 = i0.ɵɵnextContext(2); ctx_r1.ToggleDepEntityGroup(ɵ$index_567_r23 + 1, dep_r26.Entity); return i0.ɵɵresetView($event.stopPropagation()); });
666
+ i0.ɵɵelementStart(2, "span", 136);
667
+ i0.ɵɵelement(3, "i", 137);
657
668
  i0.ɵɵtext(4);
658
669
  i0.ɵɵelementEnd();
659
- i0.ɵɵelementStart(5, "span", 135);
670
+ i0.ɵɵelementStart(5, "span", 138);
660
671
  i0.ɵɵtext(6);
661
672
  i0.ɵɵelementEnd()();
662
- i0.ɵɵconditionalCreate(7, DuplicateDetectionResourceComponent_Conditional_66_For_47_Conditional_22_Conditional_4_For_2_Conditional_7_Template, 4, 1, "div", 136);
673
+ i0.ɵɵconditionalCreate(7, DuplicateDetectionResourceComponent_Conditional_68_For_47_Conditional_22_Conditional_4_For_2_Conditional_7_Template, 4, 1, "div", 139);
663
674
  i0.ɵɵelementEnd();
664
675
  } if (rf & 2) {
665
676
  const dep_r26 = ctx.$implicit;
666
- const ɵ$index_556_r23 = i0.ɵɵnextContext(3).$index;
677
+ const ɵ$index_567_r23 = i0.ɵɵnextContext(3).$index;
667
678
  const ctx_r1 = i0.ɵɵnextContext(2);
668
679
  i0.ɵɵadvance(3);
669
- i0.ɵɵclassProp("fa-chevron-right", !ctx_r1.IsDepEntityGroupExpanded(ɵ$index_556_r23 + 1, dep_r26.Entity))("fa-chevron-down", ctx_r1.IsDepEntityGroupExpanded(ɵ$index_556_r23 + 1, dep_r26.Entity));
680
+ i0.ɵɵclassProp("fa-chevron-right", !ctx_r1.IsDepEntityGroupExpanded(ɵ$index_567_r23 + 1, dep_r26.Entity))("fa-chevron-down", ctx_r1.IsDepEntityGroupExpanded(ɵ$index_567_r23 + 1, dep_r26.Entity));
670
681
  i0.ɵɵadvance();
671
682
  i0.ɵɵtextInterpolate1(" ", dep_r26.Entity, " ");
672
683
  i0.ɵɵadvance(2);
673
684
  i0.ɵɵtextInterpolate(dep_r26.Count);
674
685
  i0.ɵɵadvance();
675
- i0.ɵɵconditional(ctx_r1.IsDepEntityGroupExpanded(ɵ$index_556_r23 + 1, dep_r26.Entity) ? 7 : -1);
686
+ i0.ɵɵconditional(ctx_r1.IsDepEntityGroupExpanded(ɵ$index_567_r23 + 1, dep_r26.Entity) ? 7 : -1);
676
687
  } }
677
- function DuplicateDetectionResourceComponent_Conditional_66_For_47_Conditional_22_Conditional_4_Template(rf, ctx) { if (rf & 1) {
678
- i0.ɵɵelementStart(0, "div", 130);
679
- i0.ɵɵrepeaterCreate(1, DuplicateDetectionResourceComponent_Conditional_66_For_47_Conditional_22_Conditional_4_For_2_Template, 8, 7, "div", 131, _forTrack5);
688
+ function DuplicateDetectionResourceComponent_Conditional_68_For_47_Conditional_22_Conditional_4_Template(rf, ctx) { if (rf & 1) {
689
+ i0.ɵɵelementStart(0, "div", 133);
690
+ i0.ɵɵrepeaterCreate(1, DuplicateDetectionResourceComponent_Conditional_68_For_47_Conditional_22_Conditional_4_For_2_Template, 8, 7, "div", 134, _forTrack5);
680
691
  i0.ɵɵelementEnd();
681
692
  } if (rf & 2) {
682
- const ɵ$index_556_r23 = i0.ɵɵnextContext(2).$index;
693
+ const ɵ$index_567_r23 = i0.ɵɵnextContext(2).$index;
683
694
  const ctx_r1 = i0.ɵɵnextContext(2);
684
695
  i0.ɵɵadvance();
685
- i0.ɵɵrepeater(ctx_r1.GetGroupedDeps(ɵ$index_556_r23 + 1));
696
+ i0.ɵɵrepeater(ctx_r1.GetGroupedDeps(ɵ$index_567_r23 + 1));
686
697
  } }
687
- function DuplicateDetectionResourceComponent_Conditional_66_For_47_Conditional_22_Template(rf, ctx) { if (rf & 1) {
698
+ function DuplicateDetectionResourceComponent_Conditional_68_For_47_Conditional_22_Template(rf, ctx) { if (rf & 1) {
688
699
  const _r24 = i0.ɵɵgetCurrentView();
689
- i0.ɵɵelementStart(0, "div", 129);
690
- i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_66_For_47_Conditional_22_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r24); const ɵ$index_556_r23 = i0.ɵɵnextContext().$index; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.ToggleDepsExpanded(ɵ$index_556_r23 + 1)); });
700
+ i0.ɵɵelementStart(0, "div", 132);
701
+ i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_68_For_47_Conditional_22_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r24); const ɵ$index_567_r23 = i0.ɵɵnextContext().$index; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.ToggleDepsExpanded(ɵ$index_567_r23 + 1)); });
691
702
  i0.ɵɵelementStart(1, "span");
692
703
  i0.ɵɵtext(2);
693
704
  i0.ɵɵelementEnd();
694
- i0.ɵɵelement(3, "i", 113);
705
+ i0.ɵɵelement(3, "i", 115);
695
706
  i0.ɵɵelementEnd();
696
- i0.ɵɵconditionalCreate(4, DuplicateDetectionResourceComponent_Conditional_66_For_47_Conditional_22_Conditional_4_Template, 3, 0, "div", 130);
707
+ i0.ɵɵconditionalCreate(4, DuplicateDetectionResourceComponent_Conditional_68_For_47_Conditional_22_Conditional_4_Template, 3, 0, "div", 133);
697
708
  } if (rf & 2) {
698
- const ɵ$index_556_r23 = i0.ɵɵnextContext().$index;
709
+ const ɵ$index_567_r23 = i0.ɵɵnextContext().$index;
699
710
  const ctx_r1 = i0.ɵɵnextContext(2);
700
711
  i0.ɵɵadvance(2);
701
- i0.ɵɵtextInterpolate(ctx_r1.IsDepsExpanded(ɵ$index_556_r23 + 1) ? "Hide details" : "Show details");
712
+ i0.ɵɵtextInterpolate(ctx_r1.IsDepsExpanded(ɵ$index_567_r23 + 1) ? "Hide details" : "Show details");
702
713
  i0.ɵɵadvance();
703
- i0.ɵɵclassProp("fa-chevron-down", !ctx_r1.IsDepsExpanded(ɵ$index_556_r23 + 1))("fa-chevron-up", ctx_r1.IsDepsExpanded(ɵ$index_556_r23 + 1));
714
+ i0.ɵɵclassProp("fa-chevron-down", !ctx_r1.IsDepsExpanded(ɵ$index_567_r23 + 1))("fa-chevron-up", ctx_r1.IsDepsExpanded(ɵ$index_567_r23 + 1));
704
715
  i0.ɵɵadvance();
705
- i0.ɵɵconditional(ctx_r1.IsDepsExpanded(ɵ$index_556_r23 + 1) ? 4 : -1);
716
+ i0.ɵɵconditional(ctx_r1.IsDepsExpanded(ɵ$index_567_r23 + 1) ? 4 : -1);
717
+ } }
718
+ function DuplicateDetectionResourceComponent_Conditional_68_For_47_Conditional_24_Template(rf, ctx) { if (rf & 1) {
719
+ const _r29 = i0.ɵɵgetCurrentView();
720
+ i0.ɵɵelementStart(0, "button", 150);
721
+ i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_68_For_47_Conditional_24_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r29); const match_r30 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.RejectIndividualMatch(match_r30)); });
722
+ i0.ɵɵelement(1, "i", 67);
723
+ i0.ɵɵtext(2, " Skip ");
724
+ i0.ɵɵelementEnd();
725
+ } }
726
+ function DuplicateDetectionResourceComponent_Conditional_68_For_47_Conditional_25_Conditional_3_Template(rf, ctx) { if (rf & 1) {
727
+ const _r31 = i0.ɵɵgetCurrentView();
728
+ i0.ɵɵelementStart(0, "button", 153);
729
+ i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_68_For_47_Conditional_25_Conditional_3_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r31); const match_r30 = i0.ɵɵnextContext(2).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.UndoRejectIndividualMatch(match_r30)); });
730
+ i0.ɵɵelement(1, "i", 154);
731
+ i0.ɵɵtext(2, " Undo ");
732
+ i0.ɵɵelementEnd();
706
733
  } }
707
- function DuplicateDetectionResourceComponent_Conditional_66_For_47_Conditional_23_Template(rf, ctx) { if (rf & 1) {
708
- i0.ɵɵelementStart(0, "span", 146);
709
- i0.ɵɵelement(1, "i", 113);
734
+ function DuplicateDetectionResourceComponent_Conditional_68_For_47_Conditional_25_Template(rf, ctx) { if (rf & 1) {
735
+ i0.ɵɵelementStart(0, "span", 151);
736
+ i0.ɵɵelement(1, "i", 115);
710
737
  i0.ɵɵtext(2);
711
738
  i0.ɵɵelementEnd();
739
+ i0.ɵɵconditionalCreate(3, DuplicateDetectionResourceComponent_Conditional_68_For_47_Conditional_25_Conditional_3_Template, 3, 0, "button", 152);
712
740
  } if (rf & 2) {
713
- const match_r29 = i0.ɵɵnextContext().$implicit;
714
- i0.ɵɵclassProp("status-approved", match_r29.Match.ApprovalStatus === "Approved")("status-rejected", match_r29.Match.ApprovalStatus === "Rejected");
741
+ const match_r30 = i0.ɵɵnextContext().$implicit;
742
+ i0.ɵɵclassProp("status-approved", match_r30.Match.ApprovalStatus === "Approved")("status-rejected", match_r30.Match.ApprovalStatus === "Rejected");
715
743
  i0.ɵɵadvance();
716
- i0.ɵɵclassProp("fa-check", match_r29.Match.ApprovalStatus === "Approved")("fa-times", match_r29.Match.ApprovalStatus === "Rejected");
744
+ i0.ɵɵclassProp("fa-check", match_r30.Match.ApprovalStatus === "Approved")("fa-times", match_r30.Match.ApprovalStatus === "Rejected");
717
745
  i0.ɵɵadvance();
718
- i0.ɵɵtextInterpolate1(" ", match_r29.Match.ApprovalStatus, " ");
746
+ i0.ɵɵtextInterpolate1(" ", match_r30.Match.ApprovalStatus === "Rejected" ? "Skipped" : match_r30.Match.ApprovalStatus, " ");
747
+ i0.ɵɵadvance();
748
+ i0.ɵɵconditional(match_r30.Match.ApprovalStatus === "Rejected" ? 3 : -1);
719
749
  } }
720
- function DuplicateDetectionResourceComponent_Conditional_66_For_47_Template(rf, ctx) { if (rf & 1) {
750
+ function DuplicateDetectionResourceComponent_Conditional_68_For_47_Template(rf, ctx) { if (rf & 1) {
721
751
  const _r22 = i0.ɵɵgetCurrentView();
722
- i0.ɵɵelementStart(0, "div", 142)(1, "div", 143)(2, "span", 108);
752
+ i0.ɵɵelementStart(0, "div", 145)(1, "div", 146)(2, "span", 110);
723
753
  i0.ɵɵtext(3);
724
754
  i0.ɵɵelementEnd();
725
- i0.ɵɵelementStart(4, "span", 73);
755
+ i0.ɵɵelementStart(4, "span", 75);
726
756
  i0.ɵɵtext(5);
727
757
  i0.ɵɵelementEnd()();
728
- i0.ɵɵelementStart(6, "span", 144);
758
+ i0.ɵɵelementStart(6, "span", 147);
729
759
  i0.ɵɵtext(7);
730
760
  i0.ɵɵelementEnd();
731
- i0.ɵɵelementStart(8, "div", 109)(9, "input", 110);
732
- i0.ɵɵlistener("change", function DuplicateDetectionResourceComponent_Conditional_66_For_47_Template_input_change_9_listener() { const ɵ$index_556_r23 = i0.ɵɵrestoreView(_r22).$index; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.SetSurvivor(ɵ$index_556_r23 + 1)); });
761
+ i0.ɵɵelementStart(8, "div", 111)(9, "input", 112);
762
+ i0.ɵɵlistener("change", function DuplicateDetectionResourceComponent_Conditional_68_For_47_Template_input_change_9_listener() { const ɵ$index_567_r23 = i0.ɵɵrestoreView(_r22).$index; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.SetSurvivor(ɵ$index_567_r23 + 1)); });
733
763
  i0.ɵɵelementEnd();
734
- i0.ɵɵelementStart(10, "span", 111);
764
+ i0.ɵɵelementStart(10, "span", 113);
735
765
  i0.ɵɵtext(11);
736
766
  i0.ɵɵelementEnd()();
737
- i0.ɵɵelementStart(12, "button", 112);
738
- i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_66_For_47_Template_button_click_12_listener() { const ɵ$index_556_r23 = i0.ɵɵrestoreView(_r22).$index; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.UseAllFieldsFrom(ɵ$index_556_r23 + 1)); });
739
- i0.ɵɵelement(13, "i", 113);
767
+ i0.ɵɵelementStart(12, "button", 114);
768
+ i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_68_For_47_Template_button_click_12_listener() { const ɵ$index_567_r23 = i0.ɵɵrestoreView(_r22).$index; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.UseAllFieldsFrom(ɵ$index_567_r23 + 1)); });
769
+ i0.ɵɵelement(13, "i", 115);
740
770
  i0.ɵɵtext(14);
741
771
  i0.ɵɵelementEnd();
742
- i0.ɵɵelementStart(15, "div", 114)(16, "div", 115);
743
- i0.ɵɵelement(17, "i", 116);
744
- i0.ɵɵelementStart(18, "span", 117);
772
+ i0.ɵɵelementStart(15, "div", 116)(16, "div", 117);
773
+ i0.ɵɵelement(17, "i", 118);
774
+ i0.ɵɵelementStart(18, "span", 119);
745
775
  i0.ɵɵtext(19);
746
776
  i0.ɵɵelementEnd();
747
777
  i0.ɵɵtext(20);
748
- i0.ɵɵconditionalCreate(21, DuplicateDetectionResourceComponent_Conditional_66_For_47_Conditional_21_Template, 3, 0, "span", 118);
749
- i0.ɵɵelementEnd();
750
- i0.ɵɵconditionalCreate(22, DuplicateDetectionResourceComponent_Conditional_66_For_47_Conditional_22_Template, 5, 6);
778
+ i0.ɵɵconditionalCreate(21, DuplicateDetectionResourceComponent_Conditional_68_For_47_Conditional_21_Template, 3, 0, "span", 120);
751
779
  i0.ɵɵelementEnd();
752
- i0.ɵɵconditionalCreate(23, DuplicateDetectionResourceComponent_Conditional_66_For_47_Conditional_23_Template, 3, 9, "span", 145);
780
+ i0.ɵɵconditionalCreate(22, DuplicateDetectionResourceComponent_Conditional_68_For_47_Conditional_22_Template, 5, 6);
753
781
  i0.ɵɵelementEnd();
782
+ i0.ɵɵelementStart(23, "div", 148);
783
+ i0.ɵɵconditionalCreate(24, DuplicateDetectionResourceComponent_Conditional_68_For_47_Conditional_24_Template, 3, 0, "button", 149)(25, DuplicateDetectionResourceComponent_Conditional_68_For_47_Conditional_25_Template, 4, 10);
784
+ i0.ɵɵelementEnd()();
754
785
  } if (rf & 2) {
755
- const match_r29 = ctx.$implicit;
756
- const ɵ$index_556_r23 = ctx.$index;
786
+ const match_r30 = ctx.$implicit;
787
+ const ɵ$index_567_r23 = ctx.$index;
757
788
  const ctx_r1 = i0.ɵɵnextContext(2);
758
- i0.ɵɵclassProp("match-approved", match_r29.Match.ApprovalStatus === "Approved")("match-rejected", match_r29.Match.ApprovalStatus === "Rejected");
789
+ i0.ɵɵclassProp("match-approved", match_r30.Match.ApprovalStatus === "Approved")("match-rejected", match_r30.Match.ApprovalStatus === "Rejected");
759
790
  i0.ɵɵadvance(3);
760
- i0.ɵɵtextInterpolate(match_r29.Name);
791
+ i0.ɵɵtextInterpolate(match_r30.Name);
761
792
  i0.ɵɵadvance();
762
- i0.ɵɵclassMap(ctx_r1.GetScoreClass(match_r29.Score));
793
+ i0.ɵɵclassMap(ctx_r1.GetScoreClass(match_r30.Score));
763
794
  i0.ɵɵadvance();
764
- i0.ɵɵtextInterpolate1(" ", (match_r29.Score * 100).toFixed(0), "% ");
795
+ i0.ɵɵtextInterpolate1(" ", (match_r30.Score * 100).toFixed(0), "% ");
765
796
  i0.ɵɵadvance(2);
766
- i0.ɵɵtextInterpolate2("", match_r29.DiffCount, " difference", match_r29.DiffCount !== 1 ? "s" : "");
797
+ i0.ɵɵtextInterpolate2("", match_r30.DiffCount, " difference", match_r30.DiffCount !== 1 ? "s" : "");
767
798
  i0.ɵɵadvance(2);
768
- i0.ɵɵproperty("checked", ctx_r1.SurvivorColumnIndex === ɵ$index_556_r23 + 1);
799
+ i0.ɵɵproperty("checked", ctx_r1.SurvivorColumnIndex === ɵ$index_567_r23 + 1);
769
800
  i0.ɵɵadvance();
770
- i0.ɵɵclassProp("is-survivor", ctx_r1.SurvivorColumnIndex === ɵ$index_556_r23 + 1);
801
+ i0.ɵɵclassProp("is-survivor", ctx_r1.SurvivorColumnIndex === ɵ$index_567_r23 + 1);
771
802
  i0.ɵɵadvance();
772
- i0.ɵɵtextInterpolate1(" ", ctx_r1.SurvivorColumnIndex === ɵ$index_556_r23 + 1 ? "Surviving Record" : "Set as survivor", " ");
803
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.SurvivorColumnIndex === ɵ$index_567_r23 + 1 ? "Surviving Record" : "Set as survivor", " ");
773
804
  i0.ɵɵadvance();
774
- i0.ɵɵclassProp("all-selected", ctx_r1.AllFieldsSelectedFrom(ɵ$index_556_r23 + 1));
805
+ i0.ɵɵclassProp("all-selected", ctx_r1.AllFieldsSelectedFrom(ɵ$index_567_r23 + 1));
775
806
  i0.ɵɵadvance();
776
- i0.ɵɵclassProp("fa-check-double", ctx_r1.AllFieldsSelectedFrom(ɵ$index_556_r23 + 1))("fa-clone", !ctx_r1.AllFieldsSelectedFrom(ɵ$index_556_r23 + 1));
807
+ i0.ɵɵclassProp("fa-check-double", ctx_r1.AllFieldsSelectedFrom(ɵ$index_567_r23 + 1))("fa-clone", !ctx_r1.AllFieldsSelectedFrom(ɵ$index_567_r23 + 1));
777
808
  i0.ɵɵadvance();
778
- i0.ɵɵtextInterpolate1(" ", ctx_r1.AllFieldsSelectedFrom(ɵ$index_556_r23 + 1) ? "Using all fields" : "Use all fields", " ");
809
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.AllFieldsSelectedFrom(ɵ$index_567_r23 + 1) ? "Using all fields" : "Use all fields", " ");
779
810
  i0.ɵɵadvance(5);
780
- i0.ɵɵtextInterpolate(ctx_r1.GetTotalDeps(ɵ$index_556_r23 + 1));
781
- i0.ɵɵadvance();
782
- i0.ɵɵtextInterpolate1(" ", ctx_r1.GetTotalDeps(ɵ$index_556_r23 + 1) === 1 ? "dependency" : "dependencies", " ");
811
+ i0.ɵɵtextInterpolate(ctx_r1.GetTotalDeps(ɵ$index_567_r23 + 1));
783
812
  i0.ɵɵadvance();
784
- i0.ɵɵconditional(ctx_r1.GetMaxDepsColumnIndex() === ɵ$index_556_r23 + 1 && ctx_r1.GetTotalDeps(ɵ$index_556_r23 + 1) > 0 ? 21 : -1);
813
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.GetTotalDeps(ɵ$index_567_r23 + 1) === 1 ? "dependency" : "dependencies", " ");
785
814
  i0.ɵɵadvance();
786
- i0.ɵɵconditional(ctx_r1.GetGroupedDeps(ɵ$index_556_r23 + 1).length > 0 ? 22 : -1);
815
+ i0.ɵɵconditional(ctx_r1.GetMaxDepsColumnIndex() === ɵ$index_567_r23 + 1 && ctx_r1.GetTotalDeps(ɵ$index_567_r23 + 1) > 0 ? 21 : -1);
787
816
  i0.ɵɵadvance();
788
- i0.ɵɵconditional(match_r29.Match.ApprovalStatus !== "Pending" ? 23 : -1);
817
+ i0.ɵɵconditional(ctx_r1.GetGroupedDeps(ɵ$index_567_r23 + 1).length > 0 ? 22 : -1);
818
+ i0.ɵɵadvance(2);
819
+ i0.ɵɵconditional(match_r30.Match.ApprovalStatus === "Pending" ? 24 : 25);
789
820
  } }
790
- function DuplicateDetectionResourceComponent_Conditional_66_For_49_Conditional_3_Template(rf, ctx) { if (rf & 1) {
821
+ function DuplicateDetectionResourceComponent_Conditional_68_For_49_Conditional_3_Template(rf, ctx) { if (rf & 1) {
791
822
  i0.ɵɵtext(0);
792
823
  } if (rf & 2) {
793
- const field_r31 = i0.ɵɵnextContext().$implicit;
794
- i0.ɵɵtextInterpolate1(" ", field_r31.SourceValue, " ");
824
+ const field_r33 = i0.ɵɵnextContext().$implicit;
825
+ i0.ɵɵtextInterpolate1(" ", field_r33.SourceValue, " ");
795
826
  } }
796
- function DuplicateDetectionResourceComponent_Conditional_66_For_49_Conditional_4_Template(rf, ctx) { if (rf & 1) {
797
- i0.ɵɵelementStart(0, "span", 149);
827
+ function DuplicateDetectionResourceComponent_Conditional_68_For_49_Conditional_4_Template(rf, ctx) { if (rf & 1) {
828
+ i0.ɵɵelementStart(0, "span", 157);
798
829
  i0.ɵɵtext(1, "(not available)");
799
830
  i0.ɵɵelementEnd();
800
831
  } }
801
- function DuplicateDetectionResourceComponent_Conditional_66_For_49_Conditional_5_Template(rf, ctx) { if (rf & 1) {
802
- const _r32 = i0.ɵɵgetCurrentView();
803
- i0.ɵɵelementStart(0, "input", 152);
804
- i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_66_For_49_Conditional_5_Template_input_click_0_listener($event) { i0.ɵɵrestoreView(_r32); return i0.ɵɵresetView($event.stopPropagation()); })("change", function DuplicateDetectionResourceComponent_Conditional_66_For_49_Conditional_5_Template_input_change_0_listener() { i0.ɵɵrestoreView(_r32); const field_r31 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.SelectFieldValue(field_r31, 0)); });
832
+ function DuplicateDetectionResourceComponent_Conditional_68_For_49_Conditional_5_Template(rf, ctx) { if (rf & 1) {
833
+ const _r34 = i0.ɵɵgetCurrentView();
834
+ i0.ɵɵelementStart(0, "input", 160);
835
+ i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_68_For_49_Conditional_5_Template_input_click_0_listener($event) { i0.ɵɵrestoreView(_r34); return i0.ɵɵresetView($event.stopPropagation()); })("change", function DuplicateDetectionResourceComponent_Conditional_68_For_49_Conditional_5_Template_input_change_0_listener() { i0.ɵɵrestoreView(_r34); const field_r33 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.SelectFieldValue(field_r33, 0)); });
805
836
  i0.ɵɵelementEnd();
806
837
  } if (rf & 2) {
807
- const field_r31 = i0.ɵɵnextContext().$implicit;
808
- i0.ɵɵproperty("name", "field-" + field_r31.FieldName)("checked", field_r31.SelectedColumnIndex === 0);
838
+ const field_r33 = i0.ɵɵnextContext().$implicit;
839
+ i0.ɵɵproperty("name", "field-" + field_r33.FieldName)("checked", field_r33.SelectedColumnIndex === 0);
809
840
  } }
810
- function DuplicateDetectionResourceComponent_Conditional_66_For_49_For_7_Conditional_1_Conditional_1_Template(rf, ctx) { if (rf & 1) {
811
- const _r37 = i0.ɵɵgetCurrentView();
812
- i0.ɵɵelementStart(0, "input", 152);
813
- i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_66_For_49_For_7_Conditional_1_Conditional_1_Template_input_click_0_listener($event) { i0.ɵɵrestoreView(_r37); return i0.ɵɵresetView($event.stopPropagation()); })("change", function DuplicateDetectionResourceComponent_Conditional_66_For_49_For_7_Conditional_1_Conditional_1_Template_input_change_0_listener() { i0.ɵɵrestoreView(_r37); const ɵ$index_660_r36 = i0.ɵɵnextContext(2).$index; const field_r31 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.SelectFieldValue(field_r31, ɵ$index_660_r36 + 1)); });
841
+ function DuplicateDetectionResourceComponent_Conditional_68_For_49_For_7_Conditional_1_Conditional_1_Template(rf, ctx) { if (rf & 1) {
842
+ const _r39 = i0.ɵɵgetCurrentView();
843
+ i0.ɵɵelementStart(0, "input", 160);
844
+ i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_68_For_49_For_7_Conditional_1_Conditional_1_Template_input_click_0_listener($event) { i0.ɵɵrestoreView(_r39); return i0.ɵɵresetView($event.stopPropagation()); })("change", function DuplicateDetectionResourceComponent_Conditional_68_For_49_For_7_Conditional_1_Conditional_1_Template_input_change_0_listener() { i0.ɵɵrestoreView(_r39); const ɵ$index_685_r38 = i0.ɵɵnextContext(2).$index; const field_r33 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.SelectFieldValue(field_r33, ɵ$index_685_r38 + 1)); });
814
845
  i0.ɵɵelementEnd();
815
846
  } if (rf & 2) {
816
- const ɵ$index_660_r36 = i0.ɵɵnextContext(2).$index;
817
- const field_r31 = i0.ɵɵnextContext().$implicit;
818
- i0.ɵɵproperty("name", "field-" + field_r31.FieldName)("checked", field_r31.SelectedColumnIndex === ɵ$index_660_r36 + 1);
847
+ const ɵ$index_685_r38 = i0.ɵɵnextContext(2).$index;
848
+ const field_r33 = i0.ɵɵnextContext().$implicit;
849
+ i0.ɵɵproperty("name", "field-" + field_r33.FieldName)("checked", field_r33.SelectedColumnIndex === ɵ$index_685_r38 + 1);
819
850
  } }
820
- function DuplicateDetectionResourceComponent_Conditional_66_For_49_For_7_Conditional_1_Template(rf, ctx) { if (rf & 1) {
851
+ function DuplicateDetectionResourceComponent_Conditional_68_For_49_For_7_Conditional_1_Template(rf, ctx) { if (rf & 1) {
821
852
  i0.ɵɵtext(0);
822
- i0.ɵɵconditionalCreate(1, DuplicateDetectionResourceComponent_Conditional_66_For_49_For_7_Conditional_1_Conditional_1_Template, 1, 2, "input", 150);
853
+ i0.ɵɵconditionalCreate(1, DuplicateDetectionResourceComponent_Conditional_68_For_49_For_7_Conditional_1_Conditional_1_Template, 1, 2, "input", 158);
823
854
  } if (rf & 2) {
824
- const ctx_r37 = i0.ɵɵnextContext();
825
- const matchVal_r35 = ctx_r37.$implicit;
826
- const ɵ$index_660_r36 = ctx_r37.$index;
827
- const field_r31 = i0.ɵɵnextContext().$implicit;
828
- i0.ɵɵtextInterpolate1(" ", matchVal_r35, " ");
855
+ const ctx_r39 = i0.ɵɵnextContext();
856
+ const matchVal_r37 = ctx_r39.$implicit;
857
+ const ɵ$index_685_r38 = ctx_r39.$index;
858
+ const field_r33 = i0.ɵɵnextContext().$implicit;
859
+ i0.ɵɵtextInterpolate1(" ", matchVal_r37, " ");
829
860
  i0.ɵɵadvance();
830
- i0.ɵɵconditional(field_r31.HasDifference || field_r31.SelectedColumnIndex === ɵ$index_660_r36 + 1 ? 1 : -1);
861
+ i0.ɵɵconditional(field_r33.HasDifference || field_r33.SelectedColumnIndex === ɵ$index_685_r38 + 1 ? 1 : -1);
831
862
  } }
832
- function DuplicateDetectionResourceComponent_Conditional_66_For_49_For_7_Conditional_2_Template(rf, ctx) { if (rf & 1) {
833
- i0.ɵɵelementStart(0, "span", 149);
863
+ function DuplicateDetectionResourceComponent_Conditional_68_For_49_For_7_Conditional_2_Template(rf, ctx) { if (rf & 1) {
864
+ i0.ɵɵelementStart(0, "span", 157);
834
865
  i0.ɵɵtext(1, "(not available)");
835
866
  i0.ɵɵelementEnd();
836
867
  } }
837
- function DuplicateDetectionResourceComponent_Conditional_66_For_49_For_7_Template(rf, ctx) { if (rf & 1) {
838
- const _r33 = i0.ɵɵgetCurrentView();
839
- i0.ɵɵelementStart(0, "div", 153);
840
- i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_66_For_49_For_7_Template_div_click_0_listener() { const ctx_r33 = i0.ɵɵrestoreView(_r33); const matchVal_r35 = ctx_r33.$implicit; const ɵ$index_660_r36 = ctx_r33.$index; const field_r31 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(matchVal_r35 != null ? ctx_r1.SelectFieldValue(field_r31, ɵ$index_660_r36 + 1) : null); });
841
- i0.ɵɵconditionalCreate(1, DuplicateDetectionResourceComponent_Conditional_66_For_49_For_7_Conditional_1_Template, 2, 2)(2, DuplicateDetectionResourceComponent_Conditional_66_For_49_For_7_Conditional_2_Template, 2, 0, "span", 149);
868
+ function DuplicateDetectionResourceComponent_Conditional_68_For_49_For_7_Template(rf, ctx) { if (rf & 1) {
869
+ const _r35 = i0.ɵɵgetCurrentView();
870
+ i0.ɵɵelementStart(0, "div", 161);
871
+ i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_68_For_49_For_7_Template_div_click_0_listener() { const ctx_r35 = i0.ɵɵrestoreView(_r35); const matchVal_r37 = ctx_r35.$implicit; const ɵ$index_685_r38 = ctx_r35.$index; const field_r33 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(matchVal_r37 != null ? ctx_r1.SelectFieldValue(field_r33, ɵ$index_685_r38 + 1) : null); });
872
+ i0.ɵɵconditionalCreate(1, DuplicateDetectionResourceComponent_Conditional_68_For_49_For_7_Conditional_1_Template, 2, 2)(2, DuplicateDetectionResourceComponent_Conditional_68_For_49_For_7_Conditional_2_Template, 2, 0, "span", 157);
842
873
  i0.ɵɵelementEnd();
843
874
  } if (rf & 2) {
844
- const matchVal_r35 = ctx.$implicit;
845
- const ɵ$index_660_r36 = ctx.$index;
846
- const ctx_r38 = i0.ɵɵnextContext();
847
- const field_r31 = ctx_r38.$implicit;
848
- const ɵ$index_645_r40 = ctx_r38.$index;
875
+ const matchVal_r37 = ctx.$implicit;
876
+ const ɵ$index_685_r38 = ctx.$index;
877
+ const ctx_r40 = i0.ɵɵnextContext();
878
+ const field_r33 = ctx_r40.$implicit;
879
+ const ɵ$index_670_r42 = ctx_r40.$index;
849
880
  const ctx_r1 = i0.ɵɵnextContext(2);
850
- i0.ɵɵclassProp("grid-row-odd", ɵ$index_645_r40 % 2 !== 0)("value-same", ctx_r1.AreValuesEqual(field_r31.SourceValue, matchVal_r35))("value-different", matchVal_r35 != null && field_r31.SourceValue != null && !ctx_r1.AreValuesEqual(field_r31.SourceValue, matchVal_r35))("field-selected", field_r31.SelectedColumnIndex === ɵ$index_660_r36 + 1);
881
+ i0.ɵɵclassProp("grid-row-odd", ɵ$index_670_r42 % 2 !== 0)("value-same", ctx_r1.AreValuesEqual(field_r33.SourceValue, matchVal_r37))("value-different", matchVal_r37 != null && field_r33.SourceValue != null && !ctx_r1.AreValuesEqual(field_r33.SourceValue, matchVal_r37))("field-selected", field_r33.SelectedColumnIndex === ɵ$index_685_r38 + 1);
851
882
  i0.ɵɵadvance();
852
- i0.ɵɵconditional(matchVal_r35 != null ? 1 : 2);
883
+ i0.ɵɵconditional(matchVal_r37 != null ? 1 : 2);
853
884
  } }
854
- function DuplicateDetectionResourceComponent_Conditional_66_For_49_Template(rf, ctx) { if (rf & 1) {
855
- const _r30 = i0.ɵɵgetCurrentView();
856
- i0.ɵɵelementStart(0, "div", 147);
885
+ function DuplicateDetectionResourceComponent_Conditional_68_For_49_Template(rf, ctx) { if (rf & 1) {
886
+ const _r32 = i0.ɵɵgetCurrentView();
887
+ i0.ɵɵelementStart(0, "div", 155);
857
888
  i0.ɵɵtext(1);
858
889
  i0.ɵɵelementEnd();
859
- i0.ɵɵelementStart(2, "div", 148);
860
- i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_66_For_49_Template_div_click_2_listener() { const field_r31 = i0.ɵɵrestoreView(_r30).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.SelectFieldValue(field_r31, 0)); });
861
- i0.ɵɵconditionalCreate(3, DuplicateDetectionResourceComponent_Conditional_66_For_49_Conditional_3_Template, 1, 1)(4, DuplicateDetectionResourceComponent_Conditional_66_For_49_Conditional_4_Template, 2, 0, "span", 149);
862
- i0.ɵɵconditionalCreate(5, DuplicateDetectionResourceComponent_Conditional_66_For_49_Conditional_5_Template, 1, 2, "input", 150);
890
+ i0.ɵɵelementStart(2, "div", 156);
891
+ i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_68_For_49_Template_div_click_2_listener() { const field_r33 = i0.ɵɵrestoreView(_r32).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.SelectFieldValue(field_r33, 0)); });
892
+ i0.ɵɵconditionalCreate(3, DuplicateDetectionResourceComponent_Conditional_68_For_49_Conditional_3_Template, 1, 1)(4, DuplicateDetectionResourceComponent_Conditional_68_For_49_Conditional_4_Template, 2, 0, "span", 157);
893
+ i0.ɵɵconditionalCreate(5, DuplicateDetectionResourceComponent_Conditional_68_For_49_Conditional_5_Template, 1, 2, "input", 158);
863
894
  i0.ɵɵelementEnd();
864
- i0.ɵɵrepeaterCreate(6, DuplicateDetectionResourceComponent_Conditional_66_For_49_For_7_Template, 3, 9, "div", 151, i0.ɵɵrepeaterTrackByIndex);
895
+ i0.ɵɵrepeaterCreate(6, DuplicateDetectionResourceComponent_Conditional_68_For_49_For_7_Template, 3, 9, "div", 159, i0.ɵɵrepeaterTrackByIndex);
865
896
  } if (rf & 2) {
866
- const field_r31 = ctx.$implicit;
867
- const ɵ$index_645_r40 = ctx.$index;
868
- i0.ɵɵclassProp("grid-row-odd", ɵ$index_645_r40 % 2 !== 0);
897
+ const field_r33 = ctx.$implicit;
898
+ const ɵ$index_670_r42 = ctx.$index;
899
+ i0.ɵɵclassProp("grid-row-odd", ɵ$index_670_r42 % 2 !== 0);
869
900
  i0.ɵɵadvance();
870
- i0.ɵɵtextInterpolate1(" ", field_r31.DisplayName, " ");
901
+ i0.ɵɵtextInterpolate1(" ", field_r33.DisplayName, " ");
871
902
  i0.ɵɵadvance();
872
- i0.ɵɵclassProp("grid-row-odd", ɵ$index_645_r40 % 2 !== 0)("has-diff-in-row", field_r31.HasDifference)("field-selected", field_r31.SelectedColumnIndex === 0);
903
+ i0.ɵɵclassProp("grid-row-odd", ɵ$index_670_r42 % 2 !== 0)("has-diff-in-row", field_r33.HasDifference)("field-selected", field_r33.SelectedColumnIndex === 0);
873
904
  i0.ɵɵadvance();
874
- i0.ɵɵconditional(field_r31.SourceValue != null ? 3 : 4);
905
+ i0.ɵɵconditional(field_r33.SourceValue != null ? 3 : 4);
875
906
  i0.ɵɵadvance(2);
876
- i0.ɵɵconditional(field_r31.HasDifference || field_r31.SelectedColumnIndex === 0 ? 5 : -1);
907
+ i0.ɵɵconditional(field_r33.HasDifference || field_r33.SelectedColumnIndex === 0 ? 5 : -1);
877
908
  i0.ɵɵadvance();
878
- i0.ɵɵrepeater(field_r31.MatchValues);
909
+ i0.ɵɵrepeater(field_r33.MatchValues);
879
910
  } }
880
- function DuplicateDetectionResourceComponent_Conditional_66_Conditional_59_Template(rf, ctx) { if (rf & 1) {
911
+ function DuplicateDetectionResourceComponent_Conditional_68_Conditional_59_Template(rf, ctx) { if (rf & 1) {
881
912
  i0.ɵɵtext(0);
882
913
  } if (rf & 2) {
883
914
  const ctx_r1 = i0.ɵɵnextContext(2);
884
915
  i0.ɵɵtextInterpolate2(" \u00B7 ", ctx_r1.CherryPickedCount(), " field", ctx_r1.CherryPickedCount() !== 1 ? "s" : "", " cherry-picked ");
885
916
  } }
886
- function DuplicateDetectionResourceComponent_Conditional_66_Template(rf, ctx) { if (rf & 1) {
917
+ function DuplicateDetectionResourceComponent_Conditional_68_Conditional_67_Template(rf, ctx) { if (rf & 1) {
918
+ i0.ɵɵelementStart(0, "span", 129);
919
+ i0.ɵɵelement(1, "i", 162);
920
+ i0.ɵɵtext(2, " Merging disabled for this entity");
921
+ i0.ɵɵelementEnd();
922
+ } }
923
+ function DuplicateDetectionResourceComponent_Conditional_68_Template(rf, ctx) { if (rf & 1) {
887
924
  const _r16 = i0.ɵɵgetCurrentView();
888
- i0.ɵɵelementStart(0, "div", 90);
889
- i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_66_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r16); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CloseComparison()); });
925
+ i0.ɵɵelementStart(0, "div", 92);
926
+ i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_68_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r16); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CloseComparison()); });
890
927
  i0.ɵɵelementEnd();
891
- i0.ɵɵelementStart(1, "div", 91);
892
- i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_66_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r16); return i0.ɵɵresetView($event.stopPropagation()); });
893
- i0.ɵɵelementStart(2, "div", 92)(3, "div", 93)(4, "div", 94);
928
+ i0.ɵɵelementStart(1, "div", 93);
929
+ i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_68_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r16); return i0.ɵɵresetView($event.stopPropagation()); });
930
+ i0.ɵɵelementStart(2, "div", 94)(3, "div", 95)(4, "div", 96);
894
931
  i0.ɵɵelement(5, "i");
895
932
  i0.ɵɵelementEnd();
896
- i0.ɵɵelementStart(6, "div")(7, "div", 95);
933
+ i0.ɵɵelementStart(6, "div")(7, "div", 97);
897
934
  i0.ɵɵtext(8);
898
935
  i0.ɵɵelementEnd();
899
- i0.ɵɵelementStart(9, "span", 96);
936
+ i0.ɵɵelementStart(9, "span", 98);
900
937
  i0.ɵɵtext(10);
901
938
  i0.ɵɵelementEnd();
902
- i0.ɵɵelementStart(11, "span", 97);
939
+ i0.ɵɵelementStart(11, "span", 99);
903
940
  i0.ɵɵtext(12);
904
941
  i0.ɵɵelementEnd()()();
905
- i0.ɵɵelementStart(13, "div", 98)(14, "div", 99)(15, "button", 100);
906
- i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_66_Template_button_click_15_listener() { i0.ɵɵrestoreView(_r16); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ComparisonShowAllFields = true); });
942
+ i0.ɵɵelementStart(13, "div", 100)(14, "div", 101)(15, "button", 102);
943
+ i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_68_Template_button_click_15_listener() { i0.ɵɵrestoreView(_r16); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ComparisonShowAllFields = true); });
907
944
  i0.ɵɵtext(16, "All Fields");
908
945
  i0.ɵɵelementEnd();
909
- i0.ɵɵelementStart(17, "button", 100);
910
- i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_66_Template_button_click_17_listener() { i0.ɵɵrestoreView(_r16); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ComparisonShowAllFields = false); });
946
+ i0.ɵɵelementStart(17, "button", 102);
947
+ i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_68_Template_button_click_17_listener() { i0.ɵɵrestoreView(_r16); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ComparisonShowAllFields = false); });
911
948
  i0.ɵɵtext(18, "Differences Only");
912
949
  i0.ɵɵelementEnd()();
913
- i0.ɵɵelementStart(19, "button", 101);
914
- i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_66_Template_button_click_19_listener() { i0.ɵɵrestoreView(_r16); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CloseComparison()); });
915
- i0.ɵɵelement(20, "i", 49);
950
+ i0.ɵɵelementStart(19, "button", 103);
951
+ i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_68_Template_button_click_19_listener() { i0.ɵɵrestoreView(_r16); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CloseComparison()); });
952
+ i0.ɵɵelement(20, "i", 50);
916
953
  i0.ɵɵelementEnd()()();
917
- i0.ɵɵconditionalCreate(21, DuplicateDetectionResourceComponent_Conditional_66_Conditional_21_Template, 2, 0, "div", 102);
918
- i0.ɵɵelementStart(22, "div", 103)(23, "div", 104)(24, "div", 105);
954
+ i0.ɵɵconditionalCreate(21, DuplicateDetectionResourceComponent_Conditional_68_Conditional_21_Template, 2, 0, "div", 104);
955
+ i0.ɵɵelementStart(22, "div", 105)(23, "div", 106)(24, "div", 107);
919
956
  i0.ɵɵtext(25, "Field");
920
957
  i0.ɵɵelementEnd();
921
- i0.ɵɵelementStart(26, "div", 106)(27, "span", 107);
958
+ i0.ɵɵelementStart(26, "div", 108)(27, "span", 109);
922
959
  i0.ɵɵtext(28, "Source");
923
960
  i0.ɵɵelementEnd();
924
- i0.ɵɵelementStart(29, "span", 108);
961
+ i0.ɵɵelementStart(29, "span", 110);
925
962
  i0.ɵɵtext(30);
926
963
  i0.ɵɵelementEnd();
927
- i0.ɵɵelementStart(31, "div", 109)(32, "input", 110);
928
- i0.ɵɵlistener("change", function DuplicateDetectionResourceComponent_Conditional_66_Template_input_change_32_listener() { i0.ɵɵrestoreView(_r16); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.SetSurvivor(0)); });
964
+ i0.ɵɵelementStart(31, "div", 111)(32, "input", 112);
965
+ i0.ɵɵlistener("change", function DuplicateDetectionResourceComponent_Conditional_68_Template_input_change_32_listener() { i0.ɵɵrestoreView(_r16); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.SetSurvivor(0)); });
929
966
  i0.ɵɵelementEnd();
930
- i0.ɵɵelementStart(33, "span", 111);
967
+ i0.ɵɵelementStart(33, "span", 113);
931
968
  i0.ɵɵtext(34);
932
969
  i0.ɵɵelementEnd()();
933
- i0.ɵɵelementStart(35, "button", 112);
934
- i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_66_Template_button_click_35_listener() { i0.ɵɵrestoreView(_r16); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.UseAllFieldsFrom(0)); });
935
- i0.ɵɵelement(36, "i", 113);
970
+ i0.ɵɵelementStart(35, "button", 114);
971
+ i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_68_Template_button_click_35_listener() { i0.ɵɵrestoreView(_r16); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.UseAllFieldsFrom(0)); });
972
+ i0.ɵɵelement(36, "i", 115);
936
973
  i0.ɵɵtext(37);
937
974
  i0.ɵɵelementEnd();
938
- i0.ɵɵelementStart(38, "div", 114)(39, "div", 115);
939
- i0.ɵɵelement(40, "i", 116);
940
- i0.ɵɵelementStart(41, "span", 117);
975
+ i0.ɵɵelementStart(38, "div", 116)(39, "div", 117);
976
+ i0.ɵɵelement(40, "i", 118);
977
+ i0.ɵɵelementStart(41, "span", 119);
941
978
  i0.ɵɵtext(42);
942
979
  i0.ɵɵelementEnd();
943
980
  i0.ɵɵtext(43);
944
- i0.ɵɵconditionalCreate(44, DuplicateDetectionResourceComponent_Conditional_66_Conditional_44_Template, 3, 0, "span", 118);
981
+ i0.ɵɵconditionalCreate(44, DuplicateDetectionResourceComponent_Conditional_68_Conditional_44_Template, 3, 0, "span", 120);
945
982
  i0.ɵɵelementEnd();
946
- i0.ɵɵconditionalCreate(45, DuplicateDetectionResourceComponent_Conditional_66_Conditional_45_Template, 5, 6);
983
+ i0.ɵɵconditionalCreate(45, DuplicateDetectionResourceComponent_Conditional_68_Conditional_45_Template, 5, 6);
947
984
  i0.ɵɵelementEnd()();
948
- i0.ɵɵrepeaterCreate(46, DuplicateDetectionResourceComponent_Conditional_66_For_47_Template, 24, 26, "div", 119, _forTrack3);
949
- i0.ɵɵrepeaterCreate(48, DuplicateDetectionResourceComponent_Conditional_66_For_49_Template, 8, 11, null, null, _forTrack4);
985
+ i0.ɵɵrepeaterCreate(46, DuplicateDetectionResourceComponent_Conditional_68_For_47_Template, 26, 26, "div", 121, _forTrack3);
986
+ i0.ɵɵrepeaterCreate(48, DuplicateDetectionResourceComponent_Conditional_68_For_49_Template, 8, 11, null, null, _forTrack4);
950
987
  i0.ɵɵelementEnd()();
951
- i0.ɵɵelementStart(50, "div", 120)(51, "div", 121)(52, "span", 122);
988
+ i0.ɵɵelementStart(50, "div", 122)(51, "div", 123)(52, "span", 124);
952
989
  i0.ɵɵtext(53);
953
990
  i0.ɵɵelementEnd();
954
- i0.ɵɵelementStart(54, "span", 123);
955
- i0.ɵɵelement(55, "i", 124);
991
+ i0.ɵɵelementStart(54, "span", 125);
992
+ i0.ɵɵelement(55, "i", 126);
956
993
  i0.ɵɵtext(56, " Surviving: ");
957
994
  i0.ɵɵelementStart(57, "strong");
958
995
  i0.ɵɵtext(58);
959
996
  i0.ɵɵelementEnd();
960
- i0.ɵɵconditionalCreate(59, DuplicateDetectionResourceComponent_Conditional_66_Conditional_59_Template, 1, 2);
997
+ i0.ɵɵconditionalCreate(59, DuplicateDetectionResourceComponent_Conditional_68_Conditional_59_Template, 1, 2);
961
998
  i0.ɵɵelementEnd()();
962
- i0.ɵɵelementStart(60, "div", 125)(61, "button", 83);
963
- i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_66_Template_button_click_61_listener() { i0.ɵɵrestoreView(_r16); const ctx_r1 = i0.ɵɵnextContext(); ctx_r1.RejectMatch(ctx_r1.ComparisonGroup); return i0.ɵɵresetView(ctx_r1.CloseComparison()); });
964
- i0.ɵɵelement(62, "i", 49);
999
+ i0.ɵɵelementStart(60, "div", 127)(61, "button", 85);
1000
+ i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_68_Template_button_click_61_listener() { i0.ɵɵrestoreView(_r16); const ctx_r1 = i0.ɵɵnextContext(); ctx_r1.RejectMatch(ctx_r1.ComparisonGroup); return i0.ɵɵresetView(ctx_r1.CloseComparison()); });
1001
+ i0.ɵɵelement(62, "i", 50);
965
1002
  i0.ɵɵtext(63, " Reject All ");
966
1003
  i0.ɵɵelementEnd();
967
- i0.ɵɵelementStart(64, "button", 126);
968
- i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_66_Template_button_click_64_listener() { i0.ɵɵrestoreView(_r16); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OpenMergeConfirm()); });
969
- i0.ɵɵelement(65, "i", 124);
1004
+ i0.ɵɵelementStart(64, "button", 128);
1005
+ i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_68_Template_button_click_64_listener() { i0.ɵɵrestoreView(_r16); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OpenMergeConfirm()); });
1006
+ i0.ɵɵelement(65, "i", 126);
970
1007
  i0.ɵɵtext(66, " Merge Records ");
971
- i0.ɵɵelementEnd()()()();
1008
+ i0.ɵɵelementEnd();
1009
+ i0.ɵɵconditionalCreate(67, DuplicateDetectionResourceComponent_Conditional_68_Conditional_67_Template, 3, 0, "span", 129);
1010
+ i0.ɵɵelementEnd()()();
972
1011
  } if (rf & 2) {
973
1012
  const ctx_r1 = i0.ɵɵnextContext();
974
1013
  i0.ɵɵclassProp("comparison-closing", ctx_r1.ComparisonClosing);
@@ -1027,32 +1066,34 @@ function DuplicateDetectionResourceComponent_Conditional_66_Template(rf, ctx) {
1027
1066
  i0.ɵɵadvance(2);
1028
1067
  i0.ɵɵproperty("disabled", ctx_r1.IsSaving);
1029
1068
  i0.ɵɵadvance(3);
1030
- i0.ɵɵproperty("disabled", ctx_r1.IsSaving);
1069
+ i0.ɵɵproperty("disabled", ctx_r1.IsSaving || !ctx_r1.HasMergeableMatches || !ctx_r1.MergeEnabled)("title", !ctx_r1.MergeEnabled ? "Merging is not enabled for this entity" : ctx_r1.HasMergeableMatches ? "Merge non-skipped records" : "All matches have been skipped");
1070
+ i0.ɵɵadvance(3);
1071
+ i0.ɵɵconditional(!ctx_r1.MergeEnabled ? 67 : -1);
1031
1072
  } }
1032
- function DuplicateDetectionResourceComponent_Conditional_67_Conditional_22_For_4_Template(rf, ctx) { if (rf & 1) {
1033
- i0.ɵɵelementStart(0, "div", 178)(1, "span", 179);
1073
+ function DuplicateDetectionResourceComponent_Conditional_69_Conditional_22_For_4_Template(rf, ctx) { if (rf & 1) {
1074
+ i0.ɵɵelementStart(0, "div", 187)(1, "span", 188);
1034
1075
  i0.ɵɵtext(2);
1035
1076
  i0.ɵɵelementEnd();
1036
- i0.ɵɵelementStart(3, "span", 180);
1077
+ i0.ɵɵelementStart(3, "span", 189);
1037
1078
  i0.ɵɵtext(4);
1038
1079
  i0.ɵɵelementEnd();
1039
- i0.ɵɵelementStart(5, "span", 181);
1080
+ i0.ɵɵelementStart(5, "span", 190);
1040
1081
  i0.ɵɵtext(6);
1041
1082
  i0.ɵɵelementEnd()();
1042
1083
  } if (rf & 2) {
1043
- const field_r42 = ctx.$implicit;
1084
+ const field_r44 = ctx.$implicit;
1044
1085
  i0.ɵɵadvance(2);
1045
- i0.ɵɵtextInterpolate(field_r42.DisplayName);
1086
+ i0.ɵɵtextInterpolate(field_r44.DisplayName);
1046
1087
  i0.ɵɵadvance(2);
1047
- i0.ɵɵtextInterpolate1("\"", field_r42.Value, "\"");
1088
+ i0.ɵɵtextInterpolate1("\"", field_r44.Value, "\"");
1048
1089
  i0.ɵɵadvance(2);
1049
- i0.ɵɵtextInterpolate1("from ", field_r42.SourceName);
1090
+ i0.ɵɵtextInterpolate1("from ", field_r44.SourceName);
1050
1091
  } }
1051
- function DuplicateDetectionResourceComponent_Conditional_67_Conditional_22_Template(rf, ctx) { if (rf & 1) {
1052
- i0.ɵɵelementStart(0, "div")(1, "div", 177);
1092
+ function DuplicateDetectionResourceComponent_Conditional_69_Conditional_22_Template(rf, ctx) { if (rf & 1) {
1093
+ i0.ɵɵelementStart(0, "div")(1, "div", 186);
1053
1094
  i0.ɵɵtext(2);
1054
1095
  i0.ɵɵelementEnd();
1055
- i0.ɵɵrepeaterCreate(3, DuplicateDetectionResourceComponent_Conditional_67_Conditional_22_For_4_Template, 7, 3, "div", 178, _forTrack4);
1096
+ i0.ɵɵrepeaterCreate(3, DuplicateDetectionResourceComponent_Conditional_69_Conditional_22_For_4_Template, 7, 3, "div", 187, _forTrack4);
1056
1097
  i0.ɵɵelementEnd();
1057
1098
  } if (rf & 2) {
1058
1099
  const ctx_r1 = i0.ɵɵnextContext(2);
@@ -1061,7 +1102,7 @@ function DuplicateDetectionResourceComponent_Conditional_67_Conditional_22_Templ
1061
1102
  i0.ɵɵadvance();
1062
1103
  i0.ɵɵrepeater(ctx_r1.GetCherryPickedFields());
1063
1104
  } }
1064
- function DuplicateDetectionResourceComponent_Conditional_67_Conditional_23_For_5_Conditional_3_Template(rf, ctx) { if (rf & 1) {
1105
+ function DuplicateDetectionResourceComponent_Conditional_69_Conditional_23_For_5_Conditional_3_Template(rf, ctx) { if (rf & 1) {
1065
1106
  i0.ɵɵelementStart(0, "strong");
1066
1107
  i0.ɵɵtext(1);
1067
1108
  i0.ɵɵelementEnd();
@@ -1071,18 +1112,18 @@ function DuplicateDetectionResourceComponent_Conditional_67_Conditional_23_For_5
1071
1112
  i0.ɵɵelementEnd();
1072
1113
  i0.ɵɵtext(5);
1073
1114
  } if (rf & 2) {
1074
- const col_r43 = i0.ɵɵnextContext().$implicit;
1115
+ const col_r45 = i0.ɵɵnextContext().$implicit;
1075
1116
  const ctx_r1 = i0.ɵɵnextContext(3);
1076
1117
  i0.ɵɵadvance();
1077
- i0.ɵɵtextInterpolate(col_r43.DepCount);
1118
+ i0.ɵɵtextInterpolate(col_r45.DepCount);
1078
1119
  i0.ɵɵadvance();
1079
- i0.ɵɵtextInterpolate1(" ", col_r43.DepCount === 1 ? "dependency" : "dependencies", " from ");
1120
+ i0.ɵɵtextInterpolate1(" ", col_r45.DepCount === 1 ? "dependency" : "dependencies", " from ");
1080
1121
  i0.ɵɵadvance(2);
1081
- i0.ɵɵtextInterpolate(col_r43.Name);
1122
+ i0.ɵɵtextInterpolate(col_r45.Name);
1082
1123
  i0.ɵɵadvance();
1083
1124
  i0.ɵɵtextInterpolate1(" \u2192 ", ctx_r1.SurvivorName(), " ");
1084
1125
  } }
1085
- function DuplicateDetectionResourceComponent_Conditional_67_Conditional_23_For_5_Conditional_4_Template(rf, ctx) { if (rf & 1) {
1126
+ function DuplicateDetectionResourceComponent_Conditional_69_Conditional_23_For_5_Conditional_4_Template(rf, ctx) { if (rf & 1) {
1086
1127
  i0.ɵɵelementStart(0, "strong");
1087
1128
  i0.ɵɵtext(1, "0");
1088
1129
  i0.ɵɵelementEnd();
@@ -1091,113 +1132,113 @@ function DuplicateDetectionResourceComponent_Conditional_67_Conditional_23_For_5
1091
1132
  i0.ɵɵtext(4);
1092
1133
  i0.ɵɵelementEnd();
1093
1134
  } if (rf & 2) {
1094
- const col_r43 = i0.ɵɵnextContext().$implicit;
1135
+ const col_r45 = i0.ɵɵnextContext().$implicit;
1095
1136
  i0.ɵɵadvance(4);
1096
- i0.ɵɵtextInterpolate(col_r43.Name);
1137
+ i0.ɵɵtextInterpolate(col_r45.Name);
1097
1138
  } }
1098
- function DuplicateDetectionResourceComponent_Conditional_67_Conditional_23_For_5_Template(rf, ctx) { if (rf & 1) {
1099
- i0.ɵɵelementStart(0, "div", 184);
1100
- i0.ɵɵelement(1, "i", 185);
1139
+ function DuplicateDetectionResourceComponent_Conditional_69_Conditional_23_For_5_Template(rf, ctx) { if (rf & 1) {
1140
+ i0.ɵɵelementStart(0, "div", 193);
1141
+ i0.ɵɵelement(1, "i", 194);
1101
1142
  i0.ɵɵelementStart(2, "span");
1102
- i0.ɵɵconditionalCreate(3, DuplicateDetectionResourceComponent_Conditional_67_Conditional_23_For_5_Conditional_3_Template, 6, 4)(4, DuplicateDetectionResourceComponent_Conditional_67_Conditional_23_For_5_Conditional_4_Template, 5, 1);
1143
+ i0.ɵɵconditionalCreate(3, DuplicateDetectionResourceComponent_Conditional_69_Conditional_23_For_5_Conditional_3_Template, 6, 4)(4, DuplicateDetectionResourceComponent_Conditional_69_Conditional_23_For_5_Conditional_4_Template, 5, 1);
1103
1144
  i0.ɵɵelementEnd()();
1104
1145
  } if (rf & 2) {
1105
- const col_r43 = ctx.$implicit;
1146
+ const col_r45 = ctx.$implicit;
1106
1147
  i0.ɵɵadvance(3);
1107
- i0.ɵɵconditional(col_r43.DepCount > 0 ? 3 : 4);
1148
+ i0.ɵɵconditional(col_r45.DepCount > 0 ? 3 : 4);
1108
1149
  } }
1109
- function DuplicateDetectionResourceComponent_Conditional_67_Conditional_23_Template(rf, ctx) { if (rf & 1) {
1110
- i0.ɵɵelementStart(0, "div", 168)(1, "div", 182);
1111
- i0.ɵɵelement(2, "i", 183);
1150
+ function DuplicateDetectionResourceComponent_Conditional_69_Conditional_23_Template(rf, ctx) { if (rf & 1) {
1151
+ i0.ɵɵelementStart(0, "div", 177)(1, "div", 191);
1152
+ i0.ɵɵelement(2, "i", 192);
1112
1153
  i0.ɵɵtext(3, " Dependencies to Transfer");
1113
1154
  i0.ɵɵelementEnd();
1114
- i0.ɵɵrepeaterCreate(4, DuplicateDetectionResourceComponent_Conditional_67_Conditional_23_For_5_Template, 5, 1, "div", 184, _forTrack6);
1155
+ i0.ɵɵrepeaterCreate(4, DuplicateDetectionResourceComponent_Conditional_69_Conditional_23_For_5_Template, 5, 1, "div", 193, _forTrack6);
1115
1156
  i0.ɵɵelementEnd();
1116
1157
  } if (rf & 2) {
1117
1158
  const ctx_r1 = i0.ɵɵnextContext(2);
1118
1159
  i0.ɵɵadvance(4);
1119
1160
  i0.ɵɵrepeater(ctx_r1.GetNonSurvivorColumns());
1120
1161
  } }
1121
- function DuplicateDetectionResourceComponent_Conditional_67_For_29_Conditional_4_Template(rf, ctx) { if (rf & 1) {
1162
+ function DuplicateDetectionResourceComponent_Conditional_69_For_29_Conditional_4_Template(rf, ctx) { if (rf & 1) {
1122
1163
  i0.ɵɵtext(0);
1123
1164
  } if (rf & 2) {
1124
- const col_r44 = i0.ɵɵnextContext().$implicit;
1125
- i0.ɵɵtextInterpolate2(" ", col_r44.DepCount, " dep", col_r44.DepCount !== 1 ? "s" : "", " transferring ");
1165
+ const col_r46 = i0.ɵɵnextContext().$implicit;
1166
+ i0.ɵɵtextInterpolate2(" ", col_r46.DepCount, " dep", col_r46.DepCount !== 1 ? "s" : "", " transferring ");
1126
1167
  } }
1127
- function DuplicateDetectionResourceComponent_Conditional_67_For_29_Conditional_5_Template(rf, ctx) { if (rf & 1) {
1168
+ function DuplicateDetectionResourceComponent_Conditional_69_For_29_Conditional_5_Template(rf, ctx) { if (rf & 1) {
1128
1169
  i0.ɵɵtext(0, " no deps ");
1129
1170
  } }
1130
- function DuplicateDetectionResourceComponent_Conditional_67_For_29_Template(rf, ctx) { if (rf & 1) {
1131
- i0.ɵɵelementStart(0, "div", 172)(1, "span", 186);
1171
+ function DuplicateDetectionResourceComponent_Conditional_69_For_29_Template(rf, ctx) { if (rf & 1) {
1172
+ i0.ɵɵelementStart(0, "div", 181)(1, "span", 195);
1132
1173
  i0.ɵɵtext(2);
1133
1174
  i0.ɵɵelementEnd();
1134
- i0.ɵɵelementStart(3, "span", 187);
1135
- i0.ɵɵconditionalCreate(4, DuplicateDetectionResourceComponent_Conditional_67_For_29_Conditional_4_Template, 1, 2)(5, DuplicateDetectionResourceComponent_Conditional_67_For_29_Conditional_5_Template, 1, 0);
1175
+ i0.ɵɵelementStart(3, "span", 196);
1176
+ i0.ɵɵconditionalCreate(4, DuplicateDetectionResourceComponent_Conditional_69_For_29_Conditional_4_Template, 1, 2)(5, DuplicateDetectionResourceComponent_Conditional_69_For_29_Conditional_5_Template, 1, 0);
1136
1177
  i0.ɵɵelementEnd()();
1137
1178
  } if (rf & 2) {
1138
- const col_r44 = ctx.$implicit;
1179
+ const col_r46 = ctx.$implicit;
1139
1180
  i0.ɵɵadvance(2);
1140
- i0.ɵɵtextInterpolate(col_r44.Name);
1181
+ i0.ɵɵtextInterpolate(col_r46.Name);
1141
1182
  i0.ɵɵadvance(2);
1142
- i0.ɵɵconditional(col_r44.DepCount > 0 ? 4 : 5);
1183
+ i0.ɵɵconditional(col_r46.DepCount > 0 ? 4 : 5);
1143
1184
  } }
1144
- function DuplicateDetectionResourceComponent_Conditional_67_Conditional_35_Template(rf, ctx) { if (rf & 1) {
1145
- i0.ɵɵelement(0, "i", 33);
1185
+ function DuplicateDetectionResourceComponent_Conditional_69_Conditional_35_Template(rf, ctx) { if (rf & 1) {
1186
+ i0.ɵɵelement(0, "i", 34);
1146
1187
  i0.ɵɵtext(1, " Merging... ");
1147
1188
  } }
1148
- function DuplicateDetectionResourceComponent_Conditional_67_Conditional_36_Template(rf, ctx) { if (rf & 1) {
1149
- i0.ɵɵelement(0, "i", 124);
1189
+ function DuplicateDetectionResourceComponent_Conditional_69_Conditional_36_Template(rf, ctx) { if (rf & 1) {
1190
+ i0.ɵɵelement(0, "i", 126);
1150
1191
  i0.ɵɵtext(1);
1151
1192
  } if (rf & 2) {
1152
1193
  const ctx_r1 = i0.ɵɵnextContext(2);
1153
1194
  i0.ɵɵadvance();
1154
1195
  i0.ɵɵtextInterpolate1(" Confirm Merge (", ctx_r1.GetNonSurvivorColumns().length + 1, " records \u2192 1) ");
1155
1196
  } }
1156
- function DuplicateDetectionResourceComponent_Conditional_67_Template(rf, ctx) { if (rf & 1) {
1157
- const _r41 = i0.ɵɵgetCurrentView();
1158
- i0.ɵɵelementStart(0, "div", 154);
1159
- i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_67_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r41); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CloseMergeConfirm()); });
1160
- i0.ɵɵelementStart(1, "div", 155);
1161
- i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_67_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r41); return i0.ɵɵresetView($event.stopPropagation()); });
1162
- i0.ɵɵelementStart(2, "div", 156)(3, "div", 157);
1163
- i0.ɵɵelement(4, "i", 124);
1164
- i0.ɵɵelementEnd();
1165
- i0.ɵɵelementStart(5, "div")(6, "div", 158);
1197
+ function DuplicateDetectionResourceComponent_Conditional_69_Template(rf, ctx) { if (rf & 1) {
1198
+ const _r43 = i0.ɵɵgetCurrentView();
1199
+ i0.ɵɵelementStart(0, "div", 163);
1200
+ i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_69_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r43); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CloseMergeConfirm()); });
1201
+ i0.ɵɵelementStart(1, "div", 164);
1202
+ i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_69_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r43); return i0.ɵɵresetView($event.stopPropagation()); });
1203
+ i0.ɵɵelementStart(2, "div", 165)(3, "div", 166);
1204
+ i0.ɵɵelement(4, "i", 126);
1205
+ i0.ɵɵelementEnd();
1206
+ i0.ɵɵelementStart(5, "div")(6, "div", 167);
1166
1207
  i0.ɵɵtext(7, "Confirm Record Merge");
1167
1208
  i0.ɵɵelementEnd();
1168
- i0.ɵɵelementStart(8, "div", 159);
1209
+ i0.ɵɵelementStart(8, "div", 168);
1169
1210
  i0.ɵɵtext(9, "This action cannot be undone. Please review carefully.");
1170
1211
  i0.ɵɵelementEnd()()();
1171
- i0.ɵɵelementStart(10, "div", 160)(11, "div", 161)(12, "div", 162);
1172
- i0.ɵɵelement(13, "i", 163);
1212
+ i0.ɵɵelementStart(10, "div", 169)(11, "div", 170)(12, "div", 171);
1213
+ i0.ɵɵelement(13, "i", 172);
1173
1214
  i0.ɵɵtext(14, " Surviving Record");
1174
1215
  i0.ɵɵelementEnd();
1175
- i0.ɵɵelementStart(15, "div", 164);
1216
+ i0.ɵɵelementStart(15, "div", 173);
1176
1217
  i0.ɵɵtext(16);
1177
1218
  i0.ɵɵelementEnd();
1178
- i0.ɵɵelementStart(17, "div", 165);
1179
- i0.ɵɵelement(18, "i", 166);
1219
+ i0.ɵɵelementStart(17, "div", 174);
1220
+ i0.ɵɵelement(18, "i", 175);
1180
1221
  i0.ɵɵtext(19);
1181
1222
  i0.ɵɵelementEnd();
1182
- i0.ɵɵelementStart(20, "div", 167);
1223
+ i0.ɵɵelementStart(20, "div", 176);
1183
1224
  i0.ɵɵtext(21, "This record's ID will be retained. All dependencies from merged records will be transferred here.");
1184
1225
  i0.ɵɵelementEnd()();
1185
- i0.ɵɵconditionalCreate(22, DuplicateDetectionResourceComponent_Conditional_67_Conditional_22_Template, 5, 2, "div");
1186
- i0.ɵɵconditionalCreate(23, DuplicateDetectionResourceComponent_Conditional_67_Conditional_23_Template, 6, 0, "div", 168);
1187
- i0.ɵɵelementStart(24, "div", 169)(25, "div", 170);
1188
- i0.ɵɵelement(26, "i", 171);
1226
+ i0.ɵɵconditionalCreate(22, DuplicateDetectionResourceComponent_Conditional_69_Conditional_22_Template, 5, 2, "div");
1227
+ i0.ɵɵconditionalCreate(23, DuplicateDetectionResourceComponent_Conditional_69_Conditional_23_Template, 6, 0, "div", 177);
1228
+ i0.ɵɵelementStart(24, "div", 178)(25, "div", 179);
1229
+ i0.ɵɵelement(26, "i", 180);
1189
1230
  i0.ɵɵtext(27, " Records to Delete After Merge");
1190
1231
  i0.ɵɵelementEnd();
1191
- i0.ɵɵrepeaterCreate(28, DuplicateDetectionResourceComponent_Conditional_67_For_29_Template, 6, 2, "div", 172, _forTrack6);
1232
+ i0.ɵɵrepeaterCreate(28, DuplicateDetectionResourceComponent_Conditional_69_For_29_Template, 6, 2, "div", 181, _forTrack6);
1192
1233
  i0.ɵɵelementEnd()();
1193
- i0.ɵɵelementStart(30, "div", 173)(31, "button", 174);
1194
- i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_67_Template_button_click_31_listener() { i0.ɵɵrestoreView(_r41); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CloseMergeConfirm()); });
1195
- i0.ɵɵelement(32, "i", 175);
1234
+ i0.ɵɵelementStart(30, "div", 182)(31, "button", 183);
1235
+ i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_69_Template_button_click_31_listener() { i0.ɵɵrestoreView(_r43); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CloseMergeConfirm()); });
1236
+ i0.ɵɵelement(32, "i", 184);
1196
1237
  i0.ɵɵtext(33, " Back ");
1197
1238
  i0.ɵɵelementEnd();
1198
- i0.ɵɵelementStart(34, "button", 176);
1199
- i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_67_Template_button_click_34_listener() { i0.ɵɵrestoreView(_r41); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ExecuteMerge()); });
1200
- i0.ɵɵconditionalCreate(35, DuplicateDetectionResourceComponent_Conditional_67_Conditional_35_Template, 2, 0)(36, DuplicateDetectionResourceComponent_Conditional_67_Conditional_36_Template, 2, 1);
1239
+ i0.ɵɵelementStart(34, "button", 185);
1240
+ i0.ɵɵlistener("click", function DuplicateDetectionResourceComponent_Conditional_69_Template_button_click_34_listener() { i0.ɵɵrestoreView(_r43); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ExecuteMerge()); });
1241
+ i0.ɵɵconditionalCreate(35, DuplicateDetectionResourceComponent_Conditional_69_Conditional_35_Template, 2, 0)(36, DuplicateDetectionResourceComponent_Conditional_69_Conditional_36_Template, 2, 1);
1201
1242
  i0.ɵɵelementEnd()()()();
1202
1243
  } if (rf & 2) {
1203
1244
  const ctx_r1 = i0.ɵɵnextContext();
@@ -1219,12 +1260,20 @@ function DuplicateDetectionResourceComponent_Conditional_67_Template(rf, ctx) {
1219
1260
  i0.ɵɵconditional(ctx_r1.IsMerging ? 35 : 36);
1220
1261
  } }
1221
1262
  let DuplicateDetectionResourceComponent = class DuplicateDetectionResourceComponent extends BaseResourceComponent {
1263
+ /** Close comparison panel on Escape key */
1264
+ OnEscapeKey() {
1265
+ if (this.ComparisonGroup) {
1266
+ this.CloseComparison();
1267
+ }
1268
+ }
1222
1269
  cdr = inject(ChangeDetectorRef);
1223
1270
  navigationService = inject(NavigationService);
1224
1271
  destroy$ = new Subject();
1225
1272
  filterSubject = new Subject();
1226
1273
  // Loading state
1227
1274
  IsLoading = false;
1275
+ /** Whether the results area (runs/details/matches) is still loading */
1276
+ IsLoadingResults = false;
1228
1277
  IsSaving = false;
1229
1278
  // ── Comparison Panel State ──
1230
1279
  /** The group being compared (null = panel closed) */
@@ -1255,6 +1304,10 @@ let DuplicateDetectionResourceComponent = class DuplicateDetectionResourceCompon
1255
1304
  ShowMergeConfirm = false;
1256
1305
  /** Whether the merge is currently executing */
1257
1306
  IsMerging = false;
1307
+ /** Whether the current entity allows record merging (controls merge button availability) */
1308
+ MergeEnabled = true;
1309
+ /** Whether merge-not-available inline banner should be shown in the results area */
1310
+ ShowMergeWarningBanner = false;
1258
1311
  // Raw data
1259
1312
  Runs = [];
1260
1313
  Details = [];
@@ -1278,6 +1331,8 @@ let DuplicateDetectionResourceComponent = class DuplicateDetectionResourceCompon
1278
1331
  IsDetecting = false;
1279
1332
  DetectionProgress = 0;
1280
1333
  DetectionStage = '';
1334
+ /** Raw stage key from the last progress event — used to detect phase transitions */
1335
+ detectionRawStage = '';
1281
1336
  /** Runtime threshold overrides — initialized from entity doc, adjustable via sliders */
1282
1337
  RunPotentialThreshold = 0.70;
1283
1338
  RunAbsoluteThreshold = 0.95;
@@ -1385,6 +1440,13 @@ let DuplicateDetectionResourceComponent = class DuplicateDetectionResourceCompon
1385
1440
  async ngAfterViewInit() {
1386
1441
  this.setupFilterDebounce();
1387
1442
  await this.LoadData();
1443
+ this.navigationService.SetAgentContext(this, {
1444
+ DetectionStatus: this.IsDetecting ? 'running' : 'idle',
1445
+ PendingCount: this.PendingGroups.length,
1446
+ ApprovedCount: this.ApprovedGroups.length,
1447
+ RejectedCount: this.RejectedGroups.length,
1448
+ SelectedEntityDoc: this.SelectedEntityDocumentID || null,
1449
+ });
1388
1450
  this.NotifyLoadComplete();
1389
1451
  }
1390
1452
  ngOnDestroy() {
@@ -1399,58 +1461,94 @@ let DuplicateDetectionResourceComponent = class DuplicateDetectionResourceCompon
1399
1461
  }
1400
1462
  /**
1401
1463
  * Loads all duplicate run data and builds the Kanban groups.
1464
+ * Split into two phases so that controls become interactive immediately:
1465
+ * Phase 1 - entity docs from KH engine cache (instant)
1466
+ * Phase 2 - runs/details/matches via RunViews (heavy)
1402
1467
  */
1403
1468
  async LoadData() {
1404
1469
  this.IsLoading = true;
1405
1470
  this.cdr.detectChanges();
1406
1471
  try {
1407
- // Use KnowledgeHubMetadataEngine for cached entity document data
1408
- const engine = KnowledgeHubMetadataEngine.Instance;
1409
- await engine.Config(false);
1410
- const rv = new RunView();
1411
- const [runsResult, detailsResult, matchesResult] = await rv.RunViews([
1412
- {
1413
- EntityName: 'MJ: Duplicate Runs',
1414
- ExtraFilter: "ProcessingStatus IN ('Complete', 'Failed', 'In Progress')",
1415
- OrderBy: 'StartedAt DESC',
1416
- ResultType: 'entity_object'
1417
- },
1418
- {
1419
- EntityName: 'MJ: Duplicate Run Details',
1420
- ExtraFilter: "MatchStatus = 'Complete'",
1421
- OrderBy: '__mj_CreatedAt DESC',
1422
- ResultType: 'entity_object'
1423
- },
1424
- {
1425
- EntityName: 'MJ: Duplicate Run Detail Matches',
1426
- OrderBy: 'MatchProbability DESC',
1427
- ResultType: 'entity_object'
1428
- }
1429
- ]);
1430
- if (runsResult.Success) {
1431
- this.Runs = runsResult.Results;
1432
- }
1433
- if (detailsResult.Success) {
1434
- this.Details = detailsResult.Results;
1435
- }
1436
- if (matchesResult.Success) {
1437
- this.Matches = matchesResult.Results;
1438
- }
1439
- // Build entity document options from cached active documents
1440
- this.buildEntityDocumentOptionsFromEngine(engine.GetActiveEntityDocuments());
1441
- this.buildGroups();
1442
- this.extractEntityNames();
1443
- this.computeDataRanges();
1444
- this.applyFilters();
1472
+ // Phase 1: Populate entity document picker from cache (instant)
1473
+ await this.loadEntityDocuments();
1474
+ // Controls are now interactive - only the results area is loading
1475
+ this.IsLoading = false;
1476
+ this.IsLoadingResults = true;
1477
+ this.cdr.detectChanges();
1478
+ // Phase 2: Load heavy run/detail/match data
1479
+ await this.loadRunData();
1445
1480
  }
1446
1481
  catch (error) {
1447
1482
  console.error('Error loading duplicate detection data:', error);
1448
1483
  }
1449
1484
  finally {
1450
1485
  this.IsLoading = false;
1486
+ this.IsLoadingResults = false;
1451
1487
  this.cdr.detectChanges();
1452
1488
  }
1453
1489
  }
1490
+ /** Phase 1: Load entity documents from KH engine cache (instant). */
1491
+ async loadEntityDocuments() {
1492
+ const engine = KnowledgeHubMetadataEngine.Instance;
1493
+ await engine.Config(false);
1494
+ this.buildEntityDocumentOptionsFromEngine(engine.GetActiveEntityDocuments());
1495
+ }
1496
+ /** Phase 2: Load runs, details, and matches via RunViews batch. */
1497
+ async loadRunData() {
1498
+ const rv = new RunView();
1499
+ const [runsResult, detailsResult, matchesResult] = await rv.RunViews([
1500
+ {
1501
+ EntityName: 'MJ: Duplicate Runs',
1502
+ ExtraFilter: "ProcessingStatus IN ('Complete', 'Failed', 'In Progress')",
1503
+ OrderBy: 'StartedAt DESC',
1504
+ ResultType: 'entity_object'
1505
+ },
1506
+ {
1507
+ EntityName: 'MJ: Duplicate Run Details',
1508
+ ExtraFilter: "MatchStatus = 'Complete'",
1509
+ OrderBy: '__mj_CreatedAt DESC',
1510
+ ResultType: 'entity_object'
1511
+ },
1512
+ {
1513
+ EntityName: 'MJ: Duplicate Run Detail Matches',
1514
+ OrderBy: 'MatchProbability DESC',
1515
+ ResultType: 'entity_object'
1516
+ }
1517
+ ]);
1518
+ if (runsResult.Success) {
1519
+ this.Runs = runsResult.Results;
1520
+ }
1521
+ if (detailsResult.Success) {
1522
+ this.Details = detailsResult.Results;
1523
+ }
1524
+ if (matchesResult.Success) {
1525
+ this.Matches = matchesResult.Results;
1526
+ }
1527
+ this.buildGroups();
1528
+ this.extractEntityNames();
1529
+ this.computeDataRanges();
1530
+ this.applyFilters();
1531
+ // Reconnect to any in-progress detection run
1532
+ this.reconnectToActiveRun();
1533
+ }
1534
+ /**
1535
+ * Check if there's an in-progress detection run and reconnect to its
1536
+ * progress subscription. This handles the case where the user navigated
1537
+ * away and came back while a run was active.
1538
+ */
1539
+ reconnectToActiveRun() {
1540
+ if (this.IsDetecting)
1541
+ return; // Already tracking a run
1542
+ const activeRun = this.Runs.find(r => r.ProcessingStatus === 'In Progress');
1543
+ if (!activeRun)
1544
+ return;
1545
+ LogStatus(`[DuplicateDetection] Reconnecting to in-progress run ${activeRun.ID}`);
1546
+ this.IsDetecting = true;
1547
+ this.DetectionProgress = 0;
1548
+ this.DetectionStage = 'Reconnecting...';
1549
+ this.cdr.detectChanges();
1550
+ this.subscribeToPipelineProgress(activeRun.ID);
1551
+ }
1454
1552
  /**
1455
1553
  * Trigger a new duplicate detection run by creating a DuplicateRun entity.
1456
1554
  * The server hook auto-triggers detection when a run is saved with EndedAt === null.
@@ -1472,9 +1570,17 @@ let DuplicateDetectionResourceComponent = class DuplicateDetectionResourceCompon
1472
1570
  dupeRun.NewRecord();
1473
1571
  // Look up the EntityID from the entity document's entity name
1474
1572
  const entityInfo = md.Entities.find(e => e.Name === selectedDoc.EntityName);
1475
- if (entityInfo) {
1476
- dupeRun.EntityID = entityInfo.ID;
1573
+ if (!entityInfo) {
1574
+ MJNotificationService.Instance.CreateSimpleNotification(`Entity "${selectedDoc.EntityName}" not found in metadata`, 'error', 5000);
1575
+ this.IsDetecting = false;
1576
+ this.DetectionStage = '';
1577
+ this.cdr.detectChanges();
1578
+ return;
1477
1579
  }
1580
+ // DD-1: Track whether merging is available for the selected entity
1581
+ this.MergeEnabled = entityInfo.AllowRecordMerge;
1582
+ this.ShowMergeWarningBanner = !entityInfo.AllowRecordMerge;
1583
+ dupeRun.EntityID = entityInfo.ID;
1478
1584
  dupeRun.StartedByUserID = new Metadata().CurrentUser.ID;
1479
1585
  dupeRun.StartedAt = new Date();
1480
1586
  dupeRun.ProcessingStatus = 'In Progress';
@@ -1649,6 +1755,39 @@ let DuplicateDetectionResourceComponent = class DuplicateDetectionResourceCompon
1649
1755
  return 'Low';
1650
1756
  }
1651
1757
  /** Format a date for display */
1758
+ /**
1759
+ * Format a composite key string (e.g., "ID|5A07433E-F36B-1410-8AA5-00F1597429B5")
1760
+ * into a readable format. For single-key entities, shows just the value truncated.
1761
+ * For composite keys, shows key: value pairs.
1762
+ */
1763
+ /** Whether there are any non-skipped matches available for merging */
1764
+ get HasMergeableMatches() {
1765
+ return this.ComparisonMatches.some(m => m.Match.ApprovalStatus !== 'Rejected');
1766
+ }
1767
+ FormatRecordID(recordID) {
1768
+ if (!recordID)
1769
+ return '';
1770
+ const pairs = recordID.split('||');
1771
+ if (pairs.length === 1) {
1772
+ // Single key — extract just the value
1773
+ const parts = pairs[0].split('|');
1774
+ if (parts.length === 2) {
1775
+ const val = parts[1];
1776
+ // Truncate long UUIDs
1777
+ return val.length > 12 ? val.substring(0, 8) + '...' : val;
1778
+ }
1779
+ return recordID.length > 12 ? recordID.substring(0, 8) + '...' : recordID;
1780
+ }
1781
+ // Composite key — show key: truncated value pairs
1782
+ return pairs.map(p => {
1783
+ const parts = p.split('|');
1784
+ if (parts.length === 2) {
1785
+ const val = parts[1].length > 8 ? parts[1].substring(0, 8) + '...' : parts[1];
1786
+ return `${parts[0]}: ${val}`;
1787
+ }
1788
+ return p;
1789
+ }).join(', ');
1790
+ }
1652
1791
  FormatDate(date) {
1653
1792
  if (!date)
1654
1793
  return '';
@@ -1744,6 +1883,8 @@ let DuplicateDetectionResourceComponent = class DuplicateDetectionResourceCompon
1744
1883
  }, 60000); // 60s timeout for duplicate detection (can be very long)
1745
1884
  };
1746
1885
  resetIdleTimer();
1886
+ // Reset phase tracking for this new subscription
1887
+ this.detectionRawStage = '';
1747
1888
  const sub = provider.subscribe(subscriptionQuery, { pipelineRunID });
1748
1889
  const rxSub = sub.pipe(takeUntil(this.destroy$)).subscribe({
1749
1890
  next: (data) => {
@@ -1751,10 +1892,22 @@ let DuplicateDetectionResourceComponent = class DuplicateDetectionResourceCompon
1751
1892
  if (!progress)
1752
1893
  return;
1753
1894
  const stage = progress['Stage'];
1754
- const pct = progress['PercentComplete'];
1895
+ const pct = Math.max(0, Math.min(100, progress['PercentComplete']));
1755
1896
  const currentItem = progress['CurrentItem'];
1756
- this.DetectionProgress = pct;
1757
- this.DetectionStage = this.formatDetectionStage(stage);
1897
+ // Detect phase transitions vs. within-phase updates
1898
+ const isNewPhase = stage !== this.detectionRawStage;
1899
+ if (isNewPhase) {
1900
+ // New phase: reset progress and update display
1901
+ this.detectionRawStage = stage;
1902
+ this.DetectionProgress = pct;
1903
+ this.DetectionStage = this.formatDetectionStage(stage);
1904
+ }
1905
+ else {
1906
+ // Same phase: only move forward (never backward)
1907
+ if (pct >= this.DetectionProgress) {
1908
+ this.DetectionProgress = pct;
1909
+ }
1910
+ }
1758
1911
  this.DetectionCurrentItem = currentItem ?? '';
1759
1912
  this.cdr.detectChanges();
1760
1913
  if (stage === 'complete') {
@@ -1839,7 +1992,7 @@ let DuplicateDetectionResourceComponent = class DuplicateDetectionResourceCompon
1839
1992
  const metadata = this.parseRecordMetadata(detail.RecordMetadata);
1840
1993
  const entityName = metadata.Entity || run?.Entity || 'Unknown';
1841
1994
  const entityIcon = metadata.EntityIcon || 'fa-solid fa-database';
1842
- const recordName = metadata.Name || detail.RecordID;
1995
+ const recordName = this.resolveRecordName(metadata, entityName, detail.RecordID);
1843
1996
  // Build top match summaries from match metadata
1844
1997
  const topMatchSummaries = this.buildTopMatchSummaries(detailMatches, 3);
1845
1998
  this.AllGroups.push({
@@ -2141,6 +2294,7 @@ let DuplicateDetectionResourceComponent = class DuplicateDetectionResourceCompon
2141
2294
  return match?.Name ?? 'Unknown';
2142
2295
  }
2143
2296
  // ════════════════════════════════════════════
2297
+ // ════════════════════════════════════════════
2144
2298
  // Merge Confirmation
2145
2299
  // ════════════════════════════════════════════
2146
2300
  /** Open the merge confirmation panel */
@@ -2170,12 +2324,19 @@ let DuplicateDetectionResourceComponent = class DuplicateDetectionResourceCompon
2170
2324
  });
2171
2325
  }
2172
2326
  /** Get non-surviving columns with their dependency counts */
2327
+ /** Get non-surviving columns excluding skipped (Rejected) matches for merge confirmation display */
2173
2328
  GetNonSurvivorColumns() {
2174
2329
  const result = [];
2175
2330
  const totalColumns = 1 + this.ComparisonMatches.length;
2176
2331
  for (let i = 0; i < totalColumns; i++) {
2177
2332
  if (i === this.SurvivorColumnIndex)
2178
2333
  continue;
2334
+ // Skip records marked as Rejected/Skipped
2335
+ if (i > 0) {
2336
+ const matchInfo = this.ComparisonMatches[i - 1];
2337
+ if (matchInfo?.Match?.ApprovalStatus === 'Rejected')
2338
+ continue;
2339
+ }
2179
2340
  result.push({
2180
2341
  ColumnIndex: i,
2181
2342
  Name: this.GetColumnName(i),
@@ -2244,6 +2405,12 @@ let DuplicateDetectionResourceComponent = class DuplicateDetectionResourceCompon
2244
2405
  for (let i = 0; i < totalColumns; i++) {
2245
2406
  if (i === this.SurvivorColumnIndex)
2246
2407
  continue;
2408
+ // Skip records that the user has marked as "Skipped" (Rejected)
2409
+ if (i > 0) {
2410
+ const matchInfo = this.ComparisonMatches[i - 1];
2411
+ if (matchInfo?.Match?.ApprovalStatus === 'Rejected')
2412
+ continue;
2413
+ }
2247
2414
  const keyStr = this.getCompositeKeyStringForColumn(i);
2248
2415
  if (keyStr) {
2249
2416
  const ck = new CompositeKey();
@@ -2261,7 +2428,7 @@ let DuplicateDetectionResourceComponent = class DuplicateDetectionResourceCompon
2261
2428
  this.IsSaving = false;
2262
2429
  this.cdr.detectChanges();
2263
2430
  }
2264
- /** Reject an individual match */
2431
+ /** Reject an individual match (skip it from merge) */
2265
2432
  async RejectIndividualMatch(matchInfo) {
2266
2433
  this.IsSaving = true;
2267
2434
  matchInfo.Match.ApprovalStatus = 'Rejected';
@@ -2269,6 +2436,14 @@ let DuplicateDetectionResourceComponent = class DuplicateDetectionResourceCompon
2269
2436
  this.IsSaving = false;
2270
2437
  this.cdr.detectChanges();
2271
2438
  }
2439
+ /** Undo a rejected individual match (restore to Pending) */
2440
+ async UndoRejectIndividualMatch(matchInfo) {
2441
+ this.IsSaving = true;
2442
+ matchInfo.Match.ApprovalStatus = 'Pending';
2443
+ await matchInfo.Match.Save();
2444
+ this.IsSaving = false;
2445
+ this.cdr.detectChanges();
2446
+ }
2272
2447
  /**
2273
2448
  * Load the actual entity records for the source + all matches in one RunView call.
2274
2449
  * Record IDs are stored as composite key strings (e.g., "ID|uuid") — we parse each
@@ -2377,11 +2552,12 @@ let DuplicateDetectionResourceComponent = class DuplicateDetectionResourceCompon
2377
2552
  .sort((a, b) => b.MatchProbability - a.MatchProbability)
2378
2553
  .map(m => {
2379
2554
  const meta = this.parseRecordMetadata(m.RecordMetadata);
2380
- // Try to get name from loaded entity record, fall back to vector metadata
2381
- const nameFromRecord = this.getRecordFieldValue(m.MatchRecordID, 'Name');
2555
+ // Resolve display name using IsNameField fields from entity metadata
2556
+ const entityName = this.ComparisonGroup.EntityName;
2557
+ const resolvedName = this.resolveMatchName(entityName, m.MatchRecordID, meta);
2382
2558
  return {
2383
2559
  Match: m,
2384
- Name: nameFromRecord || meta.Name || m.MatchRecordID?.substring(0, 16) + '...',
2560
+ Name: resolvedName,
2385
2561
  Score: m.MatchProbability,
2386
2562
  Metadata: meta,
2387
2563
  DiffCount: 0,
@@ -2398,7 +2574,15 @@ let DuplicateDetectionResourceComponent = class DuplicateDetectionResourceCompon
2398
2574
  const matchRecordIds = this.ComparisonGroup.Matches
2399
2575
  .sort((a, b) => b.MatchProbability - a.MatchProbability)
2400
2576
  .map(m => m.MatchRecordID);
2401
- for (const field of entityFields.sort((a, b) => a.Sequence - b.Sequence)) {
2577
+ // Sort fields: IsNameField first, then DefaultInView, then by Sequence
2578
+ const sortedFields = [...entityFields].sort((a, b) => {
2579
+ if (a.IsNameField !== b.IsNameField)
2580
+ return a.IsNameField ? -1 : 1;
2581
+ if (a.DefaultInView !== b.DefaultInView)
2582
+ return a.DefaultInView ? -1 : 1;
2583
+ return (a.Sequence ?? 9999) - (b.Sequence ?? 9999);
2584
+ });
2585
+ for (const field of sortedFields) {
2402
2586
  if (skip.has(field.Name) || field.IsPrimaryKey)
2403
2587
  continue;
2404
2588
  const sourceVal = this.getRecordFieldValue(sourceId, field.Name);
@@ -2441,11 +2625,86 @@ let DuplicateDetectionResourceComponent = class DuplicateDetectionResourceCompon
2441
2625
  .map(m => {
2442
2626
  const meta = this.parseRecordMetadata(m.RecordMetadata);
2443
2627
  return {
2444
- Name: meta.Name || m.MatchRecordID?.substring(0, 12) + '...',
2628
+ Name: this.resolveRecordName(meta, this.SelectedEntityFilter || 'Unknown', m.MatchRecordID ?? ''),
2445
2629
  Score: m.MatchProbability,
2446
2630
  };
2447
2631
  });
2448
2632
  }
2633
+ /**
2634
+ * Resolve match record name from loaded entity records using IsNameField fields.
2635
+ * Falls back to metadata, then truncated record ID.
2636
+ */
2637
+ resolveMatchName(entityName, matchRecordID, meta) {
2638
+ try {
2639
+ const md = new Metadata();
2640
+ const entityInfo = md.Entities.find(e => e.Name === entityName);
2641
+ if (entityInfo) {
2642
+ const nameFields = entityInfo.Fields
2643
+ .filter(f => f.IsNameField)
2644
+ .sort((a, b) => (a.Sequence ?? 9999) - (b.Sequence ?? 9999));
2645
+ if (nameFields.length > 0) {
2646
+ // Try loaded entity record data first
2647
+ const parts = nameFields
2648
+ .map(f => this.getRecordFieldValue(matchRecordID, f.Name))
2649
+ .filter(v => v != null && String(v).trim() !== '')
2650
+ .map(v => String(v));
2651
+ if (parts.length > 0)
2652
+ return parts.join(' ');
2653
+ // Fall back to vector metadata
2654
+ const metaParts = nameFields
2655
+ .map(f => meta[f.Name])
2656
+ .filter(v => v != null && String(v).trim() !== '')
2657
+ .map(v => String(v));
2658
+ if (metaParts.length > 0)
2659
+ return metaParts.join(' ');
2660
+ }
2661
+ }
2662
+ }
2663
+ catch { /* fall through */ }
2664
+ return meta.Name || this.FormatRecordID(matchRecordID ?? '');
2665
+ }
2666
+ /**
2667
+ * Resolve record display name from metadata using entity IsNameField fields.
2668
+ * Combines multiple name fields (e.g., FirstName + LastName → "Sarah Chen").
2669
+ * Falls back to metadata.Name, then recordID.
2670
+ */
2671
+ resolveRecordName(metadata, entityName, recordID) {
2672
+ try {
2673
+ const md = new Metadata();
2674
+ const entityInfo = md.Entities.find(e => e.Name === entityName);
2675
+ if (entityInfo) {
2676
+ const nameFields = entityInfo.Fields
2677
+ .filter(f => f.IsNameField)
2678
+ .sort((a, b) => (a.Sequence ?? 9999) - (b.Sequence ?? 9999));
2679
+ if (nameFields.length > 0) {
2680
+ // 1. Try individual name fields from metadata (new rich metadata)
2681
+ const metaParts = nameFields
2682
+ .map(f => metadata[f.Name])
2683
+ .filter(v => v != null && String(v).trim() !== '')
2684
+ .map(v => String(v));
2685
+ if (metaParts.length > 0)
2686
+ return metaParts.join(' ');
2687
+ // 2. Try loaded entity records (available in comparison panel)
2688
+ const recordParts = nameFields
2689
+ .map(f => this.getRecordFieldValue(recordID, f.Name))
2690
+ .filter(v => v != null && String(v).trim() !== '')
2691
+ .map(v => String(v));
2692
+ if (recordParts.length > 0)
2693
+ return recordParts.join(' ');
2694
+ }
2695
+ // 3. Single NameField fallback
2696
+ if (entityInfo.NameField && metadata[entityInfo.NameField.Name]) {
2697
+ return String(metadata[entityInfo.NameField.Name]);
2698
+ }
2699
+ }
2700
+ }
2701
+ catch { /* fall through */ }
2702
+ // 4. Heuristic — skip single-char or initial-only names from old sparse metadata
2703
+ const metaName = metadata.Name;
2704
+ if (metaName && metaName.length > 2)
2705
+ return metaName;
2706
+ return metadata.Title || this.FormatRecordID(recordID);
2707
+ }
2449
2708
  /**
2450
2709
  * Determine the dominant approval status for a group of matches.
2451
2710
  * If any match is Pending, the group is Pending.
@@ -2530,7 +2789,9 @@ let DuplicateDetectionResourceComponent = class DuplicateDetectionResourceCompon
2530
2789
  }
2531
2790
  }
2532
2791
  static ɵfac = /*@__PURE__*/ (() => { let ɵDuplicateDetectionResourceComponent_BaseFactory; return function DuplicateDetectionResourceComponent_Factory(__ngFactoryType__) { return (ɵDuplicateDetectionResourceComponent_BaseFactory || (ɵDuplicateDetectionResourceComponent_BaseFactory = i0.ɵɵgetInheritedFactory(DuplicateDetectionResourceComponent)))(__ngFactoryType__ || DuplicateDetectionResourceComponent); }; })();
2533
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: DuplicateDetectionResourceComponent, selectors: [["app-duplicate-detection-resource"]], inputs: { EmbeddedMode: "EmbeddedMode" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 68, vars: 28, consts: [[1, "duplicate-detection-container"], [1, "page-header"], [1, "header-left"], [1, "page-title"], [1, "fa-solid", "fa-clone"], [1, "header-actions"], [1, "run-detection-controls"], [1, "entity-doc-select", 3, "ngModelChange", "ngModel", "disabled"], ["value", ""], [3, "value"], [1, "run-detection-btn", 3, "click", "disabled"], [1, "detection-progress-section"], [1, "threshold-controls"], [1, "kpi-strip"], [1, "kpi-card"], [1, "kpi-value"], [1, "kpi-label"], [1, "kpi-card", "kpi-pending"], [1, "kpi-card", "kpi-approved"], [1, "kpi-card", "kpi-rejected"], [1, "filter-bar"], [1, "filter-group"], [1, "filter-select", 3, "ngModelChange", "ngModel", "disabled"], [1, "filter-range"], [1, "filter-label"], ["type", "number", "min", "0", "max", "1", "step", "0.05", 1, "filter-input", "filter-input-score", 3, "ngModelChange", "placeholder", "ngModel"], ["type", "date", 1, "filter-input", "filter-input-date", 3, "ngModelChange", "min", "max", "ngModel"], [1, "clear-filters-btn"], [1, "loading-container"], [1, "empty-state"], [1, "kanban-board"], [1, "saving-overlay"], [1, "merge-confirm-backdrop"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "fa-solid", "fa-magnifying-glass"], [1, "progress-header"], [1, "progress-stage"], [1, "progress-percent"], [1, "progress-bar-track"], [1, "progress-bar-fill"], [1, "progress-current-item"], [1, "threshold-slider-group"], [1, "threshold-label"], [1, "fa-solid", "fa-adjust"], [1, "threshold-value"], ["type", "range", 1, "threshold-slider", 3, "input", "min", "max", "step", "value", "disabled"], [1, "threshold-hint"], [1, "fa-solid", "fa-bullseye"], [1, "clear-filters-btn", 3, "click"], [1, "fa-solid", "fa-times"], ["text", "Loading duplicate detection results..."], [1, "fa-solid", "fa-clone", "empty-icon"], [1, "empty-text"], [1, "empty-subtext"], [1, "kanban-column"], [1, "column-header", "column-header-pending"], [1, "fa-solid", "fa-clock"], [1, "column-title"], [1, "column-count"], [1, "column-body", 3, "dragover", "dragleave", "drop"], ["draggable", "true", 1, "kanban-card"], [1, "column-empty"], [1, "column-header", "column-header-approved"], [1, "fa-solid", "fa-check-circle"], [1, "column-header", "column-header-rejected"], [1, "fa-solid", "fa-ban"], ["draggable", "true", 1, "kanban-card", 3, "dragstart", "dragend", "click"], [1, "card-header"], [1, "card-header-left"], [1, "card-icon"], [1, "card-title-block"], [1, "card-record-name", 3, "title"], [1, "entity-badge"], [1, "score-indicator"], [1, "card-body"], [1, "match-summaries"], [1, "card-meta-row"], [1, "card-meta-item"], [1, "fa-solid", "fa-layer-group"], [1, "fa-solid", "fa-calendar"], [1, "card-actions"], [1, "action-btn", "approve-btn", 3, "click", "disabled"], [1, "fa-solid", "fa-check"], [1, "action-btn", "reject-btn", 3, "click", "disabled"], [1, "match-summary-row"], [1, "match-summary-more"], [1, "match-score"], [1, "match-name"], [1, "fa-solid", "fa-inbox"], ["text", "Saving...", "size", "small"], [1, "slide-backdrop", 3, "click"], [1, "comparison-panel", 3, "click"], [1, "comparison-header"], [1, "comparison-header-left"], [1, "comparison-entity-icon"], [1, "comparison-title"], [1, "comparison-entity-badge"], [1, "comparison-match-count"], [1, "comparison-header-right"], [1, "comparison-toggle"], [1, "toggle-btn", 3, "click"], ["title", "Close (Esc)", 1, "comparison-close-btn", 3, "click"], [1, "comparison-loading"], [1, "comparison-grid-wrapper", 3, "hidden"], [1, "comparison-grid"], [1, "grid-corner-cell"], [1, "grid-col-header", "grid-col-source"], [1, "col-header-label"], [1, "col-header-name"], [1, "surviving-selector"], ["type", "radio", "name", "survivor", 1, "surviving-radio", 3, "change", "checked"], [1, "surviving-label"], [1, "use-all-btn", 3, "click"], [1, "fa-solid"], [1, "deps-summary"], [1, "deps-total"], [1, "fa-solid", "fa-link"], [1, "deps-total-number"], [1, "deps-total-recommended"], [1, "grid-col-header", 3, "match-approved", "match-rejected"], [1, "comparison-footer"], [1, "comparison-footer-left"], [1, "comparison-summary"], [1, "merge-summary"], [1, "fa-solid", "fa-code-merge"], [1, "comparison-footer-right"], [1, "action-btn", "merge-btn", 3, "click", "disabled"], ["text", "Loading records for comparison...", "size", "medium"], [1, "fa-solid", "fa-star"], [1, "deps-header", 3, "click"], [1, "deps-detail-list"], [1, "deps-detail-group"], [1, "deps-detail-row", 3, "click"], [1, "deps-detail-entity"], [1, "fa-solid", "deps-expand-icon"], [1, "deps-detail-count"], [1, "deps-records-list"], [1, "deps-record-loading"], [1, "deps-record-row"], [1, "deps-record-row", 3, "click"], [1, "fa-solid", "fa-arrow-up-right-from-square", "deps-record-icon"], [1, "deps-record-name"], [1, "grid-col-header"], [1, "col-header-top"], [1, "col-header-diff-count"], [1, "match-status-badge", 3, "status-approved", "status-rejected"], [1, "match-status-badge"], [1, "grid-label-cell"], [1, "grid-value-cell", "grid-source-cell", 3, "click"], [1, "field-not-available"], ["type", "radio", 1, "field-select-radio", 3, "name", "checked"], [1, "grid-value-cell", 3, "grid-row-odd", "value-same", "value-different", "field-selected"], ["type", "radio", 1, "field-select-radio", 3, "click", "change", "name", "checked"], [1, "grid-value-cell", 3, "click"], [1, "merge-confirm-backdrop", 3, "click"], [1, "merge-confirm-panel", 3, "click"], [1, "merge-confirm-header"], [1, "merge-confirm-icon"], [1, "merge-confirm-title"], [1, "merge-confirm-subtitle"], [1, "merge-confirm-body"], [1, "merge-survivor-card"], [1, "merge-survivor-label"], [1, "fa-solid", "fa-shield-halved"], [1, "merge-survivor-name"], [1, "merge-survivor-pk"], [1, "fa-solid", "fa-key"], [1, "merge-survivor-detail"], [1, "merge-deps-transfer"], [1, "merge-delete-card"], [1, "merge-delete-label"], [1, "fa-solid", "fa-trash"], [1, "merge-delete-item"], [1, "merge-confirm-footer"], [1, "action-btn", "cancel-btn", 3, "click", "disabled"], [1, "fa-solid", "fa-arrow-left"], [1, "action-btn", "confirm-merge-btn", 3, "click", "disabled"], [1, "merge-section-label"], [1, "merge-field-override"], [1, "merge-field-name"], [1, "merge-field-value"], [1, "merge-field-source"], [1, "merge-deps-transfer-label"], [1, "fa-solid", "fa-arrow-right-arrow-left"], [1, "merge-deps-transfer-row"], [1, "fa-solid", "fa-arrow-right"], [1, "merge-delete-name"], [1, "merge-delete-deps"]], template: function DuplicateDetectionResourceComponent_Template(rf, ctx) { if (rf & 1) {
2792
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: DuplicateDetectionResourceComponent, selectors: [["app-duplicate-detection-resource"]], hostBindings: function DuplicateDetectionResourceComponent_HostBindings(rf, ctx) { if (rf & 1) {
2793
+ i0.ɵɵlistener("keydown.escape", function DuplicateDetectionResourceComponent_keydown_escape_HostBindingHandler() { return ctx.OnEscapeKey(); }, i0.ɵɵresolveDocument);
2794
+ } }, inputs: { EmbeddedMode: "EmbeddedMode" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 70, vars: 29, consts: [[1, "duplicate-detection-container"], [1, "page-header"], [1, "header-left"], [1, "page-title"], [1, "fa-solid", "fa-clone"], [1, "header-actions"], [1, "run-detection-controls"], [1, "entity-doc-select", 3, "ngModelChange", "ngModel", "disabled"], ["value", ""], [3, "value"], [1, "run-detection-btn", 3, "click", "disabled"], [1, "detection-progress-section"], [1, "threshold-controls"], [1, "kpi-strip"], [1, "kpi-card"], [1, "kpi-value"], [1, "kpi-label"], [1, "kpi-card", "kpi-pending"], [1, "kpi-card", "kpi-approved"], [1, "kpi-card", "kpi-rejected"], [1, "filter-bar"], [1, "filter-group"], [1, "filter-select", 3, "ngModelChange", "ngModel", "disabled"], [1, "filter-range"], [1, "filter-label"], ["type", "number", "min", "0", "max", "1", "step", "0.05", 1, "filter-input", "filter-input-score", 3, "ngModelChange", "placeholder", "ngModel"], ["type", "date", 1, "filter-input", "filter-input-date", 3, "ngModelChange", "min", "max", "ngModel"], [1, "clear-filters-btn"], [1, "merge-warning-banner"], [1, "loading-container"], [1, "empty-state"], [1, "kanban-board"], [1, "saving-overlay"], [1, "merge-confirm-backdrop"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "fa-solid", "fa-magnifying-glass"], [1, "progress-header"], [1, "progress-stage"], [1, "progress-percent"], [1, "progress-bar-track"], [1, "progress-bar-fill"], [1, "progress-current-item"], [1, "threshold-slider-group"], [1, "threshold-label"], [1, "fa-solid", "fa-adjust"], [1, "threshold-value"], ["type", "range", 1, "threshold-slider", 3, "input", "min", "max", "step", "value", "disabled"], [1, "threshold-hint"], [1, "fa-solid", "fa-bullseye"], [1, "clear-filters-btn", 3, "click"], [1, "fa-solid", "fa-times"], [1, "fa-solid", "fa-triangle-exclamation"], ["text", "Loading duplicate detection results..."], [1, "fa-solid", "fa-clone", "empty-icon"], [1, "empty-text"], [1, "empty-subtext"], [1, "kanban-column"], [1, "column-header", "column-header-pending"], [1, "fa-solid", "fa-clock"], [1, "column-title"], [1, "column-count"], [1, "column-body", 3, "dragover", "dragleave", "drop"], ["draggable", "true", 1, "kanban-card"], [1, "column-empty"], [1, "column-header", "column-header-approved"], [1, "fa-solid", "fa-check-circle"], [1, "column-header", "column-header-rejected"], [1, "fa-solid", "fa-ban"], ["draggable", "true", 1, "kanban-card", 3, "dragstart", "dragend", "click"], [1, "card-header"], [1, "card-header-left"], [1, "card-icon"], [1, "card-title-block"], [1, "card-record-name", 3, "title"], [1, "entity-badge"], [1, "score-indicator"], [1, "card-body"], [1, "match-summaries"], [1, "card-meta-row"], [1, "card-meta-item"], [1, "fa-solid", "fa-layer-group"], [1, "fa-solid", "fa-calendar"], [1, "card-actions"], [1, "action-btn", "approve-btn", 3, "click", "disabled"], [1, "fa-solid", "fa-check"], [1, "action-btn", "reject-btn", 3, "click", "disabled"], [1, "match-summary-row"], [1, "match-summary-more"], [1, "match-score"], [1, "match-name"], [1, "fa-solid", "fa-inbox"], ["text", "Saving...", "size", "small"], [1, "slide-backdrop", 3, "click"], [1, "comparison-panel", 3, "click"], [1, "comparison-header"], [1, "comparison-header-left"], [1, "comparison-entity-icon"], [1, "comparison-title"], [1, "comparison-entity-badge"], [1, "comparison-match-count"], [1, "comparison-header-right"], [1, "comparison-toggle"], [1, "toggle-btn", 3, "click"], ["title", "Close (Esc)", 1, "comparison-close-btn", 3, "click"], [1, "comparison-loading"], [1, "comparison-grid-wrapper", 3, "hidden"], [1, "comparison-grid"], [1, "grid-corner-cell"], [1, "grid-col-header", "grid-col-source"], [1, "col-header-label"], [1, "col-header-name"], [1, "surviving-selector"], ["type", "radio", "name", "survivor", 1, "surviving-radio", 3, "change", "checked"], [1, "surviving-label"], [1, "use-all-btn", 3, "click"], [1, "fa-solid"], [1, "deps-summary"], [1, "deps-total"], [1, "fa-solid", "fa-link"], [1, "deps-total-number"], [1, "deps-total-recommended"], [1, "grid-col-header", 3, "match-approved", "match-rejected"], [1, "comparison-footer"], [1, "comparison-footer-left"], [1, "comparison-summary"], [1, "merge-summary"], [1, "fa-solid", "fa-code-merge"], [1, "comparison-footer-right"], [1, "action-btn", "merge-btn", 3, "click", "disabled", "title"], [1, "merge-disabled-hint"], ["text", "Loading records for comparison...", "size", "medium"], [1, "fa-solid", "fa-star"], [1, "deps-header", 3, "click"], [1, "deps-detail-list"], [1, "deps-detail-group"], [1, "deps-detail-row", 3, "click"], [1, "deps-detail-entity"], [1, "fa-solid", "deps-expand-icon"], [1, "deps-detail-count"], [1, "deps-records-list"], [1, "deps-record-loading"], [1, "deps-record-row"], [1, "deps-record-row", 3, "click"], [1, "fa-solid", "fa-arrow-up-right-from-square", "deps-record-icon"], [1, "deps-record-name"], [1, "grid-col-header"], [1, "col-header-top"], [1, "col-header-diff-count"], [1, "match-approval-actions"], ["title", "Skip this match (exclude from merge)", 1, "match-action-btn", "match-skip-btn"], ["title", "Skip this match (exclude from merge)", 1, "match-action-btn", "match-skip-btn", 3, "click"], [1, "match-status-badge"], ["title", "Undo skip", 1, "match-action-btn", "match-undo-btn"], ["title", "Undo skip", 1, "match-action-btn", "match-undo-btn", 3, "click"], [1, "fa-solid", "fa-undo"], [1, "grid-label-cell"], [1, "grid-value-cell", "grid-source-cell", 3, "click"], [1, "field-not-available"], ["type", "radio", 1, "field-select-radio", 3, "name", "checked"], [1, "grid-value-cell", 3, "grid-row-odd", "value-same", "value-different", "field-selected"], ["type", "radio", 1, "field-select-radio", 3, "click", "change", "name", "checked"], [1, "grid-value-cell", 3, "click"], [1, "fa-solid", "fa-info-circle"], [1, "merge-confirm-backdrop", 3, "click"], [1, "merge-confirm-panel", 3, "click"], [1, "merge-confirm-header"], [1, "merge-confirm-icon"], [1, "merge-confirm-title"], [1, "merge-confirm-subtitle"], [1, "merge-confirm-body"], [1, "merge-survivor-card"], [1, "merge-survivor-label"], [1, "fa-solid", "fa-shield-halved"], [1, "merge-survivor-name"], [1, "merge-survivor-pk"], [1, "fa-solid", "fa-key"], [1, "merge-survivor-detail"], [1, "merge-deps-transfer"], [1, "merge-delete-card"], [1, "merge-delete-label"], [1, "fa-solid", "fa-trash"], [1, "merge-delete-item"], [1, "merge-confirm-footer"], [1, "action-btn", "cancel-btn", 3, "click", "disabled"], [1, "fa-solid", "fa-arrow-left"], [1, "action-btn", "confirm-merge-btn", 3, "click", "disabled"], [1, "merge-section-label"], [1, "merge-field-override"], [1, "merge-field-name"], [1, "merge-field-value"], [1, "merge-field-source"], [1, "merge-deps-transfer-label"], [1, "fa-solid", "fa-arrow-right-arrow-left"], [1, "merge-deps-transfer-row"], [1, "fa-solid", "fa-arrow-right"], [1, "merge-delete-name"], [1, "merge-delete-deps"]], template: function DuplicateDetectionResourceComponent_Template(rf, ctx) { if (rf & 1) {
2534
2795
  i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "div", 2)(3, "h2", 3);
2535
2796
  i0.ɵɵelement(4, "i", 4);
2536
2797
  i0.ɵɵtext(5, " Duplicate Detection ");
@@ -2608,10 +2869,11 @@ let DuplicateDetectionResourceComponent = class DuplicateDetectionResourceCompon
2608
2869
  i0.ɵɵelementEnd()()();
2609
2870
  i0.ɵɵconditionalCreate(61, DuplicateDetectionResourceComponent_Conditional_61_Template, 3, 0, "button", 27);
2610
2871
  i0.ɵɵelementEnd();
2611
- i0.ɵɵconditionalCreate(62, DuplicateDetectionResourceComponent_Conditional_62_Template, 2, 0, "div", 28)(63, DuplicateDetectionResourceComponent_Conditional_63_Template, 6, 0, "div", 29)(64, DuplicateDetectionResourceComponent_Conditional_64_Template, 34, 12, "div", 30);
2612
- i0.ɵɵconditionalCreate(65, DuplicateDetectionResourceComponent_Conditional_65_Template, 2, 0, "div", 31);
2613
- i0.ɵɵconditionalCreate(66, DuplicateDetectionResourceComponent_Conditional_66_Template, 67, 40);
2614
- i0.ɵɵconditionalCreate(67, DuplicateDetectionResourceComponent_Conditional_67_Template, 37, 7, "div", 32);
2872
+ i0.ɵɵconditionalCreate(62, DuplicateDetectionResourceComponent_Conditional_62_Template, 3, 0, "div", 28);
2873
+ i0.ɵɵconditionalCreate(63, DuplicateDetectionResourceComponent_Conditional_63_Template, 2, 0, "div", 29)(64, DuplicateDetectionResourceComponent_Conditional_64_Template, 2, 0, "div", 29)(65, DuplicateDetectionResourceComponent_Conditional_65_Template, 6, 0, "div", 30)(66, DuplicateDetectionResourceComponent_Conditional_66_Template, 34, 12, "div", 31);
2874
+ i0.ɵɵconditionalCreate(67, DuplicateDetectionResourceComponent_Conditional_67_Template, 2, 0, "div", 32);
2875
+ i0.ɵɵconditionalCreate(68, DuplicateDetectionResourceComponent_Conditional_68_Template, 68, 42);
2876
+ i0.ɵɵconditionalCreate(69, DuplicateDetectionResourceComponent_Conditional_69_Template, 37, 7, "div", 33);
2615
2877
  i0.ɵɵelementEnd();
2616
2878
  } if (rf & 2) {
2617
2879
  i0.ɵɵadvance(8);
@@ -2657,14 +2919,16 @@ let DuplicateDetectionResourceComponent = class DuplicateDetectionResourceCompon
2657
2919
  i0.ɵɵadvance();
2658
2920
  i0.ɵɵconditional(ctx.HasActiveFilters ? 61 : -1);
2659
2921
  i0.ɵɵadvance();
2660
- i0.ɵɵconditional(ctx.IsLoading ? 62 : ctx.TotalGroupCount === 0 ? 63 : 64);
2661
- i0.ɵɵadvance(3);
2662
- i0.ɵɵconditional(ctx.IsSaving ? 65 : -1);
2922
+ i0.ɵɵconditional(ctx.ShowMergeWarningBanner ? 62 : -1);
2923
+ i0.ɵɵadvance();
2924
+ i0.ɵɵconditional(ctx.IsLoading ? 63 : ctx.IsLoadingResults ? 64 : ctx.TotalGroupCount === 0 ? 65 : 66);
2925
+ i0.ɵɵadvance(4);
2926
+ i0.ɵɵconditional(ctx.IsSaving ? 67 : -1);
2663
2927
  i0.ɵɵadvance();
2664
- i0.ɵɵconditional(ctx.ComparisonGroup ? 66 : -1);
2928
+ i0.ɵɵconditional(ctx.ComparisonGroup ? 68 : -1);
2665
2929
  i0.ɵɵadvance();
2666
- i0.ɵɵconditional(ctx.ShowMergeConfirm && ctx.ComparisonGroup ? 67 : -1);
2667
- } }, dependencies: [i1.NgSelectOption, i1.ɵNgSelectMultipleOption, i1.DefaultValueAccessor, i1.NumberValueAccessor, i1.SelectControlValueAccessor, i1.NgControlStatus, i1.MinValidator, i1.MaxValidator, i1.NgModel, i2.LoadingComponent], styles: ["/* ============================================================\n Duplicate Detection Kanban Board - Resource Component Styles\n All colors use MJ design tokens (--mj-*) exclusively.\n ============================================================ */\n\napp-duplicate-detection-resource {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n}\n\n.duplicate-detection-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n padding: 16px 20px;\n background: var(--mj-bg-page);\n position: relative;\n overflow: hidden;\n}\n\n/* ---- Page Header ---- */\n\n.page-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 16px;\n flex-shrink: 0;\n}\n\n.page-title {\n margin: 0;\n font-size: 20px;\n font-weight: 600;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.page-title i {\n color: var(--mj-brand-primary);\n}\n\n/* ---- Header Actions ---- */\n\n.header-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.run-detection-controls {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.entity-doc-select {\n padding: 8px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n min-width: 200px;\n}\n\n.entity-doc-select:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.run-detection-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border: none;\n border-radius: 6px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n cursor: pointer;\n font-size: 13px;\n font-weight: 600;\n transition: background 0.15s;\n white-space: nowrap;\n}\n\n.run-detection-btn:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n.run-detection-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n/* ---- Detection Progress ---- */\n\n.detection-progress-section {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-brand-primary);\n border-radius: 8px;\n padding: 14px 18px;\n margin-bottom: 16px;\n flex-shrink: 0;\n}\n\n.progress-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 8px;\n}\n\n.progress-stage {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-brand-primary);\n}\n\n.progress-percent {\n font-size: 13px;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.progress-bar-track {\n height: 6px;\n border-radius: 3px;\n background: var(--mj-bg-surface-sunken);\n overflow: hidden;\n}\n\n.progress-bar-fill {\n height: 100%;\n border-radius: 3px;\n background: var(--mj-brand-primary);\n transition: width 0.3s ease;\n}\n\n.progress-current-item {\n display: block;\n margin-top: 6px;\n font-size: 11px;\n color: var(--mj-text-muted);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* ---- Threshold Controls ---- */\n\n.threshold-controls {\n display: flex;\n gap: 24px;\n padding: 12px 16px;\n border-radius: 8px;\n background: color-mix(in srgb, var(--mj-status-info) 6%, var(--mj-bg-surface));\n border: 1px solid var(--mj-border-subtle);\n margin-bottom: 16px;\n flex-shrink: 0;\n}\n\n.threshold-slider-group {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.threshold-label {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 0.82rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.threshold-value {\n margin-left: auto;\n font-weight: 700;\n color: var(--mj-brand-primary);\n font-size: 0.85rem;\n}\n\n.threshold-slider {\n width: 100%;\n height: 4px;\n appearance: none;\n -webkit-appearance: none;\n background: var(--mj-border-default);\n border-radius: 2px;\n outline: none;\n cursor: pointer;\n}\n\n.threshold-slider::-webkit-slider-thumb {\n -webkit-appearance: none;\n width: 14px;\n height: 14px;\n border-radius: 50%;\n background: var(--mj-brand-primary);\n border: 2px solid var(--mj-bg-surface);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n cursor: pointer;\n}\n\n.threshold-slider::-moz-range-thumb {\n width: 14px;\n height: 14px;\n border-radius: 50%;\n background: var(--mj-brand-primary);\n border: 2px solid var(--mj-bg-surface);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n cursor: pointer;\n}\n\n.threshold-slider:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n\n.threshold-hint {\n font-size: 0.72rem;\n color: var(--mj-text-muted);\n}\n\n/* ---- Threshold Info (legacy) ---- */\n\n.threshold-info {\n display: flex;\n gap: 16px;\n padding: 8px 14px;\n border-radius: 6px;\n background: color-mix(in srgb, var(--mj-status-info) 8%, var(--mj-bg-surface));\n border: 1px solid var(--mj-status-info-border);\n margin-bottom: 16px;\n flex-shrink: 0;\n}\n\n.threshold-item {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: var(--mj-status-info-text);\n font-weight: 500;\n}\n\n.threshold-item i {\n font-size: 11px;\n}\n\n/* ---- KPI Strip ---- */\n\n.kpi-strip {\n display: flex;\n gap: 12px;\n margin-bottom: 16px;\n flex-shrink: 0;\n}\n\n.kpi-card {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 12px 16px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n}\n\n.kpi-value {\n font-size: 28px;\n font-weight: 700;\n color: var(--mj-text-primary);\n line-height: 1.2;\n}\n\n.kpi-label {\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-top: 2px;\n}\n\n.kpi-pending .kpi-value {\n color: var(--mj-status-warning);\n}\n\n.kpi-approved .kpi-value {\n color: var(--mj-status-success);\n}\n\n.kpi-rejected .kpi-value {\n color: var(--mj-status-error);\n}\n\n/* ---- Filter Bar ---- */\n\n.filter-bar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n margin-bottom: 16px;\n flex-shrink: 0;\n}\n\n.filter-group {\n display: flex;\n align-items: flex-end;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n.filter-select {\n height: 34px;\n padding: 4px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n outline: none;\n min-width: 160px;\n}\n\n.filter-select:focus {\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.filter-range {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.filter-label {\n font-size: 11px;\n font-weight: 500;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n.filter-input {\n height: 34px;\n padding: 4px 8px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n outline: none;\n width: 100px;\n}\n\n.filter-input-score {\n width: 80px;\n}\n\n.filter-input-date {\n width: 140px;\n}\n\n.filter-input:focus {\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.clear-filters-btn {\n display: flex;\n align-items: center;\n gap: 4px;\n height: 34px;\n padding: 0 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 13px;\n cursor: pointer;\n white-space: nowrap;\n}\n\n.clear-filters-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n/* ---- Loading & Empty States ---- */\n\n.loading-container {\n display: flex;\n align-items: center;\n justify-content: center;\n flex: 1;\n min-height: 200px;\n}\n\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n flex: 1;\n min-height: 200px;\n gap: 8px;\n}\n\n.empty-icon {\n font-size: 48px;\n color: var(--mj-text-disabled);\n}\n\n.empty-text {\n font-size: 16px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n.empty-subtext {\n font-size: 13px;\n color: var(--mj-text-muted);\n margin: 0;\n}\n\n/* ---- Kanban Board ---- */\n\n.kanban-board {\n display: flex;\n gap: 16px;\n flex: 1;\n min-height: 0;\n overflow-x: auto;\n}\n\n.kanban-column {\n flex: 1;\n min-width: 280px;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 10px;\n overflow: hidden;\n}\n\n.column-header {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 16px;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n border-bottom: 1px solid var(--mj-border-subtle);\n flex-shrink: 0;\n}\n\n.column-header-pending {\n background: color-mix(in srgb, var(--mj-status-warning) 8%, var(--mj-bg-surface));\n}\n\n.column-header-pending i {\n color: var(--mj-status-warning);\n}\n\n.column-header-approved {\n background: color-mix(in srgb, var(--mj-status-success) 8%, var(--mj-bg-surface));\n}\n\n.column-header-approved i {\n color: var(--mj-status-success);\n}\n\n.column-header-rejected {\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--mj-bg-surface));\n}\n\n.column-header-rejected i {\n color: var(--mj-status-error);\n}\n\n.column-title {\n flex: 1;\n}\n\n.column-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 24px;\n height: 24px;\n padding: 0 6px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 600;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.column-body {\n flex: 1;\n overflow-y: auto;\n padding: 12px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.column-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 6px;\n padding: 32px 16px;\n color: var(--mj-text-disabled);\n font-size: 13px;\n}\n\n.column-empty i {\n font-size: 24px;\n}\n\n/* ---- Kanban Cards ---- */\n\n.kanban-card {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n transition: box-shadow 0.15s ease, border-color 0.15s ease;\n flex-shrink: 0; /* Prevent cards from shrinking \u2014 column scrolls instead */\n}\n\n.kanban-card:hover {\n border-color: var(--mj-border-strong);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-text-primary) 8%, transparent);\n}\n\n/* Drag and Drop */\n.kanban-card[draggable=\"true\"] {\n cursor: grab;\n}\n\n.kanban-card[draggable=\"true\"]:active {\n cursor: grabbing;\n}\n\n.drop-target-active {\n outline: 2px dashed var(--mj-brand-primary);\n outline-offset: -2px;\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface-card)) !important;\n}\n\n.drop-target-active .column-body {\n min-height: 100px;\n}\n\n.card-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n padding: 10px 12px;\n border-bottom: 1px solid var(--mj-border-subtle);\n gap: 8px;\n}\n\n.card-header-left {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n min-width: 0;\n flex: 1;\n}\n\n.card-icon {\n width: 2rem;\n height: 2rem;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 6px;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 0.85rem;\n flex-shrink: 0;\n}\n\n.card-title-block {\n min-width: 0;\n flex: 1;\n}\n\n.card-record-name {\n font-size: 0.85rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n margin-bottom: 2px;\n}\n\n.entity-badge {\n display: inline-flex;\n align-items: center;\n padding: 1px 6px;\n border-radius: 3px;\n font-size: 10px;\n font-weight: 500;\n color: var(--mj-text-muted);\n letter-spacing: 0.2px;\n}\n\n/* Score indicator colors */\n\n.score-indicator {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 40px;\n padding: 2px 8px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 700;\n}\n\n.score-high {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success-text);\n border: 1px solid var(--mj-status-success-border);\n}\n\n.score-medium {\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning-text);\n border: 1px solid var(--mj-status-warning-border);\n}\n\n.score-low {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error-text);\n border: 1px solid var(--mj-status-error-border);\n}\n\n.card-body {\n padding: 10px 12px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.match-summaries {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.match-summary-row {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n}\n\n.match-score {\n flex-shrink: 0;\n font-weight: 600;\n font-size: 11px;\n color: var(--mj-text-muted);\n min-width: 30px;\n}\n\n.match-name {\n color: var(--mj-text-secondary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.match-summary-more {\n font-size: 11px;\n color: var(--mj-text-muted);\n font-style: italic;\n padding-left: 38px;\n}\n\n.card-meta-row {\n display: flex;\n align-items: center;\n gap: 12px;\n font-size: 11px;\n color: var(--mj-text-muted);\n border-top: 1px solid var(--mj-border-subtle);\n padding-top: 6px;\n}\n\n.card-meta-item {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.card-meta-item i {\n font-size: 10px;\n}\n font-size: 12px;\n max-width: 180px;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n Comparison Slide-In Panel\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.slide-backdrop {\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n z-index: 9999;\n animation: fadeIn 0.2s ease;\n}\n\n.slide-backdrop.comparison-closing {\n animation: fadeOut 0.25s ease forwards;\n}\n\n@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }\n@keyframes fadeOut { from { opacity: 1; } to { opacity: 0; } }\n\n.comparison-panel {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n width: 82vw;\n max-width: 1300px;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n box-shadow: -8px 0 40px rgba(0,0,0,0.4);\n z-index: 10000;\n display: flex;\n flex-direction: column;\n animation: slideIn 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n}\n\n.comparison-panel.comparison-closing {\n animation: slideOut 0.25s cubic-bezier(0.4, 0, 0.2, 1) forwards;\n}\n\n@keyframes slideIn { from { transform: translateX(100%); } to { transform: translateX(0); } }\n@keyframes slideOut { from { transform: translateX(0); } to { transform: translateX(100%); } }\n\n/* Header */\n.comparison-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 14px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n gap: 12px;\n}\n\n.comparison-header-left {\n display: flex;\n align-items: center;\n gap: 12px;\n min-width: 0;\n}\n\n.comparison-entity-icon {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 1rem;\n flex-shrink: 0;\n}\n\n.comparison-title {\n font-size: 1rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.comparison-entity-badge {\n display: inline-block;\n padding: 1px 7px;\n border-radius: 10px;\n font-size: 0.65rem;\n font-weight: 500;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n margin-right: 6px;\n}\n\n.comparison-match-count {\n font-size: 0.72rem;\n color: var(--mj-text-muted);\n}\n\n.comparison-header-right {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-shrink: 0;\n}\n\n/* Toggle */\n.comparison-toggle {\n display: flex;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n overflow: hidden;\n}\n\n.toggle-btn {\n padding: 5px 12px;\n font-size: 0.7rem;\n font-weight: 500;\n border: none;\n cursor: pointer;\n transition: all 0.15s ease;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n}\n\n.toggle-btn:first-child {\n border-right: 1px solid var(--mj-border-default);\n}\n\n.toggle-btn.toggle-active {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.comparison-close-btn {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n font-size: 0.85rem;\n transition: all 0.15s ease;\n}\n\n.comparison-close-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n/* Loading state */\n.comparison-loading {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n/* Grid wrapper */\n.comparison-grid-wrapper {\n flex: 1;\n overflow: auto;\n min-height: 0;\n}\n\n/* Grid */\n.comparison-grid {\n display: grid;\n min-width: 100%;\n}\n\n.comparison-grid > div {\n padding: 8px 12px;\n font-size: 0.78rem;\n border-bottom: 1px solid var(--mj-border-subtle);\n border-right: 1px solid var(--mj-border-subtle);\n}\n\n/* Corner cell */\n.grid-corner-cell {\n position: sticky;\n top: 0;\n left: 0;\n z-index: 4;\n background: var(--mj-bg-surface-elevated);\n font-size: 0.65rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--mj-text-muted);\n display: flex;\n align-items: flex-end;\n padding-bottom: 6px;\n}\n\n/* Column headers */\n.grid-col-header {\n position: sticky;\n top: 0;\n z-index: 3;\n background: var(--mj-bg-surface-elevated);\n padding: 10px 12px;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.grid-col-source {\n border-left: 3px solid var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, var(--mj-bg-surface-elevated));\n}\n\n.col-header-label {\n font-size: 0.6rem;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--mj-brand-primary);\n}\n\n.col-header-top {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 6px;\n}\n\n.col-header-name {\n font-size: 0.82rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.col-header-diff-count {\n font-size: 0.65rem;\n color: var(--mj-status-warning-text);\n}\n\n/* Surviving record selector */\n.surviving-selector {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-top: 4px;\n}\n\n.surviving-radio {\n appearance: none;\n width: 14px;\n height: 14px;\n border: 2px solid var(--mj-border-strong);\n border-radius: 50%;\n cursor: pointer;\n transition: all 0.15s ease;\n flex-shrink: 0;\n}\n\n.surviving-radio:checked {\n border-color: var(--mj-brand-primary);\n background: var(--mj-brand-primary);\n box-shadow: inset 0 0 0 2px var(--mj-bg-surface-elevated);\n}\n\n.surviving-label {\n font-size: 0.65rem;\n color: var(--mj-text-muted);\n cursor: pointer;\n}\n\n.surviving-label.is-survivor {\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n/* Use all fields button */\n.use-all-btn {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 3px 8px;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 0.62rem;\n cursor: pointer;\n transition: all 0.12s ease;\n margin-top: 2px;\n}\n\n.use-all-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.use-all-btn.all-selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n}\n\n/* Per-match actions */\n.comparison-match-actions {\n display: flex;\n gap: 4px;\n margin-top: 3px;\n}\n\n.action-btn-sm {\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: 1px solid;\n border-radius: 5px;\n cursor: pointer;\n font-size: 0.65rem;\n transition: all 0.15s ease;\n}\n\n.approve-btn-sm {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success-text);\n border-color: var(--mj-status-success-border);\n}\n.approve-btn-sm:hover { background: rgba(34,197,94,0.25); }\n\n.reject-btn-sm {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error-text);\n border-color: var(--mj-status-error-border);\n}\n.reject-btn-sm:hover { background: rgba(239,68,68,0.25); }\n\n.match-status-badge {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 0.68rem;\n font-weight: 500;\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.status-approved {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success-text);\n}\n\n.status-rejected {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error-text);\n}\n\n.match-approved {\n border-top: 3px solid var(--mj-status-success);\n}\n\n.match-rejected {\n border-top: 3px solid var(--mj-status-error);\n opacity: 0.6;\n}\n\n/* Label cells */\n.grid-label-cell {\n position: sticky;\n left: 0;\n z-index: 2;\n background: var(--mj-bg-surface);\n font-size: 0.72rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n display: flex;\n align-items: center;\n}\n\n.grid-row-odd {\n background: color-mix(in srgb, var(--mj-bg-surface-sunken) 50%, var(--mj-bg-surface));\n}\n\n.grid-label-cell.grid-row-odd {\n background: color-mix(in srgb, var(--mj-bg-surface-sunken) 50%, var(--mj-bg-surface));\n}\n\n/* Value cells */\n.grid-value-cell {\n font-size: 0.78rem;\n color: var(--mj-text-primary);\n line-height: 1.45;\n word-break: break-word;\n position: relative;\n cursor: pointer;\n}\n\n.grid-source-cell {\n background: color-mix(in srgb, var(--mj-brand-primary) 3%, var(--mj-bg-surface));\n border-left: 3px solid transparent;\n}\n\n.grid-source-cell.grid-row-odd {\n background: color-mix(in srgb, var(--mj-brand-primary) 3%, color-mix(in srgb, var(--mj-bg-surface-sunken) 50%, var(--mj-bg-surface)));\n}\n\n.grid-source-cell.has-diff-in-row {\n font-weight: 600;\n}\n\n/* Diff highlighting */\n.value-same {\n color: var(--mj-text-muted);\n}\n\n.value-different {\n background: color-mix(in srgb, var(--mj-status-warning) 8%, transparent) !important;\n border-left: 3px solid var(--mj-status-warning);\n color: var(--mj-text-primary);\n}\n\n.field-not-available {\n font-style: italic;\n font-size: 0.72rem;\n color: var(--mj-text-disabled);\n}\n\n/* Field selection radio */\n.field-select-radio {\n position: absolute;\n top: 50%;\n right: 8px;\n transform: translateY(-50%);\n appearance: none;\n width: 16px;\n height: 16px;\n border: 2px solid var(--mj-border-strong);\n border-radius: 50%;\n cursor: pointer;\n transition: all 0.12s ease;\n opacity: 0.4;\n}\n\n.field-select-radio:hover {\n opacity: 0.8;\n}\n\n.field-select-radio:checked {\n border-color: var(--mj-brand-primary);\n background: var(--mj-brand-primary);\n box-shadow: inset 0 0 0 2.5px var(--mj-bg-surface);\n opacity: 1;\n}\n\n.grid-value-cell.field-selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface)) !important;\n border-left: 3px solid var(--mj-brand-primary);\n}\n\n.grid-value-cell.field-selected .field-select-radio {\n opacity: 1;\n}\n\n/* Footer */\n.comparison-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 20px;\n border-top: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.comparison-footer-left {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n.comparison-summary {\n font-size: 0.72rem;\n color: var(--mj-text-muted);\n}\n\n.merge-summary {\n font-size: 0.72rem;\n color: var(--mj-brand-primary);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.merge-summary i {\n font-size: 0.65rem;\n}\n\n.comparison-footer-right {\n display: flex;\n gap: 8px;\n}\n\n.comparison-footer-right .action-btn {\n flex: none;\n padding: 7px 14px;\n}\n\n.merge-btn {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-color: var(--mj-brand-primary);\n}\n\n.merge-btn:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n.card-actions {\n display: flex;\n gap: 8px;\n padding: 10px 12px;\n border-top: 1px solid var(--mj-border-subtle);\n}\n\n.action-btn {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n height: 32px;\n padding: 0 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: background 0.15s ease, border-color 0.15s ease;\n}\n\n.action-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.approve-btn {\n background: color-mix(in srgb, var(--mj-status-success) 10%, var(--mj-bg-surface));\n color: var(--mj-status-success-text);\n border-color: var(--mj-status-success-border);\n}\n\n.approve-btn:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-status-success) 20%, var(--mj-bg-surface));\n}\n\n.reject-btn {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n color: var(--mj-status-error-text);\n border-color: var(--mj-status-error-border);\n}\n\n.reject-btn:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-status-error) 20%, var(--mj-bg-surface));\n}\n\n/* ---- Responsive ---- */\n\n@media (max-width: 768px) {\n .kanban-board {\n flex-direction: column;\n }\n\n .kanban-column {\n min-width: auto;\n max-height: 400px;\n }\n}\n\n@media (max-width: 480px) {\n .kpi-strip {\n flex-direction: column;\n }\n\n .filter-bar {\n flex-wrap: wrap;\n }\n\n .filter-group {\n flex-direction: column;\n align-items: stretch;\n width: 100%;\n }\n\n .filter-select {\n min-width: auto;\n width: 100%;\n }\n\n .filter-input {\n width: 100%;\n }\n\n .card-actions {\n flex-direction: column;\n }\n\n .action-btn {\n width: 100%;\n }\n}\n\n/* ---- Saving Overlay ---- */\n\n.saving-overlay {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-bg-overlay);\n z-index: 10;\n border-radius: 8px;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n Dependencies Summary (in column headers)\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.deps-summary {\n margin-top: 6px;\n padding: 6px 8px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 6px;\n font-size: 0.68rem;\n}\n\n.deps-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n cursor: pointer;\n color: var(--mj-text-secondary);\n font-weight: 600;\n}\n\n.deps-header i {\n font-size: 0.6rem;\n color: var(--mj-text-muted);\n}\n\n.deps-header:hover {\n color: var(--mj-text-primary);\n}\n\n.deps-total {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 0.72rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin-bottom: 2px;\n}\n\n.deps-total i {\n font-size: 0.65rem;\n color: var(--mj-text-muted);\n}\n\n.deps-total-number {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n padding: 0 6px;\n border-radius: 8px;\n font-size: 0.7rem;\n font-weight: 700;\n}\n\n.deps-total-recommended {\n font-size: 0.58rem;\n color: var(--mj-status-success-text);\n font-weight: 600;\n margin-left: 4px;\n}\n\n.deps-total-recommended i {\n color: var(--mj-status-success-text);\n}\n\n.deps-detail-list {\n margin-top: 4px;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.deps-detail-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 3px 0;\n font-size: 0.65rem;\n color: var(--mj-text-muted);\n cursor: pointer;\n border-radius: 3px;\n transition: background 0.1s ease;\n}\n\n.deps-detail-row:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.deps-detail-entity {\n display: flex;\n align-items: center;\n gap: 4px;\n color: var(--mj-text-secondary);\n}\n\n.deps-expand-icon {\n font-size: 0.5rem;\n width: 10px;\n text-align: center;\n color: var(--mj-text-muted);\n}\n\n/* Individual dependency records list */\n.deps-records-list {\n padding-left: 14px;\n margin-bottom: 2px;\n}\n\n.deps-record-row {\n display: flex;\n align-items: center;\n gap: 5px;\n padding: 2px 4px;\n font-size: 0.6rem;\n color: var(--mj-text-muted);\n cursor: pointer;\n border-radius: 3px;\n transition: color 0.1s ease, background 0.1s ease;\n}\n\n.deps-record-row:hover {\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n}\n\n.deps-record-icon {\n font-size: 0.5rem;\n flex-shrink: 0;\n}\n\n.deps-record-name {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 0.6rem;\n}\n\n.deps-record-loading {\n padding: 3px 4px;\n font-size: 0.6rem;\n color: var(--mj-text-muted);\n}\n\n.deps-record-loading i {\n margin-right: 4px;\n}\n\n.deps-detail-count {\n color: var(--mj-text-primary);\n font-weight: 600;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n Merge Confirmation Panel\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.merge-confirm-backdrop {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.3);\n z-index: 20000;\n animation: fadeIn 0.2s ease;\n}\n\n.merge-confirm-panel {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n width: 520px;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n box-shadow: -8px 0 40px rgba(0, 0, 0, 0.4);\n z-index: 20001;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n animation: slideIn 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.merge-confirm-header {\n padding: 18px 24px;\n border-bottom: 1px solid var(--mj-border-default);\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.merge-confirm-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 10px;\n background: color-mix(in srgb, var(--mj-status-warning) 12%, var(--mj-bg-surface));\n color: var(--mj-status-warning-text);\n font-size: 1.1rem;\n flex-shrink: 0;\n}\n\n.merge-confirm-title {\n font-size: 1.05rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.merge-confirm-subtitle {\n font-size: 0.75rem;\n color: var(--mj-text-muted);\n margin-top: 2px;\n}\n\n.merge-confirm-body {\n padding: 20px 24px;\n overflow-y: auto;\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n/* Surviving record card */\n\n.merge-survivor-card {\n padding: 14px;\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, var(--mj-bg-surface));\n border: 1px solid var(--mj-brand-primary);\n border-radius: 8px;\n}\n\n.merge-survivor-label {\n font-size: 0.65rem;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--mj-brand-primary);\n margin-bottom: 4px;\n}\n\n.merge-survivor-label i {\n margin-right: 4px;\n}\n\n.merge-survivor-name {\n font-size: 0.95rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.merge-survivor-pk {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-top: 4px;\n padding: 4px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border-radius: 4px;\n font-size: 0.68rem;\n font-family: monospace;\n color: var(--mj-text-secondary);\n}\n\n.merge-survivor-pk i {\n font-size: 0.6rem;\n color: var(--mj-brand-primary);\n}\n\n.merge-survivor-detail {\n font-size: 0.72rem;\n color: var(--mj-text-muted);\n margin-top: 4px;\n}\n\n/* Cherry-picked fields section */\n\n.merge-section-label {\n font-size: 0.7rem;\n font-weight: 700;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n margin-bottom: 6px;\n}\n\n.merge-field-override {\n display: flex;\n align-items: baseline;\n gap: 8px;\n padding: 6px 0;\n border-bottom: 1px solid var(--mj-border-subtle);\n font-size: 0.78rem;\n}\n\n.merge-field-name {\n font-weight: 600;\n color: var(--mj-text-secondary);\n min-width: 110px;\n flex-shrink: 0;\n}\n\n.merge-field-value {\n color: var(--mj-text-primary);\n}\n\n.merge-field-source {\n font-size: 0.65rem;\n color: var(--mj-text-muted);\n margin-left: auto;\n white-space: nowrap;\n}\n\n/* Dependency transfer summary */\n\n.merge-deps-transfer {\n padding: 10px 14px;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n}\n\n.merge-deps-transfer-label {\n font-size: 0.65rem;\n font-weight: 700;\n text-transform: uppercase;\n color: var(--mj-brand-primary);\n margin-bottom: 6px;\n}\n\n.merge-deps-transfer-label i {\n margin-right: 4px;\n}\n\n.merge-deps-transfer-row {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 3px 0;\n font-size: 0.75rem;\n color: var(--mj-text-secondary);\n}\n\n.merge-deps-transfer-row i {\n color: var(--mj-brand-primary);\n font-size: 0.65rem;\n width: 14px;\n text-align: center;\n}\n\n/* Records to delete */\n\n.merge-delete-card {\n padding: 10px 14px;\n background: color-mix(in srgb, var(--mj-status-error) 5%, var(--mj-bg-surface));\n border: 1px solid var(--mj-status-error-border);\n border-radius: 8px;\n}\n\n.merge-delete-label {\n font-size: 0.65rem;\n font-weight: 700;\n text-transform: uppercase;\n color: var(--mj-status-error-text);\n margin-bottom: 6px;\n}\n\n.merge-delete-label i {\n margin-right: 4px;\n}\n\n.merge-delete-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 5px 0;\n font-size: 0.78rem;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.merge-delete-item:last-child {\n border-bottom: none;\n}\n\n.merge-delete-name {\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.merge-delete-deps {\n font-size: 0.65rem;\n color: var(--mj-text-muted);\n}\n\n/* Confirm footer */\n\n.merge-confirm-footer {\n padding: 14px 24px;\n border-top: 1px solid var(--mj-border-default);\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 10px;\n}\n\n.cancel-btn {\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n border-color: var(--mj-border-default);\n}\n\n.cancel-btn:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.confirm-merge-btn {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.confirm-merge-btn:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n.confirm-merge-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n/* ---- Responsive: Merge Confirm ---- */\n\n@media (max-width: 600px) {\n .merge-confirm-panel {\n width: 100%;\n }\n}\n"], encapsulation: 2 });
2930
+ i0.ɵɵconditional(ctx.ShowMergeConfirm && ctx.ComparisonGroup ? 69 : -1);
2931
+ } }, dependencies: [i1.NgSelectOption, i1.ɵNgSelectMultipleOption, i1.DefaultValueAccessor, i1.NumberValueAccessor, i1.SelectControlValueAccessor, i1.NgControlStatus, i1.MinValidator, i1.MaxValidator, i1.NgModel, i2.LoadingComponent], styles: ["/* ============================================================\n Duplicate Detection Kanban Board - Resource Component Styles\n All colors use MJ design tokens (--mj-*) exclusively.\n ============================================================ */\n\napp-duplicate-detection-resource {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n}\n\n.duplicate-detection-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n padding: 16px 20px;\n background: var(--mj-bg-page);\n position: relative;\n overflow: hidden;\n}\n\n/* ---- Page Header ---- */\n\n.page-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 16px;\n flex-shrink: 0;\n}\n\n.page-title {\n margin: 0;\n font-size: 20px;\n font-weight: 600;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.page-title i {\n color: var(--mj-brand-primary);\n}\n\n/* ---- Header Actions ---- */\n\n.header-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.run-detection-controls {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.entity-doc-select {\n padding: 8px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n min-width: 200px;\n}\n\n.entity-doc-select:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.run-detection-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border: none;\n border-radius: 6px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n cursor: pointer;\n font-size: 13px;\n font-weight: 600;\n transition: background 0.15s;\n white-space: nowrap;\n}\n\n.run-detection-btn:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n.run-detection-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n/* ---- Detection Progress ---- */\n\n.detection-progress-section {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-brand-primary);\n border-radius: 8px;\n padding: 14px 18px;\n margin-bottom: 16px;\n flex-shrink: 0;\n}\n\n.progress-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 8px;\n}\n\n.progress-stage {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-brand-primary);\n}\n\n.progress-percent {\n font-size: 13px;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.progress-bar-track {\n height: 6px;\n border-radius: 3px;\n background: var(--mj-bg-surface-sunken);\n overflow: hidden;\n}\n\n.progress-bar-fill {\n height: 100%;\n border-radius: 3px;\n background: var(--mj-brand-primary);\n transition: width 0.3s ease;\n}\n\n.progress-current-item {\n display: block;\n margin-top: 6px;\n font-size: 11px;\n color: var(--mj-text-muted);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* ---- Threshold Controls ---- */\n\n.threshold-controls {\n display: flex;\n gap: 24px;\n padding: 12px 16px;\n border-radius: 8px;\n background: color-mix(in srgb, var(--mj-status-info) 6%, var(--mj-bg-surface));\n border: 1px solid var(--mj-border-subtle);\n margin-bottom: 16px;\n flex-shrink: 0;\n}\n\n.threshold-slider-group {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.threshold-label {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 0.82rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.threshold-value {\n margin-left: auto;\n font-weight: 700;\n color: var(--mj-brand-primary);\n font-size: 0.85rem;\n}\n\n.threshold-slider {\n width: 100%;\n height: 4px;\n appearance: none;\n -webkit-appearance: none;\n background: var(--mj-border-default);\n border-radius: 2px;\n outline: none;\n cursor: pointer;\n}\n\n.threshold-slider::-webkit-slider-thumb {\n -webkit-appearance: none;\n width: 14px;\n height: 14px;\n border-radius: 50%;\n background: var(--mj-brand-primary);\n border: 2px solid var(--mj-bg-surface);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n cursor: pointer;\n}\n\n.threshold-slider::-moz-range-thumb {\n width: 14px;\n height: 14px;\n border-radius: 50%;\n background: var(--mj-brand-primary);\n border: 2px solid var(--mj-bg-surface);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n cursor: pointer;\n}\n\n.threshold-slider:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n\n.threshold-hint {\n font-size: 0.72rem;\n color: var(--mj-text-muted);\n}\n\n/* ---- Threshold Info (legacy) ---- */\n\n.threshold-info {\n display: flex;\n gap: 16px;\n padding: 8px 14px;\n border-radius: 6px;\n background: color-mix(in srgb, var(--mj-status-info) 8%, var(--mj-bg-surface));\n border: 1px solid var(--mj-status-info-border);\n margin-bottom: 16px;\n flex-shrink: 0;\n}\n\n.threshold-item {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: var(--mj-status-info-text);\n font-weight: 500;\n}\n\n.threshold-item i {\n font-size: 11px;\n}\n\n/* ---- KPI Strip ---- */\n\n.kpi-strip {\n display: flex;\n gap: 12px;\n margin-bottom: 16px;\n flex-shrink: 0;\n}\n\n.kpi-card {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 12px 16px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n}\n\n.kpi-value {\n font-size: 28px;\n font-weight: 700;\n color: var(--mj-text-primary);\n line-height: 1.2;\n}\n\n.kpi-label {\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-top: 2px;\n}\n\n.kpi-pending .kpi-value {\n color: var(--mj-status-warning);\n}\n\n.kpi-approved .kpi-value {\n color: var(--mj-status-success);\n}\n\n.kpi-rejected .kpi-value {\n color: var(--mj-status-error);\n}\n\n/* ---- Filter Bar ---- */\n\n.filter-bar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n margin-bottom: 16px;\n flex-shrink: 0;\n}\n\n.filter-group {\n display: flex;\n align-items: flex-end;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n.filter-select {\n height: 34px;\n padding: 4px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n outline: none;\n min-width: 160px;\n}\n\n.filter-select:focus {\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.filter-range {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.filter-label {\n font-size: 11px;\n font-weight: 500;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n.filter-input {\n height: 34px;\n padding: 4px 8px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n outline: none;\n width: 100px;\n}\n\n.filter-input-score {\n width: 80px;\n}\n\n.filter-input-date {\n width: 140px;\n}\n\n.filter-input:focus {\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.clear-filters-btn {\n display: flex;\n align-items: center;\n gap: 4px;\n height: 34px;\n padding: 0 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 13px;\n cursor: pointer;\n white-space: nowrap;\n}\n\n.clear-filters-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n/* ---- Loading & Empty States ---- */\n\n.loading-container {\n display: flex;\n align-items: center;\n justify-content: center;\n flex: 1;\n min-height: 200px;\n}\n\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n flex: 1;\n min-height: 200px;\n gap: 8px;\n}\n\n.empty-icon {\n font-size: 48px;\n color: var(--mj-text-disabled);\n}\n\n.empty-text {\n font-size: 16px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n.empty-subtext {\n font-size: 13px;\n color: var(--mj-text-muted);\n margin: 0;\n}\n\n/* ---- Kanban Board ---- */\n\n.kanban-board {\n display: flex;\n gap: 16px;\n flex: 1;\n min-height: 0;\n overflow-x: auto;\n}\n\n.kanban-column {\n flex: 1;\n min-width: 280px;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 10px;\n overflow: hidden;\n}\n\n.column-header {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 16px;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n border-bottom: 1px solid var(--mj-border-subtle);\n flex-shrink: 0;\n}\n\n.column-header-pending {\n background: color-mix(in srgb, var(--mj-status-warning) 8%, var(--mj-bg-surface));\n}\n\n.column-header-pending i {\n color: var(--mj-status-warning);\n}\n\n.column-header-approved {\n background: color-mix(in srgb, var(--mj-status-success) 8%, var(--mj-bg-surface));\n}\n\n.column-header-approved i {\n color: var(--mj-status-success);\n}\n\n.column-header-rejected {\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--mj-bg-surface));\n}\n\n.column-header-rejected i {\n color: var(--mj-status-error);\n}\n\n.column-title {\n flex: 1;\n}\n\n.column-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 24px;\n height: 24px;\n padding: 0 6px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 600;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.column-body {\n flex: 1;\n overflow-y: auto;\n padding: 12px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.column-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 6px;\n padding: 32px 16px;\n color: var(--mj-text-disabled);\n font-size: 13px;\n}\n\n.column-empty i {\n font-size: 24px;\n}\n\n/* ---- Kanban Cards ---- */\n\n.kanban-card {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n transition: box-shadow 0.15s ease, border-color 0.15s ease;\n flex-shrink: 0; /* Prevent cards from shrinking \u2014 column scrolls instead */\n}\n\n.kanban-card:hover {\n border-color: var(--mj-border-strong);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-text-primary) 8%, transparent);\n}\n\n/* Drag and Drop */\n.kanban-card[draggable=\"true\"] {\n cursor: grab;\n}\n\n.kanban-card[draggable=\"true\"]:active {\n cursor: grabbing;\n}\n\n.drop-target-active {\n outline: 2px dashed var(--mj-brand-primary);\n outline-offset: -2px;\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface-card)) !important;\n}\n\n.drop-target-active .column-body {\n min-height: 100px;\n}\n\n.card-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n padding: 10px 12px;\n border-bottom: 1px solid var(--mj-border-subtle);\n gap: 8px;\n}\n\n.card-header-left {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n min-width: 0;\n flex: 1;\n}\n\n.card-icon {\n width: 2rem;\n height: 2rem;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 6px;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 0.85rem;\n flex-shrink: 0;\n}\n\n.card-title-block {\n min-width: 0;\n flex: 1;\n}\n\n.card-record-name {\n font-size: 0.85rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n margin-bottom: 2px;\n}\n\n.entity-badge {\n display: inline-flex;\n align-items: center;\n padding: 1px 6px;\n border-radius: 3px;\n font-size: 10px;\n font-weight: 500;\n color: var(--mj-text-muted);\n letter-spacing: 0.2px;\n}\n\n/* Score indicator colors */\n\n.score-indicator {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 40px;\n padding: 2px 8px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 700;\n}\n\n.score-high {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success-text);\n border: 1px solid var(--mj-status-success-border);\n}\n\n.score-medium {\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning-text);\n border: 1px solid var(--mj-status-warning-border);\n}\n\n.score-low {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error-text);\n border: 1px solid var(--mj-status-error-border);\n}\n\n.card-body {\n padding: 10px 12px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.match-summaries {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.match-summary-row {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n}\n\n.match-score {\n flex-shrink: 0;\n font-weight: 600;\n font-size: 11px;\n color: var(--mj-text-muted);\n min-width: 30px;\n}\n\n.match-name {\n color: var(--mj-text-secondary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.match-summary-more {\n font-size: 11px;\n color: var(--mj-text-muted);\n font-style: italic;\n padding-left: 38px;\n}\n\n.card-meta-row {\n display: flex;\n align-items: center;\n gap: 12px;\n font-size: 11px;\n color: var(--mj-text-muted);\n border-top: 1px solid var(--mj-border-subtle);\n padding-top: 6px;\n}\n\n.card-meta-item {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.card-meta-item i {\n font-size: 10px;\n}\n font-size: 12px;\n max-width: 180px;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n Comparison Slide-In Panel\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.slide-backdrop {\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n z-index: 9999;\n animation: fadeIn 0.2s ease;\n}\n\n.slide-backdrop.comparison-closing {\n animation: fadeOut 0.25s ease forwards;\n}\n\n@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }\n@keyframes fadeOut { from { opacity: 1; } to { opacity: 0; } }\n\n.comparison-panel {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n width: 82vw;\n max-width: 1300px;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n box-shadow: -8px 0 40px rgba(0,0,0,0.4);\n z-index: 10000;\n display: flex;\n flex-direction: column;\n animation: slideIn 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n}\n\n.comparison-panel.comparison-closing {\n animation: slideOut 0.25s cubic-bezier(0.4, 0, 0.2, 1) forwards;\n}\n\n@keyframes slideIn { from { transform: translateX(100%); } to { transform: translateX(0); } }\n@keyframes slideOut { from { transform: translateX(0); } to { transform: translateX(100%); } }\n\n/* Header */\n.comparison-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 14px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n gap: 12px;\n}\n\n.comparison-header-left {\n display: flex;\n align-items: center;\n gap: 12px;\n min-width: 0;\n}\n\n.comparison-entity-icon {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 1rem;\n flex-shrink: 0;\n}\n\n.comparison-title {\n font-size: 1rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.comparison-entity-badge {\n display: inline-block;\n padding: 1px 7px;\n border-radius: 10px;\n font-size: 0.65rem;\n font-weight: 500;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n margin-right: 6px;\n}\n\n.comparison-match-count {\n font-size: 0.72rem;\n color: var(--mj-text-muted);\n}\n\n.comparison-header-right {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-shrink: 0;\n}\n\n/* Toggle */\n.comparison-toggle {\n display: flex;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n overflow: hidden;\n}\n\n.toggle-btn {\n padding: 5px 12px;\n font-size: 0.7rem;\n font-weight: 500;\n border: none;\n cursor: pointer;\n transition: all 0.15s ease;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n}\n\n.toggle-btn:first-child {\n border-right: 1px solid var(--mj-border-default);\n}\n\n.toggle-btn.toggle-active {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.comparison-close-btn {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n font-size: 0.85rem;\n transition: all 0.15s ease;\n}\n\n.comparison-close-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n/* Loading state */\n.comparison-loading {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n/* Grid wrapper */\n.comparison-grid-wrapper {\n flex: 1;\n overflow: auto;\n min-height: 0;\n}\n\n/* Grid */\n.comparison-grid {\n display: grid;\n min-width: 100%;\n}\n\n.comparison-grid > div {\n padding: 8px 12px;\n font-size: 0.78rem;\n border-bottom: 1px solid var(--mj-border-subtle);\n border-right: 1px solid var(--mj-border-subtle);\n}\n\n/* Corner cell */\n.grid-corner-cell {\n position: sticky;\n top: 0;\n left: 0;\n z-index: 4;\n background: var(--mj-bg-surface-elevated);\n font-size: 0.65rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--mj-text-muted);\n display: flex;\n align-items: flex-end;\n padding-bottom: 6px;\n}\n\n/* Column headers */\n.grid-col-header {\n position: sticky;\n top: 0;\n z-index: 3;\n background: var(--mj-bg-surface-elevated);\n padding: 10px 12px;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.grid-col-source {\n border-left: 3px solid var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, var(--mj-bg-surface-elevated));\n}\n\n.col-header-label {\n font-size: 0.6rem;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--mj-brand-primary);\n}\n\n.col-header-top {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 6px;\n}\n\n.col-header-name {\n font-size: 0.82rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.col-header-diff-count {\n font-size: 0.65rem;\n color: var(--mj-status-warning-text);\n}\n\n/* Surviving record selector */\n.surviving-selector {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-top: 4px;\n}\n\n.surviving-radio {\n appearance: none;\n width: 14px;\n height: 14px;\n border: 2px solid var(--mj-border-strong);\n border-radius: 50%;\n cursor: pointer;\n transition: all 0.15s ease;\n flex-shrink: 0;\n}\n\n.surviving-radio:checked {\n border-color: var(--mj-brand-primary);\n background: var(--mj-brand-primary);\n box-shadow: inset 0 0 0 2px var(--mj-bg-surface-elevated);\n}\n\n.surviving-label {\n font-size: 0.65rem;\n color: var(--mj-text-muted);\n cursor: pointer;\n}\n\n.surviving-label.is-survivor {\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n/* Use all fields button */\n.use-all-btn {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 3px 8px;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 0.62rem;\n cursor: pointer;\n transition: all 0.12s ease;\n margin-top: 2px;\n}\n\n.use-all-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.use-all-btn.all-selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n}\n\n/* Per-match actions */\n.comparison-match-actions {\n display: flex;\n gap: 4px;\n margin-top: 3px;\n}\n\n.action-btn-sm {\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: 1px solid;\n border-radius: 5px;\n cursor: pointer;\n font-size: 0.65rem;\n transition: all 0.15s ease;\n}\n\n.approve-btn-sm {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success-text);\n border-color: var(--mj-status-success-border);\n}\n.approve-btn-sm:hover { background: rgba(34,197,94,0.25); }\n\n.reject-btn-sm {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error-text);\n border-color: var(--mj-status-error-border);\n}\n.reject-btn-sm:hover { background: rgba(239,68,68,0.25); }\n\n.match-status-badge {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 0.68rem;\n font-weight: 500;\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.status-approved {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success-text);\n}\n\n.status-rejected {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error-text);\n}\n\n.match-approval-actions {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-top: 6px;\n}\n\n.match-action-btn {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 3px 10px;\n border-radius: 6px;\n font-size: 0.7rem;\n font-weight: 500;\n border: 1px solid var(--mj-border-default);\n cursor: pointer;\n transition: background 0.15s ease, border-color 0.15s ease;\n}\n\n.match-skip-btn {\n background: var(--mj-bg-surface);\n color: var(--mj-status-error);\n border-color: color-mix(in srgb, var(--mj-status-error) 30%, var(--mj-border-default));\n}\n\n.match-skip-btn:hover {\n background: var(--mj-status-error-bg);\n border-color: var(--mj-status-error);\n}\n\n.match-undo-btn {\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n}\n\n.match-undo-btn:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-border-strong);\n}\n\n.match-approved {\n border-top: 3px solid var(--mj-status-success);\n}\n\n.match-rejected {\n border-top: 3px solid var(--mj-status-error);\n opacity: 0.6;\n}\n\n/* Label cells */\n.grid-label-cell {\n position: sticky;\n left: 0;\n z-index: 2;\n background: var(--mj-bg-surface);\n font-size: 0.72rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n display: flex;\n align-items: center;\n}\n\n.grid-row-odd {\n background: color-mix(in srgb, var(--mj-bg-surface-sunken) 50%, var(--mj-bg-surface));\n}\n\n.grid-label-cell.grid-row-odd {\n background: color-mix(in srgb, var(--mj-bg-surface-sunken) 50%, var(--mj-bg-surface));\n}\n\n/* Value cells */\n.grid-value-cell {\n font-size: 0.78rem;\n color: var(--mj-text-primary);\n line-height: 1.45;\n word-break: break-word;\n position: relative;\n cursor: pointer;\n}\n\n.grid-source-cell {\n background: color-mix(in srgb, var(--mj-brand-primary) 3%, var(--mj-bg-surface));\n border-left: 3px solid transparent;\n}\n\n.grid-source-cell.grid-row-odd {\n background: color-mix(in srgb, var(--mj-brand-primary) 3%, color-mix(in srgb, var(--mj-bg-surface-sunken) 50%, var(--mj-bg-surface)));\n}\n\n.grid-source-cell.has-diff-in-row {\n font-weight: 600;\n}\n\n/* Diff highlighting */\n.value-same {\n color: var(--mj-text-muted);\n}\n\n.value-different {\n background: color-mix(in srgb, var(--mj-status-warning) 8%, transparent) !important;\n border-left: 3px solid var(--mj-status-warning);\n color: var(--mj-text-primary);\n}\n\n.field-not-available {\n font-style: italic;\n font-size: 0.72rem;\n color: var(--mj-text-disabled);\n}\n\n/* Field selection radio */\n.field-select-radio {\n position: absolute;\n top: 50%;\n right: 8px;\n transform: translateY(-50%);\n appearance: none;\n width: 16px;\n height: 16px;\n border: 2px solid var(--mj-border-strong);\n border-radius: 50%;\n cursor: pointer;\n transition: all 0.12s ease;\n opacity: 0.4;\n}\n\n.field-select-radio:hover {\n opacity: 0.8;\n}\n\n.field-select-radio:checked {\n border-color: var(--mj-brand-primary);\n background: var(--mj-brand-primary);\n box-shadow: inset 0 0 0 2.5px var(--mj-bg-surface);\n opacity: 1;\n}\n\n.grid-value-cell.field-selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface)) !important;\n border-left: 3px solid var(--mj-brand-primary);\n}\n\n.grid-value-cell.field-selected .field-select-radio {\n opacity: 1;\n}\n\n/* Footer */\n.comparison-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 20px;\n border-top: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.comparison-footer-left {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n.comparison-summary {\n font-size: 0.72rem;\n color: var(--mj-text-muted);\n}\n\n.merge-summary {\n font-size: 0.72rem;\n color: var(--mj-brand-primary);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.merge-summary i {\n font-size: 0.65rem;\n}\n\n.comparison-footer-right {\n display: flex;\n gap: 8px;\n}\n\n.comparison-footer-right .action-btn {\n flex: none;\n padding: 7px 14px;\n}\n\n.merge-btn {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-color: var(--mj-brand-primary);\n}\n\n.merge-btn:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n.card-actions {\n display: flex;\n gap: 8px;\n padding: 10px 12px;\n border-top: 1px solid var(--mj-border-subtle);\n}\n\n.action-btn {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n height: 32px;\n padding: 0 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: background 0.15s ease, border-color 0.15s ease;\n}\n\n.action-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.approve-btn {\n background: color-mix(in srgb, var(--mj-status-success) 10%, var(--mj-bg-surface));\n color: var(--mj-status-success-text);\n border-color: var(--mj-status-success-border);\n}\n\n.approve-btn:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-status-success) 20%, var(--mj-bg-surface));\n}\n\n.reject-btn {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n color: var(--mj-status-error-text);\n border-color: var(--mj-status-error-border);\n}\n\n.reject-btn:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-status-error) 20%, var(--mj-bg-surface));\n}\n\n/* ---- Responsive ---- */\n\n@media (max-width: 768px) {\n .kanban-board {\n flex-direction: column;\n }\n\n .kanban-column {\n min-width: auto;\n max-height: 400px;\n }\n}\n\n@media (max-width: 480px) {\n .kpi-strip {\n flex-direction: column;\n }\n\n .filter-bar {\n flex-wrap: wrap;\n }\n\n .filter-group {\n flex-direction: column;\n align-items: stretch;\n width: 100%;\n }\n\n .filter-select {\n min-width: auto;\n width: 100%;\n }\n\n .filter-input {\n width: 100%;\n }\n\n .card-actions {\n flex-direction: column;\n }\n\n .action-btn {\n width: 100%;\n }\n}\n\n/* ---- Saving Overlay ---- */\n\n.saving-overlay {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-bg-overlay);\n z-index: 10;\n border-radius: 8px;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n Dependencies Summary (in column headers)\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.deps-summary {\n margin-top: 6px;\n padding: 6px 8px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 6px;\n font-size: 0.68rem;\n}\n\n.deps-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n cursor: pointer;\n color: var(--mj-text-secondary);\n font-weight: 600;\n}\n\n.deps-header i {\n font-size: 0.6rem;\n color: var(--mj-text-muted);\n}\n\n.deps-header:hover {\n color: var(--mj-text-primary);\n}\n\n.deps-total {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 0.72rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin-bottom: 2px;\n}\n\n.deps-total i {\n font-size: 0.65rem;\n color: var(--mj-text-muted);\n}\n\n.deps-total-number {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n padding: 0 6px;\n border-radius: 8px;\n font-size: 0.7rem;\n font-weight: 700;\n}\n\n.deps-total-recommended {\n font-size: 0.58rem;\n color: var(--mj-status-success-text);\n font-weight: 600;\n margin-left: 4px;\n}\n\n.deps-total-recommended i {\n color: var(--mj-status-success-text);\n}\n\n.deps-detail-list {\n margin-top: 4px;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.deps-detail-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 3px 0;\n font-size: 0.65rem;\n color: var(--mj-text-muted);\n cursor: pointer;\n border-radius: 3px;\n transition: background 0.1s ease;\n}\n\n.deps-detail-row:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.deps-detail-entity {\n display: flex;\n align-items: center;\n gap: 4px;\n color: var(--mj-text-secondary);\n}\n\n.deps-expand-icon {\n font-size: 0.5rem;\n width: 10px;\n text-align: center;\n color: var(--mj-text-muted);\n}\n\n/* Individual dependency records list */\n.deps-records-list {\n padding-left: 14px;\n margin-bottom: 2px;\n}\n\n.deps-record-row {\n display: flex;\n align-items: center;\n gap: 5px;\n padding: 2px 4px;\n font-size: 0.6rem;\n color: var(--mj-text-muted);\n cursor: pointer;\n border-radius: 3px;\n transition: color 0.1s ease, background 0.1s ease;\n}\n\n.deps-record-row:hover {\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n}\n\n.deps-record-icon {\n font-size: 0.5rem;\n flex-shrink: 0;\n}\n\n.deps-record-name {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 0.6rem;\n}\n\n.deps-record-loading {\n padding: 3px 4px;\n font-size: 0.6rem;\n color: var(--mj-text-muted);\n}\n\n.deps-record-loading i {\n margin-right: 4px;\n}\n\n.deps-detail-count {\n color: var(--mj-text-primary);\n font-weight: 600;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n Merge Confirmation Panel\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.merge-confirm-backdrop {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.3);\n z-index: 20000;\n animation: fadeIn 0.2s ease;\n}\n\n.merge-confirm-panel {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n width: 520px;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n box-shadow: -8px 0 40px rgba(0, 0, 0, 0.4);\n z-index: 20001;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n animation: slideIn 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.merge-confirm-header {\n padding: 18px 24px;\n border-bottom: 1px solid var(--mj-border-default);\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.merge-confirm-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 10px;\n background: color-mix(in srgb, var(--mj-status-warning) 12%, var(--mj-bg-surface));\n color: var(--mj-status-warning-text);\n font-size: 1.1rem;\n flex-shrink: 0;\n}\n\n.merge-confirm-title {\n font-size: 1.05rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.merge-confirm-subtitle {\n font-size: 0.75rem;\n color: var(--mj-text-muted);\n margin-top: 2px;\n}\n\n.merge-confirm-body {\n padding: 20px 24px;\n overflow-y: auto;\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n/* Surviving record card */\n\n.merge-survivor-card {\n padding: 14px;\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, var(--mj-bg-surface));\n border: 1px solid var(--mj-brand-primary);\n border-radius: 8px;\n}\n\n.merge-survivor-label {\n font-size: 0.65rem;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--mj-brand-primary);\n margin-bottom: 4px;\n}\n\n.merge-survivor-label i {\n margin-right: 4px;\n}\n\n.merge-survivor-name {\n font-size: 0.95rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.merge-survivor-pk {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-top: 4px;\n padding: 4px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border-radius: 4px;\n font-size: 0.68rem;\n font-family: monospace;\n color: var(--mj-text-secondary);\n}\n\n.merge-survivor-pk i {\n font-size: 0.6rem;\n color: var(--mj-brand-primary);\n}\n\n.merge-survivor-detail {\n font-size: 0.72rem;\n color: var(--mj-text-muted);\n margin-top: 4px;\n}\n\n/* Cherry-picked fields section */\n\n.merge-section-label {\n font-size: 0.7rem;\n font-weight: 700;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n margin-bottom: 6px;\n}\n\n.merge-field-override {\n display: flex;\n align-items: baseline;\n gap: 8px;\n padding: 6px 0;\n border-bottom: 1px solid var(--mj-border-subtle);\n font-size: 0.78rem;\n}\n\n.merge-field-name {\n font-weight: 600;\n color: var(--mj-text-secondary);\n min-width: 110px;\n flex-shrink: 0;\n}\n\n.merge-field-value {\n color: var(--mj-text-primary);\n}\n\n.merge-field-source {\n font-size: 0.65rem;\n color: var(--mj-text-muted);\n margin-left: auto;\n white-space: nowrap;\n}\n\n/* Dependency transfer summary */\n\n.merge-deps-transfer {\n padding: 10px 14px;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n}\n\n.merge-deps-transfer-label {\n font-size: 0.65rem;\n font-weight: 700;\n text-transform: uppercase;\n color: var(--mj-brand-primary);\n margin-bottom: 6px;\n}\n\n.merge-deps-transfer-label i {\n margin-right: 4px;\n}\n\n.merge-deps-transfer-row {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 3px 0;\n font-size: 0.75rem;\n color: var(--mj-text-secondary);\n}\n\n.merge-deps-transfer-row i {\n color: var(--mj-brand-primary);\n font-size: 0.65rem;\n width: 14px;\n text-align: center;\n}\n\n/* Records to delete */\n\n.merge-delete-card {\n padding: 10px 14px;\n background: color-mix(in srgb, var(--mj-status-error) 5%, var(--mj-bg-surface));\n border: 1px solid var(--mj-status-error-border);\n border-radius: 8px;\n}\n\n.merge-delete-label {\n font-size: 0.65rem;\n font-weight: 700;\n text-transform: uppercase;\n color: var(--mj-status-error-text);\n margin-bottom: 6px;\n}\n\n.merge-delete-label i {\n margin-right: 4px;\n}\n\n.merge-delete-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 5px 0;\n font-size: 0.78rem;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.merge-delete-item:last-child {\n border-bottom: none;\n}\n\n.merge-delete-name {\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.merge-delete-deps {\n font-size: 0.65rem;\n color: var(--mj-text-muted);\n}\n\n/* Confirm footer */\n\n.merge-confirm-footer {\n padding: 14px 24px;\n border-top: 1px solid var(--mj-border-default);\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 10px;\n}\n\n.cancel-btn {\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n border-color: var(--mj-border-default);\n}\n\n.cancel-btn:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.confirm-merge-btn {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.confirm-merge-btn:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n.confirm-merge-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n/* ---- Responsive: Merge Confirm ---- */\n\n@media (max-width: 600px) {\n .merge-confirm-panel {\n width: 100%;\n }\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550 Merge Disabled Hint \u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.merge-disabled-hint {\n font-size: 11.5px;\n color: var(--mj-status-warning-text, #e65100);\n display: inline-flex;\n align-items: center;\n gap: 4px;\n margin-left: 4px;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550 Merge Warning Banner (inline, non-blocking) \u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.merge-warning-banner {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n margin-bottom: 12px;\n border-radius: 6px;\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning-text);\n border: 1px solid var(--mj-status-warning-border);\n font-size: 13px;\n font-weight: 500;\n flex-shrink: 0;\n}\n\n.merge-warning-banner i {\n font-size: 14px;\n flex-shrink: 0;\n}\n"], encapsulation: 2 });
2668
2932
  };
2669
2933
  DuplicateDetectionResourceComponent = __decorate([
2670
2934
  RegisterClass(BaseResourceComponent, 'DuplicateDetectionResource')
@@ -2672,8 +2936,11 @@ DuplicateDetectionResourceComponent = __decorate([
2672
2936
  export { DuplicateDetectionResourceComponent };
2673
2937
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(DuplicateDetectionResourceComponent, [{
2674
2938
  type: Component,
2675
- args: [{ standalone: false, selector: 'app-duplicate-detection-resource', encapsulation: ViewEncapsulation.None, template: "<div class=\"duplicate-detection-container\">\n <!-- Header -->\n <div class=\"page-header\">\n <div class=\"header-left\">\n <h2 class=\"page-title\">\n <i class=\"fa-solid fa-clone\"></i> Duplicate Detection\n </h2>\n </div>\n <div class=\"header-actions\">\n <div class=\"run-detection-controls\">\n <select class=\"entity-doc-select\"\n [(ngModel)]=\"SelectedEntityDocumentID\"\n [disabled]=\"IsDetecting\">\n <option value=\"\">Select entity document...</option>\n @for (doc of EntityDocuments; track doc.ID) {\n <option [value]=\"doc.ID\">{{ doc.Name }} ({{ doc.EntityName }})</option>\n }\n </select>\n <button class=\"run-detection-btn\"\n (click)=\"RunDetection()\"\n [disabled]=\"IsDetecting || !SelectedEntityDocumentID\">\n @if (IsDetecting) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Detecting...\n } @else {\n <i class=\"fa-solid fa-magnifying-glass\"></i> Run Detection\n }\n </button>\n </div>\n </div>\n </div>\n\n <!-- Detection Progress (visible during run) -->\n @if (IsDetecting) {\n <div class=\"detection-progress-section\">\n <div class=\"progress-header\">\n <span class=\"progress-stage\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n {{ DetectionStage }}\n </span>\n <span class=\"progress-percent\">{{ DetectionProgress }}%</span>\n </div>\n <div class=\"progress-bar-track\">\n <div class=\"progress-bar-fill\" [style.width.%]=\"DetectionProgress\"></div>\n </div>\n @if (DetectionCurrentItem) {\n <span class=\"progress-current-item\">{{ DetectionCurrentItem }}</span>\n }\n </div>\n }\n\n <!-- Threshold Controls (when entity doc selected) -->\n @if (SelectedDocumentThresholds) {\n <div class=\"threshold-controls\">\n <div class=\"threshold-slider-group\">\n <label class=\"threshold-label\">\n <i class=\"fa-solid fa-adjust\"></i>\n Potential Match\n <span class=\"threshold-value\">{{ (RunPotentialThreshold * 100).toFixed(0) }}%</span>\n </label>\n <input type=\"range\" class=\"threshold-slider\"\n [min]=\"30\" [max]=\"99\" [step]=\"1\"\n [value]=\"RunPotentialThreshold * 100\"\n (input)=\"OnPotentialThresholdChanged($any($event.target).value / 100)\"\n [disabled]=\"IsDetecting\" />\n <span class=\"threshold-hint\">Score above which duplicates are flagged for review</span>\n </div>\n <div class=\"threshold-slider-group\">\n <label class=\"threshold-label\">\n <i class=\"fa-solid fa-bullseye\"></i>\n Absolute Match\n <span class=\"threshold-value\">{{ (RunAbsoluteThreshold * 100).toFixed(0) }}%</span>\n </label>\n <input type=\"range\" class=\"threshold-slider\"\n [min]=\"50\" [max]=\"100\" [step]=\"1\"\n [value]=\"RunAbsoluteThreshold * 100\"\n (input)=\"OnAbsoluteThresholdChanged($any($event.target).value / 100)\"\n [disabled]=\"IsDetecting\" />\n <span class=\"threshold-hint\">Score above which duplicates are auto-confirmed</span>\n </div>\n </div>\n }\n\n <!-- KPI Strip -->\n <div class=\"kpi-strip\">\n <div class=\"kpi-card\">\n <div class=\"kpi-value\">{{ TotalGroupCount }}</div>\n <div class=\"kpi-label\">Total Groups</div>\n </div>\n <div class=\"kpi-card kpi-pending\">\n <div class=\"kpi-value\">{{ PendingCount }}</div>\n <div class=\"kpi-label\">Pending</div>\n </div>\n <div class=\"kpi-card kpi-approved\">\n <div class=\"kpi-value\">{{ ApprovedCount }}</div>\n <div class=\"kpi-label\">Approved</div>\n </div>\n <div class=\"kpi-card kpi-rejected\">\n <div class=\"kpi-value\">{{ RejectedCount }}</div>\n <div class=\"kpi-label\">Rejected</div>\n </div>\n </div>\n\n <!-- Filter Bar -->\n <div class=\"filter-bar\">\n <div class=\"filter-group\">\n <select class=\"filter-select\"\n [(ngModel)]=\"Filters.EntityName\"\n (ngModelChange)=\"OnFilterChange()\"\n [disabled]=\"EntityNames.length <= 1\">\n @if (EntityNames.length > 1) {\n <option value=\"\">All Entities</option>\n }\n @for (name of EntityNames; track name) {\n <option [value]=\"name\">{{ name }}</option>\n }\n </select>\n\n <div class=\"filter-range\">\n <label class=\"filter-label\">Min Score</label>\n <input type=\"number\"\n class=\"filter-input filter-input-score\"\n min=\"0\" max=\"1\" step=\"0.05\"\n [placeholder]=\"DataMinScore\"\n [(ngModel)]=\"Filters.MinScore\"\n (ngModelChange)=\"OnFilterChange()\">\n </div>\n\n <div class=\"filter-range\">\n <label class=\"filter-label\">Max Score</label>\n <input type=\"number\"\n class=\"filter-input filter-input-score\"\n min=\"0\" max=\"1\" step=\"0.05\"\n [placeholder]=\"DataMaxScore\"\n [(ngModel)]=\"Filters.MaxScore\"\n (ngModelChange)=\"OnFilterChange()\">\n </div>\n\n <div class=\"filter-range\">\n <label class=\"filter-label\">From</label>\n <input type=\"date\"\n class=\"filter-input filter-input-date\"\n [min]=\"DataMinDate\" [max]=\"DataMaxDate\"\n [(ngModel)]=\"Filters.DateFrom\"\n (ngModelChange)=\"OnFilterChange()\">\n </div>\n\n <div class=\"filter-range\">\n <label class=\"filter-label\">To</label>\n <input type=\"date\"\n class=\"filter-input filter-input-date\"\n [min]=\"DataMinDate\" [max]=\"DataMaxDate\"\n [(ngModel)]=\"Filters.DateTo\"\n (ngModelChange)=\"OnFilterChange()\">\n </div>\n </div>\n\n @if (HasActiveFilters) {\n <button class=\"clear-filters-btn\" (click)=\"ClearFilters()\">\n <i class=\"fa-solid fa-times\"></i> Clear Filters\n </button>\n }\n </div>\n\n <!-- Content -->\n @if (IsLoading) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading duplicate detection results...\"></mj-loading>\n </div>\n } @else if (TotalGroupCount === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-clone empty-icon\"></i>\n <p class=\"empty-text\">No duplicate detection results found.</p>\n <p class=\"empty-subtext\">Select an entity document and click \"Run Detection\" to start.</p>\n </div>\n } @else {\n <!-- Kanban Board -->\n <div class=\"kanban-board\">\n <!-- Pending Column -->\n <div class=\"kanban-column\" [class.drop-target-active]=\"DragOverColumn === 'Pending' && DraggedGroup?.ApprovalStatus !== 'Pending'\">\n <div class=\"column-header column-header-pending\">\n <i class=\"fa-solid fa-clock\"></i>\n <span class=\"column-title\">Pending Review</span>\n <span class=\"column-count\">{{ PendingCount }}</span>\n </div>\n <div class=\"column-body\"\n (dragover)=\"OnDragOver($event, 'Pending')\"\n (dragleave)=\"OnDragLeave($event, 'Pending')\"\n (drop)=\"OnDrop($event, 'Pending')\">\n @for (group of PendingGroups; track group.DetailId) {\n <div class=\"kanban-card\"\n draggable=\"true\"\n (dragstart)=\"OnDragStart($event, group)\"\n (dragend)=\"OnDragEnd()\"\n (click)=\"OpenComparison(group)\">\n <div class=\"card-header\">\n <div class=\"card-header-left\">\n <div class=\"card-icon\">\n <i [class]=\"group.EntityIcon\"></i>\n </div>\n <div class=\"card-title-block\">\n <div class=\"card-record-name\" [title]=\"group.RecordName\">{{ group.RecordName }}</div>\n <span class=\"entity-badge\">{{ group.EntityName }}</span>\n </div>\n </div>\n <span class=\"score-indicator\" [class]=\"GetScoreClass(group.HighestScore)\">\n {{ (group.HighestScore * 100).toFixed(0) }}%\n </span>\n </div>\n <div class=\"card-body\">\n @if (group.TopMatchSummaries.length > 0) {\n <div class=\"match-summaries\">\n @for (ms of group.TopMatchSummaries; track ms.Name) {\n <div class=\"match-summary-row\">\n <span class=\"match-score\">{{ (ms.Score * 100).toFixed(0) }}%</span>\n <span class=\"match-name\">{{ ms.Name }}</span>\n </div>\n }\n @if (group.MatchCount > group.TopMatchSummaries.length) {\n <div class=\"match-summary-more\">+{{ group.MatchCount - group.TopMatchSummaries.length }} more</div>\n }\n </div>\n }\n <div class=\"card-meta-row\">\n <span class=\"card-meta-item\">\n <i class=\"fa-solid fa-layer-group\"></i>\n {{ group.MatchCount }} match{{ group.MatchCount !== 1 ? 'es' : '' }}\n </span>\n <span class=\"card-meta-item\">\n <i class=\"fa-solid fa-calendar\"></i>\n {{ FormatDate(group.MatchedAt) }}\n </span>\n </div>\n </div>\n <div class=\"card-actions\">\n <button class=\"action-btn approve-btn\"\n [disabled]=\"IsSaving\"\n (click)=\"ApproveMatch(group); $event.stopPropagation()\">\n <i class=\"fa-solid fa-check\"></i> Approve\n </button>\n <button class=\"action-btn reject-btn\"\n [disabled]=\"IsSaving\"\n (click)=\"RejectMatch(group); $event.stopPropagation()\">\n <i class=\"fa-solid fa-times\"></i> Reject\n </button>\n </div>\n </div>\n }\n @if (PendingGroups.length === 0) {\n <div class=\"column-empty\">\n <i class=\"fa-solid fa-check-circle\"></i>\n <span>No pending items</span>\n </div>\n }\n </div>\n </div>\n\n <!-- Approved Column -->\n <div class=\"kanban-column\" [class.drop-target-active]=\"DragOverColumn === 'Approved' && DraggedGroup?.ApprovalStatus !== 'Approved'\">\n <div class=\"column-header column-header-approved\">\n <i class=\"fa-solid fa-check-circle\"></i>\n <span class=\"column-title\">Approved</span>\n <span class=\"column-count\">{{ ApprovedCount }}</span>\n </div>\n <div class=\"column-body\"\n (dragover)=\"OnDragOver($event, 'Approved')\"\n (dragleave)=\"OnDragLeave($event, 'Approved')\"\n (drop)=\"OnDrop($event, 'Approved')\">\n @for (group of ApprovedGroups; track group.DetailId) {\n <div class=\"kanban-card\"\n draggable=\"true\"\n (dragstart)=\"OnDragStart($event, group)\"\n (dragend)=\"OnDragEnd()\"\n (click)=\"OpenComparison(group)\">\n <div class=\"card-header\">\n <div class=\"card-header-left\">\n <div class=\"card-icon\">\n <i [class]=\"group.EntityIcon\"></i>\n </div>\n <div class=\"card-title-block\">\n <div class=\"card-record-name\" [title]=\"group.RecordName\">{{ group.RecordName }}</div>\n <span class=\"entity-badge\">{{ group.EntityName }}</span>\n </div>\n </div>\n <span class=\"score-indicator\" [class]=\"GetScoreClass(group.HighestScore)\">\n {{ (group.HighestScore * 100).toFixed(0) }}%\n </span>\n </div>\n <div class=\"card-body\">\n @if (group.TopMatchSummaries.length > 0) {\n <div class=\"match-summaries\">\n @for (ms of group.TopMatchSummaries; track ms.Name) {\n <div class=\"match-summary-row\">\n <span class=\"match-score\">{{ (ms.Score * 100).toFixed(0) }}%</span>\n <span class=\"match-name\">{{ ms.Name }}</span>\n </div>\n }\n @if (group.MatchCount > group.TopMatchSummaries.length) {\n <div class=\"match-summary-more\">+{{ group.MatchCount - group.TopMatchSummaries.length }} more</div>\n }\n </div>\n }\n <div class=\"card-meta-row\">\n <span class=\"card-meta-item\">\n <i class=\"fa-solid fa-layer-group\"></i>\n {{ group.MatchCount }} match{{ group.MatchCount !== 1 ? 'es' : '' }}\n </span>\n <span class=\"card-meta-item\">\n <i class=\"fa-solid fa-calendar\"></i>\n {{ FormatDate(group.MatchedAt) }}\n </span>\n </div>\n </div>\n </div>\n }\n @if (ApprovedGroups.length === 0) {\n <div class=\"column-empty\">\n <i class=\"fa-solid fa-inbox\"></i>\n <span>No approved items</span>\n </div>\n }\n </div>\n </div>\n\n <!-- Rejected Column -->\n <div class=\"kanban-column\" [class.drop-target-active]=\"DragOverColumn === 'Rejected' && DraggedGroup?.ApprovalStatus !== 'Rejected'\">\n <div class=\"column-header column-header-rejected\">\n <i class=\"fa-solid fa-ban\"></i>\n <span class=\"column-title\">Rejected</span>\n <span class=\"column-count\">{{ RejectedCount }}</span>\n </div>\n <div class=\"column-body\"\n (dragover)=\"OnDragOver($event, 'Rejected')\"\n (dragleave)=\"OnDragLeave($event, 'Rejected')\"\n (drop)=\"OnDrop($event, 'Rejected')\">\n @for (group of RejectedGroups; track group.DetailId) {\n <div class=\"kanban-card\"\n draggable=\"true\"\n (dragstart)=\"OnDragStart($event, group)\"\n (dragend)=\"OnDragEnd()\"\n (click)=\"OpenComparison(group)\">\n <div class=\"card-header\">\n <div class=\"card-header-left\">\n <div class=\"card-icon\">\n <i [class]=\"group.EntityIcon\"></i>\n </div>\n <div class=\"card-title-block\">\n <div class=\"card-record-name\" [title]=\"group.RecordName\">{{ group.RecordName }}</div>\n <span class=\"entity-badge\">{{ group.EntityName }}</span>\n </div>\n </div>\n <span class=\"score-indicator\" [class]=\"GetScoreClass(group.HighestScore)\">\n {{ (group.HighestScore * 100).toFixed(0) }}%\n </span>\n </div>\n <div class=\"card-body\">\n @if (group.TopMatchSummaries.length > 0) {\n <div class=\"match-summaries\">\n @for (ms of group.TopMatchSummaries; track ms.Name) {\n <div class=\"match-summary-row\">\n <span class=\"match-score\">{{ (ms.Score * 100).toFixed(0) }}%</span>\n <span class=\"match-name\">{{ ms.Name }}</span>\n </div>\n }\n @if (group.MatchCount > group.TopMatchSummaries.length) {\n <div class=\"match-summary-more\">+{{ group.MatchCount - group.TopMatchSummaries.length }} more</div>\n }\n </div>\n }\n <div class=\"card-meta-row\">\n <span class=\"card-meta-item\">\n <i class=\"fa-solid fa-layer-group\"></i>\n {{ group.MatchCount }} match{{ group.MatchCount !== 1 ? 'es' : '' }}\n </span>\n <span class=\"card-meta-item\">\n <i class=\"fa-solid fa-calendar\"></i>\n {{ FormatDate(group.MatchedAt) }}\n </span>\n </div>\n </div>\n </div>\n }\n @if (RejectedGroups.length === 0) {\n <div class=\"column-empty\">\n <i class=\"fa-solid fa-inbox\"></i>\n <span>No rejected items</span>\n </div>\n }\n </div>\n </div>\n </div>\n }\n\n <!-- Saving overlay -->\n @if (IsSaving) {\n <div class=\"saving-overlay\">\n <mj-loading text=\"Saving...\" size=\"small\"></mj-loading>\n </div>\n }\n\n <!-- \u2550\u2550\u2550 Comparison Slide-In Panel \u2550\u2550\u2550 -->\n @if (ComparisonGroup) {\n <div class=\"slide-backdrop\" [class.comparison-closing]=\"ComparisonClosing\" (click)=\"CloseComparison()\"></div>\n <div class=\"comparison-panel\" [class.comparison-closing]=\"ComparisonClosing\" (click)=\"$event.stopPropagation()\">\n <!-- Header -->\n <div class=\"comparison-header\">\n <div class=\"comparison-header-left\">\n <div class=\"comparison-entity-icon\">\n <i [class]=\"ComparisonGroup.EntityIcon\"></i>\n </div>\n <div>\n <div class=\"comparison-title\">{{ ComparisonGroup.RecordName }}</div>\n <span class=\"comparison-entity-badge\">{{ ComparisonGroup.EntityName }}</span>\n <span class=\"comparison-match-count\">\n {{ ComparisonGroup.MatchCount }} potential duplicate{{ ComparisonGroup.MatchCount !== 1 ? 's' : '' }}\n </span>\n </div>\n </div>\n <div class=\"comparison-header-right\">\n <div class=\"comparison-toggle\">\n <button class=\"toggle-btn\" [class.toggle-active]=\"ComparisonShowAllFields\"\n (click)=\"ComparisonShowAllFields = true\">All Fields</button>\n <button class=\"toggle-btn\" [class.toggle-active]=\"!ComparisonShowAllFields\"\n (click)=\"ComparisonShowAllFields = false\">Differences Only</button>\n </div>\n <button class=\"comparison-close-btn\" (click)=\"CloseComparison()\" title=\"Close (Esc)\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n </div>\n\n <!-- Grid -->\n @if (ComparisonLoading) {\n <div class=\"comparison-loading\">\n <mj-loading text=\"Loading records for comparison...\" size=\"medium\"></mj-loading>\n </div>\n }\n <div class=\"comparison-grid-wrapper\" [hidden]=\"ComparisonLoading\">\n <div class=\"comparison-grid\"\n [style.grid-template-columns]=\"'160px repeat(' + (1 + ComparisonMatches.length) + ', minmax(180px, 1fr))'\">\n\n <!-- Corner cell -->\n <div class=\"grid-corner-cell\">Field</div>\n\n <!-- Source column header -->\n <div class=\"grid-col-header grid-col-source\">\n <span class=\"col-header-label\">Source</span>\n <span class=\"col-header-name\">{{ ComparisonGroup.RecordName }}</span>\n <div class=\"surviving-selector\">\n <input type=\"radio\" name=\"survivor\" class=\"surviving-radio\"\n [checked]=\"SurvivorColumnIndex === 0\"\n (change)=\"SetSurvivor(0)\">\n <span class=\"surviving-label\" [class.is-survivor]=\"SurvivorColumnIndex === 0\">\n {{ SurvivorColumnIndex === 0 ? 'Surviving Record' : 'Set as survivor' }}\n </span>\n </div>\n <button class=\"use-all-btn\" [class.all-selected]=\"AllFieldsSelectedFrom(0)\"\n (click)=\"UseAllFieldsFrom(0)\">\n <i class=\"fa-solid\" [class.fa-check-double]=\"AllFieldsSelectedFrom(0)\" [class.fa-clone]=\"!AllFieldsSelectedFrom(0)\"></i>\n {{ AllFieldsSelectedFrom(0) ? 'Using all fields' : 'Use all fields' }}\n </button>\n <!-- Dependencies Summary -->\n <div class=\"deps-summary\">\n <div class=\"deps-total\">\n <i class=\"fa-solid fa-link\"></i>\n <span class=\"deps-total-number\">{{ GetTotalDeps(0) }}</span>\n {{ GetTotalDeps(0) === 1 ? 'dependency' : 'dependencies' }}\n @if (GetMaxDepsColumnIndex() === 0 && GetTotalDeps(0) > 0) {\n <span class=\"deps-total-recommended\"><i class=\"fa-solid fa-star\"></i> Most deps</span>\n }\n </div>\n @if (GetGroupedDeps(0).length > 0) {\n <div class=\"deps-header\" (click)=\"ToggleDepsExpanded(0)\">\n <span>{{ IsDepsExpanded(0) ? 'Hide details' : 'Show details' }}</span>\n <i class=\"fa-solid\" [class.fa-chevron-down]=\"!IsDepsExpanded(0)\" [class.fa-chevron-up]=\"IsDepsExpanded(0)\"></i>\n </div>\n @if (IsDepsExpanded(0)) {\n <div class=\"deps-detail-list\">\n @for (dep of GetGroupedDeps(0); track dep.Entity) {\n <div class=\"deps-detail-group\">\n <div class=\"deps-detail-row\" (click)=\"ToggleDepEntityGroup(0, dep.Entity); $event.stopPropagation()\">\n <span class=\"deps-detail-entity\">\n <i class=\"fa-solid deps-expand-icon\"\n [class.fa-chevron-right]=\"!IsDepEntityGroupExpanded(0, dep.Entity)\"\n [class.fa-chevron-down]=\"IsDepEntityGroupExpanded(0, dep.Entity)\"></i>\n {{ dep.Entity }}\n </span>\n <span class=\"deps-detail-count\">{{ dep.Count }}</span>\n </div>\n @if (IsDepEntityGroupExpanded(0, dep.Entity)) {\n <div class=\"deps-records-list\">\n @if (IsDepRecordsLoading(0, dep.Entity)) {\n <div class=\"deps-record-loading\"><i class=\"fa-solid fa-spinner fa-spin\"></i> Loading...</div>\n }\n @for (record of GetDepRecords(0, dep.Entity); track $index) {\n <div class=\"deps-record-row\" (click)=\"OpenDepRecord(record); $event.stopPropagation()\">\n <i class=\"fa-solid fa-arrow-up-right-from-square deps-record-icon\"></i>\n <span class=\"deps-record-name\">{{ record.Name }}</span>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n }\n </div>\n </div>\n\n <!-- Match column headers -->\n @for (match of ComparisonMatches; track match.Match.ID; let mi = $index) {\n <div class=\"grid-col-header\"\n [class.match-approved]=\"match.Match.ApprovalStatus === 'Approved'\"\n [class.match-rejected]=\"match.Match.ApprovalStatus === 'Rejected'\">\n <div class=\"col-header-top\">\n <span class=\"col-header-name\">{{ match.Name }}</span>\n <span class=\"score-indicator\" [class]=\"GetScoreClass(match.Score)\">\n {{ (match.Score * 100).toFixed(0) }}%\n </span>\n </div>\n <span class=\"col-header-diff-count\">{{ match.DiffCount }} difference{{ match.DiffCount !== 1 ? 's' : '' }}</span>\n <div class=\"surviving-selector\">\n <input type=\"radio\" name=\"survivor\" class=\"surviving-radio\"\n [checked]=\"SurvivorColumnIndex === mi + 1\"\n (change)=\"SetSurvivor(mi + 1)\">\n <span class=\"surviving-label\" [class.is-survivor]=\"SurvivorColumnIndex === mi + 1\">\n {{ SurvivorColumnIndex === mi + 1 ? 'Surviving Record' : 'Set as survivor' }}\n </span>\n </div>\n <button class=\"use-all-btn\" [class.all-selected]=\"AllFieldsSelectedFrom(mi + 1)\"\n (click)=\"UseAllFieldsFrom(mi + 1)\">\n <i class=\"fa-solid\" [class.fa-check-double]=\"AllFieldsSelectedFrom(mi + 1)\" [class.fa-clone]=\"!AllFieldsSelectedFrom(mi + 1)\"></i>\n {{ AllFieldsSelectedFrom(mi + 1) ? 'Using all fields' : 'Use all fields' }}\n </button>\n <!-- Dependencies Summary -->\n <div class=\"deps-summary\">\n <div class=\"deps-total\">\n <i class=\"fa-solid fa-link\"></i>\n <span class=\"deps-total-number\">{{ GetTotalDeps(mi + 1) }}</span>\n {{ GetTotalDeps(mi + 1) === 1 ? 'dependency' : 'dependencies' }}\n @if (GetMaxDepsColumnIndex() === mi + 1 && GetTotalDeps(mi + 1) > 0) {\n <span class=\"deps-total-recommended\"><i class=\"fa-solid fa-star\"></i> Most deps</span>\n }\n </div>\n @if (GetGroupedDeps(mi + 1).length > 0) {\n <div class=\"deps-header\" (click)=\"ToggleDepsExpanded(mi + 1)\">\n <span>{{ IsDepsExpanded(mi + 1) ? 'Hide details' : 'Show details' }}</span>\n <i class=\"fa-solid\" [class.fa-chevron-down]=\"!IsDepsExpanded(mi + 1)\" [class.fa-chevron-up]=\"IsDepsExpanded(mi + 1)\"></i>\n </div>\n @if (IsDepsExpanded(mi + 1)) {\n <div class=\"deps-detail-list\">\n @for (dep of GetGroupedDeps(mi + 1); track dep.Entity) {\n <div class=\"deps-detail-group\">\n <div class=\"deps-detail-row\" (click)=\"ToggleDepEntityGroup(mi + 1, dep.Entity); $event.stopPropagation()\">\n <span class=\"deps-detail-entity\">\n <i class=\"fa-solid deps-expand-icon\"\n [class.fa-chevron-right]=\"!IsDepEntityGroupExpanded(mi + 1, dep.Entity)\"\n [class.fa-chevron-down]=\"IsDepEntityGroupExpanded(mi + 1, dep.Entity)\"></i>\n {{ dep.Entity }}\n </span>\n <span class=\"deps-detail-count\">{{ dep.Count }}</span>\n </div>\n @if (IsDepEntityGroupExpanded(mi + 1, dep.Entity)) {\n <div class=\"deps-records-list\">\n @if (IsDepRecordsLoading(mi + 1, dep.Entity)) {\n <div class=\"deps-record-loading\"><i class=\"fa-solid fa-spinner fa-spin\"></i> Loading...</div>\n }\n @for (record of GetDepRecords(mi + 1, dep.Entity); track $index) {\n <div class=\"deps-record-row\" (click)=\"OpenDepRecord(record); $event.stopPropagation()\">\n <i class=\"fa-solid fa-arrow-up-right-from-square deps-record-icon\"></i>\n <span class=\"deps-record-name\">{{ record.Name }}</span>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n }\n </div>\n @if (match.Match.ApprovalStatus !== 'Pending') {\n <span class=\"match-status-badge\"\n [class.status-approved]=\"match.Match.ApprovalStatus === 'Approved'\"\n [class.status-rejected]=\"match.Match.ApprovalStatus === 'Rejected'\">\n <i class=\"fa-solid\" [class.fa-check]=\"match.Match.ApprovalStatus === 'Approved'\"\n [class.fa-times]=\"match.Match.ApprovalStatus === 'Rejected'\"></i>\n {{ match.Match.ApprovalStatus }}\n </span>\n }\n </div>\n }\n\n <!-- Field rows -->\n @for (field of GetVisibleFields(); track field.FieldName; let odd = $odd) {\n <!-- Label cell -->\n <div class=\"grid-label-cell\" [class.grid-row-odd]=\"odd\">\n {{ field.DisplayName }}\n </div>\n <!-- Source value cell -->\n <div class=\"grid-value-cell grid-source-cell\"\n [class.grid-row-odd]=\"odd\"\n [class.has-diff-in-row]=\"field.HasDifference\"\n [class.field-selected]=\"field.SelectedColumnIndex === 0\"\n (click)=\"SelectFieldValue(field, 0)\">\n @if (field.SourceValue != null) {\n {{ field.SourceValue }}\n } @else {\n <span class=\"field-not-available\">(not available)</span>\n }\n @if (field.HasDifference || field.SelectedColumnIndex === 0) {\n <input type=\"radio\" [name]=\"'field-' + field.FieldName\" class=\"field-select-radio\"\n [checked]=\"field.SelectedColumnIndex === 0\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"SelectFieldValue(field, 0)\">\n }\n </div>\n <!-- Match value cells -->\n @for (matchVal of field.MatchValues; track $index; let mi = $index) {\n <div class=\"grid-value-cell\"\n [class.grid-row-odd]=\"odd\"\n [class.value-same]=\"AreValuesEqual(field.SourceValue, matchVal)\"\n [class.value-different]=\"matchVal != null && field.SourceValue != null && !AreValuesEqual(field.SourceValue, matchVal)\"\n [class.field-selected]=\"field.SelectedColumnIndex === mi + 1\"\n (click)=\"matchVal != null ? SelectFieldValue(field, mi + 1) : null\">\n @if (matchVal != null) {\n {{ matchVal }}\n @if (field.HasDifference || field.SelectedColumnIndex === mi + 1) {\n <input type=\"radio\" [name]=\"'field-' + field.FieldName\" class=\"field-select-radio\"\n [checked]=\"field.SelectedColumnIndex === mi + 1\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"SelectFieldValue(field, mi + 1)\">\n }\n } @else {\n <span class=\"field-not-available\">(not available)</span>\n }\n </div>\n }\n }\n </div>\n </div>\n\n <!-- Footer -->\n <div class=\"comparison-footer\">\n <div class=\"comparison-footer-left\">\n <span class=\"comparison-summary\">\n Showing {{ GetVisibleFields().length }} of {{ ComparisonFields.length }} fields\n </span>\n <span class=\"merge-summary\">\n <i class=\"fa-solid fa-code-merge\"></i>\n Surviving: <strong>{{ SurvivorName() }}</strong>\n @if (CherryPickedCount() > 0) {\n &middot; {{ CherryPickedCount() }} field{{ CherryPickedCount() !== 1 ? 's' : '' }} cherry-picked\n }\n </span>\n </div>\n <div class=\"comparison-footer-right\">\n <button class=\"action-btn reject-btn\" [disabled]=\"IsSaving\"\n (click)=\"RejectMatch(ComparisonGroup!); CloseComparison()\">\n <i class=\"fa-solid fa-times\"></i> Reject All\n </button>\n <button class=\"action-btn merge-btn\" [disabled]=\"IsSaving\"\n (click)=\"OpenMergeConfirm()\">\n <i class=\"fa-solid fa-code-merge\"></i> Merge Records\n </button>\n </div>\n </div>\n </div>\n }\n\n <!-- \u2550\u2550\u2550 Merge Confirmation Panel \u2550\u2550\u2550 -->\n @if (ShowMergeConfirm && ComparisonGroup) {\n <div class=\"merge-confirm-backdrop\" (click)=\"CloseMergeConfirm()\">\n <div class=\"merge-confirm-panel\" (click)=\"$event.stopPropagation()\">\n <div class=\"merge-confirm-header\">\n <div class=\"merge-confirm-icon\"><i class=\"fa-solid fa-code-merge\"></i></div>\n <div>\n <div class=\"merge-confirm-title\">Confirm Record Merge</div>\n <div class=\"merge-confirm-subtitle\">This action cannot be undone. Please review carefully.</div>\n </div>\n </div>\n\n <div class=\"merge-confirm-body\">\n <!-- Surviving Record -->\n <div class=\"merge-survivor-card\">\n <div class=\"merge-survivor-label\"><i class=\"fa-solid fa-shield-halved\"></i> Surviving Record</div>\n <div class=\"merge-survivor-name\">{{ SurvivorName() }}</div>\n <div class=\"merge-survivor-pk\">\n <i class=\"fa-solid fa-key\"></i>\n {{ SurvivorKeyDisplay() }}\n </div>\n <div class=\"merge-survivor-detail\">This record's ID will be retained. All dependencies from merged records will be transferred here.</div>\n </div>\n\n <!-- Cherry-picked field overrides -->\n @if (GetCherryPickedFields().length > 0) {\n <div>\n <div class=\"merge-section-label\">Field Value Overrides ({{ GetCherryPickedFields().length }} field{{ GetCherryPickedFields().length !== 1 ? 's' : '' }})</div>\n @for (field of GetCherryPickedFields(); track field.FieldName) {\n <div class=\"merge-field-override\">\n <span class=\"merge-field-name\">{{ field.DisplayName }}</span>\n <span class=\"merge-field-value\">\"{{ field.Value }}\"</span>\n <span class=\"merge-field-source\">from {{ field.SourceName }}</span>\n </div>\n }\n </div>\n }\n\n <!-- Dependency transfer -->\n @if (GetNonSurvivorColumns().length > 0) {\n <div class=\"merge-deps-transfer\">\n <div class=\"merge-deps-transfer-label\"><i class=\"fa-solid fa-arrow-right-arrow-left\"></i> Dependencies to Transfer</div>\n @for (col of GetNonSurvivorColumns(); track col.ColumnIndex) {\n <div class=\"merge-deps-transfer-row\">\n <i class=\"fa-solid fa-arrow-right\"></i>\n <span>\n @if (col.DepCount > 0) {\n <strong>{{ col.DepCount }}</strong> {{ col.DepCount === 1 ? 'dependency' : 'dependencies' }} from <strong>{{ col.Name }}</strong> &rarr; {{ SurvivorName() }}\n } @else {\n <strong>0</strong> dependencies from <strong>{{ col.Name }}</strong>\n }\n </span>\n </div>\n }\n </div>\n }\n\n <!-- Records to be deleted -->\n <div class=\"merge-delete-card\">\n <div class=\"merge-delete-label\"><i class=\"fa-solid fa-trash\"></i> Records to Delete After Merge</div>\n @for (col of GetNonSurvivorColumns(); track col.ColumnIndex) {\n <div class=\"merge-delete-item\">\n <span class=\"merge-delete-name\">{{ col.Name }}</span>\n <span class=\"merge-delete-deps\">\n @if (col.DepCount > 0) {\n {{ col.DepCount }} dep{{ col.DepCount !== 1 ? 's' : '' }} transferring\n } @else {\n no deps\n }\n </span>\n </div>\n }\n </div>\n </div>\n\n <div class=\"merge-confirm-footer\">\n <button class=\"action-btn cancel-btn\" (click)=\"CloseMergeConfirm()\" [disabled]=\"IsMerging\">\n <i class=\"fa-solid fa-arrow-left\"></i> Back\n </button>\n <button class=\"action-btn confirm-merge-btn\" (click)=\"ExecuteMerge()\" [disabled]=\"IsMerging\">\n @if (IsMerging) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Merging...\n } @else {\n <i class=\"fa-solid fa-code-merge\"></i> Confirm Merge ({{ GetNonSurvivorColumns().length + 1 }} records &rarr; 1)\n }\n </button>\n </div>\n </div>\n </div>\n }\n</div>\n", styles: ["/* ============================================================\n Duplicate Detection Kanban Board - Resource Component Styles\n All colors use MJ design tokens (--mj-*) exclusively.\n ============================================================ */\n\napp-duplicate-detection-resource {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n}\n\n.duplicate-detection-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n padding: 16px 20px;\n background: var(--mj-bg-page);\n position: relative;\n overflow: hidden;\n}\n\n/* ---- Page Header ---- */\n\n.page-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 16px;\n flex-shrink: 0;\n}\n\n.page-title {\n margin: 0;\n font-size: 20px;\n font-weight: 600;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.page-title i {\n color: var(--mj-brand-primary);\n}\n\n/* ---- Header Actions ---- */\n\n.header-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.run-detection-controls {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.entity-doc-select {\n padding: 8px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n min-width: 200px;\n}\n\n.entity-doc-select:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.run-detection-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border: none;\n border-radius: 6px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n cursor: pointer;\n font-size: 13px;\n font-weight: 600;\n transition: background 0.15s;\n white-space: nowrap;\n}\n\n.run-detection-btn:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n.run-detection-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n/* ---- Detection Progress ---- */\n\n.detection-progress-section {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-brand-primary);\n border-radius: 8px;\n padding: 14px 18px;\n margin-bottom: 16px;\n flex-shrink: 0;\n}\n\n.progress-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 8px;\n}\n\n.progress-stage {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-brand-primary);\n}\n\n.progress-percent {\n font-size: 13px;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.progress-bar-track {\n height: 6px;\n border-radius: 3px;\n background: var(--mj-bg-surface-sunken);\n overflow: hidden;\n}\n\n.progress-bar-fill {\n height: 100%;\n border-radius: 3px;\n background: var(--mj-brand-primary);\n transition: width 0.3s ease;\n}\n\n.progress-current-item {\n display: block;\n margin-top: 6px;\n font-size: 11px;\n color: var(--mj-text-muted);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* ---- Threshold Controls ---- */\n\n.threshold-controls {\n display: flex;\n gap: 24px;\n padding: 12px 16px;\n border-radius: 8px;\n background: color-mix(in srgb, var(--mj-status-info) 6%, var(--mj-bg-surface));\n border: 1px solid var(--mj-border-subtle);\n margin-bottom: 16px;\n flex-shrink: 0;\n}\n\n.threshold-slider-group {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.threshold-label {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 0.82rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.threshold-value {\n margin-left: auto;\n font-weight: 700;\n color: var(--mj-brand-primary);\n font-size: 0.85rem;\n}\n\n.threshold-slider {\n width: 100%;\n height: 4px;\n appearance: none;\n -webkit-appearance: none;\n background: var(--mj-border-default);\n border-radius: 2px;\n outline: none;\n cursor: pointer;\n}\n\n.threshold-slider::-webkit-slider-thumb {\n -webkit-appearance: none;\n width: 14px;\n height: 14px;\n border-radius: 50%;\n background: var(--mj-brand-primary);\n border: 2px solid var(--mj-bg-surface);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n cursor: pointer;\n}\n\n.threshold-slider::-moz-range-thumb {\n width: 14px;\n height: 14px;\n border-radius: 50%;\n background: var(--mj-brand-primary);\n border: 2px solid var(--mj-bg-surface);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n cursor: pointer;\n}\n\n.threshold-slider:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n\n.threshold-hint {\n font-size: 0.72rem;\n color: var(--mj-text-muted);\n}\n\n/* ---- Threshold Info (legacy) ---- */\n\n.threshold-info {\n display: flex;\n gap: 16px;\n padding: 8px 14px;\n border-radius: 6px;\n background: color-mix(in srgb, var(--mj-status-info) 8%, var(--mj-bg-surface));\n border: 1px solid var(--mj-status-info-border);\n margin-bottom: 16px;\n flex-shrink: 0;\n}\n\n.threshold-item {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: var(--mj-status-info-text);\n font-weight: 500;\n}\n\n.threshold-item i {\n font-size: 11px;\n}\n\n/* ---- KPI Strip ---- */\n\n.kpi-strip {\n display: flex;\n gap: 12px;\n margin-bottom: 16px;\n flex-shrink: 0;\n}\n\n.kpi-card {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 12px 16px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n}\n\n.kpi-value {\n font-size: 28px;\n font-weight: 700;\n color: var(--mj-text-primary);\n line-height: 1.2;\n}\n\n.kpi-label {\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-top: 2px;\n}\n\n.kpi-pending .kpi-value {\n color: var(--mj-status-warning);\n}\n\n.kpi-approved .kpi-value {\n color: var(--mj-status-success);\n}\n\n.kpi-rejected .kpi-value {\n color: var(--mj-status-error);\n}\n\n/* ---- Filter Bar ---- */\n\n.filter-bar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n margin-bottom: 16px;\n flex-shrink: 0;\n}\n\n.filter-group {\n display: flex;\n align-items: flex-end;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n.filter-select {\n height: 34px;\n padding: 4px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n outline: none;\n min-width: 160px;\n}\n\n.filter-select:focus {\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.filter-range {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.filter-label {\n font-size: 11px;\n font-weight: 500;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n.filter-input {\n height: 34px;\n padding: 4px 8px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n outline: none;\n width: 100px;\n}\n\n.filter-input-score {\n width: 80px;\n}\n\n.filter-input-date {\n width: 140px;\n}\n\n.filter-input:focus {\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.clear-filters-btn {\n display: flex;\n align-items: center;\n gap: 4px;\n height: 34px;\n padding: 0 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 13px;\n cursor: pointer;\n white-space: nowrap;\n}\n\n.clear-filters-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n/* ---- Loading & Empty States ---- */\n\n.loading-container {\n display: flex;\n align-items: center;\n justify-content: center;\n flex: 1;\n min-height: 200px;\n}\n\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n flex: 1;\n min-height: 200px;\n gap: 8px;\n}\n\n.empty-icon {\n font-size: 48px;\n color: var(--mj-text-disabled);\n}\n\n.empty-text {\n font-size: 16px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n.empty-subtext {\n font-size: 13px;\n color: var(--mj-text-muted);\n margin: 0;\n}\n\n/* ---- Kanban Board ---- */\n\n.kanban-board {\n display: flex;\n gap: 16px;\n flex: 1;\n min-height: 0;\n overflow-x: auto;\n}\n\n.kanban-column {\n flex: 1;\n min-width: 280px;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 10px;\n overflow: hidden;\n}\n\n.column-header {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 16px;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n border-bottom: 1px solid var(--mj-border-subtle);\n flex-shrink: 0;\n}\n\n.column-header-pending {\n background: color-mix(in srgb, var(--mj-status-warning) 8%, var(--mj-bg-surface));\n}\n\n.column-header-pending i {\n color: var(--mj-status-warning);\n}\n\n.column-header-approved {\n background: color-mix(in srgb, var(--mj-status-success) 8%, var(--mj-bg-surface));\n}\n\n.column-header-approved i {\n color: var(--mj-status-success);\n}\n\n.column-header-rejected {\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--mj-bg-surface));\n}\n\n.column-header-rejected i {\n color: var(--mj-status-error);\n}\n\n.column-title {\n flex: 1;\n}\n\n.column-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 24px;\n height: 24px;\n padding: 0 6px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 600;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.column-body {\n flex: 1;\n overflow-y: auto;\n padding: 12px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.column-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 6px;\n padding: 32px 16px;\n color: var(--mj-text-disabled);\n font-size: 13px;\n}\n\n.column-empty i {\n font-size: 24px;\n}\n\n/* ---- Kanban Cards ---- */\n\n.kanban-card {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n transition: box-shadow 0.15s ease, border-color 0.15s ease;\n flex-shrink: 0; /* Prevent cards from shrinking \u2014 column scrolls instead */\n}\n\n.kanban-card:hover {\n border-color: var(--mj-border-strong);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-text-primary) 8%, transparent);\n}\n\n/* Drag and Drop */\n.kanban-card[draggable=\"true\"] {\n cursor: grab;\n}\n\n.kanban-card[draggable=\"true\"]:active {\n cursor: grabbing;\n}\n\n.drop-target-active {\n outline: 2px dashed var(--mj-brand-primary);\n outline-offset: -2px;\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface-card)) !important;\n}\n\n.drop-target-active .column-body {\n min-height: 100px;\n}\n\n.card-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n padding: 10px 12px;\n border-bottom: 1px solid var(--mj-border-subtle);\n gap: 8px;\n}\n\n.card-header-left {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n min-width: 0;\n flex: 1;\n}\n\n.card-icon {\n width: 2rem;\n height: 2rem;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 6px;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 0.85rem;\n flex-shrink: 0;\n}\n\n.card-title-block {\n min-width: 0;\n flex: 1;\n}\n\n.card-record-name {\n font-size: 0.85rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n margin-bottom: 2px;\n}\n\n.entity-badge {\n display: inline-flex;\n align-items: center;\n padding: 1px 6px;\n border-radius: 3px;\n font-size: 10px;\n font-weight: 500;\n color: var(--mj-text-muted);\n letter-spacing: 0.2px;\n}\n\n/* Score indicator colors */\n\n.score-indicator {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 40px;\n padding: 2px 8px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 700;\n}\n\n.score-high {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success-text);\n border: 1px solid var(--mj-status-success-border);\n}\n\n.score-medium {\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning-text);\n border: 1px solid var(--mj-status-warning-border);\n}\n\n.score-low {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error-text);\n border: 1px solid var(--mj-status-error-border);\n}\n\n.card-body {\n padding: 10px 12px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.match-summaries {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.match-summary-row {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n}\n\n.match-score {\n flex-shrink: 0;\n font-weight: 600;\n font-size: 11px;\n color: var(--mj-text-muted);\n min-width: 30px;\n}\n\n.match-name {\n color: var(--mj-text-secondary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.match-summary-more {\n font-size: 11px;\n color: var(--mj-text-muted);\n font-style: italic;\n padding-left: 38px;\n}\n\n.card-meta-row {\n display: flex;\n align-items: center;\n gap: 12px;\n font-size: 11px;\n color: var(--mj-text-muted);\n border-top: 1px solid var(--mj-border-subtle);\n padding-top: 6px;\n}\n\n.card-meta-item {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.card-meta-item i {\n font-size: 10px;\n}\n font-size: 12px;\n max-width: 180px;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n Comparison Slide-In Panel\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.slide-backdrop {\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n z-index: 9999;\n animation: fadeIn 0.2s ease;\n}\n\n.slide-backdrop.comparison-closing {\n animation: fadeOut 0.25s ease forwards;\n}\n\n@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }\n@keyframes fadeOut { from { opacity: 1; } to { opacity: 0; } }\n\n.comparison-panel {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n width: 82vw;\n max-width: 1300px;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n box-shadow: -8px 0 40px rgba(0,0,0,0.4);\n z-index: 10000;\n display: flex;\n flex-direction: column;\n animation: slideIn 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n}\n\n.comparison-panel.comparison-closing {\n animation: slideOut 0.25s cubic-bezier(0.4, 0, 0.2, 1) forwards;\n}\n\n@keyframes slideIn { from { transform: translateX(100%); } to { transform: translateX(0); } }\n@keyframes slideOut { from { transform: translateX(0); } to { transform: translateX(100%); } }\n\n/* Header */\n.comparison-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 14px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n gap: 12px;\n}\n\n.comparison-header-left {\n display: flex;\n align-items: center;\n gap: 12px;\n min-width: 0;\n}\n\n.comparison-entity-icon {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 1rem;\n flex-shrink: 0;\n}\n\n.comparison-title {\n font-size: 1rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.comparison-entity-badge {\n display: inline-block;\n padding: 1px 7px;\n border-radius: 10px;\n font-size: 0.65rem;\n font-weight: 500;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n margin-right: 6px;\n}\n\n.comparison-match-count {\n font-size: 0.72rem;\n color: var(--mj-text-muted);\n}\n\n.comparison-header-right {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-shrink: 0;\n}\n\n/* Toggle */\n.comparison-toggle {\n display: flex;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n overflow: hidden;\n}\n\n.toggle-btn {\n padding: 5px 12px;\n font-size: 0.7rem;\n font-weight: 500;\n border: none;\n cursor: pointer;\n transition: all 0.15s ease;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n}\n\n.toggle-btn:first-child {\n border-right: 1px solid var(--mj-border-default);\n}\n\n.toggle-btn.toggle-active {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.comparison-close-btn {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n font-size: 0.85rem;\n transition: all 0.15s ease;\n}\n\n.comparison-close-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n/* Loading state */\n.comparison-loading {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n/* Grid wrapper */\n.comparison-grid-wrapper {\n flex: 1;\n overflow: auto;\n min-height: 0;\n}\n\n/* Grid */\n.comparison-grid {\n display: grid;\n min-width: 100%;\n}\n\n.comparison-grid > div {\n padding: 8px 12px;\n font-size: 0.78rem;\n border-bottom: 1px solid var(--mj-border-subtle);\n border-right: 1px solid var(--mj-border-subtle);\n}\n\n/* Corner cell */\n.grid-corner-cell {\n position: sticky;\n top: 0;\n left: 0;\n z-index: 4;\n background: var(--mj-bg-surface-elevated);\n font-size: 0.65rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--mj-text-muted);\n display: flex;\n align-items: flex-end;\n padding-bottom: 6px;\n}\n\n/* Column headers */\n.grid-col-header {\n position: sticky;\n top: 0;\n z-index: 3;\n background: var(--mj-bg-surface-elevated);\n padding: 10px 12px;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.grid-col-source {\n border-left: 3px solid var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, var(--mj-bg-surface-elevated));\n}\n\n.col-header-label {\n font-size: 0.6rem;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--mj-brand-primary);\n}\n\n.col-header-top {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 6px;\n}\n\n.col-header-name {\n font-size: 0.82rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.col-header-diff-count {\n font-size: 0.65rem;\n color: var(--mj-status-warning-text);\n}\n\n/* Surviving record selector */\n.surviving-selector {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-top: 4px;\n}\n\n.surviving-radio {\n appearance: none;\n width: 14px;\n height: 14px;\n border: 2px solid var(--mj-border-strong);\n border-radius: 50%;\n cursor: pointer;\n transition: all 0.15s ease;\n flex-shrink: 0;\n}\n\n.surviving-radio:checked {\n border-color: var(--mj-brand-primary);\n background: var(--mj-brand-primary);\n box-shadow: inset 0 0 0 2px var(--mj-bg-surface-elevated);\n}\n\n.surviving-label {\n font-size: 0.65rem;\n color: var(--mj-text-muted);\n cursor: pointer;\n}\n\n.surviving-label.is-survivor {\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n/* Use all fields button */\n.use-all-btn {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 3px 8px;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 0.62rem;\n cursor: pointer;\n transition: all 0.12s ease;\n margin-top: 2px;\n}\n\n.use-all-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.use-all-btn.all-selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n}\n\n/* Per-match actions */\n.comparison-match-actions {\n display: flex;\n gap: 4px;\n margin-top: 3px;\n}\n\n.action-btn-sm {\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: 1px solid;\n border-radius: 5px;\n cursor: pointer;\n font-size: 0.65rem;\n transition: all 0.15s ease;\n}\n\n.approve-btn-sm {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success-text);\n border-color: var(--mj-status-success-border);\n}\n.approve-btn-sm:hover { background: rgba(34,197,94,0.25); }\n\n.reject-btn-sm {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error-text);\n border-color: var(--mj-status-error-border);\n}\n.reject-btn-sm:hover { background: rgba(239,68,68,0.25); }\n\n.match-status-badge {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 0.68rem;\n font-weight: 500;\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.status-approved {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success-text);\n}\n\n.status-rejected {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error-text);\n}\n\n.match-approved {\n border-top: 3px solid var(--mj-status-success);\n}\n\n.match-rejected {\n border-top: 3px solid var(--mj-status-error);\n opacity: 0.6;\n}\n\n/* Label cells */\n.grid-label-cell {\n position: sticky;\n left: 0;\n z-index: 2;\n background: var(--mj-bg-surface);\n font-size: 0.72rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n display: flex;\n align-items: center;\n}\n\n.grid-row-odd {\n background: color-mix(in srgb, var(--mj-bg-surface-sunken) 50%, var(--mj-bg-surface));\n}\n\n.grid-label-cell.grid-row-odd {\n background: color-mix(in srgb, var(--mj-bg-surface-sunken) 50%, var(--mj-bg-surface));\n}\n\n/* Value cells */\n.grid-value-cell {\n font-size: 0.78rem;\n color: var(--mj-text-primary);\n line-height: 1.45;\n word-break: break-word;\n position: relative;\n cursor: pointer;\n}\n\n.grid-source-cell {\n background: color-mix(in srgb, var(--mj-brand-primary) 3%, var(--mj-bg-surface));\n border-left: 3px solid transparent;\n}\n\n.grid-source-cell.grid-row-odd {\n background: color-mix(in srgb, var(--mj-brand-primary) 3%, color-mix(in srgb, var(--mj-bg-surface-sunken) 50%, var(--mj-bg-surface)));\n}\n\n.grid-source-cell.has-diff-in-row {\n font-weight: 600;\n}\n\n/* Diff highlighting */\n.value-same {\n color: var(--mj-text-muted);\n}\n\n.value-different {\n background: color-mix(in srgb, var(--mj-status-warning) 8%, transparent) !important;\n border-left: 3px solid var(--mj-status-warning);\n color: var(--mj-text-primary);\n}\n\n.field-not-available {\n font-style: italic;\n font-size: 0.72rem;\n color: var(--mj-text-disabled);\n}\n\n/* Field selection radio */\n.field-select-radio {\n position: absolute;\n top: 50%;\n right: 8px;\n transform: translateY(-50%);\n appearance: none;\n width: 16px;\n height: 16px;\n border: 2px solid var(--mj-border-strong);\n border-radius: 50%;\n cursor: pointer;\n transition: all 0.12s ease;\n opacity: 0.4;\n}\n\n.field-select-radio:hover {\n opacity: 0.8;\n}\n\n.field-select-radio:checked {\n border-color: var(--mj-brand-primary);\n background: var(--mj-brand-primary);\n box-shadow: inset 0 0 0 2.5px var(--mj-bg-surface);\n opacity: 1;\n}\n\n.grid-value-cell.field-selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface)) !important;\n border-left: 3px solid var(--mj-brand-primary);\n}\n\n.grid-value-cell.field-selected .field-select-radio {\n opacity: 1;\n}\n\n/* Footer */\n.comparison-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 20px;\n border-top: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.comparison-footer-left {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n.comparison-summary {\n font-size: 0.72rem;\n color: var(--mj-text-muted);\n}\n\n.merge-summary {\n font-size: 0.72rem;\n color: var(--mj-brand-primary);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.merge-summary i {\n font-size: 0.65rem;\n}\n\n.comparison-footer-right {\n display: flex;\n gap: 8px;\n}\n\n.comparison-footer-right .action-btn {\n flex: none;\n padding: 7px 14px;\n}\n\n.merge-btn {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-color: var(--mj-brand-primary);\n}\n\n.merge-btn:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n.card-actions {\n display: flex;\n gap: 8px;\n padding: 10px 12px;\n border-top: 1px solid var(--mj-border-subtle);\n}\n\n.action-btn {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n height: 32px;\n padding: 0 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: background 0.15s ease, border-color 0.15s ease;\n}\n\n.action-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.approve-btn {\n background: color-mix(in srgb, var(--mj-status-success) 10%, var(--mj-bg-surface));\n color: var(--mj-status-success-text);\n border-color: var(--mj-status-success-border);\n}\n\n.approve-btn:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-status-success) 20%, var(--mj-bg-surface));\n}\n\n.reject-btn {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n color: var(--mj-status-error-text);\n border-color: var(--mj-status-error-border);\n}\n\n.reject-btn:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-status-error) 20%, var(--mj-bg-surface));\n}\n\n/* ---- Responsive ---- */\n\n@media (max-width: 768px) {\n .kanban-board {\n flex-direction: column;\n }\n\n .kanban-column {\n min-width: auto;\n max-height: 400px;\n }\n}\n\n@media (max-width: 480px) {\n .kpi-strip {\n flex-direction: column;\n }\n\n .filter-bar {\n flex-wrap: wrap;\n }\n\n .filter-group {\n flex-direction: column;\n align-items: stretch;\n width: 100%;\n }\n\n .filter-select {\n min-width: auto;\n width: 100%;\n }\n\n .filter-input {\n width: 100%;\n }\n\n .card-actions {\n flex-direction: column;\n }\n\n .action-btn {\n width: 100%;\n }\n}\n\n/* ---- Saving Overlay ---- */\n\n.saving-overlay {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-bg-overlay);\n z-index: 10;\n border-radius: 8px;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n Dependencies Summary (in column headers)\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.deps-summary {\n margin-top: 6px;\n padding: 6px 8px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 6px;\n font-size: 0.68rem;\n}\n\n.deps-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n cursor: pointer;\n color: var(--mj-text-secondary);\n font-weight: 600;\n}\n\n.deps-header i {\n font-size: 0.6rem;\n color: var(--mj-text-muted);\n}\n\n.deps-header:hover {\n color: var(--mj-text-primary);\n}\n\n.deps-total {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 0.72rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin-bottom: 2px;\n}\n\n.deps-total i {\n font-size: 0.65rem;\n color: var(--mj-text-muted);\n}\n\n.deps-total-number {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n padding: 0 6px;\n border-radius: 8px;\n font-size: 0.7rem;\n font-weight: 700;\n}\n\n.deps-total-recommended {\n font-size: 0.58rem;\n color: var(--mj-status-success-text);\n font-weight: 600;\n margin-left: 4px;\n}\n\n.deps-total-recommended i {\n color: var(--mj-status-success-text);\n}\n\n.deps-detail-list {\n margin-top: 4px;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.deps-detail-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 3px 0;\n font-size: 0.65rem;\n color: var(--mj-text-muted);\n cursor: pointer;\n border-radius: 3px;\n transition: background 0.1s ease;\n}\n\n.deps-detail-row:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.deps-detail-entity {\n display: flex;\n align-items: center;\n gap: 4px;\n color: var(--mj-text-secondary);\n}\n\n.deps-expand-icon {\n font-size: 0.5rem;\n width: 10px;\n text-align: center;\n color: var(--mj-text-muted);\n}\n\n/* Individual dependency records list */\n.deps-records-list {\n padding-left: 14px;\n margin-bottom: 2px;\n}\n\n.deps-record-row {\n display: flex;\n align-items: center;\n gap: 5px;\n padding: 2px 4px;\n font-size: 0.6rem;\n color: var(--mj-text-muted);\n cursor: pointer;\n border-radius: 3px;\n transition: color 0.1s ease, background 0.1s ease;\n}\n\n.deps-record-row:hover {\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n}\n\n.deps-record-icon {\n font-size: 0.5rem;\n flex-shrink: 0;\n}\n\n.deps-record-name {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 0.6rem;\n}\n\n.deps-record-loading {\n padding: 3px 4px;\n font-size: 0.6rem;\n color: var(--mj-text-muted);\n}\n\n.deps-record-loading i {\n margin-right: 4px;\n}\n\n.deps-detail-count {\n color: var(--mj-text-primary);\n font-weight: 600;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n Merge Confirmation Panel\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.merge-confirm-backdrop {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.3);\n z-index: 20000;\n animation: fadeIn 0.2s ease;\n}\n\n.merge-confirm-panel {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n width: 520px;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n box-shadow: -8px 0 40px rgba(0, 0, 0, 0.4);\n z-index: 20001;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n animation: slideIn 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.merge-confirm-header {\n padding: 18px 24px;\n border-bottom: 1px solid var(--mj-border-default);\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.merge-confirm-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 10px;\n background: color-mix(in srgb, var(--mj-status-warning) 12%, var(--mj-bg-surface));\n color: var(--mj-status-warning-text);\n font-size: 1.1rem;\n flex-shrink: 0;\n}\n\n.merge-confirm-title {\n font-size: 1.05rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.merge-confirm-subtitle {\n font-size: 0.75rem;\n color: var(--mj-text-muted);\n margin-top: 2px;\n}\n\n.merge-confirm-body {\n padding: 20px 24px;\n overflow-y: auto;\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n/* Surviving record card */\n\n.merge-survivor-card {\n padding: 14px;\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, var(--mj-bg-surface));\n border: 1px solid var(--mj-brand-primary);\n border-radius: 8px;\n}\n\n.merge-survivor-label {\n font-size: 0.65rem;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--mj-brand-primary);\n margin-bottom: 4px;\n}\n\n.merge-survivor-label i {\n margin-right: 4px;\n}\n\n.merge-survivor-name {\n font-size: 0.95rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.merge-survivor-pk {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-top: 4px;\n padding: 4px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border-radius: 4px;\n font-size: 0.68rem;\n font-family: monospace;\n color: var(--mj-text-secondary);\n}\n\n.merge-survivor-pk i {\n font-size: 0.6rem;\n color: var(--mj-brand-primary);\n}\n\n.merge-survivor-detail {\n font-size: 0.72rem;\n color: var(--mj-text-muted);\n margin-top: 4px;\n}\n\n/* Cherry-picked fields section */\n\n.merge-section-label {\n font-size: 0.7rem;\n font-weight: 700;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n margin-bottom: 6px;\n}\n\n.merge-field-override {\n display: flex;\n align-items: baseline;\n gap: 8px;\n padding: 6px 0;\n border-bottom: 1px solid var(--mj-border-subtle);\n font-size: 0.78rem;\n}\n\n.merge-field-name {\n font-weight: 600;\n color: var(--mj-text-secondary);\n min-width: 110px;\n flex-shrink: 0;\n}\n\n.merge-field-value {\n color: var(--mj-text-primary);\n}\n\n.merge-field-source {\n font-size: 0.65rem;\n color: var(--mj-text-muted);\n margin-left: auto;\n white-space: nowrap;\n}\n\n/* Dependency transfer summary */\n\n.merge-deps-transfer {\n padding: 10px 14px;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n}\n\n.merge-deps-transfer-label {\n font-size: 0.65rem;\n font-weight: 700;\n text-transform: uppercase;\n color: var(--mj-brand-primary);\n margin-bottom: 6px;\n}\n\n.merge-deps-transfer-label i {\n margin-right: 4px;\n}\n\n.merge-deps-transfer-row {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 3px 0;\n font-size: 0.75rem;\n color: var(--mj-text-secondary);\n}\n\n.merge-deps-transfer-row i {\n color: var(--mj-brand-primary);\n font-size: 0.65rem;\n width: 14px;\n text-align: center;\n}\n\n/* Records to delete */\n\n.merge-delete-card {\n padding: 10px 14px;\n background: color-mix(in srgb, var(--mj-status-error) 5%, var(--mj-bg-surface));\n border: 1px solid var(--mj-status-error-border);\n border-radius: 8px;\n}\n\n.merge-delete-label {\n font-size: 0.65rem;\n font-weight: 700;\n text-transform: uppercase;\n color: var(--mj-status-error-text);\n margin-bottom: 6px;\n}\n\n.merge-delete-label i {\n margin-right: 4px;\n}\n\n.merge-delete-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 5px 0;\n font-size: 0.78rem;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.merge-delete-item:last-child {\n border-bottom: none;\n}\n\n.merge-delete-name {\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.merge-delete-deps {\n font-size: 0.65rem;\n color: var(--mj-text-muted);\n}\n\n/* Confirm footer */\n\n.merge-confirm-footer {\n padding: 14px 24px;\n border-top: 1px solid var(--mj-border-default);\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 10px;\n}\n\n.cancel-btn {\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n border-color: var(--mj-border-default);\n}\n\n.cancel-btn:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.confirm-merge-btn {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.confirm-merge-btn:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n.confirm-merge-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n/* ---- Responsive: Merge Confirm ---- */\n\n@media (max-width: 600px) {\n .merge-confirm-panel {\n width: 100%;\n }\n}\n"] }]
2676
- }], null, { EmbeddedMode: [{
2939
+ args: [{ standalone: false, selector: 'app-duplicate-detection-resource', encapsulation: ViewEncapsulation.None, template: "<div class=\"duplicate-detection-container\">\n <!-- Header -->\n <div class=\"page-header\">\n <div class=\"header-left\">\n <h2 class=\"page-title\">\n <i class=\"fa-solid fa-clone\"></i> Duplicate Detection\n </h2>\n </div>\n <div class=\"header-actions\">\n <div class=\"run-detection-controls\">\n <select class=\"entity-doc-select\"\n [(ngModel)]=\"SelectedEntityDocumentID\"\n [disabled]=\"IsDetecting\">\n <option value=\"\">Select entity document...</option>\n @for (doc of EntityDocuments; track doc.ID) {\n <option [value]=\"doc.ID\">{{ doc.Name }} ({{ doc.EntityName }})</option>\n }\n </select>\n <button class=\"run-detection-btn\"\n (click)=\"RunDetection()\"\n [disabled]=\"IsDetecting || !SelectedEntityDocumentID\">\n @if (IsDetecting) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Detecting...\n } @else {\n <i class=\"fa-solid fa-magnifying-glass\"></i> Run Detection\n }\n </button>\n </div>\n </div>\n </div>\n\n <!-- Detection Progress (visible during run) -->\n @if (IsDetecting) {\n <div class=\"detection-progress-section\">\n <div class=\"progress-header\">\n <span class=\"progress-stage\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n {{ DetectionStage }}\n </span>\n <span class=\"progress-percent\">{{ DetectionProgress }}%</span>\n </div>\n <div class=\"progress-bar-track\">\n <div class=\"progress-bar-fill\" [style.width.%]=\"DetectionProgress\"></div>\n </div>\n @if (DetectionCurrentItem) {\n <span class=\"progress-current-item\">{{ DetectionCurrentItem }}</span>\n }\n </div>\n }\n\n <!-- Threshold Controls (when entity doc selected) -->\n @if (SelectedDocumentThresholds) {\n <div class=\"threshold-controls\">\n <div class=\"threshold-slider-group\">\n <label class=\"threshold-label\">\n <i class=\"fa-solid fa-adjust\"></i>\n Potential Match\n <span class=\"threshold-value\">{{ (RunPotentialThreshold * 100).toFixed(0) }}%</span>\n </label>\n <input type=\"range\" class=\"threshold-slider\"\n [min]=\"30\" [max]=\"99\" [step]=\"1\"\n [value]=\"RunPotentialThreshold * 100\"\n (input)=\"OnPotentialThresholdChanged($any($event.target).value / 100)\"\n [disabled]=\"IsDetecting\" />\n <span class=\"threshold-hint\">Score above which duplicates are flagged for review</span>\n </div>\n <div class=\"threshold-slider-group\">\n <label class=\"threshold-label\">\n <i class=\"fa-solid fa-bullseye\"></i>\n Absolute Match\n <span class=\"threshold-value\">{{ (RunAbsoluteThreshold * 100).toFixed(0) }}%</span>\n </label>\n <input type=\"range\" class=\"threshold-slider\"\n [min]=\"50\" [max]=\"100\" [step]=\"1\"\n [value]=\"RunAbsoluteThreshold * 100\"\n (input)=\"OnAbsoluteThresholdChanged($any($event.target).value / 100)\"\n [disabled]=\"IsDetecting\" />\n <span class=\"threshold-hint\">Score above which duplicates are auto-confirmed</span>\n </div>\n </div>\n }\n\n <!-- KPI Strip -->\n <div class=\"kpi-strip\">\n <div class=\"kpi-card\">\n <div class=\"kpi-value\">{{ TotalGroupCount }}</div>\n <div class=\"kpi-label\">Total Groups</div>\n </div>\n <div class=\"kpi-card kpi-pending\">\n <div class=\"kpi-value\">{{ PendingCount }}</div>\n <div class=\"kpi-label\">Pending</div>\n </div>\n <div class=\"kpi-card kpi-approved\">\n <div class=\"kpi-value\">{{ ApprovedCount }}</div>\n <div class=\"kpi-label\">Approved</div>\n </div>\n <div class=\"kpi-card kpi-rejected\">\n <div class=\"kpi-value\">{{ RejectedCount }}</div>\n <div class=\"kpi-label\">Rejected</div>\n </div>\n </div>\n\n <!-- Filter Bar -->\n <div class=\"filter-bar\">\n <div class=\"filter-group\">\n <select class=\"filter-select\"\n [(ngModel)]=\"Filters.EntityName\"\n (ngModelChange)=\"OnFilterChange()\"\n [disabled]=\"EntityNames.length <= 1\">\n @if (EntityNames.length > 1) {\n <option value=\"\">All Entities</option>\n }\n @for (name of EntityNames; track name) {\n <option [value]=\"name\">{{ name }}</option>\n }\n </select>\n\n <div class=\"filter-range\">\n <label class=\"filter-label\">Min Score</label>\n <input type=\"number\"\n class=\"filter-input filter-input-score\"\n min=\"0\" max=\"1\" step=\"0.05\"\n [placeholder]=\"DataMinScore\"\n [(ngModel)]=\"Filters.MinScore\"\n (ngModelChange)=\"OnFilterChange()\">\n </div>\n\n <div class=\"filter-range\">\n <label class=\"filter-label\">Max Score</label>\n <input type=\"number\"\n class=\"filter-input filter-input-score\"\n min=\"0\" max=\"1\" step=\"0.05\"\n [placeholder]=\"DataMaxScore\"\n [(ngModel)]=\"Filters.MaxScore\"\n (ngModelChange)=\"OnFilterChange()\">\n </div>\n\n <div class=\"filter-range\">\n <label class=\"filter-label\">From</label>\n <input type=\"date\"\n class=\"filter-input filter-input-date\"\n [min]=\"DataMinDate\" [max]=\"DataMaxDate\"\n [(ngModel)]=\"Filters.DateFrom\"\n (ngModelChange)=\"OnFilterChange()\">\n </div>\n\n <div class=\"filter-range\">\n <label class=\"filter-label\">To</label>\n <input type=\"date\"\n class=\"filter-input filter-input-date\"\n [min]=\"DataMinDate\" [max]=\"DataMaxDate\"\n [(ngModel)]=\"Filters.DateTo\"\n (ngModelChange)=\"OnFilterChange()\">\n </div>\n </div>\n\n @if (HasActiveFilters) {\n <button class=\"clear-filters-btn\" (click)=\"ClearFilters()\">\n <i class=\"fa-solid fa-times\"></i> Clear Filters\n </button>\n }\n </div>\n\n <!-- Merge Warning Banner (non-blocking, shown when entity lacks AllowRecordMerge) -->\n @if (ShowMergeWarningBanner) {\n <div class=\"merge-warning-banner\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n Merging is not available for this entity. Detection results are read-only.\n </div>\n }\n\n <!-- Content -->\n @if (IsLoading) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading duplicate detection results...\"></mj-loading>\n </div>\n } @else if (IsLoadingResults) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading duplicate detection results...\"></mj-loading>\n </div>\n } @else if (TotalGroupCount === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-clone empty-icon\"></i>\n <p class=\"empty-text\">No duplicate detection results found.</p>\n <p class=\"empty-subtext\">Select an entity document and click \"Run Detection\" to start.</p>\n </div>\n } @else {\n <!-- Kanban Board -->\n <div class=\"kanban-board\">\n <!-- Pending Column -->\n <div class=\"kanban-column\" [class.drop-target-active]=\"DragOverColumn === 'Pending' && DraggedGroup?.ApprovalStatus !== 'Pending'\">\n <div class=\"column-header column-header-pending\">\n <i class=\"fa-solid fa-clock\"></i>\n <span class=\"column-title\">Pending Review</span>\n <span class=\"column-count\">{{ PendingCount }}</span>\n </div>\n <div class=\"column-body\"\n (dragover)=\"OnDragOver($event, 'Pending')\"\n (dragleave)=\"OnDragLeave($event, 'Pending')\"\n (drop)=\"OnDrop($event, 'Pending')\">\n @for (group of PendingGroups; track group.DetailId) {\n <div class=\"kanban-card\"\n draggable=\"true\"\n (dragstart)=\"OnDragStart($event, group)\"\n (dragend)=\"OnDragEnd()\"\n (click)=\"OpenComparison(group)\">\n <div class=\"card-header\">\n <div class=\"card-header-left\">\n <div class=\"card-icon\">\n <i [class]=\"group.EntityIcon\"></i>\n </div>\n <div class=\"card-title-block\">\n <div class=\"card-record-name\" [title]=\"group.RecordName\">{{ group.RecordName }}</div>\n <span class=\"entity-badge\">{{ group.EntityName }}</span>\n </div>\n </div>\n <span class=\"score-indicator\" [class]=\"GetScoreClass(group.HighestScore)\">\n {{ (group.HighestScore * 100).toFixed(0) }}%\n </span>\n </div>\n <div class=\"card-body\">\n @if (group.TopMatchSummaries.length > 0) {\n <div class=\"match-summaries\">\n @for (ms of group.TopMatchSummaries; track ms.Name) {\n <div class=\"match-summary-row\">\n <span class=\"match-score\">{{ (ms.Score * 100).toFixed(0) }}%</span>\n <span class=\"match-name\">{{ ms.Name }}</span>\n </div>\n }\n @if (group.MatchCount > group.TopMatchSummaries.length) {\n <div class=\"match-summary-more\">+{{ group.MatchCount - group.TopMatchSummaries.length }} more</div>\n }\n </div>\n }\n <div class=\"card-meta-row\">\n <span class=\"card-meta-item\">\n <i class=\"fa-solid fa-layer-group\"></i>\n {{ group.MatchCount }} match{{ group.MatchCount !== 1 ? 'es' : '' }}\n </span>\n <span class=\"card-meta-item\">\n <i class=\"fa-solid fa-calendar\"></i>\n {{ FormatDate(group.MatchedAt) }}\n </span>\n </div>\n </div>\n <div class=\"card-actions\">\n <button class=\"action-btn approve-btn\"\n [disabled]=\"IsSaving\"\n (click)=\"ApproveMatch(group); $event.stopPropagation()\">\n <i class=\"fa-solid fa-check\"></i> Approve\n </button>\n <button class=\"action-btn reject-btn\"\n [disabled]=\"IsSaving\"\n (click)=\"RejectMatch(group); $event.stopPropagation()\">\n <i class=\"fa-solid fa-times\"></i> Reject\n </button>\n </div>\n </div>\n }\n @if (PendingGroups.length === 0) {\n <div class=\"column-empty\">\n <i class=\"fa-solid fa-check-circle\"></i>\n <span>No pending items</span>\n </div>\n }\n </div>\n </div>\n\n <!-- Approved Column -->\n <div class=\"kanban-column\" [class.drop-target-active]=\"DragOverColumn === 'Approved' && DraggedGroup?.ApprovalStatus !== 'Approved'\">\n <div class=\"column-header column-header-approved\">\n <i class=\"fa-solid fa-check-circle\"></i>\n <span class=\"column-title\">Approved</span>\n <span class=\"column-count\">{{ ApprovedCount }}</span>\n </div>\n <div class=\"column-body\"\n (dragover)=\"OnDragOver($event, 'Approved')\"\n (dragleave)=\"OnDragLeave($event, 'Approved')\"\n (drop)=\"OnDrop($event, 'Approved')\">\n @for (group of ApprovedGroups; track group.DetailId) {\n <div class=\"kanban-card\"\n draggable=\"true\"\n (dragstart)=\"OnDragStart($event, group)\"\n (dragend)=\"OnDragEnd()\"\n (click)=\"OpenComparison(group)\">\n <div class=\"card-header\">\n <div class=\"card-header-left\">\n <div class=\"card-icon\">\n <i [class]=\"group.EntityIcon\"></i>\n </div>\n <div class=\"card-title-block\">\n <div class=\"card-record-name\" [title]=\"group.RecordName\">{{ group.RecordName }}</div>\n <span class=\"entity-badge\">{{ group.EntityName }}</span>\n </div>\n </div>\n <span class=\"score-indicator\" [class]=\"GetScoreClass(group.HighestScore)\">\n {{ (group.HighestScore * 100).toFixed(0) }}%\n </span>\n </div>\n <div class=\"card-body\">\n @if (group.TopMatchSummaries.length > 0) {\n <div class=\"match-summaries\">\n @for (ms of group.TopMatchSummaries; track ms.Name) {\n <div class=\"match-summary-row\">\n <span class=\"match-score\">{{ (ms.Score * 100).toFixed(0) }}%</span>\n <span class=\"match-name\">{{ ms.Name }}</span>\n </div>\n }\n @if (group.MatchCount > group.TopMatchSummaries.length) {\n <div class=\"match-summary-more\">+{{ group.MatchCount - group.TopMatchSummaries.length }} more</div>\n }\n </div>\n }\n <div class=\"card-meta-row\">\n <span class=\"card-meta-item\">\n <i class=\"fa-solid fa-layer-group\"></i>\n {{ group.MatchCount }} match{{ group.MatchCount !== 1 ? 'es' : '' }}\n </span>\n <span class=\"card-meta-item\">\n <i class=\"fa-solid fa-calendar\"></i>\n {{ FormatDate(group.MatchedAt) }}\n </span>\n </div>\n </div>\n </div>\n }\n @if (ApprovedGroups.length === 0) {\n <div class=\"column-empty\">\n <i class=\"fa-solid fa-inbox\"></i>\n <span>No approved items</span>\n </div>\n }\n </div>\n </div>\n\n <!-- Rejected Column -->\n <div class=\"kanban-column\" [class.drop-target-active]=\"DragOverColumn === 'Rejected' && DraggedGroup?.ApprovalStatus !== 'Rejected'\">\n <div class=\"column-header column-header-rejected\">\n <i class=\"fa-solid fa-ban\"></i>\n <span class=\"column-title\">Rejected</span>\n <span class=\"column-count\">{{ RejectedCount }}</span>\n </div>\n <div class=\"column-body\"\n (dragover)=\"OnDragOver($event, 'Rejected')\"\n (dragleave)=\"OnDragLeave($event, 'Rejected')\"\n (drop)=\"OnDrop($event, 'Rejected')\">\n @for (group of RejectedGroups; track group.DetailId) {\n <div class=\"kanban-card\"\n draggable=\"true\"\n (dragstart)=\"OnDragStart($event, group)\"\n (dragend)=\"OnDragEnd()\"\n (click)=\"OpenComparison(group)\">\n <div class=\"card-header\">\n <div class=\"card-header-left\">\n <div class=\"card-icon\">\n <i [class]=\"group.EntityIcon\"></i>\n </div>\n <div class=\"card-title-block\">\n <div class=\"card-record-name\" [title]=\"group.RecordName\">{{ group.RecordName }}</div>\n <span class=\"entity-badge\">{{ group.EntityName }}</span>\n </div>\n </div>\n <span class=\"score-indicator\" [class]=\"GetScoreClass(group.HighestScore)\">\n {{ (group.HighestScore * 100).toFixed(0) }}%\n </span>\n </div>\n <div class=\"card-body\">\n @if (group.TopMatchSummaries.length > 0) {\n <div class=\"match-summaries\">\n @for (ms of group.TopMatchSummaries; track ms.Name) {\n <div class=\"match-summary-row\">\n <span class=\"match-score\">{{ (ms.Score * 100).toFixed(0) }}%</span>\n <span class=\"match-name\">{{ ms.Name }}</span>\n </div>\n }\n @if (group.MatchCount > group.TopMatchSummaries.length) {\n <div class=\"match-summary-more\">+{{ group.MatchCount - group.TopMatchSummaries.length }} more</div>\n }\n </div>\n }\n <div class=\"card-meta-row\">\n <span class=\"card-meta-item\">\n <i class=\"fa-solid fa-layer-group\"></i>\n {{ group.MatchCount }} match{{ group.MatchCount !== 1 ? 'es' : '' }}\n </span>\n <span class=\"card-meta-item\">\n <i class=\"fa-solid fa-calendar\"></i>\n {{ FormatDate(group.MatchedAt) }}\n </span>\n </div>\n </div>\n </div>\n }\n @if (RejectedGroups.length === 0) {\n <div class=\"column-empty\">\n <i class=\"fa-solid fa-inbox\"></i>\n <span>No rejected items</span>\n </div>\n }\n </div>\n </div>\n </div>\n }\n\n <!-- Saving overlay -->\n @if (IsSaving) {\n <div class=\"saving-overlay\">\n <mj-loading text=\"Saving...\" size=\"small\"></mj-loading>\n </div>\n }\n\n <!-- \u2550\u2550\u2550 Comparison Slide-In Panel \u2550\u2550\u2550 -->\n @if (ComparisonGroup) {\n <div class=\"slide-backdrop\" [class.comparison-closing]=\"ComparisonClosing\" (click)=\"CloseComparison()\"></div>\n <div class=\"comparison-panel\" [class.comparison-closing]=\"ComparisonClosing\" (click)=\"$event.stopPropagation()\">\n <!-- Header -->\n <div class=\"comparison-header\">\n <div class=\"comparison-header-left\">\n <div class=\"comparison-entity-icon\">\n <i [class]=\"ComparisonGroup.EntityIcon\"></i>\n </div>\n <div>\n <div class=\"comparison-title\">{{ ComparisonGroup.RecordName }}</div>\n <span class=\"comparison-entity-badge\">{{ ComparisonGroup.EntityName }}</span>\n <span class=\"comparison-match-count\">\n {{ ComparisonGroup.MatchCount }} potential duplicate{{ ComparisonGroup.MatchCount !== 1 ? 's' : '' }}\n </span>\n </div>\n </div>\n <div class=\"comparison-header-right\">\n <div class=\"comparison-toggle\">\n <button class=\"toggle-btn\" [class.toggle-active]=\"ComparisonShowAllFields\"\n (click)=\"ComparisonShowAllFields = true\">All Fields</button>\n <button class=\"toggle-btn\" [class.toggle-active]=\"!ComparisonShowAllFields\"\n (click)=\"ComparisonShowAllFields = false\">Differences Only</button>\n </div>\n <button class=\"comparison-close-btn\" (click)=\"CloseComparison()\" title=\"Close (Esc)\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n </div>\n\n <!-- Grid -->\n @if (ComparisonLoading) {\n <div class=\"comparison-loading\">\n <mj-loading text=\"Loading records for comparison...\" size=\"medium\"></mj-loading>\n </div>\n }\n <div class=\"comparison-grid-wrapper\" [hidden]=\"ComparisonLoading\">\n <div class=\"comparison-grid\"\n [style.grid-template-columns]=\"'160px repeat(' + (1 + ComparisonMatches.length) + ', minmax(180px, 1fr))'\">\n\n <!-- Corner cell -->\n <div class=\"grid-corner-cell\">Field</div>\n\n <!-- Source column header -->\n <div class=\"grid-col-header grid-col-source\">\n <span class=\"col-header-label\">Source</span>\n <span class=\"col-header-name\">{{ ComparisonGroup.RecordName }}</span>\n <div class=\"surviving-selector\">\n <input type=\"radio\" name=\"survivor\" class=\"surviving-radio\"\n [checked]=\"SurvivorColumnIndex === 0\"\n (change)=\"SetSurvivor(0)\">\n <span class=\"surviving-label\" [class.is-survivor]=\"SurvivorColumnIndex === 0\">\n {{ SurvivorColumnIndex === 0 ? 'Surviving Record' : 'Set as survivor' }}\n </span>\n </div>\n <button class=\"use-all-btn\" [class.all-selected]=\"AllFieldsSelectedFrom(0)\"\n (click)=\"UseAllFieldsFrom(0)\">\n <i class=\"fa-solid\" [class.fa-check-double]=\"AllFieldsSelectedFrom(0)\" [class.fa-clone]=\"!AllFieldsSelectedFrom(0)\"></i>\n {{ AllFieldsSelectedFrom(0) ? 'Using all fields' : 'Use all fields' }}\n </button>\n <!-- Dependencies Summary -->\n <div class=\"deps-summary\">\n <div class=\"deps-total\">\n <i class=\"fa-solid fa-link\"></i>\n <span class=\"deps-total-number\">{{ GetTotalDeps(0) }}</span>\n {{ GetTotalDeps(0) === 1 ? 'dependency' : 'dependencies' }}\n @if (GetMaxDepsColumnIndex() === 0 && GetTotalDeps(0) > 0) {\n <span class=\"deps-total-recommended\"><i class=\"fa-solid fa-star\"></i> Most deps</span>\n }\n </div>\n @if (GetGroupedDeps(0).length > 0) {\n <div class=\"deps-header\" (click)=\"ToggleDepsExpanded(0)\">\n <span>{{ IsDepsExpanded(0) ? 'Hide details' : 'Show details' }}</span>\n <i class=\"fa-solid\" [class.fa-chevron-down]=\"!IsDepsExpanded(0)\" [class.fa-chevron-up]=\"IsDepsExpanded(0)\"></i>\n </div>\n @if (IsDepsExpanded(0)) {\n <div class=\"deps-detail-list\">\n @for (dep of GetGroupedDeps(0); track dep.Entity) {\n <div class=\"deps-detail-group\">\n <div class=\"deps-detail-row\" (click)=\"ToggleDepEntityGroup(0, dep.Entity); $event.stopPropagation()\">\n <span class=\"deps-detail-entity\">\n <i class=\"fa-solid deps-expand-icon\"\n [class.fa-chevron-right]=\"!IsDepEntityGroupExpanded(0, dep.Entity)\"\n [class.fa-chevron-down]=\"IsDepEntityGroupExpanded(0, dep.Entity)\"></i>\n {{ dep.Entity }}\n </span>\n <span class=\"deps-detail-count\">{{ dep.Count }}</span>\n </div>\n @if (IsDepEntityGroupExpanded(0, dep.Entity)) {\n <div class=\"deps-records-list\">\n @if (IsDepRecordsLoading(0, dep.Entity)) {\n <div class=\"deps-record-loading\"><i class=\"fa-solid fa-spinner fa-spin\"></i> Loading...</div>\n }\n @for (record of GetDepRecords(0, dep.Entity); track $index) {\n <div class=\"deps-record-row\" (click)=\"OpenDepRecord(record); $event.stopPropagation()\">\n <i class=\"fa-solid fa-arrow-up-right-from-square deps-record-icon\"></i>\n <span class=\"deps-record-name\">{{ record.Name }}</span>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n }\n </div>\n </div>\n\n <!-- Match column headers -->\n @for (match of ComparisonMatches; track match.Match.ID; let mi = $index) {\n <div class=\"grid-col-header\"\n [class.match-approved]=\"match.Match.ApprovalStatus === 'Approved'\"\n [class.match-rejected]=\"match.Match.ApprovalStatus === 'Rejected'\">\n <div class=\"col-header-top\">\n <span class=\"col-header-name\">{{ match.Name }}</span>\n <span class=\"score-indicator\" [class]=\"GetScoreClass(match.Score)\">\n {{ (match.Score * 100).toFixed(0) }}%\n </span>\n </div>\n <span class=\"col-header-diff-count\">{{ match.DiffCount }} difference{{ match.DiffCount !== 1 ? 's' : '' }}</span>\n <div class=\"surviving-selector\">\n <input type=\"radio\" name=\"survivor\" class=\"surviving-radio\"\n [checked]=\"SurvivorColumnIndex === mi + 1\"\n (change)=\"SetSurvivor(mi + 1)\">\n <span class=\"surviving-label\" [class.is-survivor]=\"SurvivorColumnIndex === mi + 1\">\n {{ SurvivorColumnIndex === mi + 1 ? 'Surviving Record' : 'Set as survivor' }}\n </span>\n </div>\n <button class=\"use-all-btn\" [class.all-selected]=\"AllFieldsSelectedFrom(mi + 1)\"\n (click)=\"UseAllFieldsFrom(mi + 1)\">\n <i class=\"fa-solid\" [class.fa-check-double]=\"AllFieldsSelectedFrom(mi + 1)\" [class.fa-clone]=\"!AllFieldsSelectedFrom(mi + 1)\"></i>\n {{ AllFieldsSelectedFrom(mi + 1) ? 'Using all fields' : 'Use all fields' }}\n </button>\n <!-- Dependencies Summary -->\n <div class=\"deps-summary\">\n <div class=\"deps-total\">\n <i class=\"fa-solid fa-link\"></i>\n <span class=\"deps-total-number\">{{ GetTotalDeps(mi + 1) }}</span>\n {{ GetTotalDeps(mi + 1) === 1 ? 'dependency' : 'dependencies' }}\n @if (GetMaxDepsColumnIndex() === mi + 1 && GetTotalDeps(mi + 1) > 0) {\n <span class=\"deps-total-recommended\"><i class=\"fa-solid fa-star\"></i> Most deps</span>\n }\n </div>\n @if (GetGroupedDeps(mi + 1).length > 0) {\n <div class=\"deps-header\" (click)=\"ToggleDepsExpanded(mi + 1)\">\n <span>{{ IsDepsExpanded(mi + 1) ? 'Hide details' : 'Show details' }}</span>\n <i class=\"fa-solid\" [class.fa-chevron-down]=\"!IsDepsExpanded(mi + 1)\" [class.fa-chevron-up]=\"IsDepsExpanded(mi + 1)\"></i>\n </div>\n @if (IsDepsExpanded(mi + 1)) {\n <div class=\"deps-detail-list\">\n @for (dep of GetGroupedDeps(mi + 1); track dep.Entity) {\n <div class=\"deps-detail-group\">\n <div class=\"deps-detail-row\" (click)=\"ToggleDepEntityGroup(mi + 1, dep.Entity); $event.stopPropagation()\">\n <span class=\"deps-detail-entity\">\n <i class=\"fa-solid deps-expand-icon\"\n [class.fa-chevron-right]=\"!IsDepEntityGroupExpanded(mi + 1, dep.Entity)\"\n [class.fa-chevron-down]=\"IsDepEntityGroupExpanded(mi + 1, dep.Entity)\"></i>\n {{ dep.Entity }}\n </span>\n <span class=\"deps-detail-count\">{{ dep.Count }}</span>\n </div>\n @if (IsDepEntityGroupExpanded(mi + 1, dep.Entity)) {\n <div class=\"deps-records-list\">\n @if (IsDepRecordsLoading(mi + 1, dep.Entity)) {\n <div class=\"deps-record-loading\"><i class=\"fa-solid fa-spinner fa-spin\"></i> Loading...</div>\n }\n @for (record of GetDepRecords(mi + 1, dep.Entity); track $index) {\n <div class=\"deps-record-row\" (click)=\"OpenDepRecord(record); $event.stopPropagation()\">\n <i class=\"fa-solid fa-arrow-up-right-from-square deps-record-icon\"></i>\n <span class=\"deps-record-name\">{{ record.Name }}</span>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n }\n </div>\n <!-- Per-match approval actions -->\n <div class=\"match-approval-actions\">\n @if (match.Match.ApprovalStatus === 'Pending') {\n <button class=\"match-action-btn match-skip-btn\"\n title=\"Skip this match (exclude from merge)\"\n (click)=\"RejectIndividualMatch(match)\">\n <i class=\"fa-solid fa-ban\"></i> Skip\n </button>\n } @else {\n <span class=\"match-status-badge\"\n [class.status-approved]=\"match.Match.ApprovalStatus === 'Approved'\"\n [class.status-rejected]=\"match.Match.ApprovalStatus === 'Rejected'\">\n <i class=\"fa-solid\" [class.fa-check]=\"match.Match.ApprovalStatus === 'Approved'\"\n [class.fa-times]=\"match.Match.ApprovalStatus === 'Rejected'\"></i>\n {{ match.Match.ApprovalStatus === 'Rejected' ? 'Skipped' : match.Match.ApprovalStatus }}\n </span>\n @if (match.Match.ApprovalStatus === 'Rejected') {\n <button class=\"match-action-btn match-undo-btn\"\n title=\"Undo skip\"\n (click)=\"UndoRejectIndividualMatch(match)\">\n <i class=\"fa-solid fa-undo\"></i> Undo\n </button>\n }\n }\n </div>\n </div>\n }\n\n <!-- Field rows -->\n @for (field of GetVisibleFields(); track field.FieldName; let odd = $odd) {\n <!-- Label cell -->\n <div class=\"grid-label-cell\" [class.grid-row-odd]=\"odd\">\n {{ field.DisplayName }}\n </div>\n <!-- Source value cell -->\n <div class=\"grid-value-cell grid-source-cell\"\n [class.grid-row-odd]=\"odd\"\n [class.has-diff-in-row]=\"field.HasDifference\"\n [class.field-selected]=\"field.SelectedColumnIndex === 0\"\n (click)=\"SelectFieldValue(field, 0)\">\n @if (field.SourceValue != null) {\n {{ field.SourceValue }}\n } @else {\n <span class=\"field-not-available\">(not available)</span>\n }\n @if (field.HasDifference || field.SelectedColumnIndex === 0) {\n <input type=\"radio\" [name]=\"'field-' + field.FieldName\" class=\"field-select-radio\"\n [checked]=\"field.SelectedColumnIndex === 0\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"SelectFieldValue(field, 0)\">\n }\n </div>\n <!-- Match value cells -->\n @for (matchVal of field.MatchValues; track $index; let mi = $index) {\n <div class=\"grid-value-cell\"\n [class.grid-row-odd]=\"odd\"\n [class.value-same]=\"AreValuesEqual(field.SourceValue, matchVal)\"\n [class.value-different]=\"matchVal != null && field.SourceValue != null && !AreValuesEqual(field.SourceValue, matchVal)\"\n [class.field-selected]=\"field.SelectedColumnIndex === mi + 1\"\n (click)=\"matchVal != null ? SelectFieldValue(field, mi + 1) : null\">\n @if (matchVal != null) {\n {{ matchVal }}\n @if (field.HasDifference || field.SelectedColumnIndex === mi + 1) {\n <input type=\"radio\" [name]=\"'field-' + field.FieldName\" class=\"field-select-radio\"\n [checked]=\"field.SelectedColumnIndex === mi + 1\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"SelectFieldValue(field, mi + 1)\">\n }\n } @else {\n <span class=\"field-not-available\">(not available)</span>\n }\n </div>\n }\n }\n </div>\n </div>\n\n <!-- Footer -->\n <div class=\"comparison-footer\">\n <div class=\"comparison-footer-left\">\n <span class=\"comparison-summary\">\n Showing {{ GetVisibleFields().length }} of {{ ComparisonFields.length }} fields\n </span>\n <span class=\"merge-summary\">\n <i class=\"fa-solid fa-code-merge\"></i>\n Surviving: <strong>{{ SurvivorName() }}</strong>\n @if (CherryPickedCount() > 0) {\n &middot; {{ CherryPickedCount() }} field{{ CherryPickedCount() !== 1 ? 's' : '' }} cherry-picked\n }\n </span>\n </div>\n <div class=\"comparison-footer-right\">\n <button class=\"action-btn reject-btn\" [disabled]=\"IsSaving\"\n (click)=\"RejectMatch(ComparisonGroup!); CloseComparison()\">\n <i class=\"fa-solid fa-times\"></i> Reject All\n </button>\n <button class=\"action-btn merge-btn\" [disabled]=\"IsSaving || !HasMergeableMatches || !MergeEnabled\"\n (click)=\"OpenMergeConfirm()\"\n [title]=\"!MergeEnabled ? 'Merging is not enabled for this entity' : HasMergeableMatches ? 'Merge non-skipped records' : 'All matches have been skipped'\">\n <i class=\"fa-solid fa-code-merge\"></i> Merge Records\n </button>\n @if (!MergeEnabled) {\n <span class=\"merge-disabled-hint\"><i class=\"fa-solid fa-info-circle\"></i> Merging disabled for this entity</span>\n }\n </div>\n </div>\n </div>\n }\n\n <!-- \u2550\u2550\u2550 Merge Confirmation Panel \u2550\u2550\u2550 -->\n @if (ShowMergeConfirm && ComparisonGroup) {\n <div class=\"merge-confirm-backdrop\" (click)=\"CloseMergeConfirm()\">\n <div class=\"merge-confirm-panel\" (click)=\"$event.stopPropagation()\">\n <div class=\"merge-confirm-header\">\n <div class=\"merge-confirm-icon\"><i class=\"fa-solid fa-code-merge\"></i></div>\n <div>\n <div class=\"merge-confirm-title\">Confirm Record Merge</div>\n <div class=\"merge-confirm-subtitle\">This action cannot be undone. Please review carefully.</div>\n </div>\n </div>\n\n <div class=\"merge-confirm-body\">\n <!-- Surviving Record -->\n <div class=\"merge-survivor-card\">\n <div class=\"merge-survivor-label\"><i class=\"fa-solid fa-shield-halved\"></i> Surviving Record</div>\n <div class=\"merge-survivor-name\">{{ SurvivorName() }}</div>\n <div class=\"merge-survivor-pk\">\n <i class=\"fa-solid fa-key\"></i>\n {{ SurvivorKeyDisplay() }}\n </div>\n <div class=\"merge-survivor-detail\">This record's ID will be retained. All dependencies from merged records will be transferred here.</div>\n </div>\n\n <!-- Cherry-picked field overrides -->\n @if (GetCherryPickedFields().length > 0) {\n <div>\n <div class=\"merge-section-label\">Field Value Overrides ({{ GetCherryPickedFields().length }} field{{ GetCherryPickedFields().length !== 1 ? 's' : '' }})</div>\n @for (field of GetCherryPickedFields(); track field.FieldName) {\n <div class=\"merge-field-override\">\n <span class=\"merge-field-name\">{{ field.DisplayName }}</span>\n <span class=\"merge-field-value\">\"{{ field.Value }}\"</span>\n <span class=\"merge-field-source\">from {{ field.SourceName }}</span>\n </div>\n }\n </div>\n }\n\n <!-- Dependency transfer -->\n @if (GetNonSurvivorColumns().length > 0) {\n <div class=\"merge-deps-transfer\">\n <div class=\"merge-deps-transfer-label\"><i class=\"fa-solid fa-arrow-right-arrow-left\"></i> Dependencies to Transfer</div>\n @for (col of GetNonSurvivorColumns(); track col.ColumnIndex) {\n <div class=\"merge-deps-transfer-row\">\n <i class=\"fa-solid fa-arrow-right\"></i>\n <span>\n @if (col.DepCount > 0) {\n <strong>{{ col.DepCount }}</strong> {{ col.DepCount === 1 ? 'dependency' : 'dependencies' }} from <strong>{{ col.Name }}</strong> &rarr; {{ SurvivorName() }}\n } @else {\n <strong>0</strong> dependencies from <strong>{{ col.Name }}</strong>\n }\n </span>\n </div>\n }\n </div>\n }\n\n <!-- Records to be deleted -->\n <div class=\"merge-delete-card\">\n <div class=\"merge-delete-label\"><i class=\"fa-solid fa-trash\"></i> Records to Delete After Merge</div>\n @for (col of GetNonSurvivorColumns(); track col.ColumnIndex) {\n <div class=\"merge-delete-item\">\n <span class=\"merge-delete-name\">{{ col.Name }}</span>\n <span class=\"merge-delete-deps\">\n @if (col.DepCount > 0) {\n {{ col.DepCount }} dep{{ col.DepCount !== 1 ? 's' : '' }} transferring\n } @else {\n no deps\n }\n </span>\n </div>\n }\n </div>\n </div>\n\n <div class=\"merge-confirm-footer\">\n <button class=\"action-btn cancel-btn\" (click)=\"CloseMergeConfirm()\" [disabled]=\"IsMerging\">\n <i class=\"fa-solid fa-arrow-left\"></i> Back\n </button>\n <button class=\"action-btn confirm-merge-btn\" (click)=\"ExecuteMerge()\" [disabled]=\"IsMerging\">\n @if (IsMerging) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Merging...\n } @else {\n <i class=\"fa-solid fa-code-merge\"></i> Confirm Merge ({{ GetNonSurvivorColumns().length + 1 }} records &rarr; 1)\n }\n </button>\n </div>\n </div>\n </div>\n }\n\n</div>\n", styles: ["/* ============================================================\n Duplicate Detection Kanban Board - Resource Component Styles\n All colors use MJ design tokens (--mj-*) exclusively.\n ============================================================ */\n\napp-duplicate-detection-resource {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n}\n\n.duplicate-detection-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n padding: 16px 20px;\n background: var(--mj-bg-page);\n position: relative;\n overflow: hidden;\n}\n\n/* ---- Page Header ---- */\n\n.page-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 16px;\n flex-shrink: 0;\n}\n\n.page-title {\n margin: 0;\n font-size: 20px;\n font-weight: 600;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.page-title i {\n color: var(--mj-brand-primary);\n}\n\n/* ---- Header Actions ---- */\n\n.header-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.run-detection-controls {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.entity-doc-select {\n padding: 8px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n min-width: 200px;\n}\n\n.entity-doc-select:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.run-detection-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border: none;\n border-radius: 6px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n cursor: pointer;\n font-size: 13px;\n font-weight: 600;\n transition: background 0.15s;\n white-space: nowrap;\n}\n\n.run-detection-btn:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n.run-detection-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n/* ---- Detection Progress ---- */\n\n.detection-progress-section {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-brand-primary);\n border-radius: 8px;\n padding: 14px 18px;\n margin-bottom: 16px;\n flex-shrink: 0;\n}\n\n.progress-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 8px;\n}\n\n.progress-stage {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-brand-primary);\n}\n\n.progress-percent {\n font-size: 13px;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.progress-bar-track {\n height: 6px;\n border-radius: 3px;\n background: var(--mj-bg-surface-sunken);\n overflow: hidden;\n}\n\n.progress-bar-fill {\n height: 100%;\n border-radius: 3px;\n background: var(--mj-brand-primary);\n transition: width 0.3s ease;\n}\n\n.progress-current-item {\n display: block;\n margin-top: 6px;\n font-size: 11px;\n color: var(--mj-text-muted);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* ---- Threshold Controls ---- */\n\n.threshold-controls {\n display: flex;\n gap: 24px;\n padding: 12px 16px;\n border-radius: 8px;\n background: color-mix(in srgb, var(--mj-status-info) 6%, var(--mj-bg-surface));\n border: 1px solid var(--mj-border-subtle);\n margin-bottom: 16px;\n flex-shrink: 0;\n}\n\n.threshold-slider-group {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.threshold-label {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 0.82rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.threshold-value {\n margin-left: auto;\n font-weight: 700;\n color: var(--mj-brand-primary);\n font-size: 0.85rem;\n}\n\n.threshold-slider {\n width: 100%;\n height: 4px;\n appearance: none;\n -webkit-appearance: none;\n background: var(--mj-border-default);\n border-radius: 2px;\n outline: none;\n cursor: pointer;\n}\n\n.threshold-slider::-webkit-slider-thumb {\n -webkit-appearance: none;\n width: 14px;\n height: 14px;\n border-radius: 50%;\n background: var(--mj-brand-primary);\n border: 2px solid var(--mj-bg-surface);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n cursor: pointer;\n}\n\n.threshold-slider::-moz-range-thumb {\n width: 14px;\n height: 14px;\n border-radius: 50%;\n background: var(--mj-brand-primary);\n border: 2px solid var(--mj-bg-surface);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n cursor: pointer;\n}\n\n.threshold-slider:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n\n.threshold-hint {\n font-size: 0.72rem;\n color: var(--mj-text-muted);\n}\n\n/* ---- Threshold Info (legacy) ---- */\n\n.threshold-info {\n display: flex;\n gap: 16px;\n padding: 8px 14px;\n border-radius: 6px;\n background: color-mix(in srgb, var(--mj-status-info) 8%, var(--mj-bg-surface));\n border: 1px solid var(--mj-status-info-border);\n margin-bottom: 16px;\n flex-shrink: 0;\n}\n\n.threshold-item {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: var(--mj-status-info-text);\n font-weight: 500;\n}\n\n.threshold-item i {\n font-size: 11px;\n}\n\n/* ---- KPI Strip ---- */\n\n.kpi-strip {\n display: flex;\n gap: 12px;\n margin-bottom: 16px;\n flex-shrink: 0;\n}\n\n.kpi-card {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 12px 16px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n}\n\n.kpi-value {\n font-size: 28px;\n font-weight: 700;\n color: var(--mj-text-primary);\n line-height: 1.2;\n}\n\n.kpi-label {\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-top: 2px;\n}\n\n.kpi-pending .kpi-value {\n color: var(--mj-status-warning);\n}\n\n.kpi-approved .kpi-value {\n color: var(--mj-status-success);\n}\n\n.kpi-rejected .kpi-value {\n color: var(--mj-status-error);\n}\n\n/* ---- Filter Bar ---- */\n\n.filter-bar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n margin-bottom: 16px;\n flex-shrink: 0;\n}\n\n.filter-group {\n display: flex;\n align-items: flex-end;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n.filter-select {\n height: 34px;\n padding: 4px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n outline: none;\n min-width: 160px;\n}\n\n.filter-select:focus {\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.filter-range {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.filter-label {\n font-size: 11px;\n font-weight: 500;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n.filter-input {\n height: 34px;\n padding: 4px 8px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n outline: none;\n width: 100px;\n}\n\n.filter-input-score {\n width: 80px;\n}\n\n.filter-input-date {\n width: 140px;\n}\n\n.filter-input:focus {\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.clear-filters-btn {\n display: flex;\n align-items: center;\n gap: 4px;\n height: 34px;\n padding: 0 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 13px;\n cursor: pointer;\n white-space: nowrap;\n}\n\n.clear-filters-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n/* ---- Loading & Empty States ---- */\n\n.loading-container {\n display: flex;\n align-items: center;\n justify-content: center;\n flex: 1;\n min-height: 200px;\n}\n\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n flex: 1;\n min-height: 200px;\n gap: 8px;\n}\n\n.empty-icon {\n font-size: 48px;\n color: var(--mj-text-disabled);\n}\n\n.empty-text {\n font-size: 16px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n.empty-subtext {\n font-size: 13px;\n color: var(--mj-text-muted);\n margin: 0;\n}\n\n/* ---- Kanban Board ---- */\n\n.kanban-board {\n display: flex;\n gap: 16px;\n flex: 1;\n min-height: 0;\n overflow-x: auto;\n}\n\n.kanban-column {\n flex: 1;\n min-width: 280px;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 10px;\n overflow: hidden;\n}\n\n.column-header {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 16px;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n border-bottom: 1px solid var(--mj-border-subtle);\n flex-shrink: 0;\n}\n\n.column-header-pending {\n background: color-mix(in srgb, var(--mj-status-warning) 8%, var(--mj-bg-surface));\n}\n\n.column-header-pending i {\n color: var(--mj-status-warning);\n}\n\n.column-header-approved {\n background: color-mix(in srgb, var(--mj-status-success) 8%, var(--mj-bg-surface));\n}\n\n.column-header-approved i {\n color: var(--mj-status-success);\n}\n\n.column-header-rejected {\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--mj-bg-surface));\n}\n\n.column-header-rejected i {\n color: var(--mj-status-error);\n}\n\n.column-title {\n flex: 1;\n}\n\n.column-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 24px;\n height: 24px;\n padding: 0 6px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 600;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.column-body {\n flex: 1;\n overflow-y: auto;\n padding: 12px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.column-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 6px;\n padding: 32px 16px;\n color: var(--mj-text-disabled);\n font-size: 13px;\n}\n\n.column-empty i {\n font-size: 24px;\n}\n\n/* ---- Kanban Cards ---- */\n\n.kanban-card {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n transition: box-shadow 0.15s ease, border-color 0.15s ease;\n flex-shrink: 0; /* Prevent cards from shrinking \u2014 column scrolls instead */\n}\n\n.kanban-card:hover {\n border-color: var(--mj-border-strong);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-text-primary) 8%, transparent);\n}\n\n/* Drag and Drop */\n.kanban-card[draggable=\"true\"] {\n cursor: grab;\n}\n\n.kanban-card[draggable=\"true\"]:active {\n cursor: grabbing;\n}\n\n.drop-target-active {\n outline: 2px dashed var(--mj-brand-primary);\n outline-offset: -2px;\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface-card)) !important;\n}\n\n.drop-target-active .column-body {\n min-height: 100px;\n}\n\n.card-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n padding: 10px 12px;\n border-bottom: 1px solid var(--mj-border-subtle);\n gap: 8px;\n}\n\n.card-header-left {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n min-width: 0;\n flex: 1;\n}\n\n.card-icon {\n width: 2rem;\n height: 2rem;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 6px;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 0.85rem;\n flex-shrink: 0;\n}\n\n.card-title-block {\n min-width: 0;\n flex: 1;\n}\n\n.card-record-name {\n font-size: 0.85rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n margin-bottom: 2px;\n}\n\n.entity-badge {\n display: inline-flex;\n align-items: center;\n padding: 1px 6px;\n border-radius: 3px;\n font-size: 10px;\n font-weight: 500;\n color: var(--mj-text-muted);\n letter-spacing: 0.2px;\n}\n\n/* Score indicator colors */\n\n.score-indicator {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 40px;\n padding: 2px 8px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 700;\n}\n\n.score-high {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success-text);\n border: 1px solid var(--mj-status-success-border);\n}\n\n.score-medium {\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning-text);\n border: 1px solid var(--mj-status-warning-border);\n}\n\n.score-low {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error-text);\n border: 1px solid var(--mj-status-error-border);\n}\n\n.card-body {\n padding: 10px 12px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.match-summaries {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.match-summary-row {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n}\n\n.match-score {\n flex-shrink: 0;\n font-weight: 600;\n font-size: 11px;\n color: var(--mj-text-muted);\n min-width: 30px;\n}\n\n.match-name {\n color: var(--mj-text-secondary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.match-summary-more {\n font-size: 11px;\n color: var(--mj-text-muted);\n font-style: italic;\n padding-left: 38px;\n}\n\n.card-meta-row {\n display: flex;\n align-items: center;\n gap: 12px;\n font-size: 11px;\n color: var(--mj-text-muted);\n border-top: 1px solid var(--mj-border-subtle);\n padding-top: 6px;\n}\n\n.card-meta-item {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.card-meta-item i {\n font-size: 10px;\n}\n font-size: 12px;\n max-width: 180px;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n Comparison Slide-In Panel\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.slide-backdrop {\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n z-index: 9999;\n animation: fadeIn 0.2s ease;\n}\n\n.slide-backdrop.comparison-closing {\n animation: fadeOut 0.25s ease forwards;\n}\n\n@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }\n@keyframes fadeOut { from { opacity: 1; } to { opacity: 0; } }\n\n.comparison-panel {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n width: 82vw;\n max-width: 1300px;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n box-shadow: -8px 0 40px rgba(0,0,0,0.4);\n z-index: 10000;\n display: flex;\n flex-direction: column;\n animation: slideIn 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n}\n\n.comparison-panel.comparison-closing {\n animation: slideOut 0.25s cubic-bezier(0.4, 0, 0.2, 1) forwards;\n}\n\n@keyframes slideIn { from { transform: translateX(100%); } to { transform: translateX(0); } }\n@keyframes slideOut { from { transform: translateX(0); } to { transform: translateX(100%); } }\n\n/* Header */\n.comparison-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 14px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n gap: 12px;\n}\n\n.comparison-header-left {\n display: flex;\n align-items: center;\n gap: 12px;\n min-width: 0;\n}\n\n.comparison-entity-icon {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 1rem;\n flex-shrink: 0;\n}\n\n.comparison-title {\n font-size: 1rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.comparison-entity-badge {\n display: inline-block;\n padding: 1px 7px;\n border-radius: 10px;\n font-size: 0.65rem;\n font-weight: 500;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n margin-right: 6px;\n}\n\n.comparison-match-count {\n font-size: 0.72rem;\n color: var(--mj-text-muted);\n}\n\n.comparison-header-right {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-shrink: 0;\n}\n\n/* Toggle */\n.comparison-toggle {\n display: flex;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n overflow: hidden;\n}\n\n.toggle-btn {\n padding: 5px 12px;\n font-size: 0.7rem;\n font-weight: 500;\n border: none;\n cursor: pointer;\n transition: all 0.15s ease;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n}\n\n.toggle-btn:first-child {\n border-right: 1px solid var(--mj-border-default);\n}\n\n.toggle-btn.toggle-active {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.comparison-close-btn {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n font-size: 0.85rem;\n transition: all 0.15s ease;\n}\n\n.comparison-close-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n/* Loading state */\n.comparison-loading {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n/* Grid wrapper */\n.comparison-grid-wrapper {\n flex: 1;\n overflow: auto;\n min-height: 0;\n}\n\n/* Grid */\n.comparison-grid {\n display: grid;\n min-width: 100%;\n}\n\n.comparison-grid > div {\n padding: 8px 12px;\n font-size: 0.78rem;\n border-bottom: 1px solid var(--mj-border-subtle);\n border-right: 1px solid var(--mj-border-subtle);\n}\n\n/* Corner cell */\n.grid-corner-cell {\n position: sticky;\n top: 0;\n left: 0;\n z-index: 4;\n background: var(--mj-bg-surface-elevated);\n font-size: 0.65rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--mj-text-muted);\n display: flex;\n align-items: flex-end;\n padding-bottom: 6px;\n}\n\n/* Column headers */\n.grid-col-header {\n position: sticky;\n top: 0;\n z-index: 3;\n background: var(--mj-bg-surface-elevated);\n padding: 10px 12px;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.grid-col-source {\n border-left: 3px solid var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, var(--mj-bg-surface-elevated));\n}\n\n.col-header-label {\n font-size: 0.6rem;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--mj-brand-primary);\n}\n\n.col-header-top {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 6px;\n}\n\n.col-header-name {\n font-size: 0.82rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.col-header-diff-count {\n font-size: 0.65rem;\n color: var(--mj-status-warning-text);\n}\n\n/* Surviving record selector */\n.surviving-selector {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-top: 4px;\n}\n\n.surviving-radio {\n appearance: none;\n width: 14px;\n height: 14px;\n border: 2px solid var(--mj-border-strong);\n border-radius: 50%;\n cursor: pointer;\n transition: all 0.15s ease;\n flex-shrink: 0;\n}\n\n.surviving-radio:checked {\n border-color: var(--mj-brand-primary);\n background: var(--mj-brand-primary);\n box-shadow: inset 0 0 0 2px var(--mj-bg-surface-elevated);\n}\n\n.surviving-label {\n font-size: 0.65rem;\n color: var(--mj-text-muted);\n cursor: pointer;\n}\n\n.surviving-label.is-survivor {\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n/* Use all fields button */\n.use-all-btn {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 3px 8px;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 0.62rem;\n cursor: pointer;\n transition: all 0.12s ease;\n margin-top: 2px;\n}\n\n.use-all-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.use-all-btn.all-selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n}\n\n/* Per-match actions */\n.comparison-match-actions {\n display: flex;\n gap: 4px;\n margin-top: 3px;\n}\n\n.action-btn-sm {\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: 1px solid;\n border-radius: 5px;\n cursor: pointer;\n font-size: 0.65rem;\n transition: all 0.15s ease;\n}\n\n.approve-btn-sm {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success-text);\n border-color: var(--mj-status-success-border);\n}\n.approve-btn-sm:hover { background: rgba(34,197,94,0.25); }\n\n.reject-btn-sm {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error-text);\n border-color: var(--mj-status-error-border);\n}\n.reject-btn-sm:hover { background: rgba(239,68,68,0.25); }\n\n.match-status-badge {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 0.68rem;\n font-weight: 500;\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.status-approved {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success-text);\n}\n\n.status-rejected {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error-text);\n}\n\n.match-approval-actions {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-top: 6px;\n}\n\n.match-action-btn {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 3px 10px;\n border-radius: 6px;\n font-size: 0.7rem;\n font-weight: 500;\n border: 1px solid var(--mj-border-default);\n cursor: pointer;\n transition: background 0.15s ease, border-color 0.15s ease;\n}\n\n.match-skip-btn {\n background: var(--mj-bg-surface);\n color: var(--mj-status-error);\n border-color: color-mix(in srgb, var(--mj-status-error) 30%, var(--mj-border-default));\n}\n\n.match-skip-btn:hover {\n background: var(--mj-status-error-bg);\n border-color: var(--mj-status-error);\n}\n\n.match-undo-btn {\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n}\n\n.match-undo-btn:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-border-strong);\n}\n\n.match-approved {\n border-top: 3px solid var(--mj-status-success);\n}\n\n.match-rejected {\n border-top: 3px solid var(--mj-status-error);\n opacity: 0.6;\n}\n\n/* Label cells */\n.grid-label-cell {\n position: sticky;\n left: 0;\n z-index: 2;\n background: var(--mj-bg-surface);\n font-size: 0.72rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n display: flex;\n align-items: center;\n}\n\n.grid-row-odd {\n background: color-mix(in srgb, var(--mj-bg-surface-sunken) 50%, var(--mj-bg-surface));\n}\n\n.grid-label-cell.grid-row-odd {\n background: color-mix(in srgb, var(--mj-bg-surface-sunken) 50%, var(--mj-bg-surface));\n}\n\n/* Value cells */\n.grid-value-cell {\n font-size: 0.78rem;\n color: var(--mj-text-primary);\n line-height: 1.45;\n word-break: break-word;\n position: relative;\n cursor: pointer;\n}\n\n.grid-source-cell {\n background: color-mix(in srgb, var(--mj-brand-primary) 3%, var(--mj-bg-surface));\n border-left: 3px solid transparent;\n}\n\n.grid-source-cell.grid-row-odd {\n background: color-mix(in srgb, var(--mj-brand-primary) 3%, color-mix(in srgb, var(--mj-bg-surface-sunken) 50%, var(--mj-bg-surface)));\n}\n\n.grid-source-cell.has-diff-in-row {\n font-weight: 600;\n}\n\n/* Diff highlighting */\n.value-same {\n color: var(--mj-text-muted);\n}\n\n.value-different {\n background: color-mix(in srgb, var(--mj-status-warning) 8%, transparent) !important;\n border-left: 3px solid var(--mj-status-warning);\n color: var(--mj-text-primary);\n}\n\n.field-not-available {\n font-style: italic;\n font-size: 0.72rem;\n color: var(--mj-text-disabled);\n}\n\n/* Field selection radio */\n.field-select-radio {\n position: absolute;\n top: 50%;\n right: 8px;\n transform: translateY(-50%);\n appearance: none;\n width: 16px;\n height: 16px;\n border: 2px solid var(--mj-border-strong);\n border-radius: 50%;\n cursor: pointer;\n transition: all 0.12s ease;\n opacity: 0.4;\n}\n\n.field-select-radio:hover {\n opacity: 0.8;\n}\n\n.field-select-radio:checked {\n border-color: var(--mj-brand-primary);\n background: var(--mj-brand-primary);\n box-shadow: inset 0 0 0 2.5px var(--mj-bg-surface);\n opacity: 1;\n}\n\n.grid-value-cell.field-selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface)) !important;\n border-left: 3px solid var(--mj-brand-primary);\n}\n\n.grid-value-cell.field-selected .field-select-radio {\n opacity: 1;\n}\n\n/* Footer */\n.comparison-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 20px;\n border-top: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.comparison-footer-left {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n.comparison-summary {\n font-size: 0.72rem;\n color: var(--mj-text-muted);\n}\n\n.merge-summary {\n font-size: 0.72rem;\n color: var(--mj-brand-primary);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.merge-summary i {\n font-size: 0.65rem;\n}\n\n.comparison-footer-right {\n display: flex;\n gap: 8px;\n}\n\n.comparison-footer-right .action-btn {\n flex: none;\n padding: 7px 14px;\n}\n\n.merge-btn {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-color: var(--mj-brand-primary);\n}\n\n.merge-btn:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n.card-actions {\n display: flex;\n gap: 8px;\n padding: 10px 12px;\n border-top: 1px solid var(--mj-border-subtle);\n}\n\n.action-btn {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n height: 32px;\n padding: 0 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: background 0.15s ease, border-color 0.15s ease;\n}\n\n.action-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.approve-btn {\n background: color-mix(in srgb, var(--mj-status-success) 10%, var(--mj-bg-surface));\n color: var(--mj-status-success-text);\n border-color: var(--mj-status-success-border);\n}\n\n.approve-btn:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-status-success) 20%, var(--mj-bg-surface));\n}\n\n.reject-btn {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n color: var(--mj-status-error-text);\n border-color: var(--mj-status-error-border);\n}\n\n.reject-btn:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-status-error) 20%, var(--mj-bg-surface));\n}\n\n/* ---- Responsive ---- */\n\n@media (max-width: 768px) {\n .kanban-board {\n flex-direction: column;\n }\n\n .kanban-column {\n min-width: auto;\n max-height: 400px;\n }\n}\n\n@media (max-width: 480px) {\n .kpi-strip {\n flex-direction: column;\n }\n\n .filter-bar {\n flex-wrap: wrap;\n }\n\n .filter-group {\n flex-direction: column;\n align-items: stretch;\n width: 100%;\n }\n\n .filter-select {\n min-width: auto;\n width: 100%;\n }\n\n .filter-input {\n width: 100%;\n }\n\n .card-actions {\n flex-direction: column;\n }\n\n .action-btn {\n width: 100%;\n }\n}\n\n/* ---- Saving Overlay ---- */\n\n.saving-overlay {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-bg-overlay);\n z-index: 10;\n border-radius: 8px;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n Dependencies Summary (in column headers)\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.deps-summary {\n margin-top: 6px;\n padding: 6px 8px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 6px;\n font-size: 0.68rem;\n}\n\n.deps-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n cursor: pointer;\n color: var(--mj-text-secondary);\n font-weight: 600;\n}\n\n.deps-header i {\n font-size: 0.6rem;\n color: var(--mj-text-muted);\n}\n\n.deps-header:hover {\n color: var(--mj-text-primary);\n}\n\n.deps-total {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 0.72rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin-bottom: 2px;\n}\n\n.deps-total i {\n font-size: 0.65rem;\n color: var(--mj-text-muted);\n}\n\n.deps-total-number {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n padding: 0 6px;\n border-radius: 8px;\n font-size: 0.7rem;\n font-weight: 700;\n}\n\n.deps-total-recommended {\n font-size: 0.58rem;\n color: var(--mj-status-success-text);\n font-weight: 600;\n margin-left: 4px;\n}\n\n.deps-total-recommended i {\n color: var(--mj-status-success-text);\n}\n\n.deps-detail-list {\n margin-top: 4px;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.deps-detail-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 3px 0;\n font-size: 0.65rem;\n color: var(--mj-text-muted);\n cursor: pointer;\n border-radius: 3px;\n transition: background 0.1s ease;\n}\n\n.deps-detail-row:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.deps-detail-entity {\n display: flex;\n align-items: center;\n gap: 4px;\n color: var(--mj-text-secondary);\n}\n\n.deps-expand-icon {\n font-size: 0.5rem;\n width: 10px;\n text-align: center;\n color: var(--mj-text-muted);\n}\n\n/* Individual dependency records list */\n.deps-records-list {\n padding-left: 14px;\n margin-bottom: 2px;\n}\n\n.deps-record-row {\n display: flex;\n align-items: center;\n gap: 5px;\n padding: 2px 4px;\n font-size: 0.6rem;\n color: var(--mj-text-muted);\n cursor: pointer;\n border-radius: 3px;\n transition: color 0.1s ease, background 0.1s ease;\n}\n\n.deps-record-row:hover {\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n}\n\n.deps-record-icon {\n font-size: 0.5rem;\n flex-shrink: 0;\n}\n\n.deps-record-name {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 0.6rem;\n}\n\n.deps-record-loading {\n padding: 3px 4px;\n font-size: 0.6rem;\n color: var(--mj-text-muted);\n}\n\n.deps-record-loading i {\n margin-right: 4px;\n}\n\n.deps-detail-count {\n color: var(--mj-text-primary);\n font-weight: 600;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n Merge Confirmation Panel\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.merge-confirm-backdrop {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.3);\n z-index: 20000;\n animation: fadeIn 0.2s ease;\n}\n\n.merge-confirm-panel {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n width: 520px;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n box-shadow: -8px 0 40px rgba(0, 0, 0, 0.4);\n z-index: 20001;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n animation: slideIn 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.merge-confirm-header {\n padding: 18px 24px;\n border-bottom: 1px solid var(--mj-border-default);\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.merge-confirm-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 10px;\n background: color-mix(in srgb, var(--mj-status-warning) 12%, var(--mj-bg-surface));\n color: var(--mj-status-warning-text);\n font-size: 1.1rem;\n flex-shrink: 0;\n}\n\n.merge-confirm-title {\n font-size: 1.05rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.merge-confirm-subtitle {\n font-size: 0.75rem;\n color: var(--mj-text-muted);\n margin-top: 2px;\n}\n\n.merge-confirm-body {\n padding: 20px 24px;\n overflow-y: auto;\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n/* Surviving record card */\n\n.merge-survivor-card {\n padding: 14px;\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, var(--mj-bg-surface));\n border: 1px solid var(--mj-brand-primary);\n border-radius: 8px;\n}\n\n.merge-survivor-label {\n font-size: 0.65rem;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--mj-brand-primary);\n margin-bottom: 4px;\n}\n\n.merge-survivor-label i {\n margin-right: 4px;\n}\n\n.merge-survivor-name {\n font-size: 0.95rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.merge-survivor-pk {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-top: 4px;\n padding: 4px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border-radius: 4px;\n font-size: 0.68rem;\n font-family: monospace;\n color: var(--mj-text-secondary);\n}\n\n.merge-survivor-pk i {\n font-size: 0.6rem;\n color: var(--mj-brand-primary);\n}\n\n.merge-survivor-detail {\n font-size: 0.72rem;\n color: var(--mj-text-muted);\n margin-top: 4px;\n}\n\n/* Cherry-picked fields section */\n\n.merge-section-label {\n font-size: 0.7rem;\n font-weight: 700;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n margin-bottom: 6px;\n}\n\n.merge-field-override {\n display: flex;\n align-items: baseline;\n gap: 8px;\n padding: 6px 0;\n border-bottom: 1px solid var(--mj-border-subtle);\n font-size: 0.78rem;\n}\n\n.merge-field-name {\n font-weight: 600;\n color: var(--mj-text-secondary);\n min-width: 110px;\n flex-shrink: 0;\n}\n\n.merge-field-value {\n color: var(--mj-text-primary);\n}\n\n.merge-field-source {\n font-size: 0.65rem;\n color: var(--mj-text-muted);\n margin-left: auto;\n white-space: nowrap;\n}\n\n/* Dependency transfer summary */\n\n.merge-deps-transfer {\n padding: 10px 14px;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n}\n\n.merge-deps-transfer-label {\n font-size: 0.65rem;\n font-weight: 700;\n text-transform: uppercase;\n color: var(--mj-brand-primary);\n margin-bottom: 6px;\n}\n\n.merge-deps-transfer-label i {\n margin-right: 4px;\n}\n\n.merge-deps-transfer-row {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 3px 0;\n font-size: 0.75rem;\n color: var(--mj-text-secondary);\n}\n\n.merge-deps-transfer-row i {\n color: var(--mj-brand-primary);\n font-size: 0.65rem;\n width: 14px;\n text-align: center;\n}\n\n/* Records to delete */\n\n.merge-delete-card {\n padding: 10px 14px;\n background: color-mix(in srgb, var(--mj-status-error) 5%, var(--mj-bg-surface));\n border: 1px solid var(--mj-status-error-border);\n border-radius: 8px;\n}\n\n.merge-delete-label {\n font-size: 0.65rem;\n font-weight: 700;\n text-transform: uppercase;\n color: var(--mj-status-error-text);\n margin-bottom: 6px;\n}\n\n.merge-delete-label i {\n margin-right: 4px;\n}\n\n.merge-delete-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 5px 0;\n font-size: 0.78rem;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.merge-delete-item:last-child {\n border-bottom: none;\n}\n\n.merge-delete-name {\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.merge-delete-deps {\n font-size: 0.65rem;\n color: var(--mj-text-muted);\n}\n\n/* Confirm footer */\n\n.merge-confirm-footer {\n padding: 14px 24px;\n border-top: 1px solid var(--mj-border-default);\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 10px;\n}\n\n.cancel-btn {\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n border-color: var(--mj-border-default);\n}\n\n.cancel-btn:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.confirm-merge-btn {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.confirm-merge-btn:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n.confirm-merge-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n/* ---- Responsive: Merge Confirm ---- */\n\n@media (max-width: 600px) {\n .merge-confirm-panel {\n width: 100%;\n }\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550 Merge Disabled Hint \u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.merge-disabled-hint {\n font-size: 11.5px;\n color: var(--mj-status-warning-text, #e65100);\n display: inline-flex;\n align-items: center;\n gap: 4px;\n margin-left: 4px;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550 Merge Warning Banner (inline, non-blocking) \u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.merge-warning-banner {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n margin-bottom: 12px;\n border-radius: 6px;\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning-text);\n border: 1px solid var(--mj-status-warning-border);\n font-size: 13px;\n font-weight: 500;\n flex-shrink: 0;\n}\n\n.merge-warning-banner i {\n font-size: 14px;\n flex-shrink: 0;\n}\n"] }]
2940
+ }], null, { OnEscapeKey: [{
2941
+ type: HostListener,
2942
+ args: ['document:keydown.escape']
2943
+ }], EmbeddedMode: [{
2677
2944
  type: Input
2678
2945
  }] }); })();
2679
2946
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(DuplicateDetectionResourceComponent, { className: "DuplicateDetectionResourceComponent", filePath: "src/AI/components/duplicates/duplicate-detection-resource.component.ts", lineNumber: 105 }); })();