@hestia-earth/ui-components 0.0.4 → 0.0.5

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 (33) hide show
  1. package/bundles/hestia-earth-ui-components.umd.js +392 -506
  2. package/bundles/hestia-earth-ui-components.umd.js.map +1 -1
  3. package/common/common.service.d.ts +1 -2
  4. package/common/public-api.d.ts +1 -0
  5. package/common/toast/toast.component.d.ts +2 -2
  6. package/common/toast.service.d.ts +3 -3
  7. package/common/utils.d.ts +3 -11
  8. package/cycles/public-api.d.ts +1 -0
  9. package/engine/aggregation-engine.service.d.ts +8 -20
  10. package/engine/engine.service.d.ts +2 -6
  11. package/esm2015/common/common.service.js +1 -7
  12. package/esm2015/common/public-api.js +2 -1
  13. package/esm2015/common/toast/toast.component.js +3 -3
  14. package/esm2015/common/toast.service.js +5 -5
  15. package/esm2015/common/utils.js +3 -61
  16. package/esm2015/cycles/public-api.js +2 -1
  17. package/esm2015/engine/aggregation-engine.service.js +11 -47
  18. package/esm2015/engine/engine.service.js +9 -15
  19. package/esm2015/impact-assessments/impact-assessments-products/impact-assessments-products.component.js +3 -3
  20. package/esm2015/mendeley/mendeley.service.js +1 -1
  21. package/esm2015/node/node-csv.service.js +1 -1
  22. package/esm2015/node/node.service.js +26 -16
  23. package/esm2015/schema/schema.service.js +1 -1
  24. package/esm2015/search/search.service.js +1 -1
  25. package/fesm2015/hestia-earth-ui-components.js +281 -372
  26. package/fesm2015/hestia-earth-ui-components.js.map +1 -1
  27. package/impact-assessments/impact-assessments-products/impact-assessments-products.component.d.ts +2 -2
  28. package/mendeley/mendeley.service.d.ts +2 -2
  29. package/node/node-csv.service.d.ts +1 -1
  30. package/node/node.service.d.ts +16 -7
  31. package/package.json +1 -1
  32. package/schema/schema.service.d.ts +1 -1
  33. package/search/search.service.d.ts +2 -2
@@ -16,7 +16,7 @@ import { faClone, faCircle, faIdBadge } from '@fortawesome/free-regular-svg-icon
16
16
  import { faAngleDoubleLeft, faAngleDoubleRight, faAngleDown, faAngleLeft, faAngleRight, faBookOpen, faBuilding, faCalculator, faChartBar, faCheck, faClipboard, faClipboardList, faClone as faClone$1, faComments, faDownload, faDrawPolygon, faEdit, faExclamationTriangle, faExternalLinkAlt, faFilter, faList, faLongArrowAltDown, faLongArrowAltUp, faLongArrowAltLeft, faLongArrowAltRight, faMap, faMapMarked, faMapMarkedAlt, faPlus, faPlusCircle, faSearch, faSeedling, faSpellCheck, faSpinner, faTimes, faUser } from '@fortawesome/free-solid-svg-icons';
17
17
  import { isEmpty, unique, isUndefined, isNumber, toPrecision, isBoolean, ConvertUnits, converters, convertValue, isEqual, diffInDays } from '@hestia-earth/utils';
18
18
  import { getColor } from 'random-material-color';
19
- import { EmissionMethodTier, NodeType, TermTermType, nestedSearchableKeys, isExpandable, SchemaType, SCHEMA_VERSION, sortKeysByType, CycleFunctionalUnit, SiteSiteType, isTypeValid, isTypeNode, typeToSchemaType } from '@hestia-earth/schema';
19
+ import { EmissionMethodTier, NodeType, isExpandable, TermTermType, nestedSearchableKeys, SchemaType, SCHEMA_VERSION, sortKeysByType, CycleFunctionalUnit, SiteSiteType, isTypeValid, isTypeNode, typeToSchemaType } from '@hestia-earth/schema';
20
20
  import { fileToExt, nodeTypeToParam, DataState, SupportedExtensions } from '@hestia-earth/api';
21
21
  import { of, ReplaySubject, forkJoin, from, zip } from 'rxjs';
22
22
  import { catchError, map, take, mergeMap, debounceTime, distinctUntilChanged, tap, switchMap, reduce, filter, distinct, toArray, mergeAll, groupBy } from 'rxjs/operators';
@@ -85,9 +85,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
85
85
  }]
86
86
  }], ctorParameters: function () { return [{ type: i1.FaIconLibrary }]; } });
87
87
 
88
- const get$5 = require('lodash.get');
88
+ const get$4 = require('lodash.get');
89
89
  const gitHome = 'https://gitlab.com/hestia-earth';
90
90
  const gitRawBaseUrl = 'https://glcdn.githack.com/hestia-earth';
91
+ const gitBranch = () => ['dev', 'staging'].some(env => baseUrl().includes(env)) ? 'develop' : 'master';
91
92
  const isChrome = () => window.navigator.userAgent.includes('Chrome');
92
93
  const baseUrl = () => window.location.origin.includes('localhost') ?
93
94
  'https://www-dev.hestia.earth' :
@@ -96,18 +97,8 @@ const baseUrl = () => window.location.origin.includes('localhost') ?
96
97
  'https://www.hestia.earth';
97
98
  const isExternal = () => baseUrl() !== window.location.origin;
98
99
  ;
99
- const loadScript = (src) => new Promise((resolve, reject) => {
100
- if (!src || document.body.querySelectorAll('script[src="' + src + '"]').length > 0) {
101
- return resolve({});
102
- }
103
- const script = document.createElement('script');
104
- script.onload = resolve;
105
- script.onerror = reject;
106
- script.src = src;
107
- document.body.appendChild(script);
108
- });
109
100
  const parseErrorStatus = (error) => ((error === null || error === void 0 ? void 0 : error.statusText) || '').toLowerCase().replace(/\s/g, '-');
