jupiter-dynamic-forms 1.16.3 → 1.16.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -607,11 +607,12 @@ class XBRLFormBuilder {
607
607
  };
608
608
  }
609
609
  /**
610
- * Build a form section from a presentation role
610
+ * Extract section title from role name (remove role number prefix)
611
+ * Handle missing role property gracefully by using role ID as fallback
611
612
  */
612
613
  static buildSectionFromRole(role, periodStartDate, periodEndDate, hypercubeData, language = "en", periodPreferences) {
613
- var _a;
614
- const title = this.extractRoleTitle(role.role);
614
+ var _a, _b;
615
+ const title = this.extractRoleTitle(role.role || role.id || "Unknown Role");
615
616
  const nonAbstractConcepts = this.getAllNonAbstractConcepts(role);
616
617
  const periodTypes = new Set(
617
618
  nonAbstractConcepts.filter((concept) => concept.periodType).map((concept) => concept.periodType)
@@ -634,6 +635,11 @@ class XBRLFormBuilder {
634
635
  }
635
636
  });
636
637
  }
638
+ if ((!hypercubeRole || !((_b = hypercubeRole.items) == null ? void 0 : _b.length)) && hypercubeData) {
639
+ conceptTrees.forEach(
640
+ (conceptTree) => this.applyCrossRoleDimensions(conceptTree, role.id, hypercubeData, language)
641
+ );
642
+ }
637
643
  return {
638
644
  id: role.id,
639
645
  title,
@@ -894,6 +900,73 @@ class XBRLFormBuilder {
894
900
  });
895
901
  return filtered;
896
902
  }
903
+ /**
904
+ * Find typed dimension members from another role that shares the same concept.
905
+ * Called when the current role has no hypercube dimensions.
906
+ * Returns typed member info only when EXACTLY ONE other role matches.
907
+ */
908
+ static findCrossRoleDimensions(conceptId, currentRoleId, hypercubeData, language = "en") {
909
+ var _a, _b;
910
+ const matchingRoles = [];
911
+ for (const role of hypercubeData.roles) {
912
+ if (role.roleId === currentRoleId)
913
+ continue;
914
+ for (const item2 of role.items) {
915
+ if (!((_a = item2.conceptIds) == null ? void 0 : _a.includes(conceptId)))
916
+ continue;
917
+ if (!((_b = item2.dimensions) == null ? void 0 : _b.some((d2) => d2.typedMember)))
918
+ continue;
919
+ matchingRoles.push(role);
920
+ break;
921
+ }
922
+ }
923
+ if (matchingRoles.length !== 1)
924
+ return null;
925
+ const matchingRole = matchingRoles[0];
926
+ const item = matchingRole.items.find((i2) => {
927
+ var _a2;
928
+ return (_a2 = i2.conceptIds) == null ? void 0 : _a2.includes(conceptId);
929
+ });
930
+ if (!item)
931
+ return null;
932
+ const result = [];
933
+ for (const dimension of item.dimensions) {
934
+ if (!dimension.typedMember)
935
+ continue;
936
+ const labelObj = dimension.labels.find((l2) => l2.lang === language) || dimension.labels.find((l2) => l2.lang === "en") || dimension.labels[0];
937
+ const axisLabel = (labelObj == null ? void 0 : labelObj.label) || dimension.id;
938
+ result.push({
939
+ axisId: dimension.id,
940
+ axisLabel,
941
+ typedMemberId: dimension.typedMember.id,
942
+ memberLabel: axisLabel
943
+ });
944
+ }
945
+ return result.length > 0 ? result : null;
946
+ }
947
+ /**
948
+ * Recursively walk a concept tree and set crossRoleTypedMembers on every field
949
+ * whose concept appears in exactly one other hypercube role with typed dimensions.
950
+ */
951
+ static applyCrossRoleDimensions(conceptTree, currentRoleId, hypercubeData, language) {
952
+ var _a;
953
+ if (!conceptTree.abstract && conceptTree.fields && conceptTree.fields.length > 0) {
954
+ const crossRoleTypedMembers = this.findCrossRoleDimensions(
955
+ conceptTree.originalConceptId,
956
+ currentRoleId,
957
+ hypercubeData,
958
+ language
959
+ );
960
+ if (crossRoleTypedMembers) {
961
+ conceptTree.fields.forEach((field2) => {
962
+ field2.crossRoleTypedMembers = crossRoleTypedMembers;
963
+ });
964
+ }
965
+ }
966
+ (_a = conceptTree.children) == null ? void 0 : _a.forEach(
967
+ (child) => this.applyCrossRoleDimensions(child, currentRoleId, hypercubeData, language)
968
+ );
969
+ }
897
970
  /**
898
971
  * Generate default columns based on period types of non-abstract concepts in a role
899
972
  */
@@ -1473,10 +1546,21 @@ class XBRLFormBuilder {
1473
1546
  }
1474
1547
  /**
1475
1548
  * Extract role title from role string
1549
+ * Handles various role formats and missing data gracefully
1476
1550
  */
1477
1551
  static extractRoleTitle(role) {
1552
+ if (!role)
1553
+ return "Unnamed Section";
1478
1554
  const match = role.match(/^\[[\d]+\]\s*(.+)$/);
1479
- return match ? match[1].trim() : role;
1555
+ if (match) {
1556
+ return match[1].trim();
1557
+ }
1558
+ if (role.match(/^[a-z]+:[^:]*$/i) || role.match(/^urn:[^:]+:[^:]+/i)) {
1559
+ const parts = role.split(/[:\-]/);
1560
+ const lastPart = parts[parts.length - 1];
1561
+ return lastPart.replace(/[_\-]/g, " ").replace(/\b\w/g, (l2) => l2.toUpperCase());
1562
+ }
1563
+ return role.trim() || "Unnamed Section";
1480
1564
  }
1481
1565
  /**
1482
1566
  * Extract role order from role string
@@ -2024,7 +2108,7 @@ class DraftStorageService {
2024
2108
  /**
2025
2109
  * Create metadata snapshot from current form state
2026
2110
  */
