@c8y/ngx-components 1019.2.4 → 1019.2.8

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 (167) hide show
  1. package/core/common/forOf.directive.d.ts +10 -1
  2. package/core/common/forOf.directive.d.ts.map +1 -1
  3. package/core/common/geo.service.d.ts +9 -0
  4. package/core/common/geo.service.d.ts.map +1 -0
  5. package/core/common/index.d.ts +1 -0
  6. package/core/common/index.d.ts.map +1 -1
  7. package/core/common/load-more.component.d.ts +1 -0
  8. package/core/common/load-more.component.d.ts.map +1 -1
  9. package/core/core.module.d.ts +50 -49
  10. package/core/core.module.d.ts.map +1 -1
  11. package/core/index.d.ts +1 -0
  12. package/core/index.d.ts.map +1 -1
  13. package/core/realtime/realtime-button.component.d.ts +5 -2
  14. package/core/realtime/realtime-button.component.d.ts.map +1 -1
  15. package/core/router/context-route.service.d.ts +6 -5
  16. package/core/router/context-route.service.d.ts.map +1 -1
  17. package/core/time-interval/index.d.ts +3 -0
  18. package/core/time-interval/index.d.ts.map +1 -0
  19. package/core/time-interval/time-interval.component.d.ts +26 -0
  20. package/core/time-interval/time-interval.component.d.ts.map +1 -0
  21. package/core/time-interval/time-interval.model.d.ts +33 -0
  22. package/core/time-interval/time-interval.model.d.ts.map +1 -0
  23. package/esm2022/context-dashboard/report-dashboard/report-dashboard-list.component.mjs +1 -1
  24. package/esm2022/core/audit-log/audit-log.component.mjs +1 -1
  25. package/esm2022/core/bootstrap/bootstrap.component.mjs +3 -3
  26. package/esm2022/core/common/forOf.directive.mjs +18 -2
  27. package/esm2022/core/common/geo.service.mjs +30 -0
  28. package/esm2022/core/common/index.mjs +2 -1
  29. package/esm2022/core/common/load-more.component.mjs +5 -2
  30. package/esm2022/core/core.module.mjs +11 -7
  31. package/esm2022/core/dynamic-forms/typeahead/typeahead.type.component.mjs +1 -1
  32. package/esm2022/core/index.mjs +2 -1
  33. package/esm2022/core/realtime/realtime-button.component.mjs +10 -4
  34. package/esm2022/core/router/context-route.service.mjs +10 -4
  35. package/esm2022/core/search/search-input.component.mjs +1 -1
  36. package/esm2022/core/time-interval/index.mjs +3 -0
  37. package/esm2022/core/time-interval/time-interval.component.mjs +85 -0
  38. package/esm2022/core/time-interval/time-interval.model.mjs +54 -0
  39. package/esm2022/datapoint-library/list/datapoint-library-list.component.mjs +2 -2
  40. package/esm2022/datapoint-selector/datapoint-selector-list-item/datapoint-selector-list-item.component.mjs +1 -1
  41. package/esm2022/device-profile/device-profile-list.component.mjs +1 -1
  42. package/esm2022/device-profile/device-tab-profile/device-tab-profile.component.mjs +1 -1
  43. package/esm2022/device-shell/shell/shell.component.mjs +1 -1
  44. package/esm2022/diagnostics/diagnostics.component.mjs +1 -1
  45. package/esm2022/ecosystem/applications/install-from-package/install-from-package.component.mjs +1 -1
  46. package/esm2022/ecosystem/shared/package-version-select/package-version-select.component.mjs +1 -1
  47. package/esm2022/location/location.component.mjs +1 -1
  48. package/esm2022/map/cluster-map.component.mjs +7 -7
  49. package/esm2022/map/map.component.mjs +92 -36
  50. package/esm2022/map/map.model.mjs +3 -2
  51. package/esm2022/operations/bulk-operations-list/bulk-operations-list.component.mjs +1 -1
  52. package/esm2022/operations/bulk-single-operations-list/single-operations-list.component.mjs +1 -1
  53. package/esm2022/operations/operations-list/operations-list.component.mjs +1 -1
  54. package/esm2022/operations/operations-timeline/operations-timeline.component.mjs +1 -1
  55. package/esm2022/operations/stepper-bulk-type-configuration/stepper-bulk-type-configuration.component.mjs +1 -1
  56. package/esm2022/operations/stepper-bulk-type-device-profile/select-device-profile-step.component.mjs +1 -1
  57. package/esm2022/operations/stepper-bulk-type-firmware/select-firmware.component.mjs +1 -1
  58. package/esm2022/operations/stepper-bulk-type-firmware/version-or-patch.component.mjs +1 -1
  59. package/esm2022/operations/stepper-bulk-type-software/select-software-step.component.mjs +1 -1
  60. package/esm2022/protocol-lpwan/lpwan-set-connections.component.mjs +1 -1
  61. package/esm2022/protocol-lpwan/lpwan-set-device-protocol.component.mjs +1 -1
  62. package/esm2022/repository/configuration/list/configuration-detail.component.mjs +1 -1
  63. package/esm2022/repository/configuration/list/configuration-list.component.mjs +1 -1
  64. package/esm2022/repository/firmware/list/add-firmware-modal.component.mjs +1 -1
  65. package/esm2022/repository/firmware/list/add-firmware-patch-modal.component.mjs +1 -1
  66. package/esm2022/repository/firmware/list/firmware-details.component.mjs +1 -1
  67. package/esm2022/repository/firmware/list/firmware-list.component.mjs +1 -1
  68. package/esm2022/repository/shared/software-type/software-type.component.mjs +1 -1
  69. package/esm2022/repository/software/device-tab/device-software-list.component.mjs +1 -1
  70. package/esm2022/repository/software/list/add-software-modal.component.mjs +1 -1
  71. package/esm2022/repository/software/list/columns/software-type.filtering-form-renderer.component.mjs +1 -1
  72. package/esm2022/repository/software/list/software-details.component.mjs +1 -1
  73. package/esm2022/sub-assets/location/asset-location.component.mjs +1 -1
  74. package/esm2022/tracking/c8y-ngx-components-tracking.mjs +5 -0
  75. package/esm2022/tracking/index.mjs +6 -0
  76. package/esm2022/tracking/tracking-marker-popup.component.mjs +34 -0
  77. package/esm2022/tracking/tracking-tab.guard.mjs +25 -0
  78. package/esm2022/tracking/tracking.component.mjs +92 -0
  79. package/esm2022/tracking/tracking.feature.mjs +16 -0
  80. package/esm2022/tracking/tracking.service.mjs +124 -0
  81. package/esm2022/trusted-certificates/crl/crl-settings.component.mjs +5 -5
  82. package/esm2022/trusted-certificates/list/trusted-certificate-list.component.mjs +1 -1
  83. package/esm2022/widgets/implementations/map/map-widget-config.component.mjs +2 -2
  84. package/fesm2022/c8y-ngx-components-context-dashboard.mjs +1 -1
  85. package/fesm2022/c8y-ngx-components-context-dashboard.mjs.map +1 -1
  86. package/fesm2022/c8y-ngx-components-datapoint-library-list.mjs +1 -1
  87. package/fesm2022/c8y-ngx-components-datapoint-library-list.mjs.map +1 -1
  88. package/fesm2022/c8y-ngx-components-datapoint-selector.mjs +1 -1
  89. package/fesm2022/c8y-ngx-components-datapoint-selector.mjs.map +1 -1
  90. package/fesm2022/c8y-ngx-components-device-profile.mjs +2 -2
  91. package/fesm2022/c8y-ngx-components-device-profile.mjs.map +1 -1
  92. package/fesm2022/c8y-ngx-components-device-shell.mjs +1 -1
  93. package/fesm2022/c8y-ngx-components-device-shell.mjs.map +1 -1
  94. package/fesm2022/c8y-ngx-components-diagnostics.mjs +1 -1
  95. package/fesm2022/c8y-ngx-components-diagnostics.mjs.map +1 -1
  96. package/fesm2022/c8y-ngx-components-ecosystem-shared.mjs +1 -1
  97. package/fesm2022/c8y-ngx-components-ecosystem-shared.mjs.map +1 -1
  98. package/fesm2022/c8y-ngx-components-ecosystem.mjs +1 -1
  99. package/fesm2022/c8y-ngx-components-ecosystem.mjs.map +1 -1
  100. package/fesm2022/c8y-ngx-components-location.mjs +1 -1
  101. package/fesm2022/c8y-ngx-components-location.mjs.map +1 -1
  102. package/fesm2022/c8y-ngx-components-map.mjs +95 -38
  103. package/fesm2022/c8y-ngx-components-map.mjs.map +1 -1
  104. package/fesm2022/c8y-ngx-components-operations-bulk-operations-list.mjs +1 -1
  105. package/fesm2022/c8y-ngx-components-operations-bulk-operations-list.mjs.map +1 -1
  106. package/fesm2022/c8y-ngx-components-operations-bulk-single-operations-list.mjs +1 -1
  107. package/fesm2022/c8y-ngx-components-operations-bulk-single-operations-list.mjs.map +1 -1
  108. package/fesm2022/c8y-ngx-components-operations-operations-list.mjs +1 -1
  109. package/fesm2022/c8y-ngx-components-operations-operations-list.mjs.map +1 -1
  110. package/fesm2022/c8y-ngx-components-operations-operations-timeline.mjs +1 -1
  111. package/fesm2022/c8y-ngx-components-operations-operations-timeline.mjs.map +1 -1
  112. package/fesm2022/c8y-ngx-components-operations-stepper-bulk-type-configuration.mjs +1 -1
  113. package/fesm2022/c8y-ngx-components-operations-stepper-bulk-type-configuration.mjs.map +1 -1
  114. package/fesm2022/c8y-ngx-components-operations-stepper-bulk-type-device-profile.mjs +1 -1
  115. package/fesm2022/c8y-ngx-components-operations-stepper-bulk-type-device-profile.mjs.map +1 -1
  116. package/fesm2022/c8y-ngx-components-operations-stepper-bulk-type-firmware.mjs +2 -2
  117. package/fesm2022/c8y-ngx-components-operations-stepper-bulk-type-firmware.mjs.map +1 -1
  118. package/fesm2022/c8y-ngx-components-operations-stepper-bulk-type-software.mjs +1 -1
  119. package/fesm2022/c8y-ngx-components-operations-stepper-bulk-type-software.mjs.map +1 -1
  120. package/fesm2022/c8y-ngx-components-protocol-lpwan.mjs +2 -2
  121. package/fesm2022/c8y-ngx-components-protocol-lpwan.mjs.map +1 -1
  122. package/fesm2022/c8y-ngx-components-repository-configuration.mjs +2 -2
  123. package/fesm2022/c8y-ngx-components-repository-configuration.mjs.map +1 -1
  124. package/fesm2022/c8y-ngx-components-repository-firmware.mjs +4 -4
  125. package/fesm2022/c8y-ngx-components-repository-firmware.mjs.map +1 -1
  126. package/fesm2022/c8y-ngx-components-repository-shared.mjs +1 -1
  127. package/fesm2022/c8y-ngx-components-repository-shared.mjs.map +1 -1
  128. package/fesm2022/c8y-ngx-components-repository-software.mjs +4 -4
  129. package/fesm2022/c8y-ngx-components-repository-software.mjs.map +1 -1
  130. package/fesm2022/c8y-ngx-components-sub-assets.mjs +1 -1
  131. package/fesm2022/c8y-ngx-components-sub-assets.mjs.map +1 -1
  132. package/fesm2022/c8y-ngx-components-tracking.mjs +271 -0
  133. package/fesm2022/c8y-ngx-components-tracking.mjs.map +1 -0
  134. package/fesm2022/c8y-ngx-components-trusted-certificates.mjs +5 -5
  135. package/fesm2022/c8y-ngx-components-trusted-certificates.mjs.map +1 -1
  136. package/fesm2022/c8y-ngx-components-widgets-implementations-map.mjs +1 -1
  137. package/fesm2022/c8y-ngx-components-widgets-implementations-map.mjs.map +1 -1
  138. package/fesm2022/c8y-ngx-components.mjs +204 -16
  139. package/fesm2022/c8y-ngx-components.mjs.map +1 -1
  140. package/locales/de.po +158 -83
  141. package/locales/en.po +6 -0
  142. package/locales/fr.po +342 -186
  143. package/locales/locales.pot +34 -28
  144. package/locales/nl.po +326 -170
  145. package/locales/pt_BR.po +342 -186
  146. package/map/cluster-map.component.d.ts +3 -3
  147. package/map/cluster-map.component.d.ts.map +1 -1
  148. package/map/map.component.d.ts +17 -7
  149. package/map/map.component.d.ts.map +1 -1
  150. package/map/map.model.d.ts +14 -6
  151. package/map/map.model.d.ts.map +1 -1
  152. package/package.json +1 -1
  153. package/tracking/c8y-ngx-components-tracking.d.ts.map +1 -0
  154. package/tracking/index.d.ts +6 -0
  155. package/tracking/index.d.ts.map +1 -0
  156. package/tracking/tracking-marker-popup.component.d.ts +17 -0
  157. package/tracking/tracking-marker-popup.component.d.ts.map +1 -0
  158. package/tracking/tracking-tab.guard.d.ts +12 -0
  159. package/tracking/tracking-tab.guard.d.ts.map +1 -0
  160. package/tracking/tracking.component.d.ts +33 -0
  161. package/tracking/tracking.component.d.ts.map +1 -0
  162. package/tracking/tracking.feature.d.ts +3 -0
  163. package/tracking/tracking.feature.d.ts.map +1 -0
  164. package/tracking/tracking.service.d.ts +38 -0
  165. package/tracking/tracking.service.d.ts.map +1 -0
  166. package/trusted-certificates/crl/crl-settings.component.d.ts +1 -1
  167. package/trusted-certificates/crl/crl-settings.component.d.ts.map +1 -1
@@ -75,7 +75,7 @@ export class SoftwareTypeFilteringFormRendererComponent {
75
75
  return uniqueBySoftwareType;
76
76
  }
77
77
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SoftwareTypeFilteringFormRendererComponent, deps: [{ token: i1.FilteringFormRendererContext }, { token: i0.ChangeDetectorRef }, { token: i2.RepositoryService }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
78
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: SoftwareTypeFilteringFormRendererComponent, selector: "ng-component", host: { listeners: { "keyup.enter": "onEnterKeyUp($event)", "keydown.escape": "onEscapeKeyDown($event)" } }, viewQueries: [{ propertyName: "typeahead", first: true, predicate: TypeaheadComponent, descendants: true }], ngImport: i0, template: "<c8y-form-group>\n <label translate>Filter by software type</label>\n <c8y-typeahead\n [(ngModel)]=\"selectedType\"\n name=\"softwareType\"\n placeholder=\"{{ typeaheadPlaceholder | translate: { example: 'yum' } }}\"\n displayProperty=\"softwareType\"\n (onSearch)=\"search$.next($event)\"\n >\n <c8y-li\n *c8yFor=\"let software of softwareWithType$; pipe: filterPipe; loadMore: 'auto'\"\n class=\"p-l-8 p-r-8 c8y-list__item--link\"\n (click)=\"\n selectedType = software; typeahead.dropdown.hide(); changeDetectorRef.detectChanges()\n \"\n [active]=\"selectedType?.softwareType === software?.softwareType\"\n >\n <c8y-highlight\n [text]=\"software?.softwareType || '--'\"\n [pattern]=\"search$.value\"\n ></c8y-highlight>\n </c8y-li>\n </c8y-typeahead>\n</c8y-form-group>\n\n<div class=\"data-grid__dropdown__footer d-flex separator-top\">\n <button\n class=\"btn btn-default btn-sm m-r-8 flex-grow\"\n (click)=\"context.resetFilter()\"\n title=\"{{ 'Reset' | translate }}\"\n translate\n >\n Reset\n </button>\n\n <button\n class=\"btn btn-primary btn-sm flex-grow\"\n (click)=\"applyFilter()\"\n title=\"{{ 'Apply' | translate }}\"\n translate\n >\n Apply\n </button>\n</div>\n", dependencies: [{ kind: "directive", type: i1.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i1.ForOfDirective, selector: "[c8yFor]", inputs: ["c8yForOf", "c8yForLoadMore", "c8yForPipe", "c8yForNotFound", "c8yForMaxIterations", "c8yForLoadingTemplate", "c8yForLoadNextLabel", "c8yForRealtime", "c8yForRealtimeOptions", "c8yForComparator", "c8yForEnableVirtualScroll", "c8yForVirtualScrollElementSize", "c8yForVirtualScrollStrategy", "c8yForVirtualScrollContainerHeight"], outputs: ["c8yForCount"] }, { kind: "component", type: i1.HighlightComponent, selector: "c8y-highlight", inputs: ["pattern", "text", "elementClass", "shouldTrimPattern"] }, { kind: "component", type: i1.TypeaheadComponent, selector: "c8y-typeahead", inputs: ["required", "maxlength", "disabled", "allowFreeEntries", "placeholder", "displayProperty", "icon", "name", "autoClose", "hideNew", "container", "selected"], outputs: ["onSearch", "onIconClick"] }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i1.FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "component", type: i1.ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "emptyActions", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "pipe", type: i1.C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.Default }); }
78
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: SoftwareTypeFilteringFormRendererComponent, selector: "ng-component", host: { listeners: { "keyup.enter": "onEnterKeyUp($event)", "keydown.escape": "onEscapeKeyDown($event)" } }, viewQueries: [{ propertyName: "typeahead", first: true, predicate: TypeaheadComponent, descendants: true }], ngImport: i0, template: "<c8y-form-group>\n <label translate>Filter by software type</label>\n <c8y-typeahead\n [(ngModel)]=\"selectedType\"\n name=\"softwareType\"\n placeholder=\"{{ typeaheadPlaceholder | translate: { example: 'yum' } }}\"\n displayProperty=\"softwareType\"\n (onSearch)=\"search$.next($event)\"\n >\n <c8y-li\n *c8yFor=\"let software of softwareWithType$; pipe: filterPipe; loadMore: 'auto'\"\n class=\"p-l-8 p-r-8 c8y-list__item--link\"\n (click)=\"\n selectedType = software; typeahead.dropdown.hide(); changeDetectorRef.detectChanges()\n \"\n [active]=\"selectedType?.softwareType === software?.softwareType\"\n >\n <c8y-highlight\n [text]=\"software?.softwareType || '--'\"\n [pattern]=\"search$.value\"\n ></c8y-highlight>\n </c8y-li>\n </c8y-typeahead>\n</c8y-form-group>\n\n<div class=\"data-grid__dropdown__footer d-flex separator-top\">\n <button\n class=\"btn btn-default btn-sm m-r-8 flex-grow\"\n (click)=\"context.resetFilter()\"\n title=\"{{ 'Reset' | translate }}\"\n translate\n >\n Reset\n </button>\n\n <button\n class=\"btn btn-primary btn-sm flex-grow\"\n (click)=\"applyFilter()\"\n title=\"{{ 'Apply' | translate }}\"\n translate\n >\n Apply\n </button>\n</div>\n", dependencies: [{ kind: "directive", type: i1.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i1.ForOfDirective, selector: "[c8yFor]", inputs: ["c8yForOf", "c8yForLoadMore", "c8yForPipe", "c8yForNotFound", "c8yForMaxIterations", "c8yForLoadingTemplate", "c8yForLoadNextLabel", "c8yForLoadingLabel", "c8yForRealtime", "c8yForRealtimeOptions", "c8yForComparator", "c8yForEnableVirtualScroll", "c8yForVirtualScrollElementSize", "c8yForVirtualScrollStrategy", "c8yForVirtualScrollContainerHeight"], outputs: ["c8yForCount", "c8yForLoadMoreComponent"] }, { kind: "component", type: i1.HighlightComponent, selector: "c8y-highlight", inputs: ["pattern", "text", "elementClass", "shouldTrimPattern"] }, { kind: "component", type: i1.TypeaheadComponent, selector: "c8y-typeahead", inputs: ["required", "maxlength", "disabled", "allowFreeEntries", "placeholder", "displayProperty", "icon", "name", "autoClose", "hideNew", "container", "selected"], outputs: ["onSearch", "onIconClick"] }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i1.FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "component", type: i1.ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "emptyActions", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "pipe", type: i1.C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.Default }); }
79
79
  }