110
- const parseErrorMessage = (error) => get$5(error, 'error.error', get$5(error, 'error.message', get$5(error, 'error', get$5(error, 'message', error))));
101
+ const parseErrorMessage = (error) => get$4(error, 'error.error', get$4(error, 'error.message', get$4(error, 'error', get$4(error, 'message', error))));
111
102
  const handleAPIError = (error) => {
112
103
  try {
113
104
  error = parseErrorMessage(error);
@@ -122,20 +113,6 @@ const errorText = (error) => {
122
113
  const err = parseErrorMessage(error);
123
114
  return parseErrorStatus(err) || err;
124
115
  };
125
- const toFormData = (data, formData = new FormData()) => {
126
- for (const key in data) {
127
- if (data.hasOwnProperty(key)) {
128
- const value = data[key];
129
- if (typeof value === 'object') {
130
- formData.append(key, JSON.stringify(value));
131
- }
132
- else {
133
- formData.append(key, value);
134
- }
135
- }
136
- }
137
- return formData;
138
- };
139
116
  const filterParams = (obj) => {
140
117
  const res = {};
141
118
  Object.keys(obj).sort().forEach(key => {
@@ -146,13 +123,6 @@ const filterParams = (obj) => {
146
123
  });
147
124
  return res;
148
125
  };
149
- const toSearchParams = (params = {}) => {
150
- const searchParams = new URLSearchParams();
151
- Object.keys(params)
152
- .filter(key => typeof params[key] !== 'undefined')
153
- .forEach(key => searchParams.append(key, `${params[key]}`));
154
- return searchParams;
155
- };
156
126
  const waitFor = (variable, callback) => {
157
127
  if (variable in window) {
158
128
  return callback();
@@ -166,23 +136,6 @@ const scrollToEl = (id, retries = 0) => {
166
136
  setTimeout(() => el ? el.scrollIntoView() : (retries < 10 ? scrollToEl(id, retries + 1) : null), 100);
167
137
  };
168
138
  const scrollTop = () => window.scrollTo(0, 0);
169
- const animateCounter = (total, callback) => {
170
- let animationDuration = 10;
171
- const step = Math.pow(10, `${total}`.length - 1);
172
- const maxSteps = parseInt(`${total / step}`, 10);
173
- let current = 0;
174
- const interval = setInterval(() => {
175
- callback(current);
176
- current += (step / animationDuration);
177
- if (current > maxSteps * step) {
178
- animationDuration = 100;
179
- }
180
- if (current > total) {
181
- callback(total);
182
- clearInterval(interval);
183
- }
184
- }, animationDuration);
185
- };
186
139
  const safeJSONParse = (value, defaultValue) => {
187
140
  try {
188
141
  return typeof value === 'string' ? JSON.parse(value) : value;
@@ -241,7 +194,7 @@ const groupNodesByTerm = (nodes = [], key, originalValues = [], filterMethod) =>
241
194
  group[termId].values[nodeId].nodes.push(blankNode);
242
195
  group[termId].values[nodeId].value = concatBlankNodeValue(group[termId].values[nodeId].value, blankNode.value);
243
196
  grouppedValueKeys.forEach(arrayKey => {
244
- const newValue = get$5(blankNode, arrayKey, []);
197
+ const newValue = get$4(blankNode, arrayKey, []);
245
198
  group[termId].values[nodeId][arrayKey] = [
246
199
  ...(group[termId].values[nodeId][arrayKey] || []),
247
200
  ...(Array.isArray(newValue) ? newValue : [newValue])
@@ -254,7 +207,7 @@ const groupNodesByTerm = (nodes = [], key, originalValues = [], filterMethod) =>
254
207
  Object.keys(group.values).map(nodeId => {
255
208
  const { index } = group.values[nodeId];
256
209
  const termId = group.term['@id'];
257
- const originalValue = get$5(originalValues, `[${index}].${key}`, []).filter((val) => val.term['@id'] === termId);
210
+ const originalValue = get$4(originalValues, `[${index}].${key}`, []).filter((val) => val.term['@id'] === termId);
258
211
  if (originalValue.length > 0) {
259
212
  const value = originalValue.reduce((array, curr) => concatBlankNodeValue(array, curr.value), []);
260
213
  group.originalValues[nodeId] = { value: propertyValue$1(value) };
@@ -263,7 +216,6 @@ const groupNodesByTerm = (nodes = [], key, originalValues = [], filterMethod) =>
263
216
  });
264
217
  return groups;
265
218
  };
266
- const sortByFn = (key, asc) => (a, b) => asc ? get$5(a, key, '').localeCompare(get$5(b, key, '')) : get$5(b, key, '').localeCompare(get$5(a, key, ''));
267
219
  const ellipsis = (text = '', maxlength = 20) => text.length > maxlength ? `${text.substring(0, maxlength)}...` : text;
268
220
  const mapsQuery = 'https://www.google.com/maps/search/?api=1&query=';
269
221
  const mapsUrl = (location) => location ? (location.lat && location.lng ?
@@ -283,8 +235,6 @@ const toDashCase = (value) => value ?
283
235
  // handle years
284
236
  .replace(/([0-9]{4})/g, g => `-${g}`) :
285
237
  null;
286
- const nodeTypeToString = (type) => `${type.charAt(0).toLowerCase()}${type.substring(1)}`;
287
- const parseNodeType = (type) => Object.values(NodeType).find(v => v.toString().toLowerCase() === (type || '').toLowerCase());
288
238
  const nodeDefaultLabel = {
289
239
  [NodeType.ImpactAssessment]: ({ name, country, endDate, product }) => name ? name.replace(`${product === null || product === void 0 ? void 0 : product.name}, `, '') : [
290
240
  product === null || product === void 0 ? void 0 : product.name,
@@ -296,15 +246,6 @@ const nodeDefaultLabel = {
296
246
  const defaultLabel = (node) => node ? (node['@type'] in nodeDefaultLabel ? nodeDefaultLabel[node['@type']](node) : node.name) || node['@id'] || node.id : '';
297
247
  const itemColor = (index) => getColor({ text: `${index}` });
298
248
  const listColor = (_v, index) => itemColor(index);
299
- const minutesBefore = (date, minutes = 1) => {
300
- date.setMinutes(date.getMinutes() - minutes);
301
- return date;
302
- };
303
- const hoursBefore = (date, hours = 1) => {
304
- date.setHours(date.getHours() - hours);
305
- return date;
306
- };
307
- const repeat = (times = 0) => (Array.from(Array(times), Math.random));
308
249
  var DeltaDisplayType;
309
250
  (function (DeltaDisplayType) {
310
251
  DeltaDisplayType["absolute"] = "absolute";
@@ -329,6 +270,7 @@ var DeltaColour;
329
270
  DeltaColour["Danger"] = "danger";
330
271
  })(DeltaColour || (DeltaColour = {}));
331
272
  const emptyValue = (value) => isEmpty(value) || isNaN(propertyValue$1(value));
273
+ const repeat = (times = 0) => (Array.from(Array(times), Math.random));
332
274
  const filenameWithoutExt = (filename = '') => {
333
275
  const file = fileToExt(filename, '');
334
276
  // remove last .
@@ -479,237 +421,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
479
421
  type: Input
480
422
  }] } });
481
423
 
482
- const searchableTypes = [
483
- NodeType.Cycle,
484
- NodeType.Source
485
- ];
486
- const serializeSearchFilters = (filters) => Object.keys(filters || {})
487
- .filter(key => filters[key].length)
488
- .map(key => `${key}=${filters[key].filter(Boolean).join('|')}`)
489
- .join(';');
490
- const deserializeSearchFilters = (filters) => (filters || '').split(';').reduce((prev, curr) => {
491
- const [key, values] = curr.split('=');
492
- prev[key] = (values || '').split('|').filter(Boolean);
493
- return prev;
494
- }, {});
495
- const matchType = (type) => Object.freeze({
496
- match: { '@type': type }
497
- });
498
- const matchTermType = (termType) => Object.freeze({
499
- match: { termType }
500
- });
501
- const matchRegex = (key, value) => Object.freeze({
502
- regexp: { [key]: { value: value.toString() } }
503
- });
504
- const matchQuery = (key, value, boost) => Object.freeze({
505
- match: {
506
- [key]: Object.assign({ query: value }, (boost ? { boost } : {}))
507
- }
508
- });
509
- const matchExactQuery = (key, value, boost) => matchQuery(`${key}.keyword`, value, boost);
510
- const matchNameNormalized = (query, boost = 20) => Object.freeze({
511
- match: { nameNormalized: { query, boost } }
512
- });
513
- const numberGte = (key, value) => Object.freeze({
514
- range: { [key]: { gte: value } }
515
- });
516
- const multiMatchQuery = (query, fields, type = 'best_fields', boost, analyzer) => Object.freeze({
517
- multi_match: Object.assign(Object.assign({ query,
518
- fields,
519
- type }, (boost ? { boost } : {})), (analyzer ? { analyzer } : {}))
520
- });
521
- const matchPhraseQuery = (query, boost, ...fields) => fields.length ? multiMatchQuery(query, fields, 'phrase', boost) : matchExactQuery('name', query, boost);
522
- const matchPhrasePrefixQuery = (query, boost = 2, ...fields) => fields.length ?
523
- multiMatchQuery(query, fields, 'phrase_prefix', boost) :
524
- Object.freeze({
525
- match_phrase_prefix: {
526
- nameSearchAsYouType: {
527
- query,
528
- boost
529
- }
530
- }
531
- });
532
- const matchBoolPrefixQuery = (query, boost = 1, ...fields) => fields.length ?
533
- multiMatchQuery(query, fields, 'bool_prefix', boost) :
534
- Object.freeze({
535
- match_bool_prefix: {
536
- name: {
537
- query,
538
- boost
539
- }
540
- }
541
- });
542
- const wildcardQuery = (query, boost = 3, ...fields) => Object.freeze({
543
- simple_query_string: {
544
- query: `*${query}*`,
545
- fields,
546
- analyze_wildcard: true,
547
- boost
548
- }
549
- });
550
- const matchCountryLevel = { match: { gadmLevel: 0 } };
551
- const matchGlobalRegion = { regexp: { '@id': 'region-*' } };
552
- const matchCountry = Object.freeze({
553
- bool: {
554
- should: [
555
- matchCountryLevel,
556
- matchGlobalRegion
557
- ],
558
- minimum_should_match: 1
559
- }
560
- });
561
- const countriesQuery = Object.freeze({
562
- bool: {
563
- must: [
564
- matchType(NodeType.Term),
565
- matchTermType(TermTermType.region),
566
- matchCountryLevel
567
- ]
568
- }
569
- });
570
- const allCountriesQuery = Object.freeze({
571
- bool: Object.assign({ must: [
572
- matchType(NodeType.Term),
573
- matchTermType(TermTermType.region)
574
- ] }, matchCountry.bool)
575
- });
576
- const matchRegion = numberGte('gadmLevel', 1);
577
- const regionsQuery = Object.freeze({
578
- bool: {
579
- must: [
580
- matchType(NodeType.Term),
581
- matchTermType(TermTermType.region),
582
- matchRegion
583
- ]
584
- }
585
- });
586
- const worldRegion = Object.freeze({
587
- '@id': 'region-world',
588
- name: 'World'
589
- });
590
- const cropsQuery = Object.freeze({
591
- bool: {
592
- must: [
593
- matchType(NodeType.Term),
594
- matchTermType(TermTermType.crop)
595
- ]
596
- }
597
- });
598
- const matchAggregatedQuery = matchQuery('aggregated', true);
599
- const isNestedKey = (key) => nestedSearchableKeys.includes(key.split('.')[0]);
600
- const matchNestedKey = (key, query) => isNestedKey(key) ? {
601
- nested: { path: key.split('.')[0], query }
602
- } : query;
603
- /**
604
- * List of fields to return in the search results.
605
- */
606
- const searchResultsFields = Object.freeze({
607
- [NodeType.Cycle]: [
608
- 'description', 'dataDescription', 'endDate',
609
- 'emissionsCount', 'inputsCount', 'productsCount',
610
- 'site.location', 'site.country.name', 'site.region.name'
611
- ],
612
- [NodeType.Source]: ['bibliography.title', 'bibliography.documentDOI'],
613
- [NodeType.ImpactAssessment]: ['emissionsResourceUseCount', 'impactsCount', 'country.name']
614
- });
615
- /**
616
- * List of fields to search in.
617
- */
618
- const searchFields = Object.freeze({
619
- [NodeType.Cycle]: ['name', 'description', 'dataDescription'],
620
- [NodeType.Source]: ['name', 'bibliography.title'],
621
- [NodeType.ImpactAssessment]: ['name', 'product.name', 'country.name']
622
- });
623
- const searchFieldsNested = Object.freeze({
624
- [NodeType.Cycle]: [
625
- 'inputs.term.name',
626
- 'emissions.term.name',
627
- 'practices.term.name'
628
- ],
629
- [NodeType.Source]: [],
630
- [NodeType.ImpactAssessment]: [
631
- 'emissionsResourceUse.term.name',
632
- 'impacts.term.name'
633
- ]
634
- });
635
- /**
636
- * Specific strict queries per type.
637
- */
638
- const searchQueries = {
639
- [NodeType.Cycle]: { must: [], must_not: [matchAggregatedQuery] },
640
- [NodeType.Source]: { must: [], must_not: [matchAggregatedQuery] }
641
- };
642
- const searchFiltersKeys = {
643
- [NodeType.Cycle]: key => key,
644
- [NodeType.Source]: key => key
645
- };
646
- /* eslint-disable complexity */
647
- const searchQuery = (type, query, filters, aggregated) => {
648
- const boolQuery = (Object.assign(Object.assign({ must: [
649
- matchType(type),
650
- aggregated ? matchAggregatedQuery : null
651
- ].filter(Boolean) }, (query ? {
652
- should: [
653
- matchPhraseQuery(query, 100, ...searchFields[type]),
654
- matchPhrasePrefixQuery(query, 20, ...searchFields[type]),
655
- matchBoolPrefixQuery(query, 10, ...searchFields[type]),
656
- ...searchFieldsNested[type].map(field => matchNestedKey(field, matchBoolPrefixQuery(query, 1, field)))
657
- ],
658
- minimum_should_match: 1
659
- } : {})), { must_not: [
660
- aggregated ? null : matchAggregatedQuery
661
- ].filter(Boolean) }));
662
- const keys = Object.keys(filters || {}).filter(key => filters[key].length);
663
- return {
664
- bool: keys.length ? {
665
- must: keys.map(key => {
666
- const filterKey = searchFiltersKeys[type](key);
667
- return {
668
- bool: {
669
- should: filters[key]
670
- .map(value => matchNestedKey(filterKey, matchExactQuery(filterKey, value)))
671
- .map(must => {
672
- const localQuery = JSON.parse(JSON.stringify(boolQuery));
673
- localQuery.must.push(must);
674
- return { bool: localQuery };
675
- }),
676
- minimum_should_match: 1
677
- }
678
- };
679
- })
680
- } : boolQuery
681
- };
682
- };
683
- /* eslint-enable complexity */
684
-
685
- const primaryProduct = ({ products }) => (products || []).find(({ primary }) => primary);
686
-
687
- const HE_API_BASE_URL = new InjectionToken('HE_API_BASE_URL');
688
- class HeCommonService {
689
- constructor(_apiBaseUrl) {
690
- this._apiBaseUrl = _apiBaseUrl;
691
- }
692
- get apiBaseUrl() {
693
- return this._apiBaseUrl || '/api';
694
- }
695
- get gitBranch() {
696
- return ['dev', 'staging'].some((env) => baseUrl().includes(env))
697
- ? 'develop'
698
- : 'master';
699
- }
700
- }
701
- HeCommonService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: HeCommonService, deps: [{ token: HE_API_BASE_URL }], target: i0.ɵɵFactoryTarget.Injectable });
702
- HeCommonService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: HeCommonService, providedIn: 'root' });
703
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: HeCommonService, decorators: [{
704
- type: Injectable,
705
- args: [{
706
- providedIn: 'root'
707
- }]
708
- }], ctorParameters: function () { return [{ type: undefined, decorators: [{
709
- type: Inject,
710
- args: [HE_API_BASE_URL]
711
- }] }]; } });
712
-
713
424
  const termProperties = (term) => Object.keys(term).filter(key => !isExpandable(term[key]) && ![
714
425
  'pinned', 'expanded', 'extended', 'selected', 'loading',
715
426
  '_score', '@type', '@id', '@context', 'createdAt',
@@ -892,6 +603,45 @@ const sortOrder = [
892
603
  TermTermType.standardsLabels
893
604
  ];
894
605
 
606
+ const HE_API_BASE_URL = new InjectionToken('HE_API_BASE_URL');
607
+ class HeCommonService {
608
+ constructor(_apiBaseUrl) {
609
+ this._apiBaseUrl = _apiBaseUrl;
610
+ }
611
+ get apiBaseUrl() {
612
+ return this._apiBaseUrl || '/api';
613
+ }
614
+ }
615
+ HeCommonService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: HeCommonService, deps: [{ token: HE_API_BASE_URL }], target: i0.ɵɵFactoryTarget.Injectable });
616
+ HeCommonService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: HeCommonService, providedIn: 'root' });
617
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: HeCommonService, decorators: [{
618
+ type: Injectable,
619
+ args: [{
620
+ providedIn: 'root'
621
+ }]
622
+ }], ctorParameters: function () { return [{ type: undefined, decorators: [{
623
+ type: Inject,
624
+ args: [HE_API_BASE_URL]
625
+ }] }]; } });
626
+
627
+ const nodeTypeUrl = (apiBaseUrl, type) => type ? `${apiBaseUrl}/${nodeTypeToParam(type)}` : '';
628
+ /**
629
+ * Get the full url to fetch the node data.
630
+ *
631
+ * @param apiBaseUrl The url of the API hosting the data.
632
+ * @param node The node with a type, id and optionally a dataState
633
+ * @returns The full url.
634
+ */
635
+ const nodeUrl = (apiBaseUrl, _a) => {
636
+ var { dataState } = _a, node = __rest(_a, ["dataState"]);
637
+ return `${nodeTypeUrl(apiBaseUrl, node['@type'] || node.type)}/${node['@id'] || node.id}${dataState ? `?dataState=${dataState}` : ''}`;
638
+ };
639
+ const nodeLogsUrl = (apiBaseUrl, _a) => {
640
+ var { dataState } = _a, node = __rest(_a, ["dataState"]);
641
+ return `${nodeUrl(apiBaseUrl, node)}/log${dataState ? `?dataState=${dataState}` : ''}`;
642
+ };
643
+ const lookupUrl = (filename) => filename.startsWith('http') ? filename : `${baseUrl()}/glossary/lookups/${filename}.csv`;
644
+ const termTypeLookupUrl = (termType) => `${baseUrl()}/glossary/${termChildToParent(termType).termType}/${termType}.csv`;
895
645
  class HeNodeService {
896
646
  constructor(http, authService, commonService) {
897
647
  this.http = http;
@@ -944,26 +694,18 @@ class HeNodeService {
944
694
  .catch(() => (responseType === 'json' ? ({}) : ''));
945
695
  }
946
696
  nodeTypeUrl(type) {
947
- return `${this.commonService.apiBaseUrl}/${nodeTypeToParam(type)}`;
697
+ return nodeTypeUrl(this.commonService.apiBaseUrl, type);
948
698
  }
949
- nodeUrl(_a) {
950
- var { dataState } = _a, node = __rest(_a, ["dataState"]);
951
- return `${this.nodeTypeUrl(node['@type'] || node.type)}/${node['@id'] || node.id}${dataState ? `?dataState=${dataState}` : ''}`;
699
+ nodeUrl(node) {
700
+ return nodeUrl(this.commonService.apiBaseUrl, node);
952
701
  }
953
- nodeLogsUrl(_a) {
954
- var { dataState } = _a, node = __rest(_a, ["dataState"]);
955
- return `${this.nodeUrl(node)}/log${dataState ? `?dataState=${dataState}` : ''}`;
956
- }
957
- lookupUrl(filename) {
958
- return filename.startsWith('http') ? filename : `${baseUrl()}/glossary/lookups/${filename}.csv`;
959
- }
960
- termTypeLookupUrl(termType) {
961
- return `${baseUrl()}/glossary/${termChildToParent(termType).termType}/${termType}.csv`;
702
+ nodeLogsUrl(node) {
703
+ return nodeLogsUrl(this.commonService.apiBaseUrl, node);
962
704
  }
963
705
  downloadLookup(filename) {
964
706
  return __awaiter(this, void 0, void 0, function* () {
965
707
  try {
966
- const url = this.lookupUrl(filename);
708
+ const url = lookupUrl(filename);
967
709
  return this.downloadRaw(url, 'text');
968
710
  }
969
711
  catch (_err) {
@@ -975,7 +717,7 @@ class HeNodeService {
975
717
  return __awaiter(this, void 0, void 0, function* () {
976
718
  try {
977
719
  const data = yield this.downloadLookup(termType);
978
- return (data === null || data === void 0 ? void 0 : data.startsWith('term.id')) ? this.lookupUrl(termType) : null;
720
+ return (data === null || data === void 0 ? void 0 : data.startsWith('term.id')) ? lookupUrl(termType) : null;
979
721
  }
980
722
  catch (_err) {
981
723
  return null;
@@ -992,42 +734,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
992
734
  }]
993
735
  }], ctorParameters: function () { return [{ type: i1$1.HttpClient }, { type: HeAuthService }, { type: HeCommonService }]; } });
994
736
 
995
- const get$4 = require('lodash.get');
737
+ const gitUrl$1 = () => `${gitHome}/hestia-aggregation-engine/-/blob/${gitBranch()}`;
738
+ const rawUrl$1 = () => `${gitRawBaseUrl}/hestia-aggregation-engine/-/raw/${gitBranch()}`;
996
739
  const lookups = Object.freeze({
997
740
  cropYield: 'region-crop-cropGroupingFaostatProduction-yield',
998
741
  cropGroupingColumn: 'cropGroupingFaostatProduction'
999
742
  });
1000
- const extractGroupedDataClosesDate = (data, year) => {
1001
- const dataByDate = (data || '').split(';').reduce((prev, curr) => (Object.assign(Object.assign({}, prev), (curr.length > 0 && curr.split(':')[1] !== '-' ? { [curr.split(':')[0]]: curr.split(':')[1] } : {}))), {});
1002
- const years = Object.keys(dataByDate).map(v => +v);
1003
- const closestYear = years.reduce((prev, curr) => Math.abs(curr - year) < Math.abs(prev - year) ? curr : prev, 0);
1004
- return closestYear ? +dataByDate[closestYear] / 10 : null;
1005
- };
1006
- const cropGrouping = (lookup, product) => (lookup.find(({ term }) => term.id === (product === null || product === void 0 ? void 0 : product.term['@id'])) || {})[lookups.cropGroupingColumn];
1007
- const cropYieldCountry = (cropYield, cycle) => cropYield.find(({ term }) => term.id === get$4(cycle, 'site.country.@id', worldRegion['@id'])) || {};
1008
- const extendCycle = ({ crop, cropYield }) => (cycle) => {
1009
- var _a, _b, _c;
1010
- const product = primaryProduct(cycle);
1011
- const grouping = cropGrouping(crop, product);
1012
- const countryData = cropYieldCountry(cropYield, cycle)[grouping];
1013
- const countryValue = extractGroupedDataClosesDate(countryData, +(cycle.endDate || ''));
1014
- const productValue = propertyValue$1(product === null || product === void 0 ? void 0 : product.value);
1015
- return {
1016
- cycle,
1017
- name: (_a = product === null || product === void 0 ? void 0 : product.term) === null || _a === void 0 ? void 0 : _a.name,
1018
- startDate: cycle.startDate,
1019
- endDate: cycle.endDate,
1020
- country: ((_c = (_b = cycle.site) === null || _b === void 0 ? void 0 : _b.country) === null || _c === void 0 ? void 0 : _c.name) || worldRegion.name,
1021
- observations: propertyValue$1(product === null || product === void 0 ? void 0 : product.observations) || 0,
1022
- yield: productValue,
1023
- faoYield: countryValue || undefined,
1024
- diff: delta(productValue, countryValue)
1025
- };
1026
- };
1027
743
  class HeAggregationEngineService {
1028
- constructor(http, commonService, nodeService) {
744
+ constructor(http, nodeService) {
1029
745
  this.http = http;
1030
- this.commonService = commonService;
1031
746
  this.nodeService = nodeService;
1032
747
  this.modelsLoading = false;
1033
748
  this.modelsLoaded = false;
@@ -1042,18 +757,12 @@ class HeAggregationEngineService {
1042
757
  yield this.loadModels().toPromise();
1043
758
  });
1044
759
  }
1045
- get gitUrl() {
1046
- return `${gitHome}/hestia-aggregation-engine/-/blob/${this.commonService.gitBranch}`;
1047
- }
1048
- get rawUrl() {
1049
- return `${gitRawBaseUrl}/hestia-aggregation-engine/-/raw/${this.commonService.gitBranch}`;
1050
- }
1051
760
  loadModels() {
1052
761
  this.modelsLoading = true;
1053
- return this.http.get(`${this.rawUrl}/model-links.json`).pipe(catchError(() => of({ links: [] })), map(({ links }) => {
762
+ return this.http.get(`${rawUrl$1()}/model-links.json`).pipe(catchError(() => of({ links: [] })), map(({ links }) => {
1054
763
  this._models.next(links.map((_a) => {
1055
764
  var { path: modelPath, docPath } = _a, link = __rest(_a, ["path", "docPath"]);
1056
- return (Object.assign(Object.assign({}, link), { path: `${this.gitUrl}/${modelPath}`, docPath: `${this.gitUrl}/${docPath}` }));
765
+ return (Object.assign(Object.assign({}, link), { path: `${gitUrl$1()}/${modelPath}`, docPath: `${gitUrl$1()}/${docPath}` }));
1057
766
  }));
1058
767
  this.modelsLoading = false;
1059
768
  this.modelsLoaded = true;
@@ -1096,16 +805,18 @@ class HeAggregationEngineService {
1096
805
  return this.lookups$.pipe(take(1)).toPromise();
1097
806
  }
1098
807
  }
1099
- HeAggregationEngineService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: HeAggregationEngineService, deps: [{ token: i1$1.HttpClient }, { token: HeCommonService }, { token: HeNodeService }], target: i0.ɵɵFactoryTarget.Injectable });
808
+ HeAggregationEngineService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: HeAggregationEngineService, deps: [{ token: i1$1.HttpClient }, { token: HeNodeService }], target: i0.ɵɵFactoryTarget.Injectable });
1100
809
  HeAggregationEngineService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: HeAggregationEngineService, providedIn: 'root' });
1101
810
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: HeAggregationEngineService, decorators: [{
1102
811
  type: Injectable,
1103
812
  args: [{
1104
813
  providedIn: 'root'
1105
814
  }]
1106
- }], ctorParameters: function () { return [{ type: i1$1.HttpClient }, { type: HeCommonService }, { type: HeNodeService }]; } });
815
+ }], ctorParameters: function () { return [{ type: i1$1.HttpClient }, { type: HeNodeService }]; } });
1107
816
 
1108
817
  const HE_ORCHESTRATOR_BASE_URL = new InjectionToken('HE_ORCHESTRATOR_BASE_URL');
818
+ const gitUrl = () => `${gitHome}/hestia-engine-models/-/blob/${gitBranch()}`;
819
+ const rawUrl = () => `${gitRawBaseUrl}/hestia-engine-models/-/raw/${gitBranch()}`;
1109
820
  const findConfigModels = ({ models }, modelId, modelKey) => models.flat().filter(({ value, key }) => modelId.startsWith(value) && (!modelKey || key === modelKey));
1110
821
  const pathToApiDocsPath = (model, term) => [
1111
822
  baseUrl(),
@@ -1117,9 +828,8 @@ const pathToApiDocsPath = (model, term) => [
1117
828
  ].filter(Boolean).join('-')
1118
829
  ].join('/');
1119
830
  class HeEngineService {
1120
- constructor(http, commonService) {
831
+ constructor(http) {
1121
832
  this.http = http;
1122
- this.commonService = commonService;
1123
833
  this.modelsLoading = false;
1124
834
  this.modelsLoaded = false;
1125
835
  this._models = new ReplaySubject(1);
@@ -1130,18 +840,12 @@ class HeEngineService {
1130
840
  yield this.loadModels().toPromise();
1131
841
  });
1132
842
  }
1133
- get gitUrl() {
1134
- return `${gitHome}/hestia-engine-models/-/blob/${this.commonService.gitBranch}`;
1135
- }
1136
- get rawUrl() {
1137
- return `${gitRawBaseUrl}/hestia-engine-models/-/raw/${this.commonService.gitBranch}`;
1138
- }
1139
843
  loadModels() {
1140
844
  this.modelsLoading = true;
1141
- return this.http.get(`${this.rawUrl}/model-links.json`).pipe(catchError(() => of({ links: [] })), map(({ links }) => {
845
+ return this.http.get(`${rawUrl()}/model-links.json`).pipe(catchError(() => of({ links: [] })), map(({ links }) => {
1142
846
  this._models.next(links.map((_a) => {
1143
847
  var { path, docPath } = _a, link = __rest(_a, ["path", "docPath"]);
1144
- return (Object.assign(Object.assign({}, link), { path: `${this.gitUrl}/${path}`, docPath: `${this.gitUrl}/${docPath}`, apiDocsPath: pathToApiDocsPath(link.model, link.term || link.modelKey) }));
848
+ return (Object.assign(Object.assign({}, link), { path: `${gitUrl()}/${path}`, docPath: `${gitUrl()}/${docPath}`, apiDocsPath: pathToApiDocsPath(link.model, link.term || link.modelKey) }));
1145
849
  }));
1146
850
  this.modelsLoading = false;
1147
851
  this.modelsLoaded = true;
@@ -1166,14 +870,14 @@ class HeEngineService {
1166
870
  }).toPromise();
1167
871
  }
1168
872
  }
1169
- HeEngineService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: HeEngineService, deps: [{ token: i1$1.HttpClient }, { token: HeCommonService }], target: i0.ɵɵFactoryTarget.Injectable });
873
+ HeEngineService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: HeEngineService, deps: [{ token: i1$1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
1170
874
  HeEngineService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: HeEngineService, providedIn: 'root' });
1171
875
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: HeEngineService, decorators: [{
1172
876
  type: Injectable,
1173
877
  args: [{
1174
878
  providedIn: 'root'
1175
879
  }]
1176
- }], ctorParameters: function () { return [{ type: i1$1.HttpClient }, { type: HeCommonService }]; } });
880
+ }], ctorParameters: function () { return [{ type: i1$1.HttpClient }]; } });
1177
881
 
