@sumaris-net/ngx-components 2.18.0-beta1 → 2.18.0-beta10

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 (57) hide show
  1. package/esm2022/public_api.mjs +2 -1
  2. package/esm2022/src/app/core/account/account.page.mjs +1 -2
  3. package/esm2022/src/app/core/auth/auth.form.mjs +1 -2
  4. package/esm2022/src/app/core/form/array/testing/form-array.test.mjs +1 -2
  5. package/esm2022/src/app/core/form/entity/entity-editor-modal.class.mjs +1 -2
  6. package/esm2022/src/app/core/form/entity/entity-editor.class.mjs +1 -2
  7. package/esm2022/src/app/core/form/entity/tab-editor.class.mjs +1 -2
  8. package/esm2022/src/app/core/form/form-container.class.mjs +6 -3
  9. package/esm2022/src/app/core/form/properties/properties.utils.mjs +60 -0
  10. package/esm2022/src/app/core/form/text-popover/text-popover.component.mjs +1 -2
  11. package/esm2022/src/app/core/menu/menu.component.mjs +1 -2
  12. package/esm2022/src/app/core/menu/menu.service.mjs +1 -2
  13. package/esm2022/src/app/core/services/account.service.mjs +3 -3
  14. package/esm2022/src/app/core/services/config.service.mjs +1 -2
  15. package/esm2022/src/app/core/services/model/entity.model.mjs +3 -9
  16. package/esm2022/src/app/core/services/model/peer.model.mjs +11 -2
  17. package/esm2022/src/app/core/services/network.service.mjs +4 -3
  18. package/esm2022/src/app/core/services/platform.service.mjs +1 -2
  19. package/esm2022/src/app/core/services/validator/local-settings.validator.mjs +8 -7
  20. package/esm2022/src/app/core/settings/settings.page.mjs +5 -5
  21. package/esm2022/src/app/core/table/async-table.class.mjs +1 -2
  22. package/esm2022/src/app/core/table/entities-table-datasource.class.mjs +1 -2
  23. package/esm2022/src/app/core/table/table.class.mjs +1 -2
  24. package/esm2022/src/app/shared/form/field.component.mjs +1 -2
  25. package/esm2022/src/app/shared/forms.mjs +45 -3
  26. package/esm2022/src/app/shared/functions.mjs +1 -2
  27. package/esm2022/src/app/shared/hotkeys/dialog/hotkeys-dialog.component.mjs +3 -3
  28. package/esm2022/src/app/shared/hotkeys/hotkeys.service.mjs +37 -9
  29. package/esm2022/src/app/shared/image/gallery/image-gallery.component.mjs +1 -2
  30. package/esm2022/src/app/shared/material/autocomplete/material.autocomplete.mjs +1 -2
  31. package/esm2022/src/app/shared/material/boolean/material.boolean.mjs +1 -2
  32. package/esm2022/src/app/shared/material/datetime/material.date.mjs +1 -2
  33. package/esm2022/src/app/shared/material/datetime/material.dateshort.mjs +4 -3
  34. package/esm2022/src/app/shared/material/datetime/material.datetime.mjs +1 -2
  35. package/esm2022/src/app/shared/material/duration/material.duration.mjs +1 -2
  36. package/esm2022/src/app/shared/material/latlong/testing/latlong.test.mjs +1 -2
  37. package/esm2022/src/app/shared/material/swipe/material.swipe.mjs +1 -2
  38. package/esm2022/src/app/shared/toolbar/toolbar.mjs +1 -2
  39. package/esm2022/src/app/shared/upload-file/testing/upload-file.testing.mjs +1 -2
  40. package/esm2022/src/app/shared/validator/validators.mjs +3 -2
  41. package/esm2022/src/app/social/job/progression/job-progression.icon.mjs +1 -2
  42. package/esm2022/src/app/social/message/message.modal.mjs +1 -2
  43. package/esm2022/src/app/social/user-event/notification/user-event-notification.icon.mjs +1 -2
  44. package/fesm2022/sumaris-net.ngx-components.mjs +230 -92
  45. package/fesm2022/sumaris-net.ngx-components.mjs.map +1 -1
  46. package/package.json +2 -2
  47. package/public_api.d.ts +1 -0
  48. package/src/app/core/form/properties/properties.utils.d.ts +27 -0
  49. package/src/app/core/services/model/entity.model.d.ts +3 -2
  50. package/src/app/core/services/model/peer.model.d.ts +1 -0
  51. package/src/app/shared/forms.d.ts +19 -0
  52. package/src/app/shared/hotkeys/hotkeys.service.d.ts +16 -2
  53. package/src/app/shared/validator/validators.d.ts +2 -0
  54. package/src/assets/i18n/en-US.json +1 -0
  55. package/src/assets/i18n/en.json +1 -0
  56. package/src/assets/i18n/fr.json +1 -0
  57. package/src/assets/manifest.json +1 -1
@@ -2,7 +2,6 @@ import * as i0 from '@angular/core';
2
2
  import { InjectionToken, Directive, Pipe, Injectable, EventEmitter, Output, Optional, Inject, NgModule, forwardRef, Component, ChangeDetectionStrategy, Input, ViewChildren, HostBinding, HostListener, ElementRef, booleanAttribute, numberAttribute, ViewChild, ANIMATION_MODULE_TYPE, RendererStyleFlags2, CUSTOM_ELEMENTS_SCHEMA, inject, ViewEncapsulation, APP_INITIALIZER, ChangeDetectorRef } from '@angular/core';
3
3
  import { firstValueFrom, shareReplay, tap, of, timer, Subject, merge, delay, isObservable, from, Subscription, BehaviorSubject, fromEvent, noop as noop$a, Observable, forkJoin, defer, timeout, debounceTime as debounceTime$1, distinctUntilChanged as distinctUntilChanged$1, fromEventPattern, interval, combineLatest, mergeMap as mergeMap$1, EMPTY, switchMap as switchMap$1 } from 'rxjs';
4
4
  import { catchError, map, filter, takeUntil, first, switchMap, tap as tap$1, debounceTime, startWith, distinctUntilChanged, mergeMap, skip, finalize, throttleTime, bufferWhen, mapTo, distinctUntilKeyChanged, take } from 'rxjs/operators';
5
- import { setTimeout as setTimeout$1 } from '@rx-angular/cdk/zone-less/browser';
6
5
  import * as i3 from '@angular/common';
7
6
  import { CommonModule, DOCUMENT, Location } from '@angular/common';
8
7
  import { CdkTableModule } from '@angular/cdk/table';
@@ -35,7 +34,7 @@ import * as i1 from '@angular/material-moment-adapter';
35
34
  import { MatMomentDateModule } from '@angular/material-moment-adapter';
36
35
  import { isMoment as isMoment$1 } from 'moment/moment';
37
36
  import * as i1$3 from '@angular/forms';
38
- import { AbstractControl, UntypedFormArray, UntypedFormGroup, UntypedFormControl, NG_VALUE_ACCESSOR, Validators, ReactiveFormsModule, FormControl, FormGroup, FormsModule } from '@angular/forms';
37
+ import { AbstractControl, UntypedFormArray, UntypedFormGroup, UntypedFormControl, Validators, NG_VALUE_ACCESSOR, ReactiveFormsModule, FormControl, FormGroup, FormsModule } from '@angular/forms';
39
38
  import { maskitoWithPlaceholder, maskitoEventHandler, maskitoDateOptionsGenerator, maskitoTimeOptionsGenerator } from '@maskito/kit';
40
39
  import * as i1$2 from '@angular/platform-browser';
41
40
  import { HammerGestureConfig, HammerModule } from '@angular/platform-browser';