80
80
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SoftwareTypeFilteringFormRendererComponent, decorators: [{
81
81
  type: Component,
@@ -121,7 +121,7 @@ export class SoftwareDetailsComponent {
121
121
  this.destroy$.unsubscribe();
122
122
  }
123
123
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SoftwareDetailsComponent, deps: [{ token: i1.ActivatedRoute }, { token: i2.InventoryService }, { token: i3.RepositoryService }, { token: i4.AlertService }, { token: i5.TranslateService }, { token: i4.ModalService }, { token: i6.BsModalService }, { token: i4.GainsightService }, { token: i1.Router }], target: i0.ɵɵFactoryTarget.Component }); }
124
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: SoftwareDetailsComponent, selector: "c8y-software-details", viewQueries: [{ propertyName: "softwareType", first: true, predicate: SoftwareTypeComponent, descendants: true, static: true }], ngImport: i0, template: "<c8y-title>\n {{ (software$ | async)?.name }}\n</c8y-title>\n\n<c8y-breadcrumb>\n <c8y-breadcrumb-item\n label=\"{{ 'Management' | translate }}\"\n icon=\"c8y-management\"\n ></c8y-breadcrumb-item>\n <c8y-breadcrumb-item\n path=\"#/software\"\n label=\"{{ 'Software repository' | translate }}\"\n icon=\"c8y-tools\"\n ></c8y-breadcrumb-item>\n <c8y-breadcrumb-item\n label=\"{{ (software$ | async)?.name }}\"\n icon=\"c8y-tools\"\n ></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<c8y-action-bar-item [placement]=\"'right'\">\n <button\n class=\"btn btn-link\"\n type=\"button\"\n title=\"{{ 'Add software' | translate }}\"\n (click)=\"addBaseVersion()\"\n *ngIf=\"!(isLegacy$ | async)\"\n >\n <i c8yIcon=\"plus-circle\"></i>\n {{ 'Add software' | translate }}\n </button>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item [placement]=\"'right'\">\n <button\n class=\"btn btn-link\"\n type=\"button\"\n title=\"{{ 'Reload' | translate }}\"\n (click)=\"reload$.next()\"\n >\n <i\n c8yIcon=\"refresh\"\n [ngClass]=\"{ 'icon-spin': reloading$ | async }\"\n ></i>\n {{ 'Reload' | translate }}\n </button>\n</c8y-action-bar-item>\n\n<div class=\"row\">\n <div class=\"col-lg-12 col-lg-max\">\n <div class=\"card card--fullpage\">\n <div class=\"card-block bg-level-1 flex-no-shrink p-t-24 p-b-24 overflow-visible\">\n <div class=\"content-flex-70\">\n <div class=\"text-center\">\n <i class=\"c8y-icon-duocolor icon-48 c8y-icon c8y-icon-tools\"></i>\n <p>\n <small class=\"label label-info\">Software</small>\n </p>\n </div>\n <div class=\"flex-grow col-10\">\n <div class=\"row\">\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label class=\"control-label\">\n {{ 'Name' | translate }}\n </label>\n <div class=\"input-group input-group-editable\">\n <input\n #nameInput\n type=\"text\"\n class=\"form-control\"\n [ngModel]=\"(software$ | async)?.name\"\n #nameModel=\"ngModel\"\n placeholder=\"{{ 'e.g. My software' | translate }}\"\n [ngStyle]=\"{ 'width.ch': (software$ | async)?.name?.length + 2 || 31 }\"\n required\n />\n <span></span>\n <div class=\"input-group-btn\">\n <button\n class=\"btn btn-primary\"\n type=\"button\"\n title=\"{{ 'Save' | translate }}\"\n (click)=\"updateSoftware$.next({ name: nameInput.value }); nameModel.reset()\"\n [disabled]=\"nameInput.value.length === 0\"\n >\n {{ 'Save' | translate }}\n </button>\n </div>\n </div>\n </c8y-form-group>\n </div>\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label class=\"control-label\">\n {{ 'Description' | translate }}\n </label>\n <div class=\"input-group input-group-editable\">\n <input\n #descriptionInput\n type=\"text\"\n class=\"form-control\"\n [ngModel]=\"(software$ | async)?.description\"\n #descriptionModel=\"ngModel\"\n placeholder=\"{{ 'e.g. Cloud connectivity software' | translate }}\"\n [ngStyle]=\"{ 'width.ch': (software$ | async)?.description?.length + 2 || 31 }\"\n />\n <span></span>\n <div class=\"input-group-btn\">\n <button\n class=\"btn btn-primary\"\n type=\"button\"\n title=\"{{ 'Save' | translate }}\"\n (click)=\"\n updateSoftware$.next({ description: descriptionInput.value });\n descriptionModel.reset()\n \"\n >\n {{ 'Save' | translate }}\n </button>\n </div>\n </div>\n </c8y-form-group>\n </div>\n </div>\n <div class=\"row\">\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label class=\"control-label\">\n {{ 'Device type' | translate }}\n <button\n class=\"btn-help\"\n type=\"button\"\n [attr.aria-label]=\"'Help' | translate\"\n popover=\"{{\n 'If the filter is set, the software will show up for installation only for devices of that type. If no filter is set, it will be available for all devices.'\n | translate\n }}\"\n triggers=\"focus\"\n container=\"body\"\n >\n <i c8yIcon=\"question-circle-o\"></i>\n </button>\n </label>\n <div class=\"input-group input-group-editable\">\n <input\n #deviceTypeInput\n type=\"text\"\n class=\"form-control\"\n [ngModel]=\"(software$ | async)?.c8y_Filter?.type\"\n #deviceTypeModel=\"ngModel\"\n placeholder=\"{{ 'e.g.' | translate }} c8y_Linux\"\n [ngStyle]=\"{ 'width.ch': (software$ | async)?.type?.length + 2 || 31 }\"\n />\n <span></span>\n <div class=\"input-group-btn\">\n <button\n class=\"btn btn-primary\"\n type=\"button\"\n title=\"{{ 'Save' | translate }}\"\n (click)=\"\n updateSoftware$.next({ c8y_Filter: { type: deviceTypeInput.value } });\n deviceTypeModel.reset()\n \"\n >\n {{ 'Save' | translate }}\n </button>\n </div>\n </div>\n </c8y-form-group>\n </div>\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label class=\"control-label\">\n {{ 'Software type' | translate }}\n </label>\n <div class=\"input-group input-group-editable\">\n <c8y-software-type\n [softwareTypeMO]=\"softwareTypeObject\"\n [style]=\"{ 'width.ch': softwareTypeObject?.softwareType?.length + 2 || 31 }\"\n (onSelectSoftware)=\"onSelectSoftwareType($event)\"\n ></c8y-software-type>\n <div class=\"input-group-btn\">\n <button\n class=\"btn btn-primary\"\n type=\"button\"\n title=\"{{ 'Save' | translate }}\"\n [ngClass]=\"isSoftwareTypeChanged ? '' : 'hidden'\"\n [disabled]=\"softwareTypeObject?.softwareType === ''\"\n (click)=\"\n updateSoftware$.next({ softwareType: softwareTypeObject.softwareType });\n softwareType.resetInput();\n isSoftwareTypeChanged = false\n \"\n >\n {{ 'Save' | translate }}\n </button>\n </div>\n </div>\n </c8y-form-group>\n </div>\n </div>\n </div>\n </div>\n </div>\n <div class=\"inner-scroll\">\n <div class=\"card-header separator-top-bottom sticky-top bg-component\">\n <div\n class=\"card-title\"\n translate\n >\n Versions\n </div>\n </div>\n\n <div class=\"card-block p-t-0 p-b-24\">\n <c8y-ui-empty-state\n *ngIf=\"(baseVersions$ | async)?.data.length === 0\"\n [icon]=\"'c8y-tools'\"\n [title]=\"'No versions to display.' | translate\"\n [subtitle]=\"'Add a new version by clicking below.' | translate\"\n >\n <p>\n <button\n class=\"btn btn-primary\"\n type=\"button\"\n title=\"{{ 'Add software' | translate }}\"\n (click)=\"addBaseVersion()\"\n >\n {{ 'Add software' | translate }}\n </button>\n </p>\n </c8y-ui-empty-state>\n\n <c8y-list-group *ngIf=\"(baseVersions$ | async)?.data.length > 0\">\n <c8y-li\n *c8yFor=\"let baseVersion of baseVersions$ | async; let i = index; loadMore: 'auto'\"\n >\n <c8y-li-icon>\n <i c8yIcon=\"c8y-tools\"></i>\n </c8y-li-icon>\n\n <c8y-li-body class=\"content-flex-50\">\n <div class=\"col-4\">\n <p\n class=\"text-truncate-wrap\"\n title=\"{{ baseVersion.c8y_Software.version }}\"\n >\n {{ baseVersion.c8y_Software.version }}\n </p>\n </div>\n <div class=\"col-5\">\n <p class=\"text-truncate-wrap\">\n <span\n class=\"text-label-small m-r-8\"\n translate\n >\n File\n </span>\n <span title=\" {{ getBinaryName$(baseVersion.c8y_Software.url) | async }}\">\n <c8y-file-download\n url=\"{{ baseVersion.c8y_Software.url }}\"\n ></c8y-file-download>\n </span>\n </p>\n </div>\n <div class=\"col-2 d-flex a-i-start\">\n <span\n *ngIf=\"isLegacy$ | async\"\n class=\"label label-warning m-l-auto-sm\"\n >\n {{ 'Legacy' | translate }}\n </span>\n\n <div\n class=\"fit-h-20\"\n *ngIf=\"!(isLegacy$ | async)\"\n >\n <button\n class=\"btn btn-danger btn-xs visible-xs m-l-auto m-r-8 m-t-8\"\n type=\"button\"\n title=\"{{ 'Delete' | translate }}\"\n (click)=\"deleteBaseVersion(baseVersion)\"\n >\n <i c8yIcon=\"delete\"></i>\n {{ 'Delete' | translate }}\n </button>\n </div>\n </div>\n <div\n *ngIf=\"!(isLegacy$ | async)\"\n class=\"m-l-auto fit-h-20 hidden-xs\"\n >\n <button\n class=\"btn btn-dot text-danger showOnHover\"\n type=\"button\"\n data-cy=\"software-details-component--Delete-button\"\n [attr.aria-label]=\"'Delete' | translate\"\n tooltip=\"{{ 'Delete' | translate }}\"\n [delay]=\"500\"\n (click)=\"deleteBaseVersion(baseVersion)\"\n >\n <i c8yIcon=\"delete\"></i>\n </button>\n </div>\n </c8y-li-body>\n </c8y-li>\n </c8y-list-group>\n </div>\n </div>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i7.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i4.ActionBarItemComponent, selector: "c8y-action-bar-item", inputs: ["placement", "priority", "itemClass", "injector", "groupId", "inGroupPriority"] }, { kind: "component", type: i4.BreadcrumbComponent, selector: "c8y-breadcrumb" }, { kind: "component", type: i4.BreadcrumbItemComponent, selector: "c8y-breadcrumb-item", inputs: ["icon", "translate", "label", "path", "injector"] }, { kind: "component", type: i4.EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "directive", type: i4.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i4.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i4.ForOfDirective, selector: "[c8yFor]", inputs: ["c8yForOf", "c8yForLoadMore", "c8yForPipe", "c8yForNotFound", "c8yForMaxIterations", "c8yForLoadingTemplate", "c8yForLoadNextLabel", "c8yForRealtime", "c8yForRealtimeOptions", "c8yForComparator", "c8yForEnableVirtualScroll", "c8yForVirtualScrollElementSize", "c8yForVirtualScrollStrategy", "c8yForVirtualScrollContainerHeight"], outputs: ["c8yForCount"] }, { kind: "component", type: i4.TitleComponent, selector: "c8y-title", inputs: ["pageTitleUpdate"] }, { kind: "directive", type: i8.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: i8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i8.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i4.FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: i4.RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "component", type: i4.ListGroupComponent, selector: "c8y-list-group" }, { kind: "component", type: i4.ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "emptyActions", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "component", type: i4.ListItemIconComponent, selector: "c8y-list-item-icon, c8y-li-icon", inputs: ["icon", "status"] }, { kind: "component", type: i4.ListItemBodyComponent, selector: "c8y-list-item-body, c8y-li-body", inputs: ["body"] }, { kind: "directive", type: i9.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "directive", type: i10.TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "component", type: i3.FileDownloadComponent, selector: "c8y-file-download", inputs: ["url"] }, { kind: "component", type: i3.SoftwareTypeComponent, selector: "c8y-software-type", inputs: ["softwareTypeMO", "disabled", "style", "required", "placeholder", "emitResultsOnly", "showBtnInNotFoundMessage", "allowFreeEntries", "showClearSelectionOption", "clearSelectionOptionLabel", "presetSoftwareTypes"], outputs: ["onSelectSoftware"] }, { kind: "pipe", type: i7.AsyncPipe, name: "async" }, { kind: "pipe", type: i4.C8yTranslatePipe, name: "translate" }] }); }
124
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: SoftwareDetailsComponent, selector: "c8y-software-details", viewQueries: [{ propertyName: "softwareType", first: true, predicate: SoftwareTypeComponent, descendants: true, static: true }], ngImport: i0, template: "<c8y-title>\n {{ (software$ | async)?.name }}\n</c8y-title>\n\n<c8y-breadcrumb>\n <c8y-breadcrumb-item\n label=\"{{ 'Management' | translate }}\"\n icon=\"c8y-management\"\n ></c8y-breadcrumb-item>\n <c8y-breadcrumb-item\n path=\"#/software\"\n label=\"{{ 'Software repository' | translate }}\"\n icon=\"c8y-tools\"\n ></c8y-breadcrumb-item>\n <c8y-breadcrumb-item\n label=\"{{ (software$ | async)?.name }}\"\n icon=\"c8y-tools\"\n ></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<c8y-action-bar-item [placement]=\"'right'\">\n <button\n class=\"btn btn-link\"\n type=\"button\"\n title=\"{{ 'Add software' | translate }}\"\n (click)=\"addBaseVersion()\"\n *ngIf=\"!(isLegacy$ | async)\"\n >\n <i c8yIcon=\"plus-circle\"></i>\n {{ 'Add software' | translate }}\n </button>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item [placement]=\"'right'\">\n <button\n class=\"btn btn-link\"\n type=\"button\"\n title=\"{{ 'Reload' | translate }}\"\n (click)=\"reload$.next()\"\n >\n <i\n c8yIcon=\"refresh\"\n [ngClass]=\"{ 'icon-spin': reloading$ | async }\"\n ></i>\n {{ 'Reload' | translate }}\n </button>\n</c8y-action-bar-item>\n\n<div class=\"row\">\n <div class=\"col-lg-12 col-lg-max\">\n <div class=\"card card--fullpage\">\n <div class=\"card-block bg-level-1 flex-no-shrink p-t-24 p-b-24 overflow-visible\">\n <div class=\"content-flex-70\">\n <div class=\"text-center\">\n <i class=\"c8y-icon-duocolor icon-48 c8y-icon c8y-icon-tools\"></i>\n <p>\n <small class=\"label label-info\">Software</small>\n </p>\n </div>\n <div class=\"flex-grow col-10\">\n <div class=\"row\">\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label class=\"control-label\">\n {{ 'Name' | translate }}\n </label>\n <div class=\"input-group input-group-editable\">\n <input\n #nameInput\n type=\"text\"\n class=\"form-control\"\n [ngModel]=\"(software$ | async)?.name\"\n #nameModel=\"ngModel\"\n placeholder=\"{{ 'e.g. My software' | translate }}\"\n [ngStyle]=\"{ 'width.ch': (software$ | async)?.name?.length + 2 || 31 }\"\n required\n />\n <span></span>\n <div class=\"input-group-btn\">\n <button\n class=\"btn btn-primary\"\n type=\"button\"\n title=\"{{ 'Save' | translate }}\"\n (click)=\"updateSoftware$.next({ name: nameInput.value }); nameModel.reset()\"\n [disabled]=\"nameInput.value.length === 0\"\n >\n {{ 'Save' | translate }}\n </button>\n </div>\n </div>\n </c8y-form-group>\n </div>\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label class=\"control-label\">\n {{ 'Description' | translate }}\n </label>\n <div class=\"input-group input-group-editable\">\n <input\n #descriptionInput\n type=\"text\"\n class=\"form-control\"\n [ngModel]=\"(software$ | async)?.description\"\n #descriptionModel=\"ngModel\"\n placeholder=\"{{ 'e.g. Cloud connectivity software' | translate }}\"\n [ngStyle]=\"{ 'width.ch': (software$ | async)?.description?.length + 2 || 31 }\"\n />\n <span></span>\n <div class=\"input-group-btn\">\n <button\n class=\"btn btn-primary\"\n type=\"button\"\n title=\"{{ 'Save' | translate }}\"\n (click)=\"\n updateSoftware$.next({ description: descriptionInput.value });\n descriptionModel.reset()\n \"\n >\n {{ 'Save' | translate }}\n </button>\n </div>\n </div>\n </c8y-form-group>\n </div>\n </div>\n <div class=\"row\">\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label class=\"control-label\">\n {{ 'Device type' | translate }}\n <button\n class=\"btn-help\"\n type=\"button\"\n [attr.aria-label]=\"'Help' | translate\"\n popover=\"{{\n 'If the filter is set, the software will show up for installation only for devices of that type. If no filter is set, it will be available for all devices.'\n | translate\n }}\"\n triggers=\"focus\"\n container=\"body\"\n >\n <i c8yIcon=\"question-circle-o\"></i>\n </button>\n </label>\n <div class=\"input-group input-group-editable\">\n <input\n #deviceTypeInput\n type=\"text\"\n class=\"form-control\"\n [ngModel]=\"(software$ | async)?.c8y_Filter?.type\"\n #deviceTypeModel=\"ngModel\"\n placeholder=\"{{ 'e.g.' | translate }} c8y_Linux\"\n [ngStyle]=\"{ 'width.ch': (software$ | async)?.type?.length + 2 || 31 }\"\n />\n <span></span>\n <div class=\"input-group-btn\">\n <button\n class=\"btn btn-primary\"\n type=\"button\"\n title=\"{{ 'Save' | translate }}\"\n (click)=\"\n updateSoftware$.next({ c8y_Filter: { type: deviceTypeInput.value } });\n deviceTypeModel.reset()\n \"\n >\n {{ 'Save' | translate }}\n </button>\n </div>\n </div>\n </c8y-form-group>\n </div>\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label class=\"control-label\">\n {{ 'Software type' | translate }}\n </label>\n <div class=\"input-group input-group-editable\">\n <c8y-software-type\n [softwareTypeMO]=\"softwareTypeObject\"\n [style]=\"{ 'width.ch': softwareTypeObject?.softwareType?.length + 2 || 31 }\"\n (onSelectSoftware)=\"onSelectSoftwareType($event)\"\n ></c8y-software-type>\n <div class=\"input-group-btn\">\n <button\n class=\"btn btn-primary\"\n type=\"button\"\n title=\"{{ 'Save' | translate }}\"\n [ngClass]=\"isSoftwareTypeChanged ? '' : 'hidden'\"\n [disabled]=\"softwareTypeObject?.softwareType === ''\"\n (click)=\"\n updateSoftware$.next({ softwareType: softwareTypeObject.softwareType });\n softwareType.resetInput();\n isSoftwareTypeChanged = false\n \"\n >\n {{ 'Save' | translate }}\n </button>\n </div>\n </div>\n </c8y-form-group>\n </div>\n </div>\n </div>\n </div>\n </div>\n <div class=\"inner-scroll\">\n <div class=\"card-header separator-top-bottom sticky-top bg-component\">\n <div\n class=\"card-title\"\n translate\n >\n Versions\n </div>\n </div>\n\n <div class=\"card-block p-t-0 p-b-24\">\n <c8y-ui-empty-state\n *ngIf=\"(baseVersions$ | async)?.data.length === 0\"\n [icon]=\"'c8y-tools'\"\n [title]=\"'No versions to display.' | translate\"\n [subtitle]=\"'Add a new version by clicking below.' | translate\"\n >\n <p>\n <button\n class=\"btn btn-primary\"\n type=\"button\"\n title=\"{{ 'Add software' | translate }}\"\n (click)=\"addBaseVersion()\"\n >\n {{ 'Add software' | translate }}\n </button>\n </p>\n </c8y-ui-empty-state>\n\n <c8y-list-group *ngIf=\"(baseVersions$ | async)?.data.length > 0\">\n <c8y-li\n *c8yFor=\"let baseVersion of baseVersions$ | async; let i = index; loadMore: 'auto'\"\n >\n <c8y-li-icon>\n <i c8yIcon=\"c8y-tools\"></i>\n </c8y-li-icon>\n\n <c8y-li-body class=\"content-flex-50\">\n <div class=\"col-4\">\n <p\n class=\"text-truncate-wrap\"\n title=\"{{ baseVersion.c8y_Software.version }}\"\n >\n {{ baseVersion.c8y_Software.version }}\n </p>\n </div>\n <div class=\"col-5\">\n <p class=\"text-truncate-wrap\">\n <span\n class=\"text-label-small m-r-8\"\n translate\n >\n File\n </span>\n <span title=\" {{ getBinaryName$(baseVersion.c8y_Software.url) | async }}\">\n <c8y-file-download\n url=\"{{ baseVersion.c8y_Software.url }}\"\n ></c8y-file-download>\n </span>\n </p>\n </div>\n <div class=\"col-2 d-flex a-i-start\">\n <span\n *ngIf=\"isLegacy$ | async\"\n class=\"label label-warning m-l-auto-sm\"\n >\n {{ 'Legacy' | translate }}\n </span>\n\n <div\n class=\"fit-h-20\"\n *ngIf=\"!(isLegacy$ | async)\"\n >\n <button\n class=\"btn btn-danger btn-xs visible-xs m-l-auto m-r-8 m-t-8\"\n type=\"button\"\n title=\"{{ 'Delete' | translate }}\"\n (click)=\"deleteBaseVersion(baseVersion)\"\n >\n <i c8yIcon=\"delete\"></i>\n {{ 'Delete' | translate }}\n </button>\n </div>\n </div>\n <div\n *ngIf=\"!(isLegacy$ | async)\"\n class=\"m-l-auto fit-h-20 hidden-xs\"\n >\n <button\n class=\"btn btn-dot text-danger showOnHover\"\n type=\"button\"\n data-cy=\"software-details-component--Delete-button\"\n [attr.aria-label]=\"'Delete' | translate\"\n tooltip=\"{{ 'Delete' | translate }}\"\n [delay]=\"500\"\n (click)=\"deleteBaseVersion(baseVersion)\"\n >\n <i c8yIcon=\"delete\"></i>\n </button>\n </div>\n </c8y-li-body>\n </c8y-li>\n </c8y-list-group>\n </div>\n </div>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i7.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i4.ActionBarItemComponent, selector: "c8y-action-bar-item", inputs: ["placement", "priority", "itemClass", "injector", "groupId", "inGroupPriority"] }, { kind: "component", type: i4.BreadcrumbComponent, selector: "c8y-breadcrumb" }, { kind: "component", type: i4.BreadcrumbItemComponent, selector: "c8y-breadcrumb-item", inputs: ["icon", "translate", "label", "path", "injector"] }, { kind: "component", type: i4.EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "directive", type: i4.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i4.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i4.ForOfDirective, selector: "[c8yFor]", inputs: ["c8yForOf", "c8yForLoadMore", "c8yForPipe", "c8yForNotFound", "c8yForMaxIterations", "c8yForLoadingTemplate", "c8yForLoadNextLabel", "c8yForLoadingLabel", "c8yForRealtime", "c8yForRealtimeOptions", "c8yForComparator", "c8yForEnableVirtualScroll", "c8yForVirtualScrollElementSize", "c8yForVirtualScrollStrategy", "c8yForVirtualScrollContainerHeight"], outputs: ["c8yForCount", "c8yForLoadMoreComponent"] }, { kind: "component", type: i4.TitleComponent, selector: "c8y-title", inputs: ["pageTitleUpdate"] }, { kind: "directive", type: i8.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: i8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i8.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i4.FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: i4.RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "component", type: i4.ListGroupComponent, selector: "c8y-list-group" }, { kind: "component", type: i4.ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "emptyActions", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "component", type: i4.ListItemIconComponent, selector: "c8y-list-item-icon, c8y-li-icon", inputs: ["icon", "status"] }, { kind: "component", type: i4.ListItemBodyComponent, selector: "c8y-list-item-body, c8y-li-body", inputs: ["body"] }, { kind: "directive", type: i9.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "directive", type: i10.TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "component", type: i3.FileDownloadComponent, selector: "c8y-file-download", inputs: ["url"] }, { kind: "component", type: i3.SoftwareTypeComponent, selector: "c8y-software-type", inputs: ["softwareTypeMO", "disabled", "style", "required", "placeholder", "emitResultsOnly", "showBtnInNotFoundMessage", "allowFreeEntries", "showClearSelectionOption", "clearSelectionOptionLabel", "presetSoftwareTypes"], outputs: ["onSelectSoftware"] }, { kind: "pipe", type: i7.AsyncPipe, name: "async" }, { kind: "pipe", type: i4.C8yTranslatePipe, name: "translate" }] }); }
125
125
  }
