geonetwork-ui 2.3.0-dev.3d65a13b → 2.3.0-dev.c3722986

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.
Files changed (72) hide show
  1. package/esm2022/libs/data-access/gn4/src/openapi/api/records.api.service.mjs +35 -7
  2. package/esm2022/libs/data-access/gn4/src/openapi/model/models.mjs +1 -2
  3. package/esm2022/libs/ui/elements/src/lib/image-overlay-preview/image-overlay-preview.component.mjs +3 -3
  4. package/esm2022/libs/ui/elements/src/lib/metadata-info/metadata-info.component.mjs +3 -3
  5. package/esm2022/libs/ui/elements/src/lib/thumbnail/thumbnail.component.mjs +4 -3
  6. package/esm2022/libs/ui/elements/src/lib/ui-elements.module.mjs +6 -5
  7. package/esm2022/libs/ui/inputs/src/lib/button/button.component.mjs +2 -1
  8. package/esm2022/libs/ui/inputs/src/lib/files-drop/files-drop.directive.mjs +59 -0
  9. package/esm2022/libs/ui/inputs/src/lib/image-input/image-input.component.mjs +183 -0
  10. package/esm2022/libs/ui/inputs/src/lib/ui-inputs.module.mjs +10 -4
  11. package/esm2022/libs/util/shared/src/lib/utils/bytes-convert.mjs +4 -0
  12. package/esm2022/libs/util/shared/src/lib/utils/image-resize.mjs +60 -0
  13. package/esm2022/libs/util/shared/src/lib/utils/index.mjs +8 -6
  14. package/esm2022/translations/de.json +10 -0
  15. package/esm2022/translations/en.json +10 -0
  16. package/esm2022/translations/es.json +10 -0
  17. package/esm2022/translations/fr.json +10 -0
  18. package/esm2022/translations/it.json +10 -0
  19. package/esm2022/translations/nl.json +10 -0
  20. package/esm2022/translations/pt.json +10 -0
  21. package/fesm2022/geonetwork-ui.mjs +494 -114
  22. package/fesm2022/geonetwork-ui.mjs.map +1 -1
  23. package/libs/data-access/gn4/src/openapi/api/records.api.service.d.ts +9 -5
  24. package/libs/data-access/gn4/src/openapi/api/records.api.service.d.ts.map +1 -1
  25. package/libs/data-access/gn4/src/openapi/model/models.d.ts +0 -1
  26. package/libs/data-access/gn4/src/openapi/model/models.d.ts.map +1 -1
  27. package/libs/ui/elements/src/lib/thumbnail/thumbnail.component.d.ts +1 -1
  28. package/libs/ui/elements/src/lib/thumbnail/thumbnail.component.d.ts.map +1 -1
  29. package/libs/ui/elements/src/lib/ui-elements.module.d.ts +20 -20
  30. package/libs/ui/inputs/src/lib/button/button.component.d.ts.map +1 -1
  31. package/libs/ui/inputs/src/lib/files-drop/files-drop.directive.d.ts +14 -0
  32. package/libs/ui/inputs/src/lib/files-drop/files-drop.directive.d.ts.map +1 -0
  33. package/libs/ui/inputs/src/lib/image-input/image-input.component.d.ts +44 -0
  34. package/libs/ui/inputs/src/lib/image-input/image-input.component.d.ts.map +1 -0
  35. package/libs/ui/inputs/src/lib/ui-inputs.module.d.ts +2 -1
  36. package/libs/ui/inputs/src/lib/ui-inputs.module.d.ts.map +1 -1
  37. package/libs/util/shared/src/lib/utils/bytes-convert.d.ts +2 -0
  38. package/libs/util/shared/src/lib/utils/bytes-convert.d.ts.map +1 -0
  39. package/libs/util/shared/src/lib/utils/image-resize.d.ts +3 -0
  40. package/libs/util/shared/src/lib/utils/image-resize.d.ts.map +1 -0
  41. package/libs/util/shared/src/lib/utils/index.d.ts +7 -5
  42. package/libs/util/shared/src/lib/utils/index.d.ts.map +1 -1
  43. package/package.json +1 -1
  44. package/src/libs/data-access/gn4/src/openapi/api/records.api.service.ts +43 -12
  45. package/src/libs/data-access/gn4/src/openapi/model/models.ts +0 -1
  46. package/src/libs/data-access/gn4/src/spec.yaml +1 -1
  47. package/src/libs/feature/editor/src/lib/components/overview-upload/overview-upload.component.css +0 -0
  48. package/src/libs/feature/editor/src/lib/components/overview-upload/overview-upload.component.html +8 -0
  49. package/src/libs/feature/editor/src/lib/components/overview-upload/overview-upload.component.ts +70 -0
  50. package/src/libs/ui/elements/src/lib/thumbnail/thumbnail.component.ts +5 -3
  51. package/src/libs/ui/elements/src/lib/ui-elements.module.ts +1 -1
  52. package/src/libs/ui/inputs/src/lib/button/button.component.ts +1 -1
  53. package/src/libs/ui/inputs/src/lib/files-drop/files-drop.directive.ts +45 -0
  54. package/src/libs/ui/inputs/src/lib/image-input/image-input.component.css +0 -0
  55. package/src/libs/ui/inputs/src/lib/image-input/image-input.component.html +146 -0
  56. package/src/libs/ui/inputs/src/lib/image-input/image-input.component.ts +193 -0
  57. package/src/libs/ui/inputs/src/lib/ui-inputs.module.ts +3 -0
  58. package/src/libs/util/shared/src/lib/utils/bytes-convert.ts +3 -0
  59. package/src/libs/util/shared/src/lib/utils/image-resize.ts +72 -0
  60. package/src/libs/util/shared/src/lib/utils/index.ts +7 -5
  61. package/translations/de.json +10 -0
  62. package/translations/en.json +10 -0
  63. package/translations/es.json +10 -0
  64. package/translations/fr.json +10 -0
  65. package/translations/it.json +10 -0
  66. package/translations/nl.json +10 -0
  67. package/translations/pt.json +10 -0
  68. package/translations/sk.json +10 -0
  69. package/esm2022/libs/data-access/gn4/src/openapi/model/inlineObject3.api.model.mjs +0 -13
  70. package/libs/data-access/gn4/src/openapi/model/inlineObject3.api.model.d.ts +0 -18
  71. package/libs/data-access/gn4/src/openapi/model/inlineObject3.api.model.d.ts.map +0 -1
  72. package/src/libs/data-access/gn4/src/openapi/model/inlineObject3.api.model.ts +0 -18
@@ -6008,6 +6008,19 @@ class RecordsApiService {
6008
6008
  }
6009
6009
  this.encoder = this.configuration.encoder || new CustomHttpParameterCodec();
6010
6010
  }
6011
+ /**
6012
+ * @param consumes string[] mime-types
6013
+ * @return true: consumes contains 'multipart/form-data', false: otherwise
6014
+ */
6015
+ canConsumeForm(consumes) {
6016
+ const form = 'multipart/form-data';
6017
+ for (const consume of consumes) {
6018
+ if (form === consume) {
6019
+ return true;
6020
+ }
6021
+ }
6022
+ return false;
6023
+ }
6011
6024
  addToHttpParams(httpParams, value, key) {
6012
6025
  if (typeof value === 'object' && value instanceof Date === false) {
6013
6026
  httpParams = this.addToHttpParamsRecursive(httpParams, value);
@@ -8981,10 +8994,13 @@ class RecordsApiService {
8981
8994
  reportProgress: reportProgress,
8982
8995
  });
8983
8996
  }
