contentoh-components-library 21.5.91 → 21.5.93
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/components/atoms/GeneralButton/styles.js +1 -1
- package/dist/components/atoms/GeneralInput/index.js +54 -245
- package/dist/components/atoms/GeneralInput/styles.js +3 -7
- package/dist/components/atoms/InputFormatter/index.js +68 -223
- package/dist/components/atoms/InputFormatter/styles.js +4 -20
- package/dist/components/molecules/StatusAsignationInfo/index.js +1 -11
- package/dist/components/molecules/TabsMenu/index.js +12 -13
- package/dist/components/molecules/TagAndInput/index.js +24 -361
- package/dist/components/molecules/TagAndInput/styles.js +2 -2
- package/dist/components/organisms/FullProductNameHeader/index.js +22 -6
- package/dist/components/organisms/InputGroup/index.js +18 -22
- package/dist/components/pages/ProviderProductEdition/index.js +47 -34
- package/dist/components/pages/ProviderProductEdition/utils.js +0 -1
- package/dist/components/pages/RetailerProductEdition/RetailerProductEdition.stories.js +196 -179
- package/dist/components/pages/RetailerProductEdition/context/provider-product-edition.context.js +260 -59
- package/dist/components/pages/RetailerProductEdition/context/reducers/product.js +38 -50
- package/dist/components/pages/RetailerProductEdition/index.js +2234 -1715
- package/dist/components/pages/RetailerProductEdition/styles.js +2 -4
- package/dist/components/pages/RetailerProductEdition/utils.js +2 -251
- package/dist/contexts/AiProductEdition.js +157 -234
- package/package.json +2 -4
- package/src/components/atoms/GeneralButton/styles.js +0 -4
- package/src/components/atoms/GeneralInput/index.js +60 -237
- package/src/components/atoms/GeneralInput/styles.js +0 -81
- package/src/components/atoms/InputFormatter/index.js +51 -200
- package/src/components/atoms/InputFormatter/styles.js +0 -284
- package/src/components/molecules/StatusAsignationInfo/index.js +1 -9
- package/src/components/molecules/TabsMenu/index.js +11 -12
- package/src/components/molecules/TagAndInput/index.js +21 -286
- package/src/components/molecules/TagAndInput/styles.js +17 -59
- package/src/components/organisms/FullProductNameHeader/index.js +28 -4
- package/src/components/organisms/FullTabsMenu/index.js +1 -1
- package/src/components/organisms/InputGroup/index.js +4 -12
- package/src/components/pages/ProviderProductEdition/index.js +69 -51
- package/src/components/pages/ProviderProductEdition/utils.js +2 -2
- package/src/components/pages/RetailerProductEdition/RetailerProductEdition.stories.js +224 -201
- package/src/components/pages/RetailerProductEdition/index.js +1718 -1546
- package/src/components/pages/RetailerProductEdition/styles.js +2 -67
- package/src/components/pages/RetailerProductEdition/utils.js +0 -240
- package/dist/ai/utils/compare-strings.js +0 -45
- package/dist/components/organisms/ChangeStatusModal/index.js +0 -531
- package/dist/components/organisms/ChangeStatusModal/styles.js +0 -85
- package/dist/global-files/statusDictionary.js +0 -103
- package/src/ai/utils/compare-strings.js +0 -45
- package/src/assets/images/Icons/arrow.png +0 -0
- package/src/assets/images/Icons/cancel.png +0 -0
- package/src/assets/images/Icons/ia-icon.png +0 -0
- package/src/assets/images/Icons/loading.svg +0 -5
- package/src/assets/images/Icons/reload.png +0 -0
- package/src/components/atoms/RetailerSelector/RetailerSelector.stories.js +0 -10
- package/src/components/atoms/RetailerSelector/index.js +0 -3
- package/src/components/atoms/RetailerSelector/styles.js +0 -0
- package/src/components/organisms/ChangeStatusModal/index.jsx +0 -488
- package/src/components/organisms/ChangeStatusModal/styles.js +0 -333
- package/src/components/pages/RetailerProductEdition/context/provider-product-edition.context.jsx +0 -575
- package/src/components/pages/RetailerProductEdition/context/provider-product-edition.reducer.js +0 -62
- package/src/components/pages/RetailerProductEdition/context/reducers/active-state.js +0 -344
- package/src/components/pages/RetailerProductEdition/context/reducers/inputs.js +0 -155
- package/src/components/pages/RetailerProductEdition/context/reducers/product.js +0 -114
- package/src/components/pages/RetailerProductEdition/context/reducers/system.js +0 -60
- package/src/components/pages/RetailerProductEdition/index_old.js +0 -1979
- package/src/components/pages/RetailerProductEdition/stories/Auditor.stories.js +0 -101
- package/src/components/pages/RetailerProductEdition/stories/ImageEditor.stories.js +0 -115
- package/src/components/pages/RetailerProductEdition/stories/TextEditor.stories.js +0 -174
- package/src/contexts/AiProductEdition.jsx +0 -344
- package/src/global-files/statusDictionary.js +0 -103
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import styled from "styled-components";
|
|
2
|
-
import { FontFamily, GlobalColors } from "../../../global-files/variables";
|
|
3
2
|
|
|
4
3
|
export const Container = styled.div`
|
|
5
4
|
display: flex;
|
|
@@ -21,8 +20,7 @@ export const Container = styled.div`
|
|
|
21
20
|
}
|
|
22
21
|
|
|
23
22
|
.product-information {
|
|
24
|
-
width: 100
|
|
25
|
-
height: 100%;
|
|
23
|
+
width: calc(100% - 341px);
|
|
26
24
|
display: flex;
|
|
27
25
|
flex-direction: column;
|
|
28
26
|
|
|
@@ -48,12 +46,6 @@ export const Container = styled.div`
|
|
|
48
46
|
padding: 10px;
|
|
49
47
|
padding-left: 0;
|
|
50
48
|
|
|
51
|
-
.action-buttons{
|
|
52
|
-
display: flex;
|
|
53
|
-
flex-direction: column;
|
|
54
|
-
gap: 1rem;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
49
|
.commentary {
|
|
58
50
|
display: flex;
|
|
59
51
|
align-items: flex-end;
|
|
@@ -95,23 +87,6 @@ export const Container = styled.div`
|
|
|
95
87
|
.feedback-box {
|
|
96
88
|
display: flex;
|
|
97
89
|
}
|
|
98
|
-
|
|
99
|
-
.required-inputs-message {
|
|
100
|
-
font-family: ${FontFamily.AvenirNext};
|
|
101
|
-
font-size: 13px;
|
|
102
|
-
color: ${GlobalColors.color_gray};
|
|
103
|
-
padding: 10px;
|
|
104
|
-
display: flex;
|
|
105
|
-
align-items: center;
|
|
106
|
-
|
|
107
|
-
p + * {
|
|
108
|
-
margin-top: 10px;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
button {
|
|
112
|
-
min-width: fit-content;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
90
|
}
|
|
116
91
|
}
|
|
117
92
|
#modal-message-box {
|
|
@@ -120,50 +95,10 @@ export const Container = styled.div`
|
|
|
120
95
|
}
|
|
121
96
|
.container {
|
|
122
97
|
width: 100%;
|
|
123
|
-
height:
|
|
98
|
+
height: 100%;
|
|
124
99
|
.dropzone {
|
|
125
100
|
height: 100%;
|
|
126
101
|
width: 100%;
|
|
127
|
-
position: relative;
|
|
128
|
-
transition: all 0.5s ease;
|
|
129
|
-
|
|
130
|
-
&.drag-active {
|
|
131
|
-
background-color: rgba(${GlobalColors.rgb_color_pink}, 0.05);
|
|
132
|
-
border: 2px dashed ${GlobalColors.color_pink};
|
|
133
|
-
border-radius: 8px;
|
|
134
|
-
|
|
135
|
-
aside {
|
|
136
|
-
opacity: 0.3;
|
|
137
|
-
pointer-events: none;
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
.drag-overlay {
|
|
142
|
-
position: absolute;
|
|
143
|
-
top: 0;
|
|
144
|
-
left: 0;
|
|
145
|
-
right: 0;
|
|
146
|
-
bottom: 0;
|
|
147
|
-
display: flex;
|
|
148
|
-
align-items: center;
|
|
149
|
-
justify-content: center;
|
|
150
|
-
background-color: rgba(${GlobalColors.rgb_color_pink}, 0.1);
|
|
151
|
-
border-radius: 8px;
|
|
152
|
-
pointer-events: none;
|
|
153
|
-
z-index: 10;
|
|
154
|
-
|
|
155
|
-
p {
|
|
156
|
-
font-family: ${FontFamily.AvenirNext};
|
|
157
|
-
font-size: 24px;
|
|
158
|
-
font-weight: 600;
|
|
159
|
-
color: ${GlobalColors.color_pink};
|
|
160
|
-
text-align: center;
|
|
161
|
-
padding: 20px;
|
|
162
|
-
background-color: ${GlobalColors.white};
|
|
163
|
-
border-radius: 8px;
|
|
164
|
-
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
102
|
}
|
|
168
103
|
}
|
|
169
104
|
`;
|
|
@@ -69,243 +69,3 @@ export const sendMessage = async (data) => {
|
|
|
69
69
|
paramsHeader
|
|
70
70
|
);
|
|
71
71
|
};
|
|
72
|
-
|
|
73
|
-
export const normalizeProduct = (product) => {
|
|
74
|
-
// Handle case where product might be wrapped in a product property
|
|
75
|
-
const productData = product.product || product;
|
|
76
|
-
const article = productData.article || {};
|
|
77
|
-
|
|
78
|
-
const categoryRetailer =
|
|
79
|
-
productData.categoryRetailer || article.categoryRetailer;
|
|
80
|
-
|
|
81
|
-
const categoryRetailerNormalized = categoryRetailer
|
|
82
|
-
? categoryRetailer.map((rel) => ({
|
|
83
|
-
id_retailer: rel.id_retailer || rel.retailer_id,
|
|
84
|
-
retailer: rel.retailer_name || rel.retailerName,
|
|
85
|
-
name: rel.retailer_name || rel.retailerName,
|
|
86
|
-
id_category: rel.id_category,
|
|
87
|
-
category: rel.category_name || rel.categoryName,
|
|
88
|
-
image: `https://content-management-images.s3.amazonaws.com/retailers/${
|
|
89
|
-
rel.id_retailer || rel.retailer_id
|
|
90
|
-
}.png`,
|
|
91
|
-
}))
|
|
92
|
-
: null;
|
|
93
|
-
|
|
94
|
-
// extraer los retailer_id de statusByRetailer donde task_group_id no sea nulo
|
|
95
|
-
const retailersIdsInOrder = productData.statusByRetailer
|
|
96
|
-
? productData.statusByRetailer.map((status) => status.retailer_id)
|
|
97
|
-
: [];
|
|
98
|
-
|
|
99
|
-
const categoryRetailerInOrder = categoryRetailerNormalized.filter((rel) =>
|
|
100
|
-
retailersIdsInOrder.includes(rel.id_retailer)
|
|
101
|
-
);
|
|
102
|
-
|
|
103
|
-
return {
|
|
104
|
-
id_article: productData.id_article || article.id_article || 0,
|
|
105
|
-
upc: productData.upc || article.upc || null,
|
|
106
|
-
sku: productData.sku || article.sku || null,
|
|
107
|
-
name: productData.name || article.name || null,
|
|
108
|
-
timestamp: productData.timestamp || article.timestamp || null,
|
|
109
|
-
id_user: productData.id_user || article.id_user || null,
|
|
110
|
-
categoryName: productData.category || article.category || null,
|
|
111
|
-
id_category: productData.id_category || article.id_category || null,
|
|
112
|
-
retailersAvailable: productData.retailersAvailable || null,
|
|
113
|
-
categoryRetailer: categoryRetailerNormalized || null,
|
|
114
|
-
percentages: productData.percentages || null,
|
|
115
|
-
summary: productData.summary || null,
|
|
116
|
-
version: productData.version || 0,
|
|
117
|
-
id_order: productData.orderId || 0,
|
|
118
|
-
status: productData.status || null,
|
|
119
|
-
datasheet_status: productData.datasheet_status || null,
|
|
120
|
-
description_status: productData.description_status || null,
|
|
121
|
-
images_status: productData.images_status || null,
|
|
122
|
-
brand: productData.brand || null,
|
|
123
|
-
services: productData.services || null,
|
|
124
|
-
country: article.country || null,
|
|
125
|
-
id_company: article.company_id || null,
|
|
126
|
-
company: article.company_name || null,
|
|
127
|
-
id_datasheet_especialist: article.id_datasheet_especialist || 0,
|
|
128
|
-
id_datasheet_facilitator: article.id_datasheet_facilitator || null,
|
|
129
|
-
id_description_especialist: article.id_description_especialist || 0,
|
|
130
|
-
id_description_facilitator: article.id_description_facilitator || null,
|
|
131
|
-
id_images_especialist: article.id_images_especialist || 0,
|
|
132
|
-
id_images_facilitator: article.id_images_facilitator || null,
|
|
133
|
-
id_auditor: article.id_auditor || 0,
|
|
134
|
-
statusByRetailer: productData.statusByRetailer || null,
|
|
135
|
-
categoryRetailerInOrder: categoryRetailerInOrder || null,
|
|
136
|
-
};
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
const TAB_TO_CONCEPT = {
|
|
140
|
-
Descripción: "description",
|
|
141
|
-
"Ficha técnica": "datasheet",
|
|
142
|
-
Imágenes: "images",
|
|
143
|
-
};
|
|
144
|
-
|
|
145
|
-
const CONCEPT_TO_TAB = {
|
|
146
|
-
description: "Descripción",
|
|
147
|
-
datasheet: "Ficha técnica",
|
|
148
|
-
images: "Imágenes",
|
|
149
|
-
};
|
|
150
|
-
|
|
151
|
-
export const getConceptByTab = (tab) => TAB_TO_CONCEPT[tab];
|
|
152
|
-
|
|
153
|
-
export const translateConcept = (concept) => CONCEPT_TO_TAB[concept];
|
|
154
|
-
|
|
155
|
-
export const getStatusArrayByRole = (idRole) => {
|
|
156
|
-
switch (idRole) {
|
|
157
|
-
case 7:
|
|
158
|
-
case 8:
|
|
159
|
-
return ["PA", "AS", "CA", "RC", "RA", "RP", "RCA"];
|
|
160
|
-
case 4:
|
|
161
|
-
case 5:
|
|
162
|
-
return ["RC", "AC", "AA", "AP", "ACA"];
|
|
163
|
-
case 6:
|
|
164
|
-
return ["RP", "RCA", "AC", "RA"];
|
|
165
|
-
default:
|
|
166
|
-
return [];
|
|
167
|
-
}
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
export const getConceptsByRole = (idRole) => {
|
|
171
|
-
switch (idRole) {
|
|
172
|
-
case 4:
|
|
173
|
-
return ["description", "datasheet"];
|
|
174
|
-
case 5:
|
|
175
|
-
return ["images"];
|
|
176
|
-
default:
|
|
177
|
-
return ["description", "datasheet", "images"];
|
|
178
|
-
}
|
|
179
|
-
};
|
|
180
|
-
|
|
181
|
-
export const buildCollaboratorAssignations = (product, users) => ({
|
|
182
|
-
Descripción: {
|
|
183
|
-
assignations: [
|
|
184
|
-
{
|
|
185
|
-
collaboratorType: "especialist",
|
|
186
|
-
id: product.id_description_especialist,
|
|
187
|
-
},
|
|
188
|
-
{
|
|
189
|
-
collaboratorType: "facilitator",
|
|
190
|
-
id: product.id_description_facilitator,
|
|
191
|
-
},
|
|
192
|
-
],
|
|
193
|
-
collaborators: {
|
|
194
|
-
especialist: users[0] || [],
|
|
195
|
-
facilitator: users[2] || [],
|
|
196
|
-
},
|
|
197
|
-
},
|
|
198
|
-
"Ficha técnica": {
|
|
199
|
-
assignations: [
|
|
200
|
-
{
|
|
201
|
-
collaboratorType: "especialist",
|
|
202
|
-
id: product.id_datasheet_especialist,
|
|
203
|
-
},
|
|
204
|
-
{
|
|
205
|
-
collaboratorType: "facilitator",
|
|
206
|
-
id: product.id_datasheet_facilitator,
|
|
207
|
-
},
|
|
208
|
-
],
|
|
209
|
-
collaborators: {
|
|
210
|
-
especialist: users[0] || [],
|
|
211
|
-
facilitator: users[2] || [],
|
|
212
|
-
},
|
|
213
|
-
},
|
|
214
|
-
Imágenes: {
|
|
215
|
-
assignations: [
|
|
216
|
-
{
|
|
217
|
-
collaboratorType: "especialist",
|
|
218
|
-
id: product.id_images_especialist,
|
|
219
|
-
},
|
|
220
|
-
{
|
|
221
|
-
collaboratorType: "facilitator",
|
|
222
|
-
id: product.id_images_facilitator,
|
|
223
|
-
},
|
|
224
|
-
],
|
|
225
|
-
collaborators: {
|
|
226
|
-
especialist: users[1] || [],
|
|
227
|
-
facilitator: users[3] || [],
|
|
228
|
-
},
|
|
229
|
-
},
|
|
230
|
-
});
|
|
231
|
-
|
|
232
|
-
export const calculateRequiredNull = (services, servicesData, activeRetailerId) => {
|
|
233
|
-
const result = {
|
|
234
|
-
"Ficha técnica": 0,
|
|
235
|
-
Descripción: 0,
|
|
236
|
-
Imágenes: 0,
|
|
237
|
-
};
|
|
238
|
-
|
|
239
|
-
const isServiceRequested = (retailerId, concept) =>
|
|
240
|
-
servicesData?.some(
|
|
241
|
-
(srv) => srv.id_retailer === retailerId && srv.service === concept
|
|
242
|
-
);
|
|
243
|
-
|
|
244
|
-
// Ficha técnica: contar inputs requeridos sin valor
|
|
245
|
-
const datasheetInputs = services[0]?.inputs || {};
|
|
246
|
-
const datasheetsByRetailer = Object.values(services[0]).filter(
|
|
247
|
-
(item) => item?.retailer?.id === activeRetailerId
|
|
248
|
-
);
|
|
249
|
-
|
|
250
|
-
datasheetsByRetailer.forEach((datasheet) => {
|
|
251
|
-
if (!isServiceRequested(datasheet.retailer?.id, "datasheet")) return;
|
|
252
|
-
|
|
253
|
-
Object.values(datasheet.data || {}).forEach((dataGroup) => {
|
|
254
|
-
dataGroup.inputs?.forEach((inputId) => {
|
|
255
|
-
const input = datasheetInputs[inputId];
|
|
256
|
-
if (
|
|
257
|
-
input?.required &&
|
|
258
|
-
input?.id_retailer === activeRetailerId &&
|
|
259
|
-
!input?.value
|
|
260
|
-
) {
|
|
261
|
-
result["Ficha técnica"]++;
|
|
262
|
-
}
|
|
263
|
-
});
|
|
264
|
-
});
|
|
265
|
-
});
|
|
266
|
-
|
|
267
|
-
// Descripción: contar inputs requeridos sin valor
|
|
268
|
-
const htmlTagsRegex = /(<\/?p>)|(<\/?strong>)|(<br>)/gm;
|
|
269
|
-
const descriptions = services[1]?.filter(
|
|
270
|
-
(desc) => desc.id === activeRetailerId
|
|
271
|
-
);
|
|
272
|
-
|
|
273
|
-
descriptions?.forEach((description) => {
|
|
274
|
-
if (!isServiceRequested(description.id, "description")) return;
|
|
275
|
-
|
|
276
|
-
description.inputs?.forEach((input) => {
|
|
277
|
-
const valueClean = input.value?.replace(htmlTagsRegex, "") || "";
|
|
278
|
-
if (input.required && !valueClean) {
|
|
279
|
-
result["Descripción"]++;
|
|
280
|
-
}
|
|
281
|
-
});
|
|
282
|
-
});
|
|
283
|
-
|
|
284
|
-
// Imágenes: contar imágenes requeridas sin valor
|
|
285
|
-
const retailerMandatories = services[2]?.retailerMandatories?.flat() || [];
|
|
286
|
-
const requestedRetailers = retailerMandatories.filter((rm) =>
|
|
287
|
-
servicesData?.some((srv) => srv.id_retailer === rm.id_retailer)
|
|
288
|
-
);
|
|
289
|
-
|
|
290
|
-
const requiredImageIds = new Set(
|
|
291
|
-
requestedRetailers
|
|
292
|
-
.filter((rm) =>
|
|
293
|
-
services[2]?.inputs?.some(
|
|
294
|
-
(input) => input.id === rm.id_image && input.required === 1
|
|
295
|
-
)
|
|
296
|
-
)
|
|
297
|
-
.map((rm) => rm.id_image)
|
|
298
|
-
);
|
|
299
|
-
|
|
300
|
-
const existingImageIds = new Set(
|
|
301
|
-
services[2]?.values?.map((img) => img.image_id) || []
|
|
302
|
-
);
|
|
303
|
-
|
|
304
|
-
requiredImageIds.forEach((imageId) => {
|
|
305
|
-
if (!existingImageIds.has(imageId)) {
|
|
306
|
-
result["Imágenes"]++;
|
|
307
|
-
}
|
|
308
|
-
});
|
|
309
|
-
|
|
310
|
-
return result;
|
|
311
|
-
};
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.getTextSimilarityPercentage = getTextSimilarityPercentage;
|
|
7
|
-
|
|
8
|
-
//Calcula el porcentaje de similitud entre la descripción generada por IA y la versión editada por el usuario.
|
|
9
|
-
function getTextSimilarityPercentage(originalText, candidateText) {
|
|
10
|
-
if (!originalText || !candidateText) return;
|
|
11
|
-
|
|
12
|
-
var normalize = function normalize(text) {
|
|
13
|
-
return text.trim().toLowerCase().replace(/\s+/g, ' ');
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
var source = normalize(originalText);
|
|
17
|
-
var target = normalize(candidateText);
|
|
18
|
-
if (source === target) return 100;
|
|
19
|
-
if (source.length === 0 || target.length === 0) return 0;
|
|
20
|
-
var sourceLength = source.length;
|
|
21
|
-
var targetLength = target.length;
|
|
22
|
-
var distanceMatrix = Array(targetLength + 1).fill(null).map(function () {
|
|
23
|
-
return [];
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
for (var i = 0; i <= sourceLength; i++) {
|
|
27
|
-
distanceMatrix[0][i] = i;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
for (var j = 0; j <= targetLength; j++) {
|
|
31
|
-
distanceMatrix[j][0] = j;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
for (var _j = 1; _j <= targetLength; _j++) {
|
|
35
|
-
for (var _i = 1; _i <= sourceLength; _i++) {
|
|
36
|
-
var substitutionCost = source[_i - 1] === target[_j - 1] ? 0 : 1;
|
|
37
|
-
distanceMatrix[_j][_i] = Math.min(distanceMatrix[_j - 1][_i] + 1, distanceMatrix[_j][_i - 1] + 1, distanceMatrix[_j - 1][_i - 1] + substitutionCost);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
var editDistance = distanceMatrix[targetLength][sourceLength];
|
|
42
|
-
var maxLength = Math.max(sourceLength, targetLength);
|
|
43
|
-
var similarityScore = 1 - editDistance / maxLength;
|
|
44
|
-
return similarityScore * 100;
|
|
45
|
-
}
|