1178
882
  var NodeKeyState;
1179
883
  (function (NodeKeyState) {
@@ -1749,7 +1453,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
1749
1453
  }] } });
1750
1454
 
1751
1455
  let toastId = 0;
1752
- class ToastService {
1456
+ class HeToastService {
1753
1457
  constructor() {
1754
1458
  this.toasts = new ReplaySubject(1);
1755
1459
  }
@@ -1772,9 +1476,9 @@ class ToastService {
1772
1476
  });
1773
1477
  }
1774
1478
  }
1775
- ToastService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: ToastService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1776
- ToastService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: ToastService, providedIn: 'root' });
1777
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: ToastService, decorators: [{
1479
+ HeToastService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: HeToastService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1480
+ HeToastService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: HeToastService, providedIn: 'root' });
1481
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: HeToastService, decorators: [{
1778
1482
  type: Injectable,
1779
1483
  args: [{
1780
1484
  providedIn: 'root'
@@ -1803,7 +1507,7 @@ class ToastComponent {
1803
1507
  this.toasts.splice(this.toasts.findIndex(val => val.id === toast.id), 1);
1804
1508
  }
1805
1509
  }
1806
- ToastComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: ToastComponent, deps: [{ token: ToastService }], target: i0.ɵɵFactoryTarget.Component });
1510
+ ToastComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: ToastComponent, deps: [{ token: HeToastService }], target: i0.ɵɵFactoryTarget.Component });
1807
1511
  ToastComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: ToastComponent, selector: "he-toast", ngImport: i0, template: "<div class=\"mb-3 columns is-centered is-vcentered\">\n <div class=\"notification is-{{toast.color}}\" role=\"alert\" *ngFor=\"let toast of toasts\">\n <button class=\"delete\" aria-label=\"delete\" (click)=\"dismiss(toast)\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n <strong [ngSwitch]=\"toast.color\">\n <ng-container *ngSwitchCase=\"'danger'\">\n <ng-container [ngSwitch]=\"toast.message\">\n <span *ngSwitchCase=\"'Unauthorized'\">You are not allowed to perform this action.</span>\n <span *ngSwitchCase=\"'form-invalid'\">Please fix all the errors on this page.</span>\n <span *ngSwitchCase=\"'users-email-already-taken'\">Email already taken.</span>\n <span *ngSwitchCase=\"'users-auth-already-taken'\">Account already connected.</span>\n <span *ngSwitchDefault>\n <span *ngIf=\"toast.showRawMessage\">{{toast.message}}</span>\n <span [class.is-hidden]=\"toast.showRawMessage\">An unknown error occurred. Please try again later.</span>\n </span>\n </ng-container>\n </ng-container>\n <ng-container *ngSwitchDefault>\n <span *ngIf=\"toast.showRawMessage\">{{toast.message}}</span>\n <span [class.is-hidden]=\"toast.showRawMessage\">An unknown error occurred. Please try again later.</span>\n </ng-container>\n </strong>\n </div>\n</div>\n", styles: [":host{bottom:0;position:fixed;width:100%}\n"], directives: [{ type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i3.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { type: i3.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { type: i3.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
1808
1512
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: ToastComponent, decorators: [{
1809
1513
  type: Component,
@@ -1812,7 +1516,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
1812
1516
  templateUrl: './toast.component.html',
1813
1517
  styleUrls: ['./toast.component.scss']
1814
1518
  }]
1815
- }], ctorParameters: function () { return [{ type: ToastService }]; } });
1519
+ }], ctorParameters: function () { return [{ type: HeToastService }]; } });
1816
1520
 
