df-ae-forms-package 1.0.89 → 1.0.90
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.esm.js +48 -39
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +48 -39
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -5304,6 +5304,12 @@ const DfFormTable$1 = React.lazy(() => Promise.resolve().then(function () { retu
|
|
|
5304
5304
|
const DfFormPreview = ({ formComponents = [], currentDevice = 'desktop', isPreviewMode = false, initialFormData = [], onSubmit, onFormDataChange, formTitle, formDescription, formTemplateId,
|
|
5305
5305
|
// Add component management props for edit mode
|
|
5306
5306
|
onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, selectedComponent, workOrderNumber, assetNumber, isStandalone, user, onCreateIssue, onUpdateIssue }) => {
|
|
5307
|
+
// Local copy of formComponents so structure updates (e.g. table cell init) are reflected immediately
|
|
5308
|
+
const [localFormComponents, setLocalFormComponents] = useState(formComponents);
|
|
5309
|
+
// Sync local state when the prop changes from the parent
|
|
5310
|
+
useEffect(() => {
|
|
5311
|
+
setLocalFormComponents(formComponents);
|
|
5312
|
+
}, [formComponents]);
|
|
5307
5313
|
// Form state
|
|
5308
5314
|
const [formValues, setFormValues] = useState({});
|
|
5309
5315
|
const [validationErrors, setValidationErrors] = useState({});
|
|
@@ -5324,7 +5330,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5324
5330
|
// Initialize form state
|
|
5325
5331
|
useEffect(() => {
|
|
5326
5332
|
initializeFormState();
|
|
5327
|
-
}, [
|
|
5333
|
+
}, [localFormComponents, initialFormData]);
|
|
5328
5334
|
// Recursive function to initialize values from nested components
|
|
5329
5335
|
const initializeComponentValues = (components, values) => {
|
|
5330
5336
|
components.forEach(component => {
|
|
@@ -5494,11 +5500,11 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5494
5500
|
});
|
|
5495
5501
|
};
|
|
5496
5502
|
// Initialize validated components
|
|
5497
|
-
let validatedFormComponents =
|
|
5498
|
-
if (
|
|
5499
|
-
validatedFormComponents = getValidatedComponents(
|
|
5503
|
+
let validatedFormComponents = localFormComponents;
|
|
5504
|
+
if (localFormComponents && localFormComponents.length > 0) {
|
|
5505
|
+
validatedFormComponents = getValidatedComponents(localFormComponents);
|
|
5500
5506
|
// Notifying parent of changed components if they were mutated (IDs added/fixed)
|
|
5501
|
-
if (JSON.stringify(validatedFormComponents) !== JSON.stringify(
|
|
5507
|
+
if (JSON.stringify(validatedFormComponents) !== JSON.stringify(localFormComponents)) {
|
|
5502
5508
|
onFormDataChange?.(validatedFormComponents);
|
|
5503
5509
|
}
|
|
5504
5510
|
}
|
|
@@ -5526,7 +5532,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5526
5532
|
setComponentAttachments(prev => ({ ...initialAttachments, ...prev }));
|
|
5527
5533
|
// Conditional logic evaluation disabled temporarily to fix table issues
|
|
5528
5534
|
// evaluateConditionalLogic()
|
|
5529
|
-
}, [initialFormData,
|
|
5535
|
+
}, [initialFormData, localFormComponents]);
|
|
5530
5536
|
// Conditional logic disabled temporarily - all components are always visible
|
|
5531
5537
|
const shouldShowComponent = useCallback((_componentId) => {
|
|
5532
5538
|
return true;
|
|
@@ -5539,7 +5545,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5539
5545
|
return;
|
|
5540
5546
|
}
|
|
5541
5547
|
// CRITICAL: Check if multiple components share this ID (ID collision detection)
|
|
5542
|
-
const componentsWithSameId =
|
|
5548
|
+
const componentsWithSameId = localFormComponents.filter(comp => comp.id === change.id);
|
|
5543
5549
|
if (componentsWithSameId.length > 1) {
|
|
5544
5550
|
console.error(`[DfFormPreview] ID COLLISION DETECTED! Multiple components share ID "${change.id}":`, componentsWithSameId.map(c => ({ id: c.id, name: c.name, label: c.basic?.label })));
|
|
5545
5551
|
// Don't update - this would cause all components with this ID to get the same value
|
|
@@ -5560,7 +5566,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5560
5566
|
}
|
|
5561
5567
|
// Clear raised issues for this component when value changes
|
|
5562
5568
|
// This ensures that if threshold condition changes, user must raise issue again
|
|
5563
|
-
const component =
|
|
5569
|
+
const component = localFormComponents.find(comp => comp.id === change.id);
|
|
5564
5570
|
if (component) {
|
|
5565
5571
|
const threshold = component?.threshold;
|
|
5566
5572
|
if (threshold && threshold.conditions && threshold.conditions.length > 0) {
|
|
@@ -5638,7 +5644,10 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5638
5644
|
});
|
|
5639
5645
|
};
|
|
5640
5646
|
// Update form components
|
|
5641
|
-
const updatedComponents = updateComponentValue(
|
|
5647
|
+
const updatedComponents = updateComponentValue(localFormComponents);
|
|
5648
|
+
// CRITICAL: Update local state immediately so structure changes (e.g. table cell init)
|
|
5649
|
+
// are reflected without waiting for Angular parent round-trip
|
|
5650
|
+
setLocalFormComponents(updatedComponents);
|
|
5642
5651
|
onFormDataChange?.(updatedComponents);
|
|
5643
5652
|
// Clear validation errors when user starts typing and re-validate
|
|
5644
5653
|
if (validationErrors[change.id]) {
|
|
@@ -5675,7 +5684,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5675
5684
|
}
|
|
5676
5685
|
// Conditional logic evaluation disabled temporarily
|
|
5677
5686
|
// evaluateConditionalLogic(newFormValues, updatedComponents)
|
|
5678
|
-
}, [
|
|
5687
|
+
}, [localFormComponents, formValues, validationErrors, onFormDataChange]);
|
|
5679
5688
|
// Recursive function to find a component by ID in nested structures
|
|
5680
5689
|
const findComponentById = useCallback((components, fieldId) => {
|
|
5681
5690
|
for (const comp of components) {
|
|
@@ -5719,7 +5728,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5719
5728
|
if (isPreviewMode)
|
|
5720
5729
|
return;
|
|
5721
5730
|
// Find component recursively (handles nested components)
|
|
5722
|
-
const component = findComponentById(
|
|
5731
|
+
const component = findComponentById(localFormComponents, fieldId);
|
|
5723
5732
|
if (!component)
|
|
5724
5733
|
return;
|
|
5725
5734
|
// Get current value from form values (real-time input)
|
|
@@ -5814,7 +5823,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5814
5823
|
...prev,
|
|
5815
5824
|
[fieldId]: errorMessage
|
|
5816
5825
|
}));
|
|
5817
|
-
}, [
|
|
5826
|
+
}, [localFormComponents, isPreviewMode, formValues, findComponentById]);
|
|
5818
5827
|
// Handle form control blur
|
|
5819
5828
|
const onFormControlBlur = useCallback((fieldId) => {
|
|
5820
5829
|
setTouchedFields(prev => ({
|
|
@@ -5844,11 +5853,11 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5844
5853
|
// useEffect(() => {
|
|
5845
5854
|
// if (!isPreviewMode && Object.keys(formValues).length > 0) {
|
|
5846
5855
|
// // Validate all form components when form values change (but not on initial load)
|
|
5847
|
-
//
|
|
5856
|
+
// localFormComponents.forEach(component => {
|
|
5848
5857
|
// validateField(component.id)
|
|
5849
5858
|
// })
|
|
5850
5859
|
// }
|
|
5851
|
-
// }, [formValues, validateField, isPreviewMode,
|
|
5860
|
+
// }, [formValues, validateField, isPreviewMode, localFormComponents])
|
|
5852
5861
|
// Enhanced form validity check
|
|
5853
5862
|
const isFormValid = useCallback(() => {
|
|
5854
5863
|
// Check if there are any validation errors
|
|
@@ -5857,7 +5866,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5857
5866
|
return false;
|
|
5858
5867
|
}
|
|
5859
5868
|
// Check required fields
|
|
5860
|
-
return
|
|
5869
|
+
return localFormComponents.every(component => {
|
|
5861
5870
|
// Use real-time form values instead of component values
|
|
5862
5871
|
const currentValue = formValues[component.id] || '';
|
|
5863
5872
|
// Check if field has a value
|
|
@@ -5903,7 +5912,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5903
5912
|
}
|
|
5904
5913
|
return true;
|
|
5905
5914
|
});
|
|
5906
|
-
}, [
|
|
5915
|
+
}, [localFormComponents, formValues, validationErrors]);
|
|
5907
5916
|
// Evaluate threshold condition (handles both numeric and string values)
|
|
5908
5917
|
const evaluateThresholdCondition = useCallback((condition, currentVal) => {
|
|
5909
5918
|
// Handle array values (for checkbox)
|
|
@@ -5957,7 +5966,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5957
5966
|
if (isPreviewMode)
|
|
5958
5967
|
return [];
|
|
5959
5968
|
const metConditions = [];
|
|
5960
|
-
|
|
5969
|
+
localFormComponents.forEach(component => {
|
|
5961
5970
|
const condition = component?.condition;
|
|
5962
5971
|
if (!condition || !condition.conditions || condition.conditions.length === 0) {
|
|
5963
5972
|
return;
|
|
@@ -5983,7 +5992,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
5983
5992
|
});
|
|
5984
5993
|
});
|
|
5985
5994
|
return metConditions;
|
|
5986
|
-
}, [
|
|
5995
|
+
}, [localFormComponents, formValues, isPreviewMode, evaluateThresholdCondition]);
|
|
5987
5996
|
// Validate threshold conditions - check if all met conditions have all mandatory actions completed
|
|
5988
5997
|
const validateThresholdConditions = useCallback(() => {
|
|
5989
5998
|
if (isPreviewMode)
|
|
@@ -6068,7 +6077,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6068
6077
|
let isValid = true;
|
|
6069
6078
|
setFormSubmitted(true);
|
|
6070
6079
|
const errors = {};
|
|
6071
|
-
|
|
6080
|
+
localFormComponents.forEach(component => {
|
|
6072
6081
|
// Use real-time form values instead of component values
|
|
6073
6082
|
const currentValue = formValues[component.id] || '';
|
|
6074
6083
|
// Check if field has a value
|
|
@@ -6135,13 +6144,13 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6135
6144
|
});
|
|
6136
6145
|
setValidationErrors(errors);
|
|
6137
6146
|
return isValid;
|
|
6138
|
-
}, [
|
|
6147
|
+
}, [localFormComponents, isPreviewMode, formValues]);
|
|
6139
6148
|
// Handle form submission
|
|
6140
6149
|
const handleSubmit = useCallback((status = 'Submitted') => {
|
|
6141
6150
|
setFormSubmitted(true);
|
|
6142
6151
|
if (!validateAllFields()) {
|
|
6143
6152
|
// Focus on the first invalid field
|
|
6144
|
-
const firstErrorField =
|
|
6153
|
+
const firstErrorField = localFormComponents.find(comp => {
|
|
6145
6154
|
const currentValue = formValues[comp.id] || '';
|
|
6146
6155
|
// Check if field has a value
|
|
6147
6156
|
let hasValue = false;
|
|
@@ -6244,12 +6253,12 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6244
6253
|
});
|
|
6245
6254
|
};
|
|
6246
6255
|
// Prepare final form data
|
|
6247
|
-
const finalFormData = updateComponentValues(
|
|
6256
|
+
const finalFormData = updateComponentValues(localFormComponents);
|
|
6248
6257
|
// Also prepare a clean key-value payload
|
|
6249
6258
|
const payloadValues = { ...formValues, status };
|
|
6250
6259
|
// Pass both the updated component tree and the flat values object
|
|
6251
6260
|
onSubmit?.(finalFormData, payloadValues);
|
|
6252
|
-
}, [
|
|
6261
|
+
}, [localFormComponents, formValues, validateAllFields, onSubmit, componentNotes, componentAttachments]);
|
|
6253
6262
|
// Get preview classes
|
|
6254
6263
|
const getPreviewClasses = useCallback(() => {
|
|
6255
6264
|
return {
|
|
@@ -6311,7 +6320,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6311
6320
|
// Debug: Log if formValue is being shared incorrectly
|
|
6312
6321
|
if (formValue !== undefined) {
|
|
6313
6322
|
// Check if this value is being used by multiple components
|
|
6314
|
-
const componentsWithSameValue =
|
|
6323
|
+
const componentsWithSameValue = localFormComponents.filter(comp => comp.id !== componentId && formValues[comp.id] === formValue);
|
|
6315
6324
|
if (componentsWithSameValue.length > 0) {
|
|
6316
6325
|
console.warn(`[DfFormPreview] Component ${componentId} shares form value with other components:`, componentsWithSameValue.map(c => c.id));
|
|
6317
6326
|
}
|
|
@@ -6410,7 +6419,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6410
6419
|
return renderFormComponent(field);
|
|
6411
6420
|
}, onNotesChange: (componentId, notes) => {
|
|
6412
6421
|
// Handle notes change for table cell components
|
|
6413
|
-
const updatedComponents =
|
|
6422
|
+
const updatedComponents = localFormComponents.map(comp => {
|
|
6414
6423
|
if (comp.id === component.id && comp.cells) {
|
|
6415
6424
|
const updatedCells = comp.cells.map((row) => Array.isArray(row) ? row.map((cell) => {
|
|
6416
6425
|
if (cell.components) {
|
|
@@ -6437,7 +6446,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6437
6446
|
onFormDataChange?.(updatedComponents);
|
|
6438
6447
|
}, onAttachmentChange: (componentId, attachments) => {
|
|
6439
6448
|
// Handle attachment change for table cell components
|
|
6440
|
-
const updatedComponents =
|
|
6449
|
+
const updatedComponents = localFormComponents.map(comp => {
|
|
6441
6450
|
if (comp.id === component.id && comp.cells) {
|
|
6442
6451
|
const updatedCells = comp.cells.map((row) => Array.isArray(row) ? row.map((cell) => {
|
|
6443
6452
|
if (cell.components) {
|
|
@@ -6467,7 +6476,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6467
6476
|
return (jsx(DfFormDataGrid, { ...commonProps, properties: component, formData: formValues, formTemplateId: formTemplateId, mode: commonProps.mode, onThresholdActionCompletion: handleThresholdActionCompletion, onThresholdIssueRaised: handleThresholdIssueRaised, onNotesChange: (componentId, notes) => {
|
|
6468
6477
|
handleComponentNotesChange(componentId, notes);
|
|
6469
6478
|
// Handle notes change for datagrid entry components
|
|
6470
|
-
const updatedComponents =
|
|
6479
|
+
const updatedComponents = localFormComponents.map(comp => {
|
|
6471
6480
|
if (comp.id === component.id && comp.entries) {
|
|
6472
6481
|
const updatedEntries = comp.entries.map((entry) => {
|
|
6473
6482
|
if (entry.components) {
|
|
@@ -6495,7 +6504,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6495
6504
|
}, onAttachmentChange: (componentId, attachments) => {
|
|
6496
6505
|
handleComponentAttachmentChange(componentId, attachments);
|
|
6497
6506
|
// Handle attachment change for datagrid entry components
|
|
6498
|
-
const updatedComponents =
|
|
6507
|
+
const updatedComponents = localFormComponents.map(comp => {
|
|
6499
6508
|
if (comp.id === component.id && comp.entries) {
|
|
6500
6509
|
const updatedEntries = comp.entries.map((entry) => {
|
|
6501
6510
|
if (entry.components) {
|
|
@@ -6523,8 +6532,8 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6523
6532
|
}, onValueChange: (change) => {
|
|
6524
6533
|
// Handle datagrid value changes (entries updates)
|
|
6525
6534
|
if (change.id === component.id && change.value && typeof change.value === 'object' && 'entries' in change.value) {
|
|
6526
|
-
// Update
|
|
6527
|
-
const updatedComponents =
|
|
6535
|
+
// Update localFormComponents with new entries structure
|
|
6536
|
+
const updatedComponents = localFormComponents.map(comp => {
|
|
6528
6537
|
if (comp.id === component.id) {
|
|
6529
6538
|
return {
|
|
6530
6539
|
...comp,
|
|
@@ -6562,12 +6571,12 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6562
6571
|
}
|
|
6563
6572
|
}, onEntryAdd: () => {
|
|
6564
6573
|
// CRITICAL: Entry has already been added via onValueChange in DfFormDataGrid
|
|
6565
|
-
// Get the updated component from
|
|
6566
|
-
const currentComponent =
|
|
6574
|
+
// Get the updated component from localFormComponents (which should have been updated by onValueChange)
|
|
6575
|
+
const currentComponent = localFormComponents.find(comp => comp.id === component.id);
|
|
6567
6576
|
if (currentComponent && currentComponent.entries) {
|
|
6568
6577
|
// Entry should already be in the component via onValueChange
|
|
6569
|
-
// Just ensure
|
|
6570
|
-
const updatedComponents =
|
|
6578
|
+
// Just ensure localFormComponents is in sync (no-op if already synced)
|
|
6579
|
+
const updatedComponents = localFormComponents.map(comp => {
|
|
6571
6580
|
if (comp.id === component.id) {
|
|
6572
6581
|
// Ensure entries are properly structured
|
|
6573
6582
|
return {
|
|
@@ -6584,7 +6593,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6584
6593
|
setTimeout(() => {
|
|
6585
6594
|
const datagridValue = formValues[component.id];
|
|
6586
6595
|
if (datagridValue && typeof datagridValue === 'object' && 'entries' in datagridValue) {
|
|
6587
|
-
const updatedComponents =
|
|
6596
|
+
const updatedComponents = localFormComponents.map(comp => {
|
|
6588
6597
|
if (comp.id === component.id) {
|
|
6589
6598
|
return {
|
|
6590
6599
|
...comp,
|
|
@@ -6599,7 +6608,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6599
6608
|
}
|
|
6600
6609
|
}, onEntryRemove: (entryIndex) => {
|
|
6601
6610
|
// Handle entry remove - update form components
|
|
6602
|
-
const updatedComponents =
|
|
6611
|
+
const updatedComponents = localFormComponents.map(comp => {
|
|
6603
6612
|
if (comp.id === component.id && comp.entries) {
|
|
6604
6613
|
const currentEntries = comp.entries || [];
|
|
6605
6614
|
const updatedEntries = currentEntries
|
|
@@ -6641,7 +6650,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6641
6650
|
return (jsx("div", { className: "form-group", children: jsxs("div", { className: "form-group-label", children: ["Unsupported Component: ", component.name] }) }));
|
|
6642
6651
|
}
|
|
6643
6652
|
};
|
|
6644
|
-
return (jsx("div", { className: "form-preview-container", children: jsx("div", { className: "form-preview-wrapper", children: jsxs("div", { className: `form-preview ${Object.entries(getPreviewClasses()).map(([key, value]) => value ? key : '').join(' ')}`, children: [jsx("div", { className: "form-canvas-header" }),
|
|
6653
|
+
return (jsx("div", { className: "form-preview-container", children: jsx("div", { className: "form-preview-wrapper", children: jsxs("div", { className: `form-preview ${Object.entries(getPreviewClasses()).map(([key, value]) => value ? key : '').join(' ')}`, children: [jsx("div", { className: "form-canvas-header" }), localFormComponents.length === 0 ? (jsx("div", { className: "empty-state", children: jsx("div", { className: "empty-state-card", children: jsx("div", { className: "empty-state-preview-area", children: jsx("span", { className: "empty-state-placeholder", children: "Add components to see the form preview" }) }) }) })) : (jsxs("form", { className: "form-preview-form", onSubmit: (e) => { e.preventDefault(); handleSubmit(); }, children: [(formTitle || formDescription) && (jsxs("div", { className: "form-header", children: [formTitle && (jsx("h1", { className: "form-title", children: formTitle })), formDescription && (jsx("p", { className: "form-description", children: formDescription }))] })), localFormComponents.map((component) => {
|
|
6645
6654
|
const basic = component.basic;
|
|
6646
6655
|
const formValue = formValues[component.id];
|
|
6647
6656
|
const isOptionBased = ['select', 'radio', 'checkbox', 'segment'].includes(component.name || '');
|
|
@@ -6693,7 +6702,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6693
6702
|
// Update local state immediately
|
|
6694
6703
|
setComponentNotes(prev => ({ ...prev, [component.id]: notes }));
|
|
6695
6704
|
// Handle notes change for regular components - update component.basic.notes
|
|
6696
|
-
const updatedComponents =
|
|
6705
|
+
const updatedComponents = localFormComponents.map(comp => {
|
|
6697
6706
|
if (comp.id === component.id) {
|
|
6698
6707
|
return {
|
|
6699
6708
|
...comp,
|
|
@@ -6710,7 +6719,7 @@ onComponentSelect, onComponentDelete, onComponentEdit, onComponentUpdate, select
|
|
|
6710
6719
|
// Update local state immediately
|
|
6711
6720
|
setComponentAttachments(prev => ({ ...prev, [component.id]: attachments || [] }));
|
|
6712
6721
|
// Handle attachment change for regular components - update component.basic.attachments
|
|
6713
|
-
const updatedComponents =
|
|
6722
|
+
const updatedComponents = localFormComponents.map(comp => {
|
|
6714
6723
|
if (comp.id === component.id) {
|
|
6715
6724
|
return {
|
|
6716
6725
|
...comp,
|