126
126
  __decorate([
127
127
  memoize(),
@@ -168,7 +168,7 @@ export class AssetLocationComponent {
168
168
  return value === null || value === undefined;
169
169
  }
170
170
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AssetLocationComponent, deps: [{ token: i1.ActivatedRoute }, { token: i2.MapService }], target: i0.ɵɵFactoryTarget.Component }); }
171
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: AssetLocationComponent, selector: "c8y-asset-location", inputs: { isEdit: "isEdit", locationMO: "locationMO", form: "form" }, viewQueries: [{ propertyName: "mapView", first: true, predicate: MapComponent, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div [hidden]=\"!showMap\">\n <div class=\"row\">\n <button\n class=\"btn btn-link pull-right\"\n style=\"margin-right: 12px\"\n title=\"Full screen\"\n type=\"button\"\n data-cy=\"asset-location-full-screen\"\n (click)=\"enableFullscreen()\"\n >\n <i c8yIcon=\"expand\"></i>\n </button>\n </div>\n <div style=\"width: 100%; height: 400px\">\n <c8y-map\n #map\n [assets]=\"assets\"\n [config]=\"config\"\n ></c8y-map>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i3.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "component", type: i2.MapComponent, selector: "c8y-map", inputs: ["config", "assets"], outputs: ["onMove", "onMoveEnd", "onZoomStart", "onZoomEnd", "onRealtimeUpdate", "onInit"] }] }); }
171
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: AssetLocationComponent, selector: "c8y-asset-location", inputs: { isEdit: "isEdit", locationMO: "locationMO", form: "form" }, viewQueries: [{ propertyName: "mapView", first: true, predicate: MapComponent, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div [hidden]=\"!showMap\">\n <div class=\"row\">\n <button\n class=\"btn btn-link pull-right\"\n style=\"margin-right: 12px\"\n title=\"Full screen\"\n type=\"button\"\n data-cy=\"asset-location-full-screen\"\n (click)=\"enableFullscreen()\"\n >\n <i c8yIcon=\"expand\"></i>\n </button>\n </div>\n <div style=\"width: 100%; height: 400px\">\n <c8y-map\n #map\n [assets]=\"assets\"\n [config]=\"config\"\n ></c8y-map>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i3.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "component", type: i2.MapComponent, selector: "c8y-map", inputs: ["config", "assets", "polyline$", "polylineOptions"], outputs: ["onMove", "onMoveEnd", "onZoomStart", "onZoomEnd", "onRealtimeUpdate", "onInit"] }] }); }
172
172
  }
173
173
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AssetLocationComponent, decorators: [{
174
174
  type: Component,
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Generated bundle index. Do not edit.
3
+ */
4
+ export * from './index';
5
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYzh5LW5neC1jb21wb25lbnRzLXRyYWNraW5nLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHJhY2tpbmcvYzh5LW5neC1jb21wb25lbnRzLXRyYWNraW5nLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBRUgsY0FBYyxTQUFTLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEdlbmVyYXRlZCBidW5kbGUgaW5kZXguIERvIG5vdCBlZGl0LlxuICovXG5cbmV4cG9ydCAqIGZyb20gJy4vaW5kZXgnO1xuIl19
@@ -0,0 +1,6 @@
1
+ export * from './tracking-marker-popup.component';
2
+ export * from './tracking-tab.guard';
3
+ export * from './tracking.component';
4
+ export * from './tracking.feature';
5
+ export * from './tracking.service';
6
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cmFja2luZy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLG1DQUFtQyxDQUFDO0FBQ2xELGNBQWMsc0JBQXNCLENBQUM7QUFDckMsY0FBYyxzQkFBc0IsQ0FBQztBQUNyQyxjQUFjLG9CQUFvQixDQUFDO0FBQ25DLGNBQWMsb0JBQW9CLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgKiBmcm9tICcuL3RyYWNraW5nLW1hcmtlci1wb3B1cC5jb21wb25lbnQnO1xuZXhwb3J0ICogZnJvbSAnLi90cmFja2luZy10YWIuZ3VhcmQnO1xuZXhwb3J0ICogZnJvbSAnLi90cmFja2luZy5jb21wb25lbnQnO1xuZXhwb3J0ICogZnJvbSAnLi90cmFja2luZy5mZWF0dXJlJztcbmV4cG9ydCAqIGZyb20gJy4vdHJhY2tpbmcuc2VydmljZSc7XG4iXX0=
@@ -0,0 +1,34 @@
1
+ import { Component, Input } from '@angular/core';
2
+ import { FormsModule } from '@angular/forms';
3
+ import { RouterModule } from '@angular/router';
4
+ import { CoreModule } from '@c8y/ngx-components';
5
+ import { TrackingService } from './tracking.service';
6
+ import * as i0 from "@angular/core";
7
+ import * as i1 from "./tracking.service";
8
+ import * as i2 from "@c8y/ngx-components";
9
+ import * as i3 from "@angular/common";
10
+ import * as i4 from "@angular/router";
11
+ export class TrackingMarkerPopupComponent {
12
+ constructor(trackingService) {
13
+ this.trackingService = trackingService;
14
+ }
15
+ async ngOnInit() {
16
+ this.isDevice = !this.trackingService.isLocationUpdateEvent(this.context);
17
+ if (this.isDevice) {
18
+ this.date = await this.trackingService.latestPositionUpdate(this.context);
19
+ this.showTrackingOptions = await this.trackingService.gsmTrackingAvailable(this.context);
20
+ }
21
+ else {
22
+ this.date = this.context.time;
23
+ }
24
+ }
25
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TrackingMarkerPopupComponent, deps: [{ token: i1.TrackingService }], target: i0.ɵɵFactoryTarget.Component }); }
26
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: TrackingMarkerPopupComponent, isStandalone: true, selector: "c8y-tracking-marker-popup", inputs: { context: "context" }, ngImport: i0, template: "<div class=\"map-marker\">\n <a\n *ngIf=\"isDevice\"\n class=\"text-truncate text-14 text-medium p-0 m-b-8 deviceLink\"\n [routerLink]=\"['/device/', context?.id]\"\n [title]=\"context?.name\"\n >\n {{ context?.name }}\n </a>\n <div\n class=\"m-b-8\"\n ng-if=\"lastUpdated\"\n >\n <p class=\"m-0\">{{ 'Position:' | translate }}</p>\n <span class=\"text-muted\">\n {{ context?.c8y_Position?.lat + ', ' + context?.c8y_Position?.lng }}\n </span>\n <p class=\"m-0 p-t-4\">{{ 'Date and time:' | translate }}</p>\n <span class=\"text-muted\">{{ date | c8yDate }}</span>\n </div>\n\n <ng-container *ngIf=\"isDevice\">\n <div\n class=\"d-flex a-i-center\"\n *ngIf=\"!showTrackingOptions; else trackingOptions\"\n >\n <label\n for=\"switch\"\n class=\"c8y-switch\"\n >\n <input\n id=\"switch\"\n type=\"checkbox\"\n [checked]=\"trackingService.trackVisible\"\n (change)=\"trackingService.toggleTrack()\"\n />\n <span></span>\n </label>\n <div class=\"description p-b-0\">\n {{ 'Show track' | translate }}\n </div>\n </div>\n <ng-template #trackingOptions>\n <div class=\"switch d-flex a-i-center\">\n <label\n for=\"switch2\"\n class=\"c8y-switch\"\n >\n <input\n id=\"switch2\"\n type=\"checkbox\"\n [checked]=\"trackingService.trackingOption === 'gps' || !trackingService.trackingOption\"\n (change)=\"trackingService.onTrackingChange('gps', $event.currentTarget['checked'])\"\n />\n <span></span>\n </label>\n <div class=\"description p-b-0\">\n {{ 'GPS data' | translate }}\n </div>\n </div>\n\n <div class=\"d-flex a-i-center\">\n <label\n id=\"switch3\"\n class=\"c8y-switch\"\n >\n <input\n id=\"switch3\"\n type=\"checkbox\"\n [checked]=\"trackingService.trackingOption === 'gsm' || !trackingService.trackingOption\"\n (change)=\"trackingService.onTrackingChange('gsm', $event.currentTarget['checked'])\"\n />\n <span></span>\n </label>\n <div class=\"description\">\n {{ 'GSM data' | translate }}\n </div>\n </div>\n </ng-template>\n </ng-container>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CoreModule }, { kind: "pipe", type: i2.C8yTranslatePipe, name: "translate" }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i2.DatePipe, name: "c8yDate" }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i4.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "ngmodule", type: FormsModule }] }); }
27
+ }
28
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TrackingMarkerPopupComponent, decorators: [{
29
+ type: Component,
30
+ args: [{ standalone: true, selector: 'c8y-tracking-marker-popup', imports: [CoreModule, RouterModule, FormsModule], template: "<div class=\"map-marker\">\n <a\n *ngIf=\"isDevice\"\n class=\"text-truncate text-14 text-medium p-0 m-b-8 deviceLink\"\n [routerLink]=\"['/device/', context?.id]\"\n [title]=\"context?.name\"\n >\n {{ context?.name }}\n </a>\n <div\n class=\"m-b-8\"\n ng-if=\"lastUpdated\"\n >\n <p class=\"m-0\">{{ 'Position:' | translate }}</p>\n <span class=\"text-muted\">\n {{ context?.c8y_Position?.lat + ', ' + context?.c8y_Position?.lng }}\n </span>\n <p class=\"m-0 p-t-4\">{{ 'Date and time:' | translate }}</p>\n <span class=\"text-muted\">{{ date | c8yDate }}</span>\n </div>\n\n <ng-container *ngIf=\"isDevice\">\n <div\n class=\"d-flex a-i-center\"\n *ngIf=\"!showTrackingOptions; else trackingOptions\"\n >\n <label\n for=\"switch\"\n class=\"c8y-switch\"\n >\n <input\n id=\"switch\"\n type=\"checkbox\"\n [checked]=\"trackingService.trackVisible\"\n (change)=\"trackingService.toggleTrack()\"\n />\n <span></span>\n </label>\n <div class=\"description p-b-0\">\n {{ 'Show track' | translate }}\n </div>\n </div>\n <ng-template #trackingOptions>\n <div class=\"switch d-flex a-i-center\">\n <label\n for=\"switch2\"\n class=\"c8y-switch\"\n >\n <input\n id=\"switch2\"\n type=\"checkbox\"\n [checked]=\"trackingService.trackingOption === 'gps' || !trackingService.trackingOption\"\n (change)=\"trackingService.onTrackingChange('gps', $event.currentTarget['checked'])\"\n />\n <span></span>\n </label>\n <div class=\"description p-b-0\">\n {{ 'GPS data' | translate }}\n </div>\n </div>\n\n <div class=\"d-flex a-i-center\">\n <label\n id=\"switch3\"\n class=\"c8y-switch\"\n >\n <input\n id=\"switch3\"\n type=\"checkbox\"\n [checked]=\"trackingService.trackingOption === 'gsm' || !trackingService.trackingOption\"\n (change)=\"trackingService.onTrackingChange('gsm', $event.currentTarget['checked'])\"\n />\n <span></span>\n </label>\n <div class=\"description\">\n {{ 'GSM data' | translate }}\n </div>\n </div>\n </ng-template>\n </ng-container>\n</div>\n" }]
31
+ }], ctorParameters: function () { return [{ type: i1.TrackingService }]; }, propDecorators: { context: [{
32
+ type: Input
33
+ }] } });
34
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhY2tpbmctbWFya2VyLXBvcHVwLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RyYWNraW5nL3RyYWNraW5nLW1hcmtlci1wb3B1cC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi90cmFja2luZy90cmFja2luZy1tYXJrZXItcG9wdXAuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQVUsTUFBTSxlQUFlLENBQUM7QUFDekQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzdDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUUvQyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFFakQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLG9CQUFvQixDQUFDOzs7Ozs7QUFRckQsTUFBTSxPQUFPLDRCQUE0QjtJQVF2QyxZQUFtQixlQUFnQztRQUFoQyxvQkFBZSxHQUFmLGVBQWUsQ0FBaUI7SUFBRyxDQUFDO0lBRXZELEtBQUssQ0FBQyxRQUFRO1FBQ1osSUFBSSxDQUFDLFFBQVEsR0FBRyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLE9BQTRCLENBQUMsQ0FBQztRQUMvRixJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUU7WUFDakIsSUFBSSxDQUFDLElBQUksR0FBRyxNQUFNLElBQUksQ0FBQyxlQUFlLENBQUMsb0JBQW9CLENBQ3pELElBQUksQ0FBQyxPQUFnQyxDQUN0QyxDQUFDO1lBQ0YsSUFBSSxDQUFDLG1CQUFtQixHQUFHLE1BQU0sSUFBSSxDQUFDLGVBQWUsQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7U0FDMUY7YUFBTTtZQUNMLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUM7U0FDL0I7SUFDSCxDQUFDOytHQXBCVSw0QkFBNEI7bUdBQTVCLDRCQUE0QixxSENkekMsdzNFQWlGQSwyQ0RyRVksVUFBVSx3UEFBRSxZQUFZLHVRQUFFLFdBQVc7OzRGQUVwQyw0QkFBNEI7a0JBTnhDLFNBQVM7aUNBQ0ksSUFBSSxZQUNOLDJCQUEyQixXQUU1QixDQUFDLFVBQVUsRUFBRSxZQUFZLEVBQUUsV0FBVyxDQUFDO3NHQUloRCxPQUFPO3NCQUROLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIElucHV0LCBPbkluaXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgUm91dGVyTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7IElFdmVudCB9IGZyb20gJ0BjOHkvY2xpZW50JztcbmltcG9ydCB7IENvcmVNb2R1bGUgfSBmcm9tICdAYzh5L25neC1jb21wb25lbnRzJztcbmltcG9ydCB7IFBvc2l0aW9uTWFuYWdlZE9iamVjdCB9IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMvbWFwJztcbmltcG9ydCB7IFRyYWNraW5nU2VydmljZSB9IGZyb20gJy4vdHJhY2tpbmcuc2VydmljZSc7XG5cbkBDb21wb25lbnQoe1xuICBzdGFuZGFsb25lOiB0cnVlLFxuICBzZWxlY3RvcjogJ2M4eS10cmFja2luZy1tYXJrZXItcG9wdXAnLFxuICB0ZW1wbGF0ZVVybDogJy4vdHJhY2tpbmctbWFya2VyLXBvcHVwLmNvbXBvbmVudC5odG1sJyxcbiAgaW1wb3J0czogW0NvcmVNb2R1bGUsIFJvdXRlck1vZHVsZSwgRm9ybXNNb2R1bGVdXG59KVxuZXhwb3J0IGNsYXNzIFRyYWNraW5nTWFya2VyUG9wdXBDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICBASW5wdXQoKVxuICBjb250ZXh0OiBQb3NpdGlvbk1hbmFnZWRPYmplY3QgfCBJRXZlbnQ7XG5cbiAgaXNEZXZpY2U6IGJvb2xlYW47XG4gIGRhdGU6IERhdGU7XG4gIHNob3dUcmFja2luZ09wdGlvbnM6IGJvb2xlYW47XG5cbiAgY29uc3RydWN0b3IocHVibGljIHRyYWNraW5nU2VydmljZTogVHJhY2tpbmdTZXJ2aWNlKSB7fVxuXG4gIGFzeW5jIG5nT25Jbml0KCkge1xuICAgIHRoaXMuaXNEZXZpY2UgPSAhdGhpcy50cmFja2luZ1NlcnZpY2UuaXNMb2NhdGlvblVwZGF0ZUV2ZW50KHRoaXMuY29udGV4dCBhcyB1bmtub3duIGFzIElFdmVudCk7XG4gICAgaWYgKHRoaXMuaXNEZXZpY2UpIHtcbiAgICAgIHRoaXMuZGF0ZSA9IGF3YWl0IHRoaXMudHJhY2tpbmdTZXJ2aWNlLmxhdGVzdFBvc2l0aW9uVXBkYXRlKFxuICAgICAgICB0aGlzLmNvbnRleHQgYXMgUG9zaXRpb25NYW5hZ2VkT2JqZWN0XG4gICAgICApO1xuICAgICAgdGhpcy5zaG93VHJhY2tpbmdPcHRpb25zID0gYXdhaXQgdGhpcy50cmFja2luZ1NlcnZpY2UuZ3NtVHJhY2tpbmdBdmFpbGFibGUodGhpcy5jb250ZXh0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5kYXRlID0gdGhpcy5jb250ZXh0LnRpbWU7XG4gICAgfVxuICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwibWFwLW1hcmtlclwiPlxuICA8YVxuICAgICpuZ0lmPVwiaXNEZXZpY2VcIlxuICAgIGNsYXNzPVwidGV4dC10cnVuY2F0ZSB0ZXh0LTE0IHRleHQtbWVkaXVtIHAtMCBtLWItOCBkZXZpY2VMaW5rXCJcbiAgICBbcm91dGVyTGlua109XCJbJy9kZXZpY2UvJywgY29udGV4dD8uaWRdXCJcbiAgICBbdGl0bGVdPVwiY29udGV4dD8ubmFtZVwiXG4gID5cbiAgICB7eyBjb250ZXh0Py5uYW1lIH19XG4gIDwvYT5cbiAgPGRpdlxuICAgIGNsYXNzPVwibS1iLThcIlxuICAgIG5nLWlmPVwibGFzdFVwZGF0ZWRcIlxuICA+XG4gICAgPHAgY2xhc3M9XCJtLTBcIj57eyAnUG9zaXRpb246JyB8IHRyYW5zbGF0ZSB9fTwvcD5cbiAgICA8c3BhbiBjbGFzcz1cInRleHQtbXV0ZWRcIj5cbiAgICAgIHt7IGNvbnRleHQ/LmM4eV9Qb3NpdGlvbj8ubGF0ICsgJywgJyArIGNvbnRleHQ/LmM4eV9Qb3NpdGlvbj8ubG5nIH19XG4gICAgPC9zcGFuPlxuICAgIDxwIGNsYXNzPVwibS0wIHAtdC00XCI+e3sgJ0RhdGUgYW5kIHRpbWU6JyB8IHRyYW5zbGF0ZSB9fTwvcD5cbiAgICA8c3BhbiBjbGFzcz1cInRleHQtbXV0ZWRcIj57eyBkYXRlIHwgYzh5RGF0ZSB9fTwvc3Bhbj5cbiAgPC9kaXY+XG5cbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImlzRGV2aWNlXCI+XG4gICAgPGRpdlxuICAgICAgY2xhc3M9XCJkLWZsZXggYS1pLWNlbnRlclwiXG4gICAgICAqbmdJZj1cIiFzaG93VHJhY2tpbmdPcHRpb25zOyBlbHNlIHRyYWNraW5nT3B0aW9uc1wiXG4gICAgPlxuICAgICAgPGxhYmVsXG4gICAgICAgIGZvcj1cInN3aXRjaFwiXG4gICAgICAgIGNsYXNzPVwiYzh5LXN3aXRjaFwiXG4gICAgICA+XG4gICAgICAgIDxpbnB1dFxuICAgICAgICAgIGlkPVwic3dpdGNoXCJcbiAgICAgICAgICB0eXBlPVwiY2hlY2tib3hcIlxuICAgICAgICAgIFtjaGVja2VkXT1cInRyYWNraW5nU2VydmljZS50cmFja1Zpc2libGVcIlxuICAgICAgICAgIChjaGFuZ2UpPVwidHJhY2tpbmdTZXJ2aWNlLnRvZ2dsZVRyYWNrKClcIlxuICAgICAgICAvPlxuICAgICAgICA8c3Bhbj48L3NwYW4+XG4gICAgICA8L2xhYmVsPlxuICAgICAgPGRpdiBjbGFzcz1cImRlc2NyaXB0aW9uIHAtYi0wXCI+XG4gICAgICAgIHt7ICdTaG93IHRyYWNrJyB8IHRyYW5zbGF0ZSB9fVxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gICAgPG5nLXRlbXBsYXRlICN0cmFja2luZ09wdGlvbnM+XG4gICAgICA8ZGl2IGNsYXNzPVwic3dpdGNoIGQtZmxleCBhLWktY2VudGVyXCI+XG4gICAgICAgIDxsYWJlbFxuICAgICAgICAgIGZvcj1cInN3aXRjaDJcIlxuICAgICAgICAgIGNsYXNzPVwiYzh5LXN3aXRjaFwiXG4gICAgICAgID5cbiAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgIGlkPVwic3dpdGNoMlwiXG4gICAgICAgICAgICB0eXBlPVwiY2hlY2tib3hcIlxuICAgICAgICAgICAgW2NoZWNrZWRdPVwidHJhY2tpbmdTZXJ2aWNlLnRyYWNraW5nT3B0aW9uID09PSAnZ3BzJyB8fCAhdHJhY2tpbmdTZXJ2aWNlLnRyYWNraW5nT3B0aW9uXCJcbiAgICAgICAgICAgIChjaGFuZ2UpPVwidHJhY2tpbmdTZXJ2aWNlLm9uVHJhY2tpbmdDaGFuZ2UoJ2dwcycsICRldmVudC5jdXJyZW50VGFyZ2V0WydjaGVja2VkJ10pXCJcbiAgICAgICAgICAvPlxuICAgICAgICAgIDxzcGFuPjwvc3Bhbj5cbiAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgPGRpdiBjbGFzcz1cImRlc2NyaXB0aW9uIHAtYi0wXCI+XG4gICAgICAgICAge3sgJ0dQUyBkYXRhJyB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGEtaS1jZW50ZXJcIj5cbiAgICAgICAgPGxhYmVsXG4gICAgICAgICAgaWQ9XCJzd2l0Y2gzXCJcbiAgICAgICAgICBjbGFzcz1cImM4eS1zd2l0Y2hcIlxuICAgICAgICA+XG4gICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICBpZD1cInN3aXRjaDNcIlxuICAgICAgICAgICAgdHlwZT1cImNoZWNrYm94XCJcbiAgICAgICAgICAgIFtjaGVja2VkXT1cInRyYWNraW5nU2VydmljZS50cmFja2luZ09wdGlvbiA9PT0gJ2dzbScgfHwgIXRyYWNraW5nU2VydmljZS50cmFja2luZ09wdGlvblwiXG4gICAgICAgICAgICAoY2hhbmdlKT1cInRyYWNraW5nU2VydmljZS5vblRyYWNraW5nQ2hhbmdlKCdnc20nLCAkZXZlbnQuY3VycmVudFRhcmdldFsnY2hlY2tlZCddKVwiXG4gICAgICAgICAgLz5cbiAgICAgICAgICA8c3Bhbj48L3NwYW4+XG4gICAgICAgIDwvbGFiZWw+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJkZXNjcmlwdGlvblwiPlxuICAgICAgICAgIHt7ICdHU00gZGF0YScgfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L25nLXRlbXBsYXRlPlxuICA8L25nLWNvbnRhaW5lcj5cbjwvZGl2PlxuIl19
@@ -0,0 +1,25 @@
1
+ import { Injectable } from '@angular/core';
2
+ import { ContextRouteService, GeoService, ViewContext } from '@c8y/ngx-components';
3
+ import { isEmpty } from 'lodash-es';
4
+ import * as i0 from "@angular/core";
5
+ import * as i1 from "@c8y/ngx-components";
6
+ export class TrackingTabFactory {
7
+ constructor(contextRouteService, geoService) {
8
+ this.contextRouteService = contextRouteService;
9
+ this.geoService = geoService;
10
+ }
11
+ canActivate(snapshot) {
12
+ const contextData = this.contextRouteService.getContextData(snapshot);
13
+ return (contextData?.context === ViewContext.Device &&
14
+ !isEmpty(this.geoService.getLatLong(contextData?.contextData)));
15
+ }
16
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TrackingTabFactory, deps: [{ token: i1.ContextRouteService }, { token: i1.GeoService }], target: i0.ɵɵFactoryTarget.Injectable }); }
17
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TrackingTabFactory, providedIn: 'root' }); }
18
+ }
19
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TrackingTabFactory, decorators: [{
20
+ type: Injectable,
21
+ args: [{
22
+ providedIn: 'root'
23
+ }]
24
+ }], ctorParameters: function () { return [{ type: i1.ContextRouteService }, { type: i1.GeoService }]; } });
25
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhY2tpbmctdGFiLmd1YXJkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHJhY2tpbmcvdHJhY2tpbmctdGFiLmd1YXJkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFHM0MsT0FBTyxFQUFFLG1CQUFtQixFQUFFLFVBQVUsRUFBRSxXQUFXLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNuRixPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sV0FBVyxDQUFDOzs7QUFLcEMsTUFBTSxPQUFPLGtCQUFrQjtJQUM3QixZQUNVLG1CQUF3QyxFQUN4QyxVQUFzQjtRQUR0Qix3QkFBbUIsR0FBbkIsbUJBQW1CLENBQXFCO1FBQ3hDLGVBQVUsR0FBVixVQUFVLENBQVk7SUFDN0IsQ0FBQztJQUVKLFdBQVcsQ0FBQyxRQUFnQztRQUMxQyxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3RFLE9BQU8sQ0FDTCxXQUFXLEVBQUUsT0FBTyxLQUFLLFdBQVcsQ0FBQyxNQUFNO1lBQzNDLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLFdBQVcsRUFBRSxXQUE2QixDQUFDLENBQUMsQ0FDakYsQ0FBQztJQUNKLENBQUM7K0dBWlUsa0JBQWtCO21IQUFsQixrQkFBa0IsY0FGakIsTUFBTTs7NEZBRVAsa0JBQWtCO2tCQUg5QixVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEFjdGl2YXRlZFJvdXRlU25hcHNob3QsIENhbkFjdGl2YXRlIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7IElNYW5hZ2VkT2JqZWN0IH0gZnJvbSAnQGM4eS9jbGllbnQnO1xuaW1wb3J0IHsgQ29udGV4dFJvdXRlU2VydmljZSwgR2VvU2VydmljZSwgVmlld0NvbnRleHQgfSBmcm9tICdAYzh5L25neC1jb21wb25lbnRzJztcbmltcG9ydCB7IGlzRW1wdHkgfSBmcm9tICdsb2Rhc2gtZXMnO1xuXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290J1xufSlcbmV4cG9ydCBjbGFzcyBUcmFja2luZ1RhYkZhY3RvcnkgaW1wbGVtZW50cyBDYW5BY3RpdmF0ZSB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgY29udGV4dFJvdXRlU2VydmljZTogQ29udGV4dFJvdXRlU2VydmljZSxcbiAgICBwcml2YXRlIGdlb1NlcnZpY2U6IEdlb1NlcnZpY2VcbiAgKSB7fVxuXG4gIGNhbkFjdGl2YXRlKHNuYXBzaG90OiBBY3RpdmF0ZWRSb3V0ZVNuYXBzaG90KTogYm9vbGVhbiB7XG4gICAgY29uc3QgY29udGV4dERhdGEgPSB0aGlzLmNvbnRleHRSb3V0ZVNlcnZpY2UuZ2V0Q29udGV4dERhdGEoc25hcHNob3QpO1xuICAgIHJldHVybiAoXG4gICAgICBjb250ZXh0RGF0YT8uY29udGV4dCA9PT0gVmlld0NvbnRleHQuRGV2aWNlICYmXG4gICAgICAhaXNFbXB0eSh0aGlzLmdlb1NlcnZpY2UuZ2V0TGF0TG9uZyhjb250ZXh0RGF0YT8uY29udGV4dERhdGEgYXMgSU1hbmFnZWRPYmplY3QpKVxuICAgICk7XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,92 @@
1
+ import { AsyncPipe } from '@angular/common';
2
+ import { Component, ViewChild } from '@angular/core';
3
+ import { FormsModule } from '@angular/forms';
4
+ import { ActivatedRoute } from '@angular/router';
5
+ import { ActionBarModule, ContextRouteService, CoreModule, EventRealtimeService, TimeIntervalComponent } from '@c8y/ngx-components';
6
+ import { MapComponent, MapModule } from '@c8y/ngx-components/map';
7
+ import { TrackingMarkerPopupComponent } from './tracking-marker-popup.component';
8
+ import { TrackingService } from './tracking.service';
9
+ import * as i0 from "@angular/core";
10
+ import * as i1 from "./tracking.service";
11
+ import * as i2 from "@c8y/ngx-components";
12
+ import * as i3 from "@angular/router";
13
+ import * as i4 from "@c8y/ngx-components/map";
14
+ import * as i5 from "@angular/common";
15
+ import * as i6 from "@angular/forms";
16
+ export class TrackingComponent {
17
+ constructor(service, realtime, contextRouteService, activatedRoute) {
18
+ this.service = service;
19
+ this.realtime = realtime;
20
+ this.contextRouteService = contextRouteService;
21
+ this.activatedRoute = activatedRoute;
22
+ this.dateRangePickerConfig = {
23
+ adaptivePosition: true,
24
+ showPreviousMonth: true,
25
+ preventChangeToNextMonth: true
26
+ };
27
+ this.config = {
28
+ realtime: false,
29
+ follow: false,
30
+ zoomLevel: 12,
31
+ fitBoundsOptions: {
32
+ padding: [50, 50]
33
+ }
34
+ };
35
+ this.maxDate = new Date();
36
+ this.activeMarkers = {};
37
+ this.realtimeDisabled = false;
38
+ }
39
+ async ngOnInit() {
40
+ const { contextData } = this.contextRouteService.getContextData(this.activatedRoute);
41
+ this.device = contextData;
42
+ this.gsmTrackingAvailable = await this.service.gsmTrackingAvailable(this.device);
43
+ }
44
+ async ngAfterViewInit() {
45
+ this.service.setDeviceId(this.device.id);
46
+ this.togglePositionRealtime(this.realtime.active);
47
+ }
48
+ toggleMarker(event) {
49
+ let marker = this.map.findMarker(event);
50
+ if (marker) {
51
+ this.map.removeMarker(marker);
52
+ delete this.activeMarkers[`p${event.id}`];
53
+ }
54
+ else {
55
+ marker = this.map.getTrackingMarker(event);
56
+ this.map.addMarkerToMap(marker);
57
+ this.activeMarkers[`p${event.id}`] = true;
58
+ }
59
+ }
60
+ togglePositionRealtime(active) {
61
+ this.config = { ...this.config, realtime: active };
62
+ }
63
+ toggleRealtime(interval) {
64
+ const currentTimeInRange = Date.now() <= interval?.dateTo?.getTime();
65
+ this.togglePositionRealtime(currentTimeInRange);
66
+ this.realtimeDisabled = !currentTimeInRange;
67
+ if (currentTimeInRange) {
68
+ this.realtime.start();
69
+ }
70
+ else {
71
+ this.realtime.stop();
72
+ }
73
+ }
74
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TrackingComponent, deps: [{ token: i1.TrackingService }, { token: i2.EventRealtimeService }, { token: i2.ContextRouteService }, { token: i3.ActivatedRoute }], target: i0.ɵɵFactoryTarget.Component }); }
75
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: TrackingComponent, isStandalone: true, selector: "ng-component", providers: [TrackingService, EventRealtimeService], viewQueries: [{ propertyName: "map", first: true, predicate: MapComponent, descendants: true }], ngImport: i0, template: "<c8y-action-bar-item\n [placement]=\"'right'\"\n [priority]=\"100\"\n>\n <c8y-realtime-btn\n [service]=\"realtime\"\n [disabled]=\"realtimeDisabled\"\n (onToggle)=\"togglePositionRealtime($event)\"\n ></c8y-realtime-btn>\n</c8y-action-bar-item>\n<c8y-action-bar-item\n *ngIf=\"gsmTrackingAvailable\"\n [placement]=\"'right'\"\n [priority]=\"80\"\n>\n <form class=\"form-inline\">\n <div class=\"c8y-select-wrapper\">\n <select\n class=\"form-control\"\n name=\"trackingOption\"\n [(ngModel)]=\"service.trackingOption\"\n (ngModelChange)=\"service.reload()\"\n >\n <option\n [ngValue]=\"undefined\"\n translate\n >\n Show all data\n </option>\n <option\n [value]=\"'gps'\"\n translate\n >\n Show GPS data\n </option>\n <option\n [value]=\"'gsm'\"\n translate\n >\n Show GSM data\n </option>\n </select>\n </div>\n </form>\n <span></span>\n</c8y-action-bar-item>\n<c8y-action-bar-item\n [placement]=\"'right'\"\n [priority]=\"60\"\n>\n <c8y-time-interval\n [maxCustomDate]=\"maxDate\"\n [dateRangePickerConfig]=\"dateRangePickerConfig\"\n (interval)=\"service.setInterval($event); toggleRealtime($event)\"\n ></c8y-time-interval>\n</c8y-action-bar-item>\n\n<div class=\"card card--grid content-fullpage d-grid grid__col--8-4--md\">\n <div class=\"bg-white p-relative\">\n <c8y-map\n [config]=\"config\"\n [assets]=\"device\"\n [polyline$]=\"service.polyline$\"\n [polylineOptions]=\"{ color: 'darkblue' }\"\n >\n <div *c8yMapPopup=\"let context\">\n <c8y-tracking-marker-popup [context]=\"context\"></c8y-tracking-marker-popup>\n </div>\n </c8y-map>\n </div>\n\n <div class=\"d-flex d-col bg-inherit content-fullpage bg-gray-white\">\n <div class=\"card-header large-padding separator sticky-top\">\n <span\n class=\"card-title\"\n translate\n >\n Tracking events\n </span>\n </div>\n <div class=\"inner-scroll\">\n <c8y-list-group class=\"c8y-list__group--strip\">\n <ng-template\n c8yFor\n let-event\n [c8yForOf]=\"service.events$\"\n [c8yForPipe]=\"service.pipe\"\n [c8yForRealtime]=\"realtime\"\n [c8yForRealtimeOptions]=\"{ entityOrId: device }\"\n [c8yForLoadMore]=\"'hidden'\"\n [c8yForNotFound]=\"empty\"\n (c8yForLoadMoreComponent)=\"\n loadMoreComponent = $event; loadMoreComponent.useIntersection = false\n \"\n >\n <c8y-li\n class=\"pointer\"\n [ngClass]=\"{ 'text-primary text-bold': activeMarkers['p' + event?.id] }\"\n (click)=\"toggleMarker(event)\"\n >\n <c8y-li-icon [ngClass]=\"{ 'text-primary': activeMarkers['p' + event?.id] }\">\n <i c8yIcon=\"c8y-location\"></i>\n </c8y-li-icon>\n <c8y-li-body>\n <div class=\"d-flex\">\n <span>\n {{ event.time | date: 'mediumDate' }}\n </span>\n <span class=\"m-l-auto\">\n {{ event.time | date: 'mediumTime' }}\n </span>\n </div>\n </c8y-li-body>\n </c8y-li>\n </ng-template>\n </c8y-list-group>\n </div>\n\n <!-- empty state -->\n <ng-template #empty>\n <c8y-ui-empty-state\n icon=\"c8y-location\"\n [title]=\"'No tracking events found.' | translate\"\n [subtitle]=\"'Select another time range.' | translate\"\n *ngIf=\"!service.hasEvents\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n </ng-template>\n\n <div *ngIf=\"loadMoreComponent?.hasMore\">\n <button\n class=\"btn btn-link fit-w sticky-bottom separator-top\"\n [title]=\"'Load more' | translate\"\n type=\"button\"\n [disabled]=\"loadMoreComponent?.isLoading\"\n (click)=\"loadMoreComponent.loadMore()\"\n >\n {{ 'Load more' | translate }}\n </button>\n </div>\n\n <div class=\"card-footer separator\">\n <button\n class=\"btn btn-default\"\n [title]=\"'Deselect all markers' | translate\"\n type=\"button\"\n [disabled]=\"(activeMarkers | json) === '{}'\"\n (click)=\"map.clearMarkers('event'); activeMarkers = {}\"\n >\n {{ 'Deselect all markers' | translate }}\n </button>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: MapModule }, { kind: "component", type: i4.MapComponent, selector: "c8y-map", inputs: ["config", "assets", "polyline$", "polylineOptions"], outputs: ["onMove", "onMoveEnd", "onZoomStart", "onZoomEnd", "onRealtimeUpdate", "onInit"] }, { kind: "directive", type: i4.MapPopupDirective, selector: "[c8yMapPopup]" }, { kind: "ngmodule", type: ActionBarModule }, { kind: "component", type: i2.ActionBarItemComponent, selector: "c8y-action-bar-item", inputs: ["placement", "priority", "itemClass", "injector", "groupId", "inGroupPriority"] }, { kind: "ngmodule", type: CoreModule }, { kind: "component", type: i2.EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "directive", type: i2.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "pipe", type: i2.C8yTranslatePipe, name: "translate" }, { kind: "directive", type: i2.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i5.JsonPipe, name: "json" }, { kind: "pipe", type: i5.DatePipe, name: "date" }, { kind: "directive", type: i2.ForOfDirective, selector: "[c8yFor]", inputs: ["c8yForOf", "c8yForLoadMore", "c8yForPipe", "c8yForNotFound", "c8yForMaxIterations", "c8yForLoadingTemplate", "c8yForLoadNextLabel", "c8yForLoadingLabel", "c8yForRealtime", "c8yForRealtimeOptions", "c8yForComparator", "c8yForEnableVirtualScroll", "c8yForVirtualScrollElementSize", "c8yForVirtualScrollStrategy", "c8yForVirtualScrollContainerHeight"], outputs: ["c8yForCount", "c8yForLoadMoreComponent"] }, { kind: "directive", type: i6.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i6.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i6.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i6.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i6.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i6.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i6.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i2.ListGroupComponent, selector: "c8y-list-group" }, { kind: "component", type: i2.ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "emptyActions", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "component", type: i2.ListItemIconComponent, selector: "c8y-list-item-icon, c8y-li-icon", inputs: ["icon", "status"] }, { kind: "component", type: i2.ListItemBodyComponent, selector: "c8y-list-item-body, c8y-li-body", inputs: ["body"] }, { kind: "component", type: i2.RealtimeButtonComponent, selector: "c8y-realtime-btn", inputs: ["service", "label", "title", "disabled"], outputs: ["onToggle"] }, { kind: "component", type: i2.TimeIntervalComponent, selector: "c8y-time-interval", inputs: ["minCustomDate", "maxCustomDate", "dateRangePickerConfig", "selectedInterval"], outputs: ["interval"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: TrackingMarkerPopupComponent, selector: "c8y-tracking-marker-popup", inputs: ["context"] }] }); }
76
+ }
77
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TrackingComponent, decorators: [{
78
+ type: Component,
79
+ args: [{ standalone: true, imports: [
80
+ MapModule,
81
+ AsyncPipe,
82
+ ActionBarModule,
83
+ CoreModule,
84
+ TimeIntervalComponent,
85
+ FormsModule,
86
+ TrackingMarkerPopupComponent
87
+ ], providers: [TrackingService, EventRealtimeService], template: "<c8y-action-bar-item\n [placement]=\"'right'\"\n [priority]=\"100\"\n>\n <c8y-realtime-btn\n [service]=\"realtime\"\n [disabled]=\"realtimeDisabled\"\n (onToggle)=\"togglePositionRealtime($event)\"\n ></c8y-realtime-btn>\n</c8y-action-bar-item>\n<c8y-action-bar-item\n *ngIf=\"gsmTrackingAvailable\"\n [placement]=\"'right'\"\n [priority]=\"80\"\n>\n <form class=\"form-inline\">\n <div class=\"c8y-select-wrapper\">\n <select\n class=\"form-control\"\n name=\"trackingOption\"\n [(ngModel)]=\"service.trackingOption\"\n (ngModelChange)=\"service.reload()\"\n >\n <option\n [ngValue]=\"undefined\"\n translate\n >\n Show all data\n </option>\n <option\n [value]=\"'gps'\"\n translate\n >\n Show GPS data\n </option>\n <option\n [value]=\"'gsm'\"\n translate\n >\n Show GSM data\n </option>\n </select>\n </div>\n </form>\n <span></span>\n</c8y-action-bar-item>\n<c8y-action-bar-item\n [placement]=\"'right'\"\n [priority]=\"60\"\n>\n <c8y-time-interval\n [maxCustomDate]=\"maxDate\"\n [dateRangePickerConfig]=\"dateRangePickerConfig\"\n (interval)=\"service.setInterval($event); toggleRealtime($event)\"\n ></c8y-time-interval>\n</c8y-action-bar-item>\n\n<div class=\"card card--grid content-fullpage d-grid grid__col--8-4--md\">\n <div class=\"bg-white p-relative\">\n <c8y-map\n [config]=\"config\"\n [assets]=\"device\"\n [polyline$]=\"service.polyline$\"\n [polylineOptions]=\"{ color: 'darkblue' }\"\n >\n <div *c8yMapPopup=\"let context\">\n <c8y-tracking-marker-popup [context]=\"context\"></c8y-tracking-marker-popup>\n </div>\n </c8y-map>\n </div>\n\n <div class=\"d-flex d-col bg-inherit content-fullpage bg-gray-white\">\n <div class=\"card-header large-padding separator sticky-top\">\n <span\n class=\"card-title\"\n translate\n >\n Tracking events\n </span>\n </div>\n <div class=\"inner-scroll\">\n <c8y-list-group class=\"c8y-list__group--strip\">\n <ng-template\n c8yFor\n let-event\n [c8yForOf]=\"service.events$\"\n [c8yForPipe]=\"service.pipe\"\n [c8yForRealtime]=\"realtime\"\n [c8yForRealtimeOptions]=\"{ entityOrId: device }\"\n [c8yForLoadMore]=\"'hidden'\"\n [c8yForNotFound]=\"empty\"\n (c8yForLoadMoreComponent)=\"\n loadMoreComponent = $event; loadMoreComponent.useIntersection = false\n \"\n >\n <c8y-li\n class=\"pointer\"\n [ngClass]=\"{ 'text-primary text-bold': activeMarkers['p' + event?.id] }\"\n (click)=\"toggleMarker(event)\"\n >\n <c8y-li-icon [ngClass]=\"{ 'text-primary': activeMarkers['p' + event?.id] }\">\n <i c8yIcon=\"c8y-location\"></i>\n </c8y-li-icon>\n <c8y-li-body>\n <div class=\"d-flex\">\n <span>\n {{ event.time | date: 'mediumDate' }}\n </span>\n <span class=\"m-l-auto\">\n {{ event.time | date: 'mediumTime' }}\n </span>\n </div>\n </c8y-li-body>\n </c8y-li>\n </ng-template>\n </c8y-list-group>\n </div>\n\n <!-- empty state -->\n <ng-template #empty>\n <c8y-ui-empty-state\n icon=\"c8y-location\"\n [title]=\"'No tracking events found.' | translate\"\n [subtitle]=\"'Select another time range.' | translate\"\n *ngIf=\"!service.hasEvents\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n </ng-template>\n\n <div *ngIf=\"loadMoreComponent?.hasMore\">\n <button\n class=\"btn btn-link fit-w sticky-bottom separator-top\"\n [title]=\"'Load more' | translate\"\n type=\"button\"\n [disabled]=\"loadMoreComponent?.isLoading\"\n (click)=\"loadMoreComponent.loadMore()\"\n >\n {{ 'Load more' | translate }}\n </button>\n </div>\n\n <div class=\"card-footer separator\">\n <button\n class=\"btn btn-default\"\n [title]=\"'Deselect all markers' | translate\"\n type=\"button\"\n [disabled]=\"(activeMarkers | json) === '{}'\"\n (click)=\"map.clearMarkers('event'); activeMarkers = {}\"\n >\n {{ 'Deselect all markers' | translate }}\n </button>\n </div>\n </div>\n</div>\n" }]
88
+ }], ctorParameters: function () { return [{ type: i1.TrackingService }, { type: i2.EventRealtimeService }, { type: i2.ContextRouteService }, { type: i3.ActivatedRoute }]; }, propDecorators: { map: [{
89
+ type: ViewChild,
90
+ args: [MapComponent]
91
+ }] } });
92
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhY2tpbmcuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHJhY2tpbmcvdHJhY2tpbmcuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vdHJhY2tpbmcvdHJhY2tpbmcuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzVDLE9BQU8sRUFBaUIsU0FBUyxFQUFVLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUM1RSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0MsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRWpELE9BQU8sRUFDTCxlQUFlLEVBQ2YsbUJBQW1CLEVBQ25CLFVBQVUsRUFFVixvQkFBb0IsRUFHcEIscUJBQXFCLEVBQ3RCLE1BQU0scUJBQXFCLENBQUM7QUFDN0IsT0FBTyxFQUFFLFlBQVksRUFBYSxTQUFTLEVBQXlCLE1BQU0seUJBQXlCLENBQUM7QUFDcEcsT0FBTyxFQUFFLDRCQUE0QixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDakYsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLG9CQUFvQixDQUFDOzs7Ozs7OztBQWdCckQsTUFBTSxPQUFPLGlCQUFpQjtJQTBCNUIsWUFDUyxPQUF3QixFQUN4QixRQUE4QixFQUM3QixtQkFBd0MsRUFDeEMsY0FBOEI7UUFIL0IsWUFBTyxHQUFQLE9BQU8sQ0FBaUI7UUFDeEIsYUFBUSxHQUFSLFFBQVEsQ0FBc0I7UUFDN0Isd0JBQW1CLEdBQW5CLG1CQUFtQixDQUFxQjtRQUN4QyxtQkFBYyxHQUFkLGNBQWMsQ0FBZ0I7UUExQnhDLDBCQUFxQixHQUEwQjtZQUM3QyxnQkFBZ0IsRUFBRSxJQUFJO1lBQ3RCLGlCQUFpQixFQUFFLElBQUk7WUFDdkIsd0JBQXdCLEVBQUUsSUFBSTtTQUMvQixDQUFDO1FBRUYs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QUE0QjtxQkFDN0IsYUFDVSxDQUFDLGVBQWUsRUFBRSxvQkFBb0IsQ0FBQzt3TUFJbEQsR0FBRztzQkFERixTQUFTO3VCQUFDLFlBQVkiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBc3luY1BpcGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgQWZ0ZXJWaWV3SW5pdCwgQ29tcG9uZW50LCBPbkluaXQsIFZpZXdDaGlsZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBBY3RpdmF0ZWRSb3V0ZSB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBJRXZlbnQgfSBmcm9tICdAYzh5L2NsaWVudCc7XG5pbXBvcnQge1xuICBBY3Rpb25CYXJNb2R1bGUsXG4gIENvbnRleHRSb3V0ZVNlcnZpY2UsXG4gIENvcmVNb2R1bGUsXG4gIERhdGVSYW5nZVBpY2tlckNvbmZpZyxcbiAgRXZlbnRSZWFsdGltZVNlcnZpY2UsXG4gIExvYWRNb3JlQ29tcG9uZW50LFxuICBUaW1lSW50ZXJ2YWwsXG4gIFRpbWVJbnRlcnZhbENvbXBvbmVudFxufSBmcm9tICdAYzh5L25neC1jb21wb25lbnRzJztcbmltcG9ydCB7IE1hcENvbXBvbmVudCwgTWFwQ29uZmlnLCBNYXBNb2R1bGUsIFBvc2l0aW9uTWFuYWdlZE9iamVjdCB9IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMvbWFwJztcbmltcG9ydCB7IFRyYWNraW5nTWFya2VyUG9wdXBDb21wb25lbnQgfSBmcm9tICcuL3RyYWNraW5nLW1hcmtlci1wb3B1cC5jb21wb25lbnQnO1xuaW1wb3J0IHsgVHJhY2tpbmdTZXJ2aWNlIH0gZnJvbSAnLi90cmFja2luZy5zZXJ2aWNlJztcblxuQENvbXBvbmVudCh7XG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIHRlbXBsYXRlVXJsOiAnLi90cmFja2luZy5jb21wb25lbnQuaHRtbCcsXG4gIGltcG9ydHM6IFtcbiAgICBNYXBNb2R1bGUsXG4gICAgQXN5bmNQaXBlLFxuICAgIEFjdGlvbkJhck1vZHVsZSxcbiAgICBDb3JlTW9kdWxlLFxuICAgIFRpbWVJbnRlcnZhbENvbXBvbmVudCxcbiAgICBGb3Jtc01vZHVsZSxcbiAgICBUcmFja2luZ01hcmtlclBvcHVwQ29tcG9uZW50XG4gIF0sXG4gIHByb3ZpZGVyczogW1RyYWNraW5nU2VydmljZSwgRXZlbnRSZWFsdGltZVNlcnZpY2VdXG59KVxuZXhwb3J0IGNsYXNzIFRyYWNraW5nQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBBZnRlclZpZXdJbml0IHtcbiAgQFZpZXdDaGlsZChNYXBDb21wb25lbnQpXG4gIG1hcDogTWFwQ29tcG9uZW50O1xuXG4gIGRhdGVSYW5nZVBpY2tlckNvbmZpZzogRGF0ZVJhbmdlUGlja2VyQ29uZmlnID0ge1xuICAgIGFkYXB0aXZlUG9zaXRpb246IHRydWUsXG4gICAgc2hvd1ByZXZpb3VzTW9udGg6IHRydWUsXG4gICAgcHJldmVudENoYW5nZVRvTmV4dE1vbnRoOiB0cnVlXG4gIH07XG5cbiAgY29uZmlnOiBNYXBDb25maWcgPSB7XG4gICAgcmVhbHRpbWU6IGZhbHNlLFxuICAgIGZvbGxvdzogZmFsc2UsXG4gICAgem9vbUxldmVsOiAxMixcbiAgICBmaXRCb3VuZHNPcHRpb25zOiB7XG4gICAgICBwYWRkaW5nOiBbNTAsIDUwXVxuICAgIH1cbiAgfTtcblxuICBtYXhEYXRlID0gbmV3IERhdGUoKTtcbiAgYWN0aXZlTWFya2VyczogeyBba2V5OiBzdHJpbmddOiBib29sZWFuIH0gPSB7fTtcbiAgcmVhbHRpbWVEaXNhYmxlZCA9IGZhbHNlO1xuICBnc21UcmFja2luZ0F2YWlsYWJsZTogYm9vbGVhbjtcbiAgZGV2aWNlOiBQb3NpdGlvbk1hbmFnZWRPYmplY3Q7XG4gIGxvYWRNb3JlQ29tcG9uZW50OiBMb2FkTW9yZUNvbXBvbmVudDtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgc2VydmljZTogVHJhY2tpbmdTZXJ2aWNlLFxuICAgIHB1YmxpYyByZWFsdGltZTogRXZlbnRSZWFsdGltZVNlcnZpY2UsXG4gICAgcHJpdmF0ZSBjb250ZXh0Um91dGVTZXJ2aWNlOiBDb250ZXh0Um91dGVTZXJ2aWNlLFxuICAgIHByaXZhdGUgYWN0aXZhdGVkUm91dGU6IEFjdGl2YXRlZFJvdXRlXG4gICkge31cblxuICBhc3luYyBuZ09uSW5pdCgpIHtcbiAgICBjb25zdCB7IGNvbnRleHREYXRhIH0gPSB0aGlzLmNvbnRleHRSb3V0ZVNlcnZpY2UuZ2V0Q29udGV4dERhdGEodGhpcy5hY3RpdmF0ZWRSb3V0ZSk7XG4gICAgdGhpcy5kZXZpY2UgPSBjb250ZXh0RGF0YSBhcyBQb3NpdGlvbk1hbmFnZWRPYmplY3Q7XG4gICAgdGhpcy5nc21UcmFja2luZ0F2YWlsYWJsZSA9IGF3YWl0IHRoaXMuc2VydmljZS5nc21UcmFja2luZ0F2YWlsYWJsZSh0aGlzLmRldmljZSk7XG4gIH1cblxuICBhc3luYyBuZ0FmdGVyVmlld0luaXQoKSB7XG4gICAgdGhpcy5zZXJ2aWNlLnNldERldmljZUlkKHRoaXMuZGV2aWNlLmlkKTtcbiAgICB0aGlzLnRvZ2dsZVBvc2l0aW9uUmVhbHRpbWUodGhpcy5yZWFsdGltZS5hY3RpdmUpO1xuICB9XG5cbiAgdG9nZ2xlTWFya2VyKGV2ZW50OiBJRXZlbnQpIHtcbiAgICBsZXQgbWFya2VyID0gdGhpcy5tYXAuZmluZE1hcmtlcihldmVudCk7XG5cbiAgICBpZiAobWFya2VyKSB7XG4gICAgICB0aGlzLm1hcC5yZW1vdmVNYXJrZXIobWFya2VyKTtcbiAgICAgIGRlbGV0ZSB0aGlzLmFjdGl2ZU1hcmtlcnNbYHAke2V2ZW50LmlkfWBdO1xuICAgIH0gZWxzZSB7XG4gICAgICBtYXJrZXIgPSB0aGlzLm1hcC5nZXRUcmFja2luZ01hcmtlcihldmVudCk7XG4gICAgICB0aGlzLm1hcC5hZGRNYXJrZXJUb01hcChtYXJrZXIpO1xuICAgICAgdGhpcy5hY3RpdmVNYXJrZXJzW2BwJHtldmVudC5pZH1gXSA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgdG9nZ2xlUG9zaXRpb25SZWFsdGltZShhY3RpdmU6IGJvb2xlYW4pIHtcbiAgICB0aGlzLmNvbmZpZyA9IHsgLi4udGhpcy5jb25maWcsIHJlYWx0aW1lOiBhY3RpdmUgfTtcbiAgfVxuXG4gIHRvZ2dsZVJlYWx0aW1lKGludGVydmFsOiBUaW1lSW50ZXJ2YWwpIHtcbiAgICBjb25zdCBjdXJyZW50VGltZUluUmFuZ2UgPSBEYXRlLm5vdygpIDw9IGludGVydmFsPy5kYXRlVG8/LmdldFRpbWUoKTtcbiAgICB0aGlzLnRvZ2dsZVBvc2l0aW9uUmVhbHRpbWUoY3VycmVudFRpbWVJblJhbmdlKTtcbiAgICB0aGlzLnJlYWx0aW1lRGlzYWJsZWQgPSAhY3VycmVudFRpbWVJblJhbmdlO1xuXG4gICAgaWYgKGN1cnJlbnRUaW1lSW5SYW5nZSkge1xuICAgICAgdGhpcy5yZWFsdGltZS5zdGFydCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnJlYWx0aW1lLnN0b3AoKTtcbiAgICB9XG4gIH1cbn1cbiIsIjxjOHktYWN0aW9uLWJhci1pdGVtXG4gIFtwbGFjZW1lbnRdPVwiJ3JpZ2h0J1wiXG4gIFtwcmlvcml0eV09XCIxMDBcIlxuPlxuICA8Yzh5LXJlYWx0aW1lLWJ0blxuICAgIFtzZXJ2aWNlXT1cInJlYWx0aW1lXCJcbiAgICBbZGlzYWJsZWRdPVwicmVhbHRpbWVEaXNhYmxlZFwiXG4gICAgKG9uVG9nZ2xlKT1cInRvZ2dsZVBvc2l0aW9uUmVhbHRpbWUoJGV2ZW50KVwiXG4gID48L2M4eS1yZWFsdGltZS1idG4+XG48L2M4eS1hY3Rpb24tYmFyLWl0ZW0+XG48Yzh5LWFjdGlvbi1iYXItaXRlbVxuICAqbmdJZj1cImdzbVRyYWNraW5nQXZhaWxhYmxlXCJcbiAgW3BsYWNlbWVudF09XCIncmlnaHQnXCJcbiAgW3ByaW9yaXR5XT1cIjgwXCJcbj5cbiAgPGZvcm0gY2xhc3M9XCJmb3JtLWlubGluZVwiPlxuICAgIDxkaXYgY2xhc3M9XCJjOHktc2VsZWN0LXdyYXBwZXJcIj5cbiAgICAgIDxzZWxlY3RcbiAgICAgICAgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIlxuICAgICAgICBuYW1lPVwidHJhY2tpbmdPcHRpb25cIlxuICAgICAgICBbKG5nTW9kZWwpXT1cInNlcnZpY2UudHJhY2tpbmdPcHRpb25cIlxuICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJzZXJ2aWNlLnJlbG9hZCgpXCJcbiAgICAgID5cbiAgICAgICAgPG9wdGlvblxuICAgICAgICAgIFtuZ1ZhbHVlXT1cInVuZGVmaW5lZFwiXG4gICAgICAgICAgdHJhbnNsYXRlXG4gICAgICAgID5cbiAgICAgICAgICBTaG93IGFsbCBkYXRhXG4gICAgICAgIDwvb3B0aW9uPlxuICAgICAgICA8b3B0aW9uXG4gICAgICAgICAgW3ZhbHVlXT1cIidncHMnXCJcbiAgICAgICAgICB0cmFuc2xhdGVcbiAgICAgICAgPlxuICAgICAgICAgIFNob3cgR1BTIGRhdGFcbiAgICAgICAgPC9vcHRpb24+XG4gICAgICAgIDxvcHRpb25cbiAgICAgICAgICBbdmFsdWVdPVwiJ2dzbSdcIlxuICAgICAgICAgIHRyYW5zbGF0ZVxuICAgICAgICA+XG4gICAgICAgICAgU2hvdyBHU00gZGF0YVxuICAgICAgICA8L29wdGlvbj5cbiAgICAgIDwvc2VsZWN0PlxuICAgIDwvZGl2PlxuICA8L2Zvcm0+XG4gIDxzcGFuPjwvc3Bhbj5cbjwvYzh5LWFjdGlvbi1iYXItaXRlbT5cbjxjOHktYWN0aW9uLWJhci1pdGVtXG4gIFtwbGFjZW1lbnRdPVwiJ3JpZ2h0J1wiXG4gIFtwcmlvcml0eV09XCI2MFwiXG4+XG4gIDxjOHktdGltZS1pbnRlcnZhbFxuICAgIFttYXhDdXN0b21EYXRlXT1cIm1heERhdGVcIlxuICAgIFtkYXRlUmFuZ2VQaWNrZXJDb25maWddPVwiZGF0ZVJhbmdlUGlja2VyQ29uZmlnXCJcbiAgICAoaW50ZXJ2YWwpPVwic2VydmljZS5zZXRJbnRlcnZhbCgkZXZlbnQpOyB0b2dnbGVSZWFsdGltZSgkZXZlbnQpXCJcbiAgPjwvYzh5LXRpbWUtaW50ZXJ2YWw+XG48L2M4eS1hY3Rpb24tYmFyLWl0ZW0+XG5cbjxkaXYgY2xhc3M9XCJjYXJkIGNhcmQtLWdyaWQgY29udGVudC1mdWxscGFnZSBkLWdyaWQgZ3JpZF9fY29sLS04LTQtLW1kXCI+XG4gIDxkaXYgY2xhc3M9XCJiZy13aGl0ZSBwLXJlbGF0aXZlXCI+XG4gICAgPGM4eS1tYXBcbiAgICAgIFtjb25maWddPVwiY29uZmlnXCJcbiAgICAgIFthc3NldHNdPVwiZGV2aWNlXCJcbiAgICAgIFtwb2x5bGluZSRdPVwic2VydmljZS5wb2x5bGluZSRcIlxuICAgICAgW3BvbHlsaW5lT3B0aW9uc109XCJ7IGNvbG9yOiAnZGFya2JsdWUnIH1cIlxuICAgID5cbiAgICAgIDxkaXYgKmM4eU1hcFBvcHVwPVwibGV0IGNvbnRleHRcIj5cbiAgICAgICAgPGM4eS10cmFja2luZy1tYXJrZXItcG9wdXAgW2NvbnRleHRdPVwiY29udGV4dFwiPjwvYzh5LXRyYWNraW5nLW1hcmtlci1wb3B1cD5cbiAgICAgIDwvZGl2PlxuICAgIDwvYzh5LW1hcD5cbiAgPC9kaXY+XG5cbiAgPGRpdiBjbGFzcz1cImQtZmxleCBkLWNvbCBiZy1pbmhlcml0IGNvbnRlbnQtZnVsbHBhZ2UgYmctZ3JheS13aGl0ZVwiPlxuICAgIDxkaXYgY2xhc3M9XCJjYXJkLWhlYWRlciBsYXJnZS1wYWRkaW5nIHNlcGFyYXRvciBzdGlja3ktdG9wXCI+XG4gICAgICA8c3BhblxuICAgICAgICBjbGFzcz1cImNhcmQtdGl0bGVcIlxuICAgICAgICB0cmFuc2xhdGVcbiAgICAgID5cbiAgICAgICAgVHJhY2tpbmcgZXZlbnRzXG4gICAgICA8L3NwYW4+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cImlubmVyLXNjcm9sbFwiPlxuICAgICAgPGM4eS1saXN0LWdyb3VwIGNsYXNzPVwiYzh5LWxpc3RfX2dyb3VwLS1zdHJpcFwiPlxuICAgICAgICA8bmctdGVtcGxhdGVcbiAgICAgICAgICBjOHlGb3JcbiAgICAgICAgICBsZXQtZXZlbnRcbiAgICAgICAgICBbYzh5Rm9yT2ZdPVwic2VydmljZS5ldmVudHMkXCJcbiAgICAgICAgICBbYzh5Rm9yUGlwZV09XCJzZXJ2aWNlLnBpcGVcIlxuICAgICAgICAgIFtjOHlGb3JSZWFsdGltZV09XCJyZWFsdGltZVwiXG4gICAgICAgICAgW2M4eUZvclJlYWx0aW1lT3B0aW9uc109XCJ7IGVudGl0eU9ySWQ6IGRldmljZSB9XCJcbiAgICAgICAgICBbYzh5Rm9yTG9hZE1vcmVdPVwiJ2hpZGRlbidcIlxuICAgICAgICAgIFtjOHlGb3JOb3RGb3VuZF09XCJlbXB0eVwiXG4gICAgICAgICAgKGM4eUZvckxvYWRNb3JlQ29tcG9uZW50KT1cIlxuICAgICAgICAgICAgbG9hZE1vcmVDb21wb25lbnQgPSAkZXZlbnQ7IGxvYWRNb3JlQ29tcG9uZW50LnVzZUludGVyc2VjdGlvbiA9IGZhbHNlXG4gICAgICAgICAgXCJcbiAgICAgICAgPlxuICAgICAgICAgIDxjOHktbGlcbiAgICAgICAgICAgIGNsYXNzPVwicG9pbnRlclwiXG4gICAgICAgICAgICBbbmdDbGFzc109XCJ7ICd0ZXh0LXByaW1hcnkgdGV4dC1ib2xkJzogYWN0aXZlTWFya2Vyc1sncCcgKyBldmVudD8uaWRdIH1cIlxuICAgICAgICAgICAgKGNsaWNrKT1cInRvZ2dsZU1hcmtlcihldmVudClcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIDxjOHktbGktaWNvbiBbbmdDbGFzc109XCJ7ICd0ZXh0LXByaW1hcnknOiBhY3RpdmVNYXJrZXJzWydwJyArIGV2ZW50Py5pZF0gfVwiPlxuICAgICAgICAgICAgICA8aSBjOHlJY29uPVwiYzh5LWxvY2F0aW9uXCI+PC9pPlxuICAgICAgICAgICAgPC9jOHktbGktaWNvbj5cbiAgICAgICAgICAgIDxjOHktbGktYm9keT5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleFwiPlxuICAgICAgICAgICAgICAgIDxzcGFuPlxuICAgICAgICAgICAgICAgICAge3sgZXZlbnQudGltZSB8IGRhdGU6ICdtZWRpdW1EYXRlJyB9fVxuICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm0tbC1hdXRvXCI+XG4gICAgICAgICAgICAgICAgICB7eyBldmVudC50aW1lIHwgZGF0ZTogJ21lZGl1bVRpbWUnIH19XG4gICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvYzh5LWxpLWJvZHk+XG4gICAgICAgICAgPC9jOHktbGk+XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICA8L2M4eS1saXN0LWdyb3VwPlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSBlbXB0eSBzdGF0ZSAtLT5cbiAgICA8bmctdGVtcGxhdGUgI2VtcHR5PlxuICAgICAgPGM4eS11aS1lbXB0eS1zdGF0ZVxuICAgICAgICBpY29uPVwiYzh5LWxvY2F0aW9uXCJcbiAgICAgICAgW3RpdGxlXT1cIidObyB0cmFja2luZyBldmVudHMgZm91bmQuJyB8IHRyYW5zbGF0ZVwiXG4gICAgICAgIFtzdWJ0aXRsZV09XCInU2VsZWN0IGFub3RoZXIgdGltZSByYW5nZS4nIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgKm5nSWY9XCIhc2VydmljZS5oYXNFdmVudHNcIlxuICAgICAgICBbaG9yaXpvbnRhbF09XCJ0cnVlXCJcbiAgICAgID48L2M4eS11aS1lbXB0eS1zdGF0ZT5cbiAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgPGRpdiAqbmdJZj1cImxvYWRNb3JlQ29tcG9uZW50Py5oYXNNb3JlXCI+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIGNsYXNzPVwiYnRuIGJ0bi1saW5rIGZpdC13IHN0aWNreS1ib3R0b20gc2VwYXJhdG9yLXRvcFwiXG4gICAgICAgIFt0aXRsZV09XCInTG9hZCBtb3JlJyB8IHRyYW5zbGF0ZVwiXG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICBbZGlzYWJsZWRdPVwibG9hZE1vcmVDb21wb25lbnQ/LmlzTG9hZGluZ1wiXG4gICAgICAgIChjbGljayk9XCJsb2FkTW9yZUNvbXBvbmVudC5sb2FkTW9yZSgpXCJcbiAgICAgID5cbiAgICAgICAge3sgJ0xvYWQgbW9yZScgfCB0cmFuc2xhdGUgfX1cbiAgICAgIDwvYnV0dG9uPlxuICAgIDwvZGl2PlxuXG4gICAgPGRpdiBjbGFzcz1cImNhcmQtZm9vdGVyIHNlcGFyYXRvclwiPlxuICAgICAgPGJ1dHRvblxuICAgICAgICBjbGFzcz1cImJ0biBidG4tZGVmYXVsdFwiXG4gICAgICAgIFt0aXRsZV09XCInRGVzZWxlY3QgYWxsIG1hcmtlcnMnIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgIFtkaXNhYmxlZF09XCIoYWN0aXZlTWFya2VycyB8IGpzb24pID09PSAne30nXCJcbiAgICAgICAgKGNsaWNrKT1cIm1hcC5jbGVhck1hcmtlcnMoJ2V2ZW50Jyk7IGFjdGl2ZU1hcmtlcnMgPSB7fVwiXG4gICAgICA+XG4gICAgICAgIHt7ICdEZXNlbGVjdCBhbGwgbWFya2VycycgfCB0cmFuc2xhdGUgfX1cbiAgICAgIDwvYnV0dG9uPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvZGl2PlxuIl19
@@ -0,0 +1,16 @@
1
+ import { makeEnvironmentProviders } from '@angular/core';
2
+ import { gettext, hookRoute, ViewContext } from '@c8y/ngx-components';
3
+ import { TrackingTabFactory } from './tracking-tab.guard';
4
+ import { TrackingComponent } from './tracking.component';
5
+ export const trackingFeatureProvider = makeEnvironmentProviders([
6
+ TrackingTabFactory,
7
+ hookRoute({
8
+ path: 'tracking',
9
+ component: TrackingComponent,
10
+ context: ViewContext.Device,
11
+ label: gettext('Tracking'),
12
+ icon: 'crosshairs',
13
+ canActivate: [TrackingTabFactory]
14
+ })
15
+ ]);
16
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhY2tpbmcuZmVhdHVyZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RyYWNraW5nL3RyYWNraW5nLmZlYXR1cmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUF3Qix3QkFBd0IsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMvRSxPQUFPLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxXQUFXLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUN0RSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUMxRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUV6RCxNQUFNLENBQUMsTUFBTSx1QkFBdUIsR0FBeUIsd0JBQXdCLENBQUM7SUFDcEYsa0JBQWtCO0lBQ2xCLFNBQVMsQ0FBQztRQUNSLElBQUksRUFBRSxVQUFVO1FBQ2hCLFNBQVMsRUFBRSxpQkFBaUI7UUFDNUIsT0FBTyxFQUFFLFdBQVcsQ0FBQyxNQUFNO1FBQzNCLEtBQUssRUFBRSxPQUFPLENBQUMsVUFBVSxDQUFDO1FBQzFCLElBQUksRUFBRSxZQUFZO1FBQ2xCLFdBQVcsRUFBRSxDQUFDLGtCQUFrQixDQUFDO0tBQ2xDLENBQUM7Q0FDSCxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBFbnZpcm9ubWVudFByb3ZpZGVycywgbWFrZUVudmlyb25tZW50UHJvdmlkZXJzIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBnZXR0ZXh0LCBob29rUm91dGUsIFZpZXdDb250ZXh0IH0gZnJvbSAnQGM4eS9uZ3gtY29tcG9uZW50cyc7XG5pbXBvcnQgeyBUcmFja2luZ1RhYkZhY3RvcnkgfSBmcm9tICcuL3RyYWNraW5nLXRhYi5ndWFyZCc7XG5pbXBvcnQgeyBUcmFja2luZ0NvbXBvbmVudCB9IGZyb20gJy4vdHJhY2tpbmcuY29tcG9uZW50JztcblxuZXhwb3J0IGNvbnN0IHRyYWNraW5nRmVhdHVyZVByb3ZpZGVyOiBFbnZpcm9ubWVudFByb3ZpZGVycyA9IG1ha2VFbnZpcm9ubWVudFByb3ZpZGVycyhbXG4gIFRyYWNraW5nVGFiRmFjdG9yeSxcbiAgaG9va1JvdXRlKHtcbiAgICBwYXRoOiAndHJhY2tpbmcnLFxuICAgIGNvbXBvbmVudDogVHJhY2tpbmdDb21wb25lbnQsXG4gICAgY29udGV4dDogVmlld0NvbnRleHQuRGV2aWNlLFxuICAgIGxhYmVsOiBnZXR0ZXh0KCdUcmFja2luZycpLFxuICAgIGljb246ICdjcm9zc2hhaXJzJyxcbiAgICBjYW5BY3RpdmF0ZTogW1RyYWNraW5nVGFiRmFjdG9yeV1cbiAgfSlcbl0pO1xuIl19
@@ -0,0 +1,124 @@
1
+ import { __decorate, __metadata } from "tslib";
2
+ import { Injectable } from '@angular/core';
3
+ import { ApplicationService, EventService } from '@c8y/client';
4
+ import { GeoService, memoize } from '@c8y/ngx-components';
5
+ import { first, get, identity, isEmpty, last } from 'lodash-es';
6
+ import { BehaviorSubject, combineLatest, pipe, Subject } from 'rxjs';
7
+ import { map, share, switchMap, tap } from 'rxjs/operators';
8
+ import * as i0 from "@angular/core";
9
+ import * as i1 from "@c8y/client";
10
+ import * as i2 from "@c8y/ngx-components";
11
+ const LOCATION_UPDATE_EVENT_TYPE = 'c8y_LocationUpdate';
12
+ export class TrackingService {
13
+ static { this.BASE_FILTER = {
14
+ pageSize: 1000,
15
+ withTotalPages: true,
16
+ type: LOCATION_UPDATE_EVENT_TYPE
17
+ }; }
18
+ constructor(eventService, applicationService, geo) {
19
+ this.eventService = eventService;
20
+ this.applicationService = applicationService;
21
+ this.geo = geo;
22
+ this.trackVisible = true;
23
+ this.hasEvents = false;
24
+ this._polylineEventsSubject$ = new BehaviorSubject([]);
25
+ this.deviceId$ = new Subject();
26
+ this.timeInterval$ = new Subject();
27
+ this.reload$ = new BehaviorSubject(null);
28
+ this.polyline$ = this._polylineEventsSubject$.asObservable().pipe(map(events => (events || []).map(event => this.geo.getLatLong(event)).filter(identity)), share());
29
+ this.events$ = combineLatest([this.deviceId$, this.timeInterval$, this.reload$]).pipe(switchMap(([source, interval]) => {
30
+ const { dateFrom, dateTo } = interval;
31
+ return this.eventService.list({
32
+ ...TrackingService.BASE_FILTER,
33
+ source,
34
+ dateFrom: dateFrom.toISOString(),
35
+ dateTo: dateTo.toISOString()
36
+ });
37
+ }), tap(() => this._polylineEventsSubject$.next([])), share());
38
+ this.pipe = pipe(tap(events => (this.hasEvents = !isEmpty(events))), map((events) => (events || []).filter(event => this.isMatchingEvent(event))), tap((events) => {
39
+ const prepend = this.compareEvents(last(this._polylineEventsSubject$.value), first(events)) < 0;
40
+ const polyline = prepend
41
+ ? [...events, ...this._polylineEventsSubject$.value]
42
+ : [...this._polylineEventsSubject$.value, ...events];
43
+ this._polylineEventsSubject$.next(polyline);
44
+ }));
45
+ }
46
+ setDeviceId(deviceId) {
47
+ this.deviceId$.next(deviceId);
48
+ }
49
+ setInterval(interval) {
50
+ this.timeInterval$.next(interval);
51
+ }
52
+ clearTrack() {
53
+ this._polylineEventsSubject$.next([]);
54
+ }
55
+ reload() {
56
+ this.reload$.next();
57
+ }
58
+ async latestPositionUpdate(mo) {
59
+ const dateTo = new Date();
60
+ dateTo.setDate(dateTo.getDate() + 1);
61
+ const filters = {
62
+ fragmentType: 'c8y_Position',
63
+ dateFrom: new Date(0).toISOString(),
64
+ dateTo: dateTo.toISOString(),
65
+ pageSize: 1,
66
+ source: mo.id
67
+ };
68
+ const events = await this.eventService.list(filters);
69
+ return events?.data?.length ? new Date(events.data[0].time) : undefined;
70
+ }
71
+ async gsmTrackingAvailable(device) {
72
+ const apps = (await this.applicationService.listByUser())?.data || [];
73
+ const appAvailable = apps.some(app => ['cellid-application-key', 'cellid-key'].some(key => app.key === key));
74
+ return appAvailable && !!(device.c8y_CellInfo || device.c8y_Mobile);
75
+ }
76
+ toggleTrack() {
77
+ if (this.trackVisible) {
78
+ this.clearTrack();
79
+ }
80
+ else {
81
+ this.reload();
82
+ }
83
+ this.trackVisible = !this.trackVisible;
84
+ }
85
+ onTrackingChange(option, checked) {
86
+ if (checked) {
87
+ this.trackingOption = !!this.trackingOption ? undefined : option;
88
+ }
89
+ else {
90
+ this.trackingOption = first(['gps', 'gsm'].filter(opt => opt !== option));
91
+ }
92
+ this.reload();
93
+ }
94
+ isLocationUpdateEvent(event) {
95
+ return event.type === LOCATION_UPDATE_EVENT_TYPE;
96
+ }
97
+ isMatchingEvent(event) {
98
+ return (this.isLocationUpdateEvent(event) &&
99
+ (!this.trackingOption ||
100
+ (this.trackingOption === 'gps' && this.isGPSEvent(event)) ||
101
+ (this.trackingOption === 'gsm' && this.isGSMEvent(event))));
102
+ }
103
+ isGPSEvent(event) {
104
+ return !this.isGSMEvent(event);
105
+ }
106
+ isGSMEvent(event) {
107
+ return /gsm/gi.test(get(event, 'c8y_Position.fixType'));
108
+ }
109
+ compareEvents(a, b) {
110
+ return Date.parse(a?.time) - Date.parse(b?.time);
111
+ }
112
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TrackingService, deps: [{ token: i1.EventService }, { token: i1.ApplicationService }, { token: i2.GeoService }], target: i0.ɵɵFactoryTarget.Injectable }); }
113
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TrackingService }); }
114
+ }
115
+ __decorate([
116
+ memoize(),
117
+ __metadata("design:type", Function),
118
+ __metadata("design:paramtypes", [Object]),
119
+ __metadata("design:returntype", Promise)
120
+ ], TrackingService.prototype, "gsmTrackingAvailable", null);
121
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TrackingService, decorators: [{
122
+ type: Injectable
123
+ }], ctorParameters: function () { return [{ type: i1.EventService }, { type: i1.ApplicationService }, { type: i2.GeoService }]; }, propDecorators: { gsmTrackingAvailable: [] } });
124
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhY2tpbmcuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RyYWNraW5nL3RyYWNraW5nLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxFQUFFLGtCQUFrQixFQUFFLFlBQVksRUFBdUIsTUFBTSxhQUFhLENBQUM7QUFDcEYsT0FBTyxFQUFtQixVQUFVLEVBQUUsT0FBTyxFQUFnQixNQUFNLHFCQUFxQixDQUFDO0FBRXpGLE9BQU8sRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ2hFLE9BQU8sRUFBRSxlQUFlLEVBQUUsYUFBYSxFQUFjLElBQUksRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDakYsT0FBTyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDOzs7O0FBRTVELE1BQU0sMEJBQTBCLEdBQUcsb0JBQW9CLENBQUM7QUFHeEQsTUFBTSxPQUFPLGVBQWU7YUFDRixnQkFBVyxHQUFHO1FBQ3BDLFFBQVEsRUFBRSxJQUFJO1FBQ2QsY0FBYyxFQUFFLElBQUk7UUFDcEIsSUFBSSxFQUFFLDBCQUEwQjtLQUNqQyxDQUFDO0lBZUYsWUFDVSxZQUEwQixFQUMxQixrQkFBc0MsRUFDdEMsR0FBZTtRQUZmLGlCQUFZLEdBQVosWUFBWSxDQUFjO1FBQzFCLHVCQUFrQixHQUFsQixrQkFBa0IsQ0FBb0I7UUFDdEMsUUFBRyxHQUFILEdBQUcsQ0FBWTtRQVp6QixpQkFBWSxHQUFHLElBQUksQ0FBQztRQUNwQixjQUFTLEdBQUcsS0FBSyxDQUFDO1FBRVYsNEJBQXVCLEdBQUcsSUFBSSxlQUFlLENBQVcsRUFBRSxDQUFDLENBQUM7UUFFNUQsY0FBUyxHQUE2QixJ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Y0FBYyxLQUFLLEtBQUssSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FDN0QsQ0FBQztJQUNKLENBQUM7SUFFTyxVQUFVLENBQUMsS0FBYTtRQUM5QixPQUFPLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNqQyxDQUFDO0lBRU8sVUFBVSxDQUFDLEtBQWE7UUFDOUIsT0FBTyxPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUUsc0JBQXNCLENBQUMsQ0FBQyxDQUFDO0lBQzFELENBQUM7SUFFTyxhQUFhLENBQUMsQ0FBUyxFQUFFLENBQVM7UUFDeEMsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUNuRCxDQUFDOytHQTdJVSxlQUFlO21IQUFmLGVBQWU7O0FBMkZwQjtJQURMLE9BQU8sRUFBRTs7OzsyREFRVDs0RkFsR1UsZUFBZTtrQkFEM0IsVUFBVTs2SkE0Rkgsb0JBQW9CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQXBwbGljYXRpb25TZXJ2aWNlLCBFdmVudFNlcnZpY2UsIElFdmVudCwgSVJlc3VsdExpc3QgfSBmcm9tICdAYzh5L2NsaWVudCc7XG5pbXBvcnQgeyBGb3JPZkZpbHRlclBpcGUsIEdlb1NlcnZpY2UsIG1lbW9pemUsIFRpbWVJbnRlcnZhbCB9IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMnO1xuaW1wb3J0IHsgUG9zaXRpb25NYW5hZ2VkT2JqZWN0IH0gZnJvbSAnQGM4eS9uZ3gtY29tcG9uZW50cy9tYXAnO1xuaW1wb3J0IHsgZmlyc3QsIGdldCwgaWRlbnRpdHksIGlzRW1wdHksIGxhc3QgfSBmcm9tICdsb2Rhc2gtZXMnO1xuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0LCBjb21iaW5lTGF0ZXN0LCBPYnNlcnZhYmxlLCBwaXBlLCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBtYXAsIHNoYXJlLCBzd2l0Y2hNYXAsIHRhcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuY29uc3QgTE9DQVRJT05fVVBEQVRFX0VWRU5UX1RZUEUgPSAnYzh5X0xvY2F0aW9uVXBkYXRlJztcblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIFRyYWNraW5nU2VydmljZSB7XG4gIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IEJBU0VfRklMVEVSID0ge1xuICAgIHBhZ2VTaXplOiAxMDAwLFxuICAgIHdpdGhUb3RhbFBhZ2VzOiB0cnVlLFxuICAgIHR5cGU6IExPQ0FUSU9OX1VQREFURV9FVkVOVF9UWVBFXG4gIH07XG5cbiAgdHJhY2tpbmdPcHRpb246ICdncHMnIHwgJ2dzbScgfCB1bmRlZmluZWQ7XG4gIGV2ZW50cyQ6IE9ic2VydmFibGU8SVJlc3VsdExpc3Q8SUV2ZW50Pj47XG4gIHBvbHlsaW5lJDogT2JzZXJ2YWJsZTxMLkxhdExuZ0V4cHJlc3Npb25bXT47XG4gIHBpcGU6IEZvck9mRmlsdGVyUGlwZTtcbiAgdHJhY2tWaXNpYmxlID0gdHJ1ZTtcbiAgaGFzRXZlbnRzID0gZmFsc2U7XG5cbiAgcHJpdmF0ZSBfcG9seWxpbmVFdmVudHNTdWJqZWN0JCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8SUV2ZW50W10+KFtdKTtcblxuICBwcml2YXRlIGRldmljZUlkJDogU3ViamVjdDxzdHJpbmcgfCBudW1iZXI+ID0gbmV3IFN1YmplY3QoKTtcbiAgcHJpdmF0ZSB0aW1lSW50ZXJ2YWwkOiBTdWJqZWN0PFRpbWVJbnRlcnZhbD4gPSBuZXcgU3ViamVjdCgpO1xuICBwcml2YXRlIHJlbG9hZCQ6IEJlaGF2aW9yU3ViamVjdDx2b2lkPiA9IG5ldyBCZWhhdmlvclN1YmplY3QobnVsbCk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBldmVudFNlcnZpY2U6IEV2ZW50U2VydmljZSxcbiAgICBwcml2YXRlIGFwcGxpY2F0aW9uU2VydmljZTogQXBwbGljYXRpb25TZXJ2aWNlLFxuICAgIHByaXZhdGUgZ2VvOiBHZW9TZXJ2aWNlXG4gICkge1xuICAgIHRoaXMucG9seWxpbmUkID0gdGhpcy5fcG9seWxpbmVFdmVudHNTdWJqZWN0JC5hc09ic2VydmFibGUoKS5waXBlKFxuICAgICAgbWFwKGV2ZW50cyA9PiAoZXZlbnRzIHx8IFtdKS5tYXAoZXZlbnQgPT4gdGhpcy5nZW8uZ2V0TGF0TG9uZyhldmVudCkpLmZpbHRlcihpZGVudGl0eSkpLFxuICAgICAgc2hhcmUoKVxuICAgICk7XG5cbiAgICB0aGlzLmV2ZW50cyQgPSBjb21iaW5lTGF0ZXN0KFt0aGlzLmRldmljZUlkJCwgdGhpcy50aW1lSW50ZXJ2YWwkLCB0aGlzLnJlbG9hZCRdKS5waXBlKFxuICAgICAgc3dpdGNoTWFwKChbc291cmNlLCBpbnRlcnZhbF0pID0+IHtcbiAgICAgICAgY29uc3QgeyBkYXRlRnJvbSwgZGF0ZVRvIH0gPSBpbnRlcnZhbDtcbiAgICAgICAgcmV0dXJuIHRoaXMuZXZlbnRTZXJ2aWNlLmxpc3Qoe1xuICAgICAgICAgIC4uLlRyYWNraW5nU2VydmljZS5CQVNFX0ZJTFRFUixcbiAgICAgICAgICBzb3VyY2UsXG4gICAgICAgICAgZGF0ZUZyb206IGRhdGVGcm9tLnRvSVNPU3RyaW5nKCksXG4gICAgICAgICAgZGF0ZVRvOiBkYXRlVG8udG9JU09TdHJpbmcoKVxuICAgICAgICB9KTtcbiAgICAgIH0pLFxuICAgICAgdGFwKCgpID0+IHRoaXMuX3BvbHlsaW5lRXZlbnRzU3ViamVjdCQubmV4dChbXSkpLFxuICAgICAgc2hhcmUoKVxuICAgICk7XG5cbiAgICB0aGlzLnBpcGUgPSBwaXBlKFxuICAgICAgdGFwKGV2ZW50cyA9PiAodGhpcy5oYXNFdmVudHMgPSAhaXNFbXB0eShldmVudHMpKSksXG4gICAgICBtYXAoKGV2ZW50czogSUV2ZW50W10pID0+IChldmVudHMgfHwgW10pLmZpbHRlcihldmVudCA9PiB0aGlzLmlzTWF0Y2hpbmdFdmVudChldmVudCkpKSxcbiAgICAgIHRhcCgoZXZlbnRzOiBJRXZlbnRbXSkgPT4ge1xuICAgICAgICBjb25zdCBwcmVwZW5kID1cbiAgICAgICAgICB0aGlzLmNvbXBhcmVFdmVudHMobGFzdCh0aGlzLl9wb2x5bGluZUV2ZW50c1N1YmplY3QkLnZhbHVlKSwgZmlyc3QoZXZlbnRzKSkgPCAwO1xuICAgICAgICBjb25zdCBwb2x5bGluZTogSUV2ZW50W10gPSBwcmVwZW5kXG4gICAgICAgICAgPyBbLi4uZXZlbnRzLCAuLi50aGlzLl9wb2x5bGluZUV2ZW50c1N1YmplY3QkLnZhbHVlXVxuICAgICAgICAgIDogWy4uLnRoaXMuX3BvbHlsaW5lRXZlbnRzU3ViamVjdCQudmFsdWUsIC4uLmV2ZW50c107XG5cbiAgICAgICAgdGhpcy5fcG9seWxpbmVFdmVudHNTdWJqZWN0JC5uZXh0KHBvbHlsaW5lKTtcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIHNldERldmljZUlkKGRldmljZUlkOiBzdHJpbmcgfCBudW1iZXIpIHtcbiAgICB0aGlzLmRldmljZUlkJC5uZXh0KGRldmljZUlkKTtcbiAgfVxuXG4gIHNldEludGVydmFsKGludGVydmFsOiBUaW1lSW50ZXJ2YWwpIHtcbiAgICB0aGlzLnRpbWVJbnRlcnZhbCQubmV4dChpbnRlcnZhbCk7XG4gIH1cblxuICBjbGVhclRyYWNrKCkge1xuICAgIHRoaXMuX3BvbHlsaW5lRXZlbnRzU3ViamVjdCQubmV4dChbXSk7XG4gIH1cblxuICByZWxvYWQoKSB7XG4gICAgdGhpcy5yZWxvYWQkLm5leHQoKTtcbiAgfVxuXG4gIGFzeW5jIGxhdGVzdFBvc2l0aW9uVXBkYXRlKG1vOiBQb3NpdGlvbk1hbmFnZWRPYmplY3QpOiBQcm9taXNlPERhdGU+IHtcbiAgICBjb25zdCBkYXRlVG8gPSBuZXcgRGF0ZSgpO1xuICAgIGRhdGVUby5zZXREYXRlKGRhdGVUby5nZXREYXRlKCkgKyAxKTtcblxuICAgIGNvbnN0IGZpbHRlcnMgPSB7XG4gICAgICBmcmFnbWVudFR5cGU6ICdjOHlfUG9zaXRpb24nLFxuICAgICAgZGF0ZUZyb206IG5ldyBEYXRlKDApLnRvSVNPU3RyaW5nKCksXG4gICAgICBkYXRlVG86IGRhdGVUby50b0lTT1N0cmluZygpLFxuICAgICAgcGFnZVNpemU6IDEsXG4gICAgICBzb3VyY2U6IG1vLmlkXG4gICAgfTtcbiAgICBjb25zdCBldmVudHMgPSBhd2FpdCB0aGlzLmV2ZW50U2VydmljZS5saXN0KGZpbHRlcnMpO1xuICAgIHJldHVybiBldmVudHM/LmRhdGE/Lmxlbmd0aCA/IG5ldyBEYXRlKGV2ZW50cy5kYXRhWzBdLnRpbWUpIDogdW5kZWZpbmVkO1xuICB9XG5cbiAgQG1lbW9pemUoKVxuICBhc3luYyBnc21UcmFja2luZ0F2YWlsYWJsZShkZXZpY2UpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCBhcHBzID0gKGF3YWl0IHRoaXMuYXBwbGljYXRpb25TZXJ2aWNlLmxpc3RCeVVzZXIoKSk/LmRhdGEgfHwgW107XG4gICAgY29uc3QgYXBwQXZhaWxhYmxlID0gYXBwcy5zb21lKGFwcCA9PlxuICAgICAgWydjZWxsaWQtYXBwbGljYXRpb24ta2V5JywgJ2NlbGxpZC1rZXknXS5zb21lKGtleSA9PiBhcHAua2V5ID09PSBrZXkpXG4gICAgKTtcblxuICAgIHJldHVybiBhcHBBdmFpbGFibGUgJiYgISEoZGV2aWNlLmM4eV9DZWxsSW5mbyB8fCBkZXZpY2UuYzh5X01vYmlsZSk7XG4gIH1cblxuICB0b2dnbGVUcmFjaygpIHtcbiAgICBpZiAodGhpcy50cmFja1Zpc2libGUpIHtcbiAgICAgIHRoaXMuY2xlYXJUcmFjaygpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnJlbG9hZCgpO1xuICAgIH1cbiAgICB0aGlzLnRyYWNrVmlzaWJsZSA9ICF0aGlzLnRyYWNrVmlzaWJsZTtcbiAgfVxuXG4gIG9uVHJhY2tpbmdDaGFuZ2Uob3B0aW9uOiAnZ3BzJyB8ICdnc20nLCBjaGVja2VkOiBib29sZWFuKSB7XG4gICAgaWYgKGNoZWNrZWQpIHtcbiAgICAgIHRoaXMudHJhY2tpbmdPcHRpb24gPSAhIXRoaXMudHJhY2tpbmdPcHRpb24gPyB1bmRlZmluZWQgOiBvcHRpb247XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudHJhY2tpbmdPcHRpb24gPSBmaXJzdChbJ2dwcycsICdnc20nXS5maWx0ZXIob3B0ID0+IG9wdCAhPT0gb3B0aW9uKSk7XG4gICAgfVxuICAgIHRoaXMucmVsb2FkKCk7XG4gIH1cblxuICBpc0xvY2F0aW9uVXBkYXRlRXZlbnQoZXZlbnQ6IElFdmVudCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBldmVudC50eXBlID09PSBMT0NBVElPTl9VUERBVEVfRVZFTlRfVFlQRTtcbiAgfVxuXG4gIHByaXZhdGUgaXNNYXRjaGluZ0V2ZW50KGV2ZW50OiBJRXZlbnQpOiBib29sZWFuIHtcbiAgICByZXR1cm4gKFxuICAgICAgdGhpcy5pc0xvY2F0aW9uVXBkYXRlRXZlbnQoZXZlbnQpICYmXG4gICAgICAoIXRoaXMudHJhY2tpbmdPcHRpb24gfHxcbiAgICAgICAgKHRoaXMudHJhY2tpbmdPcHRpb24gPT09ICdncHMnICYmIHRoaXMuaXNHUFNFdmVudChldmVudCkpIHx8XG4gICAgICAgICh0aGlzLnRyYWNraW5nT3B0aW9uID09PSAnZ3NtJyAmJiB0aGlzLmlzR1NNRXZlbnQoZXZlbnQpKSlcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBpc0dQU0V2ZW50KGV2ZW50OiBJRXZlbnQpOiBib29sZWFuIHtcbiAgICByZXR1cm4gIXRoaXMuaXNHU01FdmVudChldmVudCk7XG4gIH1cblxuICBwcml2YXRlIGlzR1NNRXZlbnQoZXZlbnQ6IElFdmVudCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAvZ3NtL2dpLnRlc3QoZ2V0KGV2ZW50LCAnYzh5X1Bvc2l0aW9uLmZpeFR5cGUnKSk7XG4gIH1cblxuICBwcml2YXRlIGNvbXBhcmVFdmVudHMoYTogSUV2ZW50LCBiOiBJRXZlbnQpOiBudW1iZXIge1xuICAgIHJldHVybiBEYXRlLnBhcnNlKGE/LnRpbWUpIC0gRGF0ZS5wYXJzZShiPy50aW1lKTtcbiAgfVxufVxuIl19