1817
1521
  class KeysPipe {
1818
1522
  transform(value, sort = false) {
@@ -2228,6 +1932,209 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
2228
1932
  }]
2229
1933
  }], ctorParameters: function () { return [{ type: i1$1.HttpClient }, { type: HeCommonService }]; } });
2230
1934
 
1935
+ const searchableTypes = [
1936
+ NodeType.Cycle,
1937
+ NodeType.Source
1938
+ ];
1939
+ const serializeSearchFilters = (filters) => Object.keys(filters || {})
1940
+ .filter(key => filters[key].length)
1941
+ .map(key => `${key}=${filters[key].filter(Boolean).join('|')}`)
1942
+ .join(';');
1943
+ const deserializeSearchFilters = (filters) => (filters || '').split(';').reduce((prev, curr) => {
1944
+ const [key, values] = curr.split('=');
1945
+ prev[key] = (values || '').split('|').filter(Boolean);
1946
+ return prev;
1947
+ }, {});
1948
+ const matchType = (type) => Object.freeze({
1949
+ match: { '@type': type }
1950
+ });
1951
+ const matchTermType = (termType) => Object.freeze({
1952
+ match: { termType }
1953
+ });
1954
+ const matchRegex = (key, value) => Object.freeze({
1955
+ regexp: { [key]: { value: value.toString() } }
1956
+ });
1957
+ const matchQuery = (key, value, boost) => Object.freeze({
1958
+ match: {
1959
+ [key]: Object.assign({ query: value }, (boost ? { boost } : {}))
1960
+ }
1961
+ });
1962
+ const matchExactQuery = (key, value, boost) => matchQuery(`${key}.keyword`, value, boost);
1963
+ const matchNameNormalized = (query, boost = 20) => Object.freeze({
1964
+ match: { nameNormalized: { query, boost } }
1965
+ });
1966
+ const numberGte = (key, value) => Object.freeze({
1967
+ range: { [key]: { gte: value } }
1968
+ });
1969
+ const multiMatchQuery = (query, fields, type = 'best_fields', boost, analyzer) => Object.freeze({
1970
+ multi_match: Object.assign(Object.assign({ query,
1971
+ fields,
1972
+ type }, (boost ? { boost } : {})), (analyzer ? { analyzer } : {}))
1973
+ });
1974
+ const matchPhraseQuery = (query, boost, ...fields) => fields.length ? multiMatchQuery(query, fields, 'phrase', boost) : matchExactQuery('name', query, boost);
1975
+ const matchPhrasePrefixQuery = (query, boost = 2, ...fields) => fields.length ?
1976
+ multiMatchQuery(query, fields, 'phrase_prefix', boost) :
1977
+ Object.freeze({
1978
+ match_phrase_prefix: {
1979
+ nameSearchAsYouType: {
1980
+ query,
1981
+ boost
1982
+ }
1983
+ }
1984
+ });
1985
+ const matchBoolPrefixQuery = (query, boost = 1, ...fields) => fields.length ?
1986
+ multiMatchQuery(query, fields, 'bool_prefix', boost) :
1987
+ Object.freeze({
1988
+ match_bool_prefix: {
1989
+ name: {
1990
+ query,
1991
+ boost
1992
+ }
1993
+ }
1994
+ });
1995
+ const wildcardQuery = (query, boost = 3, ...fields) => Object.freeze({
1996
+ simple_query_string: {
1997
+ query: `*${query}*`,
1998
+ fields,
1999
+ analyze_wildcard: true,
2000
+ boost
2001
+ }
2002
+ });
2003
+ const matchCountryLevel = { match: { gadmLevel: 0 } };
2004
+ const matchGlobalRegion = { regexp: { '@id': 'region-*' } };
2005
+ const matchCountry = Object.freeze({
2006
+ bool: {
2007
+ should: [
2008
+ matchCountryLevel,
2009
+ matchGlobalRegion
2010
+ ],
2011
+ minimum_should_match: 1
2012
+ }
2013
+ });
2014
+ const countriesQuery = Object.freeze({
2015
+ bool: {
2016
+ must: [
2017
+ matchType(NodeType.Term),
2018
+ matchTermType(TermTermType.region),
2019
+ matchCountryLevel
2020
+ ]
2021
+ }
2022
+ });
2023
+ const allCountriesQuery = Object.freeze({
2024
+ bool: Object.assign({ must: [
2025
+ matchType(NodeType.Term),
2026
+ matchTermType(TermTermType.region)
2027
+ ] }, matchCountry.bool)
2028
+ });
2029
+ const matchRegion = numberGte('gadmLevel', 1);
2030
+ const regionsQuery = Object.freeze({
2031
+ bool: {
2032
+ must: [
2033
+ matchType(NodeType.Term),
2034
+ matchTermType(TermTermType.region),
2035
+ matchRegion
2036
+ ]
2037
+ }
2038
+ });
2039
+ const worldRegion = Object.freeze({
2040
+ '@id': 'region-world',
2041
+ name: 'World'
2042
+ });
2043
+ const cropsQuery = Object.freeze({
2044
+ bool: {
2045
+ must: [
2046
+ matchType(NodeType.Term),
2047
+ matchTermType(TermTermType.crop)
2048
+ ]
2049
+ }
2050
+ });
2051
+ const matchAggregatedQuery = matchQuery('aggregated', true);
2052
+ const isNestedKey = (key) => nestedSearchableKeys.includes(key.split('.')[0]);
2053
+ const matchNestedKey = (key, query) => isNestedKey(key) ? {
2054
+ nested: { path: key.split('.')[0], query }
2055
+ } : query;
2056
+ /**
2057
+ * List of fields to return in the search results.
2058
+ */
2059
+ const searchResultsFields = Object.freeze({
2060
+ [NodeType.Cycle]: [
2061
+ 'description', 'dataDescription', 'endDate',
2062
+ 'emissionsCount', 'inputsCount', 'productsCount',
2063
+ 'site.location', 'site.country.name', 'site.region.name'
2064
+ ],
2065
+ [NodeType.Source]: ['bibliography.title', 'bibliography.documentDOI'],
2066
+ [NodeType.ImpactAssessment]: ['emissionsResourceUseCount', 'impactsCount', 'country.name']
2067
+ });
2068
+ /**
2069
+ * List of fields to search in.
2070
+ */
2071
+ const searchFields = Object.freeze({
2072
+ [NodeType.Cycle]: ['name', 'description', 'dataDescription'],
2073
+ [NodeType.Source]: ['name', 'bibliography.title'],
2074
+ [NodeType.ImpactAssessment]: ['name', 'product.name', 'country.name']
2075
+ });
2076
+ const searchFieldsNested = Object.freeze({
2077
+ [NodeType.Cycle]: [
2078
+ 'inputs.term.name',
2079
+ 'emissions.term.name',
2080
+ 'practices.term.name'
2081
+ ],
2082
+ [NodeType.Source]: [],
2083
+ [NodeType.ImpactAssessment]: [
2084
+ 'emissionsResourceUse.term.name',
2085
+ 'impacts.term.name'
2086
+ ]
2087
+ });
2088
+ /**
2089
+ * Specific strict queries per type.
2090
+ */
2091
+ const searchQueries = {
2092
+ [NodeType.Cycle]: { must: [], must_not: [matchAggregatedQuery] },
2093
+ [NodeType.Source]: { must: [], must_not: [matchAggregatedQuery] }
2094
+ };
2095
+ const searchFiltersKeys = {
2096
+ [NodeType.Cycle]: key => key,
2097
+ [NodeType.Source]: key => key
2098
+ };
2099
+ /* eslint-disable complexity */
2100
+ const searchQuery = (type, query, filters, aggregated) => {
2101
+ const boolQuery = (Object.assign(Object.assign({ must: [
2102
+ matchType(type),
2103
+ aggregated ? matchAggregatedQuery : null
2104
+ ].filter(Boolean) }, (query ? {
2105
+ should: [
2106
+ matchPhraseQuery(query, 100, ...searchFields[type]),
2107
+ matchPhrasePrefixQuery(query, 20, ...searchFields[type]),
2108
+ matchBoolPrefixQuery(query, 10, ...searchFields[type]),
2109
+ ...searchFieldsNested[type].map(field => matchNestedKey(field, matchBoolPrefixQuery(query, 1, field)))
2110
+ ],
2111
+ minimum_should_match: 1
2112
+ } : {})), { must_not: [
2113
+ aggregated ? null : matchAggregatedQuery
2114
+ ].filter(Boolean) }));
2115
+ const keys = Object.keys(filters || {}).filter(key => filters[key].length);
2116
+ return {
2117
+ bool: keys.length ? {
2118
+ must: keys.map(key => {
2119
+ const filterKey = searchFiltersKeys[type](key);
2120
+ return {
2121
+ bool: {
2122
+ should: filters[key]
2123
+ .map(value => matchNestedKey(filterKey, matchExactQuery(filterKey, value)))
2124
+ .map(must => {
2125
+ const localQuery = JSON.parse(JSON.stringify(boolQuery));
2126
+ localQuery.must.push(must);
2127
+ return { bool: localQuery };
2128
+ }),
2129
+ minimum_should_match: 1
2130
+ }
2131
+ };
2132
+ })
2133
+ } : boolQuery
2134
+ };
2135
+ };
2136
+ /* eslint-enable complexity */
2137
+
2231
2138
  const emptySearchResult = () => ({
2232
2139
  time: 0,
2233
2140
  count: 0,
@@ -2479,6 +2386,8 @@ const toCsv$1 = (lines) => json2csvAsync(lines.map(formatLine).filter(data => Ob
2479
2386
  emptyFieldValue: ''
2480
2387
  });
2481
2388
 
2389
+ const primaryProduct = ({ products }) => (products || []).find(({ primary }) => primary);
2390
+
2482
2391
  const linkTypeEnabled = (type) => [
2483
2392
  NodeType.Cycle,
2484
2393
  NodeType.ImpactAssessment,
@@ -5863,7 +5772,7 @@ class ImpactAssessmentsProductsComponent {
5863
5772
  });
5864
5773
  }
5865
5774
  }
