geonetwork-ui 2.7.0-dev.dbe423d28 → 2.7.0-dev.f29e01b0d
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/esm2022/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.mjs +18 -4
- package/esm2022/libs/common/domain/src/lib/model/dataviz/dataviz-configuration.model.mjs +1 -1
- package/esm2022/libs/common/domain/src/lib/platform.service.interface.mjs +1 -1
- package/esm2022/libs/feature/dataviz/src/lib/chart-view/chart-view.component.mjs +10 -2
- package/esm2022/libs/feature/record/src/lib/data-view/data-view.component.mjs +31 -12
- package/esm2022/libs/feature/record/src/lib/map-view/map-view.component.mjs +73 -26
- package/esm2022/libs/ui/dataviz/src/lib/data-table/data-table.component.mjs +4 -3
- package/esm2022/libs/ui/elements/src/lib/internal-link-card/internal-link-card.component.mjs +4 -4
- package/esm2022/libs/ui/elements/src/lib/metadata-quality/metadata-quality.component.mjs +21 -43
- package/esm2022/libs/util/app-config/src/lib/app-config.mjs +3 -1
- package/esm2022/libs/util/app-config/src/lib/model.mjs +1 -1
- package/esm2022/libs/util/shared/src/index.mjs +2 -2
- package/esm2022/libs/util/shared/src/lib/links/link-utils.mjs +9 -1
- package/esm2022/libs/util/shared/src/lib/record/index.mjs +3 -0
- package/esm2022/libs/util/shared/src/lib/record/quality-score.util.mjs +45 -0
- package/esm2022/libs/util/shared/src/lib/record/record.util.mjs +56 -0
- package/esm2022/translations/de.json +1 -1
- package/esm2022/translations/en.json +1 -1
- package/esm2022/translations/es.json +1 -1
- package/esm2022/translations/fr.json +1 -1
- package/esm2022/translations/it.json +1 -1
- package/esm2022/translations/nl.json +1 -1
- package/esm2022/translations/pt.json +1 -1
- package/esm2022/translations/sk.json +1 -1
- package/fesm2022/geonetwork-ui.mjs +213 -92
- package/fesm2022/geonetwork-ui.mjs.map +1 -1
- package/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.d.ts +1 -0
- package/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.d.ts.map +1 -1
- package/libs/common/domain/src/lib/model/dataviz/dataviz-configuration.model.d.ts +1 -0
- package/libs/common/domain/src/lib/model/dataviz/dataviz-configuration.model.d.ts.map +1 -1
- package/libs/common/domain/src/lib/platform.service.interface.d.ts +1 -0
- package/libs/common/domain/src/lib/platform.service.interface.d.ts.map +1 -1
- package/libs/feature/dataviz/src/lib/chart-view/chart-view.component.d.ts +3 -2
- package/libs/feature/dataviz/src/lib/chart-view/chart-view.component.d.ts.map +1 -1
- package/libs/feature/record/src/lib/data-view/data-view.component.d.ts +8 -4
- package/libs/feature/record/src/lib/data-view/data-view.component.d.ts.map +1 -1
- package/libs/feature/record/src/lib/map-view/map-view.component.d.ts +12 -5
- package/libs/feature/record/src/lib/map-view/map-view.component.d.ts.map +1 -1
- package/libs/ui/dataviz/src/lib/data-table/data-table.component.d.ts.map +1 -1
- package/libs/ui/elements/src/lib/internal-link-card/internal-link-card.component.d.ts.map +1 -1
- package/libs/ui/elements/src/lib/metadata-quality/metadata-quality.component.d.ts +7 -6
- package/libs/ui/elements/src/lib/metadata-quality/metadata-quality.component.d.ts.map +1 -1
- package/libs/util/app-config/src/lib/app-config.d.ts.map +1 -1
- package/libs/util/app-config/src/lib/model.d.ts +1 -0
- package/libs/util/app-config/src/lib/model.d.ts.map +1 -1
- package/libs/util/shared/src/index.d.ts +1 -1
- package/libs/util/shared/src/index.d.ts.map +1 -1
- package/libs/util/shared/src/lib/links/link-utils.d.ts +1 -0
- package/libs/util/shared/src/lib/links/link-utils.d.ts.map +1 -1
- package/libs/util/shared/src/lib/record/index.d.ts +3 -0
- package/libs/util/shared/src/lib/record/index.d.ts.map +1 -0
- package/libs/util/shared/src/lib/record/quality-score.util.d.ts +13 -0
- package/libs/util/shared/src/lib/record/quality-score.util.d.ts.map +1 -0
- package/libs/util/shared/src/lib/record/record.util.d.ts +3 -0
- package/libs/util/shared/src/lib/record/record.util.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.ts +25 -4
- package/src/libs/common/domain/src/lib/model/dataviz/dataviz-configuration.model.ts +1 -0
- package/src/libs/common/domain/src/lib/platform.service.interface.ts +2 -0
- package/src/libs/feature/dataviz/src/lib/chart-view/chart-view.component.ts +10 -1
- package/src/libs/feature/record/src/lib/data-view/data-view.component.html +2 -0
- package/src/libs/feature/record/src/lib/data-view/data-view.component.ts +34 -15
- package/src/libs/feature/record/src/lib/map-view/map-view.component.html +2 -0
- package/src/libs/feature/record/src/lib/map-view/map-view.component.ts +67 -22
- package/src/libs/ui/dataviz/src/lib/data-table/data-table.component.ts +6 -1
- package/src/libs/ui/elements/src/lib/internal-link-card/internal-link-card.component.html +1 -0
- package/src/libs/ui/elements/src/lib/internal-link-card/internal-link-card.component.ts +5 -1
- package/src/libs/ui/elements/src/lib/metadata-quality/metadata-quality.component.html +1 -0
- package/src/libs/ui/elements/src/lib/metadata-quality/metadata-quality.component.ts +21 -54
- package/src/libs/util/app-config/src/lib/app-config.ts +2 -0
- package/src/libs/util/app-config/src/lib/model.ts +1 -0
- package/src/libs/util/shared/src/index.ts +1 -1
- package/src/libs/util/shared/src/lib/links/link-utils.ts +9 -0
- package/src/libs/util/shared/src/lib/record/index.ts +2 -0
- package/src/libs/util/shared/src/lib/record/quality-score.util.ts +69 -0
- package/src/libs/util/shared/src/lib/{record.util.ts → record/record.util.ts} +1 -1
- package/translations/de.json +1 -1
- package/translations/en.json +1 -1
- package/translations/es.json +1 -1
- package/translations/fr.json +1 -1
- package/translations/it.json +1 -1
- package/translations/nl.json +1 -1
- package/translations/pt.json +1 -1
- package/translations/sk.json +1 -1
- package/esm2022/libs/util/shared/src/lib/record.util.mjs +0 -56
- package/libs/util/shared/src/lib/record.util.d.ts +0 -3
- package/libs/util/shared/src/lib/record.util.d.ts.map +0 -1
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
ViewChild,
|
|
10
10
|
} from '@angular/core'
|
|
11
11
|
import { MapUtilsService } from '../../../../../../libs/feature/map/src'
|
|
12
|
-
import { getLinkLabel } from '../../../../../../libs/util/shared/src'
|
|
12
|
+
import { getLinkId, getLinkLabel } from '../../../../../../libs/util/shared/src'
|
|
13
13
|
import {
|
|
14
14
|
BehaviorSubject,
|
|
15
15
|
combineLatest,
|
|
@@ -100,15 +100,28 @@ export class MapViewComponent implements AfterViewInit {
|
|
|
100
100
|
@Input() set exceedsLimit(value: boolean) {
|
|
101
101
|
this.excludeWfs$.next(value)
|
|
102
102
|
}
|
|
103
|
+
linkFromConfig$ = new BehaviorSubject(null)
|
|
104
|
+
_selectedChoice = null
|
|
105
|
+
_styleFromConfig = null
|
|
106
|
+
|
|
107
|
+
linkMap: Map<string, DatasetOnlineResource> = new Map()
|
|
103
108
|
@Input() set selectedView(value: string) {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
109
|
+
this.selectedView$.next(value)
|
|
110
|
+
}
|
|
111
|
+
@Input() set datavizConfig(value: any) {
|
|
112
|
+
if (value.view === 'map') {
|
|
113
|
+
this.selectedView$.next(value.view)
|
|
114
|
+
if (value.styleTMSIndex) {
|
|
115
|
+
this._styleFromConfig = value.styleTMSIndex
|
|
116
|
+
}
|
|
117
|
+
if (value.source) {
|
|
118
|
+
this.linkFromConfig$.next(value.source)
|
|
119
|
+
}
|
|
108
120
|
}
|
|
109
121
|
}
|
|
110
122
|
@Input() displaySource = true
|
|
111
123
|
@Output() linkSelected = new EventEmitter<DatasetOnlineResource>()
|
|
124
|
+
@Output() styleSelected = new EventEmitter<number>()
|
|
112
125
|
@ViewChild('mapContainer') mapContainer: MapContainerComponent
|
|
113
126
|
|
|
114
127
|
excludeWfs$ = new BehaviorSubject(false)
|
|
@@ -119,12 +132,13 @@ export class MapViewComponent implements AfterViewInit {
|
|
|
119
132
|
loading = false
|
|
120
133
|
error = null
|
|
121
134
|
|
|
122
|
-
selectLinkToDisplay(
|
|
123
|
-
this.
|
|
135
|
+
selectLinkToDisplay(id: string) {
|
|
136
|
+
this.selectedLinkId$.next(id)
|
|
124
137
|
}
|
|
125
138
|
|
|
126
139
|
selectStyleToDisplay(i: number) {
|
|
127
|
-
this.
|
|
140
|
+
this.selectedStyleId$.next(i)
|
|
141
|
+
this.styleSelected.emit(i)
|
|
128
142
|
}
|
|
129
143
|
|
|
130
144
|
toggleLegend() {
|
|
@@ -146,29 +160,54 @@ export class MapViewComponent implements AfterViewInit {
|
|
|
146
160
|
)
|
|
147
161
|
|
|
148
162
|
dropdownChoices$ = this.compatibleMapLinks$.pipe(
|
|
149
|
-
map((links) =>
|
|
150
|
-
|
|
151
|
-
|
|
163
|
+
map((links) => {
|
|
164
|
+
this.linkMap.clear()
|
|
165
|
+
links.forEach((link: DatasetOnlineResource) =>
|
|
166
|
+
this.linkMap.set(getLinkId(link), link)
|
|
167
|
+
)
|
|
168
|
+
return links.length
|
|
169
|
+
? links.map((link) => ({
|
|
152
170
|
label: getLinkLabel(link),
|
|
153
|
-
value:
|
|
171
|
+
value: getLinkId(link),
|
|
154
172
|
}))
|
|
155
|
-
: [{ label: 'map.dropdown.placeholder', value:
|
|
156
|
-
)
|
|
173
|
+
: [{ label: 'map.dropdown.placeholder', value: '' }]
|
|
174
|
+
})
|
|
157
175
|
)
|
|
158
176
|
|
|
159
|
-
|
|
160
|
-
|
|
177
|
+
selectedView$ = new BehaviorSubject(null)
|
|
178
|
+
selectedLinkId$ = new BehaviorSubject(null)
|
|
179
|
+
selectedStyleId$ = new BehaviorSubject(null)
|
|
161
180
|
|
|
162
181
|
selectedSourceLink$ = combineLatest([
|
|
163
182
|
this.compatibleMapLinks$,
|
|
164
|
-
this.
|
|
183
|
+
this.linkFromConfig$,
|
|
184
|
+
this.selectedLinkId$.pipe(distinctUntilChanged()),
|
|
185
|
+
this.selectedView$,
|
|
165
186
|
]).pipe(
|
|
166
187
|
tap(() => {
|
|
167
188
|
this.error = null
|
|
168
189
|
}),
|
|
169
|
-
map(([
|
|
170
|
-
|
|
171
|
-
|
|
190
|
+
map(([compatibleLinks, configLink, id, view]) => {
|
|
191
|
+
if (view === 'map') {
|
|
192
|
+
if (
|
|
193
|
+
configLink &&
|
|
194
|
+
!id &&
|
|
195
|
+
compatibleLinks.some(
|
|
196
|
+
(link) => getLinkId(link) === getLinkId(configLink)
|
|
197
|
+
)
|
|
198
|
+
) {
|
|
199
|
+
this._selectedChoice = getLinkId(configLink)
|
|
200
|
+
this.linkSelected.emit(configLink)
|
|
201
|
+
return configLink
|
|
202
|
+
} else if (id) {
|
|
203
|
+
this._selectedChoice = id
|
|
204
|
+
this.linkSelected.emit(this.linkMap.get(id))
|
|
205
|
+
return this.linkMap.get(id)
|
|
206
|
+
} else {
|
|
207
|
+
this.linkSelected.emit(compatibleLinks[0])
|
|
208
|
+
return compatibleLinks[0]
|
|
209
|
+
}
|
|
210
|
+
}
|
|
172
211
|
})
|
|
173
212
|
)
|
|
174
213
|
|
|
@@ -205,7 +244,13 @@ export class MapViewComponent implements AfterViewInit {
|
|
|
205
244
|
}
|
|
206
245
|
return of([])
|
|
207
246
|
}),
|
|
208
|
-
tap(() =>
|
|
247
|
+
tap((styles) => {
|
|
248
|
+
if (this._styleFromConfig && this._styleFromConfig <= styles.length) {
|
|
249
|
+
this.selectedStyleId$.next(this._styleFromConfig)
|
|
250
|
+
} else {
|
|
251
|
+
this.selectedStyleId$.next(0)
|
|
252
|
+
}
|
|
253
|
+
}),
|
|
209
254
|
shareReplay(1)
|
|
210
255
|
)
|
|
211
256
|
|
|
@@ -228,7 +273,7 @@ export class MapViewComponent implements AfterViewInit {
|
|
|
228
273
|
selectedLink$ = combineLatest([
|
|
229
274
|
this.selectedSourceLink$,
|
|
230
275
|
this.styleLinks$,
|
|
231
|
-
this.
|
|
276
|
+
this.selectedStyleId$.pipe(distinctUntilChanged()),
|
|
232
277
|
]).pipe(
|
|
233
278
|
map(([src, styles, styleIdx]) => (styles.length ? styles[styleIdx] : src)),
|
|
234
279
|
shareReplay(1)
|
|
@@ -14,7 +14,11 @@ import {
|
|
|
14
14
|
} from '@angular/core'
|
|
15
15
|
import { MatSort, MatSortModule } from '@angular/material/sort'
|
|
16
16
|
import { MatTableModule } from '@angular/material/table'
|
|
17
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
TranslateDirective,
|
|
19
|
+
TranslatePipe,
|
|
20
|
+
TranslateService,
|
|
21
|
+
} from '@ngx-translate/core'
|
|
18
22
|
import { DataTableDataSource } from './data-table.data.source'
|
|
19
23
|
import { BaseReader, FetchError } from '../../../../../../libs/util/data-fetcher/src'
|
|
20
24
|
import {
|
|
@@ -53,6 +57,7 @@ export interface TableItemModel {
|
|
|
53
57
|
PopupAlertComponent,
|
|
54
58
|
LetDirective,
|
|
55
59
|
TranslatePipe,
|
|
60
|
+
TranslateDirective,
|
|
56
61
|
],
|
|
57
62
|
providers: [{ provide: MatPaginatorIntl, useClass: CustomMatPaginatorIntl }],
|
|
58
63
|
selector: 'gn-ui-data-table',
|
|
@@ -21,7 +21,11 @@ import { KindBadgeComponent } from '../kind-badge/kind-badge.component'
|
|
|
21
21
|
import { MarkdownParserComponent } from '../markdown-parser/markdown-parser.component'
|
|
22
22
|
import { MetadataQualityComponent } from '../metadata-quality/metadata-quality.component'
|
|
23
23
|
import { ThumbnailComponent } from '../thumbnail/thumbnail.component'
|
|
24
|
-
import {
|
|
24
|
+
import {
|
|
25
|
+
removeWhitespace,
|
|
26
|
+
stripHtml,
|
|
27
|
+
type ValidatorMapperKeys,
|
|
28
|
+
} from '../../../../../../libs/util/shared/src'
|
|
25
29
|
|
|
26
30
|
type CardSize = 'L' | 'M' | 'S' | 'XS'
|
|
27
31
|
|
|
@@ -14,15 +14,16 @@ import {
|
|
|
14
14
|
PopoverComponent,
|
|
15
15
|
ProgressBarComponent,
|
|
16
16
|
} from '../../../../../../libs/ui/widgets/src'
|
|
17
|
+
import {
|
|
18
|
+
getQualityValidators,
|
|
19
|
+
getAllKeysValidator,
|
|
20
|
+
type ValidatorMapperKeys,
|
|
21
|
+
} from '../../../../../../libs/util/shared/src'
|
|
17
22
|
import { CommonModule } from '@angular/common'
|
|
18
23
|
import { TranslateDirective } from '@ngx-translate/core'
|
|
19
24
|
import { NgIcon, provideIcons, provideNgIconsConfig } from '@ng-icons/core'
|
|
20
25
|
import { matInfoOutline } from '@ng-icons/material-icons/outline'
|
|
21
26
|
|
|
22
|
-
type QualityChecks = {
|
|
23
|
-
[key: string]: (metadata: Partial<CatalogRecord>) => boolean
|
|
24
|
-
}
|
|
25
|
-
|
|
26
27
|
@Component({
|
|
27
28
|
selector: 'gn-ui-metadata-quality',
|
|
28
29
|
templateUrl: './metadata-quality.component.html',
|
|
@@ -48,77 +49,43 @@ type QualityChecks = {
|
|
|
48
49
|
],
|
|
49
50
|
})
|
|
50
51
|
export class MetadataQualityComponent implements OnChanges {
|
|
51
|
-
@Input() metadata:
|
|
52
|
+
@Input() metadata: CatalogRecord
|
|
52
53
|
@Input() smaller = false
|
|
53
54
|
@Input() metadataQualityDisplay: boolean
|
|
55
|
+
@Input() popoverDisplay = true
|
|
56
|
+
@Input() propsToValidate?: ValidatorMapperKeys[]
|
|
57
|
+
@Input() forceComputeScore = false // Instead of returning es' quality score
|
|
54
58
|
|
|
55
59
|
items: MetadataQualityItem[] = []
|
|
56
60
|
|
|
57
61
|
get qualityScore() {
|
|
58
|
-
const qualityScore = this.
|
|
62
|
+
const qualityScore = !this.forceComputeScore
|
|
63
|
+
? this.metadata?.extras?.qualityScore
|
|
64
|
+
: this.computedQualityScore
|
|
65
|
+
|
|
59
66
|
return typeof qualityScore === 'number'
|
|
60
67
|
? qualityScore
|
|
61
|
-
: this.
|
|
68
|
+
: this.computedQualityScore
|
|
62
69
|
}
|
|
63
70
|
|
|
64
|
-
get
|
|
71
|
+
get computedQualityScore(): number {
|
|
65
72
|
return Math.round(
|
|
66
73
|
(this.items.filter(({ value }) => value).length * 100) / this.items.length
|
|
67
74
|
)
|
|
68
75
|
}
|
|
69
76
|
|
|
70
|
-
private add(name: string, value: boolean) {
|
|
71
|
-
if (this.metadataQualityDisplay?.[name] !== false) {
|
|
72
|
-
this.items.push({ name, value })
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
77
|
hasGetCapabilities(url: string): boolean {
|
|
76
78
|
return url.toLowerCase().includes('capabilities')
|
|
77
79
|
}
|
|
78
80
|
|
|
79
|
-
private readonly COMMON_CHECKS: QualityChecks = {
|
|
80
|
-
title: (metadata) => !!metadata?.title,
|
|
81
|
-
description: (metadata) => !!metadata?.abstract,
|
|
82
|
-
keywords: (metadata) => (metadata?.keywords?.length ?? 0) > 0,
|
|
83
|
-
legalConstraints: (metadata) =>
|
|
84
|
-
(metadata?.legalConstraints?.length ?? 0) > 0,
|
|
85
|
-
contact: (metadata) => !!metadata?.contacts?.[0]?.email,
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
private readonly SPECIFIC_CHECKS: Record<string, QualityChecks> = {
|
|
89
|
-
dataset: {
|
|
90
|
-
updateFrequency: (metadata) => !!metadata?.updateFrequency,
|
|
91
|
-
topic: (metadata) => (metadata?.topics?.length ?? 0) > 0,
|
|
92
|
-
organisation: (metadata) => !!metadata?.contacts?.[0]?.organization?.name,
|
|
93
|
-
},
|
|
94
|
-
service: {
|
|
95
|
-
capabilities: (metadata) =>
|
|
96
|
-
(metadata?.onlineResources ?? []).some((resource) =>
|
|
97
|
-
this.hasGetCapabilities(resource?.url?.href ?? '')
|
|
98
|
-
),
|
|
99
|
-
},
|
|
100
|
-
reuse: {
|
|
101
|
-
topic: (metadata) => (metadata?.topics?.length ?? 0) > 0,
|
|
102
|
-
organisation: (metadata) => !!metadata?.contacts?.[0]?.organization?.name,
|
|
103
|
-
source: (metadata) => !!metadata?.extras?.sourcesIdentifiers,
|
|
104
|
-
},
|
|
105
|
-
}
|
|
106
|
-
|
|
107
81
|
initialize() {
|
|
108
|
-
this.
|
|
109
|
-
|
|
110
|
-
Object.entries(this.COMMON_CHECKS).forEach(([name, check]) => {
|
|
111
|
-
this.add(name, check(this.metadata))
|
|
112
|
-
})
|
|
113
|
-
|
|
114
|
-
const datasetType = this.metadata?.kind
|
|
115
|
-
if (datasetType && this.SPECIFIC_CHECKS[datasetType]) {
|
|
116
|
-
Object.entries(this.SPECIFIC_CHECKS[datasetType]).forEach(
|
|
117
|
-
([name, check]) => {
|
|
118
|
-
this.add(name, check(this.metadata))
|
|
119
|
-
}
|
|
120
|
-
)
|
|
82
|
+
if (!this.propsToValidate) {
|
|
83
|
+
this.propsToValidate = getAllKeysValidator()
|
|
121
84
|
}
|
|
85
|
+
|
|
86
|
+
this.items = getQualityValidators(this.metadata, this.propsToValidate).map(
|
|
87
|
+
({ name, validator }) => ({ name, value: validator() })
|
|
88
|
+
)
|
|
122
89
|
}
|
|
123
90
|
|
|
124
91
|
ngOnChanges(changes: SimpleChanges): void {
|
|
@@ -102,6 +102,7 @@ export function loadAppConfig() {
|
|
|
102
102
|
'web_component_embedder_url',
|
|
103
103
|
'languages',
|
|
104
104
|
'contact_email',
|
|
105
|
+
'reuse_form_url',
|
|
105
106
|
],
|
|
106
107
|
warnings,
|
|
107
108
|
errors
|
|
@@ -131,6 +132,7 @@ export function loadAppConfig() {
|
|
|
131
132
|
parsedGlobalSection.web_component_embedder_url,
|
|
132
133
|
LANGUAGES: parsedGlobalSection.languages,
|
|
133
134
|
CONTACT_EMAIL: parsedGlobalSection.contact_email,
|
|
135
|
+
REUSE_FORM_URL: parsedGlobalSection.reuse_form_url,
|
|
134
136
|
} as GlobalConfig)
|
|
135
137
|
|
|
136
138
|
const parsedLayersSections = parseMultiConfigSection(
|
|
@@ -230,6 +230,15 @@ export function getBadgeColor(linkFormat: FileFormat): string {
|
|
|
230
230
|
return 'var(--color-gray-700)' // Default color ?
|
|
231
231
|
}
|
|
232
232
|
|
|
233
|
+
export function getLinkId(link: DatasetOnlineResource): string {
|
|
234
|
+
const href = link.url.href ?? link.url
|
|
235
|
+
return `${getLinkLabel(link)
|
|
236
|
+
.replace(/é/g, 'e')
|
|
237
|
+
.replace(/è/g, 'e')
|
|
238
|
+
.normalize('NFD')
|
|
239
|
+
.replace(/[\u0300-\u036f]/g, '')}-${href}`
|
|
240
|
+
}
|
|
241
|
+
|
|
233
242
|
export function getLinkLabel(
|
|
234
243
|
link: DatasetOnlineResource | ServiceOnlineResource
|
|
235
244
|
): string {
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CatalogRecord,
|
|
3
|
+
RecordKind,
|
|
4
|
+
} from '../../../../../../libs/common/domain/src/lib/model/record'
|
|
5
|
+
|
|
6
|
+
type TValidatorMapper = {
|
|
7
|
+
[key: string]: (metadata: Partial<CatalogRecord>) => boolean
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const ValidatorMapper: TValidatorMapper = {
|
|
11
|
+
title: (record) => !!record?.title,
|
|
12
|
+
description: (record) => !!record?.abstract,
|
|
13
|
+
keywords: (record) => (record?.keywords?.length ?? 0) > 0,
|
|
14
|
+
legalConstraints: (record) => (record?.legalConstraints?.length ?? 0) > 0,
|
|
15
|
+
contact: (record) => !!record?.contacts?.[0]?.email,
|
|
16
|
+
updateFrequency: (record) => !!record?.updateFrequency,
|
|
17
|
+
topic: (record) => (record?.topics?.length ?? 0) > 0,
|
|
18
|
+
organisation: (record) => !!record?.contacts?.[0]?.organization?.name,
|
|
19
|
+
capabilities: (record) =>
|
|
20
|
+
record?.onlineResources?.some((resource) =>
|
|
21
|
+
resource?.url?.href.toLowerCase().includes('capabilities')
|
|
22
|
+
),
|
|
23
|
+
source: (record) => !!record?.extras?.sourcesIdentifiers,
|
|
24
|
+
} as const
|
|
25
|
+
|
|
26
|
+
export type ValidatorMapperKeys = keyof typeof ValidatorMapper & string
|
|
27
|
+
|
|
28
|
+
export function getAllKeysValidator() {
|
|
29
|
+
return Object.keys(ValidatorMapper)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function getMappersFromKind(kind: RecordKind) {
|
|
33
|
+
let kindKeys = <ValidatorMapperKeys[]>[]
|
|
34
|
+
const commonsKeys = <ValidatorMapperKeys[]>[
|
|
35
|
+
'title',
|
|
36
|
+
'description',
|
|
37
|
+
'keywords',
|
|
38
|
+
'legalConstraints',
|
|
39
|
+
'contact',
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
switch (kind) {
|
|
43
|
+
case 'service':
|
|
44
|
+
kindKeys = ['capabilities']
|
|
45
|
+
break
|
|
46
|
+
case 'reuse':
|
|
47
|
+
kindKeys = ['topic', 'organisation', 'source']
|
|
48
|
+
break
|
|
49
|
+
case 'dataset':
|
|
50
|
+
default:
|
|
51
|
+
kindKeys = ['updateFrequency', 'topic', 'organisation']
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return [...commonsKeys, ...kindKeys]
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function getQualityValidators(
|
|
58
|
+
record: Partial<CatalogRecord>,
|
|
59
|
+
propsToValidate: ValidatorMapperKeys[]
|
|
60
|
+
) {
|
|
61
|
+
const filteredProps = propsToValidate.filter((prop) =>
|
|
62
|
+
getMappersFromKind(record.kind).includes(prop)
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
return filteredProps.map((name) => ({
|
|
66
|
+
name,
|
|
67
|
+
validator: () => ValidatorMapper[name](record),
|
|
68
|
+
}))
|
|
69
|
+
}
|
package/translations/de.json
CHANGED
|
@@ -374,7 +374,6 @@
|
|
|
374
374
|
"record.action.rollback": "",
|
|
375
375
|
"record.action.switchLang": "",
|
|
376
376
|
"record.action.view": "Anzeigen",
|
|
377
|
-
"record.card.metadata.contact": "",
|
|
378
377
|
"record.externalViewer.open": "In externem Kartenviewer öffnen",
|
|
379
378
|
"record.feature.catalog.number.total.attribute": "",
|
|
380
379
|
"record.feature.catalog.number.total.object": "",
|
|
@@ -580,6 +579,7 @@
|
|
|
580
579
|
"service.metadata.filter.noLayers": "",
|
|
581
580
|
"service.metadata.other": "",
|
|
582
581
|
"service.metadata.question": "",
|
|
582
|
+
"service.metadata.reuse": "",
|
|
583
583
|
"service.metadata.search": "",
|
|
584
584
|
"service.metadata.search.clear": "",
|
|
585
585
|
"service.metadata.spatialExtent": "",
|
package/translations/en.json
CHANGED
|
@@ -374,7 +374,6 @@
|
|
|
374
374
|
"record.action.rollback": "Rollback",
|
|
375
375
|
"record.action.switchLang": "Switch to default",
|
|
376
376
|
"record.action.view": "View",
|
|
377
|
-
"record.card.metadata.contact": "Metadata Contact",
|
|
378
377
|
"record.externalViewer.open": "Open in the external map viewer",
|
|
379
378
|
"record.feature.catalog.number.total.attribute": "Total amount of objects",
|
|
380
379
|
"record.feature.catalog.number.total.object": "Total amount of attributes",
|
|
@@ -580,6 +579,7 @@
|
|
|
580
579
|
"service.metadata.filter.noLayers": "No layer matches your search",
|
|
581
580
|
"service.metadata.other": "Other information",
|
|
582
581
|
"service.metadata.question": "Ask a question",
|
|
582
|
+
"service.metadata.reuse": "Declare a reuse",
|
|
583
583
|
"service.metadata.search": "Search through the layer list",
|
|
584
584
|
"service.metadata.search.clear": "Clear the layer search",
|
|
585
585
|
"service.metadata.spatialExtent": "Spatial extent",
|
package/translations/es.json
CHANGED
|
@@ -374,7 +374,6 @@
|
|
|
374
374
|
"record.action.rollback": "",
|
|
375
375
|
"record.action.switchLang": "",
|
|
376
376
|
"record.action.view": "",
|
|
377
|
-
"record.card.metadata.contact": "",
|
|
378
377
|
"record.externalViewer.open": "",
|
|
379
378
|
"record.feature.catalog.number.total.attribute": "",
|
|
380
379
|
"record.feature.catalog.number.total.object": "",
|
|
@@ -580,6 +579,7 @@
|
|
|
580
579
|
"service.metadata.filter.noLayers": "",
|
|
581
580
|
"service.metadata.other": "",
|
|
582
581
|
"service.metadata.question": "",
|
|
582
|
+
"service.metadata.reuse": "",
|
|
583
583
|
"service.metadata.search": "",
|
|
584
584
|
"service.metadata.search.clear": "",
|
|
585
585
|
"service.metadata.spatialExtent": "",
|
package/translations/fr.json
CHANGED
|
@@ -374,7 +374,6 @@
|
|
|
374
374
|
"record.action.rollback": "Restaurer",
|
|
375
375
|
"record.action.switchLang": "Marquer par défaut",
|
|
376
376
|
"record.action.view": "Voir",
|
|
377
|
-
"record.card.metadata.contact": "Contact de la métadonnée ",
|
|
378
377
|
"record.externalViewer.open": "Ouvrir dans le visualiseur externe",
|
|
379
378
|
"record.feature.catalog.number.total.attribute": "Nombre total d'attributs",
|
|
380
379
|
"record.feature.catalog.number.total.object": "Nombre total d'objets",
|
|
@@ -580,6 +579,7 @@
|
|
|
580
579
|
"service.metadata.filter.noLayers": "Aucune couche ne correspond à votre recherche",
|
|
581
580
|
"service.metadata.other": "Autres informations",
|
|
582
581
|
"service.metadata.question": "Poser une question",
|
|
582
|
+
"service.metadata.reuse": "Déclarer une réutilisation",
|
|
583
583
|
"service.metadata.search": "Rechercher dans la liste des couches",
|
|
584
584
|
"service.metadata.search.clear": "Effacer la recherche des couches",
|
|
585
585
|
"service.metadata.spatialExtent": "Etendue spatiale",
|
package/translations/it.json
CHANGED
|
@@ -374,7 +374,6 @@
|
|
|
374
374
|
"record.action.rollback": "Annulla",
|
|
375
375
|
"record.action.switchLang": "",
|
|
376
376
|
"record.action.view": "Visualizza",
|
|
377
|
-
"record.card.metadata.contact": "Contatto del metadata",
|
|
378
377
|
"record.externalViewer.open": "Aprire nel visualizzatore esterno",
|
|
379
378
|
"record.feature.catalog.number.total.attribute": "Quantità totale di oggetti",
|
|
380
379
|
"record.feature.catalog.number.total.object": "Quantità totale di attributi",
|
|
@@ -580,6 +579,7 @@
|
|
|
580
579
|
"service.metadata.filter.noLayers": "Nessun layer abbina la ricerca",
|
|
581
580
|
"service.metadata.other": "Altri informazioni",
|
|
582
581
|
"service.metadata.question": "Fare una domanda",
|
|
582
|
+
"service.metadata.reuse": "",
|
|
583
583
|
"service.metadata.search": "Cerca nella lista del layers",
|
|
584
584
|
"service.metadata.search.clear": "Cancella la ricerca del layers",
|
|
585
585
|
"service.metadata.spatialExtent": "Estensione spaziale",
|
package/translations/nl.json
CHANGED
|
@@ -374,7 +374,6 @@
|
|
|
374
374
|
"record.action.rollback": "",
|
|
375
375
|
"record.action.switchLang": "",
|
|
376
376
|
"record.action.view": "",
|
|
377
|
-
"record.card.metadata.contact": "",
|
|
378
377
|
"record.externalViewer.open": "",
|
|
379
378
|
"record.feature.catalog.number.total.attribute": "",
|
|
380
379
|
"record.feature.catalog.number.total.object": "",
|
|
@@ -580,6 +579,7 @@
|
|
|
580
579
|
"service.metadata.filter.noLayers": "",
|
|
581
580
|
"service.metadata.other": "",
|
|
582
581
|
"service.metadata.question": "",
|
|
582
|
+
"service.metadata.reuse": "",
|
|
583
583
|
"service.metadata.search": "",
|
|
584
584
|
"service.metadata.search.clear": "",
|
|
585
585
|
"service.metadata.spatialExtent": "",
|
package/translations/pt.json
CHANGED
|
@@ -374,7 +374,6 @@
|
|
|
374
374
|
"record.action.rollback": "",
|
|
375
375
|
"record.action.switchLang": "",
|
|
376
376
|
"record.action.view": "",
|
|
377
|
-
"record.card.metadata.contact": "",
|
|
378
377
|
"record.externalViewer.open": "",
|
|
379
378
|
"record.feature.catalog.number.total.attribute": "",
|
|
380
379
|
"record.feature.catalog.number.total.object": "",
|
|
@@ -580,6 +579,7 @@
|
|
|
580
579
|
"service.metadata.filter.noLayers": "",
|
|
581
580
|
"service.metadata.other": "",
|
|
582
581
|
"service.metadata.question": "",
|
|
582
|
+
"service.metadata.reuse": "",
|
|
583
583
|
"service.metadata.search": "",
|
|
584
584
|
"service.metadata.search.clear": "",
|
|
585
585
|
"service.metadata.spatialExtent": "",
|
package/translations/sk.json
CHANGED
|
@@ -374,7 +374,6 @@
|
|
|
374
374
|
"record.action.rollback": "",
|
|
375
375
|
"record.action.switchLang": "",
|
|
376
376
|
"record.action.view": "Zobraziť",
|
|
377
|
-
"record.card.metadata.contact": "",
|
|
378
377
|
"record.externalViewer.open": "Otvoriť v externom mapovom prehliadači",
|
|
379
378
|
"record.feature.catalog.number.total.attribute": "",
|
|
380
379
|
"record.feature.catalog.number.total.object": "",
|
|
@@ -580,6 +579,7 @@
|
|
|
580
579
|
"service.metadata.filter.noLayers": "",
|
|
581
580
|
"service.metadata.other": "",
|
|
582
581
|
"service.metadata.question": "",
|
|
582
|
+
"service.metadata.reuse": "",
|
|
583
583
|
"service.metadata.search": "",
|
|
584
584
|
"service.metadata.search.clear": "",
|
|
585
585
|
"service.metadata.spatialExtent": "",
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
export function updateLanguages(record, defaultLanguage, otherLanguages) {
|
|
2
|
-
function updateFieldTranslations(target, fieldName) {
|
|
3
|
-
const fieldTranslations = {};
|
|
4
|
-
for (const lang of otherLanguages) {
|
|
5
|
-
const prevValue = record.defaultLanguage === lang
|
|
6
|
-
? target[fieldName]
|
|
7
|
-
: target.translations?.[fieldName]?.[lang];
|
|
8
|
-
fieldTranslations[lang] = prevValue ?? '';
|
|
9
|
-
}
|
|
10
|
-
const defaultPrevValue = record.defaultLanguage === defaultLanguage
|
|
11
|
-
? target[fieldName]
|
|
12
|
-
: target.translations?.[fieldName]?.[defaultLanguage];
|
|
13
|
-
return {
|
|
14
|
-
...target,
|
|
15
|
-
[fieldName]: defaultPrevValue ?? '',
|
|
16
|
-
translations: {
|
|
17
|
-
...target.translations,
|
|
18
|
-
[fieldName]: fieldTranslations,
|
|
19
|
-
},
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
function updateTranslations(target, fieldNames) {
|
|
23
|
-
let result = target;
|
|
24
|
-
for (const field of fieldNames) {
|
|
25
|
-
result = updateFieldTranslations(result, field);
|
|
26
|
-
}
|
|
27
|
-
return result;
|
|
28
|
-
}
|
|
29
|
-
const updatedRecord = updateTranslations(record, [
|
|
30
|
-
'title',
|
|
31
|
-
'abstract',
|
|
32
|
-
'lineage',
|
|
33
|
-
]);
|
|
34
|
-
updatedRecord.keywords = updatedRecord.keywords.map((k) => updateTranslations(k, ['label', 'description']));
|
|
35
|
-
updatedRecord.onlineResources = updatedRecord.onlineResources.map((o) => updateTranslations(o, ['name', 'description']));
|
|
36
|
-
updatedRecord.licenses = updatedRecord.licenses.map((l) => updateTranslations(l, ['text']));
|
|
37
|
-
updatedRecord.legalConstraints = updatedRecord.legalConstraints.map((c) => updateTranslations(c, ['text']));
|
|
38
|
-
updatedRecord.securityConstraints = updatedRecord.securityConstraints.map((c) => updateTranslations(c, ['text']));
|
|
39
|
-
updatedRecord.otherConstraints = updatedRecord.otherConstraints.map((c) => updateTranslations(c, ['text']));
|
|
40
|
-
updatedRecord.contacts = updatedRecord.contacts.map((c) => ({
|
|
41
|
-
...c,
|
|
42
|
-
organization: updateTranslations(c.organization, ['name']),
|
|
43
|
-
}));
|
|
44
|
-
updatedRecord.contactsForResource = updatedRecord.contactsForResource.map((c) => ({
|
|
45
|
-
...c,
|
|
46
|
-
organization: updateTranslations(c.organization, ['name']),
|
|
47
|
-
}));
|
|
48
|
-
updatedRecord.ownerOrganization = updateTranslations(updatedRecord.ownerOrganization, ['name']);
|
|
49
|
-
if (updatedRecord.kind === 'dataset') {
|
|
50
|
-
updatedRecord.spatialExtents = updatedRecord.spatialExtents.map((e) => updateTranslations(e, ['description']));
|
|
51
|
-
}
|
|
52
|
-
updatedRecord.defaultLanguage = defaultLanguage;
|
|
53
|
-
updatedRecord.otherLanguages = otherLanguages;
|
|
54
|
-
return updatedRecord;
|
|
55
|
-
}
|
|
56
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVjb3JkLnV0aWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9saWJzL3V0aWwvc2hhcmVkL3NyYy9saWIvcmVjb3JkLnV0aWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBeUJBLE1BQU0sVUFBVSxlQUFlLENBQzdCLE1BQVMsRUFDVCxlQUE2QixFQUM3QixjQUE4QjtJQUU5QixTQUFTLHVCQUF1QixDQUM5QixNQUFTLEVBQ1QsU0FBaUI7UUFFakIsTUFBTSxpQkFBaUIsR0FBRyxFQUFFLENBQUE7UUFDNUIsS0FBSyxNQUFNLElBQUksSUFBSSxjQUFjLEVBQUUsQ0FBQztZQUNsQyxNQUFNLFNBQVMsR0FDYixNQUFNLENBQUMsZUFBZSxLQUFLLElBQUk7Z0JBQzdCLENBQUMsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDO2dCQUNuQixDQUFDLENBQUMsTUFBTSxDQUFDLFlBQVksRUFBRSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUE7WUFDOUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLEdBQUcsU0FBUyxJQUFJLEVBQUUsQ0FBQTtRQUMzQyxDQUFDO1FBQ0QsTUFBTSxnQkFBZ0IsR0FDcEIsTUFBTSxDQUFDLGVBQWUsS0FBSyxlQUFlO1lBQ3hDLENBQUMsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDO1lBQ25CLENBQUMsQ0FBQyxNQUFNLENBQUMsWUFBWSxFQUFFLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxlQUFlLENBQUMsQ0FBQTtRQUN6RCxPQUFPO1lBQ0wsR0FBRyxNQUFNO1lBQ1QsQ0FBQyxTQUFTLENBQUMsRUFBRSxnQkFBZ0IsSUFBSSxFQUFFO1lBQ25DLFlBQVksRUFBRTtnQkFDWixHQUFHLE1BQU0sQ0FBQyxZQUFZO2dCQUN0QixDQUFDLFNBQVMsQ0FBQyxFQUFFLGlCQUFpQjthQUMvQjtTQUNGLENBQUE7SUFDSCxDQUFDO0lBQ0QsU0FBUyxrQkFBa0IsQ0FDekIsTUFB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Qy9DLGFBQWEsQ0FBQyxjQUFjLEdBQUcsY0FBYyxDQUFBO0lBQzdDLE9BQU8sYUFBYSxDQUFBO0FBQ3RCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBCYXNlUmVjb3JkLFxuICBDYXRhbG9nUmVjb3JkLFxuICBDb25zdHJhaW50LFxuICBEYXRhc2V0RG93bmxvYWREaXN0cmlidXRpb24sXG4gIERhdGFzZXRTZXJ2aWNlRGlzdHJpYnV0aW9uLFxuICBEYXRhc2V0U3BhdGlhbEV4dGVudCxcbiAgS2V5d29yZCxcbiAgTGFuZ3VhZ2VDb2RlLFxuICBPbmxpbmVMaW5rUmVzb3VyY2UsXG4gIE9yZ2FuaXphdGlvbixcbiAgU2VydmljZUVuZHBvaW50LFxufSBmcm9tICcuLi8uLi8uLi8uLi8uLi9saWJzL2NvbW1vbi9kb21haW4vc3JjL2xpYi9tb2RlbC9yZWNvcmQnXG5cbnR5cGUgVHJhbnNsYXRlZFJlY29yZE9iamVjdHMgPVxuICB8IEJhc2VSZWNvcmRcbiAgfCBDb25zdHJhaW50XG4gIHwgS2V5d29yZFxuICB8IERhdGFzZXRTZXJ2aWNlRGlzdHJpYnV0aW9uXG4gIHwgRGF0YXNldERvd25sb2FkRGlzdHJpYnV0aW9uXG4gIHwgT25saW5lTGlua1Jlc291cmNlXG4gIHwgU2VydmljZUVuZHBvaW50XG4gIHwgRGF0YXNldFNwYXRpYWxFeHRlbnRcbiAgfCBPcmdhbml6YXRpb25cblxuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZUxhbmd1YWdlczxUIGV4dGVuZHMgQ2F0YWxvZ1JlY29yZD4oXG4gIHJlY29yZDogVCxcbiAgZGVmYXVsdExhbmd1YWdlOiBMYW5ndWFnZUNvZGUsXG4gIG90aGVyTGFuZ3VhZ2VzOiBMYW5ndWFnZUNvZGVbXVxuKTogVCB7XG4gIGZ1bmN0aW9uIHVwZGF0ZUZpZWxkVHJhbnNsYXRpb25zPFQgZXh0ZW5kcyBUcmFuc2xhdGVkUmVjb3JkT2JqZWN0cz4oXG4gICAgdGFyZ2V0OiBULFxuICAgIGZpZWxkTmFtZTogc3RyaW5nXG4gICk6IFQge1xuICAgIGNvbnN0IGZpZWxkVHJhbnNsYXRpb25zID0ge31cbiAgICBmb3IgKGNvbnN0IGxhbmcgb2Ygb3RoZXJMYW5ndWFnZXMpIHtcbiAgICAgIGNvbnN0IHByZXZWYWx1ZSA9XG4gICAgICAgIHJlY29yZC5kZWZhdWx0TGFuZ3VhZ2UgPT09IGxhbmdcbiAgICAgICAgICA/IHRhcmdldFtmaWVsZE5hbWVdXG4gICAgICAgICAgOiB0YXJnZXQudHJhbnNsYXRpb25zPy5bZmllbGROYW1lXT8uW2xhbmddXG4gICAgICBmaWVsZFRyYW5zbGF0aW9uc1tsYW5nXSA9IHByZXZWYWx1ZSA/PyAnJ1xuICAgIH1cbiAgICBjb25zdCBkZWZhdWx0UHJldlZhbHVlID1cbiAgICAgIHJlY29yZC5kZWZhdWx0TGFuZ3VhZ2UgPT09IGRlZmF1bHRMYW5ndWFnZVxuICAgICAgICA/IHRhcmdldFtmaWVsZE5hbWVdXG4gICAgICAgIDogdGFyZ2V0LnRyYW5zbGF0aW9ucz8uW2ZpZWxkTmFtZV0/LltkZWZhdWx0TGFuZ3VhZ2VdXG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnRhcmdldCxcbiAgICAgIFtmaWVsZE5hbWVdOiBkZWZhdWx0UHJldlZhbHVlID8/ICcnLFxuICAgICAgdHJhbnNsYXRpb25zOiB7XG4gICAgICAgIC4uLnRhcmdldC50cmFuc2xhdGlvbnMsXG4gICAgICAgIFtmaWVsZE5hbWVdOiBmaWVsZFRyYW5zbGF0aW9ucyxcbiAgICAgIH0sXG4gICAgfVxuICB9XG4gIGZ1bmN0aW9uIHVwZGF0ZVRyYW5zbGF0aW9uczxUIGV4dGVuZHMgVHJhbnNsYXRlZFJlY29yZE9iamVjdHM+KFxuICAgIHRhcmdldDogVCxcbiAgICBmaWVsZE5hbWVzOiBzdHJpbmdbXVxuICApOiBUIHtcbiAgICBsZXQgcmVzdWx0OiBUID0gdGFyZ2V0XG4gICAgZm9yIChjb25zdCBmaWVsZCBvZiBmaWVsZE5hbWVzKSB7XG4gICAgICByZXN1bHQgPSB1cGRhdGVGaWVsZFRyYW5zbGF0aW9ucyhyZXN1bHQsIGZpZWxkKVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0XG4gIH1cblxuICBjb25zdCB1cGRhdGVkUmVjb3JkID0gdXBkYXRlVHJhbnNsYXRpb25zKHJlY29yZCwgW1xuICAgICd0aXRsZScsXG4gICAgJ2Fic3RyYWN0JyxcbiAgICAnbGluZWFnZScsXG4gIF0pXG4gIHVwZGF0ZWRSZWNvcmQua2V5d29yZHMgPSB1cGRhdGVkUmVjb3JkLmtleXdvcmRzLm1hcCgoaykgPT5cbiAgICB1cGRhdGVUcmFuc2xhdGlvbnMoaywgWydsYWJlbCcsICdkZXNjcmlwdGlvbiddKVxuICApXG4gIHVwZGF0ZWRSZWNvcmQub25saW5lUmVzb3VyY2VzID0gdXBkYXRlZFJlY29yZC5vbmxpbmVSZXNvdXJjZXMubWFwKChvKSA9PlxuICAgIHVwZGF0ZVRyYW5zbGF0aW9ucyhvLCBbJ25hbWUnLCAnZGVzY3JpcHRpb24nXSlcbiAgKVxuICB1cGRhdGVkUmVjb3JkLmxpY2Vuc2VzID0gdXBkYXRlZFJlY29yZC5saWNlbnNlcy5tYXAoKGwpID0+XG4gICAgdXBkYXRlVHJhbnNsYXRpb25zKGwsIFsndGV4dCddKVxuICApXG4gIHVwZGF0ZWRSZWNvcmQubGVnYWxDb25zdHJhaW50cyA9IHVwZGF0ZWRSZWNvcmQubGVnYWxDb25zdHJhaW50cy5tYXAoKGMpID0+XG4gICAgdXBkYXRlVHJhbnNsYXRpb25zKGMsIFsndGV4dCddKVxuICApXG4gIHVwZGF0ZWRSZWNvcmQuc2VjdXJpdHlDb25zdHJhaW50cyA9IHVwZGF0ZWRSZWNvcmQuc2VjdXJpdHlDb25zdHJhaW50cy5tYXAoXG4gICAgKGMpID0+IHVwZGF0ZVRyYW5zbGF0aW9ucyhjLCBbJ3RleHQnXSlcbiAgKVxuICB1cGRhdGVkUmVjb3JkLm90aGVyQ29uc3RyYWludHMgPSB1cGRhdGVkUmVjb3JkLm90aGVyQ29uc3RyYWludHMubWFwKChjKSA9PlxuICAgIHVwZGF0ZVRyYW5zbGF0aW9ucyhjLCBbJ3RleHQnXSlcbiAgKVxuICB1cGRhdGVkUmVjb3JkLmNvbnRhY3RzID0gdXBkYXRlZFJlY29yZC5jb250YWN0cy5tYXAoKGMpID0+ICh7XG4gICAgLi4uYyxcbiAgICBvcmdhbml6YXRpb246IHVwZGF0ZVRyYW5zbGF0aW9ucyhjLm9yZ2FuaXphdGlvbiwgWyduYW1lJ10pLFxuICB9KSlcbiAgdXBkYXRlZFJlY29yZC5jb250YWN0c0ZvclJlc291cmNlID0gdXBkYXRlZFJlY29yZC5jb250YWN0c0ZvclJlc291cmNlLm1hcChcbiAgICAoYykgPT4gKHtcbiAgICAgIC4uLmMsXG4gICAgICBvcmdhbml6YXRpb246IHVwZGF0ZVRyYW5zbGF0aW9ucyhjLm9yZ2FuaXphdGlvbiwgWyduYW1lJ10pLFxuICAgIH0pXG4gIClcbiAgdXBkYXRlZFJlY29yZC5vd25lck9yZ2FuaXphdGlvbiA9IHVwZGF0ZVRyYW5zbGF0aW9ucyhcbiAgICB1cGRhdGVkUmVjb3JkLm93bmVyT3JnYW5pemF0aW9uLFxuICAgIFsnbmFtZSddXG4gIClcblxuICBpZiAodXBkYXRlZFJlY29yZC5raW5kID09PSAnZGF0YXNldCcpIHtcbiAgICB1cGRhdGVkUmVjb3JkLnNwYXRpYWxFeHRlbnRzID0gdXBkYXRlZFJlY29yZC5zcGF0aWFsRXh0ZW50cy5tYXAoKGUpID0+XG4gICAgICB1cGRhdGVUcmFuc2xhdGlvbnMoZSwgWydkZXNjcmlwdGlvbiddKVxuICAgIClcbiAgfVxuXG4gIHVwZGF0ZWRSZWNvcmQuZGVmYXVsdExhbmd1YWdlID0gZGVmYXVsdExhbmd1YWdlXG4gIHVwZGF0ZWRSZWNvcmQub3RoZXJMYW5ndWFnZXMgPSBvdGhlckxhbmd1YWdlc1xuICByZXR1cm4gdXBkYXRlZFJlY29yZFxufVxuIl19
|