@@ -558,7 +557,7 @@ function setPropertyByPath(obj, path, value) {
558
557
  function sleep(ms) {
559
558
  if (ms <= 0)
560
559
  return Promise.resolve();
561
- return new Promise((resolve) => setTimeout$1(resolve, ms));
560
+ return new Promise((resolve) => setTimeout(resolve, ms));
562
561
  }
563
562
  function round(value) {
564
563
  if (isNotNilOrNaN(value)) {
@@ -2493,6 +2492,8 @@ class SharedValidators {
2493
2492
  pattern: 'ERROR.FIELD_NOT_VALID_PATTERN',
2494
2493
  unique: 'ERROR.FIELD_NOT_UNIQUE',
2495
2494
  entity: 'ERROR.FIELD_INVALID',
2495
+ invalid: 'ERROR.FIELD_INVALID',
2496
+ inconsistent: 'ERROR.FIELD_INCONSISTENT',
2496
2497
  equals: 'ERROR.FIELD_NOT_EQUALS',
2497
2498
  };
2498
2499
  static latitude(control) {
@@ -3022,7 +3023,7 @@ class SharedAsyncValidators {
3022
3023
  // Clear added validator. Must be done NOW (without delay) because generally a new Job is given just after
3023
3024
  form.clearAsyncValidators();
3024
3025
  // Stop the job, with a delay to let the last execution finished
3025
- setTimeout$1(() => {
3026
+ setTimeout(() => {
3026
3027
  $dispose.next();
3027
3028
  $dispose.unsubscribe();
3028
3029
  }, debounceTime);
@@ -3512,6 +3513,20 @@ function getFormErrors(control, opts) {
3512
3513
  }
3513
3514
  // Form array
3514
3515
  else if (control instanceof UntypedFormArray) {
3516
+ // Copy errors
3517
+ if (control.errors) {
3518
+ if (opts.controlName) {
3519
+ opts.result[opts.controlName] = {
3520
+ ...control.errors,
3521
+ };
3522
+ }
3523
+ else {
3524
+ opts.result = {
3525
+ ...opts.result,
3526
+ ...control.errors,
3527
+ };
3528
+ }
3529
+ }
3515
3530
  control.controls.forEach((child, index) => {
3516
3531
  getFormErrors(child, {
3517
3532
  ...opts,
@@ -3554,6 +3569,34 @@ function disableControls(form, paths, opts) {
3554
3569
  control.disable(opts);
3555
3570
  });
3556
3571
  }
3572
+ function enableControls(form, paths, opts) {
3573
+ (paths || []).forEach((path) => {
3574
+ const control = getControlFromPath(form, path);
3575
+ if (control)
3576
+ control.enable(opts);
3577
+ });
3578
+ }
3579
+ function enableControl(control, opts) {
3580
+ this.setControlEnabled(control, true, opts);
3581
+ }
3582
+ function disableControl(control, opts) {
3583
+ this.setControlEnabled(control, false, { required: false, ...opts });
3584
+ }
3585
+ function setControlEnabled(control, enabled, opts) {
3586
+ if (enabled) {
3587
+ if (isNotNil(opts?.required) && opts.required && !control.hasValidator(Validators.required)) {
3588
+ control.addValidators(Validators.required);
3589
+ }
3590
+ control.enable(opts);
3591
+ }
3592
+ else {
3593
+ control.disable(opts);
3594
+ if (isNotNil(opts?.required) && !opts.required && control.hasValidator(Validators.required)) {
3595
+ control.removeValidators(Validators.required);
3596
+ }
3597
+ control.reset(null, opts);
3598
+ }
3599
+ }
3557
3600
  function addValueInArray(arrayControl, createControl, equals, isEmpty, value, options) {
3558
3601
  const disabled = arrayControl.disabled;
3559
3602
  let hasChanged = false;
@@ -5247,7 +5290,7 @@ class MatDuration {
5247
5290
  set tabindex(value) {
5248
5291
  if (this._tabindex !== value) {
5249
5292
  this._tabindex = value;
5250
- setTimeout$1(() => this.updateTabIndex());
5293
+ setTimeout(() => this.updateTabIndex());
5251
5294
  }
5252
5295
  }
5253
5296
  get tabindex() {
@@ -5399,7 +5442,7 @@ class MatDuration {
5399
5442
  focus() {
5400
5443
  if (!this.matInputs.length)
5401
5444
  return;
5402
- setTimeout$1(() => {
5445
+ setTimeout(() => {
5403
5446
  const elementRef = this.matInputs[0]; // get the first element
5404
5447
  if (isFocusableElement(elementRef)) {
5405
5448
  elementRef.focus();
@@ -5415,7 +5458,7 @@ class MatDuration {
5415
5458
  if (isNil(this._tabindex) || this._tabindex === -1)
5416
5459
  return; // skip
5417
5460
  // Focus to first input
5418
- setTimeout$1(() => {
5461
+ setTimeout(() => {
5419
5462
  this.matInputs.forEach((elementRef, index) => {
5420
5463
  setTabIndex(elementRef, this._tabindex + index);
5421
5464
  });
@@ -5815,7 +5858,7 @@ class MatBooleanField {
5815
5858
  set tabindex(value) {
5816
5859
  if (this._tabindex !== value) {
5817
5860
  this._tabindex = value;
5818
- setTimeout$1(() => this.updateTabIndex());
5861
+ setTimeout(() => this.updateTabIndex());
5819
5862
  }
5820
5863
  }
5821
5864
  get tabindex() {
@@ -5891,7 +5934,7 @@ class MatBooleanField {
5891
5934
  this.checkboxButton.checked = value;
5892
5935
  }
5893
5936
  }
5894
- setTimeout$1(() => {
5937
+ setTimeout(() => {
5895
5938
  this.updateFakeInput();
5896
5939
  this.updateTabIndex();
5897
5940
  });
@@ -5931,7 +5974,7 @@ class MatBooleanField {
5931
5974
  this._focused = true;
5932
5975
  this._onTouchedCallback();
5933
5976
  this.markForCheck();
5934
- setTimeout$1(() => {
5977
+ setTimeout(() => {
5935
5978
  // Add a blur listener on each inputs
5936
5979
  const inputElements = this.inputsElements;
5937
5980
  inputElements.forEach((el) => (el.onblur = (e) => {
@@ -7147,7 +7190,7 @@ class MatAutocompleteField {
7147
7190
  if (!event || event.defaultPrevented)
7148
7191
  return;
7149
7192
  // Need a timeout to prevent early blur event without triggering formChange event
7150
- setTimeout$1(() => {
7193
+ setTimeout(() => {
7151
7194
  // Ignore event from mat-option
7152
7195
  if ((event.relatedTarget instanceof HTMLElement && event.relatedTarget.tagName === 'MAT-OPTION') ||
7153
7196
  // Or autocomplete panel is open because event.relatedTarget is null (cf. https://github.com/angular/components/issues/24182)
@@ -8334,7 +8377,7 @@ class MatDate {
8334
8377
  focus() {
8335
8378
  if (!this._matInput)
8336
8379
  return;
8337
- setTimeout$1(() => {
8380
+ setTimeout(() => {
8338
8381
  if (isFocusableElement(this._matInput.nativeElement)) {
8339
8382
  this._matInput.nativeElement.focus();
8340
8383
  }
@@ -8505,7 +8548,7 @@ class MatDate {
8505
8548
  if (isNil(this._tabindex) || this._tabindex === -1)
8506
8549
  return; // skip
8507
8550
  // Focus to input
8508
- setTimeout$1(() => {
8551
+ setTimeout(() => {
8509
8552
  setTabIndex(this._matInput, this._tabindex);
8510
8553
  this.markForCheck();
8511
8554
  });
@@ -8805,7 +8848,7 @@ class MatDateTime {
8805
8848
  const matInput = this._matInputs.first;
8806
8849
  if (!matInput)
8807
8850
  return;
8808
- setTimeout$1(() => {
8851
+ setTimeout(() => {
8809
8852
  if (isFocusableElement(matInput.nativeElement)) {
8810
8853
  matInput.nativeElement.focus();
8811
8854
  }
@@ -9148,7 +9191,7 @@ class MatDateTime {
9148
9191
  if (isNil(this._tabindex) || this._tabindex === -1)
9149
9192
  return; // skip
9150
9193
  // Focus to first input
9151
- setTimeout$1(() => {
9194
+ setTimeout(() => {
9152
9195
  this._matInputs.forEach((elementRef, index) => {
9153
9196
  setTabIndex(elementRef, this._tabindex + index);
9154
9197
  });
@@ -9420,7 +9463,7 @@ class MatDateShort {
9420
9463
  focus() {
9421
9464
  if (!this._matInput)
9422
9465
  return;
9423
- setTimeout$1(() => {
9466
+ setTimeout(() => {
9424
9467
  if (isFocusableElement(this._matInput.nativeElement)) {
9425
9468
  this._matInput.nativeElement.focus();
9426
9469
  }
@@ -9496,7 +9539,9 @@ class MatDateShort {
9496
9539
  updateTranslations(translations) {
9497
9540
  const datePattern = translations['COMMON.DATE_YEAR_PATTERN'] !== 'COMMON.DATE_YEAR_PATTERN' ? translations['COMMON.DATE_YEAR_PATTERN'] : 'YYYY';
9498
9541
  this.updatePattern(datePattern);
9499
- const yearPlaceholder = translations['COMMON.DATE_YEAR_PLACEHOLDER'] !== 'COMMON.DATE_YEAR_PLACEHOLDER' ? translations['COMMON.DATE_YEAR_PLACEHOLDER'] : datePattern.toLowerCase();
9542
+ const yearPlaceholder = translations['COMMON.DATE_YEAR_PLACEHOLDER'] !== 'COMMON.DATE_YEAR_PLACEHOLDER'
9543
+ ? translations['COMMON.DATE_YEAR_PLACEHOLDER']
9544
+ : datePattern.toLowerCase();
9500
9545
  this.updateMaskOptions(yearPlaceholder);
9501
9546
  }
9502
9547
  updatePattern(pattern) {
@@ -9578,7 +9623,7 @@ class MatDateShort {
9578
9623
  if (isNil(this._tabindex) || this._tabindex === -1)
9579
9624
  return; // skip
9580
9625
  // Focus to input
9581
- setTimeout$1(() => {
9626
+ setTimeout(() => {
9582
9627
  setTabIndex(this._matInput, this._tabindex);
9583
9628
  this.markForCheck();
9584
9629
  });
@@ -9745,7 +9790,7 @@ class MatSwipeField {
9745
9790
  set tabindex(value) {
9746
9791
  if (this._tabindex !== value) {
9747
9792
  this._tabindex = value;
9748
- setTimeout$1(() => this.updateTabIndex());
9793
+ setTimeout(() => this.updateTabIndex());
9749
9794
  }
9750
9795
  }
9751
9796
  get tabindex() {
@@ -9827,7 +9872,7 @@ class MatSwipeField {
9827
9872
  focus() {
9828
9873
  // show slides component
9829
9874
  this.showSlides = true;
9830
- setTimeout$1(() => {
9875
+ setTimeout(() => {
9831
9876
  if (this.prevButton) {
9832
9877
  this.prevButton.focus();
9833
9878
  }
@@ -9870,7 +9915,7 @@ class MatSwipeField {
9870
9915
  this._value = value;
9871
9916
  this.showSlides = isNotNil(this._value);
9872
9917
  this.updateSlides();
9873
- setTimeout$1(() => this.updateTabIndex());
9918
+ setTimeout(() => this.updateTabIndex());
9874
9919
  }
9875
9920
  this._writing = false;
9876
9921
  this.markForCheck();
@@ -9883,10 +9928,10 @@ class MatSwipeField {
9883
9928
  this._value = undefined;
9884
9929
  this.formControl.patchValue(null, { emitEvent: false });
9885
9930
  this.showSlides = false;
9886
- setTimeout$1(() => {
9931
+ setTimeout(() => {
9887
9932
  this.updateTabIndex();
9888
9933
  this.slideTo(0);
9889
- setTimeout$1(() => {
9934
+ setTimeout(() => {
9890
9935
  this._writing = false;
9891
9936
  }, 100);
9892
9937
  });
@@ -11096,6 +11141,65 @@ class TreeItemEntityUtils {
11096
11141
  }
11097
11142
  }
11098
11143
 
11144
+ class AppPropertiesUtils {
11145
+ /**
11146
+ * Converts an array of Property objects to an object map.
11147
+ *
11148
+ * @param {Property[]} [sources] - The array of Property objects to convert.
11149
+ * @param {Object} [opts] - Options for the conversion.
11150
+ * @param {boolean} [opts.omitNilOrBlank] - If set to true, properties with nil or blank values will be omitted from the resulting object.
11151
+ * @return {PropertiesMap} The resulting object map where keys are property keys and values are property values.
11152
+ */
11153
+ static arrayAsObject(sources, opts) {
11154
+ return ((sources || [])
11155
+ // Serialize each item
11156
+ .map(AppPropertyUtils.asObject)
11157
+ // Fill a JSON object
11158
+ .reduce((res, item) => {
11159
+ if (isNilOrBlank(item.key))
11160
+ return res;
11161
+ if (isNilOrBlank(item.value) && opts?.omitNilOrBlank !== false)
11162
+ return res;
11163
+ res[item.key] = item.value;
11164
+ return res;
11165
+ }, {}));
11166
+ }
11167
+ /**
11168
+ * Converts an object into an array of properties.
11169
+ *
11170
+ * @param {PropertiesMap} [source] - The source object containing properties to convert.
11171
+ * @return {Property[]} An array of properties derived from the source object.
11172
+ */
11173
+ static arrayFromObject(source) {
11174
+ if (Array.isArray(source))
11175
+ return source; // Already an array
11176
+ return Object.getOwnPropertyNames(source || {}).map((key) => ({
11177
+ key,
11178
+ value: source[key],
11179
+ }));
11180
+ }
11181
+ }
11182
+ class AppPropertyUtils {
11183
+ static asObject(source) {
11184
+ if (!source)
11185
+ return undefined;
11186
+ // Serialize key (WARNING: can be an object, when using autocomplete field to edit a key - see AppPropertiesForm)
11187
+ const key = source.key?.key ?? source.key;
11188
+ // Serialize the value
11189
+ let value = source.value;
11190
+ if (Array.isArray(value)) {
11191
+ value = value
11192
+ .map((v) => v?.id ?? v)
11193
+ .filter(isNotNil)
11194
+ .join(',');
11195
+ }
11196
+ else {
11197
+ value = value?.id ?? value;
11198
+ }
11199
+ return { key, value };
11200
+ }
11201
+ }
11202
+
11099
11203
  function entityToString(obj, properties) {
11100
11204
  return (obj && obj.id && joinPropertiesPath(obj, properties || ['name'])) || undefined;
11101
11205
  }
@@ -11179,14 +11283,7 @@ class EntityUtils {
11179
11283
  value: source[key],
11180
11284
  }));
11181
11285
  }
11182
- static getPropertyArrayAsObject(source) {
11183
- return (source || []).reduce((res, item) => {
11184
- // Warning: when using <app-properties-form> key can be an object, used by autocomplete field
11185
- const key = typeof item.key === 'object' ? item.key?.key : item.key;
11186
- res[key] = item.value;
11187
- return res;
11188
- }, {});
11189
- }
11286
+ static getPropertyArrayAsObject = AppPropertiesUtils.arrayAsObject;
11190
11287
  static copyIdAndUpdateDate(source, target) {
11191
11288
  if (!source)
11192
11289
  return;
@@ -11560,6 +11657,9 @@ let Peer = class Peer extends Entity {
11560
11657
  .filter(isNotNilOrBlank);
11561
11658
  return [noTrailingSlash(this.fromObject(peer).url)].concat(...paths).join('/');
11562
11659
  }
11660
+ static equals(p1, p2) {
11661
+ return p1 && p2 && Peer_1.fromObject(p1).equals(p2);
11662
+ }
11563
11663
  dns;
11564
11664
  ipv4;
11565
11665
  ipv6;
@@ -11590,7 +11690,13 @@ let Peer = class Peer extends Entity {
11590
11690
  this.path = source.path || '';
11591
11691
  }
11592
11692
  equals(other) {
11593
- return super.equals(other) && this.pubkey === other.pubkey && this.url === other.url;
11693
+ return (
11694
+ // Same entity (by id)
11695
+ (isNotNil(this.id) && isNotNil(other.id) && this.id === other.id) ||
11696
+ // Same pubkey (if defined)
11697
+ ((!this.pubkey || !other.pubkey || this.pubkey === other.pubkey) &&
11698
+ // Same url
11699
+ this.url === other.url));
11594
11700
  }
11595
11701
  /**
11596
11702
  * Return the peer URL (without trailing slash)
@@ -13278,7 +13384,7 @@ class AppFormField {
13278
13384
  return;
13279
13385
  this._onDefinitionChanged(this._definition);
13280
13386
  if (this.autocompleteField) {
13281
- setTimeout$1(() => this.autocompleteField?.reloadItems(value));
13387
+ setTimeout(() => this.autocompleteField?.reloadItems(value));
13282
13388
  }
13283
13389
  }
13284
13390
  /* -- protected method -- */
@@ -13356,7 +13462,7 @@ class AppFormField {
13356
13462
  }
13357
13463
  updateTabIndex(timeout) {
13358
13464
  if (this.tabindex && this.tabindex !== -1) {
13359
- setTimeout$1(() => {
13465
+ setTimeout(() => {
13360
13466
  const element = asInputElement(this.matInput);
13361
13467
  if (element) {
13362
13468
  element.tabIndex = this.tabindex;
@@ -13681,16 +13787,17 @@ class HotkeysDialogComponent {
13681
13787
  this.hotkeys = Array.from(this.data);
13682
13788
  }
13683
13789
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: HotkeysDialogComponent, deps: [{ token: MAT_DIALOG_DATA }], target: i0.ɵɵFactoryTarget.Component });
13684
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.8", type: HotkeysDialogComponent, selector: "ng-component", ngImport: i0, template: "<table>\n <tbody>\n <tr *ngFor=\"let keys of hotkeys\">\n <td>{{ keys[1] | translate }}</td>\n\n <td class=\"text-right\">\n <kbd>{{ keys[0] }}</kbd>\n </td>\n </tr>\n </tbody>\n</table>\n", styles: [":host table{border-collapse:collapse;width:100%;margin-bottom:1rem;color:#212529}:host th{font-weight:500;text-align:left;vertical-align:bottom;padding:.75rem;border-top:1px solid #dee2e6;border-bottom:2px solid #dee2e6}:host td{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6;padding-left:0}:host kbd{margin-right:6px;background-color:#fafbfc;border:1px solid #d1d5da;border-bottom-color:#c6cbd1;border-radius:3px;box-shadow:inset 0 -1px #c6cbd1;color:#444d56;display:inline-block;font-size:12px;line-height:10px;padding:3px 5px;vertical-align:middle}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }] });
13790
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.8", type: HotkeysDialogComponent, selector: "ng-component", ngImport: i0, template: "<table class=\"ion-padding\">\n <tbody>\n <tr *ngFor=\"let keys of hotkeys\">\n <td>{{ keys[1] | translate }}</td>\n\n <td class=\"text-right\">\n <kbd>{{ keys[0] }}</kbd>\n </td>\n </tr>\n </tbody>\n</table>\n", styles: [":host table{border-collapse:collapse;width:100%;color:#212529}:host th{font-weight:500;text-align:left;vertical-align:bottom;padding:.75rem;border-top:1px solid #dee2e6;border-bottom:2px solid #dee2e6}:host td{vertical-align:top;border-top:1px solid #dee2e6;padding:.75rem}:host kbd{margin-right:6px;background-color:#fafbfc;border:1px solid #d1d5da;border-bottom-color:#c6cbd1;border-radius:3px;box-shadow:inset 0 -1px #c6cbd1;color:#444d56;display:inline-block;font-size:12px;line-height:10px;padding:3px 5px;vertical-align:middle}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }] });
13685
13791
  }
13686
13792
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: HotkeysDialogComponent, decorators: [{
13687
13793
  type: Component,
13688
- args: [{ template: "<table>\n <tbody>\n <tr *ngFor=\"let keys of hotkeys\">\n <td>{{ keys[1] | translate }}</td>\n\n <td class=\"text-right\">\n <kbd>{{ keys[0] }}</kbd>\n </td>\n </tr>\n </tbody>\n</table>\n", styles: [":host table{border-collapse:collapse;width:100%;margin-bottom:1rem;color:#212529}:host th{font-weight:500;text-align:left;vertical-align:bottom;padding:.75rem;border-top:1px solid #dee2e6;border-bottom:2px solid #dee2e6}:host td{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6;padding-left:0}:host kbd{margin-right:6px;background-color:#fafbfc;border:1px solid #d1d5da;border-bottom-color:#c6cbd1;border-radius:3px;box-shadow:inset 0 -1px #c6cbd1;color:#444d56;display:inline-block;font-size:12px;line-height:10px;padding:3px 5px;vertical-align:middle}\n"] }]
13794
+ args: [{ template: "<table class=\"ion-padding\">\n <tbody>\n <tr *ngFor=\"let keys of hotkeys\">\n <td>{{ keys[1] | translate }}</td>\n\n <td class=\"text-right\">\n <kbd>{{ keys[0] }}</kbd>\n </td>\n </tr>\n </tbody>\n</table>\n", styles: [":host table{border-collapse:collapse;width:100%;color:#212529}:host th{font-weight:500;text-align:left;vertical-align:bottom;padding:.75rem;border-top:1px solid #dee2e6;border-bottom:2px solid #dee2e6}:host td{vertical-align:top;border-top:1px solid #dee2e6;padding:.75rem}:host kbd{margin-right:6px;background-color:#fafbfc;border:1px solid #d1d5da;border-bottom-color:#c6cbd1;border-radius:3px;box-shadow:inset 0 -1px #c6cbd1;color:#444d56;display:inline-block;font-size:12px;line-height:10px;padding:3px 5px;vertical-align:middle}\n"] }]
13689
13795
  }], ctorParameters: () => [{ type: undefined, decorators: [{
13690
13796
  type: Inject,
13691
13797
  args: [MAT_DIALOG_DATA]
13692
13798
  }] }] });
13693
13799
 
13800
+ const APP_HOTKEYS_CONFIG = new InjectionToken('HotKeysConfig');
13694
13801
  class Hotkeys {
13695
13802
  eventManager;
13696
13803
  dialog;
@@ -13703,14 +13810,24 @@ class Hotkeys {
13703
13810
  element: this._document,
13704
13811
  preventDefault: true,
13705
13812
  };
13706
- constructor(eventManager, dialog, modalController, popoverController) {
13813
+ _dialogRef;
13814
+ _config;
13815
+ constructor(eventManager, dialog, modalController, popoverController, config) {
13707
13816
  this.eventManager = eventManager;
13708
13817
  this.dialog = dialog;
13709
13818
  this.modalController = modalController;
13710
13819
  this.popoverController = popoverController;
13711
- if (this._debug)
13712
- console.debug('[hotkeys] Starting hotkeys service... Press Shift+? to get help modal.');
13713
- this.addShortcut({ keys: 'shift.?' }).subscribe(() => this.openHelpModal());
13820
+ this._config = {
13821
+ enableHelpModal: true,
13822
+ openHelpModalShortcut: 'F1',
13823
+ ...config,
13824
+ };
13825
+ // Add shortcut to open help modal
13826
+ if (this._config.enableHelpModal) {
13827
+ this.addShortcut({ keys: this._config.openHelpModalShortcut }).subscribe(() => this.openHelpModal());
13828
+ if (this._debug)
13829
+ console.debug(`[hotkeys] Starting hotkeys service... Press ${this._config.openHelpModalShortcut} to get help modal.`);
13830
+ }
13714
13831
  // For DEV only
13715
13832
  //this._debug = !environment.production;
13716
13833
  }
@@ -13751,12 +13868,23 @@ class Hotkeys {
13751
13868
  });
13752
13869
  }
13753
13870
  openHelpModal() {
13754
- this.dialog.open(HotkeysDialogComponent, {
13871
+ if (this._dialogRef) {
13872
+ this._dialogRef.close(true);
13873
+ return;
13874
+ }
13875
+ this._dialogRef = this.dialog.open(HotkeysDialogComponent, {
13755
13876
  width: '500px',
13756
13877
  data: this._hotkeys,
13757
13878
  });
13879
+ this._dialogRef
13880
+ .afterClosed()
13881
+ .pipe(first())
13882
+ .subscribe(() => {
13883
+ // Forget the dialog ref
13884
+ this._dialogRef = null;
13885
+ });
13758
13886
  }
13759
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: Hotkeys, deps: [{ token: i1$2.EventManager }, { token: i2$4.MatDialog }, { token: i2$1.ModalController }, { token: i2$1.PopoverController }], target: i0.ɵɵFactoryTarget.Injectable });
13887
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: Hotkeys, deps: [{ token: i1$2.EventManager }, { token: i2$4.MatDialog }, { token: i2$1.ModalController }, { token: i2$1.PopoverController }, { token: APP_HOTKEYS_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
13760
13888
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: Hotkeys, providedIn: 'root' });
13761
13889
  }
13762
13890
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: Hotkeys, decorators: [{
@@ -13764,7 +13892,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImpor
13764
13892
  args: [{
13765
13893
  providedIn: 'root',
13766
13894
  }]
13767
- }], ctorParameters: () => [{ type: i1$2.EventManager }, { type: i2$4.MatDialog }, { type: i2$1.ModalController }, { type: i2$1.PopoverController }] });
13895
+ }], ctorParameters: () => [{ type: i1$2.EventManager }, { type: i2$4.MatDialog }, { type: i2$1.ModalController }, { type: i2$1.PopoverController }, { type: undefined, decorators: [{
13896
+ type: Optional
13897
+ }, {
13898
+ type: Inject,
13899
+ args: [APP_HOTKEYS_CONFIG]
13900
+ }] }] });
13768
13901
 
13769
13902
  class SharedHotkeysModule {
13770
13903
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: SharedHotkeysModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
@@ -16418,7 +16551,7 @@ class TextPopover {
16418
16551
  this.enable();
16419
16552
  }
16420
16553
  ngAfterViewInit() {
16421
- setTimeout$1(() => this.form.setValue({ text: this.text }), 0);
16554
+ setTimeout(() => this.form.setValue({ text: this.text }), 0);
16422
16555
  }
16423
16556
  async onValidate(event) {
16424
16557
  await waitWhilePending(this.form);
@@ -16871,7 +17004,9 @@ class NetworkService extends StartableObservableService {
16871
17004
  return this.dataSubject.value?.clone();
16872
17005
  }
16873
17006
  set peer(peer) {
16874
- this.restart(peer);
17007
+ if (!Peer.equals(this.peer, peer)) {
17008
+ this.restart(peer);
17009
+ }
16875
17010
  }
16876
17011
  get connectionTimeout() {
16877
17012
  return this._connectionTimeout;
@@ -17013,7 +17148,7 @@ class NetworkService extends StartableObservableService {
17013
17148
  if (online) {
17014
17149
  // Call success callback (async)
17015
17150
  if (opts && opts.onRetrySuccess) {
17016
- setTimeout$1(opts.onRetrySuccess);
17151
+ setTimeout(opts.onRetrySuccess);
17017
17152
  }
17018
17153
  return true;
17019
17154
  }
@@ -19630,7 +19765,7 @@ class AccountService extends BaseGraphqlService {
19630
19765
  this.onAuthTokenChange.subscribe((token) => this.graphql.setAuthToken(token));
19631
19766
  this.onAuthBasicChange.subscribe((basic) => this.graphql.setAuthBasic(basic));
19632
19767
  // Force network to wait account service, after getting connection to the peer
19633
- this.network.on('beforeTryOnlineFinish', async (online) => {
19768
+ this.registerSubscription(this.network.on('beforeTryOnlineFinish', async (online) => {
19634
19769
  // If online, wait a full restart, because it can force offline mode
19635
19770
  if (online && (!this.started || this.isLogin())) {
19636
19771
  console.debug('[account] Force networkService.tryOnline() to wait, that graphql and account service is restarted...');
@@ -19638,7 +19773,7 @@ class AccountService extends BaseGraphqlService {
19638
19773
  if (!this.started)
19639
19774
  await this.ready();
19640
19775
  }
19641
- });
19776
+ }));
19642
19777
  }
19643
19778
  async ngOnStart() {
19644
19779
  await Promise.all([
@@ -20997,7 +21132,7 @@ class ConfigService extends BaseGraphqlService {
20997
21132
  }
20998
21133
  // Save it into local storage, for next startup
20999
21134
  if (data) {
21000
- setTimeout$1(() => this.storeLocally(data), 2000);
21135
+ setTimeout(() => this.storeLocally(data), 2000);
21001
21136
  }
21002
21137
  // If not loaded remotely: try to restore it
21003
21138
  else {
@@ -21322,7 +21457,7 @@ class PlatformService extends StartableService {
21322
21457
  }));
21323
21458
  if (this._mobile) {
21324
21459
  // Hide the splashscreen (if mobile) - after 1s - and play start sound
21325
- setTimeout$1(async () => {
21460
+ setTimeout(async () => {
21326
21461
  await SplashScreen.hide();
21327
21462
  // Play startup sound
21328
21463
  this.audioProvider.playStartupSound();
@@ -21978,7 +22113,7 @@ class ToolbarComponent {
21978
22113
  async toggleSearchBar() {
21979
22114
  this.showSearchBar = !this.showSearchBar;
21980
22115
  if (this.showSearchBar && this.searchbar) {
21981
- setTimeout$1(() => {
22116
+ setTimeout(() => {
21982
22117
  this.searchbar.setFocus();
21983
22118
  this.markForCheck();
21984
22119
  }, 300);
@@ -22030,7 +22165,7 @@ class ToolbarComponent {
22030
22165
  return;
22031
22166
  // Distinguish simple and double tap
22032
22167
  this._closeTapCount = event.tapCount;
22033
- setTimeout$1(() => {
22168
+ setTimeout(() => {
22034
22169
  // Event is obsolete (a new tap event occur)
22035
22170
  if (event.tapCount < this._closeTapCount) {
22036
22171
  // Ignore event
@@ -22052,7 +22187,7 @@ class ToolbarComponent {
22052
22187
  // Distinguish simple and double tap
22053
22188
  else {
22054
22189
  this._validateTapCount = event.tapCount;
22055
- setTimeout$1(() => {
22190
+ setTimeout(() => {
22056
22191
  // Event is obsolete (a new tap event occur)
22057
22192
  if (event.tapCount < this._validateTapCount) {
22058
22193
  // Ignore event
@@ -23959,7 +24094,7 @@ class AppImageGalleryComponent {
23959
24094
  this.onAfterEditRow.emit(row);
23960
24095
  }
23961
24096
  // Hide the toolbar, because the focus have been given to the event's origin (the edit button)
23962
- setTimeout$1(() => this.hideCardToolbar(cardToolbar), 750);
24097
+ setTimeout(() => this.hideCardToolbar(cardToolbar), 750);
23963
24098
  }
23964
24099
  showCardToolbar(cardToolbar) {
23965
24100
  const el = cardToolbar['el'];
@@ -26151,7 +26286,7 @@ class MenuService extends StartableObservableService {
26151
26286
  handler: () => {
26152
26287
  this.accountService.logout();
26153
26288
  // Back to home
26154
- setTimeout$1(() => this.navController.navigateRoot('/'), 100);
26289
+ setTimeout(() => this.navController.navigateRoot('/'), 100);
26155
26290
  },
26156
26291
  },
26157
26292
  ],
@@ -26678,7 +26813,7 @@ class MenuComponent {
26678
26813
  this.splitPane.when = value;
26679
26814
  this.detectChanges();
26680
26815
  // Propagate to the menu service
26681
- setTimeout$1(() => this.menuService.setSplitPaneShowWhen(value), 200);
26816
+ setTimeout(() => this.menuService.setSplitPaneShowWhen(value), 200);
26682
26817
  }
26683
26818
  }
26684
26819
  toggleSplitPaneShow(event) {
@@ -26718,7 +26853,7 @@ class MenuComponent {
26718
26853
  }
26719
26854
  markAsLoaded(opts) {
26720
26855
  if (this.loading) {
26721
- setTimeout$1(() => {
26856
+ setTimeout(() => {
26722
26857
  this.loading = false;
26723
26858
  if (!opts || opts.emitEvent !== false)
26724
26859
  this.markForCheck();
@@ -27943,7 +28078,7 @@ class AppAuthForm extends AppForm {
27943
28078
  const data = this.form.value;
27944
28079
  this.showPwd = false; // Hide password
27945
28080
  this.error = null; // Reset error
27946
- setTimeout$1(() => this.onSubmit.emit({
28081
+ setTimeout(() => this.onSubmit.emit({
27947
28082
  username: data.username,
27948
28083
  password: data.password,
27949
28084
  offline: data.offline,
@@ -27951,7 +28086,7 @@ class AppAuthForm extends AppForm {
27951
28086
  }
27952
28087
  register() {
27953
28088
  this.onCancel.emit();
27954
- setTimeout$1(async () => {
28089
+ setTimeout(async () => {
27955
28090
  const modal = await this.modalCtrl.create({
27956
28091
  component: RegisterModal,
27957
28092
  backdropDismiss: false,
@@ -27962,7 +28097,7 @@ class AppAuthForm extends AppForm {
27962
28097
  resetPassword() {
27963
28098
  this.onCancel.emit();
27964
28099
  const data = this.form.value;
27965
- setTimeout$1(async () => {
28100
+ setTimeout(async () => {
27966
28101
  const modal = await this.modalCtrl.create({
27967
28102
  component: AppResetPasswordModal,
27968
28103
  componentProps: {
@@ -28588,15 +28723,16 @@ class LocalSettingsValidatorService extends AppValidatorService {
28588
28723
  });
28589
28724
  }
28590
28725
  getPropertiesArray(data) {
28591
- const propertiesFormArray = new AppFormArray((value) => this.propertyValidator.getFormGroup(value, { valueMaxLength: 2000 }), (v1, v2) => this.propertyValidator.equals(v1, v2), (value) => this.propertyValidator.isEmpty(value), {
28726
+ const fromArray = new AppFormArray((value) => this.propertyValidator.getFormGroup(value, { valueMaxLength: 2000 }), (v1, v2) => this.propertyValidator.equals(v1, v2), (value) => this.propertyValidator.isEmpty(value), {
28592
28727
  allowReuseControls: false,
28593
28728
  allowEmptyArray: true,
28594
28729
  });
28595
28730
  if (data) {
28596
- const values = EntityUtils.getMapAsArray(data);
28597
- propertiesFormArray.patchValue(values);
28731
+ const values = AppPropertiesUtils.arrayFromObject(data);
28732
+ if (isNotEmptyArray(values))
28733
+ fromArray.patchValue(values);
28598
28734
  }
28599
- return propertiesFormArray;
28735
+ return fromArray;
28600
28736
  }
28601
28737
  getPropertyFormGroup(data) {
28602
28738
  return this.formBuilder.group({
@@ -29075,7 +29211,7 @@ class SettingsPage extends AppForm {
29075
29211
  // Apply inheritance
29076
29212
  this.setAccountInheritance(data.accountInheritance, { emitEvent: false });
29077
29213
  // Add a delay, because of option menu that is always opened after save!!
29078
- setTimeout$1(() => {
29214
+ setTimeout(() => {
29079
29215
  this.saving = false;
29080
29216
  this.markForCheck();
29081
29217
  }, 400);
@@ -29165,7 +29301,7 @@ class SettingsPage extends AppForm {
29165
29301
  }
29166
29302
  async getValue() {
29167
29303
  const json = this.form.value;
29168
- json.properties = EntityUtils.getPropertyArrayAsObject(json.properties);
29304
+ json.properties = AppPropertiesUtils.arrayAsObject(json.properties);
29169
29305
  // Override properties from account
29170
29306
  if (json.accountInheritance && this.isLogin) {
29171
29307
  const account = this.accountService.account;
@@ -29219,11 +29355,11 @@ class SettingsPage extends AppForm {
29219
29355
  this.cd.markForCheck();
29220
29356
  }
29221
29357
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: SettingsPage, deps: [{ token: i0.Injector }, { token: PlatformService }, { token: i2$1.NavController }, { token: LocalSettingsValidatorService }, { token: i2$1.AlertController }, { token: i1$1.TranslateService }, { token: i1$3.UntypedFormBuilder }, { token: AccountService }, { token: LocalSettingsService }, { token: i0.ChangeDetectorRef }, { token: NetworkService }, { token: APP_LOCALES }, { token: APP_SETTINGS_MENU_ITEMS, optional: true }], target: i0.ɵɵFactoryTarget.Component });
29222
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.8", type: SettingsPage, selector: "page-settings", providers: [{ provide: ValidatorService, useExisting: LocalSettingsValidatorService }], viewQueries: [{ propertyName: "propertiesForm", first: true, predicate: ["propertiesForm"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<app-toolbar\n [title]=\"'SETTINGS.TITLE' | translate\"\n color=\"primary\"\n [hasValidate]=\"dirty && !saving\"\n [hasClose]=\"!dirty && !saving\"\n (onValidate)=\"save($event)\"\n (onClose)=\"close($event)\"\n>\n <ion-buttons slot=\"end\">\n <!-- options menu -->\n <ion-button [matMenuTriggerFor]=\"optionsMenu\">\n <mat-icon slot=\"icon-only\">more_vert</mat-icon>\n </ion-button>\n </ion-buttons>\n</app-toolbar>\n\n<!-- Options menu -->\n<mat-menu #optionsMenu=\"matMenu\">\n <!-- Clear cache -->\n <button mat-menu-item [disabled]=\"saving\" (click)=\"clearCache($event)\">\n <mat-icon><ion-icon name=\"trash-outline\"></ion-icon></mat-icon>\n <ion-label translate>SETTINGS.BTN_CLEAR_CACHE</ion-label>\n </button>\n\n <!-- Reset -->\n <button mat-menu-item [disabled]=\"saving || !dirty\" (click)=\"cancel($event)\">\n <mat-icon><ion-icon name=\"refresh\"></ion-icon></mat-icon>\n <mat-label translate>COMMON.BTN_RESET</mat-label>\n </button>\n\n <!-- additional items -->\n @if (!loading) {\n @for (item of menuItems; track item) {\n @if (item.path) {\n <a mat-menu-item class=\"{{ item.cssClass }} {{ item.color }}\" (click)=\"executeAction($event, item)\">\n <mat-icon *ngIf=\"item.icon\"><ion-icon [name]=\"item.icon\"></ion-icon></mat-icon>\n <mat-icon *ngIf=\"item.matIcon\">{{ item.matIcon }}</mat-icon>\n <mat-label translate>{{ item.title }}</mat-label>\n </a>\n } @else if (!item.action) {\n <!-- divider -->\n <mat-divider class=\"{{ item.cssClass }} {{ item.color }}\">\n <mat-label translate>{{ item.title }}</mat-label>\n </mat-divider>\n }\n }\n }\n</mat-menu>\n\n<ion-content>\n <form [formGroup]=\"form\" novalidate (ngSubmit)=\"save($event)\" class=\"form-container\">\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <!-- left margin -->\n <ion-col size=\"0\" size-lg=\"1\" size-xl=\"2\">&nbsp;</ion-col>\n\n <ion-col class=\"ion-padding\">\n <!-- error -->\n <ion-item *ngIf=\"error\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error | translate\"></ion-label>\n </ion-item>\n\n <ion-list-header class=\"hidden-xs hidden-xxs\" translate>SETTINGS.DESCRIPTION</ion-list-header>\n\n <ion-list [inset]=\"mobile\">\n <ion-item lines=\"none\">\n <!-- account inheritance (desktop) -->\n @if (!mobile) {\n <mat-form-field [hidden]=\"!isLogin\">\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\" />\n\n <!-- check box (if desktop) -->\n <mat-checkbox (change)=\"setAccountInheritance($event.checked)\" [checked]=\"accountInheritance\">\n <span translate>SETTINGS.INHERIT_FROM_ACCOUNT</span>\n </mat-checkbox>\n\n <mat-error *ngIf=\"form.controls.accountInheritance.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n } @else {\n <!-- account inheritance (if mobile) -->\n <mat-form-field [hidden]=\"!isLogin\">\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\" />\n\n <!-- slide toggle -->\n <ion-text translate>SETTINGS.INHERIT_FROM_ACCOUNT</ion-text>\n <mat-slide-toggle\n matSuffix\n (change)=\"setAccountInheritance($event.checked)\"\n [checked]=\"accountInheritance\"\n ></mat-slide-toggle>\n <mat-error *ngIf=\"form.controls.accountInheritance.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n }\n </ion-item>\n </ion-list>\n\n @if (settings.enableDarkMode) {\n <ion-list-header><h3 translate>SETTINGS.DISPLAY_DIVIDER</h3></ion-list-header>\n\n <ion-list [inset]=\"mobile\">\n <!-- locale -->\n <ion-item lines=\"none\">\n <mat-form-field>\n <ion-icon matPrefix name=\"language\"></ion-icon>\n <mat-label>{{ 'SETTINGS.LOCALE' | translate }}</mat-label>\n <mat-select formControlName=\"locale\" required>\n <mat-option *ngFor=\"let item of locales\" [value]=\"item.key\">\n {{ item.value }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.locale.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n </ion-item>\n\n <!-- dark mode -->\n <ion-item lines=\"none\">\n <!-- dark mode (if mobile) -->\n <mat-form-field>\n <ion-icon matPrefix name=\"moon\"></ion-icon>\n\n <input matInput hidden formControlName=\"darkMode\" type=\"text\" />\n\n <!-- slide toggle -->\n <ion-text translate>SETTINGS.BTN_DARK_MODE</ion-text>\n <mat-slide-toggle\n matSuffix\n (change)=\"toggleDarkMode($event.checked)\"\n [checked]=\"darkMode\"\n ></mat-slide-toggle>\n </mat-form-field>\n </ion-item>\n </ion-list>\n }\n\n <!-- Network entry -->\n <ion-list-header><h3 translate>SETTINGS.NETWORK_DIVIDER</h3></ion-list-header>\n\n <ion-list [inset]=\"mobile\">\n <!-- Peer address -->\n <ion-item lines=\"none\">\n <mat-form-field>\n <ion-icon matPrefix name=\"cloud\"></ion-icon>\n\n <mat-label>{{ 'SETTINGS.PEER_URL' | translate }}</mat-label>\n <input matInput type=\"text\" formControlName=\"peerUrl\" required />\n\n <button\n mat-icon-button\n type=\"button\"\n matSuffix\n (click)=\"showSelectPeerModal()\"\n tabindex=\"-1\"\n [title]=\"'SETTINGS.BTN_CHANGE_PEER' | translate\"\n >\n <mat-icon>search</mat-icon>\n </button>\n\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('peerAlive')\" translate>\n SETTINGS.ERROR.PEER_NOT_REACHABLE\n </mat-error>\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('peerNotCompatible')\" translate>\n SETTINGS.ERROR.PEER_NOT_COMPATIBLE\n </mat-error>\n </mat-form-field>\n </ion-item>\n\n <!-- Offline mode (if mobile) -->\n @if (mobile) {\n <ion-item lines=\"none\">\n <mat-form-field>\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\" />\n\n <!-- slide toggle -->\n <ion-text translate>SETTINGS.OFFLINE_MODE</ion-text>\n <mat-slide-toggle\n matSuffix\n (change)=\"network.setForceOffline($event.checked)\"\n [checked]=\"network.offline\"\n ></mat-slide-toggle>\n </mat-form-field>\n </ion-item>\n }\n </ion-list>\n\n <!-- Data entry -->\n <ion-list-header>\n <h3 translate>SETTINGS.DATA_ENTRY_DIVIDER</h3>\n </ion-list-header>\n\n <ion-list [inset]=\"mobile\">\n <!-- Usage mode -->\n <ion-item lines=\"none\">\n <mat-form-field>\n <ion-icon matPrefix name=\"id-card\"></ion-icon>\n <mat-label>{{ 'SETTINGS.USAGE_MODE' | translate }}</mat-label>\n <mat-select formControlName=\"usageMode\" required>\n <mat-option *ngFor=\"let item of usageModes\" [value]=\"item\">\n {{ 'SETTINGS.USAGE_MODES.' + item | translate }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.usageMode.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n </ion-item>\n\n <!-- lat/long format-->\n <ion-item lines=\"none\">\n <mat-form-field>\n <ion-icon matPrefix name=\"locate\"></ion-icon>\n <mat-label>{{ 'SETTINGS.LAT_LONG_FORMAT' | translate }}</mat-label>\n <mat-select formControlName=\"latLongFormat\" required>\n <mat-option *ngFor=\"let item of latLongFormats\" [value]=\"item\">\n {{ 'COMMON.LAT_LONG.' + item + '_PLACEHOLDER' | translate }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.latLongFormat.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n </ion-item>\n </ion-list>\n\n <!-- fields options -->\n <app-properties-form\n #propertiesForm\n formArrayName=\"properties\"\n [definitions]=\"propertyDefinitions\"\n [options]=\"{ allowEmptyArray: true }\"\n [mobile]=\"mobile\"\n [showAddButton]=\"!mobile\"\n [showHintKey]=\"isAdmin\"\n ></app-properties-form>\n </ion-col>\n\n <!-- right margin -->\n <ion-col size=\"0\" size-lg=\"1\" size-xl=\"2\">&nbsp;</ion-col>\n </ion-row>\n </ion-grid>\n </form>\n</ion-content>\n\n<ion-footer hidden-xs hidden-sm hidden-mobile>\n <app-form-buttons-bar\n (onCancel)=\"cancel()\"\n (onSave)=\"save($event)\"\n [disabled]=\"!form.dirty || saving\"\n ></app-form-buttons-bar>\n</ion-footer>\n", dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2$1.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i2$1.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i2$1.IonCol, selector: "ion-col", inputs: ["offset", "offsetLg", "offsetMd", "offsetSm", "offsetXl", "offsetXs", "pull", "pullLg", "pullMd", "pullSm", "pullXl", "pullXs", "push", "pushLg", "pushMd", "pushSm", "pushXl", "pushXs", "size", "sizeLg", "sizeMd", "sizeSm", "sizeXl", "sizeXs"] }, { kind: "component", type: i2$1.IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i2$1.IonFooter, selector: "ion-footer", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i2$1.IonGrid, selector: "ion-grid", inputs: ["fixed"] }, { kind: "component", type: i2$1.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i2$1.IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i2$1.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i2$1.IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: i2$1.IonListHeader, selector: "ion-list-header", inputs: ["color", "lines", "mode"] }, { kind: "component", type: i2$1.IonRow, selector: "ion-row" }, { kind: "component", type: i2$1.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "directive", type: i1$3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$3.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i6.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i4.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i5.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i9.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i8$1.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i8$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i8$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: i12.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i2.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i9$1.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "component", type: i12$3.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "component", type: ToolbarComponent, selector: "app-toolbar", inputs: ["progressBarMode", "title", "color", "class", "backHref", "defaultBackHref", "hasValidate", "hasClose", "hasSearch", "canGoBack", "canShowMenu"], outputs: ["onValidate", "onClose", "onValidateAndClose", "onBackClick", "onSearch"] }, { kind: "component", type: FormButtonsBarComponent, selector: "app-form-buttons-bar", inputs: ["disabled", "disabledCancel", "disabledEscape", "classList", "saveButtonColor", "backText", "cancelText", "nextText", "showBack", "showCancel", "showNext", "showSave"], outputs: ["onCancel", "onSave", "onNext", "onBack", "onSaveAndClose", "onSaveAndNext"] }, { kind: "component", type: AppPropertiesForm, selector: "app-properties-form", inputs: ["formArrayName", "formArray", "options", "chipColor", "mobile", "appearance", "subscriptSizing", "showHintKey", "hintKeyPrefix", "showMoreButton", "showMoreButtonTitle", "showAddButton", "definitions"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
29358
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.8", type: SettingsPage, selector: "page-settings", providers: [{ provide: ValidatorService, useExisting: LocalSettingsValidatorService }], viewQueries: [{ propertyName: "propertiesForm", first: true, predicate: ["propertiesForm"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<app-toolbar\n [title]=\"'SETTINGS.TITLE' | translate\"\n color=\"primary\"\n [hasValidate]=\"dirty && !saving\"\n [hasClose]=\"!dirty && !saving\"\n (onValidate)=\"save($event)\"\n (onClose)=\"close($event)\"\n>\n <ion-buttons slot=\"end\">\n <!-- options menu -->\n <ion-button [matMenuTriggerFor]=\"optionsMenu\">\n <mat-icon slot=\"icon-only\">more_vert</mat-icon>\n </ion-button>\n </ion-buttons>\n</app-toolbar>\n\n<!-- Options menu -->\n<mat-menu #optionsMenu=\"matMenu\">\n <!-- Clear cache -->\n <button mat-menu-item [disabled]=\"saving\" (click)=\"clearCache($event)\">\n <mat-icon><ion-icon name=\"trash-outline\"></ion-icon></mat-icon>\n <ion-label translate>SETTINGS.BTN_CLEAR_CACHE</ion-label>\n </button>\n\n <!-- Reset -->\n <button mat-menu-item [disabled]=\"saving || !dirty\" (click)=\"cancel($event)\">\n <mat-icon><ion-icon name=\"refresh\"></ion-icon></mat-icon>\n <mat-label translate>COMMON.BTN_RESET</mat-label>\n </button>\n\n <!-- additional items -->\n @if (!loading) {\n @for (item of menuItems; track item) {\n @if (item.path) {\n <a mat-menu-item class=\"{{ item.cssClass }} {{ item.color }}\" (click)=\"executeAction($event, item)\">\n <mat-icon *ngIf=\"item.icon\"><ion-icon [name]=\"item.icon\"></ion-icon></mat-icon>\n <mat-icon *ngIf=\"item.matIcon\">{{ item.matIcon }}</mat-icon>\n <mat-label translate>{{ item.title }}</mat-label>\n </a>\n } @else if (!item.action) {\n <!-- divider -->\n <mat-divider class=\"{{ item.cssClass }} {{ item.color }}\">\n <mat-label translate>{{ item.title }}</mat-label>\n </mat-divider>\n }\n }\n }\n</mat-menu>\n\n<ion-content>\n <form [formGroup]=\"form\" novalidate (ngSubmit)=\"save($event)\" class=\"form-container\">\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <!-- left margin -->\n <ion-col size=\"0\" size-lg=\"1\" size-xl=\"2\">&nbsp;</ion-col>\n\n <ion-col class=\"ion-padding\">\n <!-- error -->\n <ion-item *ngIf=\"error\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error | translate\"></ion-label>\n </ion-item>\n\n <ion-list-header class=\"hidden-xs hidden-xxs\" translate>SETTINGS.DESCRIPTION</ion-list-header>\n\n <ion-list [inset]=\"mobile\">\n <ion-item lines=\"none\">\n <!-- account inheritance (desktop) -->\n @if (!mobile) {\n <mat-form-field [hidden]=\"!isLogin\">\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\" />\n\n <!-- check box (if desktop) -->\n <mat-checkbox (change)=\"setAccountInheritance($event.checked)\" [checked]=\"accountInheritance\">\n <span translate>SETTINGS.INHERIT_FROM_ACCOUNT</span>\n </mat-checkbox>\n\n <mat-error *ngIf=\"form.controls.accountInheritance.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n } @else {\n <!-- account inheritance (if mobile) -->\n <mat-form-field [hidden]=\"!isLogin\">\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\" />\n\n <!-- slide toggle -->\n <ion-text translate>SETTINGS.INHERIT_FROM_ACCOUNT</ion-text>\n <mat-slide-toggle\n matSuffix\n (change)=\"setAccountInheritance($event.checked)\"\n [checked]=\"accountInheritance\"\n ></mat-slide-toggle>\n <mat-error *ngIf=\"form.controls.accountInheritance.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n }\n </ion-item>\n </ion-list>\n\n @if (settings.enableDarkMode) {\n <ion-list-header><h3 translate>SETTINGS.DISPLAY_DIVIDER</h3></ion-list-header>\n\n <ion-list [inset]=\"mobile\">\n <!-- locale -->\n <ion-item lines=\"none\">\n <mat-form-field>\n <ion-icon matPrefix name=\"language\"></ion-icon>\n <mat-label>{{ 'SETTINGS.LOCALE' | translate }}</mat-label>\n <mat-select formControlName=\"locale\" required>\n <mat-option *ngFor=\"let item of locales\" [value]=\"item.key\">\n {{ item.value }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.locale.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n </ion-item>\n\n <!-- dark mode -->\n <ion-item lines=\"none\">\n <mat-form-field>\n <ion-icon matPrefix name=\"moon\"></ion-icon>\n\n <input matInput hidden formControlName=\"darkMode\" type=\"text\" />\n\n <!-- slide toggle -->\n <ion-text translate>SETTINGS.BTN_DARK_MODE</ion-text>\n <mat-slide-toggle\n matSuffix\n (change)=\"toggleDarkMode($event.checked)\"\n [checked]=\"darkMode\"\n ></mat-slide-toggle>\n </mat-form-field>\n </ion-item>\n </ion-list>\n }\n\n <!-- Network entry -->\n <ion-list-header><h3 translate>SETTINGS.NETWORK_DIVIDER</h3></ion-list-header>\n\n <ion-list [inset]=\"mobile\">\n <!-- Peer address -->\n <ion-item lines=\"none\">\n <mat-form-field>\n <ion-icon matPrefix name=\"cloud\"></ion-icon>\n\n <mat-label>{{ 'SETTINGS.PEER_URL' | translate }}</mat-label>\n <input matInput type=\"text\" formControlName=\"peerUrl\" required />\n\n <button\n mat-icon-button\n type=\"button\"\n matSuffix\n (click)=\"showSelectPeerModal()\"\n tabindex=\"-1\"\n [title]=\"'SETTINGS.BTN_CHANGE_PEER' | translate\"\n >\n <mat-icon>search</mat-icon>\n </button>\n\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('peerAlive')\" translate>\n SETTINGS.ERROR.PEER_NOT_REACHABLE\n </mat-error>\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('peerNotCompatible')\" translate>\n SETTINGS.ERROR.PEER_NOT_COMPATIBLE\n </mat-error>\n </mat-form-field>\n </ion-item>\n\n <!-- Offline mode (if mobile) -->\n @if (mobile) {\n <ion-item lines=\"none\">\n <mat-form-field>\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\" />\n\n <!-- slide toggle -->\n <ion-text translate>SETTINGS.OFFLINE_MODE</ion-text>\n <mat-slide-toggle\n matSuffix\n (change)=\"network.setForceOffline($event.checked)\"\n [checked]=\"network.offline\"\n ></mat-slide-toggle>\n </mat-form-field>\n </ion-item>\n }\n </ion-list>\n\n <!-- Data entry -->\n <ion-list-header>\n <h3 translate>SETTINGS.DATA_ENTRY_DIVIDER</h3>\n </ion-list-header>\n\n <ion-list [inset]=\"mobile\">\n <!-- Usage mode -->\n <ion-item lines=\"none\">\n <mat-form-field>\n <ion-icon matPrefix name=\"id-card\"></ion-icon>\n <mat-label>{{ 'SETTINGS.USAGE_MODE' | translate }}</mat-label>\n <mat-select formControlName=\"usageMode\" required>\n <mat-option *ngFor=\"let item of usageModes\" [value]=\"item\">\n {{ 'SETTINGS.USAGE_MODES.' + item | translate }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.usageMode.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n </ion-item>\n\n <!-- lat/long format-->\n <ion-item lines=\"none\">\n <mat-form-field>\n <ion-icon matPrefix name=\"locate\"></ion-icon>\n <mat-label>{{ 'SETTINGS.LAT_LONG_FORMAT' | translate }}</mat-label>\n <mat-select formControlName=\"latLongFormat\" required>\n <mat-option *ngFor=\"let item of latLongFormats\" [value]=\"item\">\n {{ 'COMMON.LAT_LONG.' + item + '_PLACEHOLDER' | translate }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.latLongFormat.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n </ion-item>\n </ion-list>\n\n <!-- fields options -->\n <app-properties-form\n #propertiesForm\n formArrayName=\"properties\"\n [definitions]=\"propertyDefinitions\"\n [options]=\"{ allowEmptyArray: true }\"\n [mobile]=\"mobile\"\n [showAddButton]=\"!mobile\"\n [showHintKey]=\"isAdmin\"\n ></app-properties-form>\n </ion-col>\n\n <!-- right margin -->\n <ion-col size=\"0\" size-lg=\"1\" size-xl=\"2\">&nbsp;</ion-col>\n </ion-row>\n </ion-grid>\n </form>\n</ion-content>\n\n<ion-footer hidden-xs hidden-sm hidden-mobile>\n <app-form-buttons-bar\n (onCancel)=\"cancel()\"\n (onSave)=\"save($event)\"\n [disabled]=\"!form.dirty || saving\"\n ></app-form-buttons-bar>\n</ion-footer>\n", dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2$1.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i2$1.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i2$1.IonCol, selector: "ion-col", inputs: ["offset", "offsetLg", "offsetMd", "offsetSm", "offsetXl", "offsetXs", "pull", "pullLg", "pullMd", "pullSm", "pullXl", "pullXs", "push", "pushLg", "pushMd", "pushSm", "pushXl", "pushXs", "size", "sizeLg", "sizeMd", "sizeSm", "sizeXl", "sizeXs"] }, { kind: "component", type: i2$1.IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i2$1.IonFooter, selector: "ion-footer", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i2$1.IonGrid, selector: "ion-grid", inputs: ["fixed"] }, { kind: "component", type: i2$1.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i2$1.IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i2$1.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i2$1.IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: i2$1.IonListHeader, selector: "ion-list-header", inputs: ["color", "lines", "mode"] }, { kind: "component", type: i2$1.IonRow, selector: "ion-row" }, { kind: "component", type: i2$1.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "directive", type: i1$3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$3.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i6.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i4.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i5.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i9.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i8$1.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i8$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i8$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: i12.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i2.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i9$1.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "component", type: i12$3.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "component", type: ToolbarComponent, selector: "app-toolbar", inputs: ["progressBarMode", "title", "color", "class", "backHref", "defaultBackHref", "hasValidate", "hasClose", "hasSearch", "canGoBack", "canShowMenu"], outputs: ["onValidate", "onClose", "onValidateAndClose", "onBackClick", "onSearch"] }, { kind: "component", type: FormButtonsBarComponent, selector: "app-form-buttons-bar", inputs: ["disabled", "disabledCancel", "disabledEscape", "classList", "saveButtonColor", "backText", "cancelText", "nextText", "showBack", "showCancel", "showNext", "showSave"], outputs: ["onCancel", "onSave", "onNext", "onBack", "onSaveAndClose", "onSaveAndNext"] }, { kind: "component", type: AppPropertiesForm, selector: "app-properties-form", inputs: ["formArrayName", "formArray", "options", "chipColor", "mobile", "appearance", "subscriptSizing", "showHintKey", "hintKeyPrefix", "showMoreButton", "showMoreButtonTitle", "showAddButton", "definitions"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
29223
29359
  }
29224
29360
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: SettingsPage, decorators: [{
29225
29361
  type: Component,
29226
- args: [{ selector: 'page-settings', providers: [{ provide: ValidatorService, useExisting: LocalSettingsValidatorService }], changeDetection: ChangeDetectionStrategy.OnPush, template: "<app-toolbar\n [title]=\"'SETTINGS.TITLE' | translate\"\n color=\"primary\"\n [hasValidate]=\"dirty && !saving\"\n [hasClose]=\"!dirty && !saving\"\n (onValidate)=\"save($event)\"\n (onClose)=\"close($event)\"\n>\n <ion-buttons slot=\"end\">\n <!-- options menu -->\n <ion-button [matMenuTriggerFor]=\"optionsMenu\">\n <mat-icon slot=\"icon-only\">more_vert</mat-icon>\n </ion-button>\n </ion-buttons>\n</app-toolbar>\n\n<!-- Options menu -->\n<mat-menu #optionsMenu=\"matMenu\">\n <!-- Clear cache -->\n <button mat-menu-item [disabled]=\"saving\" (click)=\"clearCache($event)\">\n <mat-icon><ion-icon name=\"trash-outline\"></ion-icon></mat-icon>\n <ion-label translate>SETTINGS.BTN_CLEAR_CACHE</ion-label>\n </button>\n\n <!-- Reset -->\n <button mat-menu-item [disabled]=\"saving || !dirty\" (click)=\"cancel($event)\">\n <mat-icon><ion-icon name=\"refresh\"></ion-icon></mat-icon>\n <mat-label translate>COMMON.BTN_RESET</mat-label>\n </button>\n\n <!-- additional items -->\n @if (!loading) {\n @for (item of menuItems; track item) {\n @if (item.path) {\n <a mat-menu-item class=\"{{ item.cssClass }} {{ item.color }}\" (click)=\"executeAction($event, item)\">\n <mat-icon *ngIf=\"item.icon\"><ion-icon [name]=\"item.icon\"></ion-icon></mat-icon>\n <mat-icon *ngIf=\"item.matIcon\">{{ item.matIcon }}</mat-icon>\n <mat-label translate>{{ item.title }}</mat-label>\n </a>\n } @else if (!item.action) {\n <!-- divider -->\n <mat-divider class=\"{{ item.cssClass }} {{ item.color }}\">\n <mat-label translate>{{ item.title }}</mat-label>\n </mat-divider>\n }\n }\n }\n</mat-menu>\n\n<ion-content>\n <form [formGroup]=\"form\" novalidate (ngSubmit)=\"save($event)\" class=\"form-container\">\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <!-- left margin -->\n <ion-col size=\"0\" size-lg=\"1\" size-xl=\"2\">&nbsp;</ion-col>\n\n <ion-col class=\"ion-padding\">\n <!-- error -->\n <ion-item *ngIf=\"error\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error | translate\"></ion-label>\n </ion-item>\n\n <ion-list-header class=\"hidden-xs hidden-xxs\" translate>SETTINGS.DESCRIPTION</ion-list-header>\n\n <ion-list [inset]=\"mobile\">\n <ion-item lines=\"none\">\n <!-- account inheritance (desktop) -->\n @if (!mobile) {\n <mat-form-field [hidden]=\"!isLogin\">\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\" />\n\n <!-- check box (if desktop) -->\n <mat-checkbox (change)=\"setAccountInheritance($event.checked)\" [checked]=\"accountInheritance\">\n <span translate>SETTINGS.INHERIT_FROM_ACCOUNT</span>\n </mat-checkbox>\n\n <mat-error *ngIf=\"form.controls.accountInheritance.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n } @else {\n <!-- account inheritance (if mobile) -->\n <mat-form-field [hidden]=\"!isLogin\">\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\" />\n\n <!-- slide toggle -->\n <ion-text translate>SETTINGS.INHERIT_FROM_ACCOUNT</ion-text>\n <mat-slide-toggle\n matSuffix\n (change)=\"setAccountInheritance($event.checked)\"\n [checked]=\"accountInheritance\"\n ></mat-slide-toggle>\n <mat-error *ngIf=\"form.controls.accountInheritance.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n }\n </ion-item>\n </ion-list>\n\n @if (settings.enableDarkMode) {\n <ion-list-header><h3 translate>SETTINGS.DISPLAY_DIVIDER</h3></ion-list-header>\n\n <ion-list [inset]=\"mobile\">\n <!-- locale -->\n <ion-item lines=\"none\">\n <mat-form-field>\n <ion-icon matPrefix name=\"language\"></ion-icon>\n <mat-label>{{ 'SETTINGS.LOCALE' | translate }}</mat-label>\n <mat-select formControlName=\"locale\" required>\n <mat-option *ngFor=\"let item of locales\" [value]=\"item.key\">\n {{ item.value }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.locale.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n </ion-item>\n\n <!-- dark mode -->\n <ion-item lines=\"none\">\n <!-- dark mode (if mobile) -->\n <mat-form-field>\n <ion-icon matPrefix name=\"moon\"></ion-icon>\n\n <input matInput hidden formControlName=\"darkMode\" type=\"text\" />\n\n <!-- slide toggle -->\n <ion-text translate>SETTINGS.BTN_DARK_MODE</ion-text>\n <mat-slide-toggle\n matSuffix\n (change)=\"toggleDarkMode($event.checked)\"\n [checked]=\"darkMode\"\n ></mat-slide-toggle>\n </mat-form-field>\n </ion-item>\n </ion-list>\n }\n\n <!-- Network entry -->\n <ion-list-header><h3 translate>SETTINGS.NETWORK_DIVIDER</h3></ion-list-header>\n\n <ion-list [inset]=\"mobile\">\n <!-- Peer address -->\n <ion-item lines=\"none\">\n <mat-form-field>\n <ion-icon matPrefix name=\"cloud\"></ion-icon>\n\n <mat-label>{{ 'SETTINGS.PEER_URL' | translate }}</mat-label>\n <input matInput type=\"text\" formControlName=\"peerUrl\" required />\n\n <button\n mat-icon-button\n type=\"button\"\n matSuffix\n (click)=\"showSelectPeerModal()\"\n tabindex=\"-1\"\n [title]=\"'SETTINGS.BTN_CHANGE_PEER' | translate\"\n >\n <mat-icon>search</mat-icon>\n </button>\n\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('peerAlive')\" translate>\n SETTINGS.ERROR.PEER_NOT_REACHABLE\n </mat-error>\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('peerNotCompatible')\" translate>\n SETTINGS.ERROR.PEER_NOT_COMPATIBLE\n </mat-error>\n </mat-form-field>\n </ion-item>\n\n <!-- Offline mode (if mobile) -->\n @if (mobile) {\n <ion-item lines=\"none\">\n <mat-form-field>\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\" />\n\n <!-- slide toggle -->\n <ion-text translate>SETTINGS.OFFLINE_MODE</ion-text>\n <mat-slide-toggle\n matSuffix\n (change)=\"network.setForceOffline($event.checked)\"\n [checked]=\"network.offline\"\n ></mat-slide-toggle>\n </mat-form-field>\n </ion-item>\n }\n </ion-list>\n\n <!-- Data entry -->\n <ion-list-header>\n <h3 translate>SETTINGS.DATA_ENTRY_DIVIDER</h3>\n </ion-list-header>\n\n <ion-list [inset]=\"mobile\">\n <!-- Usage mode -->\n <ion-item lines=\"none\">\n <mat-form-field>\n <ion-icon matPrefix name=\"id-card\"></ion-icon>\n <mat-label>{{ 'SETTINGS.USAGE_MODE' | translate }}</mat-label>\n <mat-select formControlName=\"usageMode\" required>\n <mat-option *ngFor=\"let item of usageModes\" [value]=\"item\">\n {{ 'SETTINGS.USAGE_MODES.' + item | translate }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.usageMode.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n </ion-item>\n\n <!-- lat/long format-->\n <ion-item lines=\"none\">\n <mat-form-field>\n <ion-icon matPrefix name=\"locate\"></ion-icon>\n <mat-label>{{ 'SETTINGS.LAT_LONG_FORMAT' | translate }}</mat-label>\n <mat-select formControlName=\"latLongFormat\" required>\n <mat-option *ngFor=\"let item of latLongFormats\" [value]=\"item\">\n {{ 'COMMON.LAT_LONG.' + item + '_PLACEHOLDER' | translate }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.latLongFormat.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n </ion-item>\n </ion-list>\n\n <!-- fields options -->\n <app-properties-form\n #propertiesForm\n formArrayName=\"properties\"\n [definitions]=\"propertyDefinitions\"\n [options]=\"{ allowEmptyArray: true }\"\n [mobile]=\"mobile\"\n [showAddButton]=\"!mobile\"\n [showHintKey]=\"isAdmin\"\n ></app-properties-form>\n </ion-col>\n\n <!-- right margin -->\n <ion-col size=\"0\" size-lg=\"1\" size-xl=\"2\">&nbsp;</ion-col>\n </ion-row>\n </ion-grid>\n </form>\n</ion-content>\n\n<ion-footer hidden-xs hidden-sm hidden-mobile>\n <app-form-buttons-bar\n (onCancel)=\"cancel()\"\n (onSave)=\"save($event)\"\n [disabled]=\"!form.dirty || saving\"\n ></app-form-buttons-bar>\n</ion-footer>\n" }]
29362
+ args: [{ selector: 'page-settings', providers: [{ provide: ValidatorService, useExisting: LocalSettingsValidatorService }], changeDetection: ChangeDetectionStrategy.OnPush, template: "<app-toolbar\n [title]=\"'SETTINGS.TITLE' | translate\"\n color=\"primary\"\n [hasValidate]=\"dirty && !saving\"\n [hasClose]=\"!dirty && !saving\"\n (onValidate)=\"save($event)\"\n (onClose)=\"close($event)\"\n>\n <ion-buttons slot=\"end\">\n <!-- options menu -->\n <ion-button [matMenuTriggerFor]=\"optionsMenu\">\n <mat-icon slot=\"icon-only\">more_vert</mat-icon>\n </ion-button>\n </ion-buttons>\n</app-toolbar>\n\n<!-- Options menu -->\n<mat-menu #optionsMenu=\"matMenu\">\n <!-- Clear cache -->\n <button mat-menu-item [disabled]=\"saving\" (click)=\"clearCache($event)\">\n <mat-icon><ion-icon name=\"trash-outline\"></ion-icon></mat-icon>\n <ion-label translate>SETTINGS.BTN_CLEAR_CACHE</ion-label>\n </button>\n\n <!-- Reset -->\n <button mat-menu-item [disabled]=\"saving || !dirty\" (click)=\"cancel($event)\">\n <mat-icon><ion-icon name=\"refresh\"></ion-icon></mat-icon>\n <mat-label translate>COMMON.BTN_RESET</mat-label>\n </button>\n\n <!-- additional items -->\n @if (!loading) {\n @for (item of menuItems; track item) {\n @if (item.path) {\n <a mat-menu-item class=\"{{ item.cssClass }} {{ item.color }}\" (click)=\"executeAction($event, item)\">\n <mat-icon *ngIf=\"item.icon\"><ion-icon [name]=\"item.icon\"></ion-icon></mat-icon>\n <mat-icon *ngIf=\"item.matIcon\">{{ item.matIcon }}</mat-icon>\n <mat-label translate>{{ item.title }}</mat-label>\n </a>\n } @else if (!item.action) {\n <!-- divider -->\n <mat-divider class=\"{{ item.cssClass }} {{ item.color }}\">\n <mat-label translate>{{ item.title }}</mat-label>\n </mat-divider>\n }\n }\n }\n</mat-menu>\n\n<ion-content>\n <form [formGroup]=\"form\" novalidate (ngSubmit)=\"save($event)\" class=\"form-container\">\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <!-- left margin -->\n <ion-col size=\"0\" size-lg=\"1\" size-xl=\"2\">&nbsp;</ion-col>\n\n <ion-col class=\"ion-padding\">\n <!-- error -->\n <ion-item *ngIf=\"error\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error | translate\"></ion-label>\n </ion-item>\n\n <ion-list-header class=\"hidden-xs hidden-xxs\" translate>SETTINGS.DESCRIPTION</ion-list-header>\n\n <ion-list [inset]=\"mobile\">\n <ion-item lines=\"none\">\n <!-- account inheritance (desktop) -->\n @if (!mobile) {\n <mat-form-field [hidden]=\"!isLogin\">\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\" />\n\n <!-- check box (if desktop) -->\n <mat-checkbox (change)=\"setAccountInheritance($event.checked)\" [checked]=\"accountInheritance\">\n <span translate>SETTINGS.INHERIT_FROM_ACCOUNT</span>\n </mat-checkbox>\n\n <mat-error *ngIf=\"form.controls.accountInheritance.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n } @else {\n <!-- account inheritance (if mobile) -->\n <mat-form-field [hidden]=\"!isLogin\">\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\" />\n\n <!-- slide toggle -->\n <ion-text translate>SETTINGS.INHERIT_FROM_ACCOUNT</ion-text>\n <mat-slide-toggle\n matSuffix\n (change)=\"setAccountInheritance($event.checked)\"\n [checked]=\"accountInheritance\"\n ></mat-slide-toggle>\n <mat-error *ngIf=\"form.controls.accountInheritance.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n }\n </ion-item>\n </ion-list>\n\n @if (settings.enableDarkMode) {\n <ion-list-header><h3 translate>SETTINGS.DISPLAY_DIVIDER</h3></ion-list-header>\n\n <ion-list [inset]=\"mobile\">\n <!-- locale -->\n <ion-item lines=\"none\">\n <mat-form-field>\n <ion-icon matPrefix name=\"language\"></ion-icon>\n <mat-label>{{ 'SETTINGS.LOCALE' | translate }}</mat-label>\n <mat-select formControlName=\"locale\" required>\n <mat-option *ngFor=\"let item of locales\" [value]=\"item.key\">\n {{ item.value }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.locale.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n </ion-item>\n\n <!-- dark mode -->\n <ion-item lines=\"none\">\n <mat-form-field>\n <ion-icon matPrefix name=\"moon\"></ion-icon>\n\n <input matInput hidden formControlName=\"darkMode\" type=\"text\" />\n\n <!-- slide toggle -->\n <ion-text translate>SETTINGS.BTN_DARK_MODE</ion-text>\n <mat-slide-toggle\n matSuffix\n (change)=\"toggleDarkMode($event.checked)\"\n [checked]=\"darkMode\"\n ></mat-slide-toggle>\n </mat-form-field>\n </ion-item>\n </ion-list>\n }\n\n <!-- Network entry -->\n <ion-list-header><h3 translate>SETTINGS.NETWORK_DIVIDER</h3></ion-list-header>\n\n <ion-list [inset]=\"mobile\">\n <!-- Peer address -->\n <ion-item lines=\"none\">\n <mat-form-field>\n <ion-icon matPrefix name=\"cloud\"></ion-icon>\n\n <mat-label>{{ 'SETTINGS.PEER_URL' | translate }}</mat-label>\n <input matInput type=\"text\" formControlName=\"peerUrl\" required />\n\n <button\n mat-icon-button\n type=\"button\"\n matSuffix\n (click)=\"showSelectPeerModal()\"\n tabindex=\"-1\"\n [title]=\"'SETTINGS.BTN_CHANGE_PEER' | translate\"\n >\n <mat-icon>search</mat-icon>\n </button>\n\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('peerAlive')\" translate>\n SETTINGS.ERROR.PEER_NOT_REACHABLE\n </mat-error>\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('peerNotCompatible')\" translate>\n SETTINGS.ERROR.PEER_NOT_COMPATIBLE\n </mat-error>\n </mat-form-field>\n </ion-item>\n\n <!-- Offline mode (if mobile) -->\n @if (mobile) {\n <ion-item lines=\"none\">\n <mat-form-field>\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\" />\n\n <!-- slide toggle -->\n <ion-text translate>SETTINGS.OFFLINE_MODE</ion-text>\n <mat-slide-toggle\n matSuffix\n (change)=\"network.setForceOffline($event.checked)\"\n [checked]=\"network.offline\"\n ></mat-slide-toggle>\n </mat-form-field>\n </ion-item>\n }\n </ion-list>\n\n <!-- Data entry -->\n <ion-list-header>\n <h3 translate>SETTINGS.DATA_ENTRY_DIVIDER</h3>\n </ion-list-header>\n\n <ion-list [inset]=\"mobile\">\n <!-- Usage mode -->\n <ion-item lines=\"none\">\n <mat-form-field>\n <ion-icon matPrefix name=\"id-card\"></ion-icon>\n <mat-label>{{ 'SETTINGS.USAGE_MODE' | translate }}</mat-label>\n <mat-select formControlName=\"usageMode\" required>\n <mat-option *ngFor=\"let item of usageModes\" [value]=\"item\">\n {{ 'SETTINGS.USAGE_MODES.' + item | translate }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.usageMode.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n </ion-item>\n\n <!-- lat/long format-->\n <ion-item lines=\"none\">\n <mat-form-field>\n <ion-icon matPrefix name=\"locate\"></ion-icon>\n <mat-label>{{ 'SETTINGS.LAT_LONG_FORMAT' | translate }}</mat-label>\n <mat-select formControlName=\"latLongFormat\" required>\n <mat-option *ngFor=\"let item of latLongFormats\" [value]=\"item\">\n {{ 'COMMON.LAT_LONG.' + item + '_PLACEHOLDER' | translate }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.latLongFormat.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n </ion-item>\n </ion-list>\n\n <!-- fields options -->\n <app-properties-form\n #propertiesForm\n formArrayName=\"properties\"\n [definitions]=\"propertyDefinitions\"\n [options]=\"{ allowEmptyArray: true }\"\n [mobile]=\"mobile\"\n [showAddButton]=\"!mobile\"\n [showHintKey]=\"isAdmin\"\n ></app-properties-form>\n </ion-col>\n\n <!-- right margin -->\n <ion-col size=\"0\" size-lg=\"1\" size-xl=\"2\">&nbsp;</ion-col>\n </ion-row>\n </ion-grid>\n </form>\n</ion-content>\n\n<ion-footer hidden-xs hidden-sm hidden-mobile>\n <app-form-buttons-bar\n (onCancel)=\"cancel()\"\n (onSave)=\"save($event)\"\n [disabled]=\"!form.dirty || saving\"\n ></app-form-buttons-bar>\n</ion-footer>\n" }]
29227
29363
  }], ctorParameters: () => [{ type: i0.Injector }, { type: PlatformService }, { type: i2$1.NavController }, { type: LocalSettingsValidatorService }, { type: i2$1.AlertController }, { type: i1$1.TranslateService }, { type: i1$3.UntypedFormBuilder }, { type: AccountService }, { type: LocalSettingsService }, { type: i0.ChangeDetectorRef }, { type: NetworkService }, { type: undefined, decorators: [{
29228
29364
  type: Inject,
29229
29365
  args: [APP_LOCALES]
@@ -29562,7 +29698,7 @@ class EntitiesTableDataSource extends TableDataSource {
29562
29698
  .deleteAll([row.currentData], this.serviceOptions)
29563
29699
  .catch((err) => this.handleServiceError(err))
29564
29700
  .then(() => {
29565
- setTimeout$1(() => {
29701
+ setTimeout(() => {
29566
29702
  // make sure row has been deleted (because GrapQHl cache remove can failed)
29567
29703
  const present = this.getRow(id) === row;
29568
29704
  if (present)
@@ -30703,7 +30839,7 @@ class AppTable {
30703
30839
  this.emitRefresh(event);
30704
30840
  // When target wait for a complete (e.g. IonRefresher)
30705
30841
  if (event?.target && event.target.complete) {
30706
- setTimeout$1(async () => {
30842
+ setTimeout(async () => {
30707
30843
  await this.waitIdle();
30708
30844
  event.target.complete();
30709
30845
  });
@@ -31236,7 +31372,7 @@ class AppTable {
31236
31372
  if (!this.table) {
31237
31373
  // DEBUG only -- alert user that table not found in template
31238
31374
  if (this.debug) {
31239
- setTimeout$1(() => !this.table &&
31375
+ setTimeout(() => !this.table &&
31240
31376
  console.warn(`[table] Missing <mat-table> in the HTML template (after waiting 500ms)! Component: ${this.constructor.name}`), 500);
31241
31377
  }
31242
31378
  // Make sure to wait the table
@@ -33386,7 +33522,7 @@ class AppAsyncTable {
33386
33522
  this.emitRefresh(event);
33387
33523
  // When target wait for a complete (e.g. IonRefresher)
33388
33524
  if (event?.target && event.target.complete) {
33389
- setTimeout$1(async () => {
33525
+ setTimeout(async () => {
33390
33526
  await this.waitIdle();
33391
33527
  event.target.complete();
33392
33528
  });
@@ -33911,7 +34047,7 @@ class AppAsyncTable {
33911
34047
  if (!this.table) {
33912
34048
  // DEBUG only -- alert user that table not found in template
33913
34049
  if (this.debug) {
33914
- setTimeout$1(() => !this.table &&
34050
+ setTimeout(() => !this.table &&
33915
34051
  console.warn(`[table] Missing <mat-table> in the HTML template (after waiting 500ms)! Component: ${this.constructor.name}`), 500);
33916
34052
  }
33917
34053
  // Make sure to wait the table
@@ -35044,7 +35180,10 @@ class AppFormContainer {
35044
35180
  logFormErrors(prefix) {
35045
35181
  if (this.debug)
35046
35182
  console.debug('[editor] Editor not valid. Checking where (forms, tables)...');
35047
- this._children?.forEach((c) => this.logChildrenErrors(c, prefix));
35183
+ this._children?.forEach((c, index) => {
35184
+ const path = this._childrenPath[index];
35185
+ this.logChildrenErrors(c, prefix, path);
35186
+ });
35048
35187
  }
35049
35188
  /* -- protected methods -- */
35050
35189
  registerSubscription(sub) {
@@ -35091,7 +35230,7 @@ class AppFormContainer {
35091
35230
  // If form provider: get delegate
35092
35231
  else if (c instanceof AppFormProvider) {
35093
35232
  if (!c.empty && !c.valid) {
35094
- c.waitDelegate({ timeout: 1000 }).then((delegate) => this.logChildrenErrors(delegate, prefix, 'provider'));
35233
+ c.waitDelegate({ timeout: 1000 }).then((delegate) => this.logChildrenErrors(delegate, prefix, path));
35095
35234
  }
35096
35235
  }
35097
35236
  // If table
@@ -35454,7 +35593,7 @@ class AppTabEditor extends AppEditor {
35454
35593
  }
35455
35594
  }
35456
35595
  // Realign tab, after a delay because the tab can be disabled when component is created
35457
- setTimeout$1(() => this.tabGroup.realignInkBar(), 500);
35596
+ setTimeout(() => this.tabGroup.realignInkBar(), 500);
35458
35597
  }));
35459
35598
  }
35460
35599
  }
@@ -35477,7 +35616,7 @@ class AppTabEditor extends AppEditor {
35477
35616
  this.tabGroup.selectedIndex = value;
35478
35617
  this.markForCheck();
35479
35618
  // Wait tab change in UI, before realign ink tab
35480
- setTimeout$1(() => this.tabGroup.realignInkBar(), 200);
35619
+ setTimeout(() => this.tabGroup.realignInkBar(), 200);
35481
35620
  }
35482
35621
  else if (!opts || opts.emitEvent !== false) {
35483
35622
  this.markForCheck();
@@ -35538,7 +35677,7 @@ class AppTabEditor extends AppEditor {
35538
35677
  console.error('[tab-page] Unknown swipe action: ' + event.type);
35539
35678
  return false;
35540
35679
  }
35541
- setTimeout$1(() => {
35680
+ setTimeout(() => {
35542
35681
  this.selectedTabIndex = selectTabIndex;
35543
35682
  this.markForCheck();
35544
35683
  });
@@ -35674,7 +35813,7 @@ class AppEntityEditorModal extends AppTabEditor {
35674
35813
  }
35675
35814
  else {
35676
35815
  // Use a timeout to avoid error 'NG0100: ExpressionChangedAfterItHasBeenCheckedError'
35677
- setTimeout$1(() => this.load());
35816
+ setTimeout(() => this.load());
35678
35817
  }
35679
35818
  }
35680
35819
  ngOnDestroy() {
@@ -36287,7 +36426,7 @@ class AccountPage extends AppForm {
36287
36426
  }));
36288
36427
  this.registerSubscription(this.configService.config.subscribe((config) => this.onConfigLoaded(config)));
36289
36428
  // Realign tab, after a delay because the tab can be disabled when component is created
36290
- setTimeout$1(() => this.tabGroup.realignInkBar(), 500);
36429
+ setTimeout(() => this.tabGroup.realignInkBar(), 500);
36291
36430
  }
36292
36431
  ngOnDestroy() {
36293
36432
  super.ngOnDestroy();
@@ -36427,7 +36566,7 @@ class AccountPage extends AppForm {
36427
36566
  this.disable();
36428
36567
  await this.accountService.save(newAccount);
36429
36568
  // Reload
36430
- setTimeout$1(() => this.onLogin(this.accountService.account), 100);
36569
+ setTimeout(() => this.onLogin(this.accountService.account), 100);
36431
36570
  this.markAsPristine();
36432
36571
  return true;
36433
36572
  }
@@ -37256,7 +37395,7 @@ class AppEntityEditor extends AppTabEditor {
37256
37395
  super.ngAfterViewInit();
37257
37396
  // Load data
37258
37397
  if (this._autoLoad) {
37259
- setTimeout$1(() => this.loadFromRoute(), this._autoLoadDelay);
37398
+ setTimeout(() => this.loadFromRoute(), this._autoLoadDelay);
37260
37399
  }
37261
37400
  }
37262
37401
  ngOnDestroy() {
@@ -37591,7 +37730,7 @@ class AppEntityEditor extends AppTabEditor {
37591
37730
  return false;
37592
37731
  }
37593
37732
  // Wait, then go back (wait is need in order to update back href is need)
37594
- await setTimeout$1(() => this.goBack(), 500);
37733
+ await setTimeout(() => this.goBack(), 500);
37595
37734
  return true;
37596
37735
  }
37597
37736
  async reload() {
@@ -38670,7 +38809,6 @@ class UserEventNotificationIcon {
38670
38809
  if (this.visible !== value) {
38671
38810
  this.visible = value;
38672
38811
  this.cd.markForCheck();
38673
- // FIXME: if zoneless timers, should use detectChanges() ?
38674
38812
  }
38675
38813
  }
38676
38814
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: UserEventNotificationIcon, deps: [{ token: APP_USER_EVENT_SERVICE, optional: true }, { token: AccountService }, { token: i2$1.PopoverController }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
@@ -38986,7 +39124,7 @@ class MessageModal {
38986
39124
  this.canSelectType = toBoolean(this.canSelectType, this.accountService.isAdmin());
38987
39125
  }
38988
39126
  ngAfterViewInit() {
38989
- setTimeout$1(() => {
39127
+ setTimeout(() => {
38990
39128
  this.form.markAsReady({ emitEvent: false });
38991
39129
  if (this.data) {
38992
39130
  this.data.type = this.data.type || MessageTypes.INBOX_MESSAGE;
@@ -39359,7 +39497,7 @@ class JobProgressionIcon extends RxState {
39359
39497
  // emit event
39360
39498
  this.jobFinished.emit(progression.id);
39361
39499
  if (this.autoRemove) {
39362
- setTimeout$1(() => {
39500
+ setTimeout(() => {
39363
39501
  this.stopListenJob(progression.id);
39364
39502
  }, this.autoRemoveDelay);
39365
39503
  }
@@ -40713,13 +40851,13 @@ class LatLongTestPage {
40713
40851
  this.form.get('enable').valueChanges.subscribe((value) => disableFormGroup.setValue(value));
40714
40852
  }
40715
40853
  ngOnInit() {
40716
- setTimeout$1(() => this.loadData(), 250);
40854
+ setTimeout(() => this.loadData(), 250);
40717
40855
  }
40718
40856
  toggleMode(value) {
40719
40857
  if (this.mode !== value) {
40720
40858
  this.mode = value;
40721
40859
  }
40722
- setTimeout$1(() => this.loadData(), 250);
40860
+ setTimeout(() => this.loadData(), 250);
40723
40861
  }
40724
40862
  // Load the form with data
40725
40863
  async loadData() {
@@ -40767,7 +40905,7 @@ class LatLongTestPage {
40767
40905
  }
40768
40906
  this.geoPositionMessage = logMessage;
40769
40907
  // Clean the log message, if same
40770
- setTimeout$1(() => {
40908
+ setTimeout(() => {
40771
40909
  if (this.geoPositionMessage === logMessage) {
40772
40910
  this.geoPositionMessage = null;
40773
40911
  }
@@ -41583,7 +41721,7 @@ class UploadFileTestingPage {
41583
41721
  return { type: HttpEventType.UploadProgress, total: file.size, loaded };
41584
41722
  }
41585
41723
  // Stop the timer
41586
- setTimeout$1(() => $stop.next(), 1000);
41724
+ setTimeout(() => $stop.next(), 1000);
41587
41725
  // Return final response
41588
41726
  return new HttpResponse({ body: { finalName: file.name } });
41589
41727
  }));
@@ -43122,7 +43260,7 @@ class ArrayFormTestPage extends AppForm {
43122
43260
  this.cd = cd;
43123
43261
  }
43124
43262
  ngOnInit() {
43125
- setTimeout$1(() => this.loadData(), 250);
43263
+ setTimeout(() => this.loadData(), 250);
43126
43264
  }
43127
43265
  ngOnDestroy() {
43128
43266
  this.subscription.unsubscribe();
@@ -43863,5 +44001,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImpor
43863
44001
  * Generated bundle index. Do not edit.
43864
44002
  */
43865
44003
 
43866
- export { APP_ABOUT_DEVELOPERS, APP_ABOUT_PARTNERS, APP_CONFIG_OPTIONS, APP_DEBUG_DATA_SERVICE, APP_FORM_ERROR_I18N_KEYS, APP_GRAPHQL_FRAGMENTS, APP_GRAPHQL_TYPE_POLICIES, APP_HOME_BUTTONS, APP_JOB_PROGRESSION_SERVICE, APP_LOCALES, APP_LOCAL_SETTINGS, APP_LOCAL_SETTINGS_OPTIONS, APP_LOCAL_STORAGE_TYPE_POLICIES, APP_LOGGING_SERVICE, APP_MENU_ITEMS, APP_MENU_OPTIONS, APP_NAMED_FILTER_SERVICE, APP_PROGRESS_BAR_SERVICE, APP_SETTINGS_MENU_ITEMS, APP_STORAGE, APP_STORAGE_EXPLORER_PROTECTED_KEYS, APP_TESTING_PAGES, APP_USER_EVENT_LIST_INFINITE_SCROLL_THRESHOLD, APP_USER_EVENT_SERVICE, APP_USER_SETTINGS_OPTIONS, APP_USER_TOKEN_SCOPES, AboutModal, AbstractNamedFilterService, AbstractSelectionModelPipe, AbstractTableSelectionPipe, AbstractUserEventService, Account, AccountPage, AccountService, AccountToStringPipe, AccountUtils, ActionsColumnComponent, AdminModule, AdminRoutingModule, AdminUsersModule, Alerts, AndroidOsEnvironment, AppAboutModalModule, AppAccountModule, AppAsyncTable, AppAuthForm, AppAuthModal, AppAuthModule, AppChangePasswordModule, AppChangePasswordPage, AppEditor, AppEditorOptions, AppEntityEditor, AppEntityEditorModal, AppEntityEditorModalOptions, AppEntityFormModule, AppForm, AppFormArray, AppFormButtonsBarModule, AppFormContainer, AppFormField, AppFormModule, AppFormProvider, AppFormUtils, AppGestureConfig, AppGraphQLModule, AppHelpModal, AppHomePageModule, AppIconComponent, AppIconModule, AppImageGalleryComponent, AppInMemoryTable, AppInstallUpgradeCard, AppInstallUpgradeCardModule, AppListForm, AppListFormModule, AppLoadingSpinner, AppMenuModule, AppNullForm, AppPropertiesForm, AppPropertiesFormModule, AppPropertiesTable, AppRegisterModule, AppResetPasswordModal, AppRowField, AppSelectPeerModule, AppSettingsPageModule, AppTabEditor, AppTabEditorOptions, AppTable, AppTableModule, AppTableUtils, AppTextPopoverModule, AppUpdateOfflineModeCard, AppUpdateOfflineModeCardModule, AppValidatorService, ArrayFilterPipe, ArrayFirstPipe, ArrayFormTestPage, ArrayIncludesPipe, ArrayJoinPipe, ArrayLastPipe, ArrayLengthPipe, ArrayPluckPipe, AsAnyPipe, AsArrayPipe, AsBooleanPipe, AsFloatLabelTypePipe, AsObservablePipe, AudioProvider, AudioTestingModule, AudioTestingPage, AuthGuardService, AutoTitleDirective, AutocompleteTestPage, AutofocusDirective, BadgeDirective, BadgeNumberPipe, Base58, BaseEntityService, BaseGraphqlService, BaseGraphqlServiceOptions, BaseReferential, Beans, BooleanFormatPipe, BooleanTestPage, CORE_CONFIG_OPTIONS, CORE_TESTING_PAGES, CapitalizePipe, CellValueChangeListener, ChangePasswordForm, ChipsTestPage, Color, ColorScale, ComponentDirtyGuard, ConfigFragments, ConfigService, Configuration, CoreModule, CorePipesModule, CoreTestingModule, CryptoService, CsvUtils, DATE_ISO_PATTERN, DATE_MATCH_REGEXP, DATE_PATTERN, DATE_UNIX_MS_TIMESTAMP, DATE_UNIX_TIMESTAMP, DEFAULT_JOIN_ARRAY_VALUES_SEPARATOR, DEFAULT_JOIN_PROPERTIES_SEPARATOR, DEFAULT_MENU_SHOW_WHEN, DEFAULT_PAGE_SIZE, DEFAULT_PAGE_SIZE_OPTIONS, DEFAULT_PLACEHOLDER_CHAR, DEFAULT_REQUIRED_COLUMNS, DateDiffDurationPipe, DateFormatPipe, DateFormatService, DateFromNowPipe, DateShortTestPage, DateTestPage, DateTimeTestPage, DateUtils, DebugComponent, Department, DepartmentToStringPipe, DragAndDropDirective, DurationPipe, DurationTestPage, ED25519_SEED_LENGTH, EMPTY_PLACEHOLDER_CHAR, EMPTY_PLACEHOLDER_CHAR_REGEXP_GLOBAL, ENTITIES_STORAGE_KEY_PREFIX, ENVIRONMENT, EmptyArrayPipe, EntitiesAsyncTableDataSource, EntitiesStorage, EntitiesTableDataSource, Entity, EntityClass, EntityClasses, EntityFilter, EntityFilterUtils, EntityMetadataComponent, EntityStore, EntityUtils, Environment, EnvironmentHttpLoader, EnvironmentLoader, ErrorCodes, EvenPipe, FileResponse, FileService, FileSizePipe, FilesUtils, FormArrayHelper, FormArrayTestModule, FormButtonsBarComponent, FormButtonsBarToken, FormErrorPipe, FormErrorTranslatePipe, FormErrorTranslator, FormFieldValuesHolder, FormGetArrayPipe, FormGetControlPipe, FormGetGroupPipe, FormGetPipe, FormGetValuePipe, GalleryTestPage, GeolocationUtils, GraphqlService, HAMMER_PRESS_TIME, HAMMER_TAP_TIME, HighlightPipe, HomePage, Hotkeys, HotkeysDialogComponent, IMAGE_DEFAULTS, IPosition, ImageAttachment, ImageAttachmentFilter, ImageAttachmentService, ImageGalleryModule, ImageGalleryTestingModule, ImageModule, ImageService, ImagesUtils, InMemoryEntitiesService, IsAllSelectedPipe, IsEmptySelectionPipe, IsLoginAccountPipe, IsMultipleSelectionPipe, IsNilOrBlankPipe, IsNilOrNaNPipe, IsNilPipe, IsNotAllSelectedPipe, IsNotEmptySelectionPipe, IsNotNilOrBlankPipe, IsNotNilOrNaNPipe, IsNotNilPipe, IsOnDeskPipe, IsOnFieldPipe, IsSelectedPipe, IsSingleSelectionPipe, JobModule, JobProgression, JobProgressionComponent, JobProgressionIcon, JobProgressionList, JobProgressionService, JobProgressionTestService, JobProgressionTestingPage, JobTestingModule, JobUtils, JsonUtils, KEYBOARD_HIDE_DELAY_MS, LAT_LONG_DEFAULT_MAX_DECIMALS, LAT_LONG_PATTERNS, LatLongFormatPipe, LatLongTestPage, LatitudeFormatPipe, LocalSettingsService, LogLevel, LogUtils, Logger, LoggingService, LoggingServiceModule, LongitudeFormatPipe, MASKS, MAT_FORM_FIELD_DEFAULT_APPEARANCE, MAT_FORM_FIELD_DEFAULT_SUBSCRIPT_SIZING, MINIFY_ENTITY_FOR_LOCAL_STORAGE, MINIFY_ENTITY_FOR_POD, MOMENT_NO_TIME_PROPERTY, MapGetPipe, MapKeysPipe, MapValuesPipe, MaskitoPlaceholderPipe, MaskitoTestPage, MatAutocompleteConfigHolder, MatAutocompleteField, MatAutocompleteFieldUtils, MatBadgeTestPage, MatBooleanField, MatChipsField, MatColorPipe, MatCommonTestPage, MatDate, MatDateShort, MatDateTime, MatDuration, MatLatLongField, MatPaginatorI18n, MatStepperI18n, MatSwipeField, MaterialTestingModule, MathAbsPipe, MenuComponent, MenuItem, MenuItems, MenuOptions, MenuService, MenuTestingModule, MenuTestingPage, Message, MessageFilter, MessageForm, MessageModal, MessageModule, MessageService, MessageTypeList, MessageTypes, MimeTypes, ModalToolbarComponent, NETWORK_DEFAULT_CONNECTION_TIMEOUT, NamedFilter, NamedFilterFilter, NamedFilterSelector, NamedFilterSelectorTestingModule, NamedFilterSelectorTestingPage, NavActionsColumnComponent, NetworkService, NewTokenModal, NgInitDirective, NgVarDirective, NoHtmlPipe, NotEmptyArrayPipe, NumberFormatPipe, ObservableTestPage, OddPipe, OtherMenuTestingPage, PEER_URL_REGEXP, PLUS_PLACEHOLDER_CHAR_REGEXP_GLOBAL, PRIORITIZED_AUTHORITIES, PUBKEY_REGEXP, Peer, Person, PersonFilter, PersonFragments, PersonService, PersonToStringPipe, PersonUtils, PersonValidatorService, PlatformService, ProgressBarService, ProgressInterceptor, PropertiesFormTestPage, PropertiesFormTestingModule, PropertyEntity, PropertyEntityFilter, PropertyEntityValidator, PropertyFormatPipe, PropertyGetPipe, RESERVED_END_COLUMNS, RESERVED_START_COLUMNS, Referential, ReferentialFilter, ReferentialRef, ReferentialToStringPipe, ReferentialUtils, ReferentialValidatorService, RegisterConfirmPage, RegisterForm, RegisterModal, ResizableComponent, ResizableDirective, ResizableModule, RxStateModule, SCRYPT_PARAMS, SETTINGS_DISPLAY_COLUMNS, SETTINGS_FILTER, SETTINGS_PAGE_SIZE, SETTINGS_SORTED_COLUMN, SETTINGS_STORAGE_KEY, SETTINGS_TRANSIENT_PROPERTIES, SHARED_MATERIAL_TESTING_PAGES, SHARED_STORAGE_TESTING_PAGES, SHARED_TESTING_PAGES, SOCIAL_TESTING_PAGES, SPACE_PLACEHOLDER_CHAR, SPACE_PLACEHOLDER_CHAR_REGEXP_GLOBAL, SafeHtmlPipe, SelectPeerModal, SelectionLengthPipe, ServerErrorCodes, SettingsPage, SharedAsyncValidators, SharedBadgeModule, SharedDebugModule, SharedDirectivesModule, SharedFormArrayValidators, SharedFormGroupValidators, SharedHotkeysModule, SharedMatAutocompleteModule, SharedMatBooleanModule, SharedMatChipsModule, SharedMatDateTimeModule, SharedMatDurationModule, SharedMatLatLongModule, SharedMatSwipeModule, SharedMaterialModule, SharedModule, SharedNamedFilterModule, SharedPipesModule, SharedRoutingModule, SharedTestingModule, SharedTestsPage, SharedTextFormModule, SharedToolbarModule, SharedValidators, SocialErrorCodes, SocialModule, SocialModuleOptionsToken, SocialTestingModule, Software, StartableService, StatusById, StatusIds, StatusList, StorageDrivers, StorageExplorerComponent, StorageExplorerModule, StorageExplorerTestingModule, StorageExplorerTestingRoutingModule, StorageService, StrIncludesPipe, StrLengthPipe, SubMenuTabDirective, SwipeTestPage, Table2TestPage, TableSelectColumnsComponent, TableTestPage, TableTestingModule, TableValidatorService, TextForm, TextFormTestingPage, TextPopover, TextPopoverTestingModule, TextPopoverTestingPage, ToStringPipe, ToastTestingModule, ToastTestingPage, Toasts, TokenScope, ToolbarComponent, ToolbarToken, TranslatablePipe, TranslateContextPipe, TranslateContextService, TreeItemEntityUtils, UploadFile, UploadFileComponent, UploadFilePopover, UploadFileTestingModule, UploadFileTestingPage, UriUtils, UserEventModule, UserEventNotificationIcon, UserEventNotificationList, UserEventTestService, UserEventTestingModule, UserEventTestingPage, UserSettings, UserToken, UserTokenTable, UsersPage, ValueFormatPipe, accountToString, adaptValueToControl, addValueInArray, arrayDistinct, arrayResize, arraySize, asInputElement, booleanToString, canHaveFocus, capitalizeFirstLetter, chainPromises, changeCaseToUnderscore, clearValueInArray, collectByProperty, copyEntity2Form, createPromiseEvent, createPromiseEventEmitter, departmentToString, departmentsToString, disableControls, emitPromiseEvent, entityToString, equals, equalsOrNil, escapeRegExp, fadeInAnimation, fadeInOutAnimation, fadeInSlowAnimation, filterFalse, filterFormErrors, filterFormErrorsByPath, filterFormErrorsByPrefix, filterNotNil, filterNumberInput, filterTrue, findParentWithClass, firstArrayValue, firstFalse, firstFalsePromise, firstNotNil, firstNotNilPromise, firstTrue, firstTruePromise, focusInput, focusNextInput, focusPreviousInput, formatLatLong, formatLatitude, formatLongitude, fromDateISOString, fromScrollEndEvent, fromUnixMsTimestamp, fromUnixTimestamp, getCaretPosition, getColorContrast, getColorShade, getColorTint, getConnectionType, getControlFromPath, getFocusableInputElements, getFormErrors, getFormValueFromEntity, getInputRangeFromCaretIndex, getInputSelectionRangesFromMask, getProperty, getPropertyByPath, getPropertyByPathAsString, getRandomImage, getRandomImageWithCredit, hexToRgb, hexToRgbArray, initArrayControlsFromValues, intersectArrays, isAndroid, isBlankString, isCapacitor, isControlHasInput, isEmptyArray, isIOS, isInputElement, isInstanceOf, isInt, isMobile, isNil, isNilOrBlank, isNilOrNaN, isNotEmptyArray, isNotNil, isNotNilBoolean, isNotNilObject, isNotNilOrBlank, isNotNilOrNaN, isNotNilString, isNumber, isNumberRange, isOnFieldMode, isProgressEvent, isResponseEvent, isStartableService, isTouchUi, isWindows, joinProperties, joinPropertiesPath, lastArrayValue, logFormErrors, markAllAsTouched, markAsUntouched, markControlAsTouched, markFormGroupAsTouched, maskitoAutoSelectByMaskPattern, maskitoPrefixPlugin, matchMedia, matchUpperCase, mergeLoadResult, mixHex, moveInputCaretToSeparator, newArray, noHtml, noTrailingSlash, notNilOrDefault, nullIfNilOrBlank, nullIfUndefined, parseLatitudeOrLongitude, propertiesPathComparator, propertyComparator, propertyPathComparator, referentialToString, referentialsToString, remove, removeAll, removeDiacritics, removeDuplicatesFromArray, removeEnd, removeValueInArray, replaceAll, resetCalculatedValue, resizeArray, rgbArrayToHex, rgbToHex, round, scrollFactory, selectInputContent, selectInputRange, setCalculatedValue, setPropertyByPath, setTabIndex, sleep, slideInAnimation, slideInOutAnimation, slideUpDownAnimation, sort, splitById, splitByProperty, startsWithUpperCase, suggestFromArray, suggestFromStringArray, tabindexComparator, testUserAgent, toBoolean, toDateISOString, toDuration, toFloat, toInt, toNotNil, toNumber, trimEmptyToNull, uncapitalizeFirstLetter, undefinedIfNull, underscoreToChangeCase, updateValueAndValidity, waitFor, waitForFalse, waitForTrue, waitIdle, waitWhilePending };
44004
+ export { APP_ABOUT_DEVELOPERS, APP_ABOUT_PARTNERS, APP_CONFIG_OPTIONS, APP_DEBUG_DATA_SERVICE, APP_FORM_ERROR_I18N_KEYS, APP_GRAPHQL_FRAGMENTS, APP_GRAPHQL_TYPE_POLICIES, APP_HOME_BUTTONS, APP_HOTKEYS_CONFIG, APP_JOB_PROGRESSION_SERVICE, APP_LOCALES, APP_LOCAL_SETTINGS, APP_LOCAL_SETTINGS_OPTIONS, APP_LOCAL_STORAGE_TYPE_POLICIES, APP_LOGGING_SERVICE, APP_MENU_ITEMS, APP_MENU_OPTIONS, APP_NAMED_FILTER_SERVICE, APP_PROGRESS_BAR_SERVICE, APP_SETTINGS_MENU_ITEMS, APP_STORAGE, APP_STORAGE_EXPLORER_PROTECTED_KEYS, APP_TESTING_PAGES, APP_USER_EVENT_LIST_INFINITE_SCROLL_THRESHOLD, APP_USER_EVENT_SERVICE, APP_USER_SETTINGS_OPTIONS, APP_USER_TOKEN_SCOPES, AboutModal, AbstractNamedFilterService, AbstractSelectionModelPipe, AbstractTableSelectionPipe, AbstractUserEventService, Account, AccountPage, AccountService, AccountToStringPipe, AccountUtils, ActionsColumnComponent, AdminModule, AdminRoutingModule, AdminUsersModule, Alerts, AndroidOsEnvironment, AppAboutModalModule, AppAccountModule, AppAsyncTable, AppAuthForm, AppAuthModal, AppAuthModule, AppChangePasswordModule, AppChangePasswordPage, AppEditor, AppEditorOptions, AppEntityEditor, AppEntityEditorModal, AppEntityEditorModalOptions, AppEntityFormModule, AppForm, AppFormArray, AppFormButtonsBarModule, AppFormContainer, AppFormField, AppFormModule, AppFormProvider, AppFormUtils, AppGestureConfig, AppGraphQLModule, AppHelpModal, AppHomePageModule, AppIconComponent, AppIconModule, AppImageGalleryComponent, AppInMemoryTable, AppInstallUpgradeCard, AppInstallUpgradeCardModule, AppListForm, AppListFormModule, AppLoadingSpinner, AppMenuModule, AppNullForm, AppPropertiesForm, AppPropertiesFormModule, AppPropertiesTable, AppPropertiesUtils, AppPropertyUtils, AppRegisterModule, AppResetPasswordModal, AppRowField, AppSelectPeerModule, AppSettingsPageModule, AppTabEditor, AppTabEditorOptions, AppTable, AppTableModule, AppTableUtils, AppTextPopoverModule, AppUpdateOfflineModeCard, AppUpdateOfflineModeCardModule, AppValidatorService, ArrayFilterPipe, ArrayFirstPipe, ArrayFormTestPage, ArrayIncludesPipe, ArrayJoinPipe, ArrayLastPipe, ArrayLengthPipe, ArrayPluckPipe, AsAnyPipe, AsArrayPipe, AsBooleanPipe, AsFloatLabelTypePipe, AsObservablePipe, AudioProvider, AudioTestingModule, AudioTestingPage, AuthGuardService, AutoTitleDirective, AutocompleteTestPage, AutofocusDirective, BadgeDirective, BadgeNumberPipe, Base58, BaseEntityService, BaseGraphqlService, BaseGraphqlServiceOptions, BaseReferential, Beans, BooleanFormatPipe, BooleanTestPage, CORE_CONFIG_OPTIONS, CORE_TESTING_PAGES, CapitalizePipe, CellValueChangeListener, ChangePasswordForm, ChipsTestPage, Color, ColorScale, ComponentDirtyGuard, ConfigFragments, ConfigService, Configuration, CoreModule, CorePipesModule, CoreTestingModule, CryptoService, CsvUtils, DATE_ISO_PATTERN, DATE_MATCH_REGEXP, DATE_PATTERN, DATE_UNIX_MS_TIMESTAMP, DATE_UNIX_TIMESTAMP, DEFAULT_JOIN_ARRAY_VALUES_SEPARATOR, DEFAULT_JOIN_PROPERTIES_SEPARATOR, DEFAULT_MENU_SHOW_WHEN, DEFAULT_PAGE_SIZE, DEFAULT_PAGE_SIZE_OPTIONS, DEFAULT_PLACEHOLDER_CHAR, DEFAULT_REQUIRED_COLUMNS, DateDiffDurationPipe, DateFormatPipe, DateFormatService, DateFromNowPipe, DateShortTestPage, DateTestPage, DateTimeTestPage, DateUtils, DebugComponent, Department, DepartmentToStringPipe, DragAndDropDirective, DurationPipe, DurationTestPage, ED25519_SEED_LENGTH, EMPTY_PLACEHOLDER_CHAR, EMPTY_PLACEHOLDER_CHAR_REGEXP_GLOBAL, ENTITIES_STORAGE_KEY_PREFIX, ENVIRONMENT, EmptyArrayPipe, EntitiesAsyncTableDataSource, EntitiesStorage, EntitiesTableDataSource, Entity, EntityClass, EntityClasses, EntityFilter, EntityFilterUtils, EntityMetadataComponent, EntityStore, EntityUtils, Environment, EnvironmentHttpLoader, EnvironmentLoader, ErrorCodes, EvenPipe, FileResponse, FileService, FileSizePipe, FilesUtils, FormArrayHelper, FormArrayTestModule, FormButtonsBarComponent, FormButtonsBarToken, FormErrorPipe, FormErrorTranslatePipe, FormErrorTranslator, FormFieldValuesHolder, FormGetArrayPipe, FormGetControlPipe, FormGetGroupPipe, FormGetPipe, FormGetValuePipe, GalleryTestPage, GeolocationUtils, GraphqlService, HAMMER_PRESS_TIME, HAMMER_TAP_TIME, HighlightPipe, HomePage, Hotkeys, HotkeysDialogComponent, IMAGE_DEFAULTS, IPosition, ImageAttachment, ImageAttachmentFilter, ImageAttachmentService, ImageGalleryModule, ImageGalleryTestingModule, ImageModule, ImageService, ImagesUtils, InMemoryEntitiesService, IsAllSelectedPipe, IsEmptySelectionPipe, IsLoginAccountPipe, IsMultipleSelectionPipe, IsNilOrBlankPipe, IsNilOrNaNPipe, IsNilPipe, IsNotAllSelectedPipe, IsNotEmptySelectionPipe, IsNotNilOrBlankPipe, IsNotNilOrNaNPipe, IsNotNilPipe, IsOnDeskPipe, IsOnFieldPipe, IsSelectedPipe, IsSingleSelectionPipe, JobModule, JobProgression, JobProgressionComponent, JobProgressionIcon, JobProgressionList, JobProgressionService, JobProgressionTestService, JobProgressionTestingPage, JobTestingModule, JobUtils, JsonUtils, KEYBOARD_HIDE_DELAY_MS, LAT_LONG_DEFAULT_MAX_DECIMALS, LAT_LONG_PATTERNS, LatLongFormatPipe, LatLongTestPage, LatitudeFormatPipe, LocalSettingsService, LogLevel, LogUtils, Logger, LoggingService, LoggingServiceModule, LongitudeFormatPipe, MASKS, MAT_FORM_FIELD_DEFAULT_APPEARANCE, MAT_FORM_FIELD_DEFAULT_SUBSCRIPT_SIZING, MINIFY_ENTITY_FOR_LOCAL_STORAGE, MINIFY_ENTITY_FOR_POD, MOMENT_NO_TIME_PROPERTY, MapGetPipe, MapKeysPipe, MapValuesPipe, MaskitoPlaceholderPipe, MaskitoTestPage, MatAutocompleteConfigHolder, MatAutocompleteField, MatAutocompleteFieldUtils, MatBadgeTestPage, MatBooleanField, MatChipsField, MatColorPipe, MatCommonTestPage, MatDate, MatDateShort, MatDateTime, MatDuration, MatLatLongField, MatPaginatorI18n, MatStepperI18n, MatSwipeField, MaterialTestingModule, MathAbsPipe, MenuComponent, MenuItem, MenuItems, MenuOptions, MenuService, MenuTestingModule, MenuTestingPage, Message, MessageFilter, MessageForm, MessageModal, MessageModule, MessageService, MessageTypeList, MessageTypes, MimeTypes, ModalToolbarComponent, NETWORK_DEFAULT_CONNECTION_TIMEOUT, NamedFilter, NamedFilterFilter, NamedFilterSelector, NamedFilterSelectorTestingModule, NamedFilterSelectorTestingPage, NavActionsColumnComponent, NetworkService, NewTokenModal, NgInitDirective, NgVarDirective, NoHtmlPipe, NotEmptyArrayPipe, NumberFormatPipe, ObservableTestPage, OddPipe, OtherMenuTestingPage, PEER_URL_REGEXP, PLUS_PLACEHOLDER_CHAR_REGEXP_GLOBAL, PRIORITIZED_AUTHORITIES, PUBKEY_REGEXP, Peer, Person, PersonFilter, PersonFragments, PersonService, PersonToStringPipe, PersonUtils, PersonValidatorService, PlatformService, ProgressBarService, ProgressInterceptor, PropertiesFormTestPage, PropertiesFormTestingModule, PropertyEntity, PropertyEntityFilter, PropertyEntityValidator, PropertyFormatPipe, PropertyGetPipe, RESERVED_END_COLUMNS, RESERVED_START_COLUMNS, Referential, ReferentialFilter, ReferentialRef, ReferentialToStringPipe, ReferentialUtils, ReferentialValidatorService, RegisterConfirmPage, RegisterForm, RegisterModal, ResizableComponent, ResizableDirective, ResizableModule, RxStateModule, SCRYPT_PARAMS, SETTINGS_DISPLAY_COLUMNS, SETTINGS_FILTER, SETTINGS_PAGE_SIZE, SETTINGS_SORTED_COLUMN, SETTINGS_STORAGE_KEY, SETTINGS_TRANSIENT_PROPERTIES, SHARED_MATERIAL_TESTING_PAGES, SHARED_STORAGE_TESTING_PAGES, SHARED_TESTING_PAGES, SOCIAL_TESTING_PAGES, SPACE_PLACEHOLDER_CHAR, SPACE_PLACEHOLDER_CHAR_REGEXP_GLOBAL, SafeHtmlPipe, SelectPeerModal, SelectionLengthPipe, ServerErrorCodes, SettingsPage, SharedAsyncValidators, SharedBadgeModule, SharedDebugModule, SharedDirectivesModule, SharedFormArrayValidators, SharedFormGroupValidators, SharedHotkeysModule, SharedMatAutocompleteModule, SharedMatBooleanModule, SharedMatChipsModule, SharedMatDateTimeModule, SharedMatDurationModule, SharedMatLatLongModule, SharedMatSwipeModule, SharedMaterialModule, SharedModule, SharedNamedFilterModule, SharedPipesModule, SharedRoutingModule, SharedTestingModule, SharedTestsPage, SharedTextFormModule, SharedToolbarModule, SharedValidators, SocialErrorCodes, SocialModule, SocialModuleOptionsToken, SocialTestingModule, Software, StartableService, StatusById, StatusIds, StatusList, StorageDrivers, StorageExplorerComponent, StorageExplorerModule, StorageExplorerTestingModule, StorageExplorerTestingRoutingModule, StorageService, StrIncludesPipe, StrLengthPipe, SubMenuTabDirective, SwipeTestPage, Table2TestPage, TableSelectColumnsComponent, TableTestPage, TableTestingModule, TableValidatorService, TextForm, TextFormTestingPage, TextPopover, TextPopoverTestingModule, TextPopoverTestingPage, ToStringPipe, ToastTestingModule, ToastTestingPage, Toasts, TokenScope, ToolbarComponent, ToolbarToken, TranslatablePipe, TranslateContextPipe, TranslateContextService, TreeItemEntityUtils, UploadFile, UploadFileComponent, UploadFilePopover, UploadFileTestingModule, UploadFileTestingPage, UriUtils, UserEventModule, UserEventNotificationIcon, UserEventNotificationList, UserEventTestService, UserEventTestingModule, UserEventTestingPage, UserSettings, UserToken, UserTokenTable, UsersPage, ValueFormatPipe, accountToString, adaptValueToControl, addValueInArray, arrayDistinct, arrayResize, arraySize, asInputElement, booleanToString, canHaveFocus, capitalizeFirstLetter, chainPromises, changeCaseToUnderscore, clearValueInArray, collectByProperty, copyEntity2Form, createPromiseEvent, createPromiseEventEmitter, departmentToString, departmentsToString, disableControl, disableControls, emitPromiseEvent, enableControl, enableControls, entityToString, equals, equalsOrNil, escapeRegExp, fadeInAnimation, fadeInOutAnimation, fadeInSlowAnimation, filterFalse, filterFormErrors, filterFormErrorsByPath, filterFormErrorsByPrefix, filterNotNil, filterNumberInput, filterTrue, findParentWithClass, firstArrayValue, firstFalse, firstFalsePromise, firstNotNil, firstNotNilPromise, firstTrue, firstTruePromise, focusInput, focusNextInput, focusPreviousInput, formatLatLong, formatLatitude, formatLongitude, fromDateISOString, fromScrollEndEvent, fromUnixMsTimestamp, fromUnixTimestamp, getCaretPosition, getColorContrast, getColorShade, getColorTint, getConnectionType, getControlFromPath, getFocusableInputElements, getFormErrors, getFormValueFromEntity, getInputRangeFromCaretIndex, getInputSelectionRangesFromMask, getProperty, getPropertyByPath, getPropertyByPathAsString, getRandomImage, getRandomImageWithCredit, hexToRgb, hexToRgbArray, initArrayControlsFromValues, intersectArrays, isAndroid, isBlankString, isCapacitor, isControlHasInput, isEmptyArray, isIOS, isInputElement, isInstanceOf, isInt, isMobile, isNil, isNilOrBlank, isNilOrNaN, isNotEmptyArray, isNotNil, isNotNilBoolean, isNotNilObject, isNotNilOrBlank, isNotNilOrNaN, isNotNilString, isNumber, isNumberRange, isOnFieldMode, isProgressEvent, isResponseEvent, isStartableService, isTouchUi, isWindows, joinProperties, joinPropertiesPath, lastArrayValue, logFormErrors, markAllAsTouched, markAsUntouched, markControlAsTouched, markFormGroupAsTouched, maskitoAutoSelectByMaskPattern, maskitoPrefixPlugin, matchMedia, matchUpperCase, mergeLoadResult, mixHex, moveInputCaretToSeparator, newArray, noHtml, noTrailingSlash, notNilOrDefault, nullIfNilOrBlank, nullIfUndefined, parseLatitudeOrLongitude, propertiesPathComparator, propertyComparator, propertyPathComparator, referentialToString, referentialsToString, remove, removeAll, removeDiacritics, removeDuplicatesFromArray, removeEnd, removeValueInArray, replaceAll, resetCalculatedValue, resizeArray, rgbArrayToHex, rgbToHex, round, scrollFactory, selectInputContent, selectInputRange, setCalculatedValue, setControlEnabled, setPropertyByPath, setTabIndex, sleep, slideInAnimation, slideInOutAnimation, slideUpDownAnimation, sort, splitById, splitByProperty, startsWithUpperCase, suggestFromArray, suggestFromStringArray, tabindexComparator, testUserAgent, toBoolean, toDateISOString, toDuration, toFloat, toInt, toNotNil, toNumber, trimEmptyToNull, uncapitalizeFirstLetter, undefinedIfNull, underscoreToChangeCase, updateValueAndValidity, waitFor, waitForFalse, waitForTrue, waitIdle, waitWhilePending };
43867
44005
  //# sourceMappingURL=sumaris-net.ngx-components.mjs.map