5866
- ImpactAssessmentsProductsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: ImpactAssessmentsProductsComponent, deps: [{ token: i1$4.FormBuilder }, { token: HeNodeService }, { token: HeSearchService }, { token: ToastService }], target: i0.ɵɵFactoryTarget.Component });
5775
+ ImpactAssessmentsProductsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: ImpactAssessmentsProductsComponent, deps: [{ token: i1$4.FormBuilder }, { token: HeNodeService }, { token: HeSearchService }, { token: HeToastService }], target: i0.ɵɵFactoryTarget.Component });
5867
5776
  ImpactAssessmentsProductsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: ImpactAssessmentsProductsComponent, selector: "he-impact-assessments-products", inputs: { cycles: "cycles", impactAssessments: "impactAssessments", key: "key", dataState: "dataState", enableCompare: "enableCompare", filterTermTypes: "filterTermTypes", enableFilterMethodModel: "enableFilterMethodModel" }, usesOnChanges: true, ngImport: i0, template: "<ng-container *ngIf=\"indicators.length; else emptyTable\">\n <div class=\"columns is-variable is-2 m-0\">\n <div class=\"column is-hidden-mobile\"></div>\n <div class=\"column is-narrow\">\n <div class=\"field has-addons\">\n <div class=\"control\">\n <button class=\"button is-small\" [class.is-active]=\"selectedView === View.table\" (click)=\"selectedView = View.table\">\n <span class=\"icon is-small\">\n <fa-icon icon=\"list\" aria-hidden=\"true\"></fa-icon>\n </span>\n <span>Table view</span>\n </button>\n </div>\n <div class=\"control\" *ngIf=\"impactAssessments.length > 1\">\n <button class=\"button is-small\" [class.is-active]=\"selectedView === View.chart\" (click)=\"selectedView = View.chart\">\n <span class=\"icon is-small\">\n <fa-icon icon=\"chart-bar\" aria-hidden=\"true\"></fa-icon>\n </span>\n <span>Chart view</span>\n </button>\n </div>\n <div class=\"control\" *ngIf=\"enableBreakdown\">\n <button class=\"button is-small\" [class.is-active]=\"selectedView === View.breakdown\" (click)=\"selectedView = View.breakdown\">\n <span class=\"icon is-small\">\n <fa-icon icon=\"chart-bar\" aria-hidden=\"true\"></fa-icon>\n </span>\n <span>Breakdown view</span>\n </button>\n </div>\n <div class=\"control\" *ngIf=\"!isOriginal && impactAssessments.length === 1\">\n <button class=\"button is-small\" [class.is-active]=\"selectedView === View.logs\" (click)=\"showRecalculationLogs()\">\n <span class=\"icon is-small\">\n <fa-icon icon=\"calculator\" aria-hidden=\"true\"></fa-icon>\n </span>\n <span>Recalculations logs</span>\n </button>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"px-3 pb-3\" [class.is-hidden]=\"selectedView !== View.table\">\n <div class=\"has-text-right mb-2\">\n <button class=\"button is-dark is-outlined is-small\" (click)=\"showDownload = true\">\n <fa-icon icon=\"download\"></fa-icon>\n <span class=\"pl-2\">Download (CSV)</span>\n </button>\n </div>\n\n <div class=\"table-container data-table-container mb-1\" *bindOnce=\"indicators\">\n <table class=\"table is-narrow data-table has-children-{{indicators.length + 1}}\">\n <thead>\n <tr>\n <th class=\"width-auto\">\n <div class=\"select is-small\" *ngIf=\"enableFilterMethodModel\">\n <select name=\"selectedMethodModel\"\n (change)=\"updateImpacts()\" [(ngModel)]=\"selectedMethodModel\"\n >\n <option [ngValue]=\"undefined\">Filter Model</option>\n <option *ngFor=\"let term of methodModels\" [ngValue]=\"term\">{{term.name}}</option>\n </select>\n </div>\n </th>\n <th></th>\n <th *ngFor=\"let indicator of indicators\"\n [attr.title]=\"indicator.value.term.name\"\n >\n <he-node-link [node]=\"indicator.value.term\">\n <span>{{indicator.value.term.name | ellipsis:30}}</span>\n </he-node-link>\n </th>\n </tr>\n <tr>\n <th class=\"width-auto\">\n <a [href]=\"baseUrl + '/schema/ImpactAssessment#functionalUnit'\" target=\"_blank\">Functional unit:</a>\n <span class=\"pl-1\">1 kg</span>\n </th>\n <th>Product</th>\n <th *ngFor=\"let indicator of indicators\"\n [attr.title]=\"indicator.value.term.units\"\n >{{indicator.value.term.units}}</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let impactAssessment of impactAssessments; trackBy: trackById; let i = index\">\n <td class=\"width-auto\" [attr.title]=\"impactName(impactAssessment)\" [style.border-left-color]=\"itemColor(i)\">\n <label *ngIf=\"enableCompare\" class=\"is-inline-block checkbox\">\n <input type=\"checkbox\" class=\"selector\"\n (change)=\"toggleImpact(impactAssessment)\"\n [checked]=\"isSelected(impactAssessment)\"\n >\n </label>\n <he-node-link class=\"is-inline-block\" [node]=\"impactAssessment\">\n <span class=\"is-nowrap has-text-ellipsis\">{{i + 1}}. {{impactName(impactAssessment)}}</span>\n </he-node-link>\n </td>\n <td [attr.title]=\"impactAssessment.product?.name\">\n <he-node-link *ngIf=\"impactAssessment.product\" [node]=\"impactAssessment.product\">\n <span>{{impactAssessment.product.name | ellipsis:30}}</span>\n </he-node-link>\n </td>\n <td class=\"is-nowrap\" *ngFor=\"let indicator of indicators\">\n <span *ngIf=\"indicator.value.values[impactAssessment['@id']]; else emptyValue\"\n class=\"trigger-popover\"\n [ngbPopover]=\"details\" [autoClose]=\"'outside'\"\n triggers=\"manual\" #p=\"ngbPopover\" placement=\"left\" container=\"body\"\n (click)=\"togglePopover(p, { data: indicator.value.values[impactAssessment['@id']], impactAssessment: impactAssessment, key: key })\"\n >\n <span pointer>{{propertyValue(indicator.value.values[impactAssessment['@id']].value, key === 'impacts') | precision:3 | default:'-'}}</span>\n <he-blank-node-state class=\"ml-1\"\n [node]=\"indicator.value.values[impactAssessment['@id']].nodes[0]\"\n key=\"value\"\n [state]=\"impactAssessment.aggregated ? 'aggregated' : null\"\n ></he-blank-node-state>\n </span>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n\n <he-blank-node-state-notice [dataState]=\"dataState\"></he-blank-node-state-notice>\n\n <form *ngIf=\"enableCompare\" class=\"mt-2\" [formGroup]=\"form\" (submit)=\"form.valid && addImpact()\">\n <div class=\"field has-addons\">\n <div class=\"control\">\n <span class=\"button is-small is-static\">Compare with Aggregated Impact Assessment</span>\n </div>\n <div class=\"control is-expanded\" [class.has-icons-right]=\"suggesting || loading\">\n <input class=\"input is-small\"\n placeholder=\"Search by name or id\"\n formControlName=\"search\" name=\"search\"\n\n [ngbTypeahead]=\"suggestImpactAssessment\"\n [inputFormatter]=\"formatter\"\n [resultTemplate]=\"suggestion\"\n [focusFirst]=\"true\"\n >\n <span class=\"icon is-small is-right has-text-grey-dark\" [class.is-hidden]=\"!(suggesting || loading)\">\n <fa-icon icon=\"spinner\" [pulse]=\"true\" size=\"sm\"></fa-icon>\n </span>\n </div>\n <div class=\"control\">\n <button class=\"button is-small\" type=\"submit\" [disabled]=\"suggesting || loading\">\n <fa-icon icon=\"plus\"></fa-icon>\n </button>\n </div>\n </div>\n </form>\n </div>\n\n <he-impact-assessments-indicator-breakdown-chart *ngIf=\"selectedView === View.breakdown\"\n [impactAssessment]=\"impactAssessments[0]\"\n [indicators]=\"impactAssessments[0][key]\"\n ></he-impact-assessments-indicator-breakdown-chart>\n\n <he-impact-assessments-indicators-chart *ngIf=\"impactAssessments.length > 1\" [class.is-hidden]=\"selectedView !== View.chart\"\n [key]=\"key\"\n [impactAssessments]=\"selectedImpactAssessments\"\n [filterTermTypes]=\"filterTermTypes\"\n ></he-impact-assessments-indicators-chart>\n\n <he-impact-assessments-products-logs *ngIf=\"selectedView === View.logs && !isOriginal\"\n [key]=\"key\"\n [impactAssessment]=\"impactAssessments[0]\"\n [filterTermTypes]=\"filterTermTypes\"\n [originalValues]=\"originalValues[0][key]\"\n [recalculatedValues]=\"impactAssessments[0][key]\"\n ></he-impact-assessments-products-logs>\n</ng-container>\n\n<he-node-csv-export-confirm *ngIf=\"showDownload\"\n [nodes]=\"impactAssessments\" [filename]=\"'impact-' + key + '.csv'\" [isUpload]=\"false\"\n [headerKeys]=\"['impactAssessment.id', 'impactAssessment.@id', 'impactAssessment.' + key + '.']\"\n (closed)=\"showDownload = false\"\n></he-node-csv-export-confirm>\n\n<ng-template #emptyTable>\n <div class=\"panel-block\">\n <span>No data</span>\n </div>\n</ng-template>\n\n<ng-template #emptyValue>\n <span>-</span>\n</ng-template>\n\n<ng-template #details let-node=\"impactAssessment\" let-data=\"data\" let-key=\"key\">\n <p *bindOnce=\"node\">\n <b>\n <span *ngIf=\"data.cycle\">{{cycleLabel(node.cycle)}}</span>\n <span *ngIf=\"!data.cycle\">{{data.name}}</span>\n </b>\n </p>\n <he-node-value-details\n [data]=\"data\" [nodeType]=\"node['@type']\" [dataKey]=\"key\"\n ></he-node-value-details>\n</ng-template>\n\n<ng-template #suggestion let-impact=\"result\" let-t=\"term\">\n <div class=\"is-block\">\n <ngb-highlight [result]=\"impact.name || impact.cycle.name\" [term]=\"t\"></ngb-highlight>\n </div>\n <div class=\"columns is-flex\">\n <div class=\"column\" *ngIf=\"impact.country\">\n <span class=\"pr-1 has-text-underline\">Country:</span>\n <span class=\"is-inline-flex\"><ngb-highlight [result]=\"impact.country.name\" [term]=\"t\"></ngb-highlight></span>\n </div>\n <div class=\"column\" *ngIf=\"impact.product\">\n <span class=\"pr-1 has-text-underline\">Product:</span>\n <span class=\"is-inline-flex\"><ngb-highlight [result]=\"impact.product.name\" [term]=\"t\"></ngb-highlight></span>\n </div>\n <div class=\"column\" *ngIf=\"impact.endDate\">\n <span class=\"pr-1 has-text-underline\">Date:</span>\n <span class=\"is-inline-flex\"><ngb-highlight [result]=\"impact.endDate\" [term]=\"t\"></ngb-highlight></span>\n </div>\n </div>\n</ng-template>\n", styles: ["label.checkbox{width:20px}td he-node-link{width:160px}table.data-table td:first-child{border-left-width:8px}\n"], components: [{ type: i1.FaIconComponent, selector: "fa-icon", inputs: ["classes", "icon", "title", "spin", "pulse", "mask", "styles", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "transform", "a11yRole"] }, { type: NodeLinkComponent, selector: "he-node-link", inputs: ["node", "showExternalLink"] }, { type: BlankNodeStateComponent, selector: "he-blank-node-state", inputs: ["nodeType", "dataKey", "key", "node", "state"] }, { type: BlankNodeStateNoticeComponent, selector: "he-blank-node-state-notice", inputs: ["dataState", "showDeleted"] }, { type: ImpactAssessmentsIndicatorBreakdownChartComponent, selector: "he-impact-assessments-indicator-breakdown-chart", inputs: ["impactAssessment", "indicators"] }, { type: ImpactAssessmentsIndicatorsChartComponent, selector: "he-impact-assessments-indicators-chart", inputs: ["impactAssessments", "key", "filterTermTypes"] }, { type: ImpactAssessmentsProductsLogsComponent, selector: "he-impact-assessments-products-logs", inputs: ["impactAssessment", "key", "filterTermTypes", "originalValues", "recalculatedValues"] }, { type: NodeCsvExportConfirmComponent, selector: "he-node-csv-export-confirm", inputs: ["nodes", "filename", "headerKeys", "extension", "isUpload"], outputs: ["closed"] }, { type: NodeValueDetailsComponent, selector: "he-node-value-details", inputs: ["data", "nodeType", "dataKey"] }, { type: i10.NgbHighlight, selector: "ngb-highlight", inputs: ["highlightClass", "result", "term"] }], directives: [{ type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: BindOnceDirective, selector: "[bindOnce]", inputs: ["bindOnce"] }, { type: i1$4.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i1$4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i1$4.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { type: i1$4.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i10.NgbPopover, selector: "[ngbPopover]", inputs: ["animation", "autoClose", "placement", "triggers", "container", "disablePopover", "popoverClass", "openDelay", "closeDelay", "ngbPopover", "popoverTitle"], outputs: ["shown", "hidden"], exportAs: ["ngbPopover"] }, { type: i1$4.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i1$4.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i1$4.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i1$4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i10.NgbTypeahead, selector: "input[ngbTypeahead]", inputs: ["autocomplete", "placement", "container", "editable", "focusFirst", "showHint", "inputFormatter", "ngbTypeahead", "resultFormatter", "resultTemplate"], outputs: ["selectItem"], exportAs: ["ngbTypeahead"] }, { type: i1$4.FormControlName, selector: "[formControlName]", inputs: ["disabled", "formControlName", "ngModel"], outputs: ["ngModelChange"] }], pipes: { "ellipsis": EllipsisPipe, "default": DefaultPipe, "precision": PrecisionPipe } });
