@konfuzio/document-validation-ui 0.1.34-patch.1 → 0.1.35-dev.1
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/css/app.css +1 -1
- package/dist/index.html +1 -1
- package/dist/js/app.js +1 -1
- package/dist/js/app.js.map +1 -1
- package/dist/js/chunk-vendors.js +1 -1
- package/dist/js/chunk-vendors.js.map +1 -1
- package/package.json +1 -1
- package/src/assets/scss/annotation_details.scss +3 -0
- package/src/assets/scss/document_annotations.scss +7 -1
- package/src/components/DocumentAnnotations/AnnotationContent.vue +54 -0
- package/src/components/DocumentAnnotations/AnnotationDetails.vue +118 -104
- package/src/components/DocumentAnnotations/AnnotationRow.vue +5 -1
- package/src/components/DocumentPage/BoxSelection.vue +1 -0
- package/src/components/DocumentPage/DocumentPage.vue +45 -3
- package/src/icons.js +3 -1
- package/src/locales/de.json +2 -1
- package/src/locales/en.json +3 -2
- package/src/locales/es.json +2 -1
package/package.json
CHANGED
|
@@ -269,6 +269,7 @@
|
|
|
269
269
|
width: 60%;
|
|
270
270
|
display: flex;
|
|
271
271
|
align-items: center;
|
|
272
|
+
padding-right: 12px;
|
|
272
273
|
|
|
273
274
|
.notification {
|
|
274
275
|
background-color: transparent;
|
|
@@ -279,12 +280,17 @@
|
|
|
279
280
|
font-size: 14px;
|
|
280
281
|
line-height: 20px;
|
|
281
282
|
font-weight: 400;
|
|
283
|
+
padding: 0 8px;
|
|
282
284
|
|
|
283
285
|
.annotation,
|
|
284
286
|
.empty-annotation {
|
|
285
287
|
min-height: 36px;
|
|
286
288
|
display: flex;
|
|
287
289
|
align-items: center;
|
|
290
|
+
|
|
291
|
+
.annotation-checkbox {
|
|
292
|
+
margin-right: 0px;
|
|
293
|
+
}
|
|
288
294
|
}
|
|
289
295
|
|
|
290
296
|
.loading-container {
|
|
@@ -311,7 +317,7 @@
|
|
|
311
317
|
.annotation-value {
|
|
312
318
|
display: inline-block;
|
|
313
319
|
color: $text;
|
|
314
|
-
padding: 0
|
|
320
|
+
padding: 0;
|
|
315
321
|
border: none;
|
|
316
322
|
background-color: transparent;
|
|
317
323
|
inline-size: 100%;
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div :id="annotation.id" ref="annotation" class="annotation">
|
|
3
|
+
<b-checkbox
|
|
4
|
+
v-if="annotation.metadata && annotation.metadata.checkbox"
|
|
5
|
+
v-model="isChecked"
|
|
6
|
+
class="annotation-checkbox"
|
|
7
|
+
/>
|
|
3
8
|
<span
|
|
4
9
|
:id="annotation.id"
|
|
5
10
|
ref="contentEditable"
|
|
@@ -56,8 +61,16 @@ export default {
|
|
|
56
61
|
},
|
|
57
62
|
},
|
|
58
63
|
data() {
|
|
64
|
+
const checkboxValue =
|
|
65
|
+
this.annotation &&
|
|
66
|
+
this.annotation.metadata &&
|
|
67
|
+
this.annotation.metadata.checkbox &&
|
|
68
|
+
this.annotation.metadata.checkbox.is_checked;
|
|
59
69
|
return {
|
|
60
70
|
isLoading: false,
|
|
71
|
+
checkboxDefaultValue: checkboxValue,
|
|
72
|
+
isCheckboxAvailable: false,
|
|
73
|
+
isChecked: checkboxValue,
|
|
61
74
|
};
|
|
62
75
|
},
|
|
63
76
|
computed: {
|
|
@@ -91,9 +104,50 @@ export default {
|
|
|
91
104
|
// span content changed, ex. from click on entity
|
|
92
105
|
this.setText(this.span.offset_string);
|
|
93
106
|
},
|
|
107
|
+
isChecked() {
|
|
108
|
+
if (this.isCheckboxAvailable) {
|
|
109
|
+
this.handleCheckboxChanged(this.isChecked);
|
|
110
|
+
} else {
|
|
111
|
+
if (this.isChecked !== this.checkboxDefaultValue) {
|
|
112
|
+
this.$buefy.dialog.confirm({
|
|
113
|
+
container: "#app .dv-ui-app-container",
|
|
114
|
+
canCancel: ["button"],
|
|
115
|
+
message: this.$t("edit_ann_content_warning"),
|
|
116
|
+
onConfirm: () => {
|
|
117
|
+
this.isCheckboxAvailable = true;
|
|
118
|
+
this.handleCheckboxChanged(this.isChecked);
|
|
119
|
+
},
|
|
120
|
+
onCancel: () => {
|
|
121
|
+
this.isChecked = !this.isChecked;
|
|
122
|
+
},
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
},
|
|
94
127
|
},
|
|
95
128
|
|
|
96
129
|
methods: {
|
|
130
|
+
handleCheckboxChanged(value) {
|
|
131
|
+
this.$store
|
|
132
|
+
.dispatch("document/updateAnnotation", {
|
|
133
|
+
updatedValues: {
|
|
134
|
+
metadata: {
|
|
135
|
+
checkbox: {
|
|
136
|
+
is_checked: value,
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
annotationId: this.annotation.id,
|
|
141
|
+
annotationSet: this.annotationSet,
|
|
142
|
+
})
|
|
143
|
+
.catch((error) => {
|
|
144
|
+
this.$store.dispatch("document/createErrorMessage", {
|
|
145
|
+
error,
|
|
146
|
+
serverErrorMessage: this.$t("server_error"),
|
|
147
|
+
defaultErrorMessage: this.$t("edit_error"),
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
},
|
|
97
151
|
setText(text) {
|
|
98
152
|
this.$refs.contentEditable.textContent = text;
|
|
99
153
|
},
|
|
@@ -1,135 +1,149 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
<div
|
|
9
|
-
v-if="
|
|
10
|
-
(created(annotation) || edited(annotation)) &&
|
|
11
|
-
!isNegative(annotation) &&
|
|
12
|
-
!publicView
|
|
13
|
-
"
|
|
14
|
-
>
|
|
2
|
+
<div>
|
|
3
|
+
<b-tooltip
|
|
4
|
+
:animated="false"
|
|
5
|
+
:position="fromTable ? 'is-top' : 'is-bottom'"
|
|
6
|
+
:class="[!fromTable && 'left-aligned', 'annotation-details']"
|
|
7
|
+
>
|
|
8
|
+
<div :class="['label-icon', fromTable && 'is-small']">
|
|
15
9
|
<div
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
>
|
|
22
|
-
<AcceptedUser />
|
|
23
|
-
</div>
|
|
24
|
-
</div>
|
|
25
|
-
<div
|
|
26
|
-
v-else-if="annotationIsNotFound(annotationSet, label) && !publicView"
|
|
27
|
-
:class="['annotation-details-icon', animate ? 'animated-ripple' : '']"
|
|
28
|
-
>
|
|
29
|
-
<NotFoundIcon />
|
|
30
|
-
</div>
|
|
31
|
-
<div
|
|
32
|
-
v-else-if="
|
|
33
|
-
notExtracted(annotation) || (isNegative(annotation) && !publicView)
|
|
34
|
-
"
|
|
35
|
-
:class="[
|
|
36
|
-
'annotation-details-icon',
|
|
37
|
-
animate ? 'animated-ripple' : '',
|
|
38
|
-
'question-icon',
|
|
39
|
-
]"
|
|
40
|
-
>
|
|
41
|
-
<QuestionMark />
|
|
42
|
-
</div>
|
|
43
|
-
<div v-else>
|
|
44
|
-
<div
|
|
45
|
-
v-if="accepted(annotation) && !publicView"
|
|
46
|
-
:class="[
|
|
47
|
-
'annotation-details-icon success',
|
|
48
|
-
animate ? 'animated-ripple' : '',
|
|
49
|
-
]"
|
|
10
|
+
v-if="
|
|
11
|
+
(created(annotation) || edited(annotation)) &&
|
|
12
|
+
!isNegative(annotation) &&
|
|
13
|
+
!publicView
|
|
14
|
+
"
|
|
50
15
|
>
|
|
51
|
-
<
|
|
16
|
+
<div
|
|
17
|
+
:class="[
|
|
18
|
+
'annotation-details-icon',
|
|
19
|
+
animate ? 'animated-ripple' : '',
|
|
20
|
+
'user-icon',
|
|
21
|
+
]"
|
|
22
|
+
>
|
|
23
|
+
<AcceptedUser />
|
|
24
|
+
</div>
|
|
52
25
|
</div>
|
|
53
26
|
<div
|
|
54
|
-
v-else
|
|
27
|
+
v-else-if="annotationIsNotFound(annotationSet, label) && !publicView"
|
|
55
28
|
:class="['annotation-details-icon', animate ? 'animated-ripple' : '']"
|
|
56
29
|
>
|
|
57
|
-
<
|
|
58
|
-
</div>
|
|
59
|
-
</div>
|
|
60
|
-
</div>
|
|
61
|
-
|
|
62
|
-
<template #content>
|
|
63
|
-
<div class="label-details">
|
|
64
|
-
<div v-if="description" class="label-description">
|
|
65
|
-
<span>{{ description }}</span>
|
|
30
|
+
<NotFoundIcon />
|
|
66
31
|
</div>
|
|
67
32
|
<div
|
|
68
|
-
v-if="
|
|
69
|
-
|
|
33
|
+
v-else-if="
|
|
34
|
+
notExtracted(annotation) || (isNegative(annotation) && !publicView)
|
|
35
|
+
"
|
|
36
|
+
:class="[
|
|
37
|
+
'annotation-details-icon',
|
|
38
|
+
animate ? 'animated-ripple' : '',
|
|
39
|
+
'question-icon',
|
|
40
|
+
]"
|
|
70
41
|
>
|
|
71
|
-
<
|
|
72
|
-
|
|
42
|
+
<QuestionMark />
|
|
43
|
+
</div>
|
|
44
|
+
<div v-else>
|
|
45
|
+
<div
|
|
46
|
+
v-if="accepted(annotation) && !publicView"
|
|
47
|
+
:class="[
|
|
48
|
+
'annotation-details-icon success',
|
|
49
|
+
animate ? 'animated-ripple' : '',
|
|
50
|
+
]"
|
|
51
|
+
>
|
|
52
|
+
<AcceptedCheckMark />
|
|
53
|
+
</div>
|
|
54
|
+
<div
|
|
55
|
+
v-else
|
|
73
56
|
:class="[
|
|
74
|
-
'
|
|
75
|
-
|
|
76
|
-
? 'red'
|
|
77
|
-
: confidence(annotation) <= 0.5
|
|
78
|
-
? 'yellow'
|
|
79
|
-
: '',
|
|
57
|
+
'annotation-details-icon',
|
|
58
|
+
animate ? 'animated-ripple' : '',
|
|
80
59
|
]"
|
|
81
|
-
>{{ Math.floor(confidence(annotation) * 100) / 100 }}</span
|
|
82
60
|
>
|
|
61
|
+
<CheckMark class="pending" />
|
|
62
|
+
</div>
|
|
83
63
|
</div>
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
64
|
+
</div>
|
|
65
|
+
|
|
66
|
+
<template #content>
|
|
67
|
+
<div class="label-details">
|
|
68
|
+
<div
|
|
69
|
+
v-if="
|
|
70
|
+
annotation && annotation.metadata && annotation.metadata.checkbox
|
|
71
|
+
"
|
|
72
|
+
class="label-description"
|
|
73
|
+
>
|
|
74
|
+
<b-icon size="is-small" icon="square-check" />
|
|
75
|
+
<span> {{ $t("checkbox_ann_details") }}</span>
|
|
76
|
+
</div>
|
|
77
|
+
<div v-if="description" class="label-description">
|
|
78
|
+
<span>{{ description }}</span>
|
|
79
|
+
</div>
|
|
80
|
+
<div
|
|
81
|
+
v-if="confidence(annotation) && !isNegative(annotation)"
|
|
82
|
+
:class="['confidence', publicView && 'tooltip-in-public-view']"
|
|
83
|
+
>
|
|
84
|
+
<span>{{ $t("confidence") }}</span
|
|
85
|
+
><span
|
|
99
86
|
:class="[
|
|
100
|
-
'
|
|
101
|
-
|
|
102
|
-
|
|
87
|
+
'value',
|
|
88
|
+
confidence(annotation) <= 0.2
|
|
89
|
+
? 'red'
|
|
90
|
+
: confidence(annotation) <= 0.5
|
|
91
|
+
? 'yellow'
|
|
92
|
+
: '',
|
|
103
93
|
]"
|
|
94
|
+
>{{ Math.floor(confidence(annotation) * 100) / 100 }}</span
|
|
104
95
|
>
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
<div
|
|
108
|
-
<div
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
96
|
+
</div>
|
|
97
|
+
<div v-if="!publicView" class="revision">
|
|
98
|
+
<div class="detail-icons">
|
|
99
|
+
<div v-if="created(annotation) || edited(annotation)">
|
|
100
|
+
<div
|
|
101
|
+
:class="[
|
|
102
|
+
'annotation-details-icon',
|
|
103
|
+
animate ? 'animated-ripple' : '',
|
|
104
|
+
'user-icon',
|
|
105
|
+
]"
|
|
106
|
+
>
|
|
107
|
+
<AcceptedUser />
|
|
108
|
+
</div>
|
|
116
109
|
</div>
|
|
117
110
|
<div
|
|
118
|
-
v-else
|
|
111
|
+
v-else-if="notExtracted(annotation)"
|
|
119
112
|
:class="[
|
|
120
113
|
'annotation-details-icon',
|
|
121
114
|
animate ? 'animated-ripple' : '',
|
|
115
|
+
'question-icon',
|
|
122
116
|
]"
|
|
123
117
|
>
|
|
124
|
-
<
|
|
118
|
+
<QuestionMark />
|
|
119
|
+
</div>
|
|
120
|
+
<div v-else>
|
|
121
|
+
<div
|
|
122
|
+
v-if="accepted(annotation)"
|
|
123
|
+
:class="[
|
|
124
|
+
'annotation-details-icon',
|
|
125
|
+
animate ? 'animated-ripple' : '',
|
|
126
|
+
]"
|
|
127
|
+
>
|
|
128
|
+
<AcceptedCheckMark />
|
|
129
|
+
</div>
|
|
130
|
+
<div
|
|
131
|
+
v-else
|
|
132
|
+
:class="[
|
|
133
|
+
'annotation-details-icon',
|
|
134
|
+
animate ? 'animated-ripple' : '',
|
|
135
|
+
]"
|
|
136
|
+
>
|
|
137
|
+
<CheckMark />
|
|
138
|
+
</div>
|
|
125
139
|
</div>
|
|
140
|
+
{{ getText() }}
|
|
126
141
|
</div>
|
|
127
|
-
{{ getText() }}
|
|
128
142
|
</div>
|
|
129
143
|
</div>
|
|
130
|
-
</
|
|
131
|
-
</
|
|
132
|
-
</
|
|
144
|
+
</template>
|
|
145
|
+
</b-tooltip>
|
|
146
|
+
</div>
|
|
133
147
|
</template>
|
|
134
148
|
<script>
|
|
135
149
|
import { mapGetters, mapState } from "vuex";
|
|
@@ -39,7 +39,11 @@
|
|
|
39
39
|
</div>
|
|
40
40
|
|
|
41
41
|
<div
|
|
42
|
-
v-if="
|
|
42
|
+
v-if="
|
|
43
|
+
showAnnotationTranslations &&
|
|
44
|
+
annotation &&
|
|
45
|
+
annotation.translated_string
|
|
46
|
+
"
|
|
43
47
|
:class="['annotation-translation', !isDocumentReviewed && 'pointer']"
|
|
44
48
|
@click="editAnnotationTranslation(annotation.id)"
|
|
45
49
|
>
|
|
@@ -112,6 +112,29 @@
|
|
|
112
112
|
/>
|
|
113
113
|
</v-group>
|
|
114
114
|
</template>
|
|
115
|
+
<template
|
|
116
|
+
v-if="annotation.metadata && annotation.metadata.checkbox"
|
|
117
|
+
>
|
|
118
|
+
<v-group :key="'ann' + annotation.id + '-checkbox'">
|
|
119
|
+
<v-rect
|
|
120
|
+
v-if="!isAnnotationInEditMode(annotation.id)"
|
|
121
|
+
:config="
|
|
122
|
+
annotationRect(
|
|
123
|
+
annotation.metadata.checkbox.bbox,
|
|
124
|
+
annotation.id
|
|
125
|
+
)
|
|
126
|
+
"
|
|
127
|
+
@click="handleFocusedAnnotation(annotation)"
|
|
128
|
+
@mouseenter="
|
|
129
|
+
onElementEnter(
|
|
130
|
+
annotation,
|
|
131
|
+
annotation.metadata.checkbox.bbox
|
|
132
|
+
)
|
|
133
|
+
"
|
|
134
|
+
@mouseleave="onElementLeave"
|
|
135
|
+
/>
|
|
136
|
+
</v-group>
|
|
137
|
+
</template>
|
|
115
138
|
</template>
|
|
116
139
|
</template>
|
|
117
140
|
</v-layer>
|
|
@@ -152,6 +175,7 @@
|
|
|
152
175
|
<box-selection
|
|
153
176
|
:page="page"
|
|
154
177
|
@createAnnotations="handleCreateAnnotationsFromSelection"
|
|
178
|
+
@selectEntities="handleEntitiesFromSelection"
|
|
155
179
|
/>
|
|
156
180
|
</v-layer>
|
|
157
181
|
<v-layer v-if="isMultiSelection">
|
|
@@ -465,7 +489,6 @@ export default {
|
|
|
465
489
|
)
|
|
466
490
|
return;
|
|
467
491
|
this.newAnnotation = [];
|
|
468
|
-
// this.endSelection();
|
|
469
492
|
|
|
470
493
|
const normalizedEntities = this.scaledEntities(entities, this.page);
|
|
471
494
|
if (normalizedEntities) {
|
|
@@ -482,6 +505,25 @@ export default {
|
|
|
482
505
|
}
|
|
483
506
|
},
|
|
484
507
|
|
|
508
|
+
handleEntitiesFromSelection(entities) {
|
|
509
|
+
if (
|
|
510
|
+
this.categorizeModalIsActive ||
|
|
511
|
+
this.publicView ||
|
|
512
|
+
this.isDocumentReviewed
|
|
513
|
+
)
|
|
514
|
+
return;
|
|
515
|
+
|
|
516
|
+
const normalizedEntities = this.scaledEntities(entities, this.page);
|
|
517
|
+
if (normalizedEntities.length > 0) {
|
|
518
|
+
this.$store.dispatch(
|
|
519
|
+
"selection/setSelectedEntities",
|
|
520
|
+
normalizedEntities
|
|
521
|
+
);
|
|
522
|
+
} else {
|
|
523
|
+
this.$store.dispatch("selection/setSelectedEntities", null);
|
|
524
|
+
}
|
|
525
|
+
},
|
|
526
|
+
|
|
485
527
|
handleClickedEntity(entity) {
|
|
486
528
|
if (
|
|
487
529
|
!entity ||
|
|
@@ -603,8 +645,8 @@ export default {
|
|
|
603
645
|
*/
|
|
604
646
|
entityRect(entity) {
|
|
605
647
|
let entityIsSelected = false;
|
|
606
|
-
if (this.
|
|
607
|
-
entityIsSelected = this.
|
|
648
|
+
if (this.selectedEntities && this.selectedEntities.length > 0) {
|
|
649
|
+
entityIsSelected = this.selectedEntities.find((selectedEntity) => {
|
|
608
650
|
return (
|
|
609
651
|
selectedEntity.original &&
|
|
610
652
|
selectedEntity.original.offset_string ===
|
package/src/icons.js
CHANGED
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
faFloppyDisk,
|
|
24
24
|
faCircleExclamation,
|
|
25
25
|
faLink,
|
|
26
|
+
faSquareCheck,
|
|
26
27
|
} from "@fortawesome/free-solid-svg-icons";
|
|
27
28
|
import { FontAwesomeIcon as Icons } from "@fortawesome/vue-fontawesome";
|
|
28
29
|
|
|
@@ -49,7 +50,8 @@ library.add(
|
|
|
49
50
|
faTrashArrowUp,
|
|
50
51
|
faFloppyDisk,
|
|
51
52
|
faCircleExclamation,
|
|
52
|
-
faLink
|
|
53
|
+
faLink,
|
|
54
|
+
faSquareCheck
|
|
53
55
|
);
|
|
54
56
|
|
|
55
57
|
export default Icons;
|
package/src/locales/de.json
CHANGED
|
@@ -160,5 +160,6 @@
|
|
|
160
160
|
"edit_ann_content_warning": "Wenn Sie den Text ändern, kann die KI diese Annotation nicht verwenden. Dadurch werden auch die Trainingsdaten ungültig. Versuchen Sie, die Auswahl zu verändern, um den Text zu erfassen,bevor Sie ihn manuell hinzufügen, oder drücken Sie OK, um trotzdem fortzufahren.",
|
|
161
161
|
"annotation_deleted": "Diese Annotation wurde gelöscht.",
|
|
162
162
|
"annotation_link": "Kopieren Sie den permanenten Link zu dieser Annotationen",
|
|
163
|
-
"copied": "Kopiert"
|
|
163
|
+
"copied": "Kopiert",
|
|
164
|
+
"checkbox_ann_details": "Für dieses Label wird ein Kästchen extrahiert."
|
|
164
165
|
}
|
package/src/locales/en.json
CHANGED
|
@@ -158,8 +158,9 @@
|
|
|
158
158
|
"human_feedback_needed": "Human Feedback needed",
|
|
159
159
|
"label_missing_annotations": "Missing Annotations",
|
|
160
160
|
"accepted_annotations": "Accepted Annotations",
|
|
161
|
-
"edit_ann_content_warning": "If you change the
|
|
161
|
+
"edit_ann_content_warning": "If you change the content, the AI cannot use this Annotation. You will also invalidate the training data. Try to change the selection to capture the content before adding it manually, or press OK to continue anyway.",
|
|
162
162
|
"annotation_deleted": "This annotation has been deleted.",
|
|
163
163
|
"annotation_link": "Copy the permanent link to this annotation",
|
|
164
|
-
"copied": "Copied"
|
|
164
|
+
"copied": "Copied",
|
|
165
|
+
"checkbox_ann_details": "A checkbox will be extracted for this label."
|
|
165
166
|
}
|
package/src/locales/es.json
CHANGED
|
@@ -160,5 +160,6 @@
|
|
|
160
160
|
"edit_ann_content_warning": "Si cambia el texto, la IA no puede utilizar esta anotación. También invalidarás los datos del entrenamiento. Intente cambiar la selección para capturar el texto antes de agregarlo manualmente, o presione OK para continuar de todos modos.",
|
|
161
161
|
"annotation_deleted": "Esta anotación ha sido eliminada.",
|
|
162
162
|
"annotation_link": "Copia el enlace permanente a esta anotación.",
|
|
163
|
-
"copied": "Copiada"
|
|
163
|
+
"copied": "Copiada",
|
|
164
|
+
"checkbox_ann_details": "Se extraerá una casilla de verificación para esta etiqueta."
|
|
164
165
|
}
|