2027
- createMetadataSnapshot(periodStartDate, periodEndDate, language, selectedRoleIds, allSections, typedMemberData, periodPreferences, periodData, unitData, reportingLanguage = "en") {
2111
+ createMetadataSnapshot(periodStartDate, periodEndDate, language, selectedRoleIds, allSections, typedMemberData, periodPreferences, periodData, unitData, reportingLanguage = "en", repeatCounts) {
2028
2112
  return {
2029
2113
  periodStartDate,
2030
2114
  periodEndDate,
@@ -2037,6 +2121,7 @@ class DraftStorageService {
2037
2121
  periodPreferences,
2038
2122
  periodData,
2039
2123
  unitData,
2124
+ repeatCounts,
2040
2125
  schemaVersion: this.STORAGE_VERSION
2041
2126
  };
2042
2127
  }
@@ -2646,7 +2731,6 @@ function getInputTypeForConceptType(conceptType, datatypes) {
2646
2731
  const baseTypeChain = resolveBaseTypeChain(conceptType, datatypes);
2647
2732
  if (baseTypeChain.length > 0) {
2648
2733
  const config = determineInputTypeFromBaseChain(baseTypeChain, datatypes);
2649
- console.log(`🔍 [Type Resolution] ${conceptType} → Chain:`, baseTypeChain, "→ Type:", config.fieldType, config.enumerations ? `(${config.enumerations.length} options)` : "");
2650
2734
  return config;
2651
2735
  }
2652
2736
  }
@@ -2903,6 +2987,7 @@ let JupiterFormField = class extends LitElement {
2903
2987
  this.locale = "en-US";
2904
2988
  this.hideLabel = false;
2905
2989
  this.mode = "inputForm";
2990
+ this.typedMemberValues = {};
2906
2991
  this._errors = [];
2907
2992
  this._xbrlErrors = [];
2908
2993
  this._touched = false;
@@ -3241,6 +3326,20 @@ let JupiterFormField = class extends LitElement {
3241
3326
  periodType: this.field.periodType
3242
3327
  });
3243
3328
  }
3329
+ _handleCrossRoleTypedMemberChange(event, axisId) {
3330
+ const value = event.target.value;
3331
+ this.typedMemberValues = { ...this.typedMemberValues, [axisId]: value };
3332
+ this.dispatchEvent(new CustomEvent("typed-member-change", {
3333
+ detail: {
3334
+ columnId: this.columnId,
3335
+ conceptId: this.conceptId,
3336
+ axisId,
3337
+ value
3338
+ },
3339
+ bubbles: true,
3340
+ composed: true
3341
+ }));
3342
+ }
3244
3343
  /**
3245
3344
  * Renders a plain text label for readonly mode instead of an interactive input.
3246
3345
  * Resolves the display value for selects (shows label, not raw id) and
@@ -3498,6 +3597,21 @@ let JupiterFormField = class extends LitElement {
3498
3597
  </select>
3499
3598
  </div>
3500
3599
  ` : ""}
3600
+
3601
+ ${this.field.crossRoleTypedMembers && this.field.crossRoleTypedMembers.length > 0 ? html`
3602
+ ${this.field.crossRoleTypedMembers.map((tm) => html`
3603
+ <div class="period-controls">
3604
+ <label>${tm.axisLabel}:</label>
3605
+ <input
3606
+ type="text"
3607
+ class="typed-member-input"
3608
+ .value="${this.typedMemberValues[tm.axisId] || ""}"
3609
+ @input="${(e2) => this._handleCrossRoleTypedMemberChange(e2, tm.axisId)}"
3610
+ ?disabled="${this.disabled}"
3611
+ />
3612
+ </div>
3613
+ `)}
3614
+ ` : ""}
3501
3615
  </div>
3502
3616
  </div>
3503
3617
  </div>
@@ -3686,7 +3800,7 @@ JupiterFormField.styles = css`
3686
3800
  border-radius: 8px;
3687
3801
  padding: 24px;
3688
3802
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
3689
- max-width: 400px;
3803
+ max-width: 800px;
3690
3804
  width: 90%;
3691
3805
  }
3692
3806
 
@@ -3730,7 +3844,7 @@ JupiterFormField.styles = css`
3730
3844
 
3731
3845
  .period-popup-content .period-controls {
3732
3846
  display: grid;
3733
- grid-template-columns: 60px 1fr;
3847
+ grid-template-columns: 200px 1fr;
3734
3848
  gap: 12px;
3735
3849
  align-items: center;
3736
3850
  margin-top: 0;
@@ -3741,6 +3855,8 @@ JupiterFormField.styles = css`
3741
3855
  font-weight: 500;
3742
3856
  color: var(--jupiter-text-primary, #333);
3743
3857
  text-align: right;
3858
+ white-space: normal;
3859
+ word-break: break-word;
3744
3860
  }
3745
3861
 
3746
3862
  .period-popup-content .period-controls input[type="date"] {
@@ -3778,22 +3894,44 @@ JupiterFormField.styles = css`
3778
3894
  cursor: not-allowed;
3779
3895
  }
3780
3896
 
3897
+ .period-popup-content .period-controls .typed-member-input {
3898
+ flex: 1;
3899
+ padding: 6px 8px;
3900
+ border: 1px solid var(--jupiter-border-color, #ddd);
3901
+ border-radius: 4px;
3902
+ font-size: 13px;
3903
+ font-family: inherit;
3904
+ background: var(--jupiter-input-background, #fff);
3905
+ }
3906
+
3907
+ .period-popup-content .period-controls .typed-member-input:focus {
3908
+ outline: none;
3909
+ border-color: var(--jupiter-primary-color, #1976d2);
3910
+ box-shadow: 0 0 0 2px var(--jupiter-primary-color-light, rgba(25, 118, 210, 0.2));
3911
+ }
3912
+
3913
+ .period-popup-content .period-controls .typed-member-input:disabled {
3914
+ background: var(--jupiter-disabled-background, #f5f5f5);
3915
+ color: var(--jupiter-disabled-text, #999);
3916
+ cursor: not-allowed;
3917
+ }
3918
+
3781
3919
  .field-input {
3782
3920
  width: 100%;
3783
3921
  padding: 6px 8px; /* Reduced padding for table cells */
3784
- border: 1px solid var(--jupiter-border-color, #ddd);
3922
+ border: 1px solid var(--primaryTextColor, var(--jupiter-border-color, #ddd));
3785
3923
  border-radius: 4px;
3786
3924
  font-size: 13px; /* Slightly smaller font for table */
3787
3925
  font-family: inherit;
3788
- background: var(--jupiter-input-background, #fff);
3789
- color: var(--jupiter-text-primary, #333);
3926
+ background: transparent !important;
3927
+ color: var(--primaryTextColor, var(--jupiter-text-primary, #333));
3790
3928
  box-sizing: border-box;
3791
3929
  }
3792
3930
 
3793
3931
  .field-input:focus {
3794
3932
  outline: none;
3795
- border-color: var(--jupiter-primary-color, #1976d2);
3796
- box-shadow: 0 0 0 2px var(--jupiter-primary-color-light, rgba(25, 118, 210, 0.2));
3933
+ border-color: var(--primaryTextColor, var(--jupiter-primary-color, #1976d2));
3934
+ box-shadow: 0 0 0 2px var(--boxShadowColor, var(--jupiter-primary-color-light, rgba(25, 118, 210, 0.2)));
3797
3935
  }
3798
3936
 
3799
3937
  .field-input:disabled {
@@ -3964,6 +4102,9 @@ __decorateClass$5([
3964
4102
  __decorateClass$5([
3965
4103
  n2({ type: String })
3966
4104
  ], JupiterFormField.prototype, "unit", 2);
4105
+ __decorateClass$5([
4106
+ n2({ type: Object })
4107
+ ], JupiterFormField.prototype, "typedMemberValues", 2);
3967
4108
  __decorateClass$5([
3968
4109
  r()
3969
4110
  ], JupiterFormField.prototype, "_errors", 2);
@@ -4005,6 +4146,9 @@ let JupiterConceptTree = class extends LitElement {
4005
4146
  this.locale = "en-US";
4006
4147
  this.expandedConcepts = /* @__PURE__ */ new Set();
4007
4148
  this.mode = "inputForm";
4149
+ this.typedMemberData = {};
4150
+ this.showAddButton = false;
4151
+ this.showRemoveButton = false;
4008
4152
  this._expanded = true;
4009
4153
  }
4010
4154
  connectedCallback() {
@@ -4042,6 +4186,20 @@ let JupiterConceptTree = class extends LitElement {
4042
4186
  bubbles: true
4043
4187
  }));
4044
4188
  }
4189
+ _handleAddRepeat() {
4190
+ this.dispatchEvent(new CustomEvent("add-concept-repeat", {
4191
+ detail: { conceptId: this.concept.id },
4192
+ bubbles: true,
4193
+ composed: true
4194
+ }));
4195
+ }
4196
+ _handleRemoveRepeat() {
4197
+ this.dispatchEvent(new CustomEvent("remove-concept-repeat", {
4198
+ detail: { conceptId: this.concept.id },
4199
+ bubbles: true,
4200
+ composed: true
4201
+ }));
4202
+ }
4045
4203
  _handlePeriodChange(event) {
4046
4204
  console.log(`🌲 [ConceptTree] Received period-change event:`, event.detail);
4047
4205
  event.stopPropagation();
@@ -4066,11 +4224,19 @@ let JupiterConceptTree = class extends LitElement {
4066
4224
  @click="${this._toggleExpanded}">
4067
4225
  ${hasChildren ? "▶" : ""}
4068
4226
  </div>
4069
- <div class="concept-label"
4227
+ <div class="concept-label"
4070
4228
  @click="${this._toggleExpanded}"
4071
4229
  title="${this.concept.id}${this.concept.description ? " - " + this.concept.description : ""}">
4072
4230
  ${this.concept.label}
4073
4231
  </div>
4232
+ ${this.showAddButton ? html`
4233
+ <button class="repeat-btn" type="button" title="Add row"
4234
+ @click="${this._handleAddRepeat}">+</button>
4235
+ ` : ""}
4236
+ ${this.showRemoveButton ? html`
4237
+ <button class="repeat-btn remove" type="button" title="Remove row"
4238
+ @click="${this._handleRemoveRepeat}">−</button>
4239
+ ` : ""}
4074
4240
  </div>
4075
4241
  </td>
4076
4242
 
@@ -4102,6 +4268,7 @@ let JupiterConceptTree = class extends LitElement {
4102
4268
  .masterData="${this.masterData}"
4103
4269
  .facts="${this.facts}"
4104
4270
  .column="${column2}"
4271
+ .typedMemberValues="${this.typedMemberData[`${this.concept.id}__${column2.id}`] || {}}"
4105
4272
  @field-change="${this._handleFieldChange}"
4106
4273
  @period-change="${this._handlePeriodChange}"
4107
4274
  ></jupiter-form-field>
@@ -4121,7 +4288,7 @@ JupiterConceptTree.styles = css`
4121
4288
  .concept-name-cell {
4122
4289
  vertical-align: top;
4123
4290
  padding: 2px 4px;
4124
- border: 1px solid var(--jupiter-border-color, #ddd);
4291
+ border: 1px solid var(--primaryTextColor, var(--jupiter-border-color, #ddd));
4125
4292
  border-bottom: none;
4126
4293
  background: var(--jupiter-concept-background, #f8f9fa);
4127
4294
  position: sticky;
@@ -4133,12 +4300,13 @@ JupiterConceptTree.styles = css`
4133
4300
  }
4134
4301
 
4135
4302
  .concept-name-cell.abstract {
4136
- background: var(--jupiter-abstract-background, #f0f2f5);
4303
+ background: var(--bg-color-1, var(--jupiter-abstract-background, #f0f2f5));
4137
4304
  font-weight: 600;
4305
+ color: var(--primaryTextColor, var(--jupiter-text-primary, #333));
4138
4306
  }
4139
4307
 
4140
4308
  .concept-name-cell.leaf {
4141
- background: var(--jupiter-leaf-background, #fff);
4309
+ background: var(--bg-color-2, var(--jupiter-leaf-background, #fff));
4142
4310
  font-weight: 400;
4143
4311
  }
4144
4312
 
@@ -4179,7 +4347,7 @@ JupiterConceptTree.styles = css`
4179
4347
 
4180
4348
  .concept-label {
4181
4349
  flex: 1;
4182
- color: var(--jupiter-text-primary, #333);
4350
+ color: var(--primaryTextColor, var(--jupiter-text-primary, #333));
4183
4351
  cursor: pointer;
4184
4352
  word-wrap: break-word;
4185
4353
  overflow-wrap: break-word;
@@ -4191,9 +4359,9 @@ JupiterConceptTree.styles = css`
4191
4359
  .field-cell {
4192
4360
  vertical-align: middle;
4193
4361
  padding: 2px 6px;
4194
- border: 1px solid var(--jupiter-border-color, #ddd);
4362
+ border: 1px solid var(--primaryTextColor, var(--jupiter-border-color, #ddd));
4195
4363
  border-bottom: none;
4196
- background: var(--jupiter-cell-background, #fff);
4364
+ background: var(--bg-color-2, var(--jupiter-cell-background, #fff));
4197
4365
  min-height: 28px;
4198
4366
  text-align: center;
4199
4367
  min-width: 180px;
@@ -4201,11 +4369,11 @@ JupiterConceptTree.styles = css`
4201
4369
  }
4202
4370
 
4203
4371
  .field-cell.empty {
4204
- background: var(--jupiter-empty-cell-background, #f8f9fa);
4372
+ background: var(--bg-color-2, var(--jupiter-empty-cell-background, #f8f9fa));
4205
4373
  }
4206
4374
 
4207
4375
  .field-cell.abstract-row {
4208
- background: var(--jupiter-abstract-cell-background, #f0f2f5);
4376
+ background: var(--bg-color-2, var(--jupiter-abstract-cell-background, #f0f2f5));
4209
4377
  }
4210
4378
 
4211
4379
  /* Children are rendered as separate table rows, not nested */
@@ -4213,6 +4381,38 @@ JupiterConceptTree.styles = css`
4213
4381
  display: none;
4214
4382
  }
4215
4383
 
4384
+ .repeat-btn {
4385
+ flex-shrink: 0;
4386
+ margin-left: 4px;
4387
+ width: 20px;
4388
+ height: 20px;
4389
+ padding: 0;
4390
+ border-radius: 3px;
4391
+ border: 1px solid var(--jupiter-primary-color, #1976d2);
4392
+ color: var(--jupiter-primary-color, #1976d2);
4393
+ background: transparent;
4394
+ cursor: pointer;
4395
+ font-size: 14px;
4396
+ line-height: 1;
4397
+ display: flex;
4398
+ align-items: center;
4399
+ justify-content: center;
4400
+ }
4401
+
4402
+ .repeat-btn:hover {
4403
+ background: var(--jupiter-primary-color, #1976d2);
4404
+ color: #fff;
4405
+ }
4406
+
4407
+ .repeat-btn.remove {
4408
+ border-color: var(--jupiter-error-color, #d32f2f);
4409
+ color: var(--jupiter-error-color, #d32f2f);
4410
+ }
4411
+
4412
+ .repeat-btn.remove:hover {
4413
+ background: var(--jupiter-error-color, #d32f2f);
4414
+ color: #fff;
4415
+ }
4216
4416
 
4217
4417
  `;
4218
4418
  __decorateClass$4([
@@ -4254,6 +4454,15 @@ __decorateClass$4([
4254
4454
  __decorateClass$4([
4255
4455
  n2({ type: Array })
4256
4456
  ], JupiterConceptTree.prototype, "facts", 2);
4457
+ __decorateClass$4([
4458
+ n2({ type: Object })
4459
+ ], JupiterConceptTree.prototype, "typedMemberData", 2);
4460
+ __decorateClass$4([
4461
+ n2({ type: Boolean })
4462
+ ], JupiterConceptTree.prototype, "showAddButton", 2);
4463
+ __decorateClass$4([
4464
+ n2({ type: Boolean })
4465
+ ], JupiterConceptTree.prototype, "showRemoveButton", 2);
4257
4466
  __decorateClass$4([
4258
4467
  r()
4259
4468
  ], JupiterConceptTree.prototype, "_expanded", 2);
@@ -4575,7 +4784,7 @@ JupiterAddColumnDialog.styles = css`
4575
4784
  }
4576
4785
 
4577
4786
  .dialog {
4578
- background: white;
4787
+ background: var(--bg-color-2, var(--jupiter-card-background, #fff));
4579
4788
  border-radius: 8px;
4580
4789
  padding: 24px;
4581
4790
  min-width: 400px;
@@ -4600,7 +4809,7 @@ JupiterAddColumnDialog.styles = css`
4600
4809
  .dialog-title {
4601
4810
  font-size: 20px;
4602
4811
  font-weight: 600;
4603
- color: var(--jupiter-text-primary, #333);
4812
+ color: var(--primaryTextColor, var(--jupiter-text-primary, #333));
4604
4813
  margin: 0 0 8px 0;
4605
4814
  }
4606
4815
 
@@ -4634,7 +4843,7 @@ JupiterAddColumnDialog.styles = css`
4634
4843
  display: block;
4635
4844
  font-weight: 500;
4636
4845
  margin-bottom: 6px;
4637
- color: var(--jupiter-text-primary, #333);
4846
+ color: var(--primaryTextColor, var(--jupiter-text-primary, #333));
4638
4847
  font-size: 14px;
4639
4848
  }
4640
4849
 
@@ -4647,18 +4856,20 @@ JupiterAddColumnDialog.styles = css`
4647
4856
  width: 100%;
4648
4857
  box-sizing: border-box;
4649
4858
  padding: 10px 12px;
4650
- border: 1px solid var(--jupiter-border-color, #ddd);
4859
+ border: 1px solid var(--primaryTextColor, var(--jupiter-border-color, #ddd));
4651
4860
  border-radius: 4px;
4652
4861
  font-size: 14px;
4653
4862
  font-family: inherit;
4654
4863
  transition: border-color 0.2s ease;
4864
+ background-color: transparent;
4865
+ color: var(--primaryTextColor, var(--jupiter-text-primary, #333));
4655
4866
  }
4656
4867
 
4657
- .form-input:focus {
4658
- outline: none;
4659
- border-color: var(--jupiter-primary-color, #007bff);
4660
- box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);
4661
- }
4868
+ // .form-input:focus {
4869
+ // outline: none;
4870
+ // border-color: var(--jupiter-primary-color, #007bff);
4871
+ // box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);
4872
+ // }
4662
4873
 
4663
4874
  select.form-input {
4664
4875
  cursor: pointer;
@@ -4686,27 +4897,28 @@ JupiterAddColumnDialog.styles = css`
4686
4897
  }
4687
4898
 
4688
4899
  .btn-cancel {
4689
- background: var(--jupiter-neutral-background, #f5f5f5);
4690
- color: var(--jupiter-text-primary, #333);
4900
+ color: var(--buttonBgColor, var(--jupiter-primary-color, #1976d2));
4901
+ border: 1px solid var(--buttonBgColor, var(--jupiter-primary-color, #1976d2)) !important;
4902
+ background: transparent;
4691
4903
  }
4692
4904
 
4693
- .btn-cancel:hover {
4694
- background: var(--jupiter-neutral-background-hover, #e0e0e0);
4695
- }
4905
+ // .btn-cancel:hover {
4906
+ // background: var(--jupiter-neutral-background-hover, #e0e0e0);
4907
+ // }
4696
4908
 
4697
4909
  .btn-primary {
4698
- background: var(--jupiter-primary-color, #667eea);
4699
- color: white;
4910
+ background: var(--buttonBgColor, var(--jupiter-primary-color, #1976d2));
4911
+ color: var(--buttonTextColor, white);
4700
4912
  }
4701
4913
 
4702
- .btn-primary:hover {
4703
- background: var(--jupiter-primary-color-dark, #5a6fd8);
4704
- }
4914
+ // .btn-primary:hover {
4915
+ // background: var(--jupiter-primary-color-dark, #5a6fd8);
4916
+ // }
4705
4917
 
4706
- .btn-primary:disabled {
4707
- background: var(--jupiter-disabled-background, #ccc);
4708
- cursor: not-allowed;
4709
- }
4918
+ // .btn-primary:disabled {
4919
+ // background: var(--jupiter-disabled-background, #ccc);
4920
+ // cursor: not-allowed;
4921
+ // }
4710
4922
 
4711
4923
  /* Dimension Selection Styles */
4712
4924
  .dimensions-section {
@@ -4862,6 +5074,7 @@ let JupiterFormSection = class extends LitElement {
4862
5074
  this.periodData = {};
4863
5075
  this.unitData = {};
4864
5076
  this.typedMemberData = {};
5077
+ this.repeatCounts = {};
4865
5078
  this.defaultUnits = [];
4866
5079
  this.disabled = false;
4867
5080
  this.collapsible = true;
@@ -5122,6 +5335,70 @@ let JupiterFormSection = class extends LitElement {
5122
5335
  bubbles: true
5123
5336
  }));
5124
5337
  }
5338
+ _handleAddRepeat(event) {
5339
+ event.stopPropagation();
5340
+ this.dispatchEvent(new CustomEvent("add-concept-repeat", {
5341
+ detail: event.detail,
5342
+ bubbles: true
5343
+ }));
5344
+ }
5345
+ _handleRemoveRepeat(event) {
5346
+ event.stopPropagation();
5347
+ this.dispatchEvent(new CustomEvent("remove-concept-repeat", {
5348
+ detail: event.detail,
5349
+ bubbles: true
5350
+ }));
5351
+ }
5352
+ /** Build the list of <tr> template results for a single flattened concept, including any repeat instances. */
5353
+ _renderConceptRows(concept) {
5354
+ var _a;
5355
+ const isRepeatable = this.mode !== "readonly" && !concept.abstract && ((_a = concept.fields) == null ? void 0 : _a.some((f2) => {
5356
+ var _a2;
5357
+ return ((_a2 = f2.crossRoleTypedMembers) == null ? void 0 : _a2.length) > 0;
5358
+ }));
5359
+ const repeatCount = isRepeatable ? this.repeatCounts[concept.id] || 0 : 0;
5360
+ const sharedProps = (instanceConcept, opts) => html`
5361
+ <jupiter-concept-tree
5362
+ .concept="${instanceConcept}"
5363
+ .columns="${this.columns}"
5364
+ .datatypes="${this.datatypes}"
5365
+ .formData="${this.formData}"
5366
+ .periodData="${this.periodData}"
5367
+ .unitData="${this.unitData}"
5368
+ .defaultUnits="${this.defaultUnits}"
5369
+ .disabled="${this.disabled}"
5370
+ .locale="${this.locale}"
5371
+ .expandedConcepts="${this._expandedConcepts}"
5372
+ .mode="${this.mode}"
5373
+ .masterData="${this.masterData}"
5374
+ .facts="${instanceConcept.facts}"
5375
+ .typedMemberData="${this.typedMemberData}"
5376
+ .showAddButton="${opts.showAdd || false}"
5377
+ .showRemoveButton="${opts.showRemove || false}"
5378
+ @field-change="${this._handleFieldChange}"
5379
+ @period-change="${this._handlePeriodChange}"
5380
+ @concept-expand="${this._handleConceptExpand}"
5381
+ @add-concept-repeat="${this._handleAddRepeat}"
5382
+ @remove-concept-repeat="${this._handleRemoveRepeat}"
5383
+ ></jupiter-concept-tree>
5384
+ `;
5385
+ const rows = [html`
5386
+ <tr>${sharedProps(concept, { showAdd: isRepeatable })}</tr>
5387
+ `];
5388
+ for (let n3 = 1; n3 <= repeatCount; n3++) {
5389
+ const instanceConcept = {
5390
+ ...concept,
5391
+ id: `${concept.id}__repeat_${n3}`,
5392
+ label: "",
5393
+ children: [],
5394
+ abstract: false
5395
+ };
5396
+ rows.push(html`
5397
+ <tr>${sharedProps(instanceConcept, { showRemove: true })}</tr>
5398
+ `);
5399
+ }
5400
+ return rows;
5401
+ }
5125
5402
  render() {
5126
5403
  if (!this.section.concepts || this.section.concepts.length === 0) {
5127
5404
  return html`
@@ -5242,28 +5519,7 @@ let JupiterFormSection = class extends LitElement {
5242
5519
  </tr>
5243
5520
  </thead>
5244
5521
  <tbody class="table-body">
5245
- ${this._flattenConcepts(this.section.concepts, this._expandedConcepts).filter((concept) => this.mode !== "readonly" || !this._isConceptRowBlank(concept)).map((concept) => html`
5246
- <tr>
5247
- <jupiter-concept-tree
5248
- .concept="${concept}"
5249
- .columns="${this.columns}"
5250
- .datatypes="${this.datatypes}"
5251
- .formData="${this.formData}"
5252
- .periodData="${this.periodData}"
5253
- .unitData="${this.unitData}"
5254
- .defaultUnits="${this.defaultUnits}"
5255
- .disabled="${this.disabled}"
5256
- .locale="${this.locale}"
5257
- .expandedConcepts="${this._expandedConcepts}"
5258
- .mode="${this.mode}"
5259
- .masterData="${this.masterData}"
5260
- .facts="${concept.facts}"
5261
- @field-change="${this._handleFieldChange}"
5262
- @period-change="${this._handlePeriodChange}"
5263
- @concept-expand="${this._handleConceptExpand}"
5264
- ></jupiter-concept-tree>
5265
- </tr>
5266
- `)}
5522
+ ${this._flattenConcepts(this.section.concepts, this._expandedConcepts).filter((concept) => this.mode !== "readonly" || !this._isConceptRowBlank(concept)).flatMap((concept) => this._renderConceptRows(concept))}
5267
5523
  </tbody>
5268
5524
  </table>
5269
5525
  </div>
@@ -5384,13 +5640,20 @@ JupiterFormSection.styles = css`
5384
5640
  /* Table row - no special display needed */
5385
5641
  }
5386
5642
 
5643
+ .header-cell:first-child {
5644
+ border-radius: 6px 0 0 0;
5645
+ }
5646
+ .header-cell:last-child {
5647
+ border-radius: 0 6px 0 0;
5648
+ }
5649
+
5387
5650
  .header-cell {
5388
5651
  padding: 8px 12px;
5389
5652
  text-align: left;
5390
5653
  font-weight: 600;
5391
- color: var(--jupiter-text-primary, #333);
5392
- border: 1px solid var(--jupiter-border-color, #ddd);
5393
- background: var(--jupiter-header-background, #f8f9fa);
5654
+ color: var(--primaryTextColor, var(--jupiter-text-primary, #333));
5655
+ border: 1px solid var(--primaryTextColor, var(--jupiter-border-color, #ddd));
5656
+ background: var(--bg-color-1, var(--jupiter-header-background, #f8f9fa));
5394
5657
  min-width: 180px;
5395
5658
  width: 180px;
5396
5659
  font-size: 14px;
@@ -5562,6 +5825,9 @@ __decorateClass$2([
5562
5825
  __decorateClass$2([
5563
5826
  n2({ type: Object })
5564
5827
  ], JupiterFormSection.prototype, "typedMemberData", 2);
5828
+ __decorateClass$2([
5829
+ n2({ type: Object })
5830
+ ], JupiterFormSection.prototype, "repeatCounts", 2);
5565
5831
  __decorateClass$2([
5566
5832
  n2({ type: Array })
5567
5833
  ], JupiterFormSection.prototype, "defaultUnits", 2);
@@ -6594,24 +6860,25 @@ JupiterFilterRolesDialog.styles = css`
6594
6860
 
6595
6861
  .dialog-header {
6596
6862
  padding: 20px 24px 16px;
6597
- border-bottom: 1px solid var(--jupiter-border-color, #ddd);
6863
+ border-bottom: 1px solid var(--primaryTextColor, var(--jupiter-border-color, #ddd));
6598
6864
  display: flex;
6599
6865
  align-items: center;
6600
6866
  gap: 12px;
6867
+ background: var(--bg-color-1, var(--jupiter-header-background, #f8f9fa));
6601
6868
  }
6602
6869
 
6603
6870
  .dialog-title {
6604
6871
  font-size: 18px;
6605
6872
  font-weight: 600;
6606
6873
  margin: 0;
6607
- color: var(--jupiter-text-primary, #333);
6874
+ color: var(--primaryTextColor, var(--jupiter-text-primary, #333));
6608
6875
  flex: 1;
6609
6876
  }
6610
6877
 
6611
6878
  .filter-icon {
6612
6879
  width: 20px;
6613
6880
  height: 20px;
6614
- fill: var(--jupiter-primary-color, #1976d2);
6881
+ fill: var(--primaryTextColor, var(--jupiter-primary-color, #1976d2));
6615
6882
  }
6616
6883
 
6617
6884
  .close-button {
@@ -6620,23 +6887,24 @@ JupiterFilterRolesDialog.styles = css`
6620
6887
  font-size: 24px;
6621
6888
  cursor: pointer;
6622
6889
  padding: 4px;
6623
- color: var(--jupiter-text-secondary, #666);
6890
+ color: var(--primaryTextColor, var(--jupiter-text-secondary, #666));
6624
6891
  border-radius: 4px;
6625
6892
  transition: background-color 0.2s ease;
6626
6893
  }
6627
6894
 
6628
- .close-button:hover {
6629
- background: var(--jupiter-hover-background, #f5f5f5);
6630
- }
6895
+ // .close-button:hover {
6896
+ // background: var(--jupiter-hover-background, #f5f5f5);
6897
+ // }
6631
6898
 
6632
6899
  .dialog-content {
6900
+ background: var(--bg-color-2, var(--jupiter-form-content-background, #fff));
6633
6901
  flex: 1;
6634
6902
  overflow-y: auto;
6635
6903
  padding: 20px 24px;
6636
6904
  }
6637
6905
 
6638
6906
  .description {
6639
- color: var(--jupiter-text-secondary, #666);
6907
+ color: var(--primaryTextColor, var(--secondaryTextColor, var(--jupiter-text-secondary, #666))) ;
6640
6908
  font-size: 14px;
6641
6909
  margin: 0 0 20px 0;
6642
6910
  line-height: 1.5;
@@ -6655,25 +6923,25 @@ JupiterFilterRolesDialog.styles = css`
6655
6923
  }
6656
6924
 
6657
6925
  .search-input {
6658
- width: 100%;
6926
+ width: stretch;
6659
6927
  padding: 10px 40px 10px 12px;
6660
- border: 1px solid var(--jupiter-border-color, #ddd);
6928
+ border: 1px solid var(--primaryTextColor, var(--jupiter-border-color, #ddd));
6661
6929
  border-radius: 4px;
6662
6930
  font-size: 14px;
6663
6931
  font-family: inherit;
6664
- background: var(--jupiter-background, #fff);
6665
- color: var(--jupiter-text-primary, #333);
6932
+ background: transparent;
6933
+ color: var(--primaryTextColor, var(--jupiter-text-primary, #333));
6666
6934
  transition: border-color 0.2s ease;
6667
6935
  }
6668
6936
 
6669
- .search-input:focus {
6670
- outline: none;
6671
- border-color: var(--jupiter-primary-color, #1976d2);
6672
- box-shadow: 0 0 0 2px rgba(25, 118, 210, 0.1);
6673
- }
6937
+ // .search-input:focus {
6938
+ // outline: none;
6939
+ // border-color: var(--jupiter-primary-color, #1976d2);
6940
+ // box-shadow: 0 0 0 2px rgba(25, 118, 210, 0.1);
6941
+ // }
6674
6942
 
6675
6943
  .search-input::placeholder {
6676
- color: var(--jupiter-text-secondary, #666);
6944
+ color: var(--primaryTextColor, var(--jupiter-text-secondary, #666));
6677
6945
  }
6678
6946
 
6679
6947
  .search-icon {
@@ -6731,8 +6999,8 @@ JupiterFilterRolesDialog.styles = css`
6731
6999
 
6732
7000
  .selection-control {
6733
7001
  background: none;
6734
- border: 1px solid var(--jupiter-primary-color, #1976d2);
6735
- color: var(--jupiter-primary-color, #1976d2);
7002
+ border: 1px solid var(--primaryTextColor, var(--jupiter-primary-color, #1976d2));
7003
+ color: var(--primaryTextColor, var(--jupiter-primary-color, #1976d2));
6736
7004
  padding: 6px 12px;
6737
7005
  border-radius: 4px;
6738
7006
  font-size: 12px;
@@ -6741,7 +7009,7 @@ JupiterFilterRolesDialog.styles = css`
6741
7009
  }
6742
7010
 
6743
7011
  .selection-control:hover {
6744
- background: var(--jupiter-primary-color, #1976d2);
7012
+ background: var(--menuBgColorLighter, var(--jupiter-primary-color, #1976d2));
6745
7013
  color: white;
6746
7014
  }
6747
7015
 
@@ -6751,7 +7019,7 @@ JupiterFilterRolesDialog.styles = css`
6751
7019
  gap: 8px;
6752
7020
  max-height: 300px;
6753
7021
  overflow-y: auto;
6754
- border: 1px solid var(--jupiter-border-color, #ddd);
7022
+ border: 1px solid var(--primaryTextColor, var(--jupiter-border-color, #ddd));
6755
7023
  border-radius: 4px;
6756
7024
  padding: 12px;
6757
7025
  }
@@ -6766,13 +7034,17 @@ JupiterFilterRolesDialog.styles = css`
6766
7034
  }
6767
7035
 
6768
7036
  .role-item:hover {
6769
- background: var(--jupiter-hover-background, #f5f5f5);
7037
+ background: var(--menuBgColorLighter, var(--jupiter-hover-background, #f5f5f5));
6770
7038
  }
6771
7039
 
6772
7040
  .role-checkbox {
6773
7041
  margin-top: 2px;
6774
7042
  cursor: pointer;
6775
7043
  }
7044
+
7045
+ .role-info * {
7046
+ color: var(--primaryTextColor, var(--jupiter-text-primary, #333)) !important;
7047
+ }
6776
7048
 
6777
7049
  .role-info {
6778
7050
  flex: 1;
@@ -6802,15 +7074,15 @@ JupiterFilterRolesDialog.styles = css`
6802
7074
  .period-controls {
6803
7075
  margin-top: 8px;
6804
7076
  padding: 8px;
6805
- background: var(--jupiter-background-light, #f8f9fa);
7077
+ background: var(--bg-color-1, var(--jupiter-background-light, #f8f9fa));
6806
7078
  border-radius: 4px;
6807
- border: 1px solid var(--jupiter-border-color, #e0e0e0);
7079
+ border: 1px solid var(--primaryTextColor, var(--jupiter-border-color, #e0e0e0));
6808
7080
  }
6809
7081
 
6810
7082
  .period-controls-label {
6811
7083
  font-size: 12px;
6812
7084
  font-weight: 600;
6813
- color: var(--jupiter-text-primary, #333);
7085
+ color: var(--primaryTextColor, var(--jupiter-text-primary, #333));
6814
7086
  margin: 0 0 6px 0;
6815
7087
  }
6816
7088
 
@@ -6938,11 +7210,11 @@ JupiterFilterRolesDialog.styles = css`
6938
7210
 
6939
7211
  .dialog-actions {
6940
7212
  padding: 16px 24px;
6941
- border-top: 1px solid var(--jupiter-border-color, #ddd);
7213
+ border-top: 1px solid var(--primaryTextColor, var(--jupiter-border-color, #ddd));
6942
7214
  display: flex;
6943
7215
  gap: 12px;
6944
7216
  justify-content: flex-end;
6945
- background: var(--jupiter-form-actions-background, #f8f9fa);
7217
+ background: var(--bg-color-2, var(--jupiter-form-actions-background, #f8f9fa));
6946
7218
  }
6947
7219
 
6948
7220
  .dialog-actions button {
@@ -6956,23 +7228,23 @@ JupiterFilterRolesDialog.styles = css`
6956
7228
  }
6957
7229
 
6958
7230
  .btn-primary {
6959
- background: var(--jupiter-primary-color, #1976d2);
6960
- color: white;
7231
+ background: var(--buttonBgColor, var(--jupiter-primary-color, #1976d2));
7232
+ color: var(--buttonTextColor, white);
6961
7233
  }
6962
7234
 
6963
- .btn-primary:hover:not(:disabled) {
6964
- background: var(--jupiter-primary-color-dark, #1565c0);
6965
- }
7235
+ // .btn-primary:hover:not(:disabled) {
7236
+ // background: var(--jupiter-primary-color-dark, #1565c0);
7237
+ // }
6966
7238
 
6967
7239
  .btn-secondary {
7240
+ color: var(--buttonBgColor, var(--jupiter-primary-color, #1976d2));
7241
+ border: 1px solid var(--buttonBgColor, var(--jupiter-primary-color, #1976d2)) !important;
6968
7242
  background: transparent;
6969
- color: var(--jupiter-text-secondary, #666);
6970
- border: 1px solid var(--jupiter-border-color, #ddd);
6971
7243
  }
6972
7244
 
6973
- .btn-secondary:hover:not(:disabled) {
6974
- background: var(--jupiter-hover-background, #f5f5f5);
6975
- }
7245
+ // .btn-secondary:hover:not(:disabled) {
7246
+ // background: var(--jupiter-hover-background, #f5f5f5);
7247
+ // }
6976
7248
 
6977
7249
  button:disabled {
6978
7250
  opacity: 0.6;
@@ -7187,6 +7459,7 @@ let JupiterDynamicForm = class extends LitElement {
7187
7459
  this._preservedUnitData = {};
7188
7460
  this._typedMemberData = {};
7189
7461
  this._preservedTypedMemberData = {};
7462
+ this._repeatCounts = {};
7190
7463
  this._columns = [];
7191
7464
  this._errors = [];
7192
7465
  this._touched = /* @__PURE__ */ new Set();
@@ -7405,7 +7678,6 @@ let JupiterDynamicForm = class extends LitElement {
7405
7678
  if (!((_a = this._currentSchema) == null ? void 0 : _a.sections)) {
7406
7679
  return;
7407
7680
  }
7408
- console.log("🔍 [DynamicForm] Extracting typed member values from facts");
7409
7681
  this._currentSchema.sections.forEach((section2) => {
7410
7682
  this._extractTypedMembersFromConcepts(section2.concepts || [], section2);
7411
7683
  });
@@ -7848,6 +8120,10 @@ let JupiterDynamicForm = class extends LitElement {
7848
8120
  if (this._typedMemberData[field2.columnId]) {
7849
8121
  this._preservedTypedMemberData[field2.columnId] = { ...this._typedMemberData[field2.columnId] };
7850
8122
  }
8123
+ const crossRoleKey = `${concept.id}__${field2.columnId}`;
8124
+ if (this._typedMemberData[crossRoleKey]) {
8125
+ this._preservedTypedMemberData[crossRoleKey] = { ...this._typedMemberData[crossRoleKey] };
8126
+ }
7851
8127
  });
7852
8128
  if (concept.children) {
7853
8129
  concept.children.forEach((child) => {
@@ -7868,6 +8144,10 @@ let JupiterDynamicForm = class extends LitElement {
7868
8144
  if (this._preservedTypedMemberData[field2.columnId]) {
7869
8145
  this._typedMemberData[field2.columnId] = { ...this._preservedTypedMemberData[field2.columnId] };
7870
8146
  }
8147
+ const crossRoleKey = `${concept.id}__${field2.columnId}`;
8148
+ if (this._preservedTypedMemberData[crossRoleKey]) {
8149
+ this._typedMemberData[crossRoleKey] = { ...this._preservedTypedMemberData[crossRoleKey] };
8150
+ }
7871
8151
  });
7872
8152
  if (concept.children) {
7873
8153
  concept.children.forEach((child) => {
@@ -7909,7 +8189,8 @@ let JupiterDynamicForm = class extends LitElement {
7909
8189
  this._periodPreferences,
7910
8190
  this._periodData,
7911
8191
  this._unitData,
7912
- this.reportingLanguage
8192
+ this.reportingLanguage,
8193
+ this._repeatCounts
7913
8194
  );
7914
8195
  this._draftStorageService.saveDraft(currentFormData, currentMetadata);
7915
8196
  console.log("✅ Current form data saved to draft storage with NEW preferences");
@@ -8080,14 +8361,72 @@ let JupiterDynamicForm = class extends LitElement {
8080
8361
  const parts = uniqueConceptKey.split("::");
8081
8362
  return parts.length > 1 ? parts[1] : uniqueConceptKey;
8082
8363
  }
8364
+ _handleAddConceptRepeat(event) {
8365
+ const { conceptId } = event.detail;
8366
+ this._repeatCounts = { ...this._repeatCounts, [conceptId]: (this._repeatCounts[conceptId] || 0) + 1 };
8367
+ this._dirty = true;
8368
+ }
8369
+ _handleRemoveConceptRepeat(event) {
8370
+ const { conceptId: rawConceptId } = event.detail;
8371
+ const repeatMatch = rawConceptId.match(/^(.+)__repeat_(\d+)$/);
8372
+ const baseConceptId = repeatMatch ? repeatMatch[1] : rawConceptId;
8373
+ const removeIndex = repeatMatch ? parseInt(repeatMatch[2]) : this._repeatCounts[rawConceptId] || 0;
8374
+ const current = this._repeatCounts[baseConceptId] || 0;
8375
+ if (current <= 0 || removeIndex < 1 || removeIndex > current)
8376
+ return;
8377
+ const newFormData = { ...this._formData };
8378
+ const newTypedData = { ...this._typedMemberData };
8379
+ const newUnitData = { ...this._unitData };
8380
+ const newPeriodData = { ...this._periodData };
8381
+ for (let n3 = removeIndex; n3 < current; n3++) {
8382
+ const fromId = `${baseConceptId}__repeat_${n3 + 1}`;
8383
+ const toId = `${baseConceptId}__repeat_${n3}`;
8384
+ if (newFormData[fromId] !== void 0) {
8385
+ newFormData[toId] = newFormData[fromId];
8386
+ } else {
8387
+ delete newFormData[toId];
8388
+ }
8389
+ const toPrefix = `${toId}__`;
8390
+ const fromPrefix = `${fromId}__`;
8391
+ const fromEntries = Object.keys(newTypedData).filter((k) => k.startsWith(fromPrefix));
8392
+ Object.keys(newTypedData).filter((k) => k.startsWith(toPrefix)).forEach((k) => delete newTypedData[k]);
8393
+ fromEntries.forEach((k) => {
8394
+ newTypedData[`${toId}__${k.slice(fromPrefix.length)}`] = newTypedData[k];
8395
+ });
8396
+ fromEntries.forEach((k) => delete newTypedData[k]);
8397
+ if (newUnitData[fromId] !== void 0) {
8398
+ newUnitData[toId] = newUnitData[fromId];
8399
+ } else {
8400
+ delete newUnitData[toId];
8401
+ }
8402
+ if (newPeriodData[fromId] !== void 0) {
8403
+ newPeriodData[toId] = newPeriodData[fromId];
8404
+ } else {
8405
+ delete newPeriodData[toId];
8406
+ }
8407
+ }
8408
+ const lastId = `${baseConceptId}__repeat_${current}`;
8409
+ delete newFormData[lastId];
8410
+ delete newUnitData[lastId];
8411
+ delete newPeriodData[lastId];
8412
+ const lastPrefix = `${lastId}__`;
8413
+ Object.keys(newTypedData).filter((k) => k.startsWith(lastPrefix)).forEach((k) => delete newTypedData[k]);
8414
+ this._formData = newFormData;
8415
+ this._typedMemberData = newTypedData;
8416
+ this._unitData = newUnitData;
8417
+ this._periodData = newPeriodData;
8418
+ this._repeatCounts = { ...this._repeatCounts, [baseConceptId]: current - 1 };
8419
+ this._dirty = true;
8420
+ }
8083
8421
  _handleTypedMemberChange(event) {
8084
- const { columnId, axisId, value } = event.detail;
8085
- console.log(`🔍 [DynamicForm] Typed member change: columnId=${columnId}, axisId=${axisId}, value=${value}`);
8422
+ const { columnId, axisId, value, conceptId } = event.detail;
8423
+ const storageKey = conceptId ? `${conceptId}__${columnId}` : columnId;
8424
+ console.log(`🔍 [DynamicForm] Typed member change: storageKey=${storageKey}, axisId=${axisId}, value=${value}`);
8086
8425
  const updatedTypedMemberData = { ...this._typedMemberData };
8087
- if (!updatedTypedMemberData[columnId]) {
8088
- updatedTypedMemberData[columnId] = {};
8426
+ if (!updatedTypedMemberData[storageKey]) {
8427
+ updatedTypedMemberData[storageKey] = {};
8089
8428
  }
8090
- updatedTypedMemberData[columnId] = { ...updatedTypedMemberData[columnId], [axisId]: value };
8429
+ updatedTypedMemberData[storageKey] = { ...updatedTypedMemberData[storageKey], [axisId]: value };
8091
8430
  this._typedMemberData = updatedTypedMemberData;
8092
8431
  this._dirty = true;
8093
8432
  this.requestUpdate();
@@ -8715,7 +9054,8 @@ let JupiterDynamicForm = class extends LitElement {
8715
9054
  this._periodPreferences,
8716
9055
  this._periodData,
8717
9056
  this._unitData,
8718
- this.reportingLanguage
9057
+ this.reportingLanguage,
9058
+ this._repeatCounts
8719
9059
  );
8720
9060
  const draftPayloadSnapshot = JSON.stringify({
8721
9061
  draftData,
@@ -8829,6 +9169,10 @@ let JupiterDynamicForm = class extends LitElement {
8829
9169
  this._preservedTypedMemberData = {};
8830
9170
  console.log("🔄 Restored typed member data");
8831
9171
  }
9172
+ if (metadata.repeatCounts) {
9173
+ this._repeatCounts = metadata.repeatCounts;
9174
+ console.log("🔄 Restored repeat counts:", this._repeatCounts);
9175
+ }
8832
9176
  if (metadata.periodData) {
8833
9177
  this._periodData = metadata.periodData;
8834
9178
  console.log("🔄 Restored custom field-level period data:", Object.keys(this._periodData).length, "concepts");
@@ -8872,7 +9216,7 @@ let JupiterDynamicForm = class extends LitElement {
8872
9216
  const restoredPeriodData = {};
8873
9217
  const restoredUnitData = {};
8874
9218
  formData.forEach((entry) => {
8875
- let { conceptId, value, columnId, period, unit } = entry;
9219
+ let { conceptId, draftInstanceId, value, columnId, period, unit } = entry;
8876
9220
  if (!columnId && period) {
8877
9221
  columnId = this._inferColumnIdFromPeriod(period, conceptId);
8878
9222
  if (!columnId) {
@@ -8880,13 +9224,15 @@ let JupiterDynamicForm = class extends LitElement {
8880
9224
  return;
8881
9225
  }
8882
9226
  }
8883
- const actualConceptId = this._findActualConceptId(conceptId);
8884
- const conceptIdToUse = actualConceptId || conceptId;
9227
+ const instanceKey = draftInstanceId || conceptId;
9228
+ const baseConceptId = instanceKey.includes("__repeat_") ? instanceKey.split("__repeat_")[0] : instanceKey;
9229
+ const actualBaseId = this._findActualConceptId(baseConceptId);
9230
+ const conceptIdToUse = instanceKey.includes("__repeat_") ? `${actualBaseId || baseConceptId}__repeat_${instanceKey.split("__repeat_")[1]}` : actualBaseId || instanceKey;
8885
9231
  if (!restoredFormData[conceptIdToUse]) {
8886
9232
  restoredFormData[conceptIdToUse] = {};
8887
9233
  }
8888
9234
  restoredFormData[conceptIdToUse][columnId] = value;
8889
- console.log(`📦 Restored: ${conceptIdToUse}[${columnId}] = ${value}`);
9235
+ console.log(`📦 Restored: ${conceptIdToUse}[${columnId}] = ${value}${instanceKey !== conceptId ? ` (repeat instance)` : ""}`);
8890
9236
  if (period) {
8891
9237
  if (!restoredPeriodData[conceptIdToUse]) {
8892
9238
  restoredPeriodData[conceptIdToUse] = {};
@@ -9542,7 +9888,7 @@ let JupiterDynamicForm = class extends LitElement {
9542
9888
  }
9543
9889
  if (concept.fields && concept.fields.length > 0) {
9544
9890
  concept.fields.forEach((field2) => {
9545
- var _a, _b, _c, _d;
9891
+ var _a, _b, _c, _d, _e;
9546
9892
  const conceptData = this._formData[concept.id];
9547
9893
  let fieldValue = conceptData == null ? void 0 : conceptData[field2.columnId];
9548
9894
  if ((fieldValue === void 0 || fieldValue === null || fieldValue === "") && this.masterData) {
@@ -9558,6 +9904,8 @@ let JupiterDynamicForm = class extends LitElement {
9558
9904
  const fieldPeriodData = (_a = this._periodData[concept.id]) == null ? void 0 : _a[field2.columnId];
9559
9905
  const submissionEntry = {
9560
9906
  conceptId: concept.id,
9907
+ draftInstanceId: concept.id,
9908
+ // used during draft restoration to route value to the correct _formData slot
9561
9909
  columnId: field2.columnId,
9562
9910
  // CRITICAL: Include columnId for draft restoration
9563
9911
  value: fieldValue,
@@ -9623,12 +9971,90 @@ let JupiterDynamicForm = class extends LitElement {
9623
9971
  });
9624
9972
  }
9625
9973
  }
9974
+ if (!submissionEntry.typedMembers && ((_e = field2.crossRoleTypedMembers) == null ? void 0 : _e.length)) {
9975
+ const crossRoleKey = `${concept.id}__${field2.columnId}`;
9976
+ const crossRoleValues = this._typedMemberData[crossRoleKey];
9977
+ if (crossRoleValues) {
9978
+ const filteredTypedMembers = {};
9979
+ field2.crossRoleTypedMembers.forEach((tm) => {
9980
+ const val = crossRoleValues[tm.axisId];
9981
+ if (val !== void 0 && val !== null && val !== "") {
9982
+ filteredTypedMembers[tm.axisId] = {
9983
+ value: val,
9984
+ memberName: tm.typedMemberId
9985
+ };
9986
+ }
9987
+ });
9988
+ if (Object.keys(filteredTypedMembers).length > 0) {
9989
+ submissionEntry.typedMembers = filteredTypedMembers;
9990
+ console.log(`🔍 [Submission] Adding cross-role typed members for ${concept.id}/${field2.columnId}:`, filteredTypedMembers);
9991
+ }
9992
+ }
9993
+ }
9626
9994
  if (sectionTitle === targetRole) {
9627
9995
  console.warn(`[DUPLICATE DEBUG] Final submission entry:`, submissionEntry);
9628
9996
  }
9629
9997
  submissionData.push(submissionEntry);
9630
9998
  }
9631
9999
  });
10000
+ const repeatCount = this._repeatCounts[concept.id] || 0;
10001
+ if (repeatCount > 0 && concept.fields.some((f2) => {
10002
+ var _a;
10003
+ return (_a = f2.crossRoleTypedMembers) == null ? void 0 : _a.length;
10004
+ })) {
10005
+ for (let n3 = 1; n3 <= repeatCount; n3++) {
10006
+ const instanceId = `${concept.id}__repeat_${n3}`;
10007
+ concept.fields.forEach((field2) => {
10008
+ var _a, _b, _c, _d, _e;
10009
+ const instanceValue = (_a = this._formData[instanceId]) == null ? void 0 : _a[field2.columnId];
10010
+ if (instanceValue === void 0 || instanceValue === null || instanceValue === "")
10011
+ return;
10012
+ const column2 = this._findColumnByIdInSection(field2.columnId, section2);
10013
+ const fieldPeriodData = (_b = this._periodData[instanceId]) == null ? void 0 : _b[field2.columnId];
10014
+ const instanceEntry = {
10015
+ conceptId: concept.id,
10016
+ // original concept ID (not synthetic repeat ID)
10017
+ draftInstanceId: instanceId,
10018
+ // synthetic ID used during draft restoration to route to the correct _formData slot
10019
+ columnId: field2.columnId,
10020
+ value: instanceValue,
10021
+ period: {
10022
+ type: concept.periodType || "duration"
10023
+ }
10024
+ };
10025
+ if (concept.periodType === "instant") {
10026
+ instanceEntry.period.date = (fieldPeriodData == null ? void 0 : fieldPeriodData.instantDate) || (fieldPeriodData == null ? void 0 : fieldPeriodData.endDate) || (column2 == null ? void 0 : column2.periodEndDate) || field2.periodInstantDate || field2.periodEndDate || field2.periodStartDate || this.periodStartDate;
10027
+ } else {
10028
+ instanceEntry.period.startDate = (fieldPeriodData == null ? void 0 : fieldPeriodData.startDate) || (column2 == null ? void 0 : column2.periodStartDate) || field2.periodStartDate || this.periodStartDate;
10029
+ instanceEntry.period.endDate = (fieldPeriodData == null ? void 0 : fieldPeriodData.endDate) || (column2 == null ? void 0 : column2.periodEndDate) || field2.periodEndDate || this.periodEndDate;
10030
+ }
10031
+ const instanceUnit = (_c = this._unitData[instanceId]) == null ? void 0 : _c[field2.columnId];
10032
+ if (instanceUnit) {
10033
+ instanceEntry.unit = instanceUnit;
10034
+ }
10035
+ if ((column2 == null ? void 0 : column2.type) === "dimension" && ((_d = column2.dimensionData) == null ? void 0 : _d.dimensionIdKey)) {
10036
+ instanceEntry.dimension = column2.dimensionData.dimensionIdKey;
10037
+ }
10038
+ if ((_e = field2.crossRoleTypedMembers) == null ? void 0 : _e.length) {
10039
+ const crossRoleKey = `${instanceId}__${field2.columnId}`;
10040
+ const crossRoleValues = this._typedMemberData[crossRoleKey];
10041
+ if (crossRoleValues) {
10042
+ const filteredTypedMembers = {};
10043
+ field2.crossRoleTypedMembers.forEach((tm) => {
10044
+ const val = crossRoleValues[tm.axisId];
10045
+ if (val !== void 0 && val !== null && val !== "") {
10046
+ filteredTypedMembers[tm.axisId] = { value: val, memberName: tm.typedMemberId };
10047
+ }
10048
+ });
10049
+ if (Object.keys(filteredTypedMembers).length > 0) {
10050
+ instanceEntry.typedMembers = filteredTypedMembers;
10051
+ }
10052
+ }
10053
+ }
10054
+ submissionData.push(instanceEntry);
10055
+ });
10056
+ }
10057
+ }
9632
10058
  }
9633
10059
  if (concept.children) {
9634
10060
  this._processConceptsForSubmission(concept.children, submissionData, section2);
@@ -9758,13 +10184,6 @@ let JupiterDynamicForm = class extends LitElement {
9758
10184
  }
9759
10185
  const allFields = [];
9760
10186
  this._collectAllFields(section2.concepts || [], new Set((section2.columns || []).map((col) => col.id)), section2.columns || [], allFields);
9761
- console.warn(`📊 Total fields found: ${allFields.length}`);
9762
- console.warn(`
9763
- 📋 FIELD DETAILS:`);
9764
- allFields.forEach((field2, index) => {
9765
- const status = field2.isEmpty ? "❌ EMPTY" : "✅ FILLED";
9766
- console.warn(` ${index + 1}. ${field2.conceptId} [${field2.columnId}]: ${status} = ${JSON.stringify(field2.value)}`);
9767
- });
9768
10187
  const hasErrors = this._roleHasErrors(roleId);
9769
10188
  const emptyCount = allFields.filter((f2) => f2.isEmpty).length;
9770
10189
  const filledCount = allFields.filter((f2) => !f2.isEmpty).length;
@@ -9839,10 +10258,8 @@ let JupiterDynamicForm = class extends LitElement {
9839
10258
  if (matchedFact && matchedFact.value !== null && matchedFact.value !== void 0 && matchedFact.value !== "") {
9840
10259
  value = matchedFact.value;
9841
10260
  isEmpty = false;
9842
- console.warn(` ✨ FACT PRE-POPULATED: ${fieldConceptId} [${field2.columnId}] = ${JSON.stringify(value)}`);
9843
10261
  }
9844
10262
  }
9845
- console.warn(` 🔍 Field lookup: concept.id="${conceptIdWithSuffix}", field.conceptId="${fieldConceptId}", value=${JSON.stringify(value)}, isEmpty=${isEmpty}`);
9846
10263
  allFields.push({
9847
10264
  conceptId: fieldConceptId,
9848
10265
  columnId: field2.columnId,
@@ -10302,6 +10719,7 @@ let JupiterDynamicForm = class extends LitElement {
10302
10719
  .periodData="${this._periodData}"
10303
10720
  .unitData="${this._unitData}"
10304
10721
  .typedMemberData="${this._typedMemberData}"
10722
+ .repeatCounts="${this._repeatCounts}"
10305
10723
  .defaultUnits="${this.defaultUnits}"
10306
10724
  .disabled="${this.disabled || this.readonly}"
10307
10725
  .collapsible="${config.collapsibleSections !== false}"
@@ -10315,6 +10733,8 @@ let JupiterDynamicForm = class extends LitElement {
10315
10733
  @field-change="${this._handleFieldChange}"
10316
10734
  @period-change="${this._handlePeriodChange}"
10317
10735
  @typed-member-change="${this._handleTypedMemberChange}"
10736
+ @add-concept-repeat="${this._handleAddConceptRepeat}"
10737
+ @remove-concept-repeat="${this._handleRemoveConceptRepeat}"
10318
10738
  @section-expand="${this._handleSectionExpand}"
10319
10739
  @concept-expand="${this._handleConceptExpand}"
10320
10740
  @column-remove="${this._handleColumnRemove}"
@@ -10431,6 +10851,7 @@ let JupiterDynamicForm = class extends LitElement {
10431
10851
  .periodData="${this._periodData}"
10432
10852
  .unitData="${this._unitData}"
10433
10853
  .typedMemberData="${this._typedMemberData}"
10854
+ .repeatCounts="${this._repeatCounts}"
10434
10855
  .defaultUnits="${this.defaultUnits}"
10435
10856
  .disabled="${this.disabled || this.readonly}"
10436
10857
  .collapsible="${false}"
@@ -10444,6 +10865,8 @@ let JupiterDynamicForm = class extends LitElement {
10444
10865
  .periodEndDate="${this.periodEndDate}"
10445
10866
  @field-change="${this._handleFieldChange}"
10446
10867
  @typed-member-change="${this._handleTypedMemberChange}"
10868
+ @add-concept-repeat="${this._handleAddConceptRepeat}"
10869
+ @remove-concept-repeat="${this._handleRemoveConceptRepeat}"
10447
10870
  @section-expand="${this._handleSectionExpand}"
10448
10871
  @concept-expand="${this._handleConceptExpand}"
10449
10872
  @column-remove="${this._handleColumnRemove}"
@@ -10713,7 +11136,7 @@ JupiterDynamicForm.styles = css`
10713
11136
  right: 0;
10714
11137
  padding: 16px 24px;
10715
11138
  border-top: 1px solid var(--jupiter-border-color, #ddd);
10716
- background: var(--jupiter-form-actions-background, #f8f9fa);
11139
+ background: var(--bg-color-2, var(--jupiter-form-actions-background, #f8f9fa));
10717
11140
  display: flex;
10718
11141
  gap: 12px;
10719
11142
  align-items: center;
@@ -10724,6 +11147,7 @@ JupiterDynamicForm.styles = css`
10724
11147
  .form-sections {
10725
11148
  padding: 24px;
10726
11149
  padding-bottom: 100px; /* Add space for fixed footer */
11150
+ background: var(--bg-color-2);
10727
11151
  }
10728
11152
 
10729
11153
  .validation-summary {
@@ -10761,22 +11185,23 @@ JupiterDynamicForm.styles = css`
10761
11185
  }
10762
11186
 
10763
11187
  .btn-primary {
10764
- background: var(--jupiter-primary-color, #1976d2);
10765
- color: white;
11188
+ background: var(--buttonBgColor, var(--jupiter-primary-color, #1976d2));
11189
+ color: var(--buttonTextColor, white);
10766
11190
  }
10767
11191
 
10768
- .btn-primary:hover:not(:disabled) {
10769
- background: var(--jupiter-primary-color-dark, #1565c0);
10770
- }
11192
+ // .btn-primary:hover:not(:disabled) {
11193
+ // background: var(--jupiter-primary-color-dark, #1565c0);
11194
+ // }
10771
11195
 
10772
11196
  .btn-secondary {
10773
- background: var(--jupiter-secondary-color, #757575);
10774
- color: white;
11197
+ color: var(--buttonBgColor, var(--jupiter-primary-color, #1976d2));
11198
+ border: 1px solid var(--buttonBgColor, var(--jupiter-primary-color, #1976d2)) !important;
11199
+ background: transparent;
10775
11200
  }
10776
11201
 
10777
- .btn-secondary:hover:not(:disabled) {
10778
- background: var(--jupiter-secondary-color-dark, #616161);
10779
- }
11202
+ // .btn-secondary:hover:not(:disabled) {
11203
+ // background: var(--jupiter-secondary-color-dark, #616161);
11204
+ // }
10780
11205
 
10781
11206
  .btn-outline {
10782
11207
  background: transparent;
@@ -10854,7 +11279,7 @@ JupiterDynamicForm.styles = css`
10854
11279
  padding: 8px 16px;
10855
11280
  background: transparent;
10856
11281
  border: 1px solid var(--jupiter-primary-color, #1976d2);
10857
- color: var(--jupiter-primary-color, #1976d2);
11282
+ color: var(--primaryTextColor, var(--jupiter-primary-color, #1976d2));
10858
11283
  border-radius: 4px;
10859
11284
  font-size: 13px;
10860
11285
  font-weight: 500;
@@ -10863,10 +11288,10 @@ JupiterDynamicForm.styles = css`
10863
11288
  margin-right: auto;
10864
11289
  }
10865
11290
 
10866
- .filter-roles-button:hover:not(:disabled) {
10867
- background: var(--jupiter-primary-color, #1976d2);
10868
- color: white;
10869
- }
11291
+ // .filter-roles-button:hover:not(:disabled) {
11292
+ // background: var(--jupiter-primary-color, #1976d2);
11293
+ // color: white;
11294
+ // }
10870
11295
 
10871
11296
  .filter-roles-button .filter-icon {
10872
11297
  width: 16px;
@@ -10877,8 +11302,8 @@ JupiterDynamicForm.styles = css`
10877
11302
  .roles-count {
10878
11303
  display: inline-flex;
10879
11304
  align-items: center;
10880
- background: var(--jupiter-primary-color, #1976d2);
10881
- color: white;
11305
+ background: var(--primaryTextColor, var(--jupiter-primary-color, #1976d2));
11306
+ color: var(--headerBgColor, white) !important;
10882
11307
  border-radius: 10px;
10883
11308
  font-size: 11px;
10884
11309
  font-weight: 600;
@@ -10917,9 +11342,9 @@ JupiterDynamicForm.styles = css`
10917
11342
  .side-panel-roles-list {
10918
11343
  width: 280px;
10919
11344
  min-width: 280px;
10920
- border-right: 1px solid var(--jupiter-border-color, #ddd);
11345
+ border-right: 1px solid var(--primaryTextColor, var(--jupiter-border-color, #ddd));
10921
11346
  overflow-y: auto;
10922
- background: var(--jupiter-background-light, #f8f9fa);
11347
+ background: var(--bg-color-2, var(--jupiter-background-light, #f8f9fa));
10923
11348
  display: flex;
10924
11349
  flex-direction: column;
10925
11350
  transition: width 0.3s ease, min-width 0.3s ease;
@@ -10939,8 +11364,10 @@ JupiterDynamicForm.styles = css`
10939
11364
  right: 0px;
10940
11365
  width: 32px;
10941
11366
  height: 32px;
10942
- border: 1px solid var(--jupiter-border-color, #ddd);
10943
- background: var(--jupiter-background, #fff);
11367
+ border: 1px solid var(--primaryTextColor, var(--jupiter-border-color, #ddd));
11368
+ background: var(--bg-color-2, var(--jupiter-background, #fff));
11369
+ color: var(--primaryTextColor);
11370
+
10944
11371
  border-radius: 4px;
10945
11372
  cursor: pointer;
10946
11373
  display: flex;
@@ -10948,7 +11375,6 @@ JupiterDynamicForm.styles = css`
10948
11375
  justify-content: center;
10949
11376
  z-index: 100;
10950
11377
  transition: all 0.2s ease;
10951
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
10952
11378
  }
10953
11379
 
10954
11380
  .side-panel-toggle-btn:hover {
@@ -10972,7 +11398,7 @@ JupiterDynamicForm.styles = css`
10972
11398
  position: sticky;
10973
11399
  top: 0;
10974
11400
  z-index: 10;
10975
- background: var(--jupiter-background, #fff);
11401
+ background: var(--bg-color-2, var(--jupiter-background, #fff));
10976
11402
  padding: 16px;
10977
11403
  border-bottom: 1px solid var(--jupiter-border-color, #ddd);
10978
11404
  }
@@ -10980,21 +11406,21 @@ JupiterDynamicForm.styles = css`
10980
11406
  .side-panel-search-input {
10981
11407
  width: 100%;
10982
11408
  padding: 10px 40px 10px 12px;
10983
- border: 1px solid var(--jupiter-border-color, #ddd);
11409
+ border: 1px solid var(--primaryTextColor, var(--jupiter-border-color, #ddd));
10984
11410
  border-radius: 4px;
10985
11411
  font-size: 14px;
10986
11412
  font-family: inherit;
10987
- background: var(--jupiter-background, #fff);
10988
- color: var(--jupiter-text-primary, #333);
11413
+ background: transparent;
11414
+ color: var(--primaryTextColor, var(--jupiter-text-primary, #333));
10989
11415
  transition: border-color 0.2s ease;
10990
11416
  box-sizing: border-box;
10991
11417
  }
10992
11418
 
10993
- .side-panel-search-input:focus {
10994
- outline: none;
10995
- border-color: var(--jupiter-primary-color, #1976d2);
10996
- box-shadow: 0 0 0 2px rgba(25, 118, 210, 0.1);
10997
- }
11419
+ // .side-panel-search-input:focus {
11420
+ // outline: none;
11421
+ // border-color: var(--jupiter-primary-color, #1976d2);
11422
+ // box-shadow: 0 0 0 2px rgba(25, 118, 210, 0.1);
11423
+ // }
10998
11424
 
10999
11425
  .side-panel-search-input::placeholder {
11000
11426
  color: var(--jupiter-text-secondary, #666);
@@ -11054,16 +11480,16 @@ JupiterDynamicForm.styles = css`
11054
11480
  border-bottom: 1px solid var(--jupiter-border-color, #e0e0e0);
11055
11481
  transition: background-color 0.2s ease;
11056
11482
  font-size: 14px;
11057
- color: var(--jupiter-text-primary, #333);
11483
+ color: var(--primaryTextColor, var(--jupiter-text-primary, #333));
11058
11484
  line-height: 1.4;
11059
11485
  }
11060
11486
 
11061
- .side-panel-role-item:hover {
11062
- background: var(--jupiter-hover-background, #e8e8e8);
11063
- }
11487
+ // .side-panel-role-item:hover {
11488
+ // background: var(--jupiter-hover-background, #e8e8e8);
11489
+ // }
11064
11490
 
11065
11491
  .side-panel-role-item.active {
11066
- background: var(--jupiter-primary-color, #1976d2);
11492
+ background: var(--light-color-1, var(--jupiter-primary-color, #1976d2));
11067
11493
  color: white;
11068
11494
  font-weight: 500;
11069
11495
  }
@@ -11511,6 +11937,9 @@ __decorateClass([
11511
11937
  __decorateClass([
11512
11938
  r()
11513
11939
  ], JupiterDynamicForm.prototype, "_preservedTypedMemberData", 2);
11940
+ __decorateClass([
11941
+ r()
11942
+ ], JupiterDynamicForm.prototype, "_repeatCounts", 2);
11514
11943
  __decorateClass([
11515
11944
  r()
11516
11945
  ], JupiterDynamicForm.prototype, "_columns", 2);