8984
- putResource(metadataUuid, visibility, approved, inlineObject3ApiModel, observe = 'body', reportProgress = false, options) {
8997
+ putResource(metadataUuid, file, visibility, approved, observe = 'body', reportProgress = false, options) {
8985
8998
  if (metadataUuid === null || metadataUuid === undefined) {
8986
8999
  throw new Error('Required parameter metadataUuid was null or undefined when calling putResource.');
8987
9000
  }
9001
+ if (file === null || file === undefined) {
9002
+ throw new Error('Required parameter file was null or undefined when calling putResource.');
9003
+ }
8988
9004
  let queryParameters = new HttpParams({ encoder: this.encoder });
8989
9005
  if (visibility !== undefined && visibility !== null) {
8990
9006
  queryParameters = this.addToHttpParams(queryParameters, visibility, 'visibility');
@@ -9004,17 +9020,29 @@ class RecordsApiService {
9004
9020
  headers = headers.set('Accept', httpHeaderAcceptSelected);
9005
9021
  }
9006
9022
  // to determine the Content-Type header
9007
- const consumes = ['application/json'];
9008
- const httpContentTypeSelected = this.configuration.selectHeaderContentType(consumes);
9009
- if (httpContentTypeSelected !== undefined) {
9010
- headers = headers.set('Content-Type', httpContentTypeSelected);
9023
+ const consumes = ['multipart/form-data'];
9024
+ const canConsumeForm = this.canConsumeForm(consumes);
9025
+ let formParams;
9026
+ let useForm = false;
9027
+ let convertFormParamsToString = false;
9028
+ // use FormData to transmit files using content-type "multipart/form-data"
9029
+ // see https://stackoverflow.com/questions/4007969/application-x-www-form-urlencoded-or-multipart-form-data
9030
+ useForm = canConsumeForm;
9031
+ if (useForm) {
9032
+ formParams = new FormData();
9033
+ }
9034
+ else {
9035
+ formParams = new HttpParams({ encoder: this.encoder });
9036
+ }
9037
+ if (file !== undefined) {
9038
+ formParams = formParams.append('file', file) || formParams;
9011
9039
  }
9012
9040
  let responseType_ = 'json';
9013
9041
  if (httpHeaderAcceptSelected &&
9014
9042
  httpHeaderAcceptSelected.startsWith('text')) {
9015
9043
  responseType_ = 'text';
9016
9044
  }
9017
- return this.httpClient.post(`${this.configuration.basePath}/records/${encodeURIComponent(String(metadataUuid))}/attachments`, inlineObject3ApiModel, {
9045
+ return this.httpClient.post(`${this.configuration.basePath}/records/${encodeURIComponent(String(metadataUuid))}/attachments`, convertFormParamsToString ? formParams.toString() : formParams, {
9018
9046
  params: queryParameters,
9019
9047
  responseType: responseType_,
9020
9048
  withCredentials: this.configuration.withCredentials,
@@ -16236,18 +16264,6 @@ var GroupPrivilegeApiModel;
16236
16264
  * Do not edit the class manually.
16237
16265
  */
16238
16266
 
16239
- /**
16240
- * GeoNetwork 4.2.7 OpenAPI Documentation
16241
- * This is the description of the GeoNetwork OpenAPI. Use this API to manage your catalog.
16242
- *
16243
- * The version of the OpenAPI document: 4.2.7
16244
- * Contact: geonetwork-users@lists.sourceforge.net
16245
- *
16246
- * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
16247
- * https://openapi-generator.tech
16248
- * Do not edit the class manually.
16249
- */
16250
-
16251
16267
  /**
16252
16268
  * GeoNetwork 4.2.7 OpenAPI Documentation
16253
16269
  * This is the description of the GeoNetwork OpenAPI. Use this API to manage your catalog.
@@ -17414,6 +17430,16 @@ var de = {
17414
17430
  "facets.block.title.tag.default": "Stichwort",
17415
17431
  "facets.block.title.th_regions_tree.default": "Regionen",
17416
17432
  "favorite.not.authenticated.tooltip": "<div><a href=' {link} '>Anmelden</a>, um auf diese Funktion zuzugreifen</div>",
17433
+ "input.image.altTextPlaceholder": "",
17434
+ "input.image.delete": "",
17435
+ "input.image.displayAltTextInput": "",
17436
+ "input.image.displayUrlInput": "",
17437
+ "input.image.dropFileLabel": "",
17438
+ "input.image.selectFileLabel": "",
17439
+ "input.image.uploadErrorLabel": "",
17440
+ "input.image.uploadErrorRetry": "",
17441
+ "input.image.uploadProgressCancel": "",
17442
+ "input.image.uploadProgressLabel": "",
17417
17443
  "language.ca": "Katalanisch",
17418
17444
  "language.cs": "Tschechisch",
17419
17445
  "language.de": "Deutsch",
@@ -17766,6 +17792,16 @@ var en = {
17766
17792
  "facets.block.title.tag.default": "Tag",
17767
17793
  "facets.block.title.th_regions_tree.default": "Regions",
17768
17794
  "favorite.not.authenticated.tooltip": "<div><a href=' {link} '>Login</a> to access this feature</div>",
17795
+ "input.image.altTextPlaceholder": "Image alternate text",
17796
+ "input.image.delete": "Delete",
17797
+ "input.image.displayAltTextInput": "Alternate text",
17798
+ "input.image.displayUrlInput": "Enter a URL",
17799
+ "input.image.dropFileLabel": "or drop it here",
17800
+ "input.image.selectFileLabel": "Select an image",
17801
+ "input.image.uploadErrorLabel": "The image could not be uploaded",
17802
+ "input.image.uploadErrorRetry": "Retry",
17803
+ "input.image.uploadProgressCancel": "Cancel",
17804
+ "input.image.uploadProgressLabel": "Upload in progress...",
17769
17805
  "language.ca": "Catalan",
17770
17806
  "language.cs": "Czech",
17771
17807
  "language.de": "German",
@@ -18118,6 +18154,16 @@ var es = {
18118
18154
  "facets.block.title.tag.default": "",
18119
18155
  "facets.block.title.th_regions_tree.default": "",
18120
18156
  "favorite.not.authenticated.tooltip": "",
18157
+ "input.image.altTextPlaceholder": "",
18158
+ "input.image.delete": "",
18159
+ "input.image.displayAltTextInput": "",
18160
+ "input.image.displayUrlInput": "",
18161
+ "input.image.dropFileLabel": "",
18162
+ "input.image.selectFileLabel": "",
18163
+ "input.image.uploadErrorLabel": "",
18164
+ "input.image.uploadErrorRetry": "",
18165
+ "input.image.uploadProgressCancel": "",
18166
+ "input.image.uploadProgressLabel": "",
18121
18167
  "language.ca": "Catalán",
18122
18168
  "language.cs": "Checo",
18123
18169
  "language.de": "Alemán",
@@ -18470,6 +18516,16 @@ var fr = {
18470
18516
  "facets.block.title.tag.default": "Tag",
18471
18517
  "facets.block.title.th_regions_tree.default": "Régions",
18472
18518
  "favorite.not.authenticated.tooltip": "<div><a href=' {link} '>Connectez-vous</a> pour avoir accès à cette fonctionnalité</div>",
18519
+ "input.image.altTextPlaceholder": "Texte alternatif de l'image",
18520
+ "input.image.delete": "Supprimer",
18521
+ "input.image.displayAltTextInput": "Texte alternatif",
18522
+ "input.image.displayUrlInput": "Saisir une URL",
18523
+ "input.image.dropFileLabel": "ou la glisser ici",
18524
+ "input.image.selectFileLabel": "Sélectionner une image",
18525
+ "input.image.uploadErrorLabel": "L'image n'a pas pu être chargée",
18526
+ "input.image.uploadErrorRetry": "Réessayer",
18527
+ "input.image.uploadProgressCancel": "Annuler",
18528
+ "input.image.uploadProgressLabel": "Chargement en cours...",
18473
18529
  "language.ca": "Catalan",
18474
18530
  "language.cs": "Tchèque",
18475
18531
  "language.de": "Allemand",
@@ -18822,6 +18878,16 @@ var it = {
18822
18878
  "facets.block.title.tag.default": "Tag",
18823
18879
  "facets.block.title.th_regions_tree.default": "Regioni",
18824
18880
  "favorite.not.authenticated.tooltip": "<div><a href=' {link} '>Login</a> per accedere a questa funzionalità</div>",
18881
+ "input.image.altTextPlaceholder": "",
18882
+ "input.image.delete": "",
18883
+ "input.image.displayAltTextInput": "",
18884
+ "input.image.displayUrlInput": "",
18885
+ "input.image.dropFileLabel": "",
18886
+ "input.image.selectFileLabel": "",
18887
+ "input.image.uploadErrorLabel": "",
18888
+ "input.image.uploadErrorRetry": "",
18889
+ "input.image.uploadProgressCancel": "",
18890
+ "input.image.uploadProgressLabel": "",
18825
18891
  "language.ca": "Catalano",
18826
18892
  "language.cs": "Ceco",
18827
18893
  "language.de": "Tedesco",
@@ -19174,6 +19240,16 @@ var nl = {
19174
19240
  "facets.block.title.tag.default": "",
19175
19241
  "facets.block.title.th_regions_tree.default": "",
19176
19242
  "favorite.not.authenticated.tooltip": "",
19243
+ "input.image.altTextPlaceholder": "",
19244
+ "input.image.delete": "",
19245
+ "input.image.displayAltTextInput": "",
19246
+ "input.image.displayUrlInput": "",
19247
+ "input.image.dropFileLabel": "",
19248
+ "input.image.selectFileLabel": "",
19249
+ "input.image.uploadErrorLabel": "",
19250
+ "input.image.uploadErrorRetry": "",
19251
+ "input.image.uploadProgressCancel": "",
19252
+ "input.image.uploadProgressLabel": "",
19177
19253
  "language.ca": "Catalaans",
19178
19254
  "language.cs": "Tsjechisch",
19179
19255
  "language.de": "Duits",
@@ -19526,6 +19602,16 @@ var pt = {
19526
19602
  "facets.block.title.tag.default": "",
19527
19603
  "facets.block.title.th_regions_tree.default": "",
19528
19604
  "favorite.not.authenticated.tooltip": "",
19605
+ "input.image.altTextPlaceholder": "",
19606
+ "input.image.delete": "",
19607
+ "input.image.displayAltTextInput": "",
19608
+ "input.image.displayUrlInput": "",
19609
+ "input.image.dropFileLabel": "",
19610
+ "input.image.selectFileLabel": "",
19611
+ "input.image.uploadErrorLabel": "",
19612
+ "input.image.uploadErrorRetry": "",
19613
+ "input.image.uploadProgressCancel": "",
19614
+ "input.image.uploadProgressLabel": "",
19529
19615
  "language.ca": "Catalão",
19530
19616
  "language.cs": "Tcheco",
19531
19617
  "language.de": "Alemão",
@@ -21663,6 +21749,130 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
21663
21749
  args: [PROXY_PATH]
21664
21750
  }] }]; } });
21665
21751
 
21752
+ function megabytesToBytes(megabytes) {
21753
+ return megabytes * 1048576;
21754
+ }
21755
+
21756
+ /**
21757
+ * This should be called instead of event.stopPropagation()
21758
+ * to make sure that the document receives the event
21759
+ * @param event
21760
+ */
21761
+ function propagateToDocumentOnly(event) {
21762
+ event.stopPropagation();
21763
+ setTimeout(() => {
21764
+ window.document.dispatchEvent(event);
21765
+ }, 0);
21766
+ }
21767
+
21768
+ function normalize(input) {
21769
+ return input
21770
+ .toLowerCase()
21771
+ .normalize('NFD') // explode composite chars (e.g. é) into multiple chars
21772
+ .replace(/[\u0300-\u036f]/g, '') // remove accents
21773
+ .replace(/œ/g, 'oe') // remove accents
21774
+ .replace(/[^a-z0-9\s]/g, ' '); // replace special characters with space
21775
+ }
21776
+ function asNormalizedParts(input) {
21777
+ return normalize(input)
21778
+ .split(/\s+/)
21779
+ .map((part) => part.trim())
21780
+ .filter((part) => part.length > 0);
21781
+ }
21782
+ /**
21783
+ * This creates a filter function based on a pattern (typically a user-input
21784
+ * search text).
21785
+ * @param pattern
21786
+ */
21787
+ function createFuzzyFilter(pattern) {
21788
+ const patternParts = asNormalizedParts(pattern);
21789
+ return (input) => {
21790
+ const inputParts = asNormalizedParts(input);
21791
+ return patternParts.every((patternPart) => inputParts.some((part) => part.includes(patternPart)));
21792
+ };
21793
+ }
21794
+
21795
+ function getGeometryFromGeoJSON(data) {
21796
+ if (data.type === 'FeatureCollection') {
21797
+ return data?.features?.[0]?.geometry || null;
21798
+ }
21799
+ if (data.type === 'Feature') {
21800
+ return data?.geometry || null;
21801
+ }
21802
+ if (data.type === 'GeometryCollection') {
21803
+ return data?.geometries?.[0] || null;
21804
+ }
21805
+ if (data.type === 'Polygon' ||
21806
+ data.type === 'Point' ||
21807
+ data.type === 'LineString' ||
21808
+ data.type === 'MultiPolygon' ||
21809
+ data.type === 'MultiPoint' ||
21810
+ data.type === 'MultiLineString') {
21811
+ return data || null;
21812
+ }
21813
+ return null;
21814
+ }
21815
+
21816
+ function downsizeImage(blob, maxWidth, maxHeight) {
21817
+ return new Promise((resolve, reject) => {
21818
+ const image = new Image();
21819
+ image.src = URL.createObjectURL(blob);
21820
+ image.onload = () => {
21821
+ let width = image.width;
21822
+ let height = image.height;
21823
+ if (width > maxWidth || height > maxHeight) {
21824
+ if (width > height) {
21825
+ height = height * (maxWidth / width);
21826
+ width = maxWidth;
21827
+ }
21828
+ else {
21829
+ width = width * (maxHeight / height);
21830
+ height = maxHeight;
21831
+ }
21832
+ }
21833
+ const canvas = document.createElement('canvas');
21834
+ canvas.width = width;
21835
+ canvas.height = height;
21836
+ const context = canvas.getContext('2d');
21837
+ context.drawImage(image, 0, 0, width, height);
21838
+ canvas.toBlob(resolve, blob.type);
21839
+ };
21840
+ image.onerror = reject;
21841
+ });
21842
+ }
21843
+ function downgradeImage(blob, maxSizeBytes) {
21844
+ return new Promise((resolve, reject) => {
21845
+ const image = new Image();
21846
+ image.src = URL.createObjectURL(blob);
21847
+ image.onload = () => {
21848
+ const width = image.width;
21849
+ const height = image.height;
21850
+ let quality = 1.0;
21851
+ const canvas = document.createElement('canvas');
21852
+ canvas.width = width;
21853
+ canvas.height = height;
21854
+ const context = canvas.getContext('2d');
21855
+ context.drawImage(image, 0, 0, width, height);
21856
+ const compressAndResolveBlob = (blobToCompress) => {
21857
+ if (blobToCompress.size <= maxSizeBytes) {
21858
+ resolve(blobToCompress);
21859
+ }
21860
+ else {
21861
+ quality -= 0.1;
21862
+ if (quality >= 0) {
21863
+ canvas.toBlob(compressAndResolveBlob, blob.type, quality);
21864
+ }
21865
+ else {
21866
+ reject('Unable to compress image below max size');
21867
+ }
21868
+ }
21869
+ };
21870
+ canvas.toBlob(compressAndResolveBlob, blob.type, quality);
21871
+ };
21872
+ image.onerror = reject;
21873
+ });
21874
+ }
21875
+
21666
21876
  /*
21667
21877
  * Implement AngularJS $parse
21668
21878
  * delimiter is `^^^^` cause object properties can contain `.`
@@ -21696,38 +21906,10 @@ const parse = (path) => {
21696
21906
  return fn;
21697
21907
  };
21698
21908
 
21699
- const stripHtml = function (html) {
21700
- if (!html)
21701
- return undefined;
21702
- const doc = new DOMParser().parseFromString(html, 'text/html');
21703
- return doc.body.textContent || '';
21704
- };
21705
-
21706
21909
  const removeWhitespace = function (str) {
21707
21910
  return str?.replace(/\s+/g, ' ').trim();
21708
21911
  };
21709
21912
 
21710
- function getGeometryFromGeoJSON(data) {
21711
- if (data.type === 'FeatureCollection') {
21712
- return data?.features?.[0]?.geometry || null;
21713
- }
21714
- if (data.type === 'Feature') {
21715
- return data?.geometry || null;
21716
- }
21717
- if (data.type === 'GeometryCollection') {
21718
- return data?.geometries?.[0] || null;
21719
- }
21720
- if (data.type === 'Polygon' ||
21721
- data.type === 'Point' ||
21722
- data.type === 'LineString' ||
21723
- data.type === 'MultiPolygon' ||
21724
- data.type === 'MultiPoint' ||
21725
- data.type === 'MultiLineString') {
21726
- return data || null;
21727
- }
21728
- return null;
21729
- }
21730
-
21731
21913
  function sortByToStrings(sortBy) {
21732
21914
  const array = Array.isArray(sortBy[0]) ? sortBy : [sortBy];
21733
21915
  return array.map((param) => `${param[0] === 'desc' ? '-' : ''}${param[1]}`);
@@ -21742,62 +21924,12 @@ function sortByFromString(sortByString) {
21742
21924
  ];
21743
21925
  }
21744
21926
 
21745
- /**
21746
- * Removes the given search params from the URL completely; this is case-insensitive
21747
- * @param url
21748
- * @param searchParams
21749
- */
21750
- function removeSearchParams(url, searchParams) {
21751
- const toDelete = [];
21752
- const urlObj = new URL(url, window.location.toString());
21753
- const keysLower = searchParams.map((p) => p.toLowerCase());
21754
- for (const param of urlObj.searchParams.keys()) {
21755
- if (keysLower.indexOf(param.toLowerCase()) > -1) {
21756
- toDelete.push(param);
21757
- }
21758
- }
21759
- toDelete.map((param) => urlObj.searchParams.delete(param));
21760
- return urlObj.toString();
21761
- }
21762
-
21763
- /**
21764
- * This should be called instead of event.stopPropagation()
21765
- * to make sure that the document receives the event
21766
- * @param event
21767
- */
21768
- function propagateToDocumentOnly(event) {
21769
- event.stopPropagation();
21770
- setTimeout(() => {
21771
- window.document.dispatchEvent(event);
21772
- }, 0);
21773
- }
21774
-
21775
- function normalize(input) {
21776
- return input
21777
- .toLowerCase()
21778
- .normalize('NFD') // explode composite chars (e.g. é) into multiple chars
21779
- .replace(/[\u0300-\u036f]/g, '') // remove accents
21780
- .replace(/œ/g, 'oe') // remove accents
21781
- .replace(/[^a-z0-9\s]/g, ' '); // replace special characters with space
21782
- }
21783
- function asNormalizedParts(input) {
21784
- return normalize(input)
21785
- .split(/\s+/)
21786
- .map((part) => part.trim())
21787
- .filter((part) => part.length > 0);
21788
- }
21789
- /**
21790
- * This creates a filter function based on a pattern (typically a user-input
21791
- * search text).
21792
- * @param pattern
21793
- */
21794
- function createFuzzyFilter(pattern) {
21795
- const patternParts = asNormalizedParts(pattern);
21796
- return (input) => {
21797
- const inputParts = asNormalizedParts(input);
21798
- return patternParts.every((patternPart) => inputParts.some((part) => part.includes(patternPart)));
21799
- };
21800
- }
21927
+ const stripHtml = function (html) {
21928
+ if (!html)
21929
+ return undefined;
21930
+ const doc = new DOMParser().parseFromString(html, 'text/html');
21931
+ return doc.body.textContent || '';
21932
+ };
21801
21933
 
21802
21934
  function getTemporalRangeUnion(ranges) {
21803
21935
  let earliestStartDate = Infinity;
@@ -21831,6 +21963,24 @@ function getTemporalRangeUnion(ranges) {
21831
21963
  }
21832
21964
  }
21833
21965
 
21966
+ /**
21967
+ * Removes the given search params from the URL completely; this is case-insensitive
21968
+ * @param url
21969
+ * @param searchParams
21970
+ */
21971
+ function removeSearchParams(url, searchParams) {
21972
+ const toDelete = [];
21973
+ const urlObj = new URL(url, window.location.toString());
21974
+ const keysLower = searchParams.map((p) => p.toLowerCase());
21975
+ for (const param of urlObj.searchParams.keys()) {
21976
+ if (keysLower.indexOf(param.toLowerCase()) > -1) {
21977
+ toDelete.push(param);
21978
+ }
21979
+ }
21980
+ toDelete.map((param) => urlObj.searchParams.delete(param));
21981
+ return urlObj.toString();
21982
+ }
21983
+
21834
21984
  marker('downloads.wfs.featuretype.not.found');
21835
21985
  const FORMATS = {
21836
21986
  csv: {
@@ -23602,6 +23752,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
23602
23752
 
23603
23753
  class ButtonComponent {
23604
23754
  constructor() {
23755
+ this.btnClass = 'gn-ui-btn-default';
23605
23756
  this.disabled = false;
23606
23757
  this.extraClass = '';
23607
23758
  this.buttonClick = new EventEmitter();
@@ -24983,6 +25134,229 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
24983
25134
  type: Input
24984
25135
  }] } });
24985
25136
 
25137
+ class FilesDropDirective {
25138
+ constructor() {
25139
+ this.dragFilesOver = new EventEmitter();
25140
+ this.dropFiles = new EventEmitter();
25141
+ this.dragEnterCounter = 0;
25142
+ }
25143
+ _onDragEnter(event) {
25144
+ event.preventDefault();
25145
+ this.dragEnterCounter++;
25146
+ this.dragFilesOver.emit(true);
25147
+ }
25148
+ _onDragOver(event) {
25149
+ event.preventDefault();
25150
+ }
25151
+ _onDragLeave(event) {
25152
+ event.preventDefault();
25153
+ this.dragEnterCounter = Math.max(0, this.dragEnterCounter - 1);
25154
+ if (this.dragEnterCounter === 0) {
25155
+ this.dragFilesOver.emit(false);
25156
+ }
25157
+ }
25158
+ _onDrop(event) {
25159
+ event.preventDefault();
25160
+ this.dragEnterCounter = 0;
25161
+ this.dragFilesOver.emit(false);
25162
+ const files = Array.from(event.dataTransfer.files);
25163
+ if (files.length > 0) {
25164
+ this.dropFiles.emit(files);
25165
+ }
25166
+ }
25167
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FilesDropDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
25168
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.1.7", type: FilesDropDirective, isStandalone: true, selector: "[gnUiFilesDrop]", outputs: { dragFilesOver: "dragFilesOver", dropFiles: "dropFiles" }, host: { listeners: { "dragenter": "_onDragEnter($event)", "dragover": "_onDragOver($event)", "dragleave": "_onDragLeave($event)", "drop": "_onDrop($event)" } }, ngImport: i0 }); }
25169
+ }
25170
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FilesDropDirective, decorators: [{
25171
+ type: Directive,
25172
+ args: [{
25173
+ selector: '[gnUiFilesDrop]',
25174
+ standalone: true,
25175
+ }]
25176
+ }], propDecorators: { dragFilesOver: [{
25177
+ type: Output
25178
+ }], dropFiles: [{
25179
+ type: Output
25180
+ }], _onDragEnter: [{
25181
+ type: HostListener,
25182
+ args: ['dragenter', ['$event']]
25183
+ }], _onDragOver: [{
25184
+ type: HostListener,
25185
+ args: ['dragover', ['$event']]
25186
+ }], _onDragLeave: [{
25187
+ type: HostListener,
25188
+ args: ['dragleave', ['$event']]
25189
+ }], _onDrop: [{
25190
+ type: HostListener,
25191
+ args: ['drop', ['$event']]
25192
+ }] } });
25193
+
25194
+ class ImageInputComponent {
25195
+ constructor(http, cd) {
25196
+ this.http = http;
25197
+ this.cd = cd;
25198
+ this.fileChange = new EventEmitter();
25199
+ this.urlChange = new EventEmitter();
25200
+ this.uploadCancel = new EventEmitter();
25201
+ this.delete = new EventEmitter();
25202
+ this.altTextChange = new EventEmitter();
25203
+ this.dragFilesOver = false;
25204
+ this.showUrlInput = false;
25205
+ this.downloadError = false;
25206
+ this.showAltTextInput = false;
25207
+ }
25208
+ getPrimaryText() {
25209
+ if (this.uploadError) {
25210
+ return marker('input.image.uploadErrorLabel');
25211
+ }
25212
+ if (this.uploadProgress) {
25213
+ return marker('input.image.uploadProgressLabel');
25214
+ }
25215
+ return marker('input.image.selectFileLabel');
25216
+ }
25217
+ getSecondaryText() {
25218
+ if (this.uploadError) {
25219
+ return marker('input.image.uploadErrorRetry');
25220
+ }
25221
+ if (this.uploadProgress) {
25222
+ return marker('input.image.uploadProgressCancel');
25223
+ }
25224
+ return marker('input.image.dropFileLabel');
25225
+ }
25226
+ handleDragFilesOver(dragFilesOver) {
25227
+ if (!this.showUrlInput) {
25228
+ this.dragFilesOver = dragFilesOver;
25229
+ this.cd.markForCheck();
25230
+ }
25231
+ }
25232
+ handleDropFiles(files) {
25233
+ if (!this.showUrlInput) {
25234
+ const validFiles = this.filterTypeImage(files);
25235
+ if (validFiles.length > 0) {
25236
+ this.resizeAndEmit(validFiles[0]);
25237
+ }
25238
+ }
25239
+ }
25240
+ handleFileInput(event) {
25241
+ const inputFiles = Array.from(event.target.files);
25242
+ const validFiles = this.filterTypeImage(inputFiles);
25243
+ if (validFiles.length > 0) {
25244
+ this.resizeAndEmit(validFiles[0]);
25245
+ }
25246
+ }
25247
+ displayUrlInput() {
25248
+ this.uploadCancel.emit();
25249
+ this.showUrlInput = true;
25250
+ }
25251
+ handleUrlChange(event) {
25252
+ this.downloadError = false;
25253
+ this.urlInputValue = event.target.value;
25254
+ }
25255
+ async downloadUrl() {
25256
+ const name = this.urlInputValue.split('/').pop();
25257
+ try {
25258
+ const response = await firstValueFrom(this.http.head(this.urlInputValue, { observe: 'response' }));
25259
+ if (response.headers.get('content-type')?.startsWith('image/') &&
25260
+ parseInt(response.headers.get('content-length')) <
25261
+ megabytesToBytes(this.maxSizeMB)) {
25262
+ this.http.get(this.urlInputValue, { responseType: 'blob' }).subscribe({
25263
+ next: (blob) => {
25264
+ this.cd.markForCheck();
25265
+ const file = new File([blob], name);
25266
+ this.fileChange.emit(file);
25267
+ },
25268
+ error: () => {
25269
+ this.downloadError = true;
25270
+ this.cd.markForCheck();
25271
+ this.urlChange.emit(this.urlInputValue);
25272
+ },
25273
+ });
25274
+ }
25275
+ }
25276
+ catch {
25277
+ this.downloadError = true;
25278
+ this.cd.markForCheck();
25279
+ return;
25280
+ }
25281
+ }
25282
+ handleSecondaryTextClick() {
25283
+ if (this.uploadError) {
25284
+ this.handleRetry();
25285
+ }
25286
+ else if (this.uploadProgress) {
25287
+ this.handleCancel();
25288
+ }
25289
+ }
25290
+ handleCancel() {
25291
+ this.uploadCancel.emit();
25292
+ }
25293
+ handleRetry() {
25294
+ switch (this.lastUploadType) {
25295
+ case 'file':
25296
+ this.fileChange.emit(this.lastUploadContent);
25297
+ break;
25298
+ case 'url':
25299
+ this.urlChange.emit(this.lastUploadContent);
25300
+ break;
25301
+ }
25302
+ }
25303
+ handleDelete() {
25304
+ this.delete.emit();
25305
+ }
25306
+ toggleAltTextInput() {
25307
+ this.showAltTextInput = !this.showAltTextInput;
25308
+ }
25309
+ handleAltTextChange(event) {
25310
+ const input = event.target;
25311
+ this.altTextChange.emit(input.value);
25312
+ }
25313
+ filterTypeImage(files) {
25314
+ return files.filter((file) => {
25315
+ return file.type.startsWith('image/');
25316
+ });
25317
+ }
25318
+ resizeAndEmit(imageToResize) {
25319
+ const maxSizeBytes = megabytesToBytes(this.maxSizeMB);
25320
+ downgradeImage(imageToResize, maxSizeBytes).then((resizedImage) => {
25321
+ const fileToEmit = new File([resizedImage], imageToResize.name);
25322
+ this.fileChange.emit(fileToEmit);
25323
+ });
25324
+ }
25325
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ImageInputComponent, deps: [{ token: i1.HttpClient }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
25326
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: ImageInputComponent, isStandalone: true, selector: "gn-ui-image-input", inputs: { maxSizeMB: "maxSizeMB", previewUrl: "previewUrl", altText: "altText", uploadProgress: "uploadProgress", uploadError: "uploadError" }, outputs: { fileChange: "fileChange", urlChange: "urlChange", uploadCancel: "uploadCancel", delete: "delete", altTextChange: "altTextChange" }, ngImport: i0, template: "<ng-container *ngIf=\"previewUrl; then withImage; else withoutImage\">\n</ng-container>\n\n<ng-template #withImage>\n <div class=\"w-full h-full flex flex-col gap-2\">\n <div class=\"flex-1 group relative\">\n <img\n class=\"w-full h-full object-cover border-2 border-gray-300 rounded-lg\"\n [alt]=\"altText\"\n loading=\"lazy\"\n [src]=\"previewUrl\"\n />\n <gn-ui-button\n [extraClass]=\"\n 'bg-gray-200 absolute right-2 bottom-2 invisible group-hover:visible'\n \"\n (buttonClick)=\"handleDelete()\"\n >\n <mat-icon class=\"material-symbols-outlined\">delete</mat-icon>\n </gn-ui-button>\n </div>\n <input\n *ngIf=\"showAltTextInput\"\n type=\"text\"\n class=\"py-3 px-2 border-2 border-gray-300 rounded-lg text-sm font-medium\"\n [placeholder]=\"'input.image.altTextPlaceholder' | translate\"\n [value]=\"altText\"\n (change)=\"handleAltTextChange($event)\"\n />\n <div class=\"flex flex-row gap-2\">\n <gn-ui-button\n [extraClass]=\"'bg-gray-200 font-bold'\"\n (buttonClick)=\"handleDelete()\"\n >\n <mat-icon class=\"material-symbols-outlined me-1\">delete</mat-icon>\n {{ 'input.image.delete' | translate }}\n </gn-ui-button>\n <gn-ui-button\n *ngIf=\"!showAltTextInput\"\n [extraClass]=\"'bg-gray-200 font-bold'\"\n (buttonClick)=\"toggleAltTextInput()\"\n >\n <mat-icon class=\"material-symbols-outlined me-1\">add</mat-icon>\n {{ 'input.image.displayAltTextInput' | translate }}\n </gn-ui-button>\n </div>\n </div>\n</ng-template>\n\n<ng-template #withoutImage>\n <div class=\"w-full h-full flex flex-col gap-2\">\n <label\n gnUiFilesDrop\n class=\"block flex-1 border-2 border-dashed border-gray-300 rounded-lg p-6 flex flex-col items-center justify-center gap-4\"\n (dragFilesOver)=\"handleDragFilesOver($event)\"\n (dropFiles)=\"handleDropFiles($event)\"\n >\n <div class=\"w-14 h-14 rounded-md bg-gray-200 grid\">\n <mat-icon\n *ngIf=\"!dragFilesOver && !uploadProgress && !uploadError\"\n class=\"material-symbols-outlined place-self-center text-blue-500\"\n >image</mat-icon\n >\n <mat-icon\n *ngIf=\"dragFilesOver && !uploadProgress && !uploadError\"\n class=\"material-symbols-outlined place-self-center text-blue-500\"\n >add_box</mat-icon\n >\n <div *ngIf=\"uploadProgress\">\n <mat-progress-spinner\n class=\"place-self-center\"\n [diameter]=\"56\"\n [mode]=\"'determinate'\"\n [value]=\"uploadProgress\"\n ></mat-progress-spinner>\n <span\n class=\"text-sm font-medium relative inline-block width-[30px] bottom-[40px] left-[15px]\"\n >\n {{ uploadProgress }}%\n </span>\n </div>\n <mat-icon\n *ngIf=\"uploadError\"\n class=\"material-symbols-outlined place-self-center text-rose-500\"\n >broken_image</mat-icon\n >\n </div>\n <div class=\"flex flex-col items-center gap-1\">\n <p class=\"font-medium\">{{ getPrimaryText() | translate }}</p>\n <p\n class=\"text-sm\"\n [class]=\"\n uploadProgress || uploadError\n ? 'font-bold text-blue-500 cursor-pointer'\n : 'font-medium text-gray-500'\n \"\n (click)=\"handleSecondaryTextClick()\"\n >\n {{ getSecondaryText() | translate }}\n </p>\n </div>\n <input\n type=\"file\"\n class=\"hidden\"\n (change)=\"handleFileInput($event)\"\n [disabled]=\"showUrlInput || uploadProgress || uploadError\"\n />\n </label>\n <div *ngIf=\"!showUrlInput\" class=\"flex-none\">\n <gn-ui-button\n [extraClass]=\"'bg-gray-200 font-bold'\"\n (buttonClick)=\"displayUrlInput()\"\n >\n <mat-icon class=\"material-symbols-outlined me-1\">link</mat-icon>\n {{ 'input.image.displayUrlInput' | translate }}\n </gn-ui-button>\n </div>\n <div *ngIf=\"showUrlInput\" class=\"flex-none flex flex-col gap-2\">\n <div class=\"h-2\"></div>\n <div class=\"flex gap-2 items-center\">\n <div class=\"flex-1 flex rounded-lg\">\n <span\n class=\"material-symbols-outlined px-4 inline-flex items-center min-w-fit rounded-s-lg border-2 border-e-0 border-gray-300\"\n >link</span\n >\n <input\n type=\"text\"\n class=\"py-3 ps-1 block w-full border-2 border-s-0 border-e-0 border-gray-300 text-sm font-medium\"\n placeholder=\"https://exemple.com/image.jpg\"\n (change)=\"handleUrlChange($event)\"\n />\n <gn-ui-button\n class=\"px-1 inline-flex items-center min-w-fit rounded-e-lg border-2 border-s-0 border-gray-300 text-white\"\n [extraClass]=\"\n urlInputValue && !downloadError ? 'bg-blue-500' : 'bg-gray-500'\n \"\n [disabled]=\"!urlInputValue || downloadError\"\n (buttonClick)=\"downloadUrl()\"\n >\n <mat-icon class=\"material-symbols-outlined\">arrow_upward</mat-icon>\n </gn-ui-button>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: FilesDropDirective, selector: "[gnUiFilesDrop]", outputs: ["dragFilesOver", "dropFiles"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i1$5.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
25327
+ }
25328
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ImageInputComponent, decorators: [{
25329
+ type: Component,
25330
+ args: [{ selector: 'gn-ui-image-input', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
25331
+ CommonModule,
25332
+ ButtonComponent,
25333
+ MatIconModule,
25334
+ FilesDropDirective,
25335
+ MatProgressSpinnerModule,
25336
+ TranslateModule,
25337
+ ], template: "<ng-container *ngIf=\"previewUrl; then withImage; else withoutImage\">\n</ng-container>\n\n<ng-template #withImage>\n <div class=\"w-full h-full flex flex-col gap-2\">\n <div class=\"flex-1 group relative\">\n <img\n class=\"w-full h-full object-cover border-2 border-gray-300 rounded-lg\"\n [alt]=\"altText\"\n loading=\"lazy\"\n [src]=\"previewUrl\"\n />\n <gn-ui-button\n [extraClass]=\"\n 'bg-gray-200 absolute right-2 bottom-2 invisible group-hover:visible'\n \"\n (buttonClick)=\"handleDelete()\"\n >\n <mat-icon class=\"material-symbols-outlined\">delete</mat-icon>\n </gn-ui-button>\n </div>\n <input\n *ngIf=\"showAltTextInput\"\n type=\"text\"\n class=\"py-3 px-2 border-2 border-gray-300 rounded-lg text-sm font-medium\"\n [placeholder]=\"'input.image.altTextPlaceholder' | translate\"\n [value]=\"altText\"\n (change)=\"handleAltTextChange($event)\"\n />\n <div class=\"flex flex-row gap-2\">\n <gn-ui-button\n [extraClass]=\"'bg-gray-200 font-bold'\"\n (buttonClick)=\"handleDelete()\"\n >\n <mat-icon class=\"material-symbols-outlined me-1\">delete</mat-icon>\n {{ 'input.image.delete' | translate }}\n </gn-ui-button>\n <gn-ui-button\n *ngIf=\"!showAltTextInput\"\n [extraClass]=\"'bg-gray-200 font-bold'\"\n (buttonClick)=\"toggleAltTextInput()\"\n >\n <mat-icon class=\"material-symbols-outlined me-1\">add</mat-icon>\n {{ 'input.image.displayAltTextInput' | translate }}\n </gn-ui-button>\n </div>\n </div>\n</ng-template>\n\n<ng-template #withoutImage>\n <div class=\"w-full h-full flex flex-col gap-2\">\n <label\n gnUiFilesDrop\n class=\"block flex-1 border-2 border-dashed border-gray-300 rounded-lg p-6 flex flex-col items-center justify-center gap-4\"\n (dragFilesOver)=\"handleDragFilesOver($event)\"\n (dropFiles)=\"handleDropFiles($event)\"\n >\n <div class=\"w-14 h-14 rounded-md bg-gray-200 grid\">\n <mat-icon\n *ngIf=\"!dragFilesOver && !uploadProgress && !uploadError\"\n class=\"material-symbols-outlined place-self-center text-blue-500\"\n >image</mat-icon\n >\n <mat-icon\n *ngIf=\"dragFilesOver && !uploadProgress && !uploadError\"\n class=\"material-symbols-outlined place-self-center text-blue-500\"\n >add_box</mat-icon\n >\n <div *ngIf=\"uploadProgress\">\n <mat-progress-spinner\n class=\"place-self-center\"\n [diameter]=\"56\"\n [mode]=\"'determinate'\"\n [value]=\"uploadProgress\"\n ></mat-progress-spinner>\n <span\n class=\"text-sm font-medium relative inline-block width-[30px] bottom-[40px] left-[15px]\"\n >\n {{ uploadProgress }}%\n </span>\n </div>\n <mat-icon\n *ngIf=\"uploadError\"\n class=\"material-symbols-outlined place-self-center text-rose-500\"\n >broken_image</mat-icon\n >\n </div>\n <div class=\"flex flex-col items-center gap-1\">\n <p class=\"font-medium\">{{ getPrimaryText() | translate }}</p>\n <p\n class=\"text-sm\"\n [class]=\"\n uploadProgress || uploadError\n ? 'font-bold text-blue-500 cursor-pointer'\n : 'font-medium text-gray-500'\n \"\n (click)=\"handleSecondaryTextClick()\"\n >\n {{ getSecondaryText() | translate }}\n </p>\n </div>\n <input\n type=\"file\"\n class=\"hidden\"\n (change)=\"handleFileInput($event)\"\n [disabled]=\"showUrlInput || uploadProgress || uploadError\"\n />\n </label>\n <div *ngIf=\"!showUrlInput\" class=\"flex-none\">\n <gn-ui-button\n [extraClass]=\"'bg-gray-200 font-bold'\"\n (buttonClick)=\"displayUrlInput()\"\n >\n <mat-icon class=\"material-symbols-outlined me-1\">link</mat-icon>\n {{ 'input.image.displayUrlInput' | translate }}\n </gn-ui-button>\n </div>\n <div *ngIf=\"showUrlInput\" class=\"flex-none flex flex-col gap-2\">\n <div class=\"h-2\"></div>\n <div class=\"flex gap-2 items-center\">\n <div class=\"flex-1 flex rounded-lg\">\n <span\n class=\"material-symbols-outlined px-4 inline-flex items-center min-w-fit rounded-s-lg border-2 border-e-0 border-gray-300\"\n >link</span\n >\n <input\n type=\"text\"\n class=\"py-3 ps-1 block w-full border-2 border-s-0 border-e-0 border-gray-300 text-sm font-medium\"\n placeholder=\"https://exemple.com/image.jpg\"\n (change)=\"handleUrlChange($event)\"\n />\n <gn-ui-button\n class=\"px-1 inline-flex items-center min-w-fit rounded-e-lg border-2 border-s-0 border-gray-300 text-white\"\n [extraClass]=\"\n urlInputValue && !downloadError ? 'bg-blue-500' : 'bg-gray-500'\n \"\n [disabled]=\"!urlInputValue || downloadError\"\n (buttonClick)=\"downloadUrl()\"\n >\n <mat-icon class=\"material-symbols-outlined\">arrow_upward</mat-icon>\n </gn-ui-button>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n" }]
25338
+ }], ctorParameters: function () { return [{ type: i1.HttpClient }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { maxSizeMB: [{
25339
+ type: Input
25340
+ }], previewUrl: [{
25341
+ type: Input
25342
+ }], altText: [{
25343
+ type: Input
25344
+ }], uploadProgress: [{
25345
+ type: Input
25346
+ }], uploadError: [{
25347
+ type: Input
25348
+ }], fileChange: [{
25349
+ type: Output
25350
+ }], urlChange: [{
25351
+ type: Output
25352
+ }], uploadCancel: [{
25353
+ type: Output
25354
+ }], delete: [{
25355
+ type: Output
25356
+ }], altTextChange: [{
25357
+ type: Output
25358
+ }] } });
25359
+
24986
25360
  class UiInputsModule {
24987
25361
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: UiInputsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
24988
25362
  static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.1.7", ngImport: i0, type: UiInputsModule, declarations: [DropdownSelectorComponent,
@@ -25023,7 +25397,8 @@ class UiInputsModule {
25023
25397
  MatNativeDateModule,
25024
25398
  EditableLabelDirective,
25025
25399
  TextAreaComponent,
25026
- ButtonComponent], exports: [DropdownSelectorComponent,
25400
+ ButtonComponent,
25401
+ ImageInputComponent], exports: [DropdownSelectorComponent,
25027
25402
  AutocompleteComponent,
25028
25403
  ButtonComponent,
25029
25404
  TextInputComponent,
@@ -25040,7 +25415,8 @@ class UiInputsModule {
25040
25415
  CheckboxComponent,
25041
25416
  SearchInputComponent,
25042
25417
  DateRangePickerComponent,
25043
- EditableLabelDirective] }); }
25418
+ EditableLabelDirective,
25419
+ ImageInputComponent] }); }
25044
25420
  static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: UiInputsModule, imports: [CommonModule,
25045
25421
  TranslateModule.forChild(),
25046
25422
  NgxDropzoneModule,
@@ -25057,7 +25433,8 @@ class UiInputsModule {
25057
25433
  MatFormFieldModule,
25058
25434
  MatInputModule,
25059
25435
  MatDatepickerModule,
25060
- MatNativeDateModule] }); }
25436
+ MatNativeDateModule,
25437
+ ImageInputComponent] }); }
25061
25438
  }