5868
5777
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: ImpactAssessmentsProductsComponent, decorators: [{
5869
5778
  type: Component,
@@ -5872,7 +5781,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
5872
5781
  templateUrl: './impact-assessments-products.component.html',
5873
5782
  styleUrls: ['./impact-assessments-products.component.scss']
5874
5783
  }]
5875
- }], ctorParameters: function () { return [{ type: i1$4.FormBuilder }, { type: HeNodeService }, { type: HeSearchService }, { type: ToastService }]; }, propDecorators: { cycles: [{
5784
+ }], ctorParameters: function () { return [{ type: i1$4.FormBuilder }, { type: HeNodeService }, { type: HeSearchService }, { type: HeToastService }]; }, propDecorators: { cycles: [{
5876
5785
  type: Input
5877
5786
  }], impactAssessments: [{
5878
5787
  type: Input
@@ -5957,5 +5866,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
5957
5866
  * Generated bundle index. Do not edit.
5958
5867
  */
5959
5868
 
5960
- export { BibliographiesSearchConfirmComponent, BindOnceDirective, BlankNodeDiffsComponent, BlankNodeStateComponent, BlankNodeStateNoticeComponent, BlankNodeValueDeltaComponent, ClickOutsideDirective, ClipboardComponent, CyclesActivityComponent, CyclesActivityLogsComponent, CyclesCompletenessComponent, CyclesEmissionsChartComponent, CyclesEmissionsComponent, CyclesEmissionsLogsComponent, CyclesFunctionalUnitMeasureComponent, CyclesResultComponent, CyclesSuggestFormComponent, DefaultPipe, DeltaColour, DeltaDisplayType, EllipsisPipe, FilesFormComponent, GetPipe, HE_API_BASE_URL, HE_ORCHESTRATOR_BASE_URL, HeAggregationEngineService, HeAuthService, HeBibliographiesModule, HeCommonModule, HeCommonService, HeCyclesModule, HeEngineService, HeFilesModule, HeFontawesomeModule, HeImpactAssessmentsModule, HeMendeleyService, HeNodeCsvService, HeNodeModule, HeNodeService, HeSchemaService, HeSearchModule, HeSearchService, HeSitesModule, HeUsersService, ImpactAssessmentsIndicatorBreakdownChartComponent, ImpactAssessmentsIndicatorsChartComponent, ImpactAssessmentsProductsComponent, ImpactAssessmentsProductsLogsComponent, KeyToLabelPipe, KeysPipe, Level, LinkKeyValueComponent, MAX_RESULTS, MapsDrawingConfirmComponent, MendeleySearchResult, NodeCsvExportConfirmComponent, NodeCsvSelectHeadersComponent, NodeDiffsComponent, NodeIconComponent, NodeLinkComponent, NodeLogsFileComponent, NodeLogsModelsComponent, NodeMissingLookupFactorsComponent, NodeValueDetailsComponent, PluralizePipe, PopoverComponent, PopoverConfirmComponent, PrecisionPipe, SchemaVersionLinkComponent, SitesMapsComponent, SitesMeasurementsComponent, SitesMeasurementsLogsComponent, SkeletonTextComponent, SocialTagsComponent, TagsInputDirective, TimesPipe, ToastComponent, ToastService, UnitConverterComponent, allCountriesQuery, animateCounter, arrayValue, availableProperties, baseUrl, bottom, countriesQuery, cropsQuery, dataValue, defaultLabel, definitionToSchemaType, delta, deserializeSearchFilters, ellipsis, emptyValue, errorText, filenameWithoutExt, filterParams, findPropertyById, gitHome, gitRawBaseUrl, groupNodesByTerm, grouppedKeys, grouppedValueKeys, handleAPIError, hoursBefore, isChrome, isExternal, isSchemaIri, isScrolledBelow, itemColor, keyToLabel, levels, linkTypeEnabled, listColor, loadScript, mapsUrl, matchAggregatedQuery, matchBoolPrefixQuery, matchCountry, matchExactQuery, matchGlobalRegion, matchNameNormalized, matchNestedKey, matchPhrasePrefixQuery, matchPhraseQuery, matchQuery, matchRegex, matchRegion, matchTermType, matchType, maxAreaSize, measurementValue, minutesBefore, multiMatchQuery, nestingEnabled, nestingTypeEnabled, nodeTypeToString, numberGte, parseData, parseLines, parseMessage, parseNodeType, propertyValue$1 as propertyValue, refToSchemaType, regionsQuery, repeat, roundValue, safeJSONParse, safeJSONStringify, schemaRequiredProperties, schemaTypeToDefaultValue, scrollToEl, scrollTop, searchQuery, searchResultsFields, searchableTypes, serializeSearchFilters, siteTooBig, sortByFn, sortOrder, suggestMatchQuery, suggestQuery, termChildToParent, termLocation, termLocationName, termProperties, termTypeGroups, termTypeLabel, toCsv$1 as toCsv, toDashCase, toFormData, toSearchParams, valueTypeToDefault, waitFor, wildcardQuery, worldRegion };
5869
+ export { BibliographiesSearchConfirmComponent, BindOnceDirective, BlankNodeDiffsComponent, BlankNodeStateComponent, BlankNodeStateNoticeComponent, BlankNodeValueDeltaComponent, ClickOutsideDirective, ClipboardComponent, CyclesActivityComponent, CyclesActivityLogsComponent, CyclesCompletenessComponent, CyclesEmissionsChartComponent, CyclesEmissionsComponent, CyclesEmissionsLogsComponent, CyclesFunctionalUnitMeasureComponent, CyclesResultComponent, CyclesSuggestFormComponent, DefaultPipe, DeltaColour, DeltaDisplayType, EllipsisPipe, FilesFormComponent, GetPipe, HE_API_BASE_URL, HE_ORCHESTRATOR_BASE_URL, HeAggregationEngineService, HeAuthService, HeBibliographiesModule, HeCommonModule, HeCommonService, HeCyclesModule, HeEngineService, HeFilesModule, HeFontawesomeModule, HeImpactAssessmentsModule, HeMendeleyService, HeNodeCsvService, HeNodeModule, HeNodeService, HeSchemaService, HeSearchModule, HeSearchService, HeSitesModule, HeToastService, HeUsersService, ImpactAssessmentsIndicatorBreakdownChartComponent, ImpactAssessmentsIndicatorsChartComponent, ImpactAssessmentsProductsComponent, ImpactAssessmentsProductsLogsComponent, KeyToLabelPipe, KeysPipe, Level, LinkKeyValueComponent, MAX_RESULTS, MapsDrawingConfirmComponent, MendeleySearchResult, NodeCsvExportConfirmComponent, NodeCsvSelectHeadersComponent, NodeDiffsComponent, NodeIconComponent, NodeLinkComponent, NodeLogsFileComponent, NodeLogsModelsComponent, NodeMissingLookupFactorsComponent, NodeValueDetailsComponent, PluralizePipe, PopoverComponent, PopoverConfirmComponent, PrecisionPipe, SchemaVersionLinkComponent, SitesMapsComponent, SitesMeasurementsComponent, SitesMeasurementsLogsComponent, SkeletonTextComponent, SocialTagsComponent, TagsInputDirective, TimesPipe, ToastComponent, UnitConverterComponent, addPolygonToFeature, allCountriesQuery, arrayValue, availableProperties, baseUrl, bottom, clustererImage, coordinatesToPoint, countriesQuery, createMarker, cropsQuery, dataValue, defaultFeature, defaultLabel, definitionToSchemaType, delta, deserializeSearchFilters, ellipsis, emptyValue, errorText, filenameWithoutExt, fillColor, fillStyle, filterParams, findPropertyById, gitBranch, gitHome, gitRawBaseUrl, groupNodesByTerm, grouppedKeys, grouppedValueKeys, handleAPIError, isChrome, isExternal, isSchemaIri, isScrolledBelow, itemColor, keyToLabel, levels, linkTypeEnabled, listColor, locationQuery, lookupUrl, mapsUrl, markerIcon, markerPie, matchAggregatedQuery, matchBoolPrefixQuery, matchCountry, matchExactQuery, matchGlobalRegion, matchNameNormalized, matchNestedKey, matchPhrasePrefixQuery, matchPhraseQuery, matchQuery, matchRegex, matchRegion, matchTermType, matchType, maxAreaSize, measurementValue, multiMatchQuery, nestingEnabled, nestingTypeEnabled, nodeLogsUrl, nodeUrl, numberGte, parseData, parseLines, parseMessage, pointToCoordinates, polygonBounds, polygonToCoordinates, polygonsFromFeature, primaryProduct, propertyValue$1 as propertyValue, refToSchemaType, regionsQuery, repeat, roundValue, safeJSONParse, safeJSONStringify, schemaRequiredProperties, schemaTypeToDefaultValue, scrollToEl, scrollTop, searchQuery, searchResultsFields, searchableTypes, serializeSearchFilters, siteTooBig, sortOrder, strokeColor, strokeStyle, suggestMatchQuery, suggestQuery, termChildToParent, termLocation, termLocationName, termProperties, termTypeGroups, termTypeLabel, termTypeLookupUrl, toCsv$1 as toCsv, toDashCase, valueTypeToDefault, waitFor, wildcardQuery, worldRegion };
5961
5870
  //# sourceMappingURL=hestia-earth-ui-components.js.map