25062
25439
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: UiInputsModule, decorators: [{
25063
25440
  type: NgModule,
@@ -25107,6 +25484,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
25107
25484
  EditableLabelDirective,
25108
25485
  TextAreaComponent,
25109
25486
  ButtonComponent,
25487
+ ImageInputComponent,
25110
25488
  ],
25111
25489
  exports: [
25112
25490
  DropdownSelectorComponent,
@@ -25127,6 +25505,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
25127
25505
  SearchInputComponent,
25128
25506
  DateRangePickerComponent,
25129
25507
  EditableLabelDirective,
25508
+ ImageInputComponent,
25130
25509
  ],
25131
25510
  }]
25132
25511
  }] });
@@ -25620,11 +25999,11 @@ class ThumbnailComponent {
25620
25999
  }
25621
26000
  }
25622
26001
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ThumbnailComponent, deps: [{ token: THUMBNAIL_PLACEHOLDER, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
25623
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: ThumbnailComponent, selector: "gn-ui-thumbnail", inputs: { thumbnailUrl: "thumbnailUrl", fit: "fit" }, outputs: { placeholderShown: "placeholderShown" }, viewQueries: [{ propertyName: "imgElement", first: true, predicate: ["imageElement"], descendants: true }, { propertyName: "containerElement", first: true, predicate: ["containerElement"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n #containerElement\n class=\"h-full w-full relative shrink-0 overflow-hidden flex items-center justify-center\"\n [ngClass]=\"isPlaceholder ? 'bg-gray-100' : 'bg-white'\"\n [attr.data-cy-is-placeholder]=\"isPlaceholder.toString()\"\n>\n <img\n #imageElement\n class=\"relative w-full object-center\"\n [ngClass]=\"imgFit === 'contain' ? 'h-4/5 w-4/5' : 'h-full'\"\n [ngStyle]=\"{ objectFit: imgFit }\"\n alt=\"thumbnail\"\n loading=\"lazy\"\n (load)=\"setObjectFit()\"\n [src]=\"imgUrl\"\n (error)=\"useFallback()\"\n />\n</div>\n", dependencies: [{ kind: "directive", type: i1$3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
26002
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: ThumbnailComponent, isStandalone: true, selector: "gn-ui-thumbnail", inputs: { thumbnailUrl: "thumbnailUrl", fit: "fit" }, outputs: { placeholderShown: "placeholderShown" }, viewQueries: [{ propertyName: "imgElement", first: true, predicate: ["imageElement"], descendants: true }, { propertyName: "containerElement", first: true, predicate: ["containerElement"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n #containerElement\n class=\"h-full w-full relative shrink-0 overflow-hidden flex items-center justify-center\"\n [ngClass]=\"isPlaceholder ? 'bg-gray-100' : 'bg-white'\"\n [attr.data-cy-is-placeholder]=\"isPlaceholder.toString()\"\n>\n <img\n #imageElement\n class=\"relative w-full object-center\"\n [ngClass]=\"imgFit === 'contain' ? 'h-4/5 w-4/5' : 'h-full'\"\n [ngStyle]=\"{ objectFit: imgFit }\"\n alt=\"thumbnail\"\n loading=\"lazy\"\n (load)=\"setObjectFit()\"\n [src]=\"imgUrl\"\n (error)=\"useFallback()\"\n />\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
25624
26003
  }
25625
26004
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ThumbnailComponent, decorators: [{
25626
26005
  type: Component,
25627
- args: [{ selector: 'gn-ui-thumbnail', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n #containerElement\n class=\"h-full w-full relative shrink-0 overflow-hidden flex items-center justify-center\"\n [ngClass]=\"isPlaceholder ? 'bg-gray-100' : 'bg-white'\"\n [attr.data-cy-is-placeholder]=\"isPlaceholder.toString()\"\n>\n <img\n #imageElement\n class=\"relative w-full object-center\"\n [ngClass]=\"imgFit === 'contain' ? 'h-4/5 w-4/5' : 'h-full'\"\n [ngStyle]=\"{ objectFit: imgFit }\"\n alt=\"thumbnail\"\n loading=\"lazy\"\n (load)=\"setObjectFit()\"\n [src]=\"imgUrl\"\n (error)=\"useFallback()\"\n />\n</div>\n" }]
26006
+ args: [{ selector: 'gn-ui-thumbnail', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [CommonModule], template: "<div\n #containerElement\n class=\"h-full w-full relative shrink-0 overflow-hidden flex items-center justify-center\"\n [ngClass]=\"isPlaceholder ? 'bg-gray-100' : 'bg-white'\"\n [attr.data-cy-is-placeholder]=\"isPlaceholder.toString()\"\n>\n <img\n #imageElement\n class=\"relative w-full object-center\"\n [ngClass]=\"imgFit === 'contain' ? 'h-4/5 w-4/5' : 'h-full'\"\n [ngStyle]=\"{ objectFit: imgFit }\"\n alt=\"thumbnail\"\n loading=\"lazy\"\n (load)=\"setObjectFit()\"\n [src]=\"imgUrl\"\n (error)=\"useFallback()\"\n />\n</div>\n" }]
25628
26007
  }], ctorParameters: function () { return [{ type: undefined, decorators: [{
25629
26008
  type: Optional
25630
26009
  }, {
@@ -26180,7 +26559,7 @@ class MetadataInfoComponent {
26180
26559
  this.keyword.emit(keyword);
26181
26560
  }
26182
26561
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MetadataInfoComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26183
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: MetadataInfoComponent, selector: "gn-ui-metadata-info", inputs: { metadata: "metadata", incomplete: "incomplete" }, outputs: { keyword: "keyword" }, ngImport: i0, template: "<div class=\"mb-6 md-description sm:mb-4 sm:pr-16\">\n <gn-ui-content-ghost ghostClass=\"h-32\" [showContent]=\"fieldReady('abstract')\">\n <gn-ui-max-lines [maxLines]=\"6\" *ngIf=\"metadata.abstract\">\n <div>\n <gn-ui-markdown-parser\n [textContent]=\"metadata.abstract\"\n ></gn-ui-markdown-parser>\n </div>\n </gn-ui-max-lines>\n <div *ngIf=\"metadata.keywords?.length\">\n <p class=\"mt-6 mb-3 font-medium text-primary text-sm\" translate>\n record.metadata.keywords\n </p>\n <div class=\"sm:pb-4 flex flex-wrap gap-2\">\n <gn-ui-badge\n class=\"inline-block lowercase\"\n (click)=\"onKeywordClick(keyword)\"\n [clickable]=\"true\"\n *ngFor=\"let keyword of metadata.keywords\"\n >{{ keyword.label }}</gn-ui-badge\n >\n </div>\n </div>\n </gn-ui-content-ghost>\n</div>\n\n<gn-ui-expandable-panel [title]=\"'record.metadata.usage' | translate\">\n <div class=\"flex flex-col gap-[10px] mr-4 py-[12px] rounded text-gray-900\">\n <ng-container *ngFor=\"let license of licenses\">\n <div *ngIf=\"license.url; else noUrl\" class=\"text-primary\">\n <a\n [href]=\"license.url\"\n target=\"_blank\"\n class=\"cursor-pointer hover:underline transition-all\"\n >\n {{ license.text }}\n <mat-icon\n class=\"material-symbols-outlined !w-[12px] !h-[12px] !text-[12px] opacity-75 shrink-0\"\n >open_in_new</mat-icon\n >\n </a>\n </div>\n <ng-template #noUrl>\n <div class=\"text-primary\" gnUiLinkify>\n {{ license.text }}\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"legalConstraints.length\">\n <gn-ui-markdown-parser\n *ngFor=\"let constraint of legalConstraints\"\n [textContent]=\"constraint\"\n >\n </gn-ui-markdown-parser>\n </ng-container>\n <ng-container *ngIf=\"otherConstraints.length\">\n <div gnUiLinkify *ngFor=\"let constraint of otherConstraints\">\n <h5 translate class=\"font-medium text-black text-sm mb-[2px] mt-[16px]\">\n record.metadata.otherConstraints\n </h5>\n <gn-ui-markdown-parser [textContent]=\"constraint\">\n </gn-ui-markdown-parser>\n </div>\n </ng-container>\n\n <span class=\"noUsage\" *ngIf=\"!hasUsage\">\n {{ 'record.metadata.noUsage' | translate }}\n </span>\n </div>\n</gn-ui-expandable-panel>\n<gn-ui-expandable-panel\n *ngIf=\"\n metadata.lineage ||\n metadata.recordUpdated ||\n metadata.updateFrequency ||\n metadata.status\n \"\n [title]=\"'record.metadata.details' | translate\"\n>\n <div *ngIf=\"metadata.lineage\" class=\"text-gray-900 flex flex-col mt-4 gap-2\">\n <p class=\"whitespace-pre-line break-words text-gray-900\" gnUiLinkify>\n {{ metadata.lineage }}\n </p>\n </div>\n <div class=\"flex flex-row gap-6 mt-5 mb-8\" *ngIf=\"resourceContact\">\n <div\n *ngIf=\"resourceContact.organization?.logoUrl?.href\"\n class=\"flex items-center justify-center border-solid border border-gray-300 rounded-md bg-white h-32 overflow-hidden\"\n >\n <gn-ui-thumbnail\n class=\"relative h-full w-full\"\n [thumbnailUrl]=\"resourceContact.organization.logoUrl.href\"\n fit=\"contain\"\n ></gn-ui-thumbnail>\n </div>\n <div class=\"flex flex-col gap-1\">\n <p class=\"text-sm font-medium\" translate>record.metadata.producer</p>\n <div\n class=\"text-primary font-title text-21 mr-2 cursor-pointer hover:underline\"\n data-cy=\"organization-name\"\n >\n {{ resourceContact.organization?.name }}\n </div>\n <div *ngIf=\"resourceContact.organization?.website\">\n <a\n [href]=\"resourceContact.organization.website\"\n target=\"_blank\"\n class=\"contact-website text-primary text-sm cursor-pointer hover:underline transition-all\"\n >{{ resourceContact.organization.website }}\n <mat-icon\n class=\"material-symbols-outlined !w-[12px] !h-[12px] !text-[12px] opacity-75 shrink-0\"\n >open_in_new</mat-icon\n >\n </a>\n </div>\n <div class=\"mt-4\" *ngIf=\"resourceContact.email\">\n <div class=\"flex\">\n <mat-icon\n class=\"material-symbols-outlined !w-5 !h-5 !text-[20px] opacity-75 shrink-0\"\n >\n mail_outline</mat-icon\n >\n <a\n *ngIf=\"resourceContact.email\"\n [href]=\"'mailto:' + resourceContact.email\"\n class=\"text-sm hover:underline ml-2\"\n target=\"_blank\"\n data-cy=\"contact-email\"\n >{{ resourceContact?.email }}</a\n >\n </div>\n </div>\n </div>\n </div>\n <div\n class=\"py-6 px-6 rounded bg-gray-100 grid grid-cols-2 gap-y-6 gap-x-[20px] text-gray-700\"\n >\n <div *ngIf=\"metadata.recordCreated\">\n <p class=\"text-sm\" translate>record.metadata.creation</p>\n <p class=\"text-primary font-medium mt-1\">\n {{ metadata.recordCreated.toLocaleDateString() }}\n </p>\n </div>\n <div *ngIf=\"metadata.recordPublished\">\n <p class=\"text-sm\" translate>record.metadata.publication</p>\n <p class=\"text-primary font-medium mt-1\">\n {{ metadata.recordPublished.toLocaleDateString() }}\n </p>\n </div>\n <div *ngIf=\"updateFrequency\">\n <p class=\"text-sm\" translate>record.metadata.updateFrequency</p>\n <p\n class=\"text-primary font-medium mt-1 updateFrequency\"\n translate\n [translateParams]=\"{ count: updatedTimes }\"\n >\n {{ updateFrequency }}\n </p>\n </div>\n <div *ngIf=\"metadata.languages\">\n <p class=\"text-sm mb-1\" translate>record.metadata.languages</p>\n <div class=\"flex flex-row gap-1 flex-wrap\">\n <p\n class=\"text-primary font-medium\"\n translate\n *ngFor=\"let language of metadata.languages\"\n >\n language.{{ language }}\n </p>\n </div>\n </div>\n <div *ngIf=\"temporalExtent\">\n <p class=\"text-sm\" translate>record.metadata.temporalExtent</p>\n <div class=\"flex flex-row gap-1 mb-1 text-primary font-medium\">\n <p\n *ngIf=\"temporalExtent.start && temporalExtent.end\"\n translate\n [translateParams]=\"{\n start: temporalExtent.start,\n end: temporalExtent.end\n }\"\n >\n record.metadata.temporalExtent.fromDateToDate\n </p>\n <p\n *ngIf=\"temporalExtent.start && !temporalExtent.end\"\n translate\n [translateParams]=\"{ start: temporalExtent.start }\"\n >\n record.metadata.temporalExtent.sinceDate\n </p>\n <p\n *ngIf=\"!temporalExtent.start && temporalExtent.end\"\n translate\n [translateParams]=\"{ end: temporalExtent.end }\"\n >\n record.metadata.temporalExtent.untilDate\n </p>\n </div>\n </div>\n </div>\n</gn-ui-expandable-panel>\n<gn-ui-expandable-panel\n *ngIf=\"metadata.landingPage\"\n [title]=\"'record.metadata.technical' | translate\"\n>\n <div class=\"flex flex-col gap-4 mr-4 py-5 rounded text-gray-700\">\n <div *ngIf=\"metadata.recordUpdated\">\n <p class=\"text-sm\" translate>record.metadata.updatedOn</p>\n <p class=\"text-primary font-medium\">\n {{ metadata.recordUpdated && metadata.recordUpdated.toLocaleString() }}\n </p>\n </div>\n <div *ngIf=\"metadata.landingPage\">\n <p class=\"text-sm\" translate>record.metadata.sheet</p>\n <p class=\"text-primary font-medium\" translate>\n <a [href]=\"metadata.landingPage\" target=\"_blank\">\n <span class=\"break-all\" gnUiLinkify>{{ metadata.landingPage }}</span>\n </a>\n </p>\n </div>\n <div *ngIf=\"metadata.ownerOrganization\">\n <p class=\"text-sm\" translate>record.metadata.owner</p>\n <p class=\"text-primary font-medium\">\n {{ metadata.ownerOrganization.name }}\n </p>\n </div>\n <div *ngIf=\"metadata.uniqueIdentifier\">\n <p class=\"text-sm\" translate>record.metadata.uniqueId</p>\n <div class=\"flex flex-row content-align items-end gap-1\">\n <gn-ui-copy-text-button\n [text]=\"metadata.uniqueIdentifier\"\n [tooltipText]=\"'tooltip.id.copy' | translate\"\n [displayText]=\"false\"\n ></gn-ui-copy-text-button>\n <p class=\"text-primary font-medium\">\n {{ metadata.uniqueIdentifier }}\n </p>\n </div>\n </div>\n <div *ngIf=\"metadata.topics?.length\">\n <p class=\"text-sm mb-1\" translate>record.metadata.topics</p>\n <div class=\"sm:pb-4 sm:pr-16\">\n <gn-ui-badge\n class=\"inline-block mr-2 mb-2 lowercase\"\n *ngFor=\"let topic of metadata.topics\"\n >{{ topic }}</gn-ui-badge\n >\n </div>\n </div>\n </div>\n</gn-ui-expandable-panel>\n", styles: [".md-description ::ng-deep a{@apply underline text-blue-600 hover:text-blue-800;}.info-grid>:nth-last-child(n+3){padding-bottom:10px;@apply border-b border-gray-300;}:host ::ng-deep gn-ui-copy-text-button button mat-icon{transform:scale(.8)}\n"], dependencies: [{ kind: "directive", type: i1$3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: BadgeComponent, selector: "gn-ui-badge", inputs: ["clickable"] }, { kind: "component", type: ExpandablePanelComponent, selector: "gn-ui-expandable-panel", inputs: ["title", "collapsed"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: CopyTextButtonComponent, selector: "gn-ui-copy-text-button", inputs: ["text", "tooltipText", "displayText", "rows"] }, { kind: "component", type: MarkdownParserComponent, selector: "gn-ui-markdown-parser", inputs: ["textContent"] }, { kind: "component", type: ContentGhostComponent, selector: "gn-ui-content-ghost", inputs: ["showContent", "ghostClass"] }, { kind: "component", type: ThumbnailComponent, selector: "gn-ui-thumbnail", inputs: ["thumbnailUrl", "fit"], outputs: ["placeholderShown"] }, { kind: "directive", type: GnUiLinkifyDirective, selector: "[gnUiLinkify]" }, { kind: "component", type: MaxLinesComponent, selector: "gn-ui-max-lines", inputs: ["maxLines"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
26562
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: MetadataInfoComponent, selector: "gn-ui-metadata-info", inputs: { metadata: "metadata", incomplete: "incomplete" }, outputs: { keyword: "keyword" }, ngImport: i0, template: "<div class=\"mb-6 md-description sm:mb-4 sm:pr-16\">\n <gn-ui-content-ghost ghostClass=\"h-32\" [showContent]=\"fieldReady('abstract')\">\n <gn-ui-max-lines [maxLines]=\"6\" *ngIf=\"metadata.abstract\">\n <div>\n <gn-ui-markdown-parser\n [textContent]=\"metadata.abstract\"\n ></gn-ui-markdown-parser>\n </div>\n </gn-ui-max-lines>\n <div *ngIf=\"metadata.keywords?.length\">\n <p class=\"mt-6 mb-3 font-medium text-primary text-sm\" translate>\n record.metadata.keywords\n </p>\n <div class=\"sm:pb-4 flex flex-wrap gap-2\">\n <gn-ui-badge\n class=\"inline-block lowercase\"\n (click)=\"onKeywordClick(keyword)\"\n [clickable]=\"true\"\n *ngFor=\"let keyword of metadata.keywords\"\n >{{ keyword.label }}</gn-ui-badge\n >\n </div>\n </div>\n </gn-ui-content-ghost>\n</div>\n\n<gn-ui-expandable-panel [title]=\"'record.metadata.usage' | translate\">\n <div class=\"flex flex-col gap-[10px] mr-4 py-[12px] rounded text-gray-900\">\n <ng-container *ngFor=\"let license of licenses\">\n <div *ngIf=\"license.url; else noUrl\" class=\"text-primary\">\n <a\n [href]=\"license.url\"\n target=\"_blank\"\n class=\"cursor-pointer hover:underline transition-all\"\n >\n {{ license.text }}\n <mat-icon\n class=\"material-symbols-outlined !w-[12px] !h-[12px] !text-[12px] opacity-75 shrink-0\"\n >open_in_new</mat-icon\n >\n </a>\n </div>\n <ng-template #noUrl>\n <div class=\"text-primary\" gnUiLinkify>\n {{ license.text }}\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"legalConstraints.length\">\n <gn-ui-markdown-parser\n *ngFor=\"let constraint of legalConstraints\"\n [textContent]=\"constraint\"\n >\n </gn-ui-markdown-parser>\n </ng-container>\n <ng-container *ngIf=\"otherConstraints.length\">\n <div gnUiLinkify *ngFor=\"let constraint of otherConstraints\">\n <h5 translate class=\"font-medium text-black text-sm mb-[2px] mt-[16px]\">\n record.metadata.otherConstraints\n </h5>\n <gn-ui-markdown-parser [textContent]=\"constraint\">\n </gn-ui-markdown-parser>\n </div>\n </ng-container>\n\n <span class=\"noUsage\" *ngIf=\"!hasUsage\">\n {{ 'record.metadata.noUsage' | translate }}\n </span>\n </div>\n</gn-ui-expandable-panel>\n<gn-ui-expandable-panel\n *ngIf=\"\n metadata.lineage ||\n metadata.recordUpdated ||\n metadata.updateFrequency ||\n metadata.status\n \"\n [title]=\"'record.metadata.details' | translate\"\n>\n <div *ngIf=\"metadata.lineage\" class=\"text-gray-900 flex flex-col mt-4 gap-2\">\n <p class=\"whitespace-pre-line break-words text-gray-900\" gnUiLinkify>\n {{ metadata.lineage }}\n </p>\n </div>\n <div class=\"flex flex-row gap-6 mt-5 mb-8\" *ngIf=\"resourceContact\">\n <div\n *ngIf=\"resourceContact.organization?.logoUrl?.href\"\n class=\"flex items-center justify-center border-solid border border-gray-300 rounded-md bg-white h-32 overflow-hidden\"\n >\n <gn-ui-thumbnail\n class=\"relative h-full w-full\"\n [thumbnailUrl]=\"resourceContact.organization.logoUrl.href\"\n fit=\"contain\"\n ></gn-ui-thumbnail>\n </div>\n <div class=\"flex flex-col gap-1\">\n <p class=\"text-sm font-medium\" translate>record.metadata.producer</p>\n <div\n class=\"text-primary font-title text-21 mr-2 cursor-pointer hover:underline\"\n data-cy=\"organization-name\"\n >\n {{ resourceContact.organization?.name }}\n </div>\n <div *ngIf=\"resourceContact.organization?.website\">\n <a\n [href]=\"resourceContact.organization.website\"\n target=\"_blank\"\n class=\"contact-website text-primary text-sm cursor-pointer hover:underline transition-all\"\n >{{ resourceContact.organization.website }}\n <mat-icon\n class=\"material-symbols-outlined !w-[12px] !h-[12px] !text-[12px] opacity-75 shrink-0\"\n >open_in_new</mat-icon\n >\n </a>\n </div>\n <div class=\"mt-4\" *ngIf=\"resourceContact.email\">\n <div class=\"flex\">\n <mat-icon\n class=\"material-symbols-outlined !w-5 !h-5 !text-[20px] opacity-75 shrink-0\"\n >\n mail_outline</mat-icon\n >\n <a\n *ngIf=\"resourceContact.email\"\n [href]=\"'mailto:' + resourceContact.email\"\n class=\"text-sm hover:underline ml-2\"\n target=\"_blank\"\n data-cy=\"contact-email\"\n >{{ resourceContact?.email }}</a\n >\n </div>\n </div>\n </div>\n </div>\n <div\n class=\"py-6 px-6 rounded bg-gray-100 grid grid-cols-2 gap-y-6 gap-x-[20px] text-gray-700\"\n >\n <div *ngIf=\"metadata.recordCreated\">\n <p class=\"text-sm\" translate>record.metadata.creation</p>\n <p class=\"text-primary font-medium mt-1\">\n {{ metadata.recordCreated.toLocaleDateString() }}\n </p>\n </div>\n <div *ngIf=\"metadata.recordPublished\">\n <p class=\"text-sm\" translate>record.metadata.publication</p>\n <p class=\"text-primary font-medium mt-1\">\n {{ metadata.recordPublished.toLocaleDateString() }}\n </p>\n </div>\n <div *ngIf=\"updateFrequency\">\n <p class=\"text-sm\" translate>record.metadata.updateFrequency</p>\n <p\n class=\"text-primary font-medium mt-1 updateFrequency\"\n translate\n [translateParams]=\"{ count: updatedTimes }\"\n >\n {{ updateFrequency }}\n </p>\n </div>\n <div *ngIf=\"metadata.languages\">\n <p class=\"text-sm mb-1\" translate>record.metadata.languages</p>\n <div class=\"flex flex-row gap-1 flex-wrap\">\n <p\n class=\"text-primary font-medium\"\n translate\n *ngFor=\"let language of metadata.languages\"\n >\n language.{{ language }}\n </p>\n </div>\n </div>\n <div *ngIf=\"temporalExtent\">\n <p class=\"text-sm\" translate>record.metadata.temporalExtent</p>\n <div class=\"flex flex-row gap-1 mb-1 text-primary font-medium\">\n <p\n *ngIf=\"temporalExtent.start && temporalExtent.end\"\n translate\n [translateParams]=\"{\n start: temporalExtent.start,\n end: temporalExtent.end\n }\"\n >\n record.metadata.temporalExtent.fromDateToDate\n </p>\n <p\n *ngIf=\"temporalExtent.start && !temporalExtent.end\"\n translate\n [translateParams]=\"{ start: temporalExtent.start }\"\n >\n record.metadata.temporalExtent.sinceDate\n </p>\n <p\n *ngIf=\"!temporalExtent.start && temporalExtent.end\"\n translate\n [translateParams]=\"{ end: temporalExtent.end }\"\n >\n record.metadata.temporalExtent.untilDate\n </p>\n </div>\n </div>\n </div>\n</gn-ui-expandable-panel>\n<gn-ui-expandable-panel\n *ngIf=\"metadata.landingPage\"\n [title]=\"'record.metadata.technical' | translate\"\n>\n <div class=\"flex flex-col gap-4 mr-4 py-5 rounded text-gray-700\">\n <div *ngIf=\"metadata.recordUpdated\">\n <p class=\"text-sm\" translate>record.metadata.updatedOn</p>\n <p class=\"text-primary font-medium\">\n {{ metadata.recordUpdated && metadata.recordUpdated.toLocaleString() }}\n </p>\n </div>\n <div *ngIf=\"metadata.landingPage\">\n <p class=\"text-sm\" translate>record.metadata.sheet</p>\n <p class=\"text-primary font-medium\" translate>\n <a [href]=\"metadata.landingPage\" target=\"_blank\">\n <span class=\"break-all\" gnUiLinkify>{{ metadata.landingPage }}</span>\n </a>\n </p>\n </div>\n <div *ngIf=\"metadata.ownerOrganization\">\n <p class=\"text-sm\" translate>record.metadata.owner</p>\n <p class=\"text-primary font-medium\">\n {{ metadata.ownerOrganization.name }}\n </p>\n </div>\n <div *ngIf=\"metadata.uniqueIdentifier\">\n <p class=\"text-sm\" translate>record.metadata.uniqueId</p>\n <div class=\"flex flex-row content-align items-end gap-1\">\n <gn-ui-copy-text-button\n [text]=\"metadata.uniqueIdentifier\"\n [tooltipText]=\"'tooltip.id.copy' | translate\"\n [displayText]=\"false\"\n ></gn-ui-copy-text-button>\n <p class=\"text-primary font-medium\">\n {{ metadata.uniqueIdentifier }}\n </p>\n </div>\n </div>\n <div *ngIf=\"metadata.topics?.length\">\n <p class=\"text-sm mb-1\" translate>record.metadata.topics</p>\n <div class=\"sm:pb-4 sm:pr-16\">\n <gn-ui-badge\n class=\"inline-block mr-2 mb-2 lowercase\"\n *ngFor=\"let topic of metadata.topics\"\n >{{ topic }}</gn-ui-badge\n >\n </div>\n </div>\n </div>\n</gn-ui-expandable-panel>\n", styles: [".md-description ::ng-deep a{@apply underline text-blue-600 hover:text-blue-800;}.info-grid>:nth-last-child(n+3){padding-bottom:10px;@apply border-b border-gray-300;}:host ::ng-deep gn-ui-copy-text-button button mat-icon{transform:scale(.8)}\n"], dependencies: [{ kind: "directive", type: i1$3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: BadgeComponent, selector: "gn-ui-badge", inputs: ["clickable"] }, { kind: "component", type: ExpandablePanelComponent, selector: "gn-ui-expandable-panel", inputs: ["title", "collapsed"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: CopyTextButtonComponent, selector: "gn-ui-copy-text-button", inputs: ["text", "tooltipText", "displayText", "rows"] }, { kind: "component", type: MarkdownParserComponent, selector: "gn-ui-markdown-parser", inputs: ["textContent"] }, { kind: "component", type: ThumbnailComponent, selector: "gn-ui-thumbnail", inputs: ["thumbnailUrl", "fit"], outputs: ["placeholderShown"] }, { kind: "component", type: ContentGhostComponent, selector: "gn-ui-content-ghost", inputs: ["showContent", "ghostClass"] }, { kind: "directive", type: GnUiLinkifyDirective, selector: "[gnUiLinkify]" }, { kind: "component", type: MaxLinesComponent, selector: "gn-ui-max-lines", inputs: ["maxLines"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
26184
26563
  }
26185
26564
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MetadataInfoComponent, decorators: [{
26186
26565
  type: Component,
@@ -26902,7 +27281,7 @@ class ImageOverlayPreviewComponent {
26902
27281
  basicLightbox.create(`<img src="${src}"/>`).show();
26903
27282
  }
26904
27283
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ImageOverlayPreviewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26905
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: ImageOverlayPreviewComponent, selector: "gn-ui-image-overlay-preview", inputs: { imageUrl: "imageUrl" }, outputs: { isPlaceholderShown: "isPlaceholderShown" }, ngImport: i0, template: "<gn-ui-content-ghost\n [showContent]=\"imageUrl !== undefined\"\n ghostClass=\"h-48 mb-3\"\n>\n <div\n *ngIf=\"imageUrl\"\n [showContent]=\"imageUrl !== undefined\"\n data-cy=\"record-thumbnail\"\n class=\"flex-shrink-0 bg-gray-100 rounded-lg overflow-hidden w-full border border-gray-300 group-hover:shadow-xl group-hover:border-0 h-48 mb-3\"\n >\n <gn-ui-thumbnail\n class=\"relative h-full w-full\"\n [thumbnailUrl]=\"imageUrl\"\n fit=\"cover\"\n (placeholderShown)=\"isPlaceholderShown.emit($event)\"\n ></gn-ui-thumbnail>\n <div class=\"relative\">\n <gn-ui-button\n class=\"absolute bottom-0 right-0 z-10 mr-2 mb-2\"\n [type]=\"'outline'\"\n [extraClass]=\"'!py-2 !px-0'\"\n (buttonClick)=\"openLightbox(imageUrl)\"\n >\n <mat-icon class=\"material-symbols-outlined font-extralight\"\n >zoom_out_map</mat-icon\n >\n </gn-ui-button>\n </div>\n </div>\n</gn-ui-content-ghost>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }, { kind: "component", type: ContentGhostComponent, selector: "gn-ui-content-ghost", inputs: ["showContent", "ghostClass"] }, { kind: "component", type: ThumbnailComponent, selector: "gn-ui-thumbnail", inputs: ["thumbnailUrl", "fit"], outputs: ["placeholderShown"] }] }); }
27284
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: ImageOverlayPreviewComponent, selector: "gn-ui-image-overlay-preview", inputs: { imageUrl: "imageUrl" }, outputs: { isPlaceholderShown: "isPlaceholderShown" }, ngImport: i0, template: "<gn-ui-content-ghost\n [showContent]=\"imageUrl !== undefined\"\n ghostClass=\"h-48 mb-3\"\n>\n <div\n *ngIf=\"imageUrl\"\n [showContent]=\"imageUrl !== undefined\"\n data-cy=\"record-thumbnail\"\n class=\"flex-shrink-0 bg-gray-100 rounded-lg overflow-hidden w-full border border-gray-300 group-hover:shadow-xl group-hover:border-0 h-48 mb-3\"\n >\n <gn-ui-thumbnail\n class=\"relative h-full w-full\"\n [thumbnailUrl]=\"imageUrl\"\n fit=\"cover\"\n (placeholderShown)=\"isPlaceholderShown.emit($event)\"\n ></gn-ui-thumbnail>\n <div class=\"relative\">\n <gn-ui-button\n class=\"absolute bottom-0 right-0 z-10 mr-2 mb-2\"\n [type]=\"'outline'\"\n [extraClass]=\"'!py-2 !px-0'\"\n (buttonClick)=\"openLightbox(imageUrl)\"\n >\n <mat-icon class=\"material-symbols-outlined font-extralight\"\n >zoom_out_map</mat-icon\n >\n </gn-ui-button>\n </div>\n </div>\n</gn-ui-content-ghost>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }, { kind: "component", type: ThumbnailComponent, selector: "gn-ui-thumbnail", inputs: ["thumbnailUrl", "fit"], outputs: ["placeholderShown"] }, { kind: "component", type: ContentGhostComponent, selector: "gn-ui-content-ghost", inputs: ["showContent", "ghostClass"] }] }); }
26906
27285
  }
26907
27286
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ImageOverlayPreviewComponent, decorators: [{
26908
27287
  type: Component,
@@ -26928,7 +27307,6 @@ class UiElementsModule {
26928
27307
  MetadataQualityItemComponent,
26929
27308
  SearchResultsErrorComponent,
26930
27309
  PaginationComponent,
26931
- ThumbnailComponent,
26932
27310
  AvatarComponent,
26933
27311
  UserPreviewComponent,
26934
27312
  GnUiLinkifyDirective,
@@ -26944,7 +27322,8 @@ class UiElementsModule {
26944
27322
  UiInputsModule,
26945
27323
  FormsModule,
26946
27324
  NgOptimizedImage,
26947
- MarkdownParserComponent], exports: [MetadataInfoComponent,
27325
+ MarkdownParserComponent,
27326
+ ThumbnailComponent], exports: [MetadataInfoComponent,
26948
27327
  ContentGhostComponent,
26949
27328
  DownloadItemComponent,
26950
27329
  DownloadsListComponent,
@@ -26974,7 +27353,8 @@ class UiElementsModule {
26974
27353
  UtilSharedModule,
26975
27354
  RouterModule,
26976
27355
  UiInputsModule,
26977
- FormsModule] }); }
27356
+ FormsModule,
27357
+ ThumbnailComponent] }); }
26978
27358
  }
26979
27359
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: UiElementsModule, decorators: [{
26980
27360
  type: NgModule,
@@ -26992,6 +27372,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
26992
27372
  FormsModule,
26993
27373
  NgOptimizedImage,
26994
27374
  MarkdownParserComponent,
27375
+ ThumbnailComponent,
26995
27376
  ],
26996
27377
  declarations: [
26997
27378
  MetadataInfoComponent,
@@ -27007,7 +27388,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
27007
27388
  MetadataQualityItemComponent,
27008
27389
  SearchResultsErrorComponent,
27009
27390
  PaginationComponent,
27010
- ThumbnailComponent,
27011
27391
  AvatarComponent,
27012
27392
  UserPreviewComponent,
27013
27393
  GnUiLinkifyDirective,
@@ -33309,5 +33689,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
33309
33689
  * Generated bundle index. Do not edit.
33310
33690
  */
33311
33691
 
33312
- export { ADD_RESULTS, ADD_SEARCH, AbstractAction, AddLayerFromCatalogComponent, AddLayerRecordPreviewComponent, AddResults, AddSearch, AnchorLinkDirective, ApiCardComponent, AuthService, AutocompleteComponent, AvatarComponent, AvatarServiceInterface, BLOCK_MODEL_FIXTURE, BadgeComponent, BaseReader, ButtonComponent, CLEAR_ERROR, CLEAR_RESULTS, CONFIG_MALFORMED, CONFIG_MINIMAL, CONFIG_MISSING_MANDATORY, CONFIG_OK, CONFIG_UNRECOGNIZED_KEYS, CONFIG_WITH_TRANSLATIONS, CONFIG_WRONG_LANGUAGE_CODE, CarouselComponent, CatalogTitleComponent, ChartComponent, ChartViewComponent, CheckToggleComponent, CheckboxComponent, ChipsInputComponent, ClearError, ClearResults, ColorScaleComponent, ContentGhostComponent, CopyTextButtonComponent, DEFAULT_BASELAYER_CONTEXT, DEFAULT_GN4_LOGIN_URL, DEFAULT_LANG, DEFAULT_PAGE_SIZE, DEFAULT_RESULTS_LAYOUT_CONFIG, DEFAULT_SEARCH_KEY, DEFAULT_STYLE_FIXTURE, DEFAULT_STYLE_HL_FIXTURE, DEFAULT_VIEW, DataService, DataViewComponent, DataViewPermalinkComponent, DataViewShareComponent, DataViewWebComponentComponent, DateRangePickerComponent, DefaultRouterModule, DownloadItemComponent, DownloadsListComponent, DragAndDropFileInputComponent, DropdownMultiselectComponent, DropdownSelectorComponent, EDITOR_FEATURE_KEY, EMPTY_BLOCK_MODEL_FIXTURE, ES_QUERY_FIELDS_PRIORITY, ES_RESOURCES_VALUES, ES_SOURCE_SUMMARY, EditableLabelDirective, EditorFacade, EditorService, ElasticsearchService, EmbeddedTranslateLoader, ErrorType, ExpandablePanelButtonComponent, ExpandablePanelComponent, ExternalViewerButtonComponent, FACET_ITEM_FIXTURE, FEATURE_MAP_OPTIONS, FIELDS_BRIEF, FIELDS_SUMMARY, FILTER_GEOMETRY, FORMATS, FacetBlockComponent, FacetBlockStubComponent, FacetItemComponent, FacetItemStubComponent, FacetListComponent, FacetsContainerComponent, FacetsModule, FavoriteStarComponent, FavoritesService, FeatureAuthModule, FeatureCatalogModule, FeatureDatavizModule, FeatureDetailComponent, FeatureEditorModule, FeatureInfoService, FeatureMapModule, FeatureRecordModule, FeatureSearchModule, FetchError, FieldsService, FigureComponent, FigureContainerComponent, FileTranslateLoader, FilterDropdownComponent, FormFieldArrayComponent, FormFieldComponent, FormFieldFileComponent, FormFieldObjectComponent, FormFieldRichComponent, FormFieldSimpleComponent, FormFieldSpatialExtentComponent, FormFieldTemporalExtentComponent, FuzzySearchComponent, GN_UI_VERSION, GeoTableViewComponent, GeocodingComponent, Gn4Converter, Gn4PlatformMapper, Gn4PlatformService, Gn4Repository, Gn4SettingsService, GravatarService, HttpLoaderFactory, I18nInterceptor, ImageFallbackDirective, ImageOverlayPreviewComponent, InteractiveTableColumnComponent, InteractiveTableComponent, Iso191153Converter, Iso19139Converter, LANGUAGES_LIST, LANGUAGE_NAMES, LANGUAGE_STORAGE_KEY, LANG_2_TO_3_MAPPER, LANG_3_TO_2_MAPPER, LOGIN_URL, LONLAT_CRS_CODES, LangService, LanguageSwitcherComponent, LayersPanelComponent, LinkCardComponent, LinkClassifierService, LinkUsage, LoadingMaskComponent, LogService, MAP_CONFIG_FIXTURE, MAP_FEATURE_KEY, METADATA_LANGUAGE, MY_FORMATS, MapComponent, MapContainerComponent, MapContextComponent, MapContextLayerTypeEnum, MapContextService, MapFacade, MapInstanceDirective, MapManagerService, MapStyleService, MapUtilsService, MapViewComponent, MarkdownParserComponent, MaxLinesComponent, mdview_actions as MdViewActions, MdViewFacade, MetadataCatalogComponent, MetadataContactComponent, MetadataInfoComponent, MetadataLinkType, MetadataQualityComponent, MetadataQualityItemComponent, MyOrgService, NavigationButtonComponent, ORGANIZATIONS_STRATEGY, ORGANIZATION_URL_TOKEN, OrganisationPreviewComponent, OrganisationsComponent, OrganisationsFilterComponent, OrganisationsResultComponent, OrganizationsFromGroupsService, OrganizationsFromMetadataService, PAGINATE, PARSE_DELIMITER, PATCH_RESULTS_AGGREGATIONS, PROXY_PATH, Paginate, PaginationButtonsComponent, PaginationComponent, PatchResultsAggregations, PopupAlertComponent, ProgressBarComponent, ProxyService, QUERY_FIELDS, RECORD_URL_TOKEN, REQUEST_MORE_ON_AGGREGATION, REQUEST_MORE_RESULTS, REQUEST_NEW_RESULTS, RESULTS_LAYOUT_CONFIG, ROUTER_CONFIG, ROUTER_ROUTE_DATASET, ROUTER_ROUTE_SEARCH, ROUTER_STATE_KEY, ROUTE_PARAMS, RecordApiFormComponent, RecordFormComponent, RecordMetricComponent, RecordPreviewCardComponent, RecordPreviewComponent, RecordPreviewFeedComponent, RecordPreviewListComponent, RecordPreviewRowComponent, RecordPreviewTextComponent, RecordPreviewTitleComponent, RecordsMetricsComponent, RecordsService, RelatedRecordCardComponent, RequestMoreOnAggregation, RequestMoreResults, RequestNewResults, ResultsHitsContainerComponent, ResultsHitsNumberComponent, ResultsLayoutComponent, ResultsLayoutConfigItem, ResultsListComponent, ResultsListContainerComponent, ResultsListItemComponent, ResultsTableComponent, RouterEffects, RouterFacade, RouterService, SEARCH_FEATURE_KEY, SET_CONFIG_AGGREGATIONS, SET_CONFIG_FILTERS, SET_CONFIG_REQUEST_FIELDS, SET_ERROR, SET_FAVORITES_ONLY, SET_FILTERS, SET_INCLUDE_ON_AGGREGATION, SET_PAGE_SIZE, SET_RESULTS_AGGREGATIONS, SET_RESULTS_HITS, SET_RESULTS_LAYOUT, SET_SEARCH, SET_SORT_BY, SET_SPATIAL_FILTER_ENABLED, SearchEffects, SearchFacade, SearchInputComponent, SearchResultsErrorComponent, SearchRouterContainerDirective, SearchService, SearchStateContainerDirective, SelectionService, SetConfigAggregations, SetConfigFilters, SetConfigRequestFields, SetError, SetFavoritesOnly, SetFilters, SetIncludeOnAggregation, SetPageSize, SetResultsAggregations, SetResultsHits, SetResultsLayout, SetSearch, SetSortBy, SetSpatialFilterEnabled, SiteTitleComponent, SortByComponent, SourceLabelComponent, SourcesService, SpinningLoaderComponent, StarToggleComponent, StepBarComponent, StickyHeaderComponent, SupportedTypes, TABLE_ITEM_FIXTURE, TABLE_ITEM_FIXTURE_HAB, THUMBNAIL_PLACEHOLDER, TRANSLATE_DEFAULT_CONFIG, TRANSLATE_WITH_OVERRIDES_CONFIG, TableComponent, TableViewComponent, TextAreaComponent, TextInputComponent, ThemeService, ThumbnailComponent, UPDATE_CONFIG_AGGREGATIONS, UPDATE_FILTERS, UPDATE_REQUEST_AGGREGATION_TERM, UiCatalogModule, UiDatavizModule, UiElementsModule, FacetsModule$1 as UiFacetsModule, UiInputsModule, UiLayoutModule, UiMapModule, UiSearchModule, UiWidgetsModule, UpdateConfigAggregations, UpdateFilters, UserPreviewComponent, UtilI18nModule, UtilSharedModule, ViewportIntersectorComponent, WEB_COMPONENT_EMBEDDER_URL, WFS_MAX_FEATURES, WizardComponent, WizardFieldComponent, WizardFieldType, WizardService, WizardSummarizeComponent, _reset, addLayer, changeLayerOrder, checkFileFormat, clearLayerError, createFuzzyFilter, currentPage, defaultMapOptions, dragPanCondition, dropEmptyTranslations, editorReducer, findConverterForDocument, getArrayItem, getAsArray, getAsUrl, getBadgeColor, getCustomTranslations, getError, getFavoritesOnly, getFileFormat, getFileFormatFromServiceOutput, getFirstValue, getFormatPriority, getGeometryFromGeoJSON, getGlobalConfig, getJsonDataItemsProxy, getLangFromBrowser, getLinkLabel, getLinkPriority, getMapLayers, getMapState, getMetadataQualityConfig, getMimeTypeForFormat, getOptionalMapConfig, getOptionalSearchConfig, getPageSize, getSearchConfigAggregations, getSearchFilters, getSearchResults, getSearchResultsAggregations, getSearchResultsHits, getSearchResultsLayout, getSearchResultsLoading, getSearchSortBy, getSearchState, getSearchStateSearch, getSpatialFilterEnabled, getTemporalRangeUnion, getThemeConfig, initSearch, initialEditorState, initialMapState, initialState, isConfigLoaded, isEndOfResults, isFormatInQueryParam, loadAppConfig, mapContact, mapKeywords, mapLogo, mapOrganization, mapReducer, markRecordAsChanged, mimeTypeToFormat, mouseWheelZoomCondition, openDataset, openRecord, parse, placeholder, propagateToDocumentOnly, provideGn4, provideRepositoryUrl, readDataset, readDatasetHeaders, reducer$2 as reducer, reducerSearch, removeLayer, removeSearchParams, removeWhitespace, saveRecord, saveRecordFailure, saveRecordSuccess, selectEditorState, selectFallback, selectFallbackFields, selectField, selectRecord, selectRecordChangedSinceSave, selectRecordFields, selectRecordFieldsConfig, selectRecordSaveError, selectRecordSaving, selectTranslatedField, selectTranslatedValue, setLayerError, sortByFromString, sortByToString, sortByToStrings, stripHtml, toDate, totalPages, updateLayer, updateRecordField };
33692
+ export { ADD_RESULTS, ADD_SEARCH, AbstractAction, AddLayerFromCatalogComponent, AddLayerRecordPreviewComponent, AddResults, AddSearch, AnchorLinkDirective, ApiCardComponent, AuthService, AutocompleteComponent, AvatarComponent, AvatarServiceInterface, BLOCK_MODEL_FIXTURE, BadgeComponent, BaseReader, ButtonComponent, CLEAR_ERROR, CLEAR_RESULTS, CONFIG_MALFORMED, CONFIG_MINIMAL, CONFIG_MISSING_MANDATORY, CONFIG_OK, CONFIG_UNRECOGNIZED_KEYS, CONFIG_WITH_TRANSLATIONS, CONFIG_WRONG_LANGUAGE_CODE, CarouselComponent, CatalogTitleComponent, ChartComponent, ChartViewComponent, CheckToggleComponent, CheckboxComponent, ChipsInputComponent, ClearError, ClearResults, ColorScaleComponent, ContentGhostComponent, CopyTextButtonComponent, DEFAULT_BASELAYER_CONTEXT, DEFAULT_GN4_LOGIN_URL, DEFAULT_LANG, DEFAULT_PAGE_SIZE, DEFAULT_RESULTS_LAYOUT_CONFIG, DEFAULT_SEARCH_KEY, DEFAULT_STYLE_FIXTURE, DEFAULT_STYLE_HL_FIXTURE, DEFAULT_VIEW, DataService, DataViewComponent, DataViewPermalinkComponent, DataViewShareComponent, DataViewWebComponentComponent, DateRangePickerComponent, DefaultRouterModule, DownloadItemComponent, DownloadsListComponent, DragAndDropFileInputComponent, DropdownMultiselectComponent, DropdownSelectorComponent, EDITOR_FEATURE_KEY, EMPTY_BLOCK_MODEL_FIXTURE, ES_QUERY_FIELDS_PRIORITY, ES_RESOURCES_VALUES, ES_SOURCE_SUMMARY, EditableLabelDirective, EditorFacade, EditorService, ElasticsearchService, EmbeddedTranslateLoader, ErrorType, ExpandablePanelButtonComponent, ExpandablePanelComponent, ExternalViewerButtonComponent, FACET_ITEM_FIXTURE, FEATURE_MAP_OPTIONS, FIELDS_BRIEF, FIELDS_SUMMARY, FILTER_GEOMETRY, FORMATS, FacetBlockComponent, FacetBlockStubComponent, FacetItemComponent, FacetItemStubComponent, FacetListComponent, FacetsContainerComponent, FacetsModule, FavoriteStarComponent, FavoritesService, FeatureAuthModule, FeatureCatalogModule, FeatureDatavizModule, FeatureDetailComponent, FeatureEditorModule, FeatureInfoService, FeatureMapModule, FeatureRecordModule, FeatureSearchModule, FetchError, FieldsService, FigureComponent, FigureContainerComponent, FileTranslateLoader, FilterDropdownComponent, FormFieldArrayComponent, FormFieldComponent, FormFieldFileComponent, FormFieldObjectComponent, FormFieldRichComponent, FormFieldSimpleComponent, FormFieldSpatialExtentComponent, FormFieldTemporalExtentComponent, FuzzySearchComponent, GN_UI_VERSION, GeoTableViewComponent, GeocodingComponent, Gn4Converter, Gn4PlatformMapper, Gn4PlatformService, Gn4Repository, Gn4SettingsService, GravatarService, HttpLoaderFactory, I18nInterceptor, ImageFallbackDirective, ImageOverlayPreviewComponent, InteractiveTableColumnComponent, InteractiveTableComponent, Iso191153Converter, Iso19139Converter, LANGUAGES_LIST, LANGUAGE_NAMES, LANGUAGE_STORAGE_KEY, LANG_2_TO_3_MAPPER, LANG_3_TO_2_MAPPER, LOGIN_URL, LONLAT_CRS_CODES, LangService, LanguageSwitcherComponent, LayersPanelComponent, LinkCardComponent, LinkClassifierService, LinkUsage, LoadingMaskComponent, LogService, MAP_CONFIG_FIXTURE, MAP_FEATURE_KEY, METADATA_LANGUAGE, MY_FORMATS, MapComponent, MapContainerComponent, MapContextComponent, MapContextLayerTypeEnum, MapContextService, MapFacade, MapInstanceDirective, MapManagerService, MapStyleService, MapUtilsService, MapViewComponent, MarkdownParserComponent, MaxLinesComponent, mdview_actions as MdViewActions, MdViewFacade, MetadataCatalogComponent, MetadataContactComponent, MetadataInfoComponent, MetadataLinkType, MetadataQualityComponent, MetadataQualityItemComponent, MyOrgService, NavigationButtonComponent, ORGANIZATIONS_STRATEGY, ORGANIZATION_URL_TOKEN, OrganisationPreviewComponent, OrganisationsComponent, OrganisationsFilterComponent, OrganisationsResultComponent, OrganizationsFromGroupsService, OrganizationsFromMetadataService, PAGINATE, PARSE_DELIMITER, PATCH_RESULTS_AGGREGATIONS, PROXY_PATH, Paginate, PaginationButtonsComponent, PaginationComponent, PatchResultsAggregations, PopupAlertComponent, ProgressBarComponent, ProxyService, QUERY_FIELDS, RECORD_URL_TOKEN, REQUEST_MORE_ON_AGGREGATION, REQUEST_MORE_RESULTS, REQUEST_NEW_RESULTS, RESULTS_LAYOUT_CONFIG, ROUTER_CONFIG, ROUTER_ROUTE_DATASET, ROUTER_ROUTE_SEARCH, ROUTER_STATE_KEY, ROUTE_PARAMS, RecordApiFormComponent, RecordFormComponent, RecordMetricComponent, RecordPreviewCardComponent, RecordPreviewComponent, RecordPreviewFeedComponent, RecordPreviewListComponent, RecordPreviewRowComponent, RecordPreviewTextComponent, RecordPreviewTitleComponent, RecordsMetricsComponent, RecordsService, RelatedRecordCardComponent, RequestMoreOnAggregation, RequestMoreResults, RequestNewResults, ResultsHitsContainerComponent, ResultsHitsNumberComponent, ResultsLayoutComponent, ResultsLayoutConfigItem, ResultsListComponent, ResultsListContainerComponent, ResultsListItemComponent, ResultsTableComponent, RouterEffects, RouterFacade, RouterService, SEARCH_FEATURE_KEY, SET_CONFIG_AGGREGATIONS, SET_CONFIG_FILTERS, SET_CONFIG_REQUEST_FIELDS, SET_ERROR, SET_FAVORITES_ONLY, SET_FILTERS, SET_INCLUDE_ON_AGGREGATION, SET_PAGE_SIZE, SET_RESULTS_AGGREGATIONS, SET_RESULTS_HITS, SET_RESULTS_LAYOUT, SET_SEARCH, SET_SORT_BY, SET_SPATIAL_FILTER_ENABLED, SearchEffects, SearchFacade, SearchInputComponent, SearchResultsErrorComponent, SearchRouterContainerDirective, SearchService, SearchStateContainerDirective, SelectionService, SetConfigAggregations, SetConfigFilters, SetConfigRequestFields, SetError, SetFavoritesOnly, SetFilters, SetIncludeOnAggregation, SetPageSize, SetResultsAggregations, SetResultsHits, SetResultsLayout, SetSearch, SetSortBy, SetSpatialFilterEnabled, SiteTitleComponent, SortByComponent, SourceLabelComponent, SourcesService, SpinningLoaderComponent, StarToggleComponent, StepBarComponent, StickyHeaderComponent, SupportedTypes, TABLE_ITEM_FIXTURE, TABLE_ITEM_FIXTURE_HAB, THUMBNAIL_PLACEHOLDER, TRANSLATE_DEFAULT_CONFIG, TRANSLATE_WITH_OVERRIDES_CONFIG, TableComponent, TableViewComponent, TextAreaComponent, TextInputComponent, ThemeService, ThumbnailComponent, UPDATE_CONFIG_AGGREGATIONS, UPDATE_FILTERS, UPDATE_REQUEST_AGGREGATION_TERM, UiCatalogModule, UiDatavizModule, UiElementsModule, FacetsModule$1 as UiFacetsModule, UiInputsModule, UiLayoutModule, UiMapModule, UiSearchModule, UiWidgetsModule, UpdateConfigAggregations, UpdateFilters, UserPreviewComponent, UtilI18nModule, UtilSharedModule, ViewportIntersectorComponent, WEB_COMPONENT_EMBEDDER_URL, WFS_MAX_FEATURES, WizardComponent, WizardFieldComponent, WizardFieldType, WizardService, WizardSummarizeComponent, _reset, addLayer, changeLayerOrder, checkFileFormat, clearLayerError, createFuzzyFilter, currentPage, defaultMapOptions, downgradeImage, downsizeImage, dragPanCondition, dropEmptyTranslations, editorReducer, findConverterForDocument, getArrayItem, getAsArray, getAsUrl, getBadgeColor, getCustomTranslations, getError, getFavoritesOnly, getFileFormat, getFileFormatFromServiceOutput, getFirstValue, getFormatPriority, getGeometryFromGeoJSON, getGlobalConfig, getJsonDataItemsProxy, getLangFromBrowser, getLinkLabel, getLinkPriority, getMapLayers, getMapState, getMetadataQualityConfig, getMimeTypeForFormat, getOptionalMapConfig, getOptionalSearchConfig, getPageSize, getSearchConfigAggregations, getSearchFilters, getSearchResults, getSearchResultsAggregations, getSearchResultsHits, getSearchResultsLayout, getSearchResultsLoading, getSearchSortBy, getSearchState, getSearchStateSearch, getSpatialFilterEnabled, getTemporalRangeUnion, getThemeConfig, initSearch, initialEditorState, initialMapState, initialState, isConfigLoaded, isEndOfResults, isFormatInQueryParam, loadAppConfig, mapContact, mapKeywords, mapLogo, mapOrganization, mapReducer, markRecordAsChanged, megabytesToBytes, mimeTypeToFormat, mouseWheelZoomCondition, openDataset, openRecord, parse, placeholder, propagateToDocumentOnly, provideGn4, provideRepositoryUrl, readDataset, readDatasetHeaders, reducer$2 as reducer, reducerSearch, removeLayer, removeSearchParams, removeWhitespace, saveRecord, saveRecordFailure, saveRecordSuccess, selectEditorState, selectFallback, selectFallbackFields, selectField, selectRecord, selectRecordChangedSinceSave, selectRecordFields, selectRecordFieldsConfig, selectRecordSaveError, selectRecordSaving, selectTranslatedField, selectTranslatedValue, setLayerError, sortByFromString, sortByToString, sortByToStrings, stripHtml, toDate, totalPages, updateLayer, updateRecordField };
33313
33693
  //# sourceMappingURL=geonetwork-